Autodoc
  • Namespace
  • Class
  • Tree

Namespaces

  • BlueTihi
    • Context
  • Brickrouge
    • Element
      • Nodes
    • Renderer
    • Widget
  • ICanBoogie
    • ActiveRecord
    • AutoConfig
    • CLDR
    • Composer
    • Core
    • Event
    • Exception
    • HTTP
      • Dispatcher
      • Request
    • I18n
      • Translator
    • Mailer
    • Modules
      • Taxonomy
        • Support
      • Thumbnailer
        • Versions
    • Object
    • Operation
      • Dispatcher
    • Prototype
    • Routes
    • Routing
      • Dispatcher
    • Session
  • Icybee
    • ActiveRecord
      • Model
    • ConfigOperation
    • Document
    • EditBlock
    • Element
      • ActionbarContextual
      • ActionbarSearch
      • ActionbarToolbar
    • FormBlock
    • Installer
    • ManageBlock
    • Modules
      • Articles
      • Cache
        • Collection
        • ManageBlock
      • Comments
        • ManageBlock
      • Contents
        • ManageBlock
      • Dashboard
      • Editor
        • Collection
      • Files
        • File
        • ManageBlock
      • Forms
        • Form
        • ManageBlock
      • I18n
      • Images
        • ManageBlock
      • Members
      • Modules
        • ManageBlock
      • Nodes
        • ManageBlock
        • Module
      • Pages
        • BreadcrumbElement
        • LanguagesElement
        • ManageBlock
        • NavigationBranchElement
        • NavigationElement
        • Page
        • PageController
      • Registry
      • Search
      • Seo
      • Sites
        • ManageBlock
      • Taxonomy
        • Terms
          • ManageBlock
        • Vocabulary
          • ManageBlock
      • Users
        • ManageBlock
        • NonceLogin
        • Roles
      • Views
        • ActiveRecordProvider
        • Collection
        • View
    • Operation
      • ActiveRecord
      • Constructor
      • Module
      • Widget
    • Rendering
  • None
  • Patron
  • PHP

