- 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 <objecttothis@gmail.com>
This commit is contained in:
objec
2026-04-30 14:11:54 +04:00
parent 939012dc1b
commit 4246a915c4
8 changed files with 67 additions and 27 deletions

View File

@@ -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) {

View File

@@ -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}"));
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -25,11 +25,7 @@
<a data-toggle="tab" href="#customer_stats_info"><?= lang('Customers.stats_info') ?></a>
</li>
<?php } ?>
<?php if (!empty($mailchimp_info) && !empty($mailchimp_activity)) { ?>
<li role="presentation">
<a data-toggle="tab" href="#customer_mailchimp_info"><?= lang('MailchimpPlugin.info') ?></a> <!-- This needs to be properly refactored so that it gets injected by the plugin mechanism, not here. -->
</li>
<?php } ?>
<?= pluginContent('customer_tab_nav', ['customer' => $person_info]) ?>
</ul>
<div class="tab-content">
@@ -327,9 +323,7 @@
</div>
<?php } ?>
<?php if (!empty($mailchimp_info) && !empty($mailchimp_activity)) { ?>
<?= pluginContent('customer_tabs', ['customer' => $customer]) ?>
<?php } ?>
<?= pluginContent('customer_tab_panels', ['customer' => $person_info]) ?>
</div>
<?= form_close() ?>