PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/base/CComponent.php

https://bitbucket.org/stden/yiiru
PHP | 682 lines | 294 code | 30 blank | 358 comment | 81 complexity | a21f179fb7a83251e036d0641ba99938 MD5 | raw file
  1. <?php
  2. /**
  3. * Файл содержит базовые классы для комопнентно-ориентированного и событийно-управляемого программирования.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CComponent - это базовый класс для всех компонентов.
  12. *
  13. * CComponent реализует протокол определения и использования свойств и событий.
  14. *
  15. * Свойство определяется методом-получателем (геттер, getter) и/или методом-установщиком (сеттер, setter).
  16. * Доступ к свойству можно получить как к обычному члену объекта.
  17. * Чтение или запись свойства приводит к вызову соответствующего геттера или сеттера, например,
  18. * <pre>
  19. * $a=$component->text; // эквивалентно $a=$component->getText();
  20. * $component->text='abc'; // эквивалентно $component->setText('abc');
  21. * </pre>
  22. * Структура геттера и сеттера такова:
  23. * <pre>
  24. * // геттер, определяет читаемое свойство 'text'
  25. * public function getText() { ... }
  26. * // сеттер, определяет записываемое свойство 'text' со значением $value
  27. * public function setText($value) { ... }
  28. * </pre>
  29. *
  30. * Событие определяется методом с именем, начинающимся с 'on'.
  31. * Имя события - это имя метода. При появлении события, автоматически будут вызываться функции
  32. * (называемые обработчиками событий), присоединенные к событию.
  33. *
  34. * Событие может вызываться методом {@link raiseEvent}, в котором
  35. * присоединенные обработчики события будут вызваны в порядке присоединения к событию.
  36. * Обработчики события должны иметь следующую структуру:
  37. * <pre>
  38. * function eventHandler($event) { ... }
  39. * </pre>
  40. * где $event включает параметры, ассоциированные с событием.
  41. *
  42. * Для присоединения обработчика к событию предназначен метод {@link attachEventHandler}.
  43. * Вы также можете использовать следующий синтаксис:
  44. * <pre>
  45. * $component->onClick=$callback; // или $component->onClick->add($callback);
  46. * </pre>
  47. * где $callback - валидный обратный вызов PHP. Ниже показаны примеры обратного вызова:
  48. * <pre>
  49. * 'handleOnClick' // handleOnClick() - глобальная функция
  50. * array($object,'handleOnClick') // использование $object->handleOnClick()
  51. * array('Page','handleOnClick') // использование Page::handleOnClick()
  52. * </pre>
  53. *
  54. * Для вызова события используется метод {@link raiseEvent}. 'on'-метод, определяющий событие
  55. * обычно пишется так:
  56. * <pre>
  57. * public function onClick($event)
  58. * {
  59. * $this->raiseEvent('onClick',$event);
  60. * }
  61. * </pre>
  62. * где <code>$event</code> - экземпляр класса {@link CEvent} или его потомков.
  63. * Теперь можно вызывать событие вызовом 'on'-метода напрямую вместо {@link raiseEvent}.
  64. *
  65. * Имена свойств и событий регистронезависимы.
  66. *
  67. * CComponent поддерживает поведения. Поведение - это
  68. * экземпляр класса, реализующего интерфейс {@link IBehavior}, присоединенный к компоненту.
  69. * Методы поведения могут быть вызваны так, как если бы они принадлежали компоненту. К одному
  70. * компоненту может быть присоединено несколько поведений.
  71. *
  72. * Для присоединения поведения к компоненту вызовите метод {@link attachBehavior}, а для отсоединения
  73. * поведения от компонента - метод {@link detachBehavior}.
  74. *
  75. * Поведение может временно быть включено или выключено вызовом методов {@link enableBehavior}
  76. * или {@link disableBehavior} соответственно. Если поведение отключено, его методы не могут
  77. * быть вызваны из компонента.
  78. *
  79. * Начиная с версии 1.1.0, свойства поведения (и открытые члены и свойства,
  80. * определяемые геттерами и/или сеттерами) доступны из компонента, к которому присоединено поведение.
  81. *
  82. * @author Qiang Xue <qiang.xue@gmail.com>
  83. * @version $Id: CComponent.php 3521 2011-12-29 22:10:57Z mdomba $
  84. * @package system.base
  85. * @since 1.0
  86. */
  87. class CComponent
  88. {
  89. private $_e;
  90. private $_m;
  91. /**
  92. * Возвращает значение свойства, список обработчиков события или поведение по имени.
  93. * Не вызывайте данный метод. Это "магический" метод PHP, который переопределяется,
  94. * чтобы можно было использовать следующий синтаксис для чтения свойства или получения обработчика события:
  95. * <pre>
  96. * $value=$component->propertyName;
  97. * $handlers=$component->eventName;
  98. * </pre>
  99. * @param string $name имя свойства или события
  100. * @return mixed значение свойства, обработчики события, присоединенные к событию, или именованное поведение (с версии 1.0.2)
  101. * @throws CException вызывается, если свойство или событие не определены
  102. * @see __set
  103. */
  104. public function __get($name)
  105. {
  106. $getter='get'.$name;
  107. if(method_exists($this,$getter))
  108. return $this->$getter();
  109. else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  110. {
  111. // duplicating getEventHandlers() here for performance
  112. $name=strtolower($name);
  113. if(!isset($this->_e[$name]))
  114. $this->_e[$name]=new CList;
  115. return $this->_e[$name];
  116. }
  117. else if(isset($this->_m[$name]))
  118. return $this->_m[$name];
  119. else if(is_array($this->_m))
  120. {
  121. foreach($this->_m as $object)
  122. {
  123. if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
  124. return $object->$name;
  125. }
  126. }
  127. throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
  128. array('{class}'=>get_class($this), '{property}'=>$name)));
  129. }
  130. /**
  131. * Устанавливает значение свойства компонента.
  132. * Не вызывайте данный метод. Это "магический" метод PHP, который переопределяется,
  133. * чтобы можно было использовать следующий синтаксис для установки свойства или присоединения обработчика события:
  134. * <pre>
  135. * $this->propertyName=$value;
  136. * $this->eventName=$callback;
  137. * </pre>
  138. * @param string $name имя свойства или события
  139. * @param mixed $value значение свойства или обратный вызов
  140. * @return mixed
  141. * @throws CException вызывается, если свойство/событие не определены или свойство является свойством только для чтения.
  142. * @see __get
  143. */
  144. public function __set($name,$value)
  145. {
  146. $setter='set'.$name;
  147. if(method_exists($this,$setter))
  148. return $this->$setter($value);
  149. else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  150. {
  151. // duplicating getEventHandlers() here for performance
  152. $name=strtolower($name);
  153. if(!isset($this->_e[$name]))
  154. $this->_e[$name]=new CList;
  155. return $this->_e[$name]->add($value);
  156. }
  157. else if(is_array($this->_m))
  158. {
  159. foreach($this->_m as $object)
  160. {
  161. if($object->getEnabled() && (property_exists($object,$name) || $object->canSetProperty($name)))
  162. return $object->$name=$value;
  163. }
  164. }
  165. if(method_exists($this,'get'.$name))
  166. throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
  167. array('{class}'=>get_class($this), '{property}'=>$name)));
  168. else
  169. throw new CException(Yii::t('yii','Property "{class}.{property}" is not defined.',
  170. array('{class}'=>get_class($this), '{property}'=>$name)));
  171. }
  172. /**
  173. * Проверяет, нулевое (null) ли значение свойства.
  174. * Не вызывайте данный метод. Это "магический" метод PHP, который переопределяется,
  175. * чтобы можно было использовать фукцию isset() для определения, установлено свойство компонента или нет.
  176. * @param string $name имя свойства или события
  177. * @return boolean
  178. */
  179. public function __isset($name)
  180. {
  181. $getter='get'.$name;
  182. if(method_exists($this,$getter))
  183. return $this->$getter()!==null;
  184. else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  185. {
  186. $name=strtolower($name);
  187. return isset($this->_e[$name]) && $this->_e[$name]->getCount();
  188. }
  189. else if(is_array($this->_m))
  190. {
  191. if(isset($this->_m[$name]))
  192. return true;
  193. foreach($this->_m as $object)
  194. {
  195. if($object->getEnabled() && (property_exists($object,$name) || $object->canGetProperty($name)))
  196. return $object->$name!==null;
  197. }
  198. }
  199. return false;
  200. }
  201. /**
  202. * Устанавливает свойство компонента в null.
  203. * Не вызывайте данный метод. Это "магический" метод PHP, который переопределяется,
  204. * чтобы можно было использовать фукцию unset() для установки свойства компонента в null.
  205. * @param string $name имя свойства или события
  206. * @throws CException вызывается, если свойство является свойством только для чтения
  207. * @return mixed
  208. */
  209. public function __unset($name)
  210. {
  211. $setter='set'.$name;
  212. if(method_exists($this,$setter))
  213. $this->$setter(null);
  214. else if(strncasecmp($name,'on',2)===0 && method_exists($this,$name))
  215. unset($this->_e[strtolower($name)]);
  216. else if(is_array($this->_m))
  217. {
  218. if(isset($this->_m[$name]))
  219. $this->detachBehavior($name);
  220. else
  221. {
  222. foreach($this->_m as $object)
  223. {
  224. if($object->getEnabled())
  225. {
  226. if(property_exists($object,$name))
  227. return $object->$name=null;
  228. else if($object->canSetProperty($name))
  229. return $object->$setter(null);
  230. }
  231. }
  232. }
  233. }
  234. else if(method_exists($this,'get'.$name))
  235. throw new CException(Yii::t('yii','Property "{class}.{property}" is read only.',
  236. array('{class}'=>get_class($this), '{property}'=>$name)));
  237. }
  238. /**
  239. * Вызывает именованный метод, не являющийся методом класса.
  240. * Не вызывайте данный метод. Это "магический" метод PHP, который переопределяется
  241. * для реализации функции поведения.
  242. * @param string $name имя метода
  243. * @param array $parameters параметры метода
  244. * @return mixed значение, возвращаемое методом
  245. */
  246. public function __call($name,$parameters)
  247. {
  248. if($this->_m!==null)
  249. {
  250. foreach($this->_m as $object)
  251. {
  252. if($object->getEnabled() && method_exists($object,$name))
  253. return call_user_func_array(array($object,$name),$parameters);
  254. }
  255. }
  256. if(class_exists('Closure', false) && $this->canGetProperty($name) && $this->$name instanceof Closure)
  257. return call_user_func_array($this->$name, $parameters);
  258. throw new CException(Yii::t('yii','{class} and its behaviors do not have a method or closure named "{name}".',
  259. array('{class}'=>get_class($this), '{name}'=>$name)));
  260. }
  261. /**
  262. * Возвращает объект именованного поведения.
  263. * Имя 'asa' означает 'as a'.
  264. * @param string $behavior имя поведения
  265. * @return IBehavior объект поведения; null, если поведение не существует
  266. */
  267. public function asa($behavior)
  268. {
  269. return isset($this->_m[$behavior]) ? $this->_m[$behavior] : null;
  270. }
  271. /**
  272. * Присоединяет список поведений к компоненту.
  273. * Поведения индексированы по имени и должны быть экземплярами классов, реализующих интерфейс
  274. * {@link IBehavior}, строкой, определяющих класс поведения или
  275. * массивом со следующей структурой:
  276. * <pre>
  277. * array(
  278. * 'class'=>'путь.к.BehaviorClass',
  279. * 'property1'=>'value1',
  280. * 'property2'=>'value2',
  281. * )
  282. * </pre>
  283. * @param array $behaviors список присоединяемых к компоненту поведений
  284. */
  285. public function attachBehaviors($behaviors)
  286. {
  287. foreach($behaviors as $name=>$behavior)
  288. $this->attachBehavior($name,$behavior);
  289. }
  290. /**
  291. * Отсоединяет все поведения от компонента
  292. */
  293. public function detachBehaviors()
  294. {
  295. if($this->_m!==null)
  296. {
  297. foreach($this->_m as $name=>$behavior)
  298. $this->detachBehavior($name);
  299. $this->_m=null;
  300. }
  301. }
  302. /**
  303. * Присоединяет поведение к компоненту.
  304. * Метод создает объект поведения на основе переданной конфигурации.
  305. * После этого объект поведения инициализируется
  306. * вызовом его метода {@link IBehavior::attach}.
  307. * @param string $name имя поведения. Должен уникально идентифицировать данное поведение.
  308. * @param mixed $behavior конфигурация поведения. Передается первым параметром
  309. * в метод {@link YiiBase::createComponent} для создания объекта поведения.
  310. * @return IBehavior объект поведения
  311. */
  312. public function attachBehavior($name,$behavior)
  313. {
  314. if(!($behavior instanceof IBehavior))
  315. $behavior=Yii::createComponent($behavior);
  316. $behavior->setEnabled(true);
  317. $behavior->attach($this);
  318. return $this->_m[$name]=$behavior;
  319. }
  320. /**
  321. * Отсоединяет поведение от компонента.
  322. * Вызывается метод {@link IBehavior::detach} поведения.
  323. * @param string $name имя поведения. Уникально идентифицирует поведение
  324. * @return IBehavior отсоединенное поведение. Null, если поведение не существует
  325. */
  326. public function detachBehavior($name)
  327. {
  328. if(isset($this->_m[$name]))
  329. {
  330. $this->_m[$name]->detach($this);
  331. $behavior=$this->_m[$name];
  332. unset($this->_m[$name]);
  333. return $behavior;
  334. }
  335. }
  336. /**
  337. * Включает все поведения, присоединенные к компоненту
  338. */
  339. public function enableBehaviors()
  340. {
  341. if($this->_m!==null)
  342. {
  343. foreach($this->_m as $behavior)
  344. $behavior->setEnabled(true);
  345. }
  346. }
  347. /**
  348. * Отключает все поведения, присоединенные к компоненту
  349. */
  350. public function disableBehaviors()
  351. {
  352. if($this->_m!==null)
  353. {
  354. foreach($this->_m as $behavior)
  355. $behavior->setEnabled(false);
  356. }
  357. }
  358. /**
  359. * Включает присоединенное поведение.
  360. * Поведение имеет действие только если включено.
  361. * При первом присоединении поведение включено.
  362. * @param string $name имя поведения. Уникально идентифицирует поведение
  363. */
  364. public function enableBehavior($name)
  365. {
  366. if(isset($this->_m[$name]))
  367. $this->_m[$name]->setEnabled(true);
  368. }
  369. /**
  370. * Откючает присоединенное поведение.
  371. * Поведение имеет действие только если включено.
  372. * @param string $name имя поведения. Уникально идентифицирует поведение
  373. */
  374. public function disableBehavior($name)
  375. {
  376. if(isset($this->_m[$name]))
  377. $this->_m[$name]->setEnabled(false);
  378. }
  379. /**
  380. * Показывает, определено ли свойство.
  381. * Свойство определено, если для него в классе есть методы геттер и сеттер.
  382. * Примечание: имена свойств регистронезависимы.
  383. * @param string $name имя свойства
  384. * @return boolean определено ли свойство
  385. * @see canGetProperty
  386. */
  387. public function hasProperty($name)
  388. {
  389. return method_exists($this,'get'.$name) || method_exists($this,'set'.$name);
  390. }
  391. /**
  392. * Определяет, может ли свойство быть прочитано.
  393. * Свойство читаемо, если класс имеет метод геттер для данного имени свойства.
  394. * Примечание: имена свойств регистронезависимы.
  395. * @param string $name имя свойства
  396. * @return boolean может ли свойство быть прочитано
  397. * @see canSetProperty
  398. */
  399. public function canGetProperty($name)
  400. {
  401. return method_exists($this,'get'.$name);
  402. }
  403. /**
  404. * Определяет, может ли свойство быть установлено (записываемое ли).
  405. * Свойство записываемое, если класс имеет метод гсттер для данного имени свойства.
  406. * Примечание: имена свойств регистронезависимы.
  407. * @param string $name имя свойства
  408. * @return boolean может ли свойство быть установлено (записываемое ли)
  409. * @see canGetProperty
  410. */
  411. public function canSetProperty($name)
  412. {
  413. return method_exists($this,'set'.$name);
  414. }
  415. /**
  416. * Показывает, определено ли событие.
  417. * Событие определено, если класс имеет метод с именем вида 'onXXX'.
  418. * Примечание: имена событий регистронезависимы.
  419. * @param string $name имя события
  420. * @return boolean определено ли событие
  421. */
  422. public function hasEvent($name)
  423. {
  424. return !strncasecmp($name,'on',2) && method_exists($this,$name);
  425. }
  426. /**
  427. * Проверяет, есть ли у именованного события присоединенные обработчики.
  428. * @param string $name имя события
  429. * @return boolean есть ли у события присоединенные обработчики
  430. */
  431. public function hasEventHandler($name)
  432. {
  433. $name=strtolower($name);
  434. return isset($this->_e[$name]) && $this->_e[$name]->getCount()>0;
  435. }
  436. /**
  437. * Возвращает список присоединенных обработчиков для события.
  438. * @param string $name имя события
  439. * @return CList список присоединенных обработчиков для события
  440. * @throws CException вызывается, если событие не определено
  441. */
  442. public function getEventHandlers($name)
  443. {
  444. if($this->hasEvent($name))
  445. {
  446. $name=strtolower($name);
  447. if(!isset($this->_e[$name]))
  448. $this->_e[$name]=new CList;
  449. return $this->_e[$name];
  450. }
  451. else
  452. throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
  453. array('{class}'=>get_class($this), '{event}'=>$name)));
  454. }
  455. /**
  456. * Присоединяет обработчик к событию.
  457. *
  458. * Обработчик события должен быть допустимым обратным вызовом PHP, т.е. строкой с именем глобальной функции
  459. * или массивом, содержащим два элемента, где первый элемент - объект, а второй -
  460. * имя метода объекта.
  461. *
  462. * Обработчик события должен иметь следующую структуру:
  463. * <pre>
  464. * function handlerName($event) {}
  465. * </pre>
  466. * где $event включает параметры, ассоциированные с событием.
  467. *
  468. * Это простой метод присоединения обработчика к событию.
  469. * Он эквивалентен следующему коду:
  470. * <pre>
  471. * $component->getEventHandlers($eventName)->add($eventHandler);
  472. * </pre>
  473. *
  474. * Используя метод {@link getEventHandlers} можно также определить последовательность
  475. * выполнения нескольких обработчиков, присоединенных к одному событию. Например, код
  476. * <pre>
  477. * $component->getEventHandlers($eventName)->insertAt(0,$eventHandler);
  478. * </pre>
  479. * устанавливает, что обработчик будет выполняться первым.
  480. *
  481. * @param string $name имя события
  482. * @param callback $handler обработчик события
  483. * @throws CException вызывается, если событие не определено
  484. * @see detachEventHandler
  485. */
  486. public function attachEventHandler($name,$handler)
  487. {
  488. $this->getEventHandlers($name)->add($handler);
  489. }
  490. /**
  491. * Отсоединяет существующий обработчик события.
  492. * Метод противоположен методу {@link attachEventHandler}.
  493. * @param string $name имя события
  494. * @param callback $handler удаляемый обработчик события
  495. * @return boolean успешен ли процесс отсоединения обработчика
  496. * @see attachEventHandler
  497. */
  498. public function detachEventHandler($name,$handler)
  499. {
  500. if($this->hasEventHandler($name))
  501. return $this->getEventHandlers($name)->remove($handler)!==false;
  502. else
  503. return false;
  504. }
  505. /**
  506. * Выполняет (запускает) событие.
  507. * Метод представляет собой наступление события. Он выполняет
  508. * все присоединенные к событию обработчики.
  509. * @param string $name имя события
  510. * @param CEvent $event параметр события
  511. * @throws CException вызывается, если событие неопределено или обработчик события является допустимым.
  512. */
  513. public function raiseEvent($name,$event)
  514. {
  515. $name=strtolower($name);
  516. if(isset($this->_e[$name]))
  517. {
  518. foreach($this->_e[$name] as $handler)
  519. {
  520. if(is_string($handler))
  521. call_user_func($handler,$event);
  522. else if(is_callable($handler,true))
  523. {
  524. if(is_array($handler))
  525. {
  526. // an array: 0 - object, 1 - method name
  527. list($object,$method)=$handler;
  528. if(is_string($object)) // static method call
  529. call_user_func($handler,$event);
  530. else if(method_exists($object,$method))
  531. $object->$method($event);
  532. else
  533. throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
  534. array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>$handler[1])));
  535. }
  536. else // PHP 5.3: anonymous function
  537. call_user_func($handler,$event);
  538. }
  539. else
  540. throw new CException(Yii::t('yii','Event "{class}.{event}" is attached with an invalid handler "{handler}".',
  541. array('{class}'=>get_class($this), '{event}'=>$name, '{handler}'=>gettype($handler))));
  542. // stop further handling if param.handled is set true
  543. if(($event instanceof CEvent) && $event->handled)
  544. return;
  545. }
  546. }
  547. else if(YII_DEBUG && !$this->hasEvent($name))
  548. throw new CException(Yii::t('yii','Event "{class}.{event}" is not defined.',
  549. array('{class}'=>get_class($this), '{event}'=>$name)));
  550. }
  551. /**
  552. * Выполняет выражение PHP или обратный вызов в контексте данного компонента.
  553. *
  554. * Допустимый обратный вызов PHP - это имя метода класса в формате
  555. * array(ClassName/Object, MethodName) или анонимная функция (доступно только в PHP 5.3.0 или выше).
  556. *
  557. * Если используется обратный вызов PHP, структура соответствующих функции/метода должна быть такой:
  558. * <pre>
  559. * function foo($param1, $param2, ..., $component) { ... }
  560. * </pre>
  561. * где элементы массива второго параметра данного метода будут переданы в обратный вызов как параметры
  562. * $param1, $param2, ..., а последний параметр является самим компонентом.
  563. *
  564. * Если используется выражение PHP, второй параметр будет "распакован" в переменные PHP,
  565. * которые могут быть непосредственно использованы в выражении. За деталями обратитесь
  566. * к функции {@link http://us.php.net/manual/en/function.extract.php PHP extract}.
  567. * Объект компонента доступен в выражении посредством $this.
  568. *
  569. * @param mixed $_expression_ выражение PHP или обратный вызов PHP для выполнения
  570. * @param array $_data_ дополнительные параметры, передаваемые в выражение/обратный вызов
  571. * @return mixed результат выражения
  572. * @since 1.1.0
  573. */
  574. public function evaluateExpression($_expression_,$_data_=array())
  575. {
  576. if(is_string($_expression_))
  577. {
  578. extract($_data_);
  579. return eval('return '.$_expression_.';');
  580. }
  581. else
  582. {
  583. $_data_[]=$this;
  584. return call_user_func_array($_expression_, $_data_);
  585. }
  586. }
  587. }
  588. /**
  589. * CEvent - это базовый класс для всех классов событий.
  590. *
  591. * Инкапсулирует параметры, ассоциированные с событием.
  592. * Свойство {@link sender} объявляет, кто запускает событие.
  593. * Свойство {@link handled} показывает, обработано ли событие.
  594. * Если обработчик события устанавливает свойство {@link handled} в true, то последущие
  595. * еще не выполненные обработчики выполняться не будут.
  596. *
  597. * @author Qiang Xue <qiang.xue@gmail.com>
  598. * @version $Id: CComponent.php 3521 2011-12-29 22:10:57Z mdomba $
  599. * @package system.base
  600. * @since 1.0
  601. */
  602. class CEvent extends CComponent
  603. {
  604. /**
  605. * @var object отправитель события
  606. */
  607. public $sender;
  608. /**
  609. * @var boolean обработано ли событие. По умолчанию - false.
  610. * Когда обработчик устанавливает даное свойство в true, последующие невыполненные обработчики не будут выполняться.
  611. */
  612. public $handled=false;
  613. /**
  614. * @var mixed дополнительные параметры события
  615. * @since 1.1.7
  616. */
  617. public $params;
  618. /**
  619. * Конструктор.
  620. * @param mixed $sender отправитель события
  621. * @param mixed $params дополнительные параметры события
  622. */
  623. public function __construct($sender=null,$params=null)
  624. {
  625. $this->sender=$sender;
  626. $this->params=$params;
  627. }
  628. }
  629. /**
  630. * CEnumerable - это базовый класс для всех перечисляемых типов.
  631. *
  632. * Для определения перечисляемого типа, отнаследуйте класс CEnumberable и определите строковые константы.
  633. * Каждая константа представляет собой перечисляемое значение.
  634. * Имя константы должно быть таким же, как и ее значение.
  635. * Например,
  636. * <pre>
  637. * class TextAlign extends CEnumerable
  638. * {
  639. * const Left='Left';
  640. * const Right='Right';
  641. * }
  642. * </pre>
  643. * Тогда можно использовать перечисляемые значения так - TextAlign::Left и TextAlign::Right.
  644. *
  645. * @author Qiang Xue <qiang.xue@gmail.com>
  646. * @version $Id: CComponent.php 3521 2011-12-29 22:10:57Z mdomba $
  647. * @package system.base
  648. * @since 1.0
  649. */
  650. class CEnumerable
  651. {
  652. }