ContentTreeNode.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. <?php
  2. class ContentTreeNode {
  3. protected $urlIdentifier;
  4. protected $title;
  5. protected $menu_title;
  6. protected $subTitle;
  7. protected $visible;
  8. protected $id;
  9. protected $nodeClass;
  10. protected $credentials;
  11. protected $permsType;
  12. protected $seo_keywords_type;
  13. protected $seo_keywords_content;
  14. protected $seo_description_type;
  15. protected $seo_description_content;
  16. protected $current_layout_type;
  17. protected $current_layout_content;
  18. protected $browser_title_type;
  19. protected $browser_title_content;
  20. protected $url_provider;
  21. protected $locale;
  22. protected $open_target_provider;
  23. protected $pending_delete = false;
  24. public $children = array();
  25. /**
  26. *
  27. * @var ContentTreeNode
  28. */
  29. public $parent;
  30. public $previousSibling;
  31. public $active = false;
  32. public $nextSibling;
  33. protected $owner_tree = null;
  34. protected $mockTranslation = false;
  35. function setOwnerTree($value)
  36. {
  37. $this->owner_tree = $value;
  38. }
  39. /**
  40. * @return ContentTree
  41. */
  42. function getOwnerTree()
  43. {
  44. return $this->owner_tree;
  45. }
  46. function setMockTranslation($value)
  47. {
  48. $this->mockTranslation = $value;
  49. }
  50. function __construct($node, $parentTreeNode, $locale = null)
  51. {
  52. if (null == $locale) {
  53. $locale = sfConfig::get('app_translations_default_language');
  54. }
  55. $this->setCulture($locale);
  56. $this->refreshProperties($node);
  57. $this->parent = $parentTreeNode;
  58. }
  59. function setCulture($value)
  60. {
  61. $this->locale = $value;
  62. }
  63. function getCulture()
  64. {
  65. return $this->locale;
  66. }
  67. public function refreshProperties(Node $node)
  68. {
  69. $this->urlIdentifier = $node->getUrlIdentifier($this->locale);
  70. $this->url_provider = $node->getUrlProvider();
  71. $this->open_target_provider = $node->getOpenTargetProvider();
  72. $this->title = $node->getTitle();
  73. $this->subTitle = $node->getSubTitle();
  74. $this->visible = $node->getIsVisibleInMenu();
  75. $this->nodeClass = $node->getNodeClass();
  76. $this->id = $node->getId();
  77. $this->credentials = $node->getCredentials();
  78. $this->menu_title = $node->getMenuTitle();
  79. $this->permsType = $node->getPermsType();
  80. $this->seo_keywords_type = $node->getSeoKeywordsType();
  81. $this->seo_keywords_content = $node->getSeoKeywordsContent($this->locale);
  82. $this->seo_description_type = $node->getSeoDescriptionType();
  83. $this->seo_description_content = $node->getSeoDescriptionContent($this->locale);
  84. $this->current_layout_content = $node->getCurrentLayout();
  85. $this->current_layout_type = $node->getCurrentLayoutType();
  86. $this->browser_title_type = $node->getBrowserTitleType();
  87. $this->browser_title_content = $node->getBrowserTitleContent($this->locale);
  88. }
  89. function setUrlIdentifier($value)
  90. {
  91. $this->urlIdentifier = $value;
  92. }
  93. function setBrowserTitleType($value)
  94. {
  95. $this->browser_title_type = $value;
  96. }
  97. function getBrowserTitleType()
  98. {
  99. return $this->browser_title_type;
  100. }
  101. function getBrowserTitleContent()
  102. {
  103. return $this->browser_title_content;
  104. }
  105. function setBrowserTitleContent($value)
  106. {
  107. $this->browser_title_content = $value;
  108. }
  109. function isVisibleInMenu()
  110. {
  111. return $this->visible;
  112. }
  113. function getUrl($locale = null, $force_script_name = true)
  114. {
  115. if (null == $locale) {
  116. $locale = $this->locale;
  117. }
  118. if ($this->mockTranslation || $locale != $this->locale) {
  119. // $this->mockTranslation &&
  120. $localizedContentTree = ContentTree::instance($locale);
  121. $localizedContentTree->build();
  122. $localizedNode = $localizedContentTree->getContentTreeNodeById($this->getId());
  123. // var_dump($localizedNode);exit;
  124. return $localizedNode->getUrl(null, $force_script_name);
  125. }
  126. $default = '';
  127. if (null == $this->parent && count(sfConfig::get('app_translations_available_languages')) > 1) {
  128. $default = '/' . $locale;
  129. } else {
  130. $node = $this;
  131. if (!$node->parent) {
  132. $default = '/';
  133. } else {
  134. while ($node->parent) {
  135. $default = '/' . $node->getUrlIdentifier() . $default;
  136. $node = $node->parent;
  137. }
  138. if ($default != '/' && count(sfConfig::get('app_translations_available_languages')) > 1) {
  139. $default = '/' . $locale . $default;
  140. }
  141. }
  142. }
  143. if ($this->url_provider) {
  144. $className = $this->getNodeClass();
  145. return eval("return Node$className::getUrl(\$this, '$default');");
  146. }
  147. if ($force_script_name && !empty($_SERVER['SCRIPT_NAME']) && !sfConfig::get('sf_no_script_name')) {
  148. $default = $_SERVER['SCRIPT_NAME'] . $default;
  149. }
  150. return $default;
  151. }
  152. function getOpenTarget()
  153. {
  154. if ($this->open_target_provider) {
  155. $className = $this->getNodeClass();
  156. return eval("return Node$className::getOpenTarget(\$this);");
  157. }
  158. return '_self';
  159. }
  160. function getUrlIdentifier()
  161. {
  162. return $this->urlIdentifier;
  163. }
  164. function getId()
  165. {
  166. return $this->id;
  167. }
  168. function getNodeClass()
  169. {
  170. return $this->nodeClass;
  171. }
  172. function getPage()
  173. {
  174. // printf('Id: %s, Class: %s', $this->getId(), $this->getNodeClass());
  175. return Catalyz::getPageByNodeIdAndClass($this->getId(), $this->getNodeClass(), $this->getCulture());
  176. }
  177. protected $node = null;
  178. /**
  179. *
  180. * @return Node
  181. */
  182. function getNode()
  183. {
  184. // var_dump($this->getId());
  185. if (empty($this->node)) {
  186. $criteria = new Criteria();
  187. $criteria->add(NodePeer::ID, $this->getId());
  188. $nodes = NodePeer::doSelectWithI18n($criteria, $this->getOwnerTree()->getCulture());
  189. if (count($nodes) > 0) {
  190. $this->node = array_shift($nodes);
  191. } else {
  192. $criteria = new Criteria();
  193. $criteria->add(NodePeer::ID, $this->getId());
  194. $nodes = NodePeer::doSelectWithI18n($criteria, sfConfig::get('app_translations_default_language'));
  195. if (count($nodes) > 0) {
  196. $this->node = array_shift($nodes);
  197. } else {
  198. $this->node = null;
  199. }
  200. }
  201. }
  202. return $this->node;
  203. }
  204. function getTitle()
  205. {
  206. return $this->title;
  207. }
  208. function setTitle($value)
  209. {
  210. $this->title = $value;
  211. }
  212. function getMenuTitle()
  213. {
  214. return $this->menu_title;
  215. }
  216. function getSubTitle()
  217. {
  218. return $this->subTitle;
  219. }
  220. function setSubTitle($value)
  221. {
  222. $this->subTitle = $value;
  223. }
  224. function addChild($treeNode)
  225. {
  226. $this->children[] = $treeNode;
  227. $treeNode->parent = $this;
  228. if (count($this->children) > 1) {
  229. $prevSibling = $this->children[count($this->children) - 2];
  230. $prevSibling->nextSibling = $treeNode;
  231. $treeNode->previousSibling = $prevSibling;
  232. }
  233. // printf('%s is now a child of %s<br />', $treeNode->getCaption(), $this->getCaption());
  234. }
  235. function getChildByUrlIdentifier($urlIdentifier)
  236. {
  237. foreach($this->children as $child) {
  238. if ($child->getUrlIdentifier() == $urlIdentifier) {
  239. return $child;
  240. }
  241. }
  242. return null;
  243. }
  244. function getVisibleChildren()
  245. {
  246. $result = array();
  247. foreach($this->children as $child) {
  248. if ($child->isVisibleInMenu()) {
  249. $result[] = $child;
  250. }
  251. }
  252. return $result;
  253. }
  254. function getChildren()
  255. {
  256. return $this->children;
  257. }
  258. function isActive()
  259. {
  260. return $this->active;
  261. }
  262. function getActiveChildren()
  263. {
  264. foreach($this->children as $child) {
  265. if ($child->isActive()) {
  266. return $child;
  267. }
  268. }
  269. return null;
  270. }
  271. function getContentTreeNodeById($id)
  272. {
  273. if ($this->getId() == $id) {
  274. return $this;
  275. }
  276. foreach($this->children as $child) {
  277. $result = $child->getContentTreeNodeById($id);
  278. if (null != $result) {
  279. return $result;
  280. }
  281. }
  282. return null;
  283. }
  284. public function getPermsData()
  285. {
  286. if ($this->permsType == Node::PERMS_INHERIT) {
  287. if (is_null($this->parent)) {
  288. return array(Node::PERMS_ALLOWED_TO_ANYBODY, '');
  289. }
  290. return $this->parent->getPermsData();
  291. }
  292. if ($this->permsType == Node::PERMS_ALLOWED_TO_ANYBODY) {
  293. return array(Node::PERMS_ALLOWED_TO_ANYBODY, '');
  294. }
  295. if ($this->permsType == Node::PERMS_RESTRICTED) {
  296. return array(Node::PERMS_RESTRICTED, $this->credentials);
  297. }
  298. throw new Exception('Unknown permission type: ' . $this->permsType);
  299. }
  300. public function getSeoKeywords()
  301. {
  302. switch ($this->getSeoKeywordsType()) {
  303. case Node::SEO_KEYWORDS_CUSTOM:
  304. return $this->getSeoKeywordsContent();
  305. case Node::SEO_KEYWORDS_INHERIT:
  306. if ($this->parent) {
  307. return $this->parent->getSeoKeywords();
  308. } else {
  309. return '';
  310. }
  311. } // switch
  312. return '';
  313. }
  314. public function getSeoKeywordsType(){
  315. return $this->seo_keywords_type;
  316. }
  317. public function setSeoKeywordsType($value)
  318. {
  319. $this->seo_keywords_type = $value;
  320. }
  321. public function getSeoKeywordsContent()
  322. {
  323. return $this->seo_keywords_content;
  324. }
  325. public function setSeoKeywordsContent($value)
  326. {
  327. $this->seo_keywords_content = $value;
  328. }
  329. public function getSeoDescription()
  330. {
  331. switch ($this->getSeoDescriptionType()) {
  332. case Node::SEO_DESCRIPTION_CUSTOM:
  333. return $this->getSeoDescriptionContent();
  334. case Node::SEO_DESCRIPTION_INHERIT:
  335. if ($this->parent) {
  336. return $this->parent->getSeoDescription();
  337. } else {
  338. return '';
  339. }
  340. } // switch
  341. return '';
  342. }
  343. public function getSeoDescriptionType(){
  344. return $this->seo_description_type;
  345. }
  346. public function setSeoDescriptionType($value)
  347. {
  348. $this->seo_description_type = $value;
  349. }
  350. public function getSeoDescriptionContent()
  351. {
  352. return $this->seo_description_content;
  353. }
  354. public function setSeoDescriptionContent($value)
  355. {
  356. $this->seo_description_content = $value;
  357. }
  358. public function getCurrentLayoutForAction()
  359. {
  360. switch ($this->current_layout_type) {
  361. case Node::LAYOUT_INHERIT:
  362. if (!$this->parent) {
  363. return $this->current_layout_content;
  364. } else {
  365. return $this->parent->getCurrentLayoutForAction();
  366. }
  367. case Node::LAYOUT_CUSTOM:
  368. return $this->current_layout_content;
  369. default:
  370. throw new Exception('Unknown CurrentLayoutType value: ' . $this->current_layout_type);
  371. }
  372. }
  373. // function getCurrentLayoutForAction()
  374. // {
  375. // switch ($this->getCurrentLayoutType()) {
  376. // case self::LAYOUT_INHERIT:
  377. // // printf('%s -&gt; isRoot: %d<br />', $this->getTitle(), $this->isRoot());
  378. // if ($this->isRoot()) {
  379. // return $this->getCurrentLayout();
  380. // } else {
  381. // return $this->getParent()->getCurrentLayoutForAction();
  382. // }
  383. // case self::LAYOUT_CUSTOM:
  384. // return $this->getCurrentLayout();
  385. // // case self::LAYOUT_USE_CURRENT:
  386. // // return $this->getCurrentLayout();
  387. // default:
  388. // throw new Exception('Unknown CurrentLayoutType value: ' . $this->getCurrentLayoutType());
  389. // }
  390. // }
  391. protected function formatLayoutName($layoutIdentifier)
  392. {
  393. return explode('/', $layoutIdentifier);
  394. }
  395. function getCurrentLayoutNameForAction()
  396. {
  397. return $this->formatLayoutName($this->getCurrentLayoutForAction());
  398. }
  399. public function canViewContent()
  400. {
  401. list($perms_type, $credentials) = $this->getPermsData();
  402. switch ($perms_type) {
  403. case Node::PERMS_ALLOWED_TO_ANYBODY:
  404. return true;
  405. case Node::PERMS_RESTRICTED:
  406. $credentials = explode('|', $credentials);
  407. $sfUser = sfContext::getInstance()->getUser();
  408. // var_dump($credentials);exit;
  409. return $sfUser->hasCredential(CREDENTIAL_WEBMASTER) || $sfUser->hasCredential($credentials, false);
  410. default:
  411. return false;
  412. } // switch
  413. }
  414. public function canContentBeSeenByAnonymous()
  415. {
  416. list($perms_type, $credentials) = $this->getPermsData();
  417. return $perms_type == Node::PERMS_ALLOWED_TO_ANYBODY;
  418. }
  419. public function hasPendingDelete()
  420. {
  421. return $this->pending_delete;
  422. }
  423. public function setPendingDelete($value)
  424. {
  425. $this->pending_delete = $value;
  426. }
  427. public function getFirstChildByClass($class, $recursive = false)
  428. {
  429. if (count($this->children) == 0) {
  430. return null;
  431. }
  432. $node = $this->children[0];
  433. do {
  434. if ($node->getNodeClass() == $class) {
  435. return $node;
  436. }
  437. if($recursive && count($node->children)>0){
  438. $result = $node->getFirstChildByClass($class, $recursive);
  439. if(null != $result){
  440. return $result;
  441. }
  442. }
  443. $node = $node->nextSibling;
  444. } while ($node);
  445. return null;
  446. }
  447. function cacheChildrenPages()
  448. {
  449. $children_pages = array();
  450. foreach ($this->getChildren() as $child) {
  451. $children_pages[$child->getNodeClass()][] = $child->getId();
  452. }
  453. foreach ($children_pages as $node_class => $node_ids) {
  454. Catalyz::cachePageByNodeIdsAndClass($node_ids, $node_class);
  455. }
  456. }
  457. function getNumberOfDescendants()
  458. {
  459. $result = 0;
  460. foreach($this->children as $child) {
  461. $result += $child->getNumberOfDescendants() + 1 ;
  462. }
  463. return $result;
  464. }
  465. function getAvailableTranslations($force_locale_culture = false)
  466. {
  467. if (null == $this->getId()) {
  468. return array();
  469. }
  470. return $this->getNode()->getAvailableTranslations($force_locale_culture);
  471. }
  472. function getAll()
  473. {
  474. $result = $this->children;
  475. foreach($this->children as $child) {
  476. $result = array_merge($result, $child->getAll());
  477. }
  478. return $result;
  479. }
  480. function getBreadcrum($separator = ' > ', $truncate = false)
  481. {
  482. sfLoader::loadHelpers(array('Text'));
  483. $title = $this->getTitle();
  484. if ($truncate && 0 < $truncate) {
  485. $title = truncate_text($title, $truncate);
  486. }
  487. $result = $title;
  488. $parent = $this->parent;
  489. while ($parent && $parent->parent) {
  490. $title = $parent->getTitle();
  491. if ($truncate && 0 < $truncate) {
  492. $title = truncate_text($title, $truncate);
  493. }
  494. $result = $title . $separator . $result;
  495. $parent = $parent->parent;
  496. }
  497. return $result;
  498. }
  499. /**
  500. * ContentTreeNode::getPathToCacheFile()
  501. *
  502. * @param string $culture
  503. * @return string
  504. */
  505. public function getPathToCacheFile($culture = '')
  506. {
  507. return sprintf('%s/cache%s.html', sfConfig::get('sf_web_dir'), $this->getUrl($culture, false));
  508. }
  509. public function isTranslationAvailable($culture)
  510. {
  511. $translations = $this->getAvailableTranslations();
  512. return !empty($translations[$culture]);
  513. }
  514. /**
  515. * ContentTreeNode::setMenuTitle()
  516. *
  517. * @param mixed $node
  518. * @return
  519. */
  520. public function setMenuTitle($value)
  521. {
  522. $this->menu_title = $value;
  523. }
  524. function isChildOfNodeId($nodeId)
  525. {
  526. $result = false;
  527. $parent = $this->parent;
  528. while (!$result && $parent) {
  529. $result = $parent->getId() == $nodeId;
  530. $parent = $parent->parent;
  531. }
  532. return $result;
  533. }
  534. }
  535. ?>