/libraries/src/Categories/CategoryNode.php

https://github.com/joomla/joomla-cms · PHP · 496 lines · 150 code · 66 blank · 280 comment · 16 complexity · c6620e63172fab4333082a6935c5514e MD5 · raw file

  1. <?php
  2. /**
  3. * Joomla! Content Management System
  4. *
  5. * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
  6. * @license GNU General Public License version 2 or later; see LICENSE.txt
  7. */
  8. namespace Joomla\CMS\Categories;
  9. use Joomla\CMS\Factory;
  10. use Joomla\CMS\Object\CMSObject;
  11. use Joomla\CMS\Tree\NodeInterface;
  12. use Joomla\CMS\Tree\NodeTrait;
  13. use Joomla\Registry\Registry;
  14. /**
  15. * Helper class to load Categorytree
  16. *
  17. * @since 1.6
  18. */
  19. class CategoryNode extends CMSObject implements NodeInterface
  20. {
  21. use NodeTrait;
  22. /**
  23. * Primary key
  24. *
  25. * @var integer
  26. * @since 1.6
  27. */
  28. public $id = null;
  29. /**
  30. * The id of the category in the asset table
  31. *
  32. * @var integer
  33. * @since 1.6
  34. */
  35. public $asset_id = null;
  36. /**
  37. * The id of the parent of category in the asset table, 0 for category root
  38. *
  39. * @var integer
  40. * @since 1.6
  41. */
  42. public $parent_id = null;
  43. /**
  44. * The lft value for this category in the category tree
  45. *
  46. * @var integer
  47. * @since 1.6
  48. */
  49. public $lft = null;
  50. /**
  51. * The rgt value for this category in the category tree
  52. *
  53. * @var integer
  54. * @since 1.6
  55. */
  56. public $rgt = null;
  57. /**
  58. * The depth of this category's position in the category tree
  59. *
  60. * @var integer
  61. * @since 1.6
  62. */
  63. public $level = null;
  64. /**
  65. * The extension this category is associated with
  66. *
  67. * @var integer
  68. * @since 1.6
  69. */
  70. public $extension = null;
  71. /**
  72. * The menu title for the category (a short name)
  73. *
  74. * @var string
  75. * @since 1.6
  76. */
  77. public $title = null;
  78. /**
  79. * The the alias for the category
  80. *
  81. * @var string
  82. * @since 1.6
  83. */
  84. public $alias = null;
  85. /**
  86. * Description of the category.
  87. *
  88. * @var string
  89. * @since 1.6
  90. */
  91. public $description = null;
  92. /**
  93. * The publication status of the category
  94. *
  95. * @var boolean
  96. * @since 1.6
  97. */
  98. public $published = null;
  99. /**
  100. * Whether the category is or is not checked out
  101. *
  102. * @var boolean
  103. * @since 1.6
  104. */
  105. public $checked_out = null;
  106. /**
  107. * The time at which the category was checked out
  108. *
  109. * @var string
  110. * @since 1.6
  111. */
  112. public $checked_out_time = null;
  113. /**
  114. * Access level for the category
  115. *
  116. * @var integer
  117. * @since 1.6
  118. */
  119. public $access = null;
  120. /**
  121. * JSON string of parameters
  122. *
  123. * @var string
  124. * @since 1.6
  125. */
  126. public $params = null;
  127. /**
  128. * Metadata description
  129. *
  130. * @var string
  131. * @since 1.6
  132. */
  133. public $metadesc = null;
  134. /**
  135. * Key words for metadata
  136. *
  137. * @var string
  138. * @since 1.6
  139. */
  140. public $metakey = null;
  141. /**
  142. * JSON string of other metadata
  143. *
  144. * @var string
  145. * @since 1.6
  146. */
  147. public $metadata = null;
  148. /**
  149. * The ID of the user who created the category
  150. *
  151. * @var integer
  152. * @since 1.6
  153. */
  154. public $created_user_id = null;
  155. /**
  156. * The time at which the category was created
  157. *
  158. * @var string
  159. * @since 1.6
  160. */
  161. public $created_time = null;
  162. /**
  163. * The ID of the user who last modified the category
  164. *
  165. * @var integer
  166. * @since 1.6
  167. */
  168. public $modified_user_id = null;
  169. /**
  170. * The time at which the category was modified
  171. *
  172. * @var string
  173. * @since 1.6
  174. */
  175. public $modified_time = null;
  176. /**
  177. * Number of times the category has been viewed
  178. *
  179. * @var integer
  180. * @since 1.6
  181. */
  182. public $hits = null;
  183. /**
  184. * The language for the category in xx-XX format
  185. *
  186. * @var string
  187. * @since 1.6
  188. */
  189. public $language = null;
  190. /**
  191. * Number of items in this category or descendants of this category
  192. *
  193. * @var integer
  194. * @since 1.6
  195. */
  196. public $numitems = null;
  197. /**
  198. * Number of children items
  199. *
  200. * @var integer
  201. * @since 1.6
  202. */
  203. public $childrennumitems = null;
  204. /**
  205. * Slug for the category (used in URL)
  206. *
  207. * @var string
  208. * @since 1.6
  209. */
  210. public $slug = null;
  211. /**
  212. * Array of assets
  213. *
  214. * @var array
  215. * @since 1.6
  216. */
  217. public $assets = null;
  218. /**
  219. * Path from root to this category
  220. *
  221. * @var array
  222. * @since 1.6
  223. */
  224. protected $_path = array();
  225. /**
  226. * Flag if all children have been loaded
  227. *
  228. * @var boolean
  229. * @since 1.6
  230. */
  231. protected $_allChildrenloaded = false;
  232. /**
  233. * Constructor of this tree
  234. *
  235. * @var Categories
  236. * @since 1.6
  237. */
  238. protected $_constructor = null;
  239. /**
  240. * Class constructor
  241. *
  242. * @param array $category The category data.
  243. * @param Categories $constructor The tree constructor.
  244. *
  245. * @since 1.6
  246. */
  247. public function __construct($category = null, $constructor = null)
  248. {
  249. if ($category) {
  250. $this->setProperties($category);
  251. if ($constructor) {
  252. $this->_constructor = $constructor;
  253. }
  254. return true;
  255. }
  256. return false;
  257. }
  258. /**
  259. * Set the parent of this category
  260. *
  261. * If the category already has a parent, the link is unset
  262. *
  263. * @param CategoryNode|null $parent CategoryNode for the parent to be set or null
  264. *
  265. * @return void
  266. *
  267. * @since 1.6
  268. */
  269. public function setParent(NodeInterface $parent)
  270. {
  271. if (!\is_null($this->_parent)) {
  272. $key = array_search($this, $this->_parent->_children);
  273. unset($this->_parent->_children[$key]);
  274. }
  275. $this->_parent = $parent;
  276. $this->_parent->_children[] = & $this;
  277. if (\count($this->_parent->_children) > 1) {
  278. end($this->_parent->_children);
  279. $this->_leftSibling = prev($this->_parent->_children);
  280. $this->_leftSibling->_rightsibling = & $this;
  281. }
  282. if ($this->parent_id != 1) {
  283. $this->_path = $parent->getPath();
  284. }
  285. $this->_path[$this->id] = $this->id . ':' . $this->alias;
  286. }
  287. /**
  288. * Get the children of this node
  289. *
  290. * @param boolean $recursive False by default
  291. *
  292. * @return CategoryNode[] The children
  293. *
  294. * @since 1.6
  295. */
  296. public function &getChildren($recursive = false)
  297. {
  298. if (!$this->_allChildrenloaded) {
  299. $temp = $this->_constructor->get($this->id, true);
  300. if ($temp) {
  301. $this->_children = $temp->getChildren();
  302. $this->_leftSibling = $temp->getSibling(false);
  303. $this->_rightSibling = $temp->getSibling(true);
  304. $this->setAllLoaded();
  305. }
  306. }
  307. if ($recursive) {
  308. $items = array();
  309. foreach ($this->_children as $child) {
  310. $items[] = $child;
  311. $items = array_merge($items, $child->getChildren(true));
  312. }
  313. return $items;
  314. }
  315. return $this->_children;
  316. }
  317. /**
  318. * Returns the right or left sibling of a category
  319. *
  320. * @param boolean $right If set to false, returns the left sibling
  321. *
  322. * @return CategoryNode|null CategoryNode object with the sibling information or null if there is no sibling on that side.
  323. *
  324. * @since 1.6
  325. */
  326. public function getSibling($right = true)
  327. {
  328. if (!$this->_allChildrenloaded) {
  329. $temp = $this->_constructor->get($this->id, true);
  330. $this->_children = $temp->getChildren();
  331. $this->_leftSibling = $temp->getSibling(false);
  332. $this->_rightSibling = $temp->getSibling(true);
  333. $this->setAllLoaded();
  334. }
  335. if ($right) {
  336. return $this->_rightSibling;
  337. } else {
  338. return $this->_leftSibling;
  339. }
  340. }
  341. /**
  342. * Returns the category parameters
  343. *
  344. * @return Registry
  345. *
  346. * @since 1.6
  347. */
  348. public function getParams()
  349. {
  350. if (!($this->params instanceof Registry)) {
  351. $this->params = new Registry($this->params);
  352. }
  353. return $this->params;
  354. }
  355. /**
  356. * Returns the category metadata
  357. *
  358. * @return Registry A Registry object containing the metadata
  359. *
  360. * @since 1.6
  361. */
  362. public function getMetadata()
  363. {
  364. if (!($this->metadata instanceof Registry)) {
  365. $this->metadata = new Registry($this->metadata);
  366. }
  367. return $this->metadata;
  368. }
  369. /**
  370. * Returns the category path to the root category
  371. *
  372. * @return array
  373. *
  374. * @since 1.6
  375. */
  376. public function getPath()
  377. {
  378. return $this->_path;
  379. }
  380. /**
  381. * Returns the user that created the category
  382. *
  383. * @param boolean $modifiedUser Returns the modified_user when set to true
  384. *
  385. * @return \Joomla\CMS\User\User A User object containing a userid
  386. *
  387. * @since 1.6
  388. */
  389. public function getAuthor($modifiedUser = false)
  390. {
  391. if ($modifiedUser) {
  392. return Factory::getUser($this->modified_user_id);
  393. }
  394. return Factory::getUser($this->created_user_id);
  395. }
  396. /**
  397. * Set to load all children
  398. *
  399. * @return void
  400. *
  401. * @since 1.6
  402. */
  403. public function setAllLoaded()
  404. {
  405. $this->_allChildrenloaded = true;
  406. foreach ($this->_children as $child) {
  407. $child->setAllLoaded();
  408. }
  409. }
  410. /**
  411. * Returns the number of items.
  412. *
  413. * @param boolean $recursive If false number of children, if true number of descendants
  414. *
  415. * @return integer Number of children or descendants
  416. *
  417. * @since 1.6
  418. */
  419. public function getNumItems($recursive = false)
  420. {
  421. if ($recursive) {
  422. $count = $this->numitems;
  423. foreach ($this->getChildren() as $child) {
  424. $count = $count + $child->getNumItems(true);
  425. }
  426. return $count;
  427. }
  428. return $this->numitems;
  429. }
  430. }