<commit_before><?php
/*"******************************************************************************************************
*   (c) 2004-2006 by MulchProductions, www.mulchprod.de                                                 *
*   (c) 2007-2014 by Kajona, www.kajona.de                                                              *
*       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt                                 *
*-------------------------------------------------------------------------------------------------------*
*   $Id$                                         *
********************************************************************************************************/

/**
 * The core eventmanager is used to trigger and fire internal events such as status-changed or record-deleted-events.
 * Therefore the corresponding interface-implementers are called and notified.
 *
 * Since version 4.5, the eventdispatcher provides a fully generic approach. Hardcoded-/package based dependencies are no longer required.
 *
 * @package module_system
 * @author <EMAIL>
 * @since 4.0
 */
class class_core_eventdispatcher {

    /**
     * @var  class_core_eventdispatcher
     */
    private static $objInstance = null;

    /**
     * @var class_model[]
     */
    private static $arrListeners = array();

    /**
     * @var interface_genericevent_listener[][]
     */
    private $arrRegisteredListeners = array();

    /**
     * Private for the sake of a singleton
     */
    private function __construct() {
    }

    /**
     * Returns an instance of system wide event-dispatcher
     * @return class_core_eventdispatcher
     */
    public static function getInstance() {
        if(self::$objInstance == null)
            self::$objInstance = new class_core_eventdispatcher();

        return self::$objInstance;
    }

