123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- <?php
- /* For licensing terms, see /license.txt */
- /**
- * @TODO: Improve description
- *
- * @package chamilo.hookmanagement
- */
- class HookManagement implements HookManagementInterface
- {
- /**
- * Constructor.
- */
- protected function __construct()
- {
- $this->tables[TABLE_HOOK_OBSERVER] = Database::get_main_table(TABLE_HOOK_OBSERVER);
- $this->tables[TABLE_HOOK_EVENT] = Database::get_main_table(TABLE_HOOK_EVENT);
- $this->tables[TABLE_HOOK_CALL] = Database::get_main_table(TABLE_HOOK_CALL);
- $this->hookCalls = $this->listAllHookCalls();
- $this->hookEvents = $this->listAllHookEvents();
- $this->hookObservers = $this->listAllHookObservers();
- }
- /**
- * Instance the hook manager.
- *
- * @staticvar null $result
- *
- * @return HookManagement
- */
- public static function create()
- {
- static $result = null;
- return $result ? $result : $result = new self();
- }
- /**
- * Insert hook into Database. Return insert id.
- *
- * @param string $eventName
- * @param string $observerClassName
- * @param int $type
- *
- * @return int
- */
- public function insertHook($eventName, $observerClassName, $type)
- {
- if ($type === HOOK_EVENT_TYPE_ALL) {
- $this->insertHook($eventName, $observerClassName, HOOK_EVENT_TYPE_PRE);
- $this->insertHook($eventName, $observerClassName, HOOK_EVENT_TYPE_POST);
- } else {
- $this->insertHookIfNotExist($eventName, $observerClassName);
- // Check if exists hook call
- $row = Database::select(
- 'id, enabled',
- $this->tables[TABLE_HOOK_CALL],
- [
- 'where' => [
- 'hook_event_id = ? ' => $this->hookEvents[$eventName],
- 'AND hook_observer_id = ? ' => $this->hookObservers[$observerClassName],
- 'AND type = ? ' => $type,
- ],
- ],
- 'ASSOC'
- );
- if (!empty($row) && is_array($row)) {
- // Check if is hook call is active
- if ((int) $row['enabled'] === 0) {
- Database::update(
- $this->tables[TABLE_HOOK_CALL],
- [
- 'enabled' => 1,
- ],
- [
- 'id = ?' => $row['id'],
- ]
- );
- }
- }
- }
- }
- /**
- * Delete hook from Database. Return deleted rows number.
- *
- * @param string $eventName
- * @param string $observerClassName
- * @param int $type
- *
- * @return int
- */
- public function deleteHook($eventName, $observerClassName, $type)
- {
- if ($type === HOOK_EVENT_TYPE_ALL) {
- $this->deleteHook($eventName, $observerClassName, HOOK_EVENT_TYPE_PRE);
- $this->deleteHook($eventName, $observerClassName, HOOK_EVENT_TYPE_POST);
- } else {
- $this->insertHookIfNotExist($eventName, $observerClassName);
- Database::update(
- $this->tables[TABLE_HOOK_CALL],
- [
- 'enabled' => 0,
- ],
- [
- 'id = ? ' => $this->hookCalls[$eventName][$observerClassName][$type],
- ]
- );
- }
- }
- /**
- * Update hook observer order by hook event.
- *
- * @param $eventName
- * @param $type
- * @param $hookOrders
- *
- * @return int
- */
- public function orderHook($eventName, $type, $hookOrders)
- {
- foreach ($this->hookCalls[$eventName] as $observerClassName => $types) {
- foreach ($hookOrders as $oldOrder => $newOrder) {
- $res = Database::update(
- $this->tables[TABLE_HOOK_CALL],
- [
- 'hook_order ' => $newOrder,
- ],
- [
- 'id = ? ' => $types[$type],
- 'AND hook_order = ? ' => $oldOrder,
- ]
- );
- if ($res) {
- break;
- }
- }
- }
- }
- /**
- * Return a list an associative array where keys are the active hook observer class name.
- *
- * @param string $eventName
- *
- * @return array
- */
- public function listHookObservers($eventName)
- {
- $array = [];
- $joinTable = $this->tables[TABLE_HOOK_CALL].' hc'.
- ' INNER JOIN '.$this->tables[TABLE_HOOK_EVENT].' he'.
- ' ON hc.hook_event_id = he.id '.
- ' INNER JOIN '.$this->tables[TABLE_HOOK_OBSERVER].' ho '.
- ' ON hc.hook_observer_id = ho.id ';
- $columns = 'ho.class_name, ho.path, ho.plugin_name, hc.enabled';
- $where = ['where' => ['he.class_name = ? ' => $eventName, 'AND hc.enabled = ? ' => 1]];
- $rows = Database::select($columns, $joinTable, $where);
- foreach ($rows as $row) {
- $array[$row['class_name']] = $row;
- }
- return $array;
- }
- /**
- * Return a list an associative array where keys are the active hook observer class name.
- *
- * @return array
- */
- public function listAllHookObservers()
- {
- $array = [];
- $columns = 'id, class_name';
- $rows = Database::select($columns, $this->tables[TABLE_HOOK_OBSERVER]);
- foreach ($rows as $row) {
- $array[$row['class_name']] = $row['id'];
- }
- return $array;
- }
- /**
- * Return a list an associative array where keys are the active hook observer class name.
- *
- * @return array
- */
- public function listAllHookEvents()
- {
- $array = [];
- $columns = 'id, class_name';
- $rows = Database::select($columns, $this->tables[TABLE_HOOK_EVENT]);
- foreach ($rows as $row) {
- $array[$row['class_name']] = $row['id'];
- }
- return $array;
- }
- /**
- * Return a list an associative array where keys are the active hook observer class name.
- *
- * @return array
- */
- public function listAllHookCalls()
- {
- $array = [];
- $joinTable = $this->tables[TABLE_HOOK_CALL].' hc'.
- ' INNER JOIN '.$this->tables[TABLE_HOOK_EVENT].' he'.
- ' ON hc.hook_event_id = he.id '.
- ' INNER JOIN '.$this->tables[TABLE_HOOK_OBSERVER].' ho '.
- ' ON hc.hook_observer_id = ho.id ';
- $columns = 'he.class_name AS event_class_name, ho.class_name AS observer_class_name, hc.id AS id, hc.type AS type';
- $rows = Database::select($columns, $joinTable);
- foreach ($rows as $row) {
- $array[$row['event_class_name']][$row['observer_class_name']][$row['type']] = $row['id'];
- }
- return $array;
- }
- /**
- * Check if hooks (event, observer, call) exist in Database, if not,
- * Will insert them into their respective table.
- *
- * @param string $eventName
- * @param string $observerClassName
- *
- * @return int
- */
- public function insertHookIfNotExist($eventName = null, $observerClassName = null)
- {
- // Check if exists hook event
- if (isset($eventName) && !isset($this->hookEvents[$eventName])) {
- $attributes = [
- 'class_name' => $eventName,
- 'description' => get_lang('HookDescription'.$eventName),
- ];
- $id = Database::insert($this->tables[TABLE_HOOK_EVENT], $attributes);
- $this->hookEvents[$eventName] = $id;
- }
- // Check if exists hook observer
- if (isset($observerClassName) &&
- !isset($this->hookObservers[$observerClassName])
- ) {
- $object = $observerClassName::create();
- $attributes = [
- 'class_name' => $observerClassName,
- 'path' => $object->getPath(),
- 'plugin_name' => $object->getPluginName(),
- ];
- $id = Database::insert($this->tables[TABLE_HOOK_OBSERVER], $attributes);
- $this->hookObservers[$observerClassName] = $id;
- }
- if (isset($eventName) &&
- isset($observerClassName) &&
- !isset($this->hookCalls[$eventName][$observerClassName])
- ) {
- // HOOK TYPE PRE
- $row = Database::select(
- 'MAX(hook_order) as hook_order',
- $this->tables[TABLE_HOOK_CALL],
- [
- 'where' => [
- 'hook_event_id = ? ' => $this->hookEvents[$eventName],
- 'AND type = ? ' => HOOK_EVENT_TYPE_PRE,
- ],
- ],
- 'ASSOC'
- );
- // Check if exists hook call
- $id = Database::insert(
- $this->tables[TABLE_HOOK_CALL],
- [
- 'hook_event_id' => $this->hookEvents[$eventName],
- 'hook_observer_id' => $this->hookObservers[$observerClassName],
- 'type' => HOOK_EVENT_TYPE_PRE,
- 'enabled' => 0,
- 'hook_order' => $row['hook_order'] + 1,
- ]
- );
- $this->hookCalls[$eventName][$observerClassName][HOOK_EVENT_TYPE_PRE] = $id;
- // HOOK TYPE POST
- $row = Database::select(
- 'MAX(hook_order) as hook_order',
- $this->tables[TABLE_HOOK_CALL],
- [
- 'where' => [
- 'hook_event_id = ? ' => $this->hookEvents[$eventName],
- 'AND type = ? ' => HOOK_EVENT_TYPE_POST,
- ],
- ],
- 'ASSOC'
- );
- // Check if exists hook call
- $id = Database::insert(
- $this->tables[TABLE_HOOK_CALL],
- [
- 'hook_event_id' => $this->hookEvents[$eventName],
- 'hook_observer_id' => $this->hookObservers[$observerClassName],
- 'type' => HOOK_EVENT_TYPE_POST,
- 'enabled' => 0,
- 'hook_order' => $row['hook_order'] + 1,
- ]
- );
- $this->hookCalls[$eventName][$observerClassName][HOOK_EVENT_TYPE_POST] = $id;
- } elseif (isset($eventName) && !isset($observerClassName)) {
- foreach ($this->hookObservers as $observer => $id) {
- $this->insertHookIfNotExist($eventName, $observer);
- }
- } elseif (!isset($eventName) && isset($observerClassName)) {
- foreach ($this->hookEvents as $event => $id) {
- $this->insertHookIfNotExist($event, $observerClassName);
- }
- }
- return 1;
- }
- /**
- * Return the hook call id identified by hook event, hook observer and type.
- *
- * @param string $eventName
- * @param string $observerClassName
- * @param int $type
- *
- * @return mixed
- */
- public function getHookCallId($eventName, $observerClassName, $type)
- {
- $eventName = Database::escape_string($eventName);
- $observerClassName($observerClassName);
- $type = Database::escape_string($type);
- $joinTable = $this->tables[TABLE_HOOK_CALL].' hc'.
- ' INNER JOIN '.$this->tables[TABLE_HOOK_EVENT].' he'.
- ' ON hc.hook_event_id = he.id '.
- ' INNER JOIN '.$this->tables[TABLE_HOOK_OBSERVER].' ho '.
- ' ON hc.hook_observer_id = ho.id ';
- $row = Database::select(
- 'id',
- $joinTable,
- [
- 'where' => [
- 'he.class_name = ? ' => $eventName,
- 'AND ho.class_name = ? ' => $observerClassName,
- 'AND hc.type = ? ' => $type,
- ],
- ],
- 'ASSOC'
- );
- return $row['id'];
- }
- }
|