<?php

defined('HOSTCMS') || exit('HostCMS: access denied.');

/**
 * Event system adds function calls for extending functionality.
 *
 * @package HostCMS 6\Core
 * @version 6.x
 * @author Hostmake LLC
 * @copyright © 2005-2013 ООО "Хостмэйк" (Hostmake LLC), http://www.hostcms.ru
 */
class Core_Event
{
	/**
	 * List of attached observers
	 * @var array
	 */
	static protected $_attached = array();

	/**
	 * Attach observer
	 * @param string $eventName event name
	 * @param string $function function name
	 *
	 * <code>
	 * function my_function($object, $args)
	 * {
	 * 	// do something
	 * }
	 * $function = 'my_function';
	 * // Attach observer $function for event 'Class.onBeforeDelete'
	 * Core_Event::attach('Class.onBeforeDelete', $function);
	 * </code>
	 */
	static public function attach($eventName, $function)
	{
		self::$_attached[$eventName][] = $function;
	}

	/**
	 * Detach observer
	 * @param string $eventName event name
	 * @param string $function function name
	 *
	 * <code>
	 * $function = 'my_function';
	 * // Detach observer $function from event 'Class.onBeforeDelete'
	 * Core_Event::detach('Class.onBeforeDelete', $function);
	 * </code>
	 */
	static public function detach($eventName, $function)
	{
		if (isset(self::$_attached[$eventName]))
		{
			foreach (self::$_attached[$eventName] AS $key => $value)
			{
				if ($function === $value)
				{
					unset(self::$_attached[$eventName][$key]);
				}
			}
		}
	}

	/**
	 * Notify all observers. If observer return FALSE, the cycle will stop.
	 *
	 * <code>
	 * // Call event 'Class.onBeforeDelete'
	 * Core_Event::notify('Class.onBeforeDelete', $this, array($primaryKey));
	 * </code>
	 *
	 * @param $eventName Name of event
	 * @param $object
	 * @param $args
	 */
	static public function notify($eventName, $object = NULL, $args = array())
	{
		if (isset(self::$_attached[$eventName]))
		{
			foreach (self::$_attached[$eventName] as $observer)
			{
				if (call_user_func($observer, $object, $args) === FALSE)
				{
					break;
				}
			}

			return TRUE;
		}

		return FALSE;
	}

	/**
	 * Get count of observers
	 * @param string $eventName event name
	 *
	 * <code>
	 * echo Core_Event::getCount('Class.onBeforeDelete');
	 * </code>
	 */
	static public function getCount($eventName)
	{
		// shop_item.onCallproducer
		return isset(self::$_attached[$eventName])
			? count(self::$_attached[$eventName])
			: 0;
	}
}
