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

  • CacheManager
  • ConfigBlock
  • ConfigOperation
  • Content
  • DeleteBlock
  • EditBlock
  • HomeExcludeOperation
  • HomeIncludeOperation
  • Hooks
  • ManageBlock
  • Model
  • Module
  • Rendered
  • SaveOperation
  • Update20140330
  • ViewProvider

Traits

  • DateProperty
  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\Contents;
 13 
 14 use ICanBoogie\ActiveRecord\DateTimePropertySupport;
 15 use ICanBoogie\DateTime;
 16 use ICanBoogie\PropertyNotWritable;
 17 
 18 /**
 19  * Representation of a content.
 20  *
 21  * The {@link Content} class extends the {@link \Icybee\Modules\Nodes\Node} class with the
 22  * following properties:
 23  *
 24  * - {@link $subtitle}: An optional subtitle.
 25  * - {@link $body}: A body (with a customizable editor).
 26  * - {@link $excerpt}: An optional excerpt, that can be generated from the body if it is not
 27  * defined.
 28  * - {@link $date}: The date of the content.
 29  * - {@link $editor}: The editor used to edit the body of the content.
 30  * - {@link $is_home_excluded}: An additionnal visibility option.
 31  *
 32  * @property \ICanBoogie\DateTime $date The date of the content.
 33  */
 34 class Content extends \Icybee\Modules\Nodes\Node
 35 {
 36     const SUBTITLE = 'subtitle';
 37     const BODY = 'body';
 38     const EXCERPT = 'excerpt';
 39     const DATE = 'date';
 40     const EDITOR = 'editor';
 41     const IS_HOME_EXCLUDED = 'is_home_excluded';
 42 
 43     /**
 44      * Sets the {@link $rendered_body} property of the loaded records if suitable rendered bodies
 45      * are available in the cache.
 46      *
 47      * @param \Icybee\Modules\Views\ActiveRecordProvider\AlterResultEvent $event
 48      * @param \Icybee\Modules\Views\ActiveRecordProvider $target
 49      */
 50     static public function on_views_activerecordprovider_alter_result(\Icybee\Modules\Views\ActiveRecordProvider\AlterResultEvent $event, \Icybee\Modules\Views\ActiveRecordProvider $target)
 51     {
 52         if (!is_array($event->result) || !($event->module instanceof Module))
 53         {
 54             return;
 55         }
 56 
 57         $cache = self::obtain_cache();
 58 
 59         if (!$cache)
 60         {
 61             return;
 62         }
 63 
 64         $records = $event->result;
 65         $record = current($records);
 66 
 67         if (!($record instanceof Content))
 68         {
 69             return;
 70         }
 71 
 72         $keys_and_dates = [];
 73 
 74         /* @var $record Content */
 75 
 76         foreach ($records as $record)
 77         {
 78             $keys_and_dates[$record->nid] = $record->updated_at;
 79         }
 80 
 81         if (!$keys_and_dates)
 82         {
 83             return;
 84         }
 85 
 86         /* @var $rendered_list_by_nid Rendered[] */
 87         /* @var $rendered Rendered */
 88 
 89         $rendered_list_by_nid = [];
 90 
 91         foreach ($cache->filter_by_nid(array_keys($keys_and_dates)) as $rendered)
 92         {
 93             $rendered_list_by_nid[$rendered->nid] = $rendered;
 94         }
 95 
 96         foreach ($records as $record)
 97         {
 98             $nid = $record->nid;
 99 
100             if (empty($rendered_list_by_nid[$nid]))
101             {
102                 continue;
103             }
104 
105             $rendered = $rendered_list_by_nid[$nid];
106 
107             if ($record->updated_at > $rendered->updated_at)
108             {
109                 continue;
110             }
111 
112             $record->rendered_body = $rendered->body;
113         }
114     }
115 
116     /**
117      * Subtitle.
118      *
119      * @var string
120      */
121     public $subtitle;
122 
123     /**
124      * Body of the content.
125      *
126      * The body needs to be rendered by its editor in order to obtain the real body.
127      *
128      * @var string
129      */
130     public $body;
131 
132     /**
133      * An excerpt of the body.
134      *
135      * @var string
136      */
137     public $excerpt;
138 
139     /**
140      * Returns an excerpt of the body.
141      *
142      * The getter is invoked when the {@link $excerpt} property is not accessible.
143      *
144      * @return string
145      */
146     protected function get_excerpt()
147     {
148         return \ICanBoogie\excerpt((string) $this);
149     }
150 
151     use DateProperty;
152 
153     /**
154      * The identifier of the editor that was used to edit the body.
155      *
156      * @var string
157      */
158     public $editor;
159 
160     /**
161      * `true` if the content should not appear on the "home" view.
162      *
163      * @var bool
164      */
165     public $is_home_excluded;
166 
167     /**
168      * The {@link $excerpt} property is unset if it is empty, until it is defined again, the
169      * {@link get_excerpt()} getter provides a default value made from the {@link $body}
170      * property.
171      *
172      * @param Model|string $model Defaults to "contents".
173      */
174     public function __construct($model='contents')
175     {
176         if (empty($this->excerpt))
177         {
178             unset($this->excerpt);
179         }
180 
181         parent::__construct($model);
182     }
183 
184     /**
185      * @var bool|null true is the cache should be used, false if the cache should not be used, and
186      * null if we don't yet know if the cache should be used or not.
187      */
188     static private $use_cache;
189     static private $cache_model;
190 
191     static private function obtain_cache()
192     {
193         global $core;
194 
195         if (self::$cache_model)
196         {
197             return self::$cache_model;
198         }
199 
200         if (self::$use_cache === null)
201         {
202             self::$use_cache = !empty($core->registry['contents.cache_rendered_body']);
203         }
204 
205         if (!self::$use_cache)
206         {
207             return;
208         }
209 
210         return self::$cache_model = $core->models['contents/rendered'];
211     }
212 
213     private $rendered_body;
214 
215     /**
216      * Renders the body of the activerecord into a string.
217      *
218      * The body is rendered using the editor that was used to edit the content.
219      *
220      * A cache maybe used to store et retrieve the rendered content.
221      *
222      * @return string The rendered body.
223      */
224     public function __toString()
225     {
226         global $core;
227 
228         $rendered_body = $this->rendered_body;
229 
230         if ($rendered_body)
231         {
232             return $rendered_body;
233         }
234 
235         $rendered_body = $body = $this->body;
236 
237         try
238         {
239             $cache = self::obtain_cache();
240 
241             if ($cache)
242             {
243                 $nid = $this->nid;
244                 $updated_at = $this->updated_at;
245                 $cached = $cache
246                 ->select('body')
247                 ->filter_by_nid_and_updated_at($nid, $updated_at)
248                 ->rc;
249 
250                 if ($cached)
251                 {
252                     return $cached;
253                 }
254 
255                 if ($this->editor)
256                 {
257                     $rendered_body = $this->render_body();
258                 }
259 
260                 if ($rendered_body && $rendered_body != $body)
261                 {
262                     $cache->save([
263 
264                         'nid' => $nid,
265                         'updated_at' => $updated_at,
266                         'body' => $rendered_body
267 
268                     ], null, [ 'on duplicate' => true ] );
269                 }
270             }
271             else if ($this->editor)
272             {
273                 $rendered_body = $this->render_body();
274             }
275         }
276         catch (\Exception $e)
277         {
278             $rendered_body = \ICanBoogie\Debug::format_alert($e);
279         }
280 
281         $this->rendered_body = $rendered_body;
282 
283         return $rendered_body;
284     }
285 
286     /**
287      * Renders the body using the associated editor.
288      *
289      * @return string
290      */
291     protected function render_body()
292     {
293         $body = $this->body;
294 
295         if (!$this->editor)
296         {
297             return $body;
298         }
299 
300         $editor = \ICanBoogie\Core::get()->editors[$this->editor];
301 
302         return (string) $editor->render($editor->unserialize($body));
303     }
304 
305     /**
306      * Returns the year of the date.
307      *
308      * @return string
309      */
310     protected function get_year()
311     {
312         return $this->get_date()->year;
313     }
314 
315     /**
316      * Returns the month of the date.
317      *
318      * @return string A padded string e.g. "02";
319      */
320     protected function get_month()
321     {
322         return $this->get_date()->format('m');
323     }
324 
325     /**
326      * Returns the day of the date.
327      *
328      * @return string A padded string e.g. "02";
329      */
330     protected function get_day()
331     {
332         return $this->get_date()->format('d');
333     }
334 
335     /**
336      * Overrides the method to support the `date` property.
337      */
338     protected function lazy_get_previous()
339     {
340         $ids = $this->model->select('nid')->order('date, created_at, nid')->own->visible->all(\PDO::FETCH_COLUMN);
341         $key = array_search($this->nid, $ids);
342 
343         return $key ? $this->model[$ids[$key - 1]] : null;
344     }
345 
346     /**
347      * Overrides the method to support the `date` property.
348      */
349     protected function lazy_get_next()
350     {
351         $ids = $this->model->select('nid')->order('date, created_at, nid')->own->visible->all(\PDO::FETCH_COLUMN);
352         $key = array_search($this->nid, $ids);
353 
354         return $key < count($ids) - 1 ? $this->model[$ids[$key + 1]] : null;
355     }
356 
357     /**
358      * Returns an excerpt of the content.
359      *
360      * If the {@link $excerpt} property is not empty the excerpt is created from it, otherwise it
361      * is created from the {@link $body}.
362      *
363      * @param number $limit The number of words desired.
364      *
365      * @return string
366      */
367     public function excerpt($limit=55)
368     {
369         return isset($this->excerpt) ? \ICanBoogie\excerpt($this->excerpt, $limit) : \ICanBoogie\excerpt((string) $this, $limit);
370     }
371 }
372 
373 /**
374  * Implements the`date` property.
375  *
376  * @property \ICanBoogie\DateTime $date The date of the record.
377  */
378 trait DateProperty
379 {
380     /**
381      * The date of the record.
382      *
383      * @var mixed
384      */
385     private $date;
386 
387     /**
388      * Returns the date of the record.
389      *
390      * @return \ICanBoogie\DateTime
391      */
392     protected function get_date()
393     {
394         return DateTimePropertySupport::datetime_get($this->date);
395     }
396 
397     /**
398      * Sets the date of the record.
399      *
400      * @param mixed $datetime
401      */
402     protected function set_date($datetime)
403     {
404         DateTimePropertySupport::datetime_set($this->date, $datetime);
405     }
406 }
Autodoc API documentation generated by ApiGen 2.8.0