Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 82 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
| CustomerController | |
0.00% |
0 / 82 |
|
0.00% |
0 / 8 |
1056 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
| getCustomersList | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
6 | |||
| getCustomerByLicense | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
| getCustomerById | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
| getCustomerByPhone | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
| createCustomer | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
72 | |||
| addConstantContact | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
12 | |||
| updateEmailOptIn | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
42 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace BuyerKiosk\BuyerKiosk\Controllers; |
| 4 | |
| 5 | use UserFrosting\Sprunje\Sprunje; |
| 6 | use UserFrosting\Support\Exception\ForbiddenException; |
| 7 | use UserFrosting\Support\Exception\NotFoundException; |
| 8 | |
| 9 | class CustomerController extends \BuyerKiosk\Core\Controllers\BaseController { |
| 10 | |
| 11 | private $log; |
| 12 | private $store; |
| 13 | private $storeDB; |
| 14 | |
| 15 | public function __construct($app, \Store $store) |
| 16 | { |
| 17 | parent::__construct($app); |
| 18 | $this->log = new \KLogger(logDirectory."customer_controller.log", \KLogger::DEBUG); |
| 19 | $this->store = $store; |
| 20 | $this->storeDB = dbConnectByName($store->getDbName()); |
| 21 | } |
| 22 | |
| 23 | /** |
| 24 | * Returns a list of Customers for the DataTables AJAX request. |
| 25 | * |
| 26 | * This method receives parameters from DataTables via POST request, |
| 27 | * performs server-side processing (filtering, sorting, pagination), |
| 28 | * and returns the data in the format required by DataTables. |
| 29 | * /api/{store_id}/customers |
| 30 | * @param string $typeNum The store identifier. |
| 31 | */ |
| 32 | public function getCustomersList($typeNum) |
| 33 | { |
| 34 | // Placeholder for server-side processing logic |
| 35 | $request = $this->app->request; |
| 36 | $params = $request->post(); |
| 37 | |
| 38 | // TODO: Implement server-side processing logic here |
| 39 | |
| 40 | $response = $this->app->response; |
| 41 | $response->headers->set('Content-Type', 'application/json'); |
| 42 | // Placeholder response |
| 43 | $response->setBody(json_encode([ |
| 44 | 'draw' => isset($params['draw']) ? intval($params['draw']) : 0, |
| 45 | 'recordsTotal' => 0, |
| 46 | 'recordsFiltered' => 0, |
| 47 | 'data' => [] |
| 48 | ])); |
| 49 | return $response; |
| 50 | } |
| 51 | |
| 52 | // Other methods from the original CustomersListController can be moved or adapted here if needed. |
| 53 | // For example: getCustomerById, getCustomerByPhone, createCustomer, etc. |
| 54 | // Make sure namespaces and dependencies are correct. |
| 55 | |
| 56 | public function getCustomerByLicense($id) { |
| 57 | try{ |
| 58 | $stmt = $this->storeDB->prepare("SELECT customerID FROM customers WHERE driversLicense = :id LIMIT 1"); |
| 59 | $stmt->bindValue(":id", $id); |
| 60 | if($stmt->execute()) { |
| 61 | if($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
| 62 | return new \Customer($row['customerID'], $this->store->getTypeNum()); |
| 63 | } |
| 64 | } |
| 65 | } catch (\PDOException $e) { |
| 66 | $this->log->LogError("[GET_CUSTOMER_BY_ID] ".$e->getMessage()); |
| 67 | } |
| 68 | return null; |
| 69 | } |
| 70 | |
| 71 | public function getCustomerById($customerID) |
| 72 | { |
| 73 | try { |
| 74 | $stmt = $this->storeDB->prepare(" |
| 75 | SELECT customerID |
| 76 | FROM customers |
| 77 | WHERE customerID = :customerID |
| 78 | LIMIT 1 |
| 79 | "); |
| 80 | $stmt->bindValue(":customerID", $customerID); |
| 81 | if ($stmt->execute()) { |
| 82 | if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
| 83 | return new \Customer($row['customerID'], $this->store->getTypeNum()); |
| 84 | } |
| 85 | } |
| 86 | } catch (\PDOException $e) { |
| 87 | $this->log->LogError("[GET_CUSTOMER_BY_ID] " . $e->getMessage()); |
| 88 | } |
| 89 | return null; |
| 90 | } |
| 91 | public function getCustomerByPhone($phone) |
| 92 | { |
| 93 | try { |
| 94 | // Strip out non-digit chars for consistency |
| 95 | $phone = preg_replace('/\D/', '', $phone); |
| 96 | |
| 97 | $stmt = $this->storeDB->prepare(" |
| 98 | SELECT customerID |
| 99 | FROM customers |
| 100 | WHERE phone = :phone |
| 101 | LIMIT 1 |
| 102 | "); |
| 103 | $stmt->bindValue(":phone", $phone); |
| 104 | if ($stmt->execute()) { |
| 105 | if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { |
| 106 | return new \Customer($row['customerID'], $this->store->getTypeNum()); |
| 107 | } |
| 108 | } |
| 109 | } catch (\PDOException $e) { |
| 110 | $this->log->LogError("[GET_CUSTOMER_BY_PHONE] " . $e->getMessage()); |
| 111 | } |
| 112 | return null; |
| 113 | } |
| 114 | |
| 115 | public function createCustomer($data) { |
| 116 | try { |
| 117 | // Validate required fields |
| 118 | $requiredFields = ['firstName', 'lastName', 'phone']; |
| 119 | foreach ($requiredFields as $field) { |
| 120 | if (empty($data[$field])) { |
| 121 | throw new \Exception("Missing required field: {$field}"); |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | // Format phone number (remove non-numeric characters) |
| 126 | $data['phone'] = preg_replace('/[^0-9]/', '', $data['phone']); |
| 127 | |
| 128 | // Create new customer using the Customer model |
| 129 | $customerModel = new \Customer(null, $this->store->getTypeNum()); |
| 130 | $customerID = $customerModel->create($data); |
| 131 | |
| 132 | if (!$customerID) { |
| 133 | throw new \Exception("Failed to create customer record"); |
| 134 | } |
| 135 | |
| 136 | // Add customer to Constant Contact queue if emailOptIn is set to 1 |
| 137 | if (isset($data['emailOptIn']) && $data['emailOptIn'] == 1 && isset($data['email'])) { |
| 138 | $this->addConstantContact($data['email'], $data['firstName'], $data['lastName']); |
| 139 | } |
| 140 | |
| 141 | |
| 142 | return $customerID; |
| 143 | |
| 144 | } catch (\Exception $e) { |
| 145 | $this->log->LogError("[CREATE_CUSTOMER] " . $e->getMessage()); |
| 146 | throw $e; // Re-throw the exception to be handled by the caller or framework |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | private function addConstantContact($email, $firstName, $lastName) { |
| 151 | // Ensure Predis is available or handle appropriately |
| 152 | if (class_exists('\Predis\Client')) { |
| 153 | try { |
| 154 | $redis = new \Predis\Client(); |
| 155 | $contact = [ |
| 156 | 'email' => $email, |
| 157 | 'first_name' => $firstName, |
| 158 | 'last_name' => $lastName |
| 159 | ]; |
| 160 | $json = json_encode($contact); |
| 161 | $redis->rpush($this->store->getTypeNum() . "_CC", $json); |
| 162 | } catch (\Exception $e) { |
| 163 | $this->log->LogError("[ADD_CONSTANT_CONTACT] Redis Error: " . $e->getMessage()); |
| 164 | // Decide how to handle Redis connection errors (e.g., log, notify, fallback) |
| 165 | } |
| 166 | } else { |
| 167 | $this->log->LogWarning("[ADD_CONSTANT_CONTACT] Predis client class not found."); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | public function updateEmailOptIn($customerID, $optIn) { |
| 172 | try { |
| 173 | $customer = new \Customer($customerID, $this->store->getTypeNum()); |
| 174 | if (!$customer->getCustomerID()) { |
| 175 | throw new NotFoundException("Customer not found."); |
| 176 | } |
| 177 | $customer->setOnEmail($optIn); |
| 178 | $customer->update(); // Assumes update method exists and works |
| 179 | |
| 180 | if ($optIn == 1 && $customer->getEmail()) { |
| 181 | $this->addConstantContact($customer->getEmail(), $customer->getFirstName(), $customer->getLastName()); |
| 182 | } |
| 183 | } catch (NotFoundException $e) { |
| 184 | $this->log->LogError("[UPDATE_EMAIL_OPT_IN] Customer ID {$customerID} not found. " . $e->getMessage()); |
| 185 | throw $e; |
| 186 | } |
| 187 | catch (\Exception $e) { |
| 188 | $this->log->LogError("[UPDATE_EMAIL_OPT_IN] Error updating opt-in for customer ID {$customerID}: " . $e->getMessage()); |
| 189 | throw $e; // Re-throw for framework error handling |
| 190 | } |
| 191 | } |
| 192 | } |