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

  • AlterColumnsEvent
  • AlterQueryEvent
  • AlterRenderedCellsEvent
  • BooleanCellRenderer
  • BooleanColumn
  • CellRenderer
  • Column
  • DateColumn
  • DateTimeColumn
  • EditColumn
  • EditDecorator
  • FilterDecorator
  • HeaderRenderer
  • KeyColumn
  • Options
  • RegisterColumnsEvent
  • SizeColumn
  • Translator
  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\ManageBlock;
 13 
 14 use ICanBoogie\ActiveRecord\Query;
 15 
 16 use Brickrouge\DropdownMenu;
 17 use Brickrouge\Element;
 18 
 19 /**
 20  * Representation of a column of the manager element.
 21  *
 22  * This is the base class for all the columns.
 23  *
 24  * @property-read mixed $filter_value The value used by the column to filter the records.
 25  * @property-read bool $is_filtering `true` if the column is currently filtering the records.
 26  * `false` otherwise.
 27  */
 28 class Column extends \ICanBoogie\Object
 29 {
 30     const ORDER_ASC = 1;
 31     const ORDER_DESC = -1;
 32 
 33     public $id;
 34 
 35     public $title;
 36     public $class;
 37     public $filters;
 38     public $reset;
 39     public $orderable = false;
 40     public $order;
 41     public $default_order = self::ORDER_ASC;
 42     public $discreet = true;
 43 
 44     protected $header_renderer = 'Icybee\ManageBlock\HeaderRenderer';
 45     protected $cell_renderer = 'Icybee\ManageBlock\CellRenderer';
 46 
 47     public $manager;
 48 
 49     public function __construct(\Icybee\ManageBlock $manager, $id, array $options=array())
 50     {
 51         // TODO-20130627
 52 
 53         if (method_exists($this, 'update_filters'))
 54         {
 55             throw new \Exception("The <q>update_filters()</q> method is deprecated, please use the <q>alter_filters()</q> method.");
 56         }
 57 
 58         if (method_exists($this, 'alter_query'))
 59         {
 60             throw new \Exception("The <q>alter_query()</q> method is deprecated, please use the <q>alter_query_with_filter()</q> method.");
 61         }
 62 
 63         // /
 64 
 65         $this->manager = $manager;
 66         $this->id = $id;
 67 
 68         $this->modify_options($options + $this->resolve_default_values());
 69     }
 70 
 71     // TODO-20130627: remove this compat method
 72     protected function set_filtering()
 73     {
 74         throw new \InvalidArgumentException("The <q>filtering</q> property is deprecated. Use <q>is_filtering</q> or <q>filter_value</q>");
 75     }
 76 
 77     protected function set_label($value)
 78     {
 79         trigger_error("The <q>label</q> property is deprecated, use <q>title</q> instead.");
 80 
 81         $this->title = $value;
 82     }
 83 
 84     protected function get_label()
 85     {
 86         trigger_error("The <q>label</q> property is deprecated, use <q>title</q> instead.");
 87 
 88         return $this->title;
 89     }
 90 
 91     /**
 92      * Returns `true` if the column is filtering the records.
 93      *
 94      * @return boolean
 95      */
 96     protected function get_is_filtering()
 97     {
 98         return $this->manager->is_filtering($this->id);
 99     }
100 
101     /**
102      * Returns the value used by the column to filter the records.
103      *
104      * @return mixed|null
105      */
106     protected function get_filter_value()
107     {
108         return $this->is_filtering ? $this->manager->options->filters[$this->id] : null;
109     }
110 
111     /**
112      * Translates and formats the specified string.
113      *
114      * @param string $native
115      * @param array $args
116      * @param array $options
117      *
118      * @return string
119      */
120     public function t($native, array $args=array(), array $options=array())
121     {
122         return $this->manager->t($native, $args, $options);
123     }
124 
125     /**
126      * Returns the default values for the column initialization.
127      *
128      * @return array
129      */
130     protected function resolve_default_values()
131     {
132         $id = $this->id;
133         $fields = $this->manager->model->extended_schema['fields'];
134         $field = isset($fields[$id]) ? $fields[$id] : null;
135 
136         $orderable = true;
137         $default_order = 1;
138         $discreet = false;
139 
140         if ($field)
141         {
142             if (($field['type'] == 'integer' && (!empty($field['primary']) || !empty($field['indexed']))) || $field['type'] == 'boolean')
143             {
144                 $orderable = false;
145 
146                 if (!empty($field['indexed']))
147                 {
148                     $discreet = true;
149                 }
150             }
151 
152             if (in_array($field['type'], array('date', 'datetime', 'timestamp')))
153             {
154                 $default_order = -1;
155             }
156         }
157         else
158         {
159             $orderable = false;
160         }
161 
162         return array
163         (
164             'title' => $id,
165             'reset' => "?$id=",
166             'orderable' => $orderable,
167             'default_order' => $default_order
168         );
169     }
170 
171     /**
172      * Modifies the options of the column.
173      *
174      * @param array $options
175      *
176      * @return \Icybee\ManageBlock\Column
177      */
178     public function modify_options(array $options)
179     {
180         foreach ($options as $option => $value)
181         {
182             switch ($option)
183             {
184                 case 'label':
185                 case 'title':
186                 case 'class':
187                 case 'filters':
188                 case 'reset':
189                 case 'orderable':
190                 case 'order':
191                 case 'default_order':
192                 case 'discreet':
193                 case 'filtering':
194                 case 'header_renderer':
195                 case 'cell_renderer':
196                     $this->$option = $value;
197                     break;
198 
199                 case 'hook':
200 //                  var_dump($value);
201                     break;
202             }
203         }
204 
205         return $this;
206     }
207 
208     /**
209      * Updates the filters for the records according to the specified modifiers.
210      *
211      * Note: The filters are returned as is, subclasses shoudl override the method according to
212      * their needs.
213      *
214      * @param array $filters
215      * @param array $modifiers
216      *
217      * @return array The updated filters.
218      */
219     public function alter_filters(array $filters, array $modifiers)
220     {
221         return $filters;
222     }
223 
224     /**
225      * Alters the query according to the filter value specified.
226      *
227      * The method does a simple `{$this->id} = {$filter_value}`, subclasses might want to override
228      * the method according to the kind of filter they provide.
229      *
230      * @param Query $query
231      * @param mixed $filter_value
232      *
233      * @return Query
234      */
235     public function alter_query_with_filter(Query $query, $filter_value)
236     {
237         if ($filter_value)
238         {
239             $query->and(array($this->id => $filter_value));
240         }
241 
242         return $query;
243     }
244 
245     /**
246      * Alters the ORDER clause of the query according to the column identifier and the order
247      * direction.
248      *
249      * The implementation of the method is simple, subclasses might want to override the method
250      * to support complexer ordering.
251      *
252      * @param Query $query
253      * @param int $order_direction
254      *
255      * @return Query
256      */
257     public function alter_query_with_order(Query $query, $order_direction)
258     {
259         return $query->order("`$this->id` " . ($order_direction < 0 ? 'desc' : 'asc'));
260     }
261 
262     /**
263      * Alters the records.
264      *
265      * Note: The records are returned as is, subclasses might override the method according to
266      * their needs.
267      *
268      * @param array $records
269      *
270      * @return array[]ActiveRecord
271      */
272     public function alter_records(array $records)
273     {
274         return $records;
275     }
276 
277     /**
278      * Returns the options available for the filter.
279      *
280      * @return array|null
281      */
282     protected function get_options()
283     {
284         if (empty($this->filters['options']))
285         {
286             return;
287         }
288 
289         $options = array();
290 
291         foreach ($this->filters['options'] as $qs => $label)
292         {
293             if ($qs[0] == '=')
294             {
295                 $qs = $this->id . $qs;
296             }
297 
298             $options['?' . $qs] = $this->manager->t($label);
299         }
300 
301         return $options;
302     }
303 
304     /**
305      * Renders the column's options.
306      */
307     public function render_options()
308     {
309         $options = $this->get_options();
310 
311         if (!$options)
312         {
313             return;
314         }
315 
316         if ($this->is_filtering)
317         {
318             $options = array_merge
319             (
320                 array
321                 (
322                     $this->reset => $this->t('Display all'),
323                     false
324                 ),
325 
326                 $options
327             );
328         }
329 
330         $menu = new DropdownMenu
331         (
332             array
333             (
334                 DropdownMenu::OPTIONS => $options,
335 
336                 'value' => $this->filter_value
337             )
338         );
339 
340         return <<<EOT
341 <div class="dropdown navbar"><a href="#" data-toggle="dropdown"><i class="icon-cog"></i></a>$menu</div>
342 EOT;
343     }
344 
345     /**
346      * Renders the column's header.
347      *
348      * @return string
349      */
350     public function render_header()
351     {
352         $renderer = $this->header_renderer;
353 
354         if (!($renderer instanceof HeaderRenderer))
355         {
356             $this->header_renderer = $renderer = new $renderer($this);
357         }
358 
359         return $renderer();
360     }
361 
362     /**
363      * Renders a column cell.
364      *
365      * @param mixed $record
366      *
367      * @return string
368      */
369     public function render_cell($record)
370     {
371         $renderer = $this->cell_renderer;
372 
373         if (!($renderer instanceof CellRenderer))
374         {
375             $this->cell_renderer = $renderer = new $renderer($this);
376         }
377 
378         return $renderer($record, $this->id);
379     }
380 
381     /**
382      * Adds assets to the document.
383      *
384      * Subclasses might implement this method to add assets to the document.
385      *
386      * @param \Brickrouge\Document $document
387      */
388     public function add_assets(\Brickrouge\Document $document)
389     {
390 
391     }
392 }
393 
394 /**
395  * Default header renderer.
396  */
397 class HeaderRenderer
398 {
399     protected $column;
400 
401     public function __construct(Column $column)
402     {
403         $this->column = $column;
404     }
405 
406     public function __invoke()
407     {
408         $column = $this->column;
409         $module = $this->column->manager->module;
410         $id = $column->id;
411         $title = $column->title;
412         $t = $this->column->manager->t;
413 
414         if ($title)
415         {
416             $title = $t($id, array(), array('scope' => 'column', 'default' => $title));
417         }
418 
419         if ($column->is_filtering)
420         {
421             $a_title = $t('View all');
422             $title = $title ?: '&nbsp;';
423 
424             return <<<EOT
425 <a href="{$column->reset}" title="{$a_title}"><span class="title">{$title}</span></a>
426 EOT;
427         }
428 
429         if ($title && $column->orderable)
430         {
431             $order = $column->order;
432             $order_reverse = ($order === null) ? $column->default_order : -$order;
433 
434             return new Element
435             (
436                 'a', array
437                 (
438                     Element::INNER_HTML => '<span class="title">' . $title . '</span>',
439 
440                     'title' => $t('Sort by: :identifier', array(':identifier' => $title)),
441                     'href' => "?order=$id:" . ($order_reverse < 0 ? 'desc' : 'asc'),
442                     'class' => $order ? ($order < 0 ? 'desc' : 'asc') : null
443                 )
444             );
445         }
446 
447         return $title;
448     }
449 }
450 
451 /**
452  * Default cell renderer.
453  */
454 class CellRenderer
455 {
456     protected $column;
457 
458     public function __construct(Column $column)
459     {
460         $this->column = $column;
461     }
462 
463     public function __invoke($record, $property)
464     {
465         return \Brickrouge\escape($record->$property);
466     }
467 
468     public function t($str, array $args=array(), array $options=array())
469     {
470         return $this->column->t($str, $args, $options);
471     }
472 }
Autodoc API documentation generated by ApiGen 2.8.0