/zf/library/Zend/Tag/Cloud.php
PHP | 410 lines | 199 code | 52 blank | 159 comment | 32 complexity | e8aa1600d292fb56394672af3045e8dd MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
1<?php 2/** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to license@zend.com so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Tag 17 * @subpackage Cloud 18 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) 19 * @license http://framework.zend.com/license/new-bsd New BSD License 20 * @version $Id: Cloud.php 23775 2011-03-01 17:25:24Z ralph $ 21 */ 22 23/** 24 * @see Zend_Tag_Item 25 */ 26require_once 'Zend/Tag/Item.php'; 27 28/** 29 * @category Zend 30 * @package Zend_Tag 31 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) 32 * @license http://framework.zend.com/license/new-bsd New BSD License 33 */ 34class Zend_Tag_Cloud 35{ 36 /** 37 * Decorator for the cloud 38 * 39 * @var Zend_Tag_Cloud_Decorator_Cloud 40 */ 41 protected $_cloudDecorator = null; 42 43 /** 44 * Decorator for the tags 45 * 46 * @var Zend_Tag_Cloud_Decorator_Tag 47 */ 48 protected $_tagDecorator = null; 49 50 /** 51 * List of all tags 52 * 53 * @var Zend_Tag_ItemList 54 */ 55 protected $_tags = null; 56 57 /** 58 * Plugin loader for decorators 59 * 60 * @var Zend_Loader_PluginLoader 61 */ 62 protected $_pluginLoader = null; 63 64 /** 65 * Option keys to skip when calling setOptions() 66 * 67 * @var array 68 */ 69 protected $_skipOptions = array( 70 'options', 71 'config', 72 ); 73 74 /** 75 * Create a new tag cloud with options 76 * 77 * @param mixed $options 78 */ 79 public function __construct($options = null) 80 { 81 if ($options instanceof Zend_Config) { 82 $this->setConfig($options); 83 } 84 85 if (is_array($options)) { 86 $this->setOptions($options); 87 } 88 } 89 90 /** 91 * Set options from Zend_Config 92 * 93 * @param Zend_Config $config 94 * @return Zend_Tag_Cloud 95 */ 96 public function setConfig(Zend_Config $config) 97 { 98 $this->setOptions($config->toArray()); 99 100 return $this; 101 } 102 103 /** 104 * Set options from array 105 * 106 * @param array $options Configuration for Zend_Tag_Cloud 107 * @return Zend_Tag_Cloud 108 */ 109 public function setOptions(array $options) 110 { 111 if (isset($options['prefixPath'])) { 112 $this->addPrefixPaths($options['prefixPath']); 113 unset($options['prefixPath']); 114 } 115 116 foreach ($options as $key => $value) { 117 if (in_array(strtolower($key), $this->_skipOptions)) { 118 continue; 119 } 120 121 $method = 'set' . ucfirst($key); 122 if (method_exists($this, $method)) { 123 $this->$method($value); 124 } 125 } 126 127 return $this; 128 } 129 130 /** 131 * Set the tags for the tag cloud. 132 * 133 * $tags should be an array containing single tags as array. Each tag 134 * array should at least contain the keys 'title' and 'weight'. Optionally 135 * you may supply the key 'url', to which the tag links to. Any additional 136 * parameter in the array is silently ignored and can be used by custom 137 * decorators. 138 * 139 * @param array $tags 140 * @return Zend_Tag_Cloud 141 */ 142 public function setTags(array $tags) 143 { 144 // Validate and cleanup the tags 145 $itemList = $this->getItemList(); 146 147 foreach ($tags as $tag) { 148 if ($tag instanceof Zend_Tag_Taggable) { 149 $itemList[] = $tag; 150 } else if (is_array($tag)) { 151 $itemList[] = new Zend_Tag_Item($tag); 152 } else { 153 require_once 'Zend/Tag/Cloud/Exception.php'; 154 throw new Zend_Tag_Cloud_Exception('Tag must be an instance of Zend_Tag_Taggable or an array'); 155 } 156 } 157 158 return $this; 159 } 160 161 /** 162 * Append a single tag to the cloud 163 * 164 * @param Zend_Tag_Taggable|array $tag 165 * @return Zend_Tag_Cloud 166 */ 167 public function appendTag($tag) 168 { 169 $tags = $this->getItemList(); 170 if ($tag instanceof Zend_Tag_Taggable) { 171 $tags[] = $tag; 172 } else if (is_array($tag)) { 173 $tags[] = new Zend_Tag_Item($tag); 174 } else { 175 require_once 'Zend/Tag/Cloud/Exception.php'; 176 throw new Zend_Tag_Cloud_Exception('Tag must be an instance of Zend_Tag_Taggable or an array'); 177 } 178 179 return $this; 180 } 181 182 /** 183 * Set the item list 184 * 185 * @param Zend_Tag_ItemList $itemList 186 * @return Zend_Tag_Cloud 187 */ 188 public function setItemList(Zend_Tag_ItemList $itemList) 189 { 190 $this->_tags = $itemList; 191 return $this; 192 } 193 194 /** 195 * Retrieve the item list 196 * 197 * If item list is undefined, creates one. 198 * 199 * @return Zend_Tag_ItemList 200 */ 201 public function getItemList() 202 { 203 if (null === $this->_tags) { 204 require_once 'Zend/Tag/ItemList.php'; 205 $this->setItemList(new Zend_Tag_ItemList()); 206 } 207 return $this->_tags; 208 } 209 210 /** 211 * Set the decorator for the cloud 212 * 213 * @param mixed $decorator 214 * @return Zend_Tag_Cloud 215 */ 216 public function setCloudDecorator($decorator) 217 { 218 $options = null; 219 220 if (is_array($decorator)) { 221 if (isset($decorator['options'])) { 222 $options = $decorator['options']; 223 } 224 225 if (isset($decorator['decorator'])) { 226 $decorator = $decorator['decorator']; 227 } 228 } 229 230 if (is_string($decorator)) { 231 $classname = $this->getPluginLoader()->load($decorator); 232 $decorator = new $classname($options); 233 } 234 235 if (!($decorator instanceof Zend_Tag_Cloud_Decorator_Cloud)) { 236 require_once 'Zend/Tag/Cloud/Exception.php'; 237 throw new Zend_Tag_Cloud_Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Cloud'); 238 } 239 240 $this->_cloudDecorator = $decorator; 241 242 return $this; 243 } 244 245 /** 246 * Get the decorator for the cloud 247 * 248 * @return Zend_Tag_Cloud_Decorator_Cloud 249 */ 250 public function getCloudDecorator() 251 { 252 if (null === $this->_cloudDecorator) { 253 $this->setCloudDecorator('htmlCloud'); 254 } 255 return $this->_cloudDecorator; 256 } 257 258 /** 259 * Set the decorator for the tags 260 * 261 * @param mixed $decorator 262 * @return Zend_Tag_Cloud 263 */ 264 public function setTagDecorator($decorator) 265 { 266 $options = null; 267 268 if (is_array($decorator)) { 269 if (isset($decorator['options'])) { 270 $options = $decorator['options']; 271 } 272 273 if (isset($decorator['decorator'])) { 274 $decorator = $decorator['decorator']; 275 } 276 } 277 278 if (is_string($decorator)) { 279 $classname = $this->getPluginLoader()->load($decorator); 280 $decorator = new $classname($options); 281 } 282 283 if (!($decorator instanceof Zend_Tag_Cloud_Decorator_Tag)) { 284 require_once 'Zend/Tag/Cloud/Exception.php'; 285 throw new Zend_Tag_Cloud_Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Tag'); 286 } 287 288 $this->_tagDecorator = $decorator; 289 290 return $this; 291 } 292 293 /** 294 * Get the decorator for the tags 295 * 296 * @return Zend_Tag_Cloud_Decorator_Tag 297 */ 298 public function getTagDecorator() 299 { 300 if (null === $this->_tagDecorator) { 301 $this->setTagDecorator('htmlTag'); 302 } 303 return $this->_tagDecorator; 304 } 305 306 /** 307 * Set plugin loaders for use with decorators 308 * 309 * @param Zend_Loader_PluginLoader_Interface $loader 310 * @return Zend_Tag_Cloud 311 */ 312 public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader) 313 { 314 $this->_pluginLoader = $loader; 315 return $this; 316 } 317 318 /** 319 * Get the plugin loader for decorators 320 * 321 * @return Zend_Loader_PluginLoader 322 */ 323 public function getPluginLoader() 324 { 325 if ($this->_pluginLoader === null) { 326 $prefix = 'Zend_Tag_Cloud_Decorator_'; 327 $pathPrefix = 'Zend/Tag/Cloud/Decorator/'; 328 329 require_once 'Zend/Loader/PluginLoader.php'; 330 $this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix)); 331 } 332 333 return $this->_pluginLoader; 334 } 335 336 /** 337 * Add many prefix paths at once 338 * 339 * @param array $paths 340 * @return Zend_Tag_Cloud 341 */ 342 public function addPrefixPaths(array $paths) 343 { 344 if (isset($paths['prefix']) && isset($paths['path'])) { 345 return $this->addPrefixPath($paths['prefix'], $paths['path']); 346 } 347 348 foreach ($paths as $path) { 349 if (!isset($path['prefix']) || !isset($path['path'])) { 350 continue; 351 } 352 353 $this->addPrefixPath($path['prefix'], $path['path']); 354 } 355 356 return $this; 357 } 358 359 /** 360 * Add prefix path for plugin loader 361 * 362 * @param string $prefix 363 * @param string $path 364 * @return Zend_Tag_Cloud 365 */ 366 public function addPrefixPath($prefix, $path) 367 { 368 $loader = $this->getPluginLoader(); 369 $loader->addPrefixPath($prefix, $path); 370 371 return $this; 372 } 373 374 /** 375 * Render the tag cloud 376 * 377 * @return string 378 */ 379 public function render() 380 { 381 $tags = $this->getItemList(); 382 383 if (count($tags) === 0) { 384 return ''; 385 } 386 387 $tagsResult = $this->getTagDecorator()->render($tags); 388 $cloudResult = $this->getCloudDecorator()->render($tagsResult); 389 390 return $cloudResult; 391 } 392 393 /** 394 * Render the tag cloud 395 * 396 * @return string 397 */ 398 public function __toString() 399 { 400 try { 401 $result = $this->render(); 402 return $result; 403 } catch (Exception $e) { 404 $message = "Exception caught by tag cloud: " . $e->getMessage() 405 . "\nStack Trace:\n" . $e->getTraceAsString(); 406 trigger_error($message, E_USER_WARNING); 407 return ''; 408 } 409 } 410}