    /**
     * Adds a listener to the list of registered listeners.
     *
     * @param string $strEventIdentifier
     * @param interface_genericevent_listener $objListener
     *
     * @return void
     */
    public function addListener($strEventIdentifier, interface_genericevent_listener $objListener) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        class_logger::getInstance(class_logger::EVENTS)->addLogRow("registering listener for type ".$strEventIdentifier.", instance of ".get_class($objListener), class_logger::$levelInfo);
        $this->arrRegisteredListeners[$strEventIdentifier][] = $objListener;
    }

    /**
     * Removes all listeners of the same class registered for the given event-identifier
     * and adds the passed listener afterwards.
     *
     * @param string $strEventIdentifier
     * @param interface_genericevent_listener $objListener
     *
     * @return void
     */
    public function removeAndAddListener($strEventIdentifier, interface_genericevent_listener $objListener) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        foreach($this->arrRegisteredListeners[$strEventIdentifier] as $objOneRegistered) {
            if(get_class($objListener) == get_class($objOneRegistered)) {
                $this->removeListener($strEventIdentifier, $objOneRegistered);
            }
        }

        $this->addListener($strEventIdentifier, $objListener);
    }

    /**
     * Removes ALL registered listeners for the given extension point
     *
     * @param string $strEventIdentifier
     *
     * @return void
     */
    public function removeAllListeners($strEventIdentifier) {
        $this->arrRegisteredListeners[$strEventIdentifier] = array();
    }

    /**
     * Removes a registered listener from a list of given event-listeners.
     * The listener is identified by a reference-comparison, so only the same instance will be removed.
     *
     * @param string $strEventIdentifier
     * @param interface_genericevent_listener $objListener
     *
     * @return bool
     */
    public function removeListener($strEventIdentifier, interface_genericevent_listener $objListener) {
        foreach($this->arrRegisteredListeners[$strEventIdentifier] as $intKey => $objOneListener) {
            if($objListener === $objOneListener) {
                class_logger::getInstance(class_logger::EVENTS)->addLogRow("removing listener for type ".$strEventIdentifier.", instance of ".get_class($objOneListener), class_logger::$levelInfo);
                unset($this->arrRegisteredListeners[$strEventIdentifier][$intKey]);
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the list of listeners currently registered for a given event
     *
     * @param string $strEventIdentifier
     *
     * @return interface_genericevent_listener[]
     */
    public function getRegisteredListeners($strEventIdentifier) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        return $this->arrRegisteredListeners[$strEventIdentifier];
    }

    /**
     * Notifies all listeners implementing the passed extension point.
     * The list of arguments is passed to all listeners.
     * Make sure to return a valid boolean value, otherwise the chain of event-handler may be broken.
     *
     * @param string $strEventIdentifier
     * @param array $arrArguments
     *
     * @return bool
     * @since 4.5
     * @see interface_genericevent_listener
     */
    public function notifyGenericListeners($strEventIdentifier, $arrArguments) {
        $bitReturn = true;
        /** @var $objOneListener interface_genericevent_listener */
        foreach($this->arrRegisteredListeners[$strEventIdentifier] as $objOneListener) {
            class_logger::getInstance(class_logger::EVENTS)->addLogRow("propagating event of type ".$strEventIdentifier." to instance of ".get_class($objOneListener), class_logger::$levelInfo);
            $bitReturn = $objOneListener->handleEvent($strEventIdentifier, $arrArguments) && $bitReturn;
        }

        return $bitReturn;
    }

    /**
     * Returns all classes (here: instances of the class) implementing a given interface
     * @param string $strInterface<commit_msg>BUG: added a missing array initialization<commit_after><?php
/*"******************************************************************************************************
*   (c) 2004-2006 by MulchProductions, www.mulchprod.de                                                 *
*   (c) 2007-2014 by Kajona, www.kajona.de                                                              *
*       Published under the GNU LGPL v2.1, see /system/licence_lgpl.txt                                 *
*-------------------------------------------------------------------------------------------------------*
*   $Id$                                         *
********************************************************************************************************/

/**
 * The core eventmanager is used to trigger and fire internal events such as status-changed or record-deleted-events.
 * Therefore the corresponding interface-implementers are called and notified.
 *
 * Since version 4.5, the eventdispatcher provides a fully generic approach. Hardcoded-/package based dependencies are no longer required.
 *
 * @package module_system
 * @author <EMAIL>
 * @since 4.0
 */
class class_core_eventdispatcher {

    /**
     * @var  class_core_eventdispatcher
     */
    private static $objInstance = null;

    /**
     * @var class_model[]
     */
    private static $arrListeners = array();

    /**
     * @var interface_genericevent_listener[][]
     */
    private $arrRegisteredListeners = array();

    /**
     * Private for the sake of a singleton
     */
    private function __construct() {
    }

    /**
     * Returns an instance of system wide event-dispatcher
     * @return class_core_eventdispatcher
     */
    public static function getInstance() {
        if(self::$objInstance == null)
            self::$objInstance = new class_core_eventdispatcher();

        return self::$objInstance;
    }

    /**
     * Adds a listener to the list of registered listeners.
     *
     * @param string $strEventIdentifier
     * @param interface_genericevent_listener $objListener
     *
     * @return void
     */
    public function addListener($strEventIdentifier, interface_genericevent_listener $objListener) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        class_logger::getInstance(class_logger::EVENTS)->addLogRow("registering listener for type ".$strEventIdentifier.", instance of ".get_class($objListener), class_logger::$levelInfo);
        $this->arrRegisteredListeners[$strEventIdentifier][] = $objListener;
    }

    /**
     * Removes all listeners of the same class registered for the given event-identifier
     * and adds the passed listener afterwards.
     *
     * @param string $strEventIdentifier
     * @param interface_genericevent_listener $objListener
     *
     * @return void
     */
    public function removeAndAddListener($strEventIdentifier, interface_genericevent_listener $objListener) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        foreach($this->arrRegisteredListeners[$strEventIdentifier] as $objOneRegistered) {
            if(get_class($objListener) == get_class($objOneRegistered)) {
                $this->removeListener($strEventIdentifier, $objOneRegistered);
            }
        }

        $this->addListener($strEventIdentifier, $objListener);
    }

    /**
     * Removes ALL registered listeners for the given extension point
     *
     * @param string $strEventIdentifier
     *
     * @return void
     */
    public function removeAllListeners($strEventIdentifier) {
        $this->arrRegisteredListeners[$strEventIdentifier] = array();
    }

    /**
     * Removes a registered listener from a list of given event-listeners.
     * The listener is identified by a reference-comparison, so only the same instance will be removed.
     *
     * @param string $strEventIdentifier
     * @param interface_genericevent_listener $objListener
     *
     * @return bool
     */
    public function removeListener($strEventIdentifier, interface_genericevent_listener $objListener) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        foreach($this->arrRegisteredListeners[$strEventIdentifier] as $intKey => $objOneListener) {
            if($objListener === $objOneListener) {
                class_logger::getInstance(class_logger::EVENTS)->addLogRow("removing listener for type ".$strEventIdentifier.", instance of ".get_class($objOneListener), class_logger::$levelInfo);
                unset($this->arrRegisteredListeners[$strEventIdentifier][$intKey]);
                return true;
            }
        }
        return false;
    }

    /**
     * Returns the list of listeners currently registered for a given event
     *
     * @param string $strEventIdentifier
     *
     * @return interface_genericevent_listener[]
     */
    public function getRegisteredListeners($strEventIdentifier) {
        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        return $this->arrRegisteredListeners[$strEventIdentifier];
    }

    /**
     * Notifies all listeners implementing the passed extension point.
     * The list of arguments is passed to all listeners.
     * Make sure to return a valid boolean value, otherwise the chain of event-handler may be broken.
     *
     * @param string $strEventIdentifier
     * @param array $arrArguments
     *
     * @return bool
     * @since 4.5
     * @see interface_genericevent_listener
     */
    public function notifyGenericListeners($strEventIdentifier, $arrArguments) {
        $bitReturn = true;

        if(!isset($this->arrRegisteredListeners[$strEventIdentifier]))
            $this->arrRegisteredListeners[$strEventIdentifier] = array();

        /** @var $objOneListener interface_genericevent_listener */
        foreach($this->arrRegisteredListeners[$strEventIdentifier] as $objOneListener) {
            class_logger::getInstance(class_logger::EVENTS)->addLogRow("propagating event of type ".$strEventIdentifier." to instance of ".get_class($objOneListener), class_logger::$levelInfo);
            $bitReturn = $objOneListener->handleEvent($strEventIdentifier, $arrArguments) && $bitReturn;
        }

        return $bitReturn;
    }

    /**
     * Returns all classes (here: instances of the class) implementing a given interface
     * @param string $strInterface
{'fraction_non_alphanumeric': 0.14228855721393036, 'fraction_numerical': 0.0036739380022962113, 'mean_word_length': 2.7752094770297604, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3828277', 'n_tokens_mistral': 3212, 'n_tokens_neox': 3164, 'n_words': 778}