From 4246a915c4e6a56a8da7de9f06ef0dcc9267dad4 Mon Sep 17 00:00:00 2001 From: objec Date: Thu, 30 Apr 2026 14:11:54 +0400 Subject: [PATCH] - Correct README.md reference to views and information about renderView() - Fix the output of pluginContent in the pluginHelper - Register view injection events - Correct the parameter type in getMailchimpViewData - Correct the statusOptions creation business logic - Removed unnecessary view injection point - Corrected which variable was passed to the customer_saved event - Assigned $customer_data['person_id'] on customer update - Added renderView() function to BasePlugin.php Signed-off-by: objec --- app/Controllers/Customers.php | 3 +- app/Helpers/plugin_helper.php | 13 +++----- app/Libraries/Plugins/BasePlugin.php | 6 ++++ app/Models/Customer.php | 1 + .../Libraries/MailchimpLibrary.php | 4 +-- .../MailchimpPlugin/MailchimpPlugin.php | 31 +++++++++++++++++-- app/Plugins/README.md | 26 ++++++++++++++-- app/Views/customers/form.php | 10 ++---- 8 files changed, 67 insertions(+), 27 deletions(-) diff --git a/app/Controllers/Customers.php b/app/Controllers/Customers.php index cb3e1916d..f69d9a044 100644 --- a/app/Controllers/Customers.php +++ b/app/Controllers/Customers.php @@ -181,7 +181,6 @@ class Customers extends Persons } Events::trigger('customer_loaded', $info); - Events::trigger('view:customer_tabs', $info); return view("customers/form", $data); } @@ -233,7 +232,7 @@ class Customers extends Persons ]; if ($this->customer->save_customer($personData, $customerData, $customerId)) { - Events::trigger('customer_saved', $personData); + Events::trigger('customer_saved', $customerData); // New customer if ($customerId == NEW_ENTRY) { diff --git a/app/Helpers/plugin_helper.php b/app/Helpers/plugin_helper.php index 227de8679..5ea9c4232 100644 --- a/app/Helpers/plugin_helper.php +++ b/app/Helpers/plugin_helper.php @@ -5,20 +5,15 @@ use CodeIgniter\Events\Events; if (!function_exists('pluginContent')) { function pluginContent(string $section, array $data = []): string { - $results = Events::trigger("view:{$section}", $data); - - if (is_array($results)) { - return implode('', array_filter($results, fn ($r) => is_string($r))); - } - - return is_string($results) ? $results : ''; + ob_start(); + Events::trigger("view:{$section}", $data); + return ob_get_clean() ?: ''; } } if (!function_exists('pluginContentExists')) { function pluginContentExists(string $section): bool { - $observers = Events::listRegistered("view:{$section}"); - return !empty($observers); + return !empty(Events::listeners("view:{$section}")); } } diff --git a/app/Libraries/Plugins/BasePlugin.php b/app/Libraries/Plugins/BasePlugin.php index c9290dd28..4230231cc 100644 --- a/app/Libraries/Plugins/BasePlugin.php +++ b/app/Libraries/Plugins/BasePlugin.php @@ -67,4 +67,10 @@ abstract class BasePlugin implements PluginInterface { log_message($level, "[Plugin:{$this->getPluginName()}] {$message}"); } + + protected function renderView(string $viewName, array $data = []): string + { + $namespace = substr(get_class($this), 0, strrpos(get_class($this), '\\')); + return view($namespace . '\\Views\\' . $viewName, $data); + } } diff --git a/app/Models/Customer.php b/app/Models/Customer.php index 5e86d3fca..60f0c49e2 100644 --- a/app/Models/Customer.php +++ b/app/Models/Customer.php @@ -223,6 +223,7 @@ class Customer extends Person } else { $builder->where('person_id', $customer_id); $success = $builder->update($customer_data); + $customer_data['person_id'] = $customer_id; } } diff --git a/app/Plugins/MailchimpPlugin/Libraries/MailchimpLibrary.php b/app/Plugins/MailchimpPlugin/Libraries/MailchimpLibrary.php index 306506634..8b930222d 100644 --- a/app/Plugins/MailchimpPlugin/Libraries/MailchimpLibrary.php +++ b/app/Plugins/MailchimpPlugin/Libraries/MailchimpLibrary.php @@ -274,7 +274,7 @@ class MailchimpLibrary return !($this->removeMember($listId, $customer->email) === false); } - public function getMailchimpViewData(array $customerData): array + public function getMailchimpViewData(stdClass $customerData): array { if (!empty($customerData->email)) { $listId = $this->settings['list_id']; @@ -332,7 +332,7 @@ class MailchimpLibrary $statusOptions = []; foreach (SubscriptionStatus::cases() as $case) { $lowercaseName = strtolower($case->name); - $statusOptions[(int)$case] = lang("MailchimpPlugin.subscription_status_{$lowercaseName}"); + $statusOptions[$case->value] = lang("MailchimpPlugin.subscription_status_{$lowercaseName}"); } return $statusOptions; diff --git a/app/Plugins/MailchimpPlugin/MailchimpPlugin.php b/app/Plugins/MailchimpPlugin/MailchimpPlugin.php index 5d031de8c..8f7d9bf97 100644 --- a/app/Plugins/MailchimpPlugin/MailchimpPlugin.php +++ b/app/Plugins/MailchimpPlugin/MailchimpPlugin.php @@ -48,7 +48,8 @@ class MailchimpPlugin extends BasePlugin { Events::on('customer_saved', [$this, 'onCustomerSaved']); Events::on('customer_deleted', [$this, 'onCustomerDeleted']); - Events::on('view:customer_tabs', [$this, 'injectMailchimpCustomerTab']); + Events::on('view:customer_tab_nav', [$this, 'injectMailchimpTabNav']); + Events::on('view:customer_tab_panels', [$this, 'injectMailchimpTabPanel']); log_message('debug', 'Mailchimp plugin events registered'); } @@ -145,11 +146,35 @@ class MailchimpPlugin extends BasePlugin return parent::saveSettings($normalized); } - public function injectMailchimpCustomerTab(array $customerData): string + public function injectMailchimpTabNav(array $data): void { + echo $this->renderView('customer_tab_nav', []); + } + + public function injectMailchimpTabPanel(array $data): void + { + $customerData = $data['customer'] ?? new stdClass(); $mailchimpData = $this->mailchimpLibrary->getMailchimpViewData($customerData); - return view('Plugins/MailchimpPlugin/Views/customer_tab', $mailchimpData); + $mailchimpInfo = $mailchimpData['mailchimpActivity'] ?? []; + $viewData = [ + 'mailchimpData' => [ + 'status' => $mailchimpInfo['status'] ?? '', + 'vip' => $mailchimpInfo['vip'] ?? 0, + 'member_rating' => $mailchimpInfo['member_rating'] ?? 0, + 'email_client' => $mailchimpInfo['email_client'] ?? '', + ], + 'mailchimpActivity' => [ + 'total' => $mailchimpInfo['total'] ?? 0, + 'last_open' => $mailchimpInfo['last_open'] ?? '', + 'open' => $mailchimpInfo['open'] ?? 0, + 'click' => $mailchimpInfo['click'] ?? 0, + 'unopen' => $mailchimpInfo['unopen'] ?? 0, + ], + 'subscriptionStatusOptions' => $mailchimpData['subscriptionStatusOptions'] ?? [], + ]; + + echo $this->renderView('customer_tab', $viewData); } public function onCustomerSaved(array $customerData): void diff --git a/app/Plugins/README.md b/app/Plugins/README.md index f3246ec03..92b22b92d 100644 --- a/app/Plugins/README.md +++ b/app/Plugins/README.md @@ -62,6 +62,26 @@ class MyPlugin extends BasePlugin } ``` +`BasePlugin` provides these protected helpers: + +| Method | Signature | Description | +|--------|-----------|-------------| +| `getSetting` | `(string $key, mixed $default = null): mixed` | Read one plugin setting | +| `setSetting` | `(string $key, mixed $value): bool` | Write one plugin setting | +| `log` | `(string $level, string $message): void` | Write to CI4 log with plugin prefix | +| `renderView` | `(string $viewName, array $data = []): string` | Render a view from the plugin's own `Views/` directory | + +#### `renderView()` + +Resolves views relative to the plugin's own namespace, so you pass only the bare view name — no path prefix needed: + +```php +// Renders App\Plugins\MyPlugin\Views\customer_tab.php +echo $this->renderView('customer_tab', $data); +``` + +The method derives the namespace from `get_class($this)`, so it works automatically for any plugin that follows the standard directory layout. Use it inside view-hook callbacks (with `echo`) or anywhere a rendered HTML string is needed. + ### Plugin Manager The `PluginManager` class handles: @@ -128,16 +148,16 @@ class ExamplePlugin extends BasePlugin Events::on('view:customer_tabs', [$this, 'injectCustomerTab']); } - public function injectCustomerTab(array $data): string + public function injectCustomerTab(array $data): void { - return view('Plugins/ExamplePlugin/Views/customer_tab', $data); + echo $this->renderView('customer_tab', $data); } } ``` ### Plugin View Files -The plugin's view files are self-contained within the plugin directory: +Plugin view files live in the plugin's `Views/` subdirectory. `renderView('customer_tab', $data)` resolves to `app/Plugins/ExamplePlugin/Views/customer_tab.php`: ```php // app/Plugins/ExamplePlugin/Views/customer_tab.php diff --git a/app/Views/customers/form.php b/app/Views/customers/form.php index 375988335..93e9b79d3 100644 --- a/app/Views/customers/form.php +++ b/app/Views/customers/form.php @@ -25,11 +25,7 @@ - -
  • - -
  • - + $person_info]) ?>
    @@ -327,9 +323,7 @@
    - - $customer]) ?> - + $person_info]) ?>