1<?php 2namespace LimeSurvey\PluginManager; 3use Yii; 4use Hash; 5Yii::import('application.helpers.Hash'); 6 7class PluginEvent 8{ 9 /** 10 * The name of this event 11 * 12 * @var string 13 */ 14 protected $_event = ''; 15 16 /** 17 * This array holds the content blocks that plugins generate, idexed by plugin name 18 * 19 * @var array of PluginEventContent 20 */ 21 protected $_content = array(); 22 23 /** 24 * The class who fired the event, or null when not set 25 * 26 * @var object 27 */ 28 protected $_sender = null; 29 30 /** 31 * When true it prevents delegating the event to other plugins. 32 * 33 * @var boolean 34 */ 35 protected $_stop = false; 36 37 /** 38 * Internal storage for event data. Can be used to communicate between sender 39 * and plugin or between different plugins handling the event. 40 * 41 * @var array 42 */ 43 protected $_parameters = array(); 44 45 /** 46 * Constructor for the PluginEvent 47 * 48 * @param string $event Name of the event fired 49 * @param object $sender The object sending the event 50 * @return \PluginEvent 51 */ 52 public function __construct($event, $sender = null) 53 { 54 if (!is_null($sender) && is_object($sender)) { 55 $this->_sender = $sender; 56 } 57 58 $this->_event = $event; 59 60 return $this; 61 } 62 63 /** 64 * Get a value for the given key. 65 * 66 * When the value is not set, it will return the given default or null when 67 * no default was given. 68 * 69 * @param string $key 70 * @param mixed $default 71 * @return mixed 72 */ 73 public function get($key = null, $default = null) 74 { 75 if (!Hash::check($this->_parameters, $key)) { 76 return $default; 77 } else { 78 return Hash::get($this->_parameters, $key); 79 } 80 } 81 82 /** 83 * Return an array of pluginname / PluginEventContent but only when it has content 84 * 85 * @return PluginEventContent[] 86 */ 87 public function getAllContent() 88 { 89 $output = array(); 90 foreach ($this->_content as $plugin => $content) { 91 /* @var $content PluginEventContent */ 92 if ($content->hasContent()) { 93 $output[$plugin] = $content; 94 } 95 } 96 97 return $output; 98 } 99 100 /** 101 * Returns content for the given plugin(name) 102 * 103 * When there is no content yet, it will return an empty content object. 104 * 105 * @param PluginBase|string $plugin The plugin we want content for or a string name 106 * @return PluginEventContent 107 */ 108 public function getContent($plugin) 109 { 110 $pluginName = ''; 111 if (is_string($plugin)) { 112 $pluginName = $plugin; 113 } elseif ($plugin instanceof PluginBase) { 114 $pluginName = get_class($plugin); 115 } 116 117 if (array_key_exists($pluginName, $this->_content)) { 118 return $this->_content[$pluginName]; 119 } else { 120 return $this->setContent($pluginName); 121 } 122 } 123 124 /** 125 * Return the name of the event 126 * 127 * @return string 128 */ 129 public function getEventName() 130 { 131 return $this->_event; 132 } 133 134 /** 135 * Return the sender of the event 136 * 137 * Normally the class that fired the event, but can return false when not set. 138 * 139 * @return object The object sending the event, or false when unknown 140 */ 141 public function getSender() 142 { 143 if (!is_null($this->_sender)) { 144 return $this->_sender; 145 } else { 146 return false; 147 } 148 } 149 150 /** 151 * Returns true when execution of this event was stopped using $this->stop() 152 * 153 * @return boolean 154 */ 155 public function isStopped() 156 { 157 return $this->_stop; 158 } 159 160 /** 161 * Set a key/value pair to be used by plugins hanlding this event. 162 * 163 * @param string $key 164 * @param mixed $value 165 * @return \PluginEvent Fluent interface 166 */ 167 public function set($key, $value) 168 { 169 $this->_parameters = Hash::insert($this->_parameters, $key, $value); 170 return $this; 171 } 172 173 /** 174 * Appends a new value into the old. 175 * 176 * $value has to be an array in this case, since it is 177 * assumed that old value was an array. The new and old 178 * array value will be merged. 179 * 180 * @param string $key 181 * @param array $value 182 * @return \PluginEvent Fluent interface 183 */ 184 public function append($key, array $value) 185 { 186 if (!Hash::check($this->_parameters, $key)) { 187 $oldValue = array(); 188 } else { 189 $oldValue = Hash::get($this->_parameters, $key); 190 } 191 192 $value = array_merge($value, $oldValue); 193 194 $this->_parameters = Hash::insert($this->_parameters, $key, $value); 195 return $this; 196 } 197 198 /** 199 * Set content for $plugin, replacing any preexisting content 200 * 201 * @param string $plugin The plugin setting the context or a string name 202 * @param string $content 203 * @param string $cssClass 204 * @param string $id 205 * @return PluginEventContent 206 */ 207 public function setContent($plugin, $content = null, $cssClass = null, $id = null) 208 { 209 if (is_string($plugin)) { 210 $pluginName = $plugin; 211 } elseif ($plugin instanceof PluginBase) { 212 $pluginName = get_class($plugin); 213 } 214 215 $contentObject = new PluginEventContent($content, $cssClass, $id); 216 if (isset($pluginName)) { 217 $this->_content[$pluginName] = $contentObject; 218 } else { 219 $this->_content[] = $contentObject; 220 } 221 222 return $contentObject; 223 } 224 225 /** 226 * Halt execution of this event by other plugins 227 */ 228 public function stop() 229 { 230 $this->_stop = true; 231 } 232} 233