Classes

  • Blueprint
  • BlueprintNode
  • BreadcrumbElement
  • Content
  • ContentModel
  • CopyOperation
  • DeleteOperation
  • EditBlock
  • ExportBlock
  • ExportOperation
  • Hooks
  • ImportOperation
  • LanguagesElement
  • ListView
  • ManageBlock
  • Model
  • Module
  • NavigationBranchElement
  • NavigationElement
  • NavigationExcludeOperation
  • NavigationIncludeOperation
  • Page
  • PageController
  • PopPage
  • PopTemplate
  • QueryOperationOperation
  • SaveOperation
  • TemplateEditorsOperation
  • UpdateTreeOperation
  1 <?php
  2 
  3 /*
  4  * This file is part of the Icybee package.
  5  *
  6  * (c) Olivier Laviale <olivier.laviale@gmail.com>
  7  *
  8  * For the full copyright and license information, please view the LICENSE
  9  * file that was distributed with this source code.
 10  */
 11 
 12 namespace Icybee\Modules\Pages;
 13 
 14 use ICanBoogie\Routing\Pattern;
 15 
 16 use Icybee\Modules\Sites\Site;
 17 
 18 /**
 19  * Representation of a page.
 20  *
 21  * @property Page $parent Parent page of the page.
 22  * @property \Icybee\Modules\Sites\Site $site The site the page belongs to.
 23  * @property-read bool $is_accessible Whether the page is accessible or not.
 24  * @property-read bool $is_active Wheter the page is active or not.
 25  * @property-read bool $is_home Whether the page is the home page of the site or not.
 26  * @property-read bool $is_trail Whether the page is in the navigation trail or not.
 27  * @property-read array[]Page $navigation_children Navigation children of the page.
 28  * @property-read int $descendents_count The number of descendents.
 29  */
 30 class Page extends \Icybee\Modules\Nodes\Node
 31 {
 32     const PARENTID = 'parentid';
 33     const LOCATIONID = 'locationid';
 34     const PATTERN = 'pattern';
 35     const WEIGHT = 'weight';
 36     const TEMPLATE = 'template';
 37     const LABEL = 'label';
 38     const IS_NAVIGATION_EXCLUDED = 'is_navigation_excluded';
 39 
 40     /**
 41      * The identifier of the parent page.
 42      *
 43      * @var int
 44      */
 45     public $parentid;
 46 
 47     /**
 48      * The identifier of the page the page is redirected to.
 49      *
 50      * @var int
 51      */
 52     public $locationid;
 53 
 54     /**
 55      * The pattern used to create the URL of the nodes displayed by the page.
 56      *
 57      * @var string
 58      */
 59     public $pattern;
 60 
 61     /**
 62      * Weight of the page in the hierarchy.
 63      *
 64      * @var int
 65      */
 66     public $weight;
 67 
 68     /**
 69      * Template used to render the page.
 70      *
 71      * @var string
 72      */
 73     public $template;
 74 
 75     /**
 76      * Returns the template for the page.
 77      *
 78      * This function is only called if the {@link pattern} property was empty during construct. The
 79      * template is guested according the place of the page in the hierarchy:
 80      *
 81      * - The page is the home page: `home.html`
 82      * - The page has a parent which is not the home page: the template of the parent.
 83      * - Otherwise: `page.html`
 84      *
 85      * @return string
 86      */
 87     protected function get_template()
 88     {
 89         if ($this->is_home)
 90         {
 91             return 'home.html';
 92         }
 93         else if ($this->parent && !$this->parent->is_home)
 94         {
 95             return $this->parent->template;
 96         }
 97 
 98         return 'page.html';
 99     }
100 
101     /**
102      * Returns the extension used by the page's template.
103      *
104      * @return string ".html" if the template is "page.html".
105      */
106     protected function get_extension()
107     {
108         $extension = pathinfo($this->template, PATHINFO_EXTENSION);
109 
110         return $extension ? '.' . $extension : null;
111     }
112 
113     /**
114      * The text to use instead of the title when it is used in the navigation of the breadcrumb.
115      *
116      * @var string
117      */
118     public $label;
119 
120     /**
121      * Returns the label for the page.
122      *
123      * This function is only called if the {@link label} property was empty during construct. It
124      * returns the {@link $title} property.
125      *
126      * @return string
127      */
128     protected function get_label()
129     {
130         return $this->title;
131     }
132 
133     /**
134      * Whether the page is excluded from the navigation.
135      *
136      * @var bool
137      */
138     public $is_navigation_excluded;
139 
140     /**
141      * @var string Part of the URL captured by the pattern.
142      * @todo-20130307: rename as "path_part"
143      */
144     public $url_part;
145 
146     /**
147      * @var array Variables captured from the URL using the pattern.
148      * @todo-20130327: rename as "path_params"
149      */
150     public $url_variables = array();
151 
152     /**
153      * @var Node Node object currently acting as the body of the page.
154      * @todo-20130327: use request's context instead
155      */
156     public $node;
157 
158     /**
159      * @var bool true if the page is cachable, false otherwise.
160      */
161     public $cachable = true;
162 
163     public function __construct($model='pages')
164     {
165         if (empty($this->label))
166         {
167             unset($this->label);
168         }
169 
170         if (empty($this->template))
171         {
172             unset($this->template);
173         }
174 
175         parent::__construct($model);
176     }
177 
178     public function __sleep()
179     {
180         $keys = parent::__sleep();
181 
182         // TODO-20130327: is this necessary?
183 
184         if (isset($this->template))
185         {
186             $keys['template'] = 'template';
187         }
188 
189         return $keys;
190     }
191 
192     /**
193      * Returns the previous online sibling for the page.
194      *
195      * @return Page|false The previous sibling, or false if there is none.
196      */
197     protected function lazy_get_previous()
198     {
199         return $this->model
200         ->where('is_online = 1 AND nid != ? AND parentid = ? AND siteid = ? AND weight <= ?', $this->nid, $this->parentid, $this->siteid, $this->weight)
201         ->order('weight desc, created_at desc')->one;
202     }
203 
204     /**
205      * Returns the next online sibling for the page.
206      *
207      * @return Page|false The next sibling, or false if there is none.
208      */
209     protected function lazy_get_next()
210     {
211         return $this->model
212         ->where('is_online = 1 AND nid != ? AND parentid = ? AND siteid = ? AND weight >= ?', $this->nid, $this->parentid, $this->siteid, $this->weight)
213         ->order('weight, created_at')->one;
214     }
215 
216     /**
217      * Returns the URL of the page.
218      *
219      * @return string
220      */
221     protected function lazy_get_url()
222     {
223         global $core;
224 
225         if ($this->location)
226         {
227             return $this->location->url;
228         }
229 
230         $url_pattern = $this->url_pattern;
231 
232         if ($this->is_home)
233         {
234             return $url_pattern;
235         }
236 
237         $url = null;
238 
239         if (Pattern::is_pattern($url_pattern))
240         {
241             if ($this->url_variables)
242             {
243                 $url = Pattern::from($url_pattern)->format($this->url_variables);
244 
245 //              \ICanBoogie\log('URL %pattern rescued using URL variables', array('%pattern' => $pattern));
246             }
247             else
248             {
249                 $page = isset($core->request->context->page) ? $core->request->context->page : null;
250 
251                 if ($page && $page->url_variables)
252                 {
253                     $url = Pattern::from($url_pattern)->format($page->url_variables);
254 
255 //                  \ICanBoogie\log("URL pattern %pattern was resolved using current page's variables", array('%pattern' => $pattern));
256                 }
257                 else
258                 {
259                     $url = '#url-pattern-could-not-be-resolved';
260                 }
261             }
262         }
263         else
264         {
265             $url = $url_pattern;
266         }
267 
268         return $url;
269     }
270 
271     /**
272      * Returns the absulte URL of the pages.
273      *
274      * @return string The absolute URL of the page.
275      */
276     protected function lazy_get_absolute_url()
277     {
278         $site = $this->site;
279 
280         return $site->url . substr($this->url, strlen($site->path));
281     }
282 
283     public function translation($language=null)
284     {
285         $translation = parent::translation($language);
286 
287         if ($translation->nid != $this->nid && isset($this->url_variables))
288         {
289             $translation->url_variables = $this->url_variables;
290         }
291 
292         return $translation;
293     }
294 
295     protected function lazy_get_translations()
296     {
297         $translations = parent::lazy_get_translations();
298 
299         if (!$translations || empty($this->url_variables))
300         {
301             return $translations;
302         }
303 
304         foreach ($translations as $translation)
305         {
306             $translation->url_variables = $this->url_variables;
307         }
308 
309         return $translations;
310     }
311 
312     /**
313      * Returns the URL pattern of the page.
314      *
315      * @return string
316      */
317     protected function lazy_get_url_pattern()
318     {
319         $site = $this->site;
320 
321         if ($this->is_home)
322         {
323             return $site->path . '/';
324         }
325 
326         $parent = $this->parent;
327         $pattern = $this->pattern;
328 
329         return ($parent ? $parent->url_pattern : $site->path . '/')
330         . ($pattern ? $pattern : $this->slug)
331         . ($this->has_child ? '/' : $this->extension);
332     }
333 
334     /**
335      * Returns if the page is accessible or not in the navigation tree.
336      */
337     protected function get_is_accessible()
338     {
339         global $core;
340 
341         if ($core->user->is_guest && $this->site->status != Site::STATUS_OK)
342         {
343             return false;
344         }
345 
346         return ($this->parent && !$this->parent->is_accessible) ? false : $this->is_online;
347     }
348 
349     /**
350      * Checks if the page is the home page.
351      *
352      * A page is considered a home page when the page has no parent, its weight value is zero and
353      * it is online.
354      *
355      * @return bool `true` if the page record is the home page, `false` otherwise.
356      */
357     protected function get_is_home()
358     {
359         return (!$this->parentid && !$this->weight && $this->is_online);
360     }
361 
362     /**
363      * Checks if the page record is the active page.
364      *
365      * The global variable `page` must be defined in order to identify the active page.
366      *
367      * @return bool true if the page record is the active page, false otherwise.
368      *
369      * @todo-20130327: create the set_active_page() and get_active_page() helpers ?
370      */
371     protected function get_is_active()
372     {
373         global $core;
374 
375         return $core->request->context->page->nid == $this->nid;
376     }
377 
378     /**
379      * Checks if the page record is in the active page trail.
380      *
381      * The global variable `page` must be defined in order to identifiy the active page.
382      *
383      * @return bool true if the page is in the active page trail, false otherwise.
384      */
385     protected function get_is_trail()
386     {
387         global $core;
388 
389         $node = $core->request->context->page; // TODO-20130327: use a get_active_page() helper?
390 
391         while ($node)
392         {
393             if ($node->nid == $this->nid)
394             {
395                 return true;
396             }
397 
398             $node = $node->parent;
399         }
400 
401         return false;
402     }
403 
404     /**
405      * Returns the location target for the page record.
406      *
407      * @return Icybee\Modules\Pages\Page|null The location target, or null if there is none.
408      */
409     protected function get_location()
410     {
411         return $this->locationid ? $this->model[$this->locationid] : null;
412     }
413 
414     /**
415      * Returns the home page for the page record.
416      *
417      * @return Icybee\Modules\Pages\Page
418      */
419     protected function get_home()
420     {
421         return $this->model->find_home($this->siteid);
422     }
423 
424     /**
425      * Returns the parent of the page.
426      *
427      * @return Icybee\Modules\Pages\Page|null The parent page or null is the page has no parent.
428      */
429     protected function lazy_get_parent()
430     {
431         return $this->parentid ? $this->model[$this->parentid] : null;
432     }
433 
434     /**
435      * Return the online children page for this page.
436      *
437      * TODO-20100629: The `children` virtual property should return *all* the children for the page,
438      * we should create a `online_children` virtual property that returns only _online_ children,
439      * or maybe a `accessible_children` virtual property ?
440      */
441     protected function lazy_get_children()
442     {
443         $blueprint = $this->model->blueprint($this->siteid);
444         $pages = $blueprint['pages'];
445 
446         if (!$pages[$this->nid]->children)
447         {
448             return array();
449         }
450 
451         $ids = array();
452 
453         foreach ($pages[$this->nid]->children as $nid => $child)
454         {
455             if (!$child->is_online)
456             {
457                 continue;
458             }
459 
460             $ids[] = $nid;
461         }
462 
463         return $this->model->find($ids);
464     }
465 
466     /**
467      * Returns the page's children that are online and part of the navigation.
468      *
469      * @return array[int]Page
470      */
471     protected function lazy_get_navigation_children()
472     {
473         $index = $this->model->blueprint($this->siteid)->index;
474 
475         if (empty($index[$this->nid]) || !$index[$this->nid]->children)
476         {
477             return array();
478         }
479 
480         $ids = array();
481 
482         foreach ($index[$this->nid]->children as $nid => $child)
483         {
484             if (!$child->is_online || $child->is_navigation_excluded || $child->pattern)
485             {
486                 continue;
487             }
488 
489             $ids[] = $nid;
490         }
491 
492         if (!$ids)
493         {
494             return array();
495         }
496 
497         return $this->model->find($ids);
498     }
499 
500     /**
501      * Checks if the page as at least one child.
502      *
503      * @return boolean
504      */
505     protected function get_has_child()
506     {
507         return $this->model->blueprint($this->siteid)->has_children($this->nid);
508     }
509 
510     /**
511      * Returns the number of children.
512      *
513      * @return int
514      */
515     protected function get_children_count()
516     {
517         return $this->model->blueprint($this->siteid)->children_count($this->nid);
518     }
519 
520     /**
521      * Returns the number of descendent.
522      *
523      * @return int
524      */
525     protected function get_descendents_count()
526     {
527         return $this->model->blueprint($this->siteid)->index[$this->nid]->descendents_count;
528     }
529 
530     /**
531      * Returns the depth level of this page in the navigation tree.
532      */
533     protected function get_depth()
534     {
535         return $this->parent ? $this->parent->depth + 1 : 0;
536     }
537 
538     /**
539      * Returns the contents of the page as an array.
540      *
541      * Keys of the array are the contentid, values are the contents objects.
542      *
543      * @return array[string]\Icybee\Modules\Pages\Pages\Content
544      */
545     protected function lazy_get_contents()
546     {
547         global $core;
548 
549         $entries = $core->models['pages/contents']->filter_by_pageid($this->nid);
550         $contents = array();
551 
552         foreach ($entries as $entry)
553         {
554             $contents[$entry->contentid] = $entry;
555         }
556 
557         return $contents;
558     }
559 
560     /**
561      * Returns the body of this page.
562      *
563      * The body is the page's contents object with the 'body' identifier.
564      *
565      * @return \Icybee\Modules\Pages\Pages\Content
566      */
567     protected function lazy_get_body()
568     {
569         $contents = $this->contents;
570 
571         return isset($contents['body']) ? $contents['body'] : null;
572     }
573 
574     /**
575      * Replaces `type` value by "page" and `id` value by "page-id-<nid>".
576      *
577      * The following class names are added:
578      *
579      * - `slug`: "page-slug-<slug>"
580      * - `home`: true if the page is the home page.
581      * - `active`: true if the page is the active page.
582      * - `trail`: true if the page is in the breadcrumb trail.
583      * - `node-id`: "node-id-<nid>" if the page displays a node.
584      * - `node-constructor`: "node-constructor-<normalized_constructor>" if the page displays a node.
585      * - `template`: "template-<name>" the name of the page's template, without its extension.
586      */
587     protected function get_css_class_names()
588     {
589         $names = array_merge
590         (
591             parent::get_css_class_names(), array
592             (
593                 'type' => 'page',
594                 'id' => 'page-id-' . $this->nid,
595                 'slug' => 'page-slug-'. $this->slug,
596                 'home' => ($this->home->nid == $this->nid),
597                 'active' => $this->is_active,
598                 'trail' => $this->is_trail,
599                 'template' => 'template-' . preg_replace('#\.(html|php)$#', '', $this->template),
600                 'has-children' => count($this->navigation_children) != 0
601             )
602         );
603 
604         if (isset($this->node))
605         {
606             $node = $this->node;
607 
608             $names['node-id'] = 'node-id-' . $node->nid;
609             $names['node-constructor'] = 'node-constructor-' . \ICanBoogie\normalize($node->constructor);
610         }
611 
612         return $names;
613     }
614 
615     /**
616      * Return the description for the page.
617      */
618 
619     // TODO-20101115: these should be methods added by the "SEO" module
620 
621     protected function get_description()
622     {
623         return $this->metas['description'];
624     }
625 
626     protected function get_document_title()
627     {
628         return $this->metas['document_title'] ? $this->metas['document_title'] : $this->title;
629     }
630 }
Autodoc API documentation generated by ApiGen 2.8.0