Dotclear

source: inc/admin/lib.moduleslist.php @ 2171:bb80994ddeed

Revision 2171:bb80994ddeed, 23.0 KB checked in by Denis Jean-Chirstian <contact@…>, 12 years ago (diff)

Revamp blog themes manager using new dcRepository stuff (no js and no css), and some dcModulesList enhancements

Line 
1<?php
2
3class adminModulesList
4{
5     public $core;
6     public $modules;
7
8     public static  $allow_multi_install;
9     public static $distributed_modules = array();
10
11     protected $list_id = 'unknow';
12
13     protected $path = false;
14     protected $path_writable = false;
15     protected $path_pattern = false;
16
17     protected $page_url = 'plugins.php';
18     protected $page_qs = '?';
19     protected $page_tab = '';
20
21     public static $nav_indexes = 'abcdefghijklmnopqrstuvwxyz0123456789';
22     protected $nav_list = array();
23     protected $nav_special = 'other';
24
25     protected $sort_field = 'sname';
26     protected $sort_asc = true;
27
28     public function __construct($core, $root, $allow_multi_install=false)
29     {
30          $this->core = $core;
31          self::$allow_multi_install = (boolean) $allow_multi_install;
32          $this->setPathInfo($root);
33          $this->setNavSpecial(__('other'));
34
35          $this->init();
36     }
37
38     protected function init()
39     {
40          return null;
41     }
42
43     public function newList($list_id)
44     {
45          $this->modules = array();
46          $this->page_tab = '';
47          $this->list_id = $list_id;
48
49          return $this;
50     }
51
52     protected function setPathInfo($root)
53     {
54          $paths = explode(PATH_SEPARATOR, $root);
55          $path = array_pop($paths);
56          unset($paths);
57
58          $this->path = $path;
59          if (is_dir($path) && is_writeable($path)) {
60               $this->path_writable = true;
61               $this->path_pattern = preg_quote($path,'!');
62          }
63
64          return $this;
65     }
66
67     public function getPath()
68     {
69          return $this->path;
70     }
71
72     public function isPathWritable()
73     {
74          return $this->path_writable;
75     }
76
77     public function isPathDeletable($root)
78     {
79          return $this->path_writable 
80               && preg_match('!^'.$this->path_pattern.'!', $root) 
81               && $this->core->auth->isSuperAdmin();
82     }
83
84     public function setPageURL($url)
85     {
86          $this->page_qs = strpos('?', $url) ? '&' : '?';
87          $this->page_url = $url;
88
89          return $this;
90     }
91
92     public function getPageURL($queries='', $with_tab=true)
93     {
94          return $this->page_url.
95               (!empty($queries) ? $this->page_qs : '').
96               (is_array($queries) ? http_build_query($queries) : $queries).
97               ($with_tab && !empty($this->page_tab) ? '#'.$this->page_tab : '');
98     }
99
100     public function setPageTab($tab)
101     {
102          $this->page_tab = $tab;
103
104          return $this;
105     }
106
107     public function getPageTab()
108     {
109          return $this->page_tab;
110     }
111
112     public function getSearchQuery()
113     {
114          $query = !empty($_REQUEST['m_search']) ? trim($_REQUEST['m_search']) : null;
115          return strlen($query) > 1 ? $query : null;
116     }
117
118     public function displaySearchForm()
119     {
120          $query = $this->getSearchQuery();
121
122          if (empty($this->modules) && $query === null) {
123               return $this;
124          }
125
126          echo 
127          '<form action="'.$this->getPageURL().'" method="get" class="fieldset">'.
128          '<p><label for="m_search" class="classic">'.__('Search in repository:').'&nbsp;</label><br />'.
129          form::field(array('m_search','m_search'), 30, 255, html::escapeHTML($query)).
130          '<input type="submit" value="'.__('Search').'" /> ';
131          if ($query) { echo ' <a href="'.$this->getPageURL().'" class="button">'.__('Reset search').'</a>'; }
132          echo '</p>'.
133          '</form>';
134
135          if ($query) {
136               echo 
137               '<p class="message">'.sprintf(
138                    __('Found %d result for search "%s":', 'Found %d results for search "%s":', count($this->modules)), 
139                    count($this->modules), html::escapeHTML($query)
140                    ).
141               '</p>';
142          }
143          return $this;
144     }
145
146     public function setNavSpecial($str)
147     {
148          $this->nav_special = (string) $str;
149          $this->nav_list = array_merge(str_split(self::$nav_indexes), array($this->nav_special));
150
151          return $this;
152     }
153
154     public function getNavQuery()
155     {
156          return isset($_REQUEST['m_nav']) && in_array($_REQUEST['m_nav'], $this->nav_list) ? $_REQUEST['m_nav'] : $this->nav_list[0];
157     }
158
159     public function displayNavMenu()
160     {
161          if (empty($this->modules) || $this->getSearchQuery() !== null) {
162               return $this;
163          }
164
165          # Fetch modules required field
166          $indexes = array();
167          foreach ($this->modules as $id => $module) {
168               if (!isset($module[$this->sort_field])) {
169                    continue;
170               }
171               $char = substr($module[$this->sort_field], 0, 1);
172               if (!in_array($char, $this->nav_list)) {
173                    $char = $this->nav_special;
174               }
175               if (!isset($indexes[$char])) {
176                    $indexes[$char] = 0;
177               }
178               $indexes[$char]++;
179          }
180
181          $buttons = array();
182          foreach($this->nav_list as $char) {
183               # Selected letter
184               if ($this->getNavQuery() == $char) {
185                    $buttons[] = '<li class="active" title="'.__('current selection').'"><strong> '.$char.' </strong></li>';
186               }
187               # Letter having modules
188               elseif (!empty($indexes[$char])) {
189                    $title = sprintf(__('%d module', '%d modules', $indexes[$char]), $indexes[$char]);
190                    $buttons[] = '<li class="btn" title="'.$title.'"><a href="'.$this->getPageURL('m_nav='.$char).'" title="'.$title.'"> '.$char.' </a></li>';
191               }
192               # Letter without modules
193               else {
194                    $buttons[] = '<li class="btn no-link" title="'.__('no module').'"> '.$char.' </li>';
195               }
196          }
197          # Parse navigation menu
198          echo '<div class="pager">'.__('Browse index:').' <ul>'.implode('',$buttons).'</ul></div>';
199
200          return $this;
201     }
202
203     public function setSortField($field, $asc=true)
204     {
205          $this->sort_field = $field;
206          $this->sort_asc = (boolean) $asc;
207
208          return $this;
209     }
210
211     public function getSortQuery()
212     {
213          return !empty($_REQUEST['m_sort']) ? $_REQUEST['m_sort'] : $this->sort_field;
214     }
215
216     public function displaySortForm()
217     {
218          //not yet implemented
219     }
220
221     public function displayMessage($action)
222     {
223          switch($action) {
224               case 'activate': 
225                    $str = __('Module successfully activated.'); break;
226               case 'deactivate': 
227                    $str = __('Module successfully deactivated.'); break;
228               case 'delete': 
229                    $str = __('Module successfully deleted.'); break;
230               case 'install': 
231                    $str = __('Module successfully installed.'); break;
232               case 'update': 
233                    $str = __('Module successfully updated.'); break;
234               default:
235                    $str = ''; break;
236          }
237          if (!empty($str)) {
238               dcPage::success($str);
239          }
240     }
241
242     public function setModules($modules)
243     {
244          $this->modules = array();
245          foreach($modules as $id => $module) {
246               $this->modules[$id] = self::setModuleInfo($id, $module);
247          }
248
249          return $this;
250     }
251
252     public function getModules()
253     {
254          return $this->modules;
255     }
256
257     public static function setModuleInfo($id, $module)
258     {
259          $label = empty($module['label']) ? $id : $module['label'];
260          $name = __(empty($module['name']) ? $label : $module['name']);
261         
262          return array_merge(
263               # Default values
264               array(
265                    'desc'                   => '',
266                    'author'            => '',
267                    'version'                => 0,
268                    'current_version'   => 0,
269                    'root'                   => '',
270                    'root_writable'     => false,
271                    'permissions'       => null,
272                    'parent'            => null,
273                    'priority'               => 1000,
274                    'standalone_config' => false,
275                    'support'                => '',
276                    'section'                => '',
277                    'tags'                   => '',
278                    'details'                => '',
279                    'sshot'             => ''
280               ),
281               # Module's values
282               $module,
283               # Clean up values
284               array(
285                    'id'                     => $id,
286                    'sid'                    => self::sanitizeString($id),
287                    'label'             => $label,
288                    'name'                   => $name,
289                    'sname'             => self::sanitizeString($name)
290               )
291          );
292     }
293
294     public static function setDistributedModules($modules)
295     {
296          self::$distributed_modules = $modules;
297     }
298
299     public static function isDistributedModule($module)
300     {
301          $distributed_modules = self::$distributed_modules;
302
303          return is_array($distributed_modules) && in_array($module, $distributed_modules);
304     }
305
306     public static function sortModules($modules, $field, $asc=true)
307     {
308          $sorter = array();
309          foreach($modules as $id => $module) {
310               $sorter[$id] = isset($module[$field]) ? $module[$field] : $field;
311          }
312          array_multisort($sorter, $asc ? SORT_ASC : SORT_DESC, $modules);
313
314          return $modules;
315     }
316
317     public function displayModulesList($cols=array('name', 'config', 'version', 'desc'), $actions=array(), $nav_limit=false)
318     {
319          echo 
320          '<div class="table-outer">'.
321          '<table id="'.html::escapeHTML($this->list_id).'" class="modules'.(in_array('expander', $cols) ? ' expandable' : '').'">'.
322          '<caption class="hidden">'.html::escapeHTML(__('Modules list')).'</caption><tr>';
323
324          if (in_array('name', $cols)) {
325               echo 
326               '<th class="first nowrap"'.(in_array('icon', $cols) ? ' colspan="2"' : '').'>'.__('Name').'</th>';
327          }
328
329          if (in_array('version', $cols)) {
330               echo 
331               '<th class="nowrap count" scope="col">'.__('Version').'</th>';
332          }
333
334          if (in_array('current_version', $cols)) {
335               echo 
336               '<th class="nowrap count" scope="col">'.__('Current version').'</th>';
337          }
338
339          if (in_array('desc', $cols)) {
340               echo 
341               '<th class="nowrap" scope="col">'.__('Details').'</th>';
342          }
343
344          if (in_array('distrib', $cols)) {
345               echo '<th'.(in_array('desc', $cols) ? '' : ' class="maximal"').'></th>';
346          }
347
348          if (!empty($actions) && $this->core->auth->isSuperAdmin()) {
349               echo 
350               '<th class="minimal nowrap">'.__('Action').'</th>';
351          }
352
353          echo 
354          '</tr>';
355
356          $sort_field = $this->getSortQuery();
357
358          # Sort modules by id
359          $modules = $this->getSearchQuery() === null ?
360               self::sortModules($this->modules, $sort_field, $this->sort_asc) :
361               $this->modules;
362
363          $count = 0;
364          foreach ($modules as $id => $module)
365          {
366               # Show only requested modules
367               if ($nav_limit && $this->getSearchQuery() === null) {
368                    $char = substr($module[$sort_field], 0, 1);
369                    if (!in_array($char, $this->nav_list)) {
370                         $char = $this->nav_special;
371                    }
372                    if ($this->getNavQuery() != $char) {
373                         continue;
374                    }
375               }
376
377               echo 
378               '<tr class="line" id="'.html::escapeHTML($this->list_id).'_m_'.html::escapeHTML($id).'">';
379
380               if (in_array('icon', $cols)) {
381                    echo 
382                    '<td class="module-icon nowrap">'.sprintf(
383                         '<img alt="%1$s" title="%1$s" src="%2$s" />', 
384                         html::escapeHTML($id), file_exists($module['root'].'/icon.png') ? 'index.php?pf='.$id.'/icon.png' : 'images/module.png'
385                    ).'</td>';
386               }
387
388               # Link to config file
389               $config = in_array('config', $cols) && !empty($module['root']) && file_exists(path::real($module['root'].'/_config.php'));
390
391               echo 
392               '<td class="module-name nowrap" scope="row">'.($config ? 
393                    '<a href="'.$this->getPageURL('module='.$id.'&conf=1').'" title"'.sprintf(__('Configure module "%s"'), html::escapeHTML($module['name'])).'">'.html::escapeHTML($module['name']).'</a>' : 
394                    html::escapeHTML($module['name'])
395               ).'</td>';
396
397               if (in_array('version', $cols)) {
398                    echo 
399                    '<td class="module-version nowrap count">'.html::escapeHTML($module['version']).'</td>';
400               }
401
402               if (in_array('current_version', $cols)) {
403                    echo 
404                    '<td class="module-current-version nowrap count">'.html::escapeHTML($module['current_version']).'</td>';
405               }
406
407               if (in_array('desc', $cols)) {
408                    echo 
409                    '<td class="module-desc maximal">'.html::escapeHTML($module['desc']).'</td>';
410               }
411
412               if (in_array('distrib', $cols)) {
413                    echo 
414                    '<td class="module-distrib">'.(self::isDistributedModule($id) ? 
415                         '<img src="images/dotclear_pw.png" alt="'.
416                         __('Module from official distribution').'" title="'.
417                         __('module from official distribution').'" />' 
418                    : '').'</td>';
419               }
420
421               if (!empty($actions) && $this->core->auth->isSuperAdmin()) {
422                    echo 
423                    '<td class="module-actions nowrap">';
424
425                    $this->displayLineActions($id, $module, $actions);
426
427                    echo
428                    '</td>';
429               }
430
431               echo 
432               '</tr>';
433
434               $count++;
435          }
436          echo 
437          '</table></div>';
438
439          if(!$count) {
440               echo 
441               '<p class="message">'.__('No module matches your search.').'</p>';
442          }
443     }
444
445     protected function displayLineActions($id, $module, $actions, $echo=true)
446     {
447          $submits = array();
448
449          # Activate
450          if (in_array('deactivate', $actions) && $module['root_writable']) {
451               $submits[] = '<input type="submit" name="deactivate" value="'.__('Deactivate').'" />';
452          }
453
454          # Deactivate
455          if (in_array('activate', $actions) && $module['root_writable']) {
456               $submits[] = '<input type="submit" name="activate" value="'.__('Activate').'" />';
457          }
458
459          # Delete
460          if (in_array('delete', $actions) && $this->isPathDeletable($module['root'])) {
461               $submits[] = '<input type="submit" class="delete" name="delete" value="'.__('Delete').'" />';
462          }
463
464          # Install (form repository)
465          if (in_array('install', $actions) && $this->path_writable) {
466               $submits[] = '<input type="submit" name="install" value="'.__('Install').'" />';
467          }
468
469          # Update (from repository)
470          if (in_array('update', $actions) && $this->path_writable) {
471               $submits[] = '<input type="submit" name="update" value="'.__('Update').'" />';
472          }
473
474          # Parse form
475          if (!empty($submits)) {
476               $res = 
477               '<form action="'.$this->getPageURL().'" method="post">'.
478               '<div>'.
479               $this->core->formNonce().
480               form::hidden(array('module'), html::escapeHTML($id)).
481               form::hidden(array('tab'), $this->page_tab).
482               implode(' ', $submits).
483               '</div>'.
484               '</form>';
485
486               if (!$echo) {
487                    return $res;
488               }
489               echo $res;
490          }
491     }
492
493     public function executeAction($prefix, dcModules $modules, dcRepository $repository)
494     {
495          if (!$this->core->auth->isSuperAdmin() || !$this->isPathWritable()) {
496               return null;
497          }
498
499          # List actions
500          if (!empty($_POST['module'])) {
501
502               $id = $_POST['module'];
503
504               if (!empty($_POST['activate'])) {
505
506                    $enabled = $modules->getDisabledModules();
507                    if (!isset($enabled[$id])) {
508                         throw new Exception(__('No such module.'));
509                    }
510
511                    # --BEHAVIOR-- moduleBeforeActivate
512                    $this->core->callBehavior($type.'BeforeActivate', $id);
513
514                    $modules->activateModule($id);
515
516                    # --BEHAVIOR-- moduleAfterActivate
517                    $this->core->callBehavior($type.'AfterActivate', $id);
518
519                    http::redirect($this->getPageURL('msg=activate'));
520               }
521
522               if (!empty($_POST['deactivate'])) {
523
524                    if (!$modules->moduleExists($id)) {
525                         throw new Exception(__('No such module.'));
526                    }
527
528                    $module = $modules->getModules($id);
529                    $module['id'] = $id;
530
531                    if (!$module['root_writable']) {
532                         throw new Exception(__('You don\'t have permissions to deactivate this module.'));
533                    }
534
535                    # --BEHAVIOR-- moduleBeforeDeactivate
536                    $this->core->callBehavior($prefix.'BeforeDeactivate', $module);
537
538                    $modules->deactivateModule($id);
539
540                    # --BEHAVIOR-- moduleAfterDeactivate
541                    $this->core->callBehavior($prefix.'AfterDeactivate', $module);
542
543                    http::redirect($this->getPageURL('msg=deactivate'));
544               }
545
546               if (!empty($_POST['delete'])) {
547
548                    $disabled = $modules->getDisabledModules();
549                    if (!isset($disabled[$id])) {
550
551                         if (!$modules->moduleExists($id)) {
552                              throw new Exception(__('No such module.'));
553                         }
554
555                         $module = $modules->getModules($id);
556                         $module['id'] = $id;
557
558                         if (!$this->isPathDeletable($module['root'])) {
559                              throw new Exception(__("You don't have permissions to delete this module."));
560                         }
561
562                         # --BEHAVIOR-- moduleBeforeDelete
563                         $this->core->callBehavior($prefix.'BeforeDelete', $module);
564
565                         $modules->deleteModule($id);
566
567                         # --BEHAVIOR-- moduleAfterDelete
568                         $this->core->callBehavior($prefix.'AfterDelete', $module);
569                    }
570                    else {
571                         $modules->deleteModule($id, true);
572                    }
573
574                    http::redirect($this->getPageURL('msg=delete'));
575               }
576
577               if (!empty($_POST['update'])) {
578
579                    $updated = $repository->get();
580                    if (!isset($updated[$id])) {
581                         throw new Exception(__('No such module.'));
582                    }
583
584                    if (!$modules->moduleExists($id)) {
585                         throw new Exception(__('No such module.'));
586                    }
587
588                    $module = $updated[$id];
589                    $module['id'] = $id;
590               
591                    if (!self::$allow_multi_install) {
592                         $dest = $module['root'].'/../'.basename($module['file']);
593                    }
594                    else {
595                         $dest = $this->getPath().'/'.basename($module['file']);
596                         if ($module['root'] != $dest) {
597                              @file_put_contents($module['root'].'/_disabled', '');
598                         }
599                    }
600
601                    # --BEHAVIOR-- moduleBeforeUpdate
602                    $this->core->callBehavior($type.'BeforeUpdate', $module);
603
604                    $repository->process($module['file'], $dest);
605
606                    # --BEHAVIOR-- moduleAfterUpdate
607                    $this->core->callBehavior($type.'AfterUpdate', $module);
608
609                    http::redirect($this->getPageURL('msg=upadte'));
610               }
611
612               if (!empty($_POST['install'])) {
613
614                    $updated = $repository->get();
615                    if (!isset($updated[$id])) {
616                         throw new Exception(__('No such module.'));
617                    }
618
619                    $module = $updated[$id];
620                    $module['id'] = $id;
621
622                    $dest = $this->getPath().'/'.basename($module['file']);
623
624                    # --BEHAVIOR-- moduleBeforeAdd
625                    $this->core->callBehavior($type.'BeforeAdd', $module);
626
627                    $ret_code = $repository->process($module['file'], $dest);
628
629                    # --BEHAVIOR-- moduleAfterAdd
630                    $this->core->callBehavior($type.'AfterAdd', $module);
631
632                    http::redirect($this->getPageURL('msg='.($ret_code == 2 ? 'update' : 'install')));
633               }
634          }
635          # Manual actions
636          elseif (!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file']) 
637               || !empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url']))
638          {
639               if (empty($_POST['your_pwd']) || !$this->core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY, $_POST['your_pwd']))) {
640                    throw new Exception(__('Password verification failed'));
641               }
642
643               if (!empty($_POST['upload_pkg'])) {
644                    files::uploadStatus($_FILES['pkg_file']);
645                   
646                    $dest = $this->getPath().'/'.$_FILES['pkg_file']['name'];
647                    if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'], $dest)) {
648                         throw new Exception(__('Unable to move uploaded file.'));
649                    }
650               }
651               else {
652                    $url = urldecode($_POST['pkg_url']);
653                    $dest = $this->getPath().'/'.basename($url);
654                    $repository->download($url, $dest);
655               }
656
657               # --BEHAVIOR-- moduleBeforeAdd
658               $this->core->callBehavior($prefix.'BeforeAdd', null);
659
660               $ret_code = $repository->install($dest);
661
662               # --BEHAVIOR-- moduleAfterAdd
663               $this->core->callBehavior($prefix.'AfterAdd', null);
664
665               http::redirect($this->getPageURL('msg='.($ret_code == 2 ? 'update' : 'install')).'#'.$prefix);
666          }
667          return null;
668     }
669
670     public function displayManualForm()
671     {
672          if (!$this->core->auth->isSuperAdmin() || !$this->isPathWritable()) {
673               return null;
674          }
675
676          # 'Upload module' form
677          echo
678          '<form method="post" action="'.$this->getPageURL().'" id="uploadpkg" enctype="multipart/form-data" class="fieldset">'.
679          '<h4>'.__('Upload a zip file').'</h4>'.
680          '<p class="field"><label for="pkg_file" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Zip file path:').'</label> '.
681          '<input type="file" name="pkg_file" id="pkg_file" /></p>'.
682          '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '.
683          form::password(array('your_pwd','your_pwd1'),20,255).'</p>'.
684          '<p><input type="submit" name="upload_pkg" value="'.__('Upload').'" />'.
685          form::hidden(array('tab'), $this->getPageTab()).
686          $this->core->formNonce().'</p>'.
687          '</form>';
688         
689          # 'Fetch module' form
690          echo
691          '<form method="post" action="'.$this->getPageURL().'" id="fetchpkg" class="fieldset">'.
692          '<h4>'.__('Download a zip file').'</h4>'.
693          '<p class="field"><label for="pkg_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Zip file URL:').'</label> '.
694          form::field(array('pkg_url','pkg_url'),40,255).'</p>'.
695          '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '.
696          form::password(array('your_pwd','your_pwd2'),20,255).'</p>'.
697          '<p><input type="submit" name="fetch_pkg" value="'.__('Download').'" />'.
698          form::hidden(array('tab'), $this->getPageTab()).
699          $this->core->formNonce().'</p>'.
700          '</form>';
701     }
702
703     public static function sanitizeString($str)
704     {
705          return preg_replace('/[^A-Za-z0-9\@\#+_-]/', '', strtolower($str));
706     }
707}
708
709class adminThemesList extends adminModulesList
710{
711     protected $page_url = 'blog_theme.php';
712
713     public function displayModulesList($cols=array('name', 'config', 'version', 'desc'), $actions=array(), $nav_limit=false)
714     {
715          echo 
716          '<div id="'.html::escapeHTML($this->list_id).'" class="modules'.(in_array('expander', $cols) ? ' expandable' : '').' one-box">';
717
718          $sort_field = $this->getSortQuery();
719
720          # Sort modules by id
721          $modules = $this->getSearchQuery() === null ?
722               self::sortModules($this->modules, $sort_field, $this->sort_asc) :
723               $this->modules;
724
725          $res = '';
726          $count = 0;
727          foreach ($modules as $id => $module)
728          {
729               # Show only requested modules
730               if ($nav_limit && $this->getSearchQuery() === null) {
731                    $char = substr($module[$sort_field], 0, 1);
732                    if (!in_array($char, $this->nav_list)) {
733                         $char = $this->nav_special;
734                    }
735                    if ($this->getNavQuery() != $char) {
736                         continue;
737                    }
738               }
739
740               $current = $this->core->blog->settings->system->theme == $id;
741
742               if (preg_match('#^http(s)?://#', $this->core->blog->settings->system->themes_url)) {
743                    $theme_url = http::concatURL($this->core->blog->settings->system->themes_url, '/'.$id);
744               } else {
745                    $theme_url = http::concatURL($this->core->blog->url, $this->core->blog->settings->system->themes_url.'/'.$id);
746               }
747
748               $has_conf = file_exists(path::real($this->core->blog->themes_path.'/'.$id).'/_config.php');
749               $has_css = file_exists(path::real($this->core->blog->themes_path.'/'.$id).'/style.css');
750               $parent = $module['parent'];
751               $has_parent = !empty($module['parent']);
752               if ($has_parent) {
753                    $is_parent_present = $this->core->themes->moduleExists($parent);
754               }
755
756               $line = 
757               '<div class="box '.($current ? 'current-theme' : 'theme').'">';
758
759               if (in_array('sshot', $cols)) {
760                    # Screenshot from url
761                    if (preg_match('#^http(s)?://#', $module['sshot'])) {
762                         $sshot = $module['sshot'];
763                    }
764                    # Screenshot from installed module
765                    elseif (file_exists($this->core->blog->themes_path.'/'.$id.'/screenshot.jpg')) {
766                         $sshot = $this->getPageURL('shot='.rawurlencode($id));
767                    }
768                    # Default screenshot
769                    else {
770                         $sshot = 'images/noscreenshot.png';
771                    }
772
773                    $line .= 
774                    '<div class="module-sshot"><img src="'.$sshot.'" alt="'.__('screenshot.').'" /></div>';
775               }
776
777               if (in_array('name', $cols)) {
778                    $line .= 
779                    '<h4 class="module-name">'.html::escapeHTML($module['name']).'</h4>';
780               }
781
782               $line .= 
783               '<div class="module-infos">'.
784               '<p>';
785
786               if (in_array('desc', $cols)) {
787                    $line .= 
788                    '<span class="module-desc">'.html::escapeHTML($module['desc']).'</span> ';
789               }
790
791               if (in_array('author', $cols)) {
792                    $line .= 
793                    '<span class="module-author">'.sprintf(__('by %s'),html::escapeHTML($module['author'])).'</span> ';
794               }
795
796               if (in_array('version', $cols)) {
797                    $line .= 
798                    '<span class="module-version">'.sprintf(__('version %s'),html::escapeHTML($module['version'])).'</span> ';
799               }
800
801               if (in_array('parent', $cols) && $has_parent) {
802                    if ($is_parent_present) {
803                         $line .= 
804                         '<span class="module-parent-ok">'.sprintf(__('(built on "%s")'),html::escapeHTML($parent)).'</span> ';
805                    }
806                    else {
807                         $line .= 
808                         '<span class="module-parent-missing">'.sprintf(__('(requires "%s")'),html::escapeHTML($parent)).'</span> ';
809                    }
810               }
811
812               $line .= 
813               '</p>'.
814               '</div>';
815
816               $line .= 
817               '<div class="modules-actions">';
818               
819               # _GET actions
820               $line .= 
821               '<p>';
822
823               if ($current && $has_css) {
824                    $line .= 
825                    '<a href="'.$theme_url.'/style.css" class="button">'.__('View stylesheet').'</a> ';
826               }
827               if ($current && $has_conf) {
828                    $line .= 
829                    '<a href="'.$this->getPageURL('conf=1').'" class="button">'.__('Configure theme').'</a> ';
830               }
831               $line .= 
832               '</p>';
833
834               # Plugins actions
835               if ($current) {
836                    # --BEHAVIOR-- adminCurrentThemeDetails
837                    $line .= 
838                    $this->core->callBehavior('adminCurrentThemeDetails', $this->core, $id, $module);
839               }
840
841               # _POST actions
842               if (!empty($actions) && $this->core->auth->isSuperAdmin()) {
843                    $line .=
844                    $this->displayLineActions($id, $module, $actions, false);
845               }
846
847               $line .= 
848               '</div>';
849
850               $line .=
851               '</div>';
852
853               $count++;
854
855               $res = $current ? $line.$res : $res.$line;
856          }
857          echo 
858          $res.
859          '</div>';
860
861          if(!$count) {
862               echo 
863               '<p class="message">'.__('No module matches your search.').'</p>';
864          }
865     }
866}
Note: See TracBrowser for help on using the repository browser.

Sites map