زند فریم ورک 2 – مثالی در رابطه با Event Manager
در مطلب مربوط به زند فریم ورک ۲ – Event Manager در رابطه با Event Manager بحث کردیم. اما در این مطلب یک مثال کاربردی از این الگو را نمایش خواهیم داد. در یکی از پروژه هایی که کار کردم نیاز بود که تمام ورود های کاربران بر اساس زمان ورود آنها در سیستم ثبت شده و در نهایت گزارشی از این اطلاعات تهیه شود. در این مورد از Event Manager استفاده کردم تا رویدادی را با نام auth.login ایجاد نمایم و با استفاده از listener کار ثبت اطلاعات را در پایگاه داده انجام دهم.
ابتدا ماژولی با نام ActivityLog ایجاد کرده و سپس کلاسی با نام LogEventManager برای مدیریت رویداد مورد نظر ایجاد میکنیم که از EventManagerAwareInterface استفاده میکند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php namespace ActivityLog\Events; use Zend\EventManager\EventManagerAwareInterface; use Zend\EventManager\EventManagerInterface; class LogEventManager implements EventManagerAwareInterface { protected $events; public function setEventManager(EventManagerInterface $events) { $events->setIdentifiers(array( __CLASS__, get_class($this), )); $this->events = $events; } public function getEventManager() { return $this->events; } public function logAuthentication($data = array()) { $this->getEventManager()->trigger('auth.login', $this, $data); } } |
سپس یک Listener با نام LogEventListener ایجاد کرده تا هنگامی که رویداد مورد نظر رخ داد یکی از متد هایی که تنظیم کرده ایم اجرا شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php namespace ActivityLog\Events; use Zend\EventManager\ListenerAggregateInterface; use Zend\EventManager\EventManagerInterface; use Zend\Mvc\MvcEvent; use Zend\EventManager\EventInterface; use ActivityLog\Model\LogActivityTable; use Zend\ServiceManager\ServiceManager; class LogEventListener implements ListenerAggregateInterface { protected $listeners; protected $events; protected $serviceManager; public function __construct(ServiceManager $serviceManager) { $this->serviceManager = $serviceManager; } public function attach(EventManagerInterface $events) { $this->events = $events; $sharedEvents = $events->getSharedManager(); $this->listeners[] = $sharedEvents->attach('*' ,'auth.login', array($this, 'login'), 1000); } public function detach(EventManagerInterface $events) { foreach ($this->listeners as $index => $listener) { if ($events->detach($listener)) { unset($this->listeners[$index]); } } } public function login(EventInterface $event) { $userData = $event->getParams(); // Get adapter service // $dbAdapter = $this->serviceManager->get('Zend\Db\Adapter'); $logActivityTable = new LogActivityTable(); $logActivityTable->addLog('auth.login', $userData->id); return; } } |
با این روش listener مربوطه با استفاده از SharedManager به سرویس مربوط به LogEventManager دسترسی خواهد داشت. اولین پارامتر متد attach کد مشخصه ی EventManager است که قبلا ایجاد کرده ایم. علامت * مشخص میکند که بر روی تمام مشخصه ها اجرا شود.
حال در فایل مربوط به تنظیمات ماژول کد های زیر را قرار می دهیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?php namespace ActivityLog; use Zend\Mvc\MvcEvent; use ActivityLog\Events\LogEventListener; class Module { public function onBootstrap(MvcEvent $event) { $eventManager = $event->getApplication()->getEventManager(); $eventManager->attachAggregate(new LogEventListener( $event->getApplication()->getServiceManager() )); } public function getConfig() { return include __DIR__ . '/config/module.config.php'; } public function getAutoloaderConfig() { return array( 'Zend\Loader\StandardAutoloader' => array( 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__ ), ), ); } public function getServiceConfig() { return array( 'invokables' => array( 'LogEventManager' => '\ActivityLog\Events\LogEventManager' ) ); } } |
با این روش امکان اینکه listener مربوطه بتواند به رویداد های دیگر نیز پاسخ دهد وجود دارد. در روشی که در مستندات زند فریم ورک بیان شده است شما از یک closure یا تابع بی نام به عنوان listener استفاده خواهید کرد. اما از نظر من با این روش کد مرتب تری خواهید داشت. حال در هر بخشی از هر ماژول که بخواهیم میتوانیم رویداد مورد نظر را فراخوانی و پارامتر های مورد نظر را در اختیار آن قرار دهیم.
1 |
$this->getServiceLocator()->get('LogEventManager')->logAuthentication($this->userData); |
در هر بخشی از هر ماژول که به SerciveManager دسترسی داشته باشیم میتوانیم با فراخوانی دستور بالا رویداد مربوطه را فراخوانی کرده و کنترل برنامه به Listener آن رویداد منتقل شود.
محمد باقر رستمی
Latest posts by محمد باقر رستمی (see all)
- ماژول ZF2Base - 18 دی, 1394
- Singleton Pattern - 26 شهریور, 1394
- Prototype Pattern - 13 مرداد, 1394
مطالب دیگر
ماژول ZF2Base
Singleton Pattern
Prototype Pattern
Factory Method Pattern
مفهوم SOLID در برنامه نویسی – DIP
Abstract Factory Pattern
Builder Pattern
الگوهای طراحی چیست؟
مفهوم SOLID در برنامه نویسی – ISP
مفهوم SOLID در برنامه نویسی – LSP