Файл: library/XenForo/Model/CodeEvent.php
Строк: 571
<?php
/**
* Model to work with code events.
*
* @package XenForo_CodeEvents
*/
class XenForo_Model_CodeEvent extends XenForo_Model
{
/**
* Gets all code events, ordered by their event IDs.
*
* @return array Format: [event id] => info
*/
public function getAllEvents()
{
return $this->fetchAllKeyed('
SELECT *
FROM xf_code_event
ORDER BY event_id
', 'event_id');
}
/**
* Gets all events that belong to an add-on, ordered by their event IDs.
*
* @param string $addOnId
*
* @return array Format: [event id] => info
*/
public function getEventsByAddOn($addOnId)
{
return $this->fetchAllKeyed('
SELECT *
FROM xf_code_event
WHERE addon_id = ?
ORDER BY event_id
', 'event_id', $addOnId);
}
/**
* Gets the specified code event based on its ID.
*
* @param string $id
*
* @return array|false
*/
public function getEventById($id)
{
return $this->_getDb()->fetchRow('
SELECT *
FROM xf_code_event
WHERE event_id = ?
', $id);
}
/**
* Gets multiple code events based on a list of IDs.
*
* @param array $ids Event IDs
*
* @return array Format: [event id] => info
*/
public function getEventsByIds(array $ids)
{
if (!$ids)
{
return array();
}
return $this->fetchAllKeyed('
SELECT *
FROM xf_code_event
WHERE event_id IN (' . $this->_getDb()->quote($ids) . ')
', 'event_id');
}
/**
* Gets all code events as key-value pair options.
*
* @return array Format: [event id] => event id
*/
public function getEventOptions()
{
return $this->_getDB()->fetchPairs('
SELECT event_id, event_id
FROM xf_code_event
ORDER BY event_id
');
}
/**
* Gets the file name for the development output.
*
* @return string
*/
public function getEventsDevelopmentFileName()
{
$config = XenForo_Application::get('config');
if (!$config->debug || !$config->development->directory)
{
return '';
}
return XenForo_Application::getInstance()->getRootDir()
. '/' . $config->development->directory . '/file_output/code_events.xml';
}
/**
* Determines if the option development file is writable. If the file
* does not exist, it checks whether the parent directory is writable.
*
* @param $fileName
*
* @return boolean
*/
public function canWriteEventsDevelopmentFile($fileName)
{
return file_exists($fileName) ? is_writable($fileName) : is_writable(dirname($fileName));
}
/**
* Gets the code events development XML data.
*
* @return DOMDocument
*/
public function getEventsDevelopmentXml()
{
$document = new DOMDocument('1.0', 'utf-8');
$document->formatOutput = true;
$rootNode = $document->createElement('code_events');
$document->appendChild($rootNode);
$this->appendEventsAddOnXml($rootNode, 'XenForo');
return $document;
}
/**
* Appends the code events XML for an add-on to a specified node.
*
* @param DOMElement $rootNode XML node to append data to as children
* @param string $addOnId Add-on to get data for
*/
public function appendEventsAddOnXml(DOMElement $rootNode, $addOnId)
{
$events = $this->getEventsByAddOn($addOnId);
$document = $rootNode->ownerDocument;
foreach ($events AS $event)
{
$eventNode = $document->createElement('event');
$eventNode->setAttribute('event_id', $event['event_id']);
$eventNode->appendChild($document->createCDATASection($event['description']));
$rootNode->appendChild($eventNode);
}
}
/**
* Deletes the code events that belong to the specified add-on.
*
* @param string $addOnId
*/
public function deleteEventsForAddOn($addOnId)
{
$db = $this->_getDb();
$db->delete('xf_code_event', 'addon_id = ' . $db->quote($addOnId));
}
/**
* Imports the code events development XML data.
*
* @param string $fileName File to read the XML from
*/
public function importEventsDevelopmentXml($fileName)
{
$document = new SimpleXMLElement($fileName, 0, true);
$this->importEventsAddOnXml($document, 'XenForo');
}
/**
* Imports the code events for an add-on.
*
* @param SimpleXMLElement $xml XML element pointing to the root of the event data
* @param string $addOnId Add-on to import for
*/
public function importEventsAddOnXml(SimpleXMLElement $xml, $addOnId)
{
$db = $this->_getDb();
XenForo_Db::beginTransaction($db);
$this->deleteEventsForAddOn($addOnId);
$xmlEvents = XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->event);
$eventIds = array();
foreach ($xmlEvents AS $event)
{
$eventIds[] = (string)$event['event_id'];
}
$events = $this->getEventsByIds($eventIds);
foreach ($xmlEvents AS $event)
{
$eventId = (string)$event['event_id'];
$dw = XenForo_DataWriter::create('XenForo_DataWriter_CodeEvent');
if (isset($events[$eventId]))
{
$dw->setExistingData($events[$eventId]);
}
$dw->bulkSet(array(
'event_id' => $eventId,
'description' => (string)$event,
'addon_id' => $addOnId
));
$dw->save();
}
XenForo_Db::commit($db);
}
/**
* Gets all event listeners, ordered by their event, grouped by the
* add-on they belong to.
*
* @return array Format: [addon id][event listener id] => info
*/
public function getEventListenersGroupedByAddOn()
{
$output = array();
foreach ($this->getAllEventListeners() AS $listener)
{
$output[$listener['addon_id']][$listener['event_listener_id']] = $listener;
}
return $output;
}
/**
* Gets an array of all event listeners, ordered by their event and execution order,
* keyed by event_listener_id
*
* @return array
*/
public function getAllEventListeners()
{
return $this->fetchAllKeyed('
SELECT *
FROM xf_code_event_listener
ORDER BY event_id, execute_order
', 'event_listener_id');
}
/**
* Gets the specified event listener.
*
* @param integer $id
*
* @return array|false
*/
public function getEventListenerById($id)
{
return $this->_getDb()->fetchRow('
SELECT *
FROM xf_code_event_listener
WHERE event_listener_id = ?
', $id);
}
/**
* Gets all event listeners for the specified add-on in event and execute order.
*
* @param string $addOnId
*
* @return array Format: [event listener id] => info
*/
public function getEventListenersByAddOn($addOnId)
{
return $this->fetchAllKeyed('
SELECT *
FROM xf_code_event_listener
WHERE addon_id = ?
ORDER BY event_id, execute_order
', 'event_listener_id', $addOnId);
}
/**
* Gets the event listener array that's used for the cache.
*
* @return array Format: [event id][hint][] => [callback class, callback method]
*/
public function getEventListenerArray()
{
$output = array();
$listenerResult = $this->_getDb()->query('
SELECT listener.event_id, listener.callback_class, listener.callback_method, listener.hint
FROM xf_code_event_listener AS listener
LEFT JOIN xf_addon AS addon ON
(addon.addon_id = listener.addon_id AND addon.active = 1)
WHERE listener.active = 1
AND (addon.addon_id IS NOT NULL OR listener.addon_id = '')
ORDER BY listener.event_id ASC, listener.execute_order
');
while ($listener = $listenerResult->fetch())
{
$hint = $listener['hint'] ? $listener['hint'] : '_';
$output[$listener['event_id']][$hint][] = array($listener['callback_class'], $listener['callback_method']);
}
return $output;
}
/**
* Gets the default event listener record.
*
* @return array
*/
public function getDefaultEventListener()
{
return array(
'event_listener_id' => 0,
'event_id' => '',
'execute_order' => 10,
'description' => '',
'callback_class' => '',
'callback_method' => '',
'active' => 1,
'hint' => '',
'addon_id' => null // must fail isset
);
}
/**
* Appends the code event listeners XML for an add-on to a specified node.
*
* @param DOMElement $rootNode XML node to append data to as children
* @param string $addOnId Add-on to get data for
*/
public function appendEventListenersAddOnXml(DOMElement $rootNode, $addOnId)
{
$document = $rootNode->ownerDocument;
$listeners = $this->getEventListenersByAddOn($addOnId);
foreach ($listeners AS $listener)
{
$listenerNode = $document->createElement('listener');
$listenerNode->setAttribute('event_id', $listener['event_id']);
$listenerNode->setAttribute('execute_order', $listener['execute_order']);
$listenerNode->setAttribute('callback_class', $listener['callback_class']);
$listenerNode->setAttribute('callback_method', $listener['callback_method']);
$listenerNode->setAttribute('active', $listener['active']);
$listenerNode->setAttribute('hint', $listener['hint']);
$listenerNode->setAttribute('description', $listener['description']);
$rootNode->appendChild($listenerNode);
}
}
/**
* Deletes the code event listeners that belong to the specified add-on.
*
* @param string $addOnId
*/
public function deleteEventListenersForAddOn($addOnId)
{
$db = $this->_getDb();
$db->delete('xf_code_event_listener', 'addon_id = ' . $db->quote($addOnId));
}
/**
* Imports the code event listeners for an add-on.
*
* @param SimpleXMLElement $xml XML element pointing to the root of the listeners data
* @param string $addOnId Add-on to import for
*/
public function importEventListenersAddOnXml(SimpleXMLElement $xml, $addOnId)
{
$db = $this->_getDb();
XenForo_Db::beginTransaction($db);
$this->deleteEventListenersForAddOn($addOnId);
$xmlListeners = XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->listener);
foreach ($xmlListeners AS $event)
{
$eventId = (string)$event['event_id'];
$dw = XenForo_DataWriter::create('XenForo_DataWriter_CodeEventListener');
$dw->setOption(XenForo_DataWriter_CodeEventListener::OPTION_REBUILD_CACHE, false);
$dw->bulkSet(array(
'event_id' => (string)$event['event_id'],
'execute_order' => (string)$event['execute_order'],
'callback_class' => (string)$event['callback_class'],
'callback_method' => (string)$event['callback_method'],
'active' => (string)$event['active'],
'description' => (string)$event['description'],
'hint' => (string)$event['hint'],
'addon_id' => $addOnId
));
$dw->save();
}
$this->rebuildEventListenerCache();
XenForo_Db::commit($db);
}
/**
* Rebuilds the event listener cache.
*
* @return array
*/
public function rebuildEventListenerCache()
{
$cache = $this->getEventListenerArray();
$this->_getDataRegistryModel()->set('codeEventListeners', $cache);
return $cache;
}
}