/library/Zend/Tag/Cloud.php

https://github.com/Exercise/zf2 · PHP · 412 lines · 197 code · 52 blank · 163 comment · 32 complexity · 9384e71ea43138acb53846b15fea07e3 MD5 · raw file

  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-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @namespace
  24. */
  25. namespace Zend\Tag;
  26. use Zend\Config,
  27. Zend\Loader\PrefixPathMapper,
  28. Zend\Loader\ShortNameLocater,
  29. Zend\Loader\PluginLoader;
  30. /**
  31. * @uses \Zend\Loader\PluginLoader
  32. * @uses \Zend\Tag\Cloud\Exception
  33. * @uses \Zend\Tag\Item
  34. * @uses \Zend\Tag\ItemList
  35. * @category Zend
  36. * @package Zend_Tag
  37. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  38. * @license http://framework.zend.com/license/new-bsd New BSD License
  39. */
  40. class Cloud
  41. {
  42. /**
  43. * Decorator for the cloud
  44. *
  45. * @var \Zend\Tag\Cloud\Decorator\Cloud
  46. */
  47. protected $_cloudDecorator = null;
  48. /**
  49. * Decorator for the tags
  50. *
  51. * @var \Zend\Tag\Cloud\Decorator\Tag
  52. */
  53. protected $_tagDecorator = null;
  54. /**
  55. * List of all tags
  56. *
  57. * @var \Zend\Tag\ItemList
  58. */
  59. protected $_tags = null;
  60. /**
  61. * Plugin loader for decorators
  62. *
  63. * @var \Zend\Loader\ShortNameLocater
  64. */
  65. protected $_pluginLoader = null;
  66. /**
  67. * Option keys to skip when calling setOptions()
  68. *
  69. * @var array
  70. */
  71. protected $_skipOptions = array(
  72. 'options',
  73. 'config',
  74. );
  75. /**
  76. * Create a new tag cloud with options
  77. *
  78. * @param mixed $options
  79. */
  80. public function __construct($options = null)
  81. {
  82. if ($options instanceof Config\Config) {
  83. $this->setConfig($options);
  84. }
  85. if (is_array($options)) {
  86. $this->setOptions($options);
  87. }
  88. }
  89. /**
  90. * Set options from Zend_Config
  91. *
  92. * @param \Zend\Config\Config $config
  93. * @return \Zend\Tag\Cloud
  94. */
  95. public function setConfig(Config\Config $config)
  96. {
  97. $this->setOptions($config->toArray());
  98. return $this;
  99. }
  100. /**
  101. * Set options from array
  102. *
  103. * @param array $options Configuration for \Zend\Tag\Cloud
  104. * @return \Zend\Tag\Cloud
  105. */
  106. public function setOptions(array $options)
  107. {
  108. if (isset($options['prefixPath'])) {
  109. $this->addPrefixPaths($options['prefixPath']);
  110. unset($options['prefixPath']);
  111. }
  112. foreach ($options as $key => $value) {
  113. if (in_array(strtolower($key), $this->_skipOptions)) {
  114. continue;
  115. }
  116. $method = 'set' . ucfirst($key);
  117. if (method_exists($this, $method)) {
  118. $this->$method($value);
  119. }
  120. }
  121. return $this;
  122. }
  123. /**
  124. * Set the tags for the tag cloud.
  125. *
  126. * $tags should be an array containing single tags as array. Each tag
  127. * array should at least contain the keys 'title' and 'weight'. Optionally
  128. * you may supply the key 'url', to which the tag links to. Any additional
  129. * parameter in the array is silently ignored and can be used by custom
  130. * decorators.
  131. *
  132. * @param array $tags
  133. * @return \Zend\Tag\Cloud
  134. */
  135. public function setTags(array $tags)
  136. {
  137. // Validate and cleanup the tags
  138. $itemList = $this->getItemList();
  139. foreach ($tags as $tag) {
  140. if ($tag instanceof Taggable) {
  141. $itemList[] = $tag;
  142. } else if (is_array($tag)) {
  143. $itemList[] = new Item($tag);
  144. } else {
  145. throw new Cloud\Exception('Tag must be an instance of Zend_Tag_Taggable or an array');
  146. }
  147. }
  148. return $this;
  149. }
  150. /**
  151. * Append a single tag to the cloud
  152. *
  153. * @param \Zend\Tag\Taggable|array $tag
  154. * @return \Zend\Tag\Cloud
  155. */
  156. public function appendTag($tag)
  157. {
  158. $tags = $this->getItemList();
  159. if ($tag instanceof Taggable) {
  160. $tags[] = $tag;
  161. } else if (is_array($tag)) {
  162. $tags[] = new Item($tag);
  163. } else {
  164. throw new Cloud\Exception('Tag must be an instance of Zend_Tag_Taggable or an array');
  165. }
  166. return $this;
  167. }
  168. /**
  169. * Set the item list
  170. *
  171. * @param \Zend\Tag\ItemList $itemList
  172. * @return \Zend\Tag\Cloud
  173. */
  174. public function setItemList(ItemList $itemList)
  175. {
  176. $this->_tags = $itemList;
  177. return $this;
  178. }
  179. /**
  180. * Retrieve the item list
  181. *
  182. * If item list is undefined, creates one.
  183. *
  184. * @return \Zend\Tag\ItemList
  185. */
  186. public function getItemList()
  187. {
  188. if (null === $this->_tags) {
  189. $this->setItemList(new ItemList());
  190. }
  191. return $this->_tags;
  192. }
  193. /**
  194. * Set the decorator for the cloud
  195. *
  196. * @param mixed $decorator
  197. * @return \Zend\Tag\Cloud
  198. */
  199. public function setCloudDecorator($decorator)
  200. {
  201. $options = null;
  202. if (is_array($decorator)) {
  203. if (isset($decorator['options'])) {
  204. $options = $decorator['options'];
  205. }
  206. if (isset($decorator['decorator'])) {
  207. $decorator = $decorator['decorator'];
  208. }
  209. }
  210. if (is_string($decorator)) {
  211. $classname = $this->getPluginLoader()->load($decorator);
  212. $decorator = new $classname($options);
  213. }
  214. if (!($decorator instanceof Cloud\Decorator\Cloud)) {
  215. throw new Cloud\Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Cloud');
  216. }
  217. $this->_cloudDecorator = $decorator;
  218. return $this;
  219. }
  220. /**
  221. * Get the decorator for the cloud
  222. *
  223. * @return \Zend\Tag\Cloud\Decorator\Cloud
  224. */
  225. public function getCloudDecorator()
  226. {
  227. if (null === $this->_cloudDecorator) {
  228. $this->setCloudDecorator('htmlCloud');
  229. }
  230. return $this->_cloudDecorator;
  231. }
  232. /**
  233. * Set the decorator for the tags
  234. *
  235. * @param mixed $decorator
  236. * @return \Zend\Tag\Cloud
  237. */
  238. public function setTagDecorator($decorator)
  239. {
  240. $options = null;
  241. if (is_array($decorator)) {
  242. if (isset($decorator['options'])) {
  243. $options = $decorator['options'];
  244. }
  245. if (isset($decorator['decorator'])) {
  246. $decorator = $decorator['decorator'];
  247. }
  248. }
  249. if (is_string($decorator)) {
  250. $classname = $this->getPluginLoader()->load($decorator);
  251. $decorator = new $classname($options);
  252. }
  253. if (!($decorator instanceof Cloud\Decorator\Tag)) {
  254. throw new Cloud\Exception('Decorator is no instance of Zend_Tag_Cloud_Decorator_Tag');
  255. }
  256. $this->_tagDecorator = $decorator;
  257. return $this;
  258. }
  259. /**
  260. * Get the decorator for the tags
  261. *
  262. * @return \Zend\Tag\Cloud\Decorator\Tag
  263. */
  264. public function getTagDecorator()
  265. {
  266. if (null === $this->_tagDecorator) {
  267. $this->setTagDecorator('htmlTag');
  268. }
  269. return $this->_tagDecorator;
  270. }
  271. /**
  272. * Set plugin loaders for use with decorators
  273. *
  274. * @param \Zend\Loader\ShortNameLocater $loader
  275. * @return \Zend\Tag\Cloud
  276. */
  277. public function setPluginLoader(ShortNameLocater $loader)
  278. {
  279. $this->_pluginLoader = $loader;
  280. return $this;
  281. }
  282. /**
  283. * Get the plugin loader for decorators
  284. *
  285. * @return \Zend\Loader\ShortNameLocater
  286. */
  287. public function getPluginLoader()
  288. {
  289. if ($this->_pluginLoader === null) {
  290. $prefix = 'Zend\Tag\Cloud\Decorator\\';
  291. $pathPrefix = 'Zend/Tag/Cloud/Decorator/';
  292. $this->_pluginLoader = new PluginLoader(array($prefix => $pathPrefix));
  293. }
  294. return $this->_pluginLoader;
  295. }
  296. /**
  297. * Add many prefix paths at once
  298. *
  299. * @param array $paths
  300. * @return \Zend\Tag\Cloud
  301. */
  302. public function addPrefixPaths(array $paths)
  303. {
  304. if (isset($paths['prefix']) && isset($paths['path'])) {
  305. return $this->addPrefixPath($paths['prefix'], $paths['path']);
  306. }
  307. foreach ($paths as $path) {
  308. if (!isset($path['prefix']) || !isset($path['path'])) {
  309. continue;
  310. }
  311. $this->addPrefixPath($path['prefix'], $path['path']);
  312. }
  313. return $this;
  314. }
  315. /**
  316. * Add prefix path for plugin loader
  317. *
  318. * @param string $prefix
  319. * @param string $path
  320. * @return \Zend\Tag\Cloud
  321. */
  322. public function addPrefixPath($prefix, $path)
  323. {
  324. $loader = $this->getPluginLoader();
  325. $loader->addPrefixPath($prefix, $path);
  326. return $this;
  327. }
  328. /**
  329. * Render the tag cloud
  330. *
  331. * @return string
  332. */
  333. public function render()
  334. {
  335. $tags = $this->getItemList();
  336. if (count($tags) === 0) {
  337. return '';
  338. }
  339. $tagsResult = $this->getTagDecorator()->render($tags);
  340. $cloudResult = $this->getCloudDecorator()->render($tagsResult);
  341. return $cloudResult;
  342. }
  343. /**
  344. * Render the tag cloud
  345. *
  346. * @return string
  347. */
  348. public function __toString()
  349. {
  350. try {
  351. $result = $this->render();
  352. return $result;
  353. } catch (\Exception $e) {
  354. $message = "Exception caught by tag cloud: " . $e->getMessage()
  355. . "\nStack Trace:\n" . $e->getTraceAsString();
  356. trigger_error($message, E_USER_WARNING);
  357. return '';
  358. }
  359. }
  360. }