/libraries/Zend/Tag/Cloud.php

https://github.com/kiranatama/sagalaya · PHP · 330 lines · 161 code · 43 blank · 126 comment · 21 complexity · 97a6ac18c889ab7519af42b528f98724 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Tag
  9. */
  10. namespace Zend\Tag;
  11. use Traversable;
  12. use Zend\Stdlib\ArrayUtils;
  13. /**
  14. * @category Zend
  15. * @package Zend_Tag
  16. */
  17. class Cloud
  18. {
  19. /**
  20. * DecoratorInterface for the cloud
  21. *
  22. * @var Cloud
  23. */
  24. protected $cloudDecorator = null;
  25. /**
  26. * DecoratorInterface for the tags
  27. *
  28. * @var Tag
  29. */
  30. protected $tagDecorator = null;
  31. /**
  32. * List of all tags
  33. *
  34. * @var ItemList
  35. */
  36. protected $tags = null;
  37. /**
  38. * Plugin manager for decorators
  39. *
  40. * @var Cloud\DecoratorPluginManager
  41. */
  42. protected $decorators = null;
  43. /**
  44. * Option keys to skip when calling setOptions()
  45. *
  46. * @var array
  47. */
  48. protected $skipOptions = array(
  49. 'options',
  50. 'config',
  51. );
  52. /**
  53. * Create a new tag cloud with options
  54. *
  55. * @param array|Traversable $options
  56. */
  57. public function __construct($options = null)
  58. {
  59. if ($options instanceof Traversable) {
  60. $options = ArrayUtils::iteratorToArray($options);
  61. }
  62. if (is_array($options)) {
  63. $this->setOptions($options);
  64. }
  65. }
  66. /**
  67. * Set options from array
  68. *
  69. * @param array $options Configuration for Cloud
  70. * @return Cloud
  71. */
  72. public function setOptions(array $options)
  73. {
  74. foreach ($options as $key => $value) {
  75. if (in_array(strtolower($key), $this->skipOptions)) {
  76. continue;
  77. }
  78. $method = 'set' . $key;
  79. if (method_exists($this, $method)) {
  80. $this->$method($value);
  81. }
  82. }
  83. return $this;
  84. }
  85. /**
  86. * Set the tags for the tag cloud.
  87. *
  88. * $tags should be an array containing single tags as array. Each tag
  89. * array should at least contain the keys 'title' and 'weight'. Optionally
  90. * you may supply the key 'url', to which the tag links to. Any additional
  91. * parameter in the array is silently ignored and can be used by custom
  92. * decorators.
  93. *
  94. * @param array $tags
  95. * @throws Exception\InvalidArgumentException
  96. * @return Cloud
  97. */
  98. public function setTags(array $tags)
  99. {
  100. foreach ($tags as $tag) {
  101. $this->appendTag($tag);
  102. }
  103. return $this;
  104. }
  105. /**
  106. * Append a single tag to the cloud
  107. *
  108. * @param TaggableInterface|array $tag
  109. * @throws Exception\InvalidArgumentException
  110. * @return Cloud
  111. */
  112. public function appendTag($tag)
  113. {
  114. $tags = $this->getItemList();
  115. if ($tag instanceof TaggableInterface) {
  116. $tags[] = $tag;
  117. return $this;
  118. }
  119. if (!is_array($tag)) {
  120. throw new Exception\InvalidArgumentException(sprintf(
  121. 'Tag must be an instance of %s\TaggableInterface or an array; received "%s"',
  122. __NAMESPACE__,
  123. (is_object($tag) ? get_class($tag) : gettype($tag))
  124. ));
  125. }
  126. $tags[] = new Item($tag);
  127. return $this;
  128. }
  129. /**
  130. * Set the item list
  131. *
  132. * @param ItemList $itemList
  133. * @return Cloud
  134. */
  135. public function setItemList(ItemList $itemList)
  136. {
  137. $this->tags = $itemList;
  138. return $this;
  139. }
  140. /**
  141. * Retrieve the item list
  142. *
  143. * If item list is undefined, creates one.
  144. *
  145. * @return ItemList
  146. */
  147. public function getItemList()
  148. {
  149. if (null === $this->tags) {
  150. $this->setItemList(new ItemList());
  151. }
  152. return $this->tags;
  153. }
  154. /**
  155. * Set the decorator for the cloud
  156. *
  157. * @param mixed $decorator
  158. * @throws Exception\InvalidArgumentException
  159. * @return Cloud
  160. */
  161. public function setCloudDecorator($decorator)
  162. {
  163. $options = null;
  164. if (is_array($decorator)) {
  165. if (isset($decorator['options'])) {
  166. $options = $decorator['options'];
  167. }
  168. if (isset($decorator['decorator'])) {
  169. $decorator = $decorator['decorator'];
  170. }
  171. }
  172. if (is_string($decorator)) {
  173. $decorator = $this->getDecoratorPluginManager()->get($decorator, $options);
  174. }
  175. if (!($decorator instanceof Cloud\Decorator\AbstractCloud)) {
  176. throw new Exception\InvalidArgumentException('DecoratorInterface is no instance of Cloud\Decorator\AbstractCloud');
  177. }
  178. $this->cloudDecorator = $decorator;
  179. return $this;
  180. }
  181. /**
  182. * Get the decorator for the cloud
  183. *
  184. * @return Cloud
  185. */
  186. public function getCloudDecorator()
  187. {
  188. if (null === $this->cloudDecorator) {
  189. $this->setCloudDecorator('htmlCloud');
  190. }
  191. return $this->cloudDecorator;
  192. }
  193. /**
  194. * Set the decorator for the tags
  195. *
  196. * @param mixed $decorator
  197. * @throws Exception\InvalidArgumentException
  198. * @return Cloud
  199. */
  200. public function setTagDecorator($decorator)
  201. {
  202. $options = null;
  203. if (is_array($decorator)) {
  204. if (isset($decorator['options'])) {
  205. $options = $decorator['options'];
  206. }
  207. if (isset($decorator['decorator'])) {
  208. $decorator = $decorator['decorator'];
  209. }
  210. }
  211. if (is_string($decorator)) {
  212. $decorator = $this->getDecoratorPluginManager()->get($decorator, $options);
  213. }
  214. if (!($decorator instanceof Cloud\Decorator\AbstractTag)) {
  215. throw new Exception\InvalidArgumentException('DecoratorInterface is no instance of Cloud\Decorator\Tag');
  216. }
  217. $this->tagDecorator = $decorator;
  218. return $this;
  219. }
  220. /**
  221. * Get the decorator for the tags
  222. *
  223. * @return Tag
  224. */
  225. public function getTagDecorator()
  226. {
  227. if (null === $this->tagDecorator) {
  228. $this->setTagDecorator('htmlTag');
  229. }
  230. return $this->tagDecorator;
  231. }
  232. /**
  233. * Set plugin manager for use with decorators
  234. *
  235. * @param Cloud\DecoratorPluginManager $decorators
  236. * @return Cloud
  237. */
  238. public function setDecoratorPluginManager(Cloud\DecoratorPluginManager $decorators)
  239. {
  240. $this->decorators = $decorators;
  241. return $this;
  242. }
  243. /**
  244. * Get the plugin manager for decorators
  245. *
  246. * @return Cloud\DecoratorPluginManager
  247. */
  248. public function getDecoratorPluginManager()
  249. {
  250. if ($this->decorators === null) {
  251. $this->decorators = new Cloud\DecoratorPluginManager();
  252. }
  253. return $this->decorators;
  254. }
  255. /**
  256. * Render the tag cloud
  257. *
  258. * @return string
  259. */
  260. public function render()
  261. {
  262. $tags = $this->getItemList();
  263. if (count($tags) === 0) {
  264. return '';
  265. }
  266. $tagsResult = $this->getTagDecorator()->render($tags);
  267. $cloudResult = $this->getCloudDecorator()->render($tagsResult);
  268. return $cloudResult;
  269. }
  270. /**
  271. * Render the tag cloud
  272. *
  273. * @return string
  274. */
  275. public function __toString()
  276. {
  277. try {
  278. $result = $this->render();
  279. return $result;
  280. } catch (\Exception $e) {
  281. $message = "Exception caught by tag cloud: " . $e->getMessage()
  282. . "\nStack Trace:\n" . $e->getTraceAsString();
  283. trigger_error($message, E_USER_WARNING);
  284. return '';
  285. }
  286. }
  287. }