Apache Zeta Components Manual :: File Source for signal_collection.php
Source for file signal_collection.php
Documentation is available at signal_collection.php
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
* @version //autogentag//
* ezcSignalCollection implements a mechanism for inter and intra object communication.
* See the tutorial for extensive examples on how to use this class.
* @property bool $signalsBlocked If set to true emits will not cause any slots to be called.
* @property-read string $identifier The identifier of this signal collection.
* Usually the class name of the object containing the collection.
* Holds the properties of this class.
* @var array(string=>mixed)
private $properties =
array();
* Holds the connections for this object with the default priority.
* @var array(string=>array(callback))
private $defaultConnections =
array();
* Holds the priority connections for this object.
* @var array(string=>array(int=>array(callback)))
private $priorityConnections =
array();
* If set this object will be used to fetch static connections instead of ezcSignalStaticConnections.
* @var ezcSignalStaticConnectionsBase
private static $staticConnectionsHolder =
null;
* Holds the options for this signal collection
* @var ezcSignalCollectionOptions
* Constructs a new signal collection with the identifier $identifier.
* The identifier can be used to connect to signals statically using
* ezcSignalStaticConnections.
* Through the associative array options you can specify the options for this class in the
* format array( 'optionName' => value ). See the documentation of ezcSignalCollectionOptions
* for information on the available options.
* @param string $identifier
public function __construct( $identifier =
"default", array $options =
array() )
$this->properties['identifier'] =
$identifier;
$this->signalsBlocked =
false;
* If set, $holder will be used to fetch static connections instead of ezcSignalStaticConnections.
* @param ezcSignalStaticConnectionsBase $holder
self::$staticConnectionsHolder =
$holder;
* Returns the current provider of static connections or null if there is none.
* @return ezcSignalStaticConnectionsBase
return self::$staticConnectionsHolder;
* Sets the property $name to $value.
* @throws ezcBasePropertyNotFoundException if the property does not exist.
public function __set( $name, $value )
$this->properties[$name] =
$value;
* Returns the property $name.
* @throws ezcBasePropertyNotFoundException if the property does not exist.
public function __get( $name )
return $this->properties[$name];
* Sets the options of this class.
* @param ezcSignalCollectionOptions|array(string=>value)$options The options to set
* either as an associative array in the form array(optionName=>value) or a
* ezcSignalCollectionOptions object.
* @throws ezcBaseSettingNotFoundException
* If you tried to set a non-existent option value.
* @throws ezcBaseSettingValueException
* If the value is not valid for the desired option.
* @throws ezcBaseValueException
* If you submit neither an array nor an instance of
* ezcSignalCollectionOptions.
$this->options =
$options;
throw
new ezcBaseValueException( "options", $options, 'array or instance of ezcSignalCollectionOptions' );
* Returns the options for this class.
* @return ezcSignalCollectionOptions
* Returns true if any slots have been connected to the signal $signal.
* False is returned if no slots have been connected to the $signal.
* Note: Emitting the signal $signal may still not call any slots if
* the property signalsBlocked has been set.
* @throws ezcSignalSlotException if the signals options has been set and $signal is not in the list of signals.
// if the the signals option is set we must check if the signal exists
if ( $this->options->signals !=
null &&
!in_array( $signal, $this->options->signals ) )
if ( self::$staticConnectionsHolder ==
null ) // custom static connections class
else if ( count( self::$staticConnectionsHolder->getConnections( $this->identifier, $signal ) ) >
0 )
if ( isset
( $this->defaultConnections[$signal] ) &&
count( $this->defaultConnections[$signal] ) >
0 )
if ( isset
( $this->priorityConnections[$signal] ) &&
count( $this->priorityConnections[$signal] ) >
0 )
* Emits the signal with the name $signal
* Any additional parameters are sent as parameters to the slot.
* @throws ezcSignalSlotException if the signals options has been set and $signal is not in the list of signals.
* @param ... $signal_parameters
public function emit( $signal )
// if the the signals option is set we must check if the signal exists
if ( $this->options->signals !=
null &&
!in_array( $signal, $this->options->signals ) )
if ( $this->signalsBlocked )
// prepare the parameters
// check if there are any static connections
$priStaticConnections =
array();
if ( self::$staticConnectionsHolder ==
null )
$priStaticConnections =
self::$staticConnectionsHolder->getConnections( $this->identifier, $signal );
$hasPriStaticConnections =
false;
if ( count( $priStaticConnections ) >
( isset
( $priStaticConnections[1000] ) ?
1 :
0) )
$hasPriStaticConnections =
true;
// fast algorithm if there are no prioritized slots
if ( isset
( $this->priorityConnections[$signal] ) ===
false &&
!$hasPriStaticConnections )
if ( isset
( $this->defaultConnections[$signal] ) )
foreach ( $this->defaultConnections[$signal] as $callback )
if ( isset
( $priStaticConnections[1000] ) )
foreach ( $priStaticConnections[1000] as $callback )
else // default algorithm
if ( isset
( $this->priorityConnections[$signal] ) )
$defaultKeys =
array_keys( $this->priorityConnections[$signal] );
$staticKeys =
array_keys( $priStaticConnections );
sort( $allKeys, SORT_NUMERIC );
foreach ( $allKeys as $key ) // call all slots in the correct order
if ( $key ==
1000 && isset
( $this->defaultConnections[$signal] ) )
foreach ( $this->defaultConnections[$signal] as $callback )
if ( isset
( $this->priorityConnections[$signal][$key] ) )
foreach ( $this->priorityConnections[$signal][$key] as $callback )
if ( isset
( $priStaticConnections[$key] ) )
foreach ( $priStaticConnections[$key] as $callback )
* Connects the signal $signal to the slot $slot.
* To control the order in which slots are called you can set a priority
* from 1 - 65 536. The lower the number the higher the priority. The default
* Slots with the same priority may be called with in any order.
* A slot will be called once for every time it is connected. It is possible
* to connect a slot more than once.
* See the PHP documentation for examples on the callback type.
* http://php.net/callback.
* We recommend avoiding excessive usage of the $priority parameter
* since it makes it much harder to track how your program works.
* @throws ezcSignalSlotException if the signals options has been set and $signal is not in the list of signals.
public function connect( $signal, $slot, $priority =
1000 )
// if the the signals option is set we must check if the signal exists
if ( $this->options->signals !=
null &&
!in_array( $signal, $this->options->signals ) )
if ( $priority ===
1000 ) // default
$this->defaultConnections[$signal][] =
$slot;
$this->priorityConnections[$signal][$priority][] =
$slot;
sort( $this->priorityConnections[$signal][$priority], SORT_NUMERIC );
* Disconnects the $slot from the $signal.
* If the priority is given it will try to disconnect a slot with that priority.
* If no such slot is found no slot will be disconnected.
* If no priority is given it will disconnect the matching slot with the lowest priority.
* @throws ezcSignalSlotException if the signals options has been set and $signal is not in the list of signals.
public function disconnect( $signal, $slot, $priority =
null )
// if the the signals option is set we must check if the signal exists
if ( $this->options->signals !=
null &&
!in_array( $signal, $this->options->signals ) )
if ( $priority ===
null ) // delete first found, searched from back
if ( isset
( $this->priorityConnections[$signal] ) )
$priorityKeys =
array_keys( $this->priorityConnections[$signal] );
rsort( $allPriorities, SORT_NUMERIC );
foreach ( $allPriorities as $priority )
if ( $priority ===
1000 )
if ( isset
( $this->defaultConnections[$signal] ) )
foreach ( $this->defaultConnections[$signal] as $key =>
$callback )
if ( ezcSignalCallbackComparer::compareCallbacks( $slot, $callback ) )
unset
( $this->defaultConnections[$signal][$key] );
if ( isset
( $this->priorityConnections[$signal] ) &&
isset
( $this->priorityConnections[$signal][$priority] ) )
foreach ( $this->priorityConnections[$signal][$priority] as $key =>
$callback)
if ( ezcSignalCallbackComparer::compareCallbacks( $slot, $callback ) )
unset
( $this->priorityConnections[$signal][$priority][$key] );
// if the priority is empty now it should be unset
if ( count( $this->priorityConnections[$signal][$priority] ) ==
0 )
unset
( $this->priorityConnections[$signal][$priority] );
else if ( $priority ===
1000 ) // only delete from default
if ( isset
( $this->defaultConnections[$signal] ) )
foreach ( $this->defaultConnections[$signal] as $key =>
$callback )
if ( ezcSignalCallbackComparer::compareCallbacks( $slot, $callback ) )
unset
( $this->defaultConnections[$signal][$key] );
else // delete from priority connectinos
if ( isset
( $this->priorityConnections[$signal] ) &&
isset
( $this->priorityConnections[$signal][$priority] ) )
foreach ( $this->priorityConnections[$signal][$priority] as $key =>
$callback )
if ( ezcSignalCallbackComparer::compareCallbacks( $slot, $callback ) )
unset
( $this->priorityConnections[$signal][$priority][$key] );
// if the priority is empty now it should be unset
if ( count( $this->priorityConnections[$signal][$priority] ) ==
0 )
unset
( $this->priorityConnections[$signal][$priority] );