File indexing completed on 2024-12-22 05:37:07

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Tag
0017  * @subpackage Cloud
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_Tag_Item
0025  */
0026 // require_once 'Zend/Tag/Item.php';
0027 
0028 /**
0029  * @category   Zend
0030  * @package    Zend_Tag
0031  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0032  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0033  */
0034 class Zend_Tag_Cloud
0035 {
0036     /**
0037      * Decorator for the cloud
0038      *
0039      * @var Zend_Tag_Cloud_Decorator_Cloud
0040      */
0041     protected $_cloudDecorator = null;
0042 
0043     /**
0044      * Decorator for the tags
0045      *
0046      * @var Zend_Tag_Cloud_Decorator_Tag
0047      */
0048     protected $_tagDecorator = null;
0049 
0050     /**
0051      * List of all tags
0052      *
0053      * @var Zend_Tag_ItemList
0054      */
0055     protected $_tags = null;
0056 
0057     /**
0058      * Plugin loader for decorators
0059      *
0060      * @var Zend_Loader_PluginLoader
0061      */
0062     protected $_pluginLoader = null;
0063 
0064     /**
0065      * Option keys to skip when calling setOptions()
0066      *
0067      * @var array
0068      */
0069     protected $_skipOptions = array(
0070         'options',
0071         'config',
0072     );
0073 
0074     /**
0075      * Create a new tag cloud with options
0076      *
0077      * @param mixed $options
0078      */
0079     public function __construct($options = null)
0080     {
0081         if ($options instanceof Zend_Config) {
0082             $this->setConfig($options);
0083         }
0084 
0085         if (is_array($options)) {
0086             $this->setOptions($options);
0087         }
0088     }
0089 
0090     /**
0091      * Set options from Zend_Config
0092      *
0093      * @param  Zend_Config $config
0094      * @return Zend_Tag_Cloud
0095      */
0096     public function setConfig(Zend_Config $config)
0097     {
0098         $this->setOptions($config->toArray());
0099 
0100         return $this;
0101     }
0102 
0103     /**
0104      * Set options from array
0105      *
0106      * @param  array $options Configuration for Zend_Tag_Cloud
0107      * @return Zend_Tag_Cloud
0108      */
0109     public function setOptions(array $options)
0110     {
0111         if (isset($options['prefixPath'])) {
0112             $this->addPrefixPaths($options['prefixPath']);
0113             unset($options['prefixPath']);
0114         }
0115 
0116         foreach ($options as $key => $value) {
0117             if (in_array(strtolower($key), $this->_skipOptions)) {
0118                 continue;
0119             }
0120 
0121             $method = 'set' . ucfirst($key);
0122             if (method_exists($this, $method)) {
0123                 $this->$method($value);
0124             }
0125         }
0126 
0127         return $this;
0128     }
0129 
0130     /**
0131      * Set the tags for the tag cloud.
0132      *
0133      * $tags should be an array containing single tags as array. Each tag
0134      * array should at least contain the keys 'title' and 'weight'. Optionally
0135      * you may supply the key 'url', to which the tag links to. Any additional
0136      * parameter in the array is silently ignored and can be used by custom
0137      * decorators.
0138      *
0139      * @param  array $tags
0140      * @return Zend_Tag_Cloud
0141      */
0142     public function setTags(array $tags)
0143     {
0144         // Validate and cleanup the tags
0145         $itemList = $this->getItemList();
0146 
0147         foreach ($tags as $tag) {
0148             if ($tag instanceof Zend_Tag_Taggable) {
0149                 $itemList[] = $tag;
0150             } else if (is_array($tag)) {
0151                 $itemList[] = new Zend_Tag_Item($tag);
0152             } else {
0153                 // require_once 'Zend/Tag/Cloud/Exception.php';
0154                 throw new Zend_Tag_Cloud_Exception('Tag must be an instance of Zend_Tag_Taggable or an array');
0155             }
0156         }
0157 
0158         return $this;
0159     }
0160 
0161     /**
0162      * Append a single tag to the cloud
0163      *
0164      * @param  Zend_Tag_Taggable|array $tag
0165      * @return Zend_Tag_Cloud
0166      */
0167     public function appendTag($tag)
0168     {
0169         $tags = $this->getItemList();
0170         if ($tag instanceof Zend_Tag_Taggable) {
0171             $tags[] = $tag;
0172         } else if (is_array($tag)) {
0173             $tags[] = new Zend_Tag_Item($tag);
0174         } else {
0175             // require_once 'Zend/Tag/Cloud/Exception.php';
0176             throw new Zend_Tag_Cloud_Exception('Tag must be an instance of Zend_Tag_Taggable or an array');
0177         }
0178 
0179         return $this;
0180     }
0181 
0182     /**
0183      * Set the item list
0184      *
0185      * @param  Zend_Tag_ItemList $itemList
0186      * @return Zend_Tag_Cloud
0187      */
0188     public function setItemList(Zend_Tag_ItemList $itemList)
0189     {
0190         $this->_tags = $itemList;
0191         return $this;
0192     }
0193 
0194     /**
0195      * Retrieve the item list
0196      *
0197      * If item list is undefined, creates one.
0198      *
0199      * @return Zend_Tag_ItemList
0200      */
0201     public function getItemList()
0202     {
0203         if (null === $this->_tags) {
0204             // require_once 'Zend/Tag/ItemList.php';
0205             $this->setItemList(new Zend_Tag_ItemList());
0206         }
0207         return $this->_tags;
0208     }
0209 
0210     /**
0211      * Set the decorator for the cloud
0212      *
0213      * @param  mixed $decorator
0214      * @return Zend_Tag_Cloud
0215      */
0216     public function setCloudDecorator($decorator)
0217     {
0218         $options = null;
0219 
0220         if (is_array($decorator)) {
0221             if (isset($decorator['options'])) {
0222                 $options = $decorator['options'];
0223             }
0224 
0225             if (isset($decorator['decorator'])) {
0226                 $decorator = $decorator['decorator'];
0227             }
0228         }
0229 
0230         if (is_string($decorator)) {
0231             $classname = $this->getPluginLoader()->load($decorator);
0232             $decorator = new $classname($options);
0233         }
0234 
0235         if (!($decorator instanceof Zend_Tag_Cloud_Decorator_Cloud)) {
0236             // require_once 'Zend/Tag/Cloud/Exception.php';
0237             throw new Zend_Tag_Cloud_Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Cloud');
0238         }
0239 
0240         $this->_cloudDecorator = $decorator;
0241 
0242         return $this;
0243     }
0244 
0245     /**
0246      * Get the decorator for the cloud
0247      *
0248      * @return Zend_Tag_Cloud_Decorator_Cloud
0249      */
0250     public function getCloudDecorator()
0251     {
0252         if (null === $this->_cloudDecorator) {
0253             $this->setCloudDecorator('htmlCloud');
0254         }
0255         return $this->_cloudDecorator;
0256     }
0257 
0258     /**
0259      * Set the decorator for the tags
0260      *
0261      * @param  mixed $decorator
0262      * @return Zend_Tag_Cloud
0263      */
0264     public function setTagDecorator($decorator)
0265     {
0266         $options = null;
0267 
0268         if (is_array($decorator)) {
0269             if (isset($decorator['options'])) {
0270                 $options = $decorator['options'];
0271             }
0272 
0273             if (isset($decorator['decorator'])) {
0274                 $decorator = $decorator['decorator'];
0275             }
0276         }
0277 
0278         if (is_string($decorator)) {
0279             $classname = $this->getPluginLoader()->load($decorator);
0280             $decorator = new $classname($options);
0281         }
0282 
0283         if (!($decorator instanceof Zend_Tag_Cloud_Decorator_Tag)) {
0284             // require_once 'Zend/Tag/Cloud/Exception.php';
0285             throw new Zend_Tag_Cloud_Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Tag');
0286         }
0287 
0288         $this->_tagDecorator = $decorator;
0289 
0290         return $this;
0291     }
0292 
0293     /**
0294      * Get the decorator for the tags
0295      *
0296      * @return Zend_Tag_Cloud_Decorator_Tag
0297      */
0298     public function getTagDecorator()
0299     {
0300         if (null === $this->_tagDecorator) {
0301             $this->setTagDecorator('htmlTag');
0302         }
0303         return $this->_tagDecorator;
0304     }
0305 
0306     /**
0307      * Set plugin loaders for use with decorators
0308      *
0309      * @param  Zend_Loader_PluginLoader_Interface $loader
0310      * @return Zend_Tag_Cloud
0311      */
0312     public function setPluginLoader(Zend_Loader_PluginLoader_Interface $loader)
0313     {
0314         $this->_pluginLoader = $loader;
0315         return $this;
0316     }
0317 
0318     /**
0319      * Get the plugin loader for decorators
0320      *
0321      * @return Zend_Loader_PluginLoader
0322      */
0323     public function getPluginLoader()
0324     {
0325         if ($this->_pluginLoader === null) {
0326             $prefix     = 'Zend_Tag_Cloud_Decorator_';
0327             $pathPrefix = 'Zend/Tag/Cloud/Decorator/';
0328 
0329             // require_once 'Zend/Loader/PluginLoader.php';
0330             $this->_pluginLoader = new Zend_Loader_PluginLoader(array($prefix => $pathPrefix));
0331         }
0332 
0333         return $this->_pluginLoader;
0334     }
0335 
0336     /**
0337      * Add many prefix paths at once
0338      *
0339      * @param  array $paths
0340      * @return Zend_Tag_Cloud
0341      */
0342     public function addPrefixPaths(array $paths)
0343     {
0344         if (isset($paths['prefix']) && isset($paths['path'])) {
0345             return $this->addPrefixPath($paths['prefix'], $paths['path']);
0346         }
0347 
0348         foreach ($paths as $path) {
0349             if (!isset($path['prefix']) || !isset($path['path'])) {
0350                 continue;
0351             }
0352 
0353             $this->addPrefixPath($path['prefix'], $path['path']);
0354         }
0355 
0356         return $this;
0357     }
0358 
0359     /**
0360      * Add prefix path for plugin loader
0361      *
0362      * @param  string $prefix
0363      * @param  string $path
0364      * @return Zend_Tag_Cloud
0365      */
0366     public function addPrefixPath($prefix, $path)
0367     {
0368         $loader = $this->getPluginLoader();
0369         $loader->addPrefixPath($prefix, $path);
0370 
0371         return $this;
0372     }
0373 
0374     /**
0375      * Render the tag cloud
0376      *
0377      * @return string
0378      */
0379     public function render()
0380     {
0381         $tags = $this->getItemList();
0382 
0383         if (count($tags) === 0) {
0384             return '';
0385         }
0386 
0387         $tagsResult  = $this->getTagDecorator()->render($tags);
0388         $cloudResult = $this->getCloudDecorator()->render($tagsResult);
0389 
0390         return $cloudResult;
0391     }
0392 
0393     /**
0394      * Render the tag cloud
0395      *
0396      * @return string
0397      */
0398     public function __toString()
0399     {
0400         try {
0401             $result = $this->render();
0402             return $result;
0403         } catch (Exception $e) {
0404             $message = "Exception caught by tag cloud: " . $e->getMessage()
0405                      . "\nStack Trace:\n" . $e->getTraceAsString();
0406             trigger_error($message, E_USER_WARNING);
0407             return '';
0408         }
0409     }
0410 }