From d9d93e0d9d1209cdce297742457bbc8b8f91bae2 Mon Sep 17 00:00:00 2001 From: objec Date: Thu, 16 Apr 2026 17:29:46 +0400 Subject: [PATCH] Mailchimp PLugin - Corrected grammar in PHPdocs - PSR refactoring of local variables and code blocks - Moved MailchimpPlugin.php to its own plugin folder - Refactored out mailchimp code to the plugin - Created customer_loaded event trigger Signed-off-by: objec --- app/Controllers/Customers.php | 72 +++---------------- app/Libraries/Plugins/PluginInterface.php | 12 ++-- app/Models/Customer.php | 2 +- .../{ => MailchimpPlugin}/MailchimpPlugin.php | 51 ++++++++++++- app/Plugins/README.md | 17 ++--- 5 files changed, 76 insertions(+), 78 deletions(-) rename app/Plugins/{ => MailchimpPlugin}/MailchimpPlugin.php (73%) diff --git a/app/Controllers/Customers.php b/app/Controllers/Customers.php index 42d9345a2..e89182cae 100644 --- a/app/Controllers/Customers.php +++ b/app/Controllers/Customers.php @@ -2,11 +2,10 @@ namespace App\Controllers; -use App\Libraries\Mailchimp_lib; - use App\Models\Customer; use App\Models\Customer_rewards; use App\Models\Tax_code; +use CodeIgniter\Events\Events; use CodeIgniter\HTTP\DownloadResponse; use CodeIgniter\HTTP\ResponseInterface; use Config\OSPOS; @@ -15,8 +14,6 @@ use stdClass; class Customers extends Persons { - private string $_list_id; - private Mailchimp_lib $mailchimp_lib; private Customer_rewards $customer_rewards; private Customer $customer; private Tax_code $tax_code; @@ -25,20 +22,11 @@ class Customers extends Persons public function __construct() { parent::__construct('customers'); - $this->mailchimp_lib = new Mailchimp_lib(); + $this->customer_rewards = model(Customer_rewards::class); $this->customer = model(Customer::class); $this->tax_code = model(Tax_code::class); $this->config = config(OSPOS::class)->settings; - - //TODO: This logic needs to be moved to the Mailchimp plugin - $encrypter = Services::encrypter(); - - if (!empty($this->config['mailchimp_list_id'])) { - $this->_list_id = $encrypter->decrypt($this->config['mailchimp_list_id']); - } else { - $this->_list_id = ''; - } } /** @@ -53,6 +41,7 @@ class Customers extends Persons /** * Gets one row for a customer manage table. This is called using AJAX to update one row. + * @param int $row_id * @return ResponseInterface */ public function getRow(int $row_id): ResponseInterface @@ -142,14 +131,16 @@ class Customers extends Persons /** * Loads the customer edit form + * @param int $customerId * @return string */ - public function getView(int $customer_id = NEW_ENTRY): string + public function getView(int $customerId = NEW_ENTRY): string { - // Set default values - if ($customer_id == null) $customer_id = NEW_ENTRY; + if ($customerId == null) { + $customerId = NEW_ENTRY; + } - $info = $this->customer->get_info($customer_id); + $info = $this->customer->get_info($customerId); foreach (get_object_vars($info) as $property => $value) { $info->$property = $value; } @@ -181,7 +172,7 @@ class Customers extends Persons $data['use_destination_based_tax'] = $this->config['use_destination_based_tax']; // Retrieve the total amount the customer spent so far together with min, max and average values - $stats = $this->customer->get_stats($customer_id); + $stats = $this->customer->get_stats($customerId); if (!empty($stats)) { foreach (get_object_vars($stats) as $property => $value) { $info->$property = $value; @@ -189,48 +180,7 @@ class Customers extends Persons $data['stats'] = $stats; } - // Retrieve the info from Mailchimp only if there is an email address assigned - if (!empty($info->email)) { - // Collect Mailchimp customer info - if (($mailchimp_info = $this->mailchimp_lib->getMemberInfo($this->_list_id, $info->email)) !== false) { - $data['mailchimp_info'] = $mailchimp_info; - - // Collect customer Mailchimp emails activities (stats) - if (($activities = $this->mailchimp_lib->getMemberActivity($this->_list_id, $info->email)) !== false) { - if (array_key_exists('activity', $activities)) { - $open = 0; - $unopen = 0; - $click = 0; - $total = 0; - $lastopen = ''; - - foreach ($activities['activity'] as $activity) { - if ($activity['action'] == 'sent') { - ++$unopen; - } elseif ($activity['action'] == 'open') { - if (empty($lastopen)) { - $lastopen = substr($activity['timestamp'], 0, 10); - } - ++$open; - } elseif ($activity['action'] == 'click') { - if (empty($lastopen)) { - $lastopen = substr($activity['timestamp'], 0, 10); - } - ++$click; - } - - ++$total; - } - - $data['mailchimp_activity']['total'] = $total; - $data['mailchimp_activity']['open'] = $open; - $data['mailchimp_activity']['unopen'] = $unopen; - $data['mailchimp_activity']['click'] = $click; - $data['mailchimp_activity']['lastopen'] = $lastopen; - } - } - } - } + Events::trigger('customer_loaded', $info); return view("customers/form", $data); } diff --git a/app/Libraries/Plugins/PluginInterface.php b/app/Libraries/Plugins/PluginInterface.php index 8a032c661..c7df6b46c 100644 --- a/app/Libraries/Plugins/PluginInterface.php +++ b/app/Libraries/Plugins/PluginInterface.php @@ -14,10 +14,10 @@ interface PluginInterface /** * Register event listeners for this plugin. - * + * * Use Events::on() to register callbacks for OSPOS events. * This method is called when the plugin is loaded and enabled. - * + * * Example: * Events::on('item_sale', [$this, 'onItemSale']); * Events::on('item_change', [$this, 'onItemChange']); @@ -26,7 +26,7 @@ interface PluginInterface /** * Install the plugin. - * + * * Called when the plugin is first enabled. Use this to create database tables, * set default configuration values, and run any setup required. */ @@ -34,7 +34,7 @@ interface PluginInterface /** * Uninstall the plugin. - * + * * Called when the plugin is being removed. Use this to remove database tables, * clean up configuration, etc. */ @@ -45,7 +45,7 @@ interface PluginInterface /** * Get the path to the plugin's configuration view file. * Returns null if the plugin has no configuration UI. - * + * * Example: 'Plugins/mailchimp/config' */ public function getConfigView(): ?string; @@ -53,4 +53,4 @@ interface PluginInterface public function getSettings(): array; public function saveSettings(array $settings): bool; -} \ No newline at end of file +} diff --git a/app/Models/Customer.php b/app/Models/Customer.php index 2cadd9677..5e86d3fca 100644 --- a/app/Models/Customer.php +++ b/app/Models/Customer.php @@ -44,7 +44,7 @@ class Customer extends Person } /** - * Checks if account number exists + * Checks if the account number exists */ public function check_account_number_exists(string $account_number, string $person_id = ''): bool { diff --git a/app/Plugins/MailchimpPlugin.php b/app/Plugins/MailchimpPlugin/MailchimpPlugin.php similarity index 73% rename from app/Plugins/MailchimpPlugin.php rename to app/Plugins/MailchimpPlugin/MailchimpPlugin.php index d2aae9cff..d2859ebd9 100644 --- a/app/Plugins/MailchimpPlugin.php +++ b/app/Plugins/MailchimpPlugin/MailchimpPlugin.php @@ -1,9 +1,9 @@ mailchimpLibrary = new MailchimpLibrary(); log_message('debug', 'MailchimpPlugin initialized'); } @@ -46,6 +47,7 @@ class MailchimpPlugin extends BasePlugin public function registerEvents(): void { + Events::on('customer_loaded', [$this, 'onCustomerLoaded']); Events::on('customer_saved', [$this, 'onCustomerSaved']); Events::on('customer_deleted', [$this, 'onCustomerDeleted']); @@ -104,6 +106,51 @@ class MailchimpPlugin extends BasePlugin return parent::saveSettings($normalized); } + public function onCustomerLoaded(object $customerInfo): void + {//TODO: This likely needs to be refactored to a controller function, called here then below it call another function to generate the view data so the mailchimpCustomerForm.php view can be displayed as a partial view. Does the view need to be called here? + if (!empty($customerInfo->email)) { + $mailchimpInfo = $this->mailchimpLibrary->getMemberInfo($this->_list_id, $customerInfo->email); + if ($mailchimpInfo !== false) { + $customerData['mailchimp_info'] = $mailchimpInfo; + + $customerActivities = $this->mailchimpLibrary->getMemberActivity($this->_list_id, $customerInfo->email); + if ($customerActivities !== false) { + if (array_key_exists('activity', $customerActivities)) { + $open = 0; + $unopen = 0; + $click = 0; + $total = 0; + $lastOpen = ''; + + foreach ($customerActivities['activity'] as $activity) { + if ($activity['action'] == 'sent') { + ++$unopen; + } elseif ($activity['action'] == 'open') { + if (empty($lastOpen)) { + $lastOpen = substr($activity['timestamp'], 0, 10); + } + ++$open; + } elseif ($activity['action'] == 'click') { + if (empty($lastOpen)) { + $lastOpen = substr($activity['timestamp'], 0, 10); + } + ++$click; + } + + ++$total; + } + + $customerData['mailchimp_activity']['total'] = $total; + $customerData['mailchimp_activity']['open'] = $open; + $customerData['mailchimp_activity']['unopen'] = $unopen; + $customerData['mailchimp_activity']['click'] = $click; + $customerData['mailchimp_activity']['lastopen'] = $lastOpen; + } + } + } + } + } + public function onCustomerSaved(array $customerData): void { if (!$this->shouldSyncOnSave()) { diff --git a/app/Plugins/README.md b/app/Plugins/README.md index dc927f351..1d18d86c2 100644 --- a/app/Plugins/README.md +++ b/app/Plugins/README.md @@ -75,14 +75,15 @@ The `PluginManager` class handles: OSPOS fires these events that plugins can listen to: -| Event | Arguments | Description | -|-------|-----------|-------------| -| `item_sale` | `array $saleData` | Fired when a sale is completed | -| `item_return` | `array $returnData` | Fired when a return is processed | -| `item_change` | `int $itemId` | Fired when an item is created/updated/deleted | -| `item_inventory` | `array $inventoryData` | Fired on inventory changes | -| `items_csv_import` | `array $importData` | Fired after items CSV import | -| `customers_csv_import` | `array $importData` | Fired after customers CSV import | +| Event | Arguments | Description | +|------------------------|------------------------|--------------------------------------------------| +| `item_sale` | `array $saleData` | Fired when a sale is completed | +| `item_return` | `array $returnData` | Fired when a return is processed | +| `item_change` | `int $itemId` | Fired when an item is created/updated/deleted | +| `item_inventory` | `array $inventoryData` | Fired on inventory changes | +| `items_csv_import` | `array $importData` | Fired after items CSV import | +| `customers_csv_import` | `array $importData` | Fired after customers CSV import | +| `customer_load` | `array $customerData` | Fired during customer form view data preparation | ## View Hooks (Injecting Plugin Content into Views)