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

  • ActivateOperation
  • DeactivateOperation
  • InactivesBlock
  • ManageBlock
  • ManageController
  • Module
  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\Modules;
 13 
 14 use ICanBoogie\I18n;
 15 use ICanBoogie\I18n\FormattedString;
 16 use ICanBoogie\Operation;
 17 use ICanBoogie\Route;
 18 
 19 use Brickrouge\A;
 20 use Brickrouge\Button;
 21 use Brickrouge\Element;
 22 use Brickrouge\Form;
 23 use Brickrouge\ListView;
 24 
 25 use Icybee\Element\ActionbarToolbar;
 26 
 27 class ManageBlock extends ListView
 28 {
 29     static protected function add_assets(\Brickrouge\Document $document)
 30     {
 31         parent::add_assets($document);
 32 
 33         $document->css->add(\Icybee\ASSETS . 'css/manage.css');
 34         $document->css->add(DIR . 'public/admin.css');
 35     }
 36 
 37     protected $module;
 38 
 39     public function __construct(Module $module, array $attributes=array())
 40     {
 41         global $core;
 42 
 43         $this->module = $module;
 44 
 45         if (!$core->user->has_permission(Module::PERMISSION_ADMINISTER, $module))
 46         {
 47             throw new HTTPException("You don't have permission to administer modules.", array(), 403);
 48         }
 49 
 50         parent::__construct
 51         (
 52             $attributes + array
 53             (
 54                 self::ENTRIES => array_values($core->modules->enabled_modules_descriptors),
 55                 self::COLUMNS => array
 56                 (
 57                     'key' =>        __CLASS__ . '\KeyColumn',
 58                     'title' =>      __CLASS__ . '\TitleColumn',
 59                     'version' =>    __CLASS__ . '\VersionColumn',
 60                     'dependency' => __CLASS__ . '\DependencyColumn',
 61                     'install' =>    __CLASS__ . '\InstallColumn',
 62                     'configure' =>  __CLASS__ . '\ConfigureColumn'
 63                 ),
 64 
 65                 'class' => 'form-primary'
 66             )
 67         );
 68 
 69         $this->attach_buttons();
 70     }
 71 
 72     /**
 73      * The title and the category of the entries (descriptors) are translated and stored under
 74      * `__i18n_title` and `__i18n_category` respectively. The entries (descriptors) are ordered
 75      * according to their translated title.
 76      */
 77     protected function get_entries()
 78     {
 79         $entries = parent::get_entries();
 80 
 81         foreach ($entries as &$descriptor)
 82         {
 83             $descriptor['__i18n_title'] = self::resolve_module_title($descriptor[Module::T_ID]);
 84             $descriptor['__i18n_category'] = self::translate_module_category($descriptor);
 85         }
 86 
 87         unset($descriptor);
 88 
 89         usort($entries, function($a, $b) {
 90 
 91             return \ICanBoogie\unaccent_compare_ci($a['__i18n_title'], $b['__i18n_title']);
 92 
 93         });
 94 
 95         return $entries;
 96     }
 97 
 98     protected function render_rows(array $rows)
 99     {
100         $rendered_rows = parent::render_rows($rows);
101         $entries = $this->entries;
102         $grouped = array();
103 
104         foreach ($rendered_rows as $i => $row)
105         {
106             $descriptor = $entries[$i];
107             $grouped[$descriptor['__i18n_category']][$i] = $row;
108         }
109 
110         uksort($grouped, 'ICanBoogie\unaccent_compare_ci');
111 
112         $span = count($rendered_rows) - 2;
113         $rendered_rows = array();
114 
115         foreach ($grouped as $group_title => $rows)
116         {
117             $rendered_rows[] = <<<EOT
118 <tr class="listview-divider">
119     <td>&nbsp;</td>
120     <td>$group_title</td>
121     <td colspan="$span">&nbsp;</td>
122 </tr>
123 EOT;
124             foreach ($rows as $row)
125             {
126                 $rendered_rows[] = $row;
127             }
128         }
129 
130         return $rendered_rows;
131     }
132 
133     protected function decorate($html)
134     {
135         $operation_destination_name = \ICanBoogie\Operation::DESTINATION;
136         $operation_destination_value = $this->module->id;
137         $operation_name = \ICanBoogie\Operation::NAME;
138         // TODO-20130702: Fix the following hack:
139         $operation_value = ($this instanceof InactivesBlock) ? Module::OPERATION_ACTIVATE : Module::OPERATION_DEACTIVATE;
140 
141         return <<<EOT
142 <form action="" method="POST" class="form-primary">
143     <input type="hidden" name="{$operation_destination_name}" value="$operation_destination_value" />
144     <input type="hidden" name="{$operation_name}" value="$operation_value" />
145 
146     $html
147 </form>
148 EOT;
149     }
150 
151     protected function attach_buttons()
152     {
153         global $core;
154 
155         $core->events->attach(function(ActionbarToolbar\CollectEvent $event, ActionbarToolbar $target) {
156 
157             $event->buttons[] = new Button
158             (
159                 'Disable selected modules', array
160                 (
161                     'class' => 'btn-primary btn-danger',
162                     'type' => 'submit',
163                     'data-target' => '.form-primary'
164                 )
165             );
166 
167         });
168     }
169 
170     static public function resolve_module_title($module_id)
171     {
172         global $core;
173 
174         return I18n\t
175         (
176             'module_title.' . strtr($module_id, '.', '_'), array(), array
177             (
178                 'default' => isset($core->modules->descriptors[$module_id]) ? $core->modules->descriptors[$module_id][Module::T_TITLE] : $module_id
179             )
180         );
181     }
182 
183     static public function translate_module_category(array $descriptor)
184     {
185         $category = $descriptor[Module::T_CATEGORY];
186 
187         if (!$category)
188         {
189             list($category) = explode('.', $descriptor[Module::T_ID]);
190         }
191 
192         return I18n\t($category, array(), array('scope' => 'module_category', 'default' => ucfirst($category)));
193     }
194 }
195 
196 /*
197  * COLUMNS
198  */
199 
200 namespace Icybee\Modules\Modules\ManageBlock;
201 
202 use ICanBoogie\I18n;
203 use ICanBoogie\I18n\FormattedString;
204 use ICanBoogie\Module;
205 use ICanBoogie\Operation;
206 
207 use Brickrouge\A;
208 use Brickrouge\Element;
209 use Brickrouge\ListViewColumn;
210 
211 use Icybee\Modules\Modules\ManageBlock;
212 
213 /**
214  * Representation of the `key` column.
215  */
216 class KeyColumn extends ListViewColumn
217 {
218     public function __construct(ManageBlock $listview, $id, array $options=array())
219     {
220         parent::__construct
221         (
222             $listview, $id, $options + array
223             (
224                 'title' => null
225             )
226         );
227     }
228 
229     public function render_cell($descriptor)
230     {
231         global $core;
232 
233         $module_id = $descriptor[Module::T_ID];
234         $disabled = $descriptor[Module::T_REQUIRED];
235 
236         if ($core->modules->usage($module_id))
237         {
238             $disabled = true;
239         }
240 
241         return new Element
242         (
243             Element::TYPE_CHECKBOX, array
244             (
245                 'name' => Operation::KEY . '[' . $module_id . ']',
246                 'disabled' => $disabled
247             )
248         );
249     }
250 }
251 
252 /**
253  * Representation of the `title` column.
254  */
255 class TitleColumn extends ListViewColumn
256 {
257     public function __construct(ManageBlock $listview, $id, array $options=array())
258     {
259         parent::__construct
260         (
261             $listview, $id, $options + array
262             (
263                 'title' => 'Module'
264             )
265         );
266     }
267 
268     public function render_cell($descriptor)
269     {
270         $module_id = $descriptor[Module::T_ID];
271         $title = $descriptor['__i18n_title'];
272 
273         $html = \ICanBoogie\Routes::get()->find('/admin/' . $module_id) ? '<a href="' . \ICanBoogie\Routing\contextualize('/admin/' . $module_id) . '">' . $title . '</a>' : $title;
274 
275         $description = I18n\t
276         (
277             'module_description.' . strtr($module_id, '.', '_'), array(), array
278             (
279                 'default' => I18n\t($descriptor[Module::T_DESCRIPTION]) ?: '<em class="light">' . I18n\t('No description') . '</em>'
280             )
281         );
282 
283         if ($description)
284         {
285             $html .= '<div class="small">' . $description . '</div>';
286         }
287 
288         return $html;
289     }
290 }
291 
292 /**
293  * Representation of the `version` column.
294  */
295 class VersionColumn extends ListViewColumn
296 {
297     public function __construct(ManageBlock $listview, $id, array $options=array())
298     {
299         parent::__construct
300         (
301             $listview, $id, $options + array
302             (
303                 'title' => 'Version'
304             )
305         );
306     }
307 
308     public function render_cell($descriptor)
309     {
310         $version = $descriptor[Module::T_VERSION];
311 
312         if (!$version)
313         {
314             return;
315         }
316 
317         return '<span class="small lighter">' . $version . '</span>';
318     }
319 }
320 
321 /**
322  * Representation of the `dependency` column.
323  */
324 class DependencyColumn extends ListViewColumn
325 {
326     public function __construct(ManageBlock $listview, $id, array $options=array())
327     {
328         parent::__construct
329         (
330             $listview, $id, $options + array
331             (
332                 'title' => 'Dependency'
333             )
334         );
335     }
336 
337     public function render_cell($descriptor)
338     {
339         global $core;
340 
341         $html = '';
342         $extends = $descriptor[Module::T_EXTENDS];
343         $module_id = $descriptor[Module::T_ID];
344 
345         if ($extends)
346         {
347             $label = ManageBlock::resolve_module_title($extends);
348             $class = isset($core->modules[$extends]) ? 'success' : 'warning';
349 
350             $html .= '<div class="extends">Extends: ';
351             $html .= '<span class="label label-' . $class . '">' . $label . '</span>';
352             $html .= '</div>';
353         }
354 
355         $requires = $descriptor[Module::T_REQUIRES];
356 
357         if ($requires)
358         {
359             $html .= '<div class="requires">Requires: ';
360 
361             foreach ($requires as $require_id => $version)
362             {
363                 $label = ManageBlock::resolve_module_title($require_id);
364                 $label_class = isset($core->modules[$require_id]) ? 'success' : 'warning';
365 
366                 $html .= <<<EOT
367 <span class="label label-{$label_class}" title="Version $version">$label</span>
368 EOT;
369 
370                 $html .= ' ';
371             }
372 
373             $html .= '</div>';
374         }
375 
376         $usage = $core->modules->usage($module_id);
377 
378         if ($usage)
379         {
380             $html .= '<div class="usage light">' . I18n\t('Used by :count modules', array(':count' => $usage)) . '</div>';
381         }
382 
383         return $html;
384     }
385 }
386 
387 /**
388  * Representation of the `install` column.
389  */
390 class InstallColumn extends ListViewColumn
391 {
392     public function __construct(ManageBlock $listview, $id, array $options=array())
393     {
394         parent::__construct
395         (
396             $listview, $id, $options + array
397             (
398                 'title' => 'Installed'
399             )
400         );
401     }
402 
403     public function render_cell($descriptor)
404     {
405         global $core;
406 
407         $module_id = $descriptor[Module::T_ID];
408 
409         try
410         {
411             $module = $core->modules[$module_id];
412         }
413         catch (\Exception $e)
414         {
415             return '<div class="alert alert-error">' . $e->getMessage() . '</div>';
416         }
417 
418         $html = '';
419         $is_installed = false;
420 
421         # EXTENDS
422 
423         $errors = new \ICanBoogie\Errors;
424         $extends_errors = new \ICanBoogie\Errors;
425         $n_errors = count($errors);
426 
427         while ($descriptor[Module::T_EXTENDS])
428         {
429             $extends = $descriptor[Module::T_EXTENDS];
430 
431             if (empty($core->modules->descriptors[$extends]))
432             {
433                 $errors[$module_id] = I18n\t('Requires the %module module which is missing.', array('%module' => $extends));
434 
435                 break;
436             }
437             else if (!isset($core->modules[$extends]))
438             {
439                 $errors[$module_id] = I18n\t('Requires the %module module which is disabled.', array('%module' => $extends));
440 
441                 break;
442             }
443             else
444             {
445                 $extends_errors->clear();
446                 $extends_module = $core->modules[$extends];
447                 $extends_is_installed = $extends_module->is_installed($extends_errors);
448 
449                 if (count($extends_errors))
450                 {
451                     $extends_is_installed = false;
452                 }
453 
454                 if (!$extends_is_installed)
455                 {
456                     $errors[$module_id] = I18n\t('Requires the %module module which is disabled.', array('%module' => $extends));
457 
458                     break;
459                 }
460             }
461 
462             $descriptor = $core->modules->descriptors[$extends];
463         }
464 
465         if ($n_errors != count($errors))
466         {
467             $html .= '<div class="alert alert-error">' . implode('<br />', (array) $errors[$module_id]) . '</div>';
468         }
469         else
470         {
471             try
472             {
473                 $n_errors = count($errors);
474                 $is_installed = $module->is_installed($errors);
475 
476                 if (count($errors) != $n_errors)
477                 {
478                     $is_installed = false;
479                 }
480             }
481             catch (\Exception $e)
482             {
483                 $errors[$module->id] = I18n\t
484                 (
485                     'Exception with module %module: :message', array
486                     (
487                         '%module' => (string) $module,
488                         ':message' => $e->getMessage()
489                     )
490                 );
491             }
492 
493             if ($is_installed)
494             {
495                 $html .= I18n\t('Installed');
496             }
497             else if ($is_installed === false)
498             {
499                 $btn = '<a class="btn btn-danger" href="'
500                 . \ICanBoogie\Routing\contextualize("/admin/modules/{$module}/install")
501                 . '">' . I18n\t('Install module') . '</a>';
502 
503                 $title = new FormattedString('The module %title is not properly installed', array('title' => $module->title));
504 
505                 \ICanBoogie\log_error("$title.");
506 
507                 if (isset($errors[$module_id]))
508                 {
509                     $error = $errors[$module_id];
510 
511                     if (is_array($error))
512                     {
513                         $error = implode('</p><p>', $error);
514                     }
515 
516                     $html .= <<<EOT
517 <div class="alert alert-error alert-block undissmissable">
518     <h4 class="alert-heading">$title</h4>
519     <div class="content">
520         <p>$error</p>
521     </div>
522 
523     <div class="alert-actions">$btn</div>
524 </div>
525 EOT;
526                 }
527                 else
528                 {
529                     $html .= $btn;
530                 }
531             }
532             else // null
533             {
534                 $html .= '<em class="not-applicable light">Not applicable</em>';
535             }
536         }
537 
538         return $html;
539     }
540 }
541 
542 /**
543  * Representation of the `configure` column.
544  */
545 class ConfigureColumn extends ListViewColumn
546 {
547     public function __construct(ManageBlock $listview, $id, array $options=array())
548     {
549         parent::__construct
550         (
551             $listview, $id, $options + array
552             (
553                 'title' => null
554             )
555         );
556     }
557 
558     public function render_cell($descriptor)
559     {
560         global $core;
561 
562         $module_id = $descriptor[Module::T_ID];
563 
564         if (empty($core->routes["admin:$module_id/config"]))
565         {
566             return;
567         }
568 
569         $route = $core->routes["admin:$module_id/config"];
570 
571         return new A('Configure', \ICanBoogie\Routing\contextualize($route->pattern));
572     }
573 }
Autodoc API documentation generated by ApiGen 2.8.0