Dotclear


Ignore:
Files:
8 added
11 edited

Legend:

Unmodified
Added
Removed
  • admin/blog_theme.php

    r2191 r2196  
    1515dcPage::check('admin'); 
    1616 
    17 # Loading themes 
     17# -------------------------------------------------- 
     18# @todo Add settings to Dotclear update features 
     19if ($core->blog->settings->system->repository_theme_url === null) { 
     20     $core->blog->settings->system->put( 
     21          'repository_theme_url', 'http://update.dotaddict.org/dc2/themes.xml', 'string', 'Themes XML feed location', true, true 
     22     ); 
     23} 
     24# -------------------------------------------------- 
     25 
     26# -- Loading themes -- 
    1827$core->themes = new dcThemes($core); 
    19 $core->themes->loadModules($core->blog->themes_path,null); 
    20  
    21 # Theme screenshot 
     28$core->themes->loadModules($core->blog->themes_path, null); 
     29 
     30# -- Repository helper -- 
     31$repository = new dcRepository( 
     32     $core->themes,  
     33     $core->blog->settings->system->repository_theme_url 
     34); 
     35$repository->check(); 
     36 
     37# -- Page helper -- 
     38$list = new adminThemesList( 
     39     $core,  
     40     $core->blog->themes_path, 
     41     false 
     42); 
     43 
     44# -- Theme screenshot -- 
    2245if (!empty($_GET['shot']) && $core->themes->moduleExists($_GET['shot'])) 
    2346{ 
     
    4366} 
    4467 
    45 $can_install = $core->auth->isSuperAdmin(); 
    46 $is_writable = is_dir($core->blog->themes_path) && is_writable($core->blog->themes_path); 
    47 $default_tab = 'themes-list'; 
    48  
    49 # Selecting theme 
    50 if (!empty($_POST['theme']) && !empty($_POST['select']) && empty($_REQUEST['conf'])) 
    51 { 
    52      $core->blog->settings->addNamespace('system'); 
    53      $core->blog->settings->system->put('theme',$_POST['theme']); 
    54      $core->blog->triggerBlog(); 
    55      $theme = $core->themes->getModules($_POST['theme']); 
    56      dcPage::addSuccessNotice(sprintf( 
    57           __('Current theme has been successfully changed to "%s".'), 
    58           html::escapeHTML($theme['name'])) 
     68# -- Display module configuration page -- 
     69if ($list->setConfigurationFile($core->themes, $core->blog->settings->system->theme)) { 
     70 
     71     # Get content before page headers 
     72     include $list->getConfigurationFile(); 
     73 
     74     # Gather content 
     75     $list->setConfigurationContent(); 
     76 
     77     # Display page 
     78     dcPage::open(__('Blog appearance'), 
     79          dcPage::jsPageTabs(). 
     80          dcPage::jsColorPicker(). 
     81 
     82          # --BEHAVIOR-- themesToolsHeaders 
     83          $core->callBehavior('themesToolsHeaders', $core, true), 
     84 
     85          dcPage::breadcrumb( 
     86               array( 
     87                    html::escapeHTML($core->blog->name) => '', 
     88                    __('Blog appearance') => 'blog_theme.php', 
     89                    '<span class="page-title">'.__('Theme configuration').'</span>' => '' 
     90               )) 
    5991     ); 
    6092 
    61      http::redirect('blog_theme.php'); 
    62 } 
    63  
    64 if ($can_install && !empty($_POST['theme']) && !empty($_POST['remove']) && empty($_REQUEST['conf'])) 
    65 { 
    66      try 
    67      { 
    68           if ($_POST['theme'] == 'default') { 
    69                throw new Exception(__('You can\'t remove default theme.')); 
    70           } 
    71            
    72           if (!$core->themes->moduleExists($_POST['theme'])) { 
    73                throw new Exception(__('Theme does not exist.')); 
    74           } 
    75            
    76           $theme = $core->themes->getModules($_POST['theme']); 
    77            
    78           # --BEHAVIOR-- themeBeforeDelete 
    79           $core->callBehavior('themeBeforeDelete',$theme); 
    80            
    81           $core->themes->deleteModule($_POST['theme']); 
    82            
    83           # --BEHAVIOR-- themeAfterDelete 
    84           $core->callBehavior('themeAfterDelete',$theme); 
    85            
    86           http::redirect('blog_theme.php'); 
    87      } 
    88      catch (Exception $e) 
    89      { 
     93     if (!empty($_GET['done'])){ 
     94          dcPage::success(__('Theme successfully configured.')); 
     95     } 
     96 
     97     # Display previously gathered content 
     98     $list->getConfigurationContent(); 
     99 
     100     dcPage::close(); 
     101 
     102     # Stop reading code here 
     103     return; 
     104} 
     105 
     106# -- Execute actions -- 
     107if (!empty($_POST) && empty($_REQUEST['conf']) && $core->auth->isSuperAdmin() && $list->isPathWritable()) { 
     108     try { 
     109          $list->executeAction('themes', $core->themes, $repository); 
     110     } 
     111     catch (Exception $e) { 
    90112          $core->error->add($e->getMessage()); 
    91113     } 
    92114} 
    93115 
    94 # Theme upload 
    95 if ($can_install && $is_writable && ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || 
    96      (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url'])))) 
    97 { 
    98      try 
    99      { 
    100           if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { 
    101                throw new Exception(__('Password verification failed')); 
    102           } 
    103            
    104           if (!empty($_POST['upload_pkg'])) 
    105           { 
    106                files::uploadStatus($_FILES['pkg_file']); 
    107                 
    108                $dest = $core->blog->themes_path.'/'.$_FILES['pkg_file']['name']; 
    109                if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { 
    110                     throw new Exception(__('Unable to move uploaded file.')); 
    111                } 
    112           } 
    113           else 
    114           { 
    115                $url = urldecode($_POST['pkg_url']); 
    116                $dest = $core->blog->themes_path.'/'.basename($url); 
    117                 
    118                try 
    119                { 
    120                     $client = netHttp::initClient($url,$path); 
    121                     $client->setUserAgent('Dotclear - http://www.dotclear.org/'); 
    122                     $client->useGzip(false); 
    123                     $client->setPersistReferers(false); 
    124                     $client->setOutput($dest); 
    125                     $client->get($path); 
    126                } 
    127                catch( Exception $e) 
    128                { 
    129                     throw new Exception(__('An error occurred while downloading the file.')); 
    130                } 
    131                 
    132                unset($client); 
    133           } 
    134            
    135           $ret_code = dcModules::installPackage($dest,$core->themes); 
    136           if ($ret_code == 2) { 
    137                dcPage::addSuccessNotice(__('Theme has been successfully upgraded.')); 
    138           } else { 
    139                dcPage::addSuccessNotice(__('Theme has been successfully installed.')); 
    140           } 
    141           http::redirect('blog_theme.php'); 
    142      } 
    143      catch (Exception $e) 
    144      { 
    145           $core->error->add($e->getMessage()); 
    146           $default_tab = 'add-theme'; 
    147      } 
    148 } 
    149  
    150 $theme_conf_mode = false; 
    151 if (!empty($_REQUEST['conf'])) 
    152 { 
    153      $theme_conf_file = path::real($core->blog->themes_path.'/'.$core->blog->settings->system->theme).'/_config.php'; 
    154      if (file_exists($theme_conf_file)) { 
    155           $theme_conf_mode = true; 
    156      } 
    157 } 
    158  
    159 function display_theme_details($id,$details,$current) 
    160 { 
    161      global $core; 
    162       
    163      $screenshot = 'images/noscreenshot.png'; 
    164      if (file_exists($core->blog->themes_path.'/'.$id.'/screenshot.jpg')) { 
    165           $screenshot = 'blog_theme.php?shot='.rawurlencode($id); 
    166      } 
    167       
    168      $radio_id = 'theme_'.html::escapeHTML($id); 
    169      if (preg_match('#^http(s)?://#',$core->blog->settings->system->themes_url)) { 
    170           $theme_url = http::concatURL($core->blog->settings->system->themes_url,'/'.$id); 
    171      } else { 
    172           $theme_url = http::concatURL($core->blog->url,$core->blog->settings->system->themes_url.'/'.$id); 
    173      } 
    174      $has_conf = file_exists(path::real($core->blog->themes_path.'/'.$id).'/_config.php'); 
    175      $has_css = file_exists(path::real($core->blog->themes_path.'/'.$id).'/style.css'); 
    176      $parent = $core->themes->moduleInfo($id,'parent'); 
    177      $has_parent = (boolean)$parent; 
    178      if ($has_parent) { 
    179           $is_parent_present = $core->themes->moduleExists($parent); 
    180      } 
    181       
    182      $res = 
    183      '<div class="theme-details'.($current ? ' current-theme' : '').'">'. 
    184      '<div class="theme-shot"><img src="'.$screenshot.'" alt="" /></div>'. 
    185      '<div class="theme-info">'. 
    186           '<h4>'.form::radio(array('theme',$radio_id),html::escapeHTML($id),$current,'','',($has_parent && !$is_parent_present)).' '. 
    187           '<label class="classic" for="'.$radio_id.'">'. 
    188           html::escapeHTML($details['name']).'</label></h4>'. 
    189           '<p><span class="theme-desc">'.html::escapeHTML($details['desc']).'</span> '. 
    190           '<span class="theme-author">'.sprintf(__('by %s'),html::escapeHTML($details['author'])).'</span> '. 
    191           '<span class="theme-version">'.sprintf(__('version %s'),html::escapeHTML($details['version'])).'</span> '; 
    192           if ($has_parent) { 
    193                if ($is_parent_present) { 
    194                     $res .= '<span class="theme-parent-ok">'.sprintf(__('(built on "%s")'),html::escapeHTML($parent)).'</span> '; 
    195                } else { 
    196                     $res .= '<span class="theme-parent-missing">'.sprintf(__('(requires "%s")'),html::escapeHTML($parent)).'</span> '; 
    197                } 
    198           } 
    199           if ($has_css) { 
    200                $res .= '<span class="theme-css"><a href="'.$theme_url.'/style.css">'.__('Stylesheet').'</a></span>'; 
    201           } 
    202           $res .= '</p>'; 
    203      $res .= 
    204      '</div>'. 
    205      '<div class="theme-actions">'; 
    206           if ($current && $has_conf) { 
    207                $res .= '<p><a href="blog_theme.php?conf=1" class="button">'.__('Configure theme').'</a></p>'; 
    208           } 
    209           if ($current) { 
    210                # --BEHAVIOR-- adminCurrentThemeDetails 
    211                $res .= $core->callBehavior('adminCurrentThemeDetails',$core,$id,$details); 
    212           } 
    213      $res .= 
    214      '</div>'. 
    215      '</div>'; 
    216       
    217      return $res; 
    218 } 
    219  
    220 if (!$theme_conf_mode) 
    221 { 
    222      $breadcrumb = dcPage::breadcrumb( 
     116# -- Page header -- 
     117dcPage::open(__('Themes management'), 
     118     dcPage::jsLoad('js/_blog_theme.js'). 
     119     dcPage::jsPageTabs(). 
     120     dcPage::jsColorPicker(), 
     121 
     122     # --BEHAVIOR-- themesToolsHeaders 
     123     $core->callBehavior('themesToolsHeaders', $core, false), 
     124 
     125     dcPage::breadcrumb( 
    223126          array( 
    224127               html::escapeHTML($core->blog->name) => '', 
    225                __('Blog appearance') => '' 
    226           )); 
    227 } else { 
    228      $breadcrumb = dcPage::breadcrumb( 
    229           array( 
    230                html::escapeHTML($core->blog->name) => '', 
    231                __('Blog appearance') => 'blog_theme.php', 
    232                __('Theme configuration') => '' 
    233           )); 
    234 } 
    235  
    236 dcPage::open(__('Blog appearance'), 
    237      (!$theme_conf_mode ? dcPage::jsLoad('js/_blog_theme.js') : ''). 
    238      dcPage::jsPageTabs($default_tab). 
    239      dcPage::jsColorPicker(), 
    240      $breadcrumb 
     128               '<span class="page-title">'.__('Blog appearance').'</span>' => '' 
     129          )) 
    241130); 
    242131 
    243 if (!$theme_conf_mode) 
    244 { 
    245      if (!empty($_GET['upd'])) { 
    246           dcPage::success(__('Theme has been successfully changed.')); 
    247      } 
    248       
    249      if (!empty($_GET['added'])) { 
    250           dcPage::success(($_GET['added'] == 2 ? __('Theme has been successfully upgraded') : __('Theme has been successfully installed.'))); 
    251      } 
    252       
    253      if (!empty($_GET['del'])) { 
    254           dcPage::success(__('Theme has been successfully deleted.')); 
    255      } 
    256       
    257      # Themes list 
    258      echo '<div class="multi-part" id="themes-list" title="'.__('Themes').'">'. 
    259      '<h3>'.__('Available themes in your installation').'</h3>'; 
    260       
    261      $themes = $core->themes->getModules(); 
    262      if (isset($themes[$core->blog->settings->system->theme])) { 
    263           echo '<p>'.sprintf(__('You are currently using <strong>%s</strong>'),$themes[$core->blog->settings->system->theme]['name']).'.</p>'; 
    264      } 
    265       
    266      echo 
    267      '<form action="blog_theme.php" method="post" id="themes-form">'. 
    268      '<div id="themes">'; 
    269       
    270      if (isset($themes[$core->blog->settings->system->theme])) { 
    271           echo display_theme_details($core->blog->settings->system->theme,$themes[$core->blog->settings->system->theme],true); 
    272      } 
    273       
    274      foreach ($themes as $k => $v) 
    275      { 
    276           if ($core->blog->settings->system->theme == $k) { // Current theme 
    277                continue; 
    278           } 
    279           echo display_theme_details($k,$v,false); 
    280      } 
    281       
    282      echo '</div>'; 
    283       
    284      echo 
    285      '<div id="themes-actions">'. 
    286       
    287      '<p>'.$core->formNonce().'<input type="submit" name="select" value="'.__('Use selected theme').'" /> ';   
    288      if ($can_install) { 
    289           echo ' <input type="submit" class="delete" name="remove" value="'.__('Delete selected theme').'" />'; 
    290      } 
    291      echo '</p>'. 
    292       
    293      '</div>'. 
    294      '</form>'. 
     132# -- Succes messages -- 
     133if (!empty($_GET['msg'])) { 
     134     $list->displayMessage($_GET['msg']); 
     135} 
     136 
     137# -- Display modules lists -- 
     138if ($core->auth->isSuperAdmin() && $list->isPathWritable()) { 
     139 
     140     # Updated modules from repo 
     141     $modules = $repository->get(true); 
     142     if (!empty($modules)) { 
     143          echo  
     144          '<div class="multi-part" id="update" title="'.html::escapeHTML(__('Update themes')).'">'. 
     145          '<h3>'.html::escapeHTML(__('Update themes')).'</h3>'. 
     146          '<p>'.sprintf( 
     147               __('There is one theme to update available from %2$s.', 'There are %s themes to update available from %s.', count($modules)), 
     148               count($modules), 
     149               '<a href="http://dotaddict.org/dc2/themes">Dotaddict</a>' 
     150          ).'</p>'; 
     151 
     152          $list 
     153               ->newList('theme-update') 
     154               ->setModules($modules) 
     155               ->setPageTab('update') 
     156               ->displayModulesList( 
     157                    /*cols */      array('sshot', 'name', 'desc', 'author', 'version', 'current_version', 'parent'), 
     158                    /* actions */  array('update') 
     159               ); 
     160 
     161          echo 
     162          '</div>'; 
     163     } 
     164} 
     165 
     166# List all active plugins 
     167echo 
     168'<div class="multi-part" id="themes" title="'.__('Installed themes').'">'; 
     169 
     170$modules = $core->themes->getModules(); 
     171if (!empty($modules)) { 
     172 
     173     echo 
     174     '<h3>'.__('Activated themes').'</h3>'. 
     175     '<p>'.__('Manage installed themes from this list.').'</p>'; 
     176 
     177     $list 
     178          ->newList('theme-activate') 
     179          ->setModules($modules) 
     180          ->setPageTab('themes') 
     181          ->displayModulesList( 
     182               /* cols */          array('sshot', 'name', 'config', 'desc', 'author', 'version', 'parent'), 
     183               /* actions */  array('select', 'deactivate', 'delete') 
     184          ); 
     185} 
     186 
     187$modules = $core->themes->getDisabledModules(); 
     188if (!empty($modules)) { 
     189 
     190     echo 
     191     '<h3>'.__('Deactivated themes').'</h3>'. 
     192     '<p>'.__('Deactivated themes are installed but not usable. You can activate them from here.').'</p>'; 
     193 
     194     $list 
     195          ->newList('theme-deactivate') 
     196          ->setModules($modules) 
     197          ->setPageTab('themes') 
     198          ->displayModulesList( 
     199               /* cols */          array('name', 'distrib'), 
     200               /* actions */  array('activate', 'delete') 
     201          ); 
     202} 
     203 
     204echo  
     205'</div>'; 
     206 
     207if ($core->auth->isSuperAdmin() && $list->isPathWritable()) { 
     208 
     209     # New modules from repo 
     210     $search = $list->getSearchQuery(); 
     211     $modules = $search ? $repository->search($search) : $repository->get(); 
     212 
     213     echo 
     214     '<div class="multi-part" id="new" title="'.__('Add themes from Dotaddict').'">'. 
     215     '<h3>'.__('Add themes from Dotaddict repository').'</h3>'; 
     216 
     217     $list 
     218          ->newList('theme-new') 
     219          ->setModules($modules) 
     220          ->setPageTab('new') 
     221          ->displaySearchForm() 
     222          ->displayNavMenu() 
     223          ->displayModulesList( 
     224               /* cols */          array('expander', 'sshot', 'name', 'config', 'desc', 'author', 'version', 'parent', 'distrib'), 
     225               /* actions */  array('install'), 
     226               /* nav limit */     true 
     227          ); 
     228 
     229     echo 
     230     '<p class="info vertical-separator">'.sprintf( 
     231          __("Visit %s repository, the resources center for Dotclear."), 
     232          '<a href="http://dotaddict.org/dc2/themes">Dotaddict</a>' 
     233          ). 
     234     '</p>'. 
     235 
    295236     '</div>'; 
    296       
    297      # Add a new theme 
    298      if ($can_install) 
    299      { 
    300           echo 
    301           '<div class="multi-part clear" id="add-theme" title="'.__('Install or upgrade a theme').'">'. 
    302           '<h3>'.__('Add themes to your installation').'</h3>'. 
    303           '<p class="form-note info">'.sprintf(__('You can find additional themes for your blog on %s.'), 
    304           '<a href="http://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>').'</p>'; 
    305            
    306           if ($is_writable) 
    307           { 
    308                echo '<p>'.__('You can also install themes by uploading or downloading zip files.').'</p>'; 
    309                 
    310                # 'Upload theme' form 
    311                echo 
    312                '<form method="post" action="blog_theme.php" id="uploadpkg" enctype="multipart/form-data" class="fieldset">'. 
    313                '<h4>'.__('Upload a zip file').'</h4>'. 
    314                '<p class="field"><label for="pkg_file" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Theme zip file:').'</label> '. 
    315                '<input type="file" name="pkg_file" id="pkg_file" /></p>'. 
    316                '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 
    317                form::password(array('your_pwd','your_pwd1'),20,255).'</p>'. 
    318                '<p><input type="submit" name="upload_pkg" value="'.__('Upload theme').'" />'. 
    319                $core->formNonce().'</p>'. 
    320                '</form>'; 
    321                 
    322                # 'Fetch theme' form 
    323                echo 
    324                '<form method="post" action="blog_theme.php" id="fetchpkg" class="fieldset">'. 
    325                '<h4>'.__('Download a zip file').'</h4>'. 
    326                '<p class="field"><label for="pkg_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Theme zip file URL:').'</label> '. 
    327                form::field(array('pkg_url','pkg_url'),40,255).'</p>'. 
    328                '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 
    329                form::password(array('your_pwd','your_pwd2'),20,255).'</p>'. 
    330                '<p><input type="submit" name="fetch_pkg" value="'.__('Download theme').'" />'. 
    331                $core->formNonce().'</p>'. 
    332                '</form>'; 
    333           } 
    334           else 
    335           { 
    336                echo 
    337                '<p class="static-msg">'. 
    338                __('To enable this function, please give write access to your themes directory.'). 
    339                '</p>'; 
    340           } 
    341           echo '</div>'; 
    342      } 
    343 } 
    344 else 
    345 { 
    346      $theme_name = $core->themes->moduleInfo($core->blog->settings->system->theme,'name'); 
    347      $core->themes->loadModuleL10Nresources($core->blog->settings->system->theme,$_lang); 
    348  
    349      echo 
    350      '<p><a class="back" href="blog_theme.php">'.__('Back to Blog appearance').'</a></p>'; 
    351       
    352      try 
    353      { 
    354           # Let theme configuration set their own form(s) if required 
    355           $standalone_config = (boolean) $core->themes->moduleInfo($core->blog->settings->system->theme,'standalone_config'); 
    356  
    357           if (!$standalone_config) 
    358                echo '<form id="theme_config" action="blog_theme.php?conf=1" method="post" enctype="multipart/form-data">'; 
    359  
    360           include $theme_conf_file; 
    361  
    362           if (!$standalone_config) 
    363                echo 
    364                '<p class="clear"><input type="submit" value="'.__('Save').'" />'. 
    365                $core->formNonce().'</p>'. 
    366                '</form>'; 
    367  
    368      } 
    369      catch (Exception $e) 
    370      { 
    371           echo '<div class="error"><p>'.$e->getMessage().'</p></div>'; 
    372      } 
     237 
     238     # Add a new plugin 
     239     echo 
     240     '<div class="multi-part" id="addtheme" title="'.__('Install or upgrade manually').'">'; 
     241 
     242     echo '<p>'.__('You can install themes by uploading or downloading zip files.').'</p>'; 
     243      
     244     $list->displayManualForm(); 
     245 
     246     echo 
     247     '</div>'; 
    373248} 
    374249 
  • admin/index.php

    r2166 r2175  
    123123     } 
    124124     $__dashboard_icons['prefs'] = new ArrayObject(array(__('My preferences'),'preferences.php','images/menu/user-pref-b.png')); 
     125} 
     126 
     127# Check plugins and themes update from repository 
     128function dc_check_repository_update($mod, $url, $img, $icon) 
     129{ 
     130     $repo = new dcRepository($mod, $url); 
     131     $repo->check(); 
     132     $upd = $repo->get(true); 
     133     if (!empty($upd)) { 
     134          $icon[0] .= '<br />'.sprintf(__('An update is available', '%s updates are available.', count($upd)),count($upd)); 
     135          $icon[1] .= '#update'; 
     136          $icon[2] = 'images/menu/'.$img.'-b-update.png'; 
     137     } 
     138} 
     139if (isset($__dashboard_icons['plugins'])) { 
     140     dc_check_repository_update($core->plugins, $core->blog->settings->system->repository_plugin_url, 'plugins', $__dashboard_icons['plugins']); 
     141} 
     142if (isset($__dashboard_icons['blog_theme'])) { 
     143     $themes = new dcThemes($core); 
     144     $themes->loadModules($core->blog->themes_path, null); 
     145     dc_check_repository_update($themes, $core->blog->settings->system->repository_theme_url, 'blog-theme', $__dashboard_icons['blog_theme']); 
    125146} 
    126147 
  • admin/js/_blog_theme.js

    r2101 r2195  
    11$(function() { 
    2      $('#themes-actions').hide(); 
    3      var submit_s = $('#themes-actions input[name=select]'); 
    4      var submit_r = $('#themes-actions input[name=remove]'); 
    5       
    6      var details = $('#themes div.theme-details'); 
    7      $('div.theme-actions',details).hide(); 
    8      $('input:radio',details).hide(); 
    9      $('div.theme-info span, div.theme-info a',details).hide(); 
    10      details.removeClass('theme-details').addClass('theme-details-js'); 
    11       
    12      var themes_wrapper = $('<div id="themes-wrapper"></div>'); 
    13      var theme_box = $('<div id="theme-box"><div</div>'); 
    14      $('#themes').wrap(themes_wrapper).before(theme_box); 
    15       
    16      details.each(function() { 
    17           var box = this; 
    18           var a = $(document.createElement('a')); 
    19           a.attr('href','#'); 
    20           a.attr('title',$('>div h3>label',this).text()); 
    21           $(box).wrap(a); 
    22           $(box).parent().click(function(event) { 
    23                update_box(box); 
    24                event.preventDefault(); 
    25                return false; 
    26           }); 
     2     $('.module-sshot').not('.current-theme .module-sshot').each(function(){ 
     3          var bar = $('<div>').addClass('bloc-toggler'); 
     4          $(this).after( 
     5          $(bar).toggleWithLegend($(this).parent().children('.toggle-bloc'),{ 
     6               img_on_src: dotclear.img_plus_theme_src, 
     7               img_on_alt: dotclear.img_plus_theme_alt, 
     8               img_off_src: dotclear.img_minus_theme_src, 
     9               img_off_alt: dotclear.img_minus_theme_alt,  
     10               legend_click: true 
     11          })); 
    2712     }); 
    28       
    29      function update_box(e) { 
    30           theme_box.empty(); 
    31           var img = $('div.theme-shot',e).clone(); 
    32           var info = $('div.theme-info',e).clone(); 
    33            
    34           if ($(e).hasClass('current-theme')) { 
    35                var actions = $('div.theme-actions',e).clone(); 
    36                actions.show(); 
    37           } else { 
    38                var actions = $('<div class="theme-actions"></div>'); 
    39                if (submit_s.length > 0  && !$('input:radio',info).attr('disabled')) { 
    40                     var select = $('<a href="#" class="button">' + dotclear.msg.use_this_theme + '</a>'); 
    41                     select.addClass('select-button').click(function(){ 
    42                          submit_s.click(); 
    43                          return false; 
    44                     }); 
    45                     actions.append(select).append('&nbsp;&nbsp;'); 
    46                } 
    47                if (submit_r.length > 0 && $('input:radio',info).attr('id') != 'theme_default') { 
    48                     var remove = $('<a href="#" class="button delete">' + dotclear.msg.remove_this_theme + '</a>'); 
    49                     remove.click(function() { 
    50                          var t_name = $(this).parents('#theme-box').find('div.theme-info h3:first').text(); 
    51                          t_name = $.trim(t_name); 
    52                          if (window.confirm(dotclear.msg.confirm_delete_theme.replace('%s',t_name))) { 
    53                               submit_r.click(); 
    54                          } 
    55                          return false; 
    56                     }); 
    57                     actions.append(remove); 
    58                } 
    59           } 
    60            
    61           $('input:radio',info).remove(); 
    62           $('span, a',info).show(); 
    63            
    64           theme_box.append(img).append(info).append(actions); 
    65           details.removeClass('theme-selected'); 
    66           $(e).addClass('theme-selected'); 
    67           $('input:radio',e).prop('checked',true); 
    68      } 
    69       
    70      update_box(details[0]); 
    7113}); 
  • admin/js/_plugins.js

    r0 r2171  
     1dotclear.moduleExpander = function(line) { 
     2        var td = line.firstChild; 
     3         
     4        var img = document.createElement('img'); 
     5        img.src = dotclear.img_plus_src; 
     6        img.alt = dotclear.img_plus_alt; 
     7        img.className = 'expand'; 
     8        $(img).css('cursor','pointer'); 
     9        img.line = line; 
     10        img.onclick = function() { dotclear.viewModuleContent(this,this.line); }; 
     11         
     12        td.insertBefore(img,td.firstChild); 
     13}; 
     14 
     15dotclear.modulesExpander = function(line,lines) { 
     16        var td = line.firstChild; 
     17 
     18        var img = document.createElement('img'); 
     19        img.src = dotclear.img_plus_src; 
     20        img.alt = dotclear.img_plus_alt; 
     21        img.className = 'expand'; 
     22        $(img).css('cursor','pointer'); 
     23        img.lines = lines; 
     24        img.onclick = function() { dotclear.viewModulesContent(this,this.lines); }; 
     25 
     26        td.insertBefore(img,td.firstChild); 
     27}; 
     28 
     29dotclear.viewModulesContent = function(img,lines) { 
     30         
     31        action = 'toggle'; 
     32 
     33        if (img.alt == dotclear.img_plus_alt) { 
     34                img.src = dotclear.img_minus_src; 
     35                img.alt = dotclear.img_minus_alt; 
     36                action = 'open'; 
     37        } else { 
     38                img.src = dotclear.img_plus_src; 
     39                img.alt = dotclear.img_plus_alt; 
     40                action = 'close'; 
     41        } 
     42         
     43        lines.each(function() { 
     44                var td = this.firstChild; 
     45                dotclear.viewModuleContent(td.firstChild,td.firstChild.line,action); 
     46        }); 
     47}; 
     48 
     49dotclear.viewModuleContent = function(img,line,action) { 
     50 
     51        var action = action || 'toggle'; 
     52          var cols = $('td',$(line)).length 
     53        var sp = line.id.split('_m_'); 
     54          var listId=sp[0]; 
     55          var moduleId= sp[1]; 
     56 
     57        var tr = document.getElementById('pe'+moduleId); 
     58         
     59          if ( !tr && ( action == 'toggle' || action == 'open' ) ) { 
     60                tr = document.createElement('tr'); 
     61                tr.id = 'pe'+moduleId; 
     62 
     63                var td = document.createElement('td'); 
     64                td.colSpan = cols; 
     65                td.className = 'expand'; 
     66                tr.appendChild(td); 
     67                 
     68                img.src = dotclear.img_minus_src; 
     69                img.alt = dotclear.img_minus_alt; 
     70                 
     71                // Get post content 
     72                $.get('services.php',{f:'getModuleById', id: moduleId, list: listId},function(data) { 
     73                        var rsp = $(data).children('rsp')[0]; 
     74                         
     75                        if (rsp.attributes[0].value == 'ok') { 
     76                                var author = $(rsp).find('author').text(); 
     77                                var details = $(rsp).find('details').text(); 
     78                                var support = $(rsp).find('support').text(); 
     79                                        var box = document.createElement('div'); 
     80                                var dl = document.createElement('ul'); 
     81                                dl.className = "mod-more"; 
     82                                 
     83                                if (author) { 
     84                                        $(dl).append($('<li class="module-author">'+dotclear.msg.module_author+' '+author+'</li>')); 
     85                                } 
     86                                if (details) { 
     87                                        var dd = ''; 
     88                                        dd += '<a class="module-details" href="'+details+'">'+dotclear.msg.module_details+'</a>'; 
     89                                        if (support) { 
     90                                                dd += ' - '; 
     91                                                dd += '<a class="module-support" href="'+support+'">'+dotclear.msg.module_support+'</a>'; 
     92                                        } 
     93                                        $(dl).append($('<li>'+dotclear.msg.module_help+' '+dd+'</li>')); 
     94                                } 
     95 
     96                                $(td).append($(box).addClass('two-boxes').append(dl)); 
     97                                 
     98                                var section = $(rsp).find('section').text(); 
     99                                var tags = $(rsp).find('tags').text(); 
     100                                 
     101                                        var boxb = document.createElement('div'); 
     102                                var dlb = document.createElement('ul'); 
     103                                dlb.className = "mod-more"; 
     104                                 
     105                                if (section) { 
     106                                        $(dlb).append($('<li class="module-section">'+dotclear.msg.module_section+' '+section+'</li>')); 
     107                                } 
     108                                if (tags) { 
     109                                        $(dlb).append($('<li class="module-tags">'+dotclear.msg.module_tags+' '+tags+'</li>')); 
     110                                } 
     111                                $(td).append($(boxb).addClass('two-boxes').append(dlb)); 
     112                        } else { 
     113                                alert($(rsp).find('message').text()); 
     114                        } 
     115                }); 
     116                 
     117                $(line).addClass('expand'); 
     118                line.parentNode.insertBefore(tr,line.nextSibling); 
     119        } 
     120        else if (tr && tr.style.display == 'none' && ( action == 'toggle' || action == 'open' ) ) 
     121        { 
     122                $(tr).css('display', 'table-row'); 
     123                $(line).addClass('expand'); 
     124                img.src = dotclear.img_minus_src; 
     125                img.alt = dotclear.img_minus_alt; 
     126        } 
     127        else if (tr && tr.style.display != 'none' && ( action == 'toggle' || action == 'close' ) ) 
     128        { 
     129                $(tr).css('display', 'none'); 
     130                $(line).removeClass('expand'); 
     131                img.src = dotclear.img_plus_src; 
     132                img.alt = dotclear.img_plus_alt; 
     133        } 
     134         
     135        parentTable = $(line).parents('table'); 
     136        if( parentTable.find('tr.expand').length == parentTable.find('tr.line').length ) { 
     137                img = parentTable.find('tr:not(.line) th:first img'); 
     138                img.attr('src',dotclear.img_minus_src); 
     139                img.attr('alt',dotclear.img_minus_alt); 
     140        } 
     141         
     142        if( parentTable.find('tr.expand').length == 0 ) { 
     143                img = parentTable.find('tr:not(.line) th:first img'); 
     144                img.attr('src',dotclear.img_plus_src); 
     145                img.attr('alt',dotclear.img_plus_alt); 
     146        } 
     147         
     148}; 
     149 
     150 
    1151$(function() { 
    2      $('table.plugins form input[type=submit][name=delete]').click(function() { 
    3           var p_name = $('input[name=plugin_id]',$(this).parent()).val(); 
    4           return window.confirm(dotclear.msg.confirm_delete_plugin.replace('%s',p_name)); 
    5      }); 
     152        $('table.modules.expandable tr:not(.line)').each(function() { 
     153                dotclear.modulesExpander(this,$('table.modules tr.line')); 
     154        }); 
     155        $('table.modules.expandable tr.line').each(function() { 
     156                dotclear.moduleExpander(this); 
     157        }); 
    6158}); 
  • admin/plugins.php

    r2166 r2182  
    1313require dirname(__FILE__).'/../inc/admin/prepend.php'; 
    1414 
    15 dcPage::checkSuper(); 
    16  
    17 $default_tab = !empty($_REQUEST['tab']) ? html::escapeHTML($_REQUEST['tab']) : 'plugins'; 
    18  
    19 $p_paths = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT); 
    20 $p_path = array_pop($p_paths); 
    21 unset($p_paths); 
    22  
    23 $is_writable = false; 
    24 if (is_dir($p_path) && is_writeable($p_path)) { 
    25      $is_writable = true; 
    26      $p_path_pat = preg_quote($p_path,'!'); 
    27 } 
    28  
    29 $plugin_id = !empty($_POST['plugin_id']) ? $_POST['plugin_id'] : null; 
    30  
    31 if ($is_writable) 
    32 { 
    33      # Delete plugin 
    34      if ($plugin_id && !empty($_POST['delete'])) 
    35      { 
    36           try 
    37           { 
    38                if (empty($_POST['deactivated'])) 
    39                { 
    40                     if (!$core->plugins->moduleExists($plugin_id)) { 
    41                          throw new Exception(__('No such plugin.')); 
    42                     } 
    43                      
    44                     $plugin = $core->plugins->getModules($plugin_id); 
    45                     $plugin['id'] = $plugin_id; 
    46                      
    47                     if (!preg_match('!^'.$p_path_pat.'!', $plugin['root'])) { 
    48                          throw new Exception(__('You don\'t have permissions to delete this plugin.')); 
    49                     } 
    50                      
    51                     # --BEHAVIOR-- pluginBeforeDelete 
    52                     $core->callBehavior('pluginsBeforeDelete', $plugin); 
    53                      
    54                     $core->plugins->deleteModule($plugin_id); 
    55                      
    56                     # --BEHAVIOR-- pluginAfterDelete 
    57                     $core->callBehavior('pluginsAfterDelete', $plugin); 
    58                } 
    59                else 
    60                { 
    61                     $core->plugins->deleteModule($plugin_id,true); 
    62                } 
    63                 
    64                http::redirect('plugins.php?removed=1'); 
    65           } 
    66           catch (Exception $e) 
    67           { 
    68                $core->error->add($e->getMessage()); 
    69           } 
    70      } 
    71      # Deactivate plugin 
    72      elseif ($plugin_id && !empty($_POST['deactivate'])) 
    73      { 
    74           try 
    75           { 
    76                if (!$core->plugins->moduleExists($plugin_id)) { 
    77                     throw new Exception(__('No such plugin.')); 
    78                } 
    79                 
    80                $plugin = $core->plugins->getModules($plugin_id); 
    81                $plugin['id'] = $plugin_id; 
    82                 
    83                if (!$plugin['root_writable']) { 
    84                     throw new Exception(__('You don\'t have permissions to deactivate this plugin.')); 
    85                } 
    86                 
    87                # --BEHAVIOR-- pluginBeforeDeactivate 
    88                $core->callBehavior('pluginsBeforeDeactivate', $plugin); 
    89                      
    90                $core->plugins->deactivateModule($plugin_id); 
    91  
    92                # --BEHAVIOR-- pluginAfterDeactivate 
    93                $core->callBehavior('pluginsAfterDeactivate', $plugin); 
    94                      
    95                http::redirect('plugins.php'); 
    96           } 
    97           catch (Exception $e) 
    98           { 
    99                $core->error->add($e->getMessage()); 
    100           } 
    101      } 
    102      # Activate plugin 
    103      elseif ($plugin_id && !empty($_POST['activate'])) 
    104      { 
    105           try 
    106           { 
    107                $p = $core->plugins->getDisabledModules(); 
    108                if (!isset($p[$plugin_id])) { 
    109                     throw new Exception(__('No such plugin.')); 
    110                } 
    111  
    112                # --BEHAVIOR-- pluginBeforeActivate 
    113                $core->callBehavior('pluginsBeforeActivate', $plugin_id); 
    114                 
    115                $core->plugins->activateModule($plugin_id); 
    116  
    117                # --BEHAVIOR-- pluginAfterActivate 
    118                $core->callBehavior('pluginsAfterActivate', $plugin_id); 
    119                 
    120                http::redirect('plugins.php'); 
    121           } 
    122           catch (Exception $e) 
    123           { 
    124                $core->error->add($e->getMessage()); 
    125           } 
    126      } 
    127      # Plugin upload 
    128      elseif ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || 
    129           (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url']))) 
    130      { 
    131           try 
    132           { 
    133                if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { 
    134                     throw new Exception(__('Password verification failed')); 
    135                } 
    136                 
    137                if (!empty($_POST['upload_pkg'])) 
    138                { 
    139                     files::uploadStatus($_FILES['pkg_file']); 
    140                      
    141                     $dest = $p_path.'/'.$_FILES['pkg_file']['name']; 
    142                     if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { 
    143                          throw new Exception(__('Unable to move uploaded file.')); 
    144                     } 
    145                } 
    146                else 
    147                { 
    148                     $url = urldecode($_POST['pkg_url']); 
    149                     $dest = $p_path.'/'.basename($url); 
    150                      
    151                     try 
    152                     { 
    153                          $client = netHttp::initClient($url,$path); 
    154                          $client->setUserAgent('Dotclear - http://www.dotclear.org/'); 
    155                          $client->useGzip(false); 
    156                          $client->setPersistReferers(false); 
    157                          $client->setOutput($dest); 
    158                          $client->get($path); 
    159                     } 
    160                     catch( Exception $e) 
    161                     { 
    162                          throw new Exception(__('An error occurred while downloading the file.')); 
    163                     } 
    164                      
    165                     unset($client); 
    166                } 
    167  
    168                # --BEHAVIOR-- pluginBeforeAdd 
    169                $core->callBehavior('pluginsBeforeAdd', $plugin_id); 
    170                                
    171                $ret_code = $core->plugins->installPackage($dest,$core->plugins); 
    172  
    173                # --BEHAVIOR-- pluginAfterAdd 
    174                $core->callBehavior('pluginsAfterAdd', $plugin_id); 
    175                 
    176                http::redirect('plugins.php?added='.$ret_code); 
    177           } 
    178           catch (Exception $e) 
    179           { 
    180                $core->error->add($e->getMessage()); 
    181                $default_tab = 'addplugin'; 
    182           } 
    183      } 
    184 } 
    185  
    186 # Plugin install 
    187 $plugins_install = $core->plugins->installModules(); 
    188  
    189 /* DISPLAY Main page 
    190 -------------------------------------------------------- */ 
     15dcPage::check('admin'); 
     16 
     17# -------------------------------------------------- 
     18# @todo Add settings to Dotclear update features 
     19if ($core->blog->settings->system->plugins_allow_multi_install === null) { 
     20     $core->blog->settings->system->put( 
     21          'plugins_allow_multi_install', false, 'boolean', 'Allow multi-installation for plugins', true, true 
     22     ); 
     23} 
     24if ($core->blog->settings->system->repository_plugin_url === null) { 
     25     $core->blog->settings->system->put( 
     26          'repository_plugin_url', 'http://update.dotaddict.org/dc2/plugins.xml', 'string', 'Plugins XML feed location', true, true 
     27     ); 
     28} 
     29# -------------------------------------------------- 
     30 
     31# -- Repository helper -- 
     32$repository = new dcRepository( 
     33     $core->plugins,  
     34     $core->blog->settings->system->repository_plugin_url 
     35); 
     36$repository->check(); 
     37 
     38# -- Page helper -- 
     39$list = new adminModulesList( 
     40     $core,  
     41     DC_PLUGINS_ROOT, 
     42     $core->blog->settings->system->plugins_allow_multi_install 
     43); 
     44 
     45$list::setDistributedModules(array( 
     46     'aboutConfig', 
     47     'akismet', 
     48     'antispam', 
     49     'attachments', 
     50     'blogroll', 
     51     'blowupConfig', 
     52     'daInstaller', 
     53     'fairTrackbacks', 
     54     'importExport', 
     55     'maintenance', 
     56     'pages', 
     57     'pings', 
     58     'simpleMenu', 
     59     'tags', 
     60     'themeEditor', 
     61     'userPref', 
     62     'widgets' 
     63)); 
     64 
     65# -- Display module configuration page -- 
     66if ($list->setConfigurationFile($core->plugins)) { 
     67 
     68     # Get content before page headers 
     69     include $list->getConfigurationFile(); 
     70 
     71     # Gather content 
     72     $list->setConfigurationContent(); 
     73 
     74     # Display page 
     75     dcPage::open(__('Plugins management'), 
     76 
     77          # --BEHAVIOR-- pluginsToolsHeaders 
     78          $core->callBehavior('pluginsToolsHeaders', $core, true), 
     79 
     80          dcPage::breadcrumb( 
     81               array( 
     82                    html::escapeHTML($core->blog->name) => '', 
     83                    '<a href="'.$list->getPageURL().'">'.__('Plugins management').'</a>' => '', 
     84                    '<span class="page-title">'.__('Plugin configuration').'</span>' => '' 
     85               )) 
     86     ); 
     87 
     88     # Message 
     89     if (!empty($_GET['done'])){ 
     90          dcPage::success(__('Plugin successfully configured.')); 
     91     } 
     92 
     93     # Display previously gathered content 
     94     $list->getConfigurationContent(); 
     95 
     96     dcPage::close(); 
     97 
     98     # Stop reading code here 
     99     return; 
     100} 
     101 
     102# -- Execute actions -- 
     103if (!empty($_POST) && empty($_REQUEST['conf']) && $core->auth->isSuperAdmin() && $list->isPathWritable()) { 
     104     try { 
     105          $list->executeAction('plugins', $core->plugins, $repository); 
     106     } 
     107     catch (Exception $e) { 
     108          $core->error->add($e->getMessage()); 
     109     } 
     110} 
     111 
     112# -- Plugin install -- 
     113$plugins_install = null; 
     114if (!$core->error->flag()) { 
     115     $plugins_install = $core->plugins->installModules(); 
     116} 
     117 
     118# -- Page header -- 
    191119dcPage::open(__('Plugins management'), 
    192120     dcPage::jsLoad('js/_plugins.js'). 
    193      dcPage::jsPageTabs($default_tab), 
     121     dcPage::jsPageTabs(). 
     122 
     123     # --BEHAVIOR-- pluginsToolsHeaders 
     124     $core->callBehavior('pluginsToolsHeaders', $core, false), 
     125 
    194126     dcPage::breadcrumb( 
    195127          array( 
     
    199131); 
    200132 
    201 if (!empty($_GET['removed'])) { 
    202      dcPage::success(__('Plugin has been successfully deleted.')); 
    203 } 
    204 if (!empty($_GET['added'])) { 
    205      dcPage::success(($_GET['added'] == 2 ? __('Plugin has been successfully upgraded') : __('Plugin has been successfully installed.'))); 
    206 } 
    207  
    208 # Plugins install messages 
    209 if (!empty($plugins_install['success'])) 
    210 { 
    211      echo '<div class="static-msg">'.__('Following plugins have been installed:').'<ul>'; 
     133# -- Succes messages -- 
     134if (!empty($_GET['msg'])) { 
     135     $list->displayMessage($_GET['msg']); 
     136} 
     137 
     138# -- Plugins install messages -- 
     139if (!empty($plugins_install['success'])) { 
     140     echo  
     141     '<div class="static-msg">'.__('Following plugins have been installed:').'<ul>'; 
    212142     foreach ($plugins_install['success'] as $k => $v) { 
    213           echo '<li>'.$k.'</li>'; 
    214      } 
    215      echo '</ul></div>'; 
    216 } 
    217 if (!empty($plugins_install['failure'])) 
    218 { 
    219      echo '<div class="error">'.__('Following plugins have not been installed:').'<ul>'; 
     143          echo  
     144          '<li>'.$k.'</li>'; 
     145     } 
     146     echo  
     147     '</ul></div>'; 
     148} 
     149if (!empty($plugins_install['failure'])) { 
     150     echo  
     151     '<div class="error">'.__('Following plugins have not been installed:').'<ul>'; 
    220152     foreach ($plugins_install['failure'] as $k => $v) { 
    221           echo '<li>'.$k.' ('.$v.')</li>'; 
    222      } 
    223      echo '</ul></div>'; 
     153          echo  
     154          '<li>'.$k.' ('.$v.')</li>'; 
     155     } 
     156     echo  
     157     '</ul></div>'; 
     158} 
     159 
     160# -- Display modules lists -- 
     161if ($core->auth->isSuperAdmin() && $list->isPathWritable()) { 
     162 
     163     # Updated modules from repo 
     164     $modules = $repository->get(true); 
     165     if (!empty($modules)) { 
     166          echo  
     167          '<div class="multi-part" id="update" title="'.html::escapeHTML(__('Update plugins')).'">'. 
     168          '<h3>'.html::escapeHTML(__('Update plugins')).'</h3>'. 
     169          '<p>'.sprintf( 
     170               __('There is one plugin to update available from %2$s.', 'There are %s plugins to update available from %s.', count($modules)), 
     171               count($modules), 
     172               '<a href="http://dotaddict.org/dc2/plugins">Dotaddict</a>' 
     173          ).'</p>'; 
     174 
     175          $list 
     176               ->newList('plugin-update') 
     177               ->setModules($modules) 
     178               ->setPageTab('update') 
     179               ->displayModulesList( 
     180                    /*cols */      array('icon', 'name', 'version', 'current_version', 'desc'), 
     181                    /* actions */  array('update') 
     182               ); 
     183 
     184          echo 
     185          '</div>'; 
     186     } 
    224187} 
    225188 
    226189# List all active plugins 
    227 echo '<p>'.__('Plugins add new functionalities to Dotclear. '. 
    228 'Here you can activate or deactivate installed plugins.').'</p>'; 
    229  
    230 echo (!$core->plugins->moduleExists('daInstaller') ? 
    231      sprintf('<p><strong>'.__('You can find additional plugins for your blog on %s.').'</strong></p>', 
    232           '<a href="http://plugins.dotaddict.org/dc2/">Dotaddict</a>') : 
    233      sprintf('<p><strong>'.__('You can find additional plugins for your blog on %s or using the %s.').'</strong></p>', 
    234           '<a href="http://plugins.dotaddict.org/dc2/">Dotaddict</a>', 
    235           '<a href="plugin.php?p=daInstaller">'.__('DotAddict.org Installer').'</a>')); 
    236  
    237 if ($is_writable) { 
    238      echo '<p>'.__('To install or upgrade a plugin you generally just need to upload it '. 
    239      'in "Install or upgrade a plugin" section.'); 
    240 } else { 
    241      echo '<p>'.__('To install or upgrade a plugin you just need to extract it in your plugins directory.'); 
    242 } 
    243 echo '</p>'; 
    244  
    245190echo 
    246 '<div class="multi-part" id="plugins" title="'.__('Plugins').'">'; 
    247  
    248 $p_available = $core->plugins->getModules(); 
    249 uasort($p_available,create_function('$a,$b','return strcasecmp($a["name"],$b["name"]);')); 
    250 if (!empty($p_available))  
    251 { 
     191'<div class="multi-part" id="plugins" title="'.__('Installed plugins').'">'; 
     192 
     193$modules = $core->plugins->getModules(); 
     194if (!empty($modules)) { 
     195 
    252196     echo 
    253197     '<h3>'.__('Activated plugins').'</h3>'. 
    254      '<div class="table-outer clear">'. 
    255      '<table class="plugins"><tr>'. 
    256      '<th>'.__('Plugin').'</th>'. 
    257      '<th class="nowrap">'.__('Version').'</th>'. 
    258      '<th class="nowrap">'.__('Details').'</th>'. 
    259      '<th class="nowrap">'.__('Action').'</th>'. 
    260      '</tr>'; 
    261       
    262      $distrib_plugins = array('aboutConfig','akismet','antispam','attachments','blogroll','blowupConfig','daInstaller', 
    263           'fairTrackbacks','importExport','maintenance','pages','pings','simpleMenu','tags','themeEditor','userPref','widgets'); 
    264      $distrib_img = '<img src="images/dotclear_pw.png"'. 
    265           ' alt="'.__('Plugin from official distribution').'" title="'.__('Plugin from official distribution').'" />'; 
    266  
    267      foreach ($p_available as $k => $v) 
    268      { 
    269           $is_deletable = $is_writable && preg_match('!^'.$p_path_pat.'!',$v['root']); 
    270           $is_deactivable = $v['root_writable']; 
    271           $is_distrib = in_array($k, $distrib_plugins); 
    272            
    273           echo 
    274           '<tr class="line wide">'. 
    275           '<td class="minimal nowrap"><strong>'.html::escapeHTML($k).'</strong></td>'. 
    276           '<td class="minimal">'.html::escapeHTML($v['version']).'</td>'. 
    277           '<td class="maximal'.($is_distrib ? ' distrib' : '').'"><strong>'.html::escapeHTML(__($v['name'])).'</strong> '. 
    278           '<br />'.html::escapeHTML(__($v['desc'])).($is_distrib ? ' '.$distrib_img : '').'</td>'. 
    279           '<td class="nowrap action">'; 
    280            
    281           if ($is_deletable || $is_deactivable) 
    282           { 
    283                echo 
    284                '<form action="plugins.php" method="post">'. 
    285                '<div>'. 
    286                $core->formNonce(). 
    287                form::hidden(array('plugin_id'),html::escapeHTML($k)). 
    288                ($is_deactivable ? '<input type="submit" name="deactivate" value="'.__('Deactivate').'" /> ' : ''). 
    289                ($is_deletable ? '<input type="submit" class="delete" name="delete" value="'.__('Delete').'" /> ' : ''). 
    290                '</div>'. 
    291                '</form>'; 
    292           } 
    293            
    294           echo 
    295           '</td>'. 
    296           '</tr>'; 
    297      } 
    298      echo 
    299      '</table></div>'; 
    300 } 
    301  
    302 $p_disabled = $core->plugins->getDisabledModules(); 
    303 uksort($p_disabled,create_function('$a,$b','return strcasecmp($a,$b);')); 
    304 if (!empty($p_disabled)) 
    305 { 
     198     '<p>'.__('Manage installed plugins from this list.').'</p>'; 
     199 
     200     $list 
     201          ->newList('plugin-activate') 
     202          ->setModules($modules) 
     203          ->setPageTab('plugins') 
     204          ->displayModulesList( 
     205               /* cols */          array('expander', 'icon', 'name', 'config', 'version', 'desc', 'distrib'), 
     206               /* actions */  array('deactivate', 'delete') 
     207          ); 
     208} 
     209 
     210# Deactivated modules 
     211$modules = $core->plugins->getDisabledModules(); 
     212if (!empty($modules)) { 
     213 
    306214     echo 
    307215     '<h3>'.__('Deactivated plugins').'</h3>'. 
    308      '<div class="clear table-outer">'. 
    309      '<table class="plugins"><tr>'. 
    310      '<th>'.__('Plugin').'</th>'. 
    311      '<th class="nowrap">'.__('Action').'</th>'. 
    312      '</tr>'; 
    313       
    314      foreach ($p_disabled as $k => $v) 
    315      { 
    316           $is_deletable = $is_writable && preg_match('!^'.$p_path_pat.'!',$v['root']); 
    317           $is_activable = $v['root_writable']; 
    318            
    319           echo 
    320           '<tr class="line wide">'. 
    321           '<td class="maximal nowrap"><strong>'.html::escapeHTML($k).'</strong></td>'. 
    322           '<td class="nowrap action">'; 
    323            
    324           if ($is_deletable || $is_activable) 
    325           { 
    326                echo 
    327                '<form action="plugins.php" method="post">'. 
    328                '<div>'. 
    329                $core->formNonce(). 
    330                form::hidden(array('plugin_id'),html::escapeHTML($k)). 
    331                form::hidden(array('deactivated'),1). 
    332                ($is_activable ? '<input type="submit" name="activate" value="'.__('Activate').'" /> ' : ''). 
    333                ($is_deletable ? '<input type="submit" class="delete" name="delete" value="'.__('Delete').'" /> ' : ''). 
    334                '</div>'. 
    335                '</form>'; 
    336           } 
    337            
    338           echo 
    339           '</td>'. 
    340           '</tr>'; 
    341      } 
    342      echo 
    343      '</table></div>'; 
    344 } 
    345  
    346 echo '</div>'; 
    347  
    348 # Add a new plugin 
    349 echo 
    350 '<div class="multi-part" id="addplugin" title="'.__('Install or upgrade a plugin').'">'; 
    351  
    352 if ($is_writable) 
    353 { 
     216     '<p>'.__('Deactivated plugins are installed but not usable. You can activate them from here.').'</p>'; 
     217 
     218     $list 
     219          ->newList('plugin-deactivate') 
     220          ->setModules($modules) 
     221          ->setPageTab('plugins') 
     222          ->displayModulesList( 
     223               /* cols */          array('icon', 'name', 'distrib'), 
     224               /* actions */  array('activate', 'delete') 
     225          ); 
     226} 
     227 
     228echo  
     229'</div>'; 
     230 
     231if ($core->auth->isSuperAdmin() && $list->isPathWritable()) { 
     232 
     233     # New modules from repo 
     234     $search = $list->getSearchQuery(); 
     235     $modules = $search ? $repository->search($search) : $repository->get(); 
     236 
     237     echo 
     238     '<div class="multi-part" id="new" title="'.__('Add plugins from Dotaddict').'">'. 
     239     '<h3>'.__('Add plugins from Dotaddict repository').'</h3>'; 
     240 
     241     $list 
     242          ->newList('plugin-new') 
     243          ->setModules($modules) 
     244          ->setPageTab('new') 
     245          ->displaySearchForm() 
     246          ->displayNavMenu() 
     247          ->displayModulesList( 
     248               /* cols */          array('expander', 'name', 'version', 'desc'), 
     249               /* actions */  array('install'), 
     250               /* nav limit */     true 
     251          ); 
     252 
     253     echo 
     254     '<p class="info vertical-separator">'.sprintf( 
     255          __("Visit %s repository, the resources center for Dotclear."), 
     256          '<a href="http://dotaddict.org/dc2/plugins">Dotaddict</a>' 
     257          ). 
     258     '</p>'. 
     259 
     260     '</div>'; 
     261 
     262     # Add a new plugin 
     263     echo 
     264     '<div class="multi-part" id="addplugin" title="'.__('Install or upgrade manually').'">'; 
     265 
    354266     echo '<p>'.__('You can install plugins by uploading or downloading zip files.').'</p>'; 
    355267      
    356      # 'Upload plugin' form 
    357      echo 
    358      '<form method="post" action="plugins.php" id="uploadpkg" enctype="multipart/form-data" class="fieldset">'. 
    359      '<h3>'.__('Upload a zip file').'</h3>'. 
    360      '<p class="field"><label for="pkg_file" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Plugin zip file:').'</label> '. 
    361      '<input type="file" id="pkg_file" name="pkg_file" /></p>'. 
    362      '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 
    363      form::password(array('your_pwd','your_pwd1'),20,255).'</p>'. 
    364      '<p><input type="submit" name="upload_pkg" value="'.__('Upload plugin').'" />'. 
    365      $core->formNonce(). 
    366      '</p>'. 
    367      '</form>'; 
    368       
    369      # 'Fetch plugin' form 
    370      echo 
    371      '<form method="post" action="plugins.php" id="fetchpkg" class="fieldset">'. 
    372      '<h3>'.__('Download a zip file').'</h3>'. 
    373      '<p class="field"><label for="pkg_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Plugin zip file URL:').'</label> '. 
    374      form::field(array('pkg_url','pkg_url'),40,255).'</p>'. 
    375      '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 
    376      form::password(array('your_pwd','your_pwd2'),20,255).'</p>'. 
    377      '<p><input type="submit" name="fetch_pkg" value="'.__('Download plugin').'" />'. 
    378      $core->formNonce().'</p>'. 
    379      '</form>'; 
    380 } 
    381 else 
    382 { 
    383      echo 
    384      '<p class="static-msg">'. 
    385      __('To enable this function, please give write access to your plugins directory.'). 
    386      '</p>'; 
    387 } 
    388 echo '</div>'; 
     268     $list->displayManualForm(); 
     269 
     270     echo 
     271     '</div>'; 
     272} 
    389273 
    390274# --BEHAVIOR-- pluginsToolsTabs 
    391 $core->callBehavior('pluginsToolsTabs',$core); 
     275$core->callBehavior('pluginsToolsTabs', $core); 
     276 
     277# -- Notice for super admin -- 
     278if ($core->auth->isSuperAdmin() && !$list->isPathWritable()) { 
     279     echo  
     280     '<p class="warning">'.__('Some functions are disabled, please give write access to your plugins directory to enable them.').'</p>'; 
     281} 
    392282 
    393283dcPage::close(); 
  • admin/services.php

    r1699 r2174  
    2727$core->rest->addFunction('searchMeta',array('dcRestMethods','searchMeta')); 
    2828$core->rest->addFunction('setSectionFold',array('dcRestMethods','setSectionFold')); 
     29$core->rest->addFunction('getModuleById',array('dcRestMethods','getModuleById')); 
    2930 
    3031$core->rest->serve(); 
     
    442443          return true; 
    443444     } 
    444            
    445       
     445      
     446     public static function getModuleById($core, $get, $post) 
     447     { 
     448          if (empty($get['id'])) { 
     449                    throw new Exception('No module ID'); 
     450          } 
     451          if (empty($get['list'])) { 
     452                    throw new Exception('No list ID'); 
     453          } 
     454 
     455          $id = $get['id']; 
     456          $list = $get['list']; 
     457          $module = array(); 
     458 
     459          if ($list == 'plugin-activate') { 
     460               $modules = $core->plugins->getModules(); 
     461               if (empty($modules) || !isset($modules[$id])) { 
     462                    throw new Exception('Unknow module ID'); 
     463               } 
     464               $module = $modules[$id]; 
     465          } 
     466          elseif ($list == 'plugin-new') { 
     467               $repository = new dcRepository( 
     468                    $core->plugins,  
     469                    $core->blog->settings->system->repository_plugin_url 
     470               ); 
     471               $repository->check(); 
     472 
     473               $modules = $repository->get(); 
     474               if (empty($modules) || !isset($modules[$id])) { 
     475                    throw new Exception('Unknow module ID'); 
     476               } 
     477               $module = $modules[$id]; 
     478          } 
     479          else { 
     480               // behavior not implemented yet 
     481          } 
     482 
     483          if (empty($module)) { 
     484                    throw new Exception('Unknow module ID'); 
     485          } 
     486 
     487          $module = adminModulesList::parseModuleInfo($id, $module); 
     488 
     489          $rsp = new xmlTag('module'); 
     490          $rsp->id = $id; 
     491           
     492          foreach($module as $k => $v) { 
     493               $rsp->{$k}((string) $v); 
     494          } 
     495 
     496          return $rsp; 
     497     } 
    446498} 
    447499?> 
  • admin/style/default.css

    r2152 r2195  
    158158     -moz-box-sizing: border-box;  
    159159     -webkit-box-sizing: border-box;  
    160      box-sizing: border-box;   
     160     box-sizing: border-box; 
     161     text-align: left; 
    161162     } 
    162163.two-boxes { 
     
    15321533                    } 
    15331534/* ------------------------------------------------------------------- blog_theme.php */ 
    1534 #themes { 
    1535      margin: 0; 
    1536      width: 100%; 
    1537      padding: 0; 
    1538      } 
    1539      .theme-details { 
    1540           border-top: 1px solid #ccc; 
    1541           padding: 12px; 
    1542           display: inline-block; 
    1543           vertical-align: top; 
    1544           width: 284px; 
    1545           } 
    1546           .theme-details.current-theme { 
    1547                background: #eef; 
    1548                } 
    1549           .theme-details:hover { 
    1550                background: #f3f3f3; 
    1551                } 
    1552           .theme-shot img { 
    1553                display: block; 
    1554                border: 1px solid #ccc; 
    1555                margin-bottom: 1.5em; 
    1556                } 
    1557           span.theme-desc { 
    1558                display: block; 
    1559                } 
    1560           span.theme-version { 
    1561                color: #676e78; 
    1562                } 
    1563           .theme-css { 
    1564                display: block; 
    1565                } 
    1566      #themes-actions { 
    1567           border-bottom: 1px solid #999; 
    1568           margin-bottom: 3em; 
    1569           } 
    1570 /* Themes list, JS version */ 
    1571 #themes-wrapper { 
    1572      display: table; 
    1573      } 
    1574      #themes-wrapper #themes { 
    1575           display: table-cell; 
    1576           vertical-align: top; 
    1577           padding-left: 1em; 
    1578           } 
    1579      #theme-box { 
    1580           display: table-cell; 
    1581           vertical-align: top; 
    1582           padding: 0; 
    1583           width: 312px; 
    1584           border: 1px solid #ccc; 
    1585           border-radius: 3px; 
    1586           } 
    1587           #theme-box .theme-shot, 
    1588           #theme-box .theme-info, 
    1589           #theme-box .theme-actions { 
    1590                background: #eef; 
    1591                padding: 1em 16px; 
    1592                margin: 0; 
    1593                } 
    1594           #theme-box .theme-shot img { 
    1595                display: block; 
    1596                width: 280px; 
    1597                height: 245px; 
    1598                border: 1px solid #ccc; 
    1599                } 
    1600           #theme-box h4 { 
    1601                color: #000; 
    1602                background: #eef; 
    1603                } 
    1604           #theme-box span.theme-version { 
    1605                color: #676e78; 
    1606                } 
    1607           #theme-box span.theme-parent-ok { 
    1608                color: #676e78; 
    1609                } 
    1610           #theme-box span.theme-parent-missing { 
    1611                color: #c00; 
    1612                font-weight:bold; 
    1613                } 
    1614           #theme-box .theme-actions { 
    1615                border-bottom: 1px solid #ccc; 
    1616                } 
    1617 #themes .theme-details-js { 
     1535.box.theme { 
     1536     margin: .5em; 
     1537     padding: 1em 1em .5em 1em; 
     1538     border: 1px solid #ccc; 
     1539     } 
     1540.box.current-theme { 
     1541     width: 652px; 
     1542     margin: .5em; 
     1543     padding: 1em 0 .5em 1em; 
     1544     background: #FCFDFD; 
     1545     border: 1px solid #9AC123; 
     1546     -webkit-border-radius: .5em; 
     1547                  border-radius: .5em;   
     1548     } 
     1549#theme-new .box.theme { 
     1550     width: 280px; 
     1551     } 
     1552.module-name { 
     1553     margin-bottom: .5em; 
     1554     } 
     1555.module-sshot img { 
     1556     border: 1px solid #ddd; 
     1557     padding: .5em; 
     1558     background: #f7f7f7; 
     1559     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2); 
     1560     } 
     1561.module-actions { 
     1562     margin-top: 1em; 
     1563     } 
     1564.current-theme .module-sshot img { 
    16181565     float: left; 
    1619      width: 120px; 
    1620      height: 150px; 
    1621      margin: 0 12px 24px; 
    1622      padding: 12px 12px 0; 
     1566     margin-right: 2em; 
     1567     margin-bottom: 1em; 
     1568     } 
     1569.bloc-toggler { 
    16231570     text-align: center; 
    1624      background: #f3f3f3; 
    1625      border: 1px solid #ddd; 
    1626      cursor: pointer; 
    1627      border-radius: 4px; 
    1628      } 
    1629      #themes .theme-details-js label { 
    1630           cursor: pointer; 
    1631           } 
    1632      #themes .theme-details-js.theme-selected { 
    1633           background: #e7e7e7; 
    1634           border: 1px solid #999; 
    1635           } 
    1636      #themes .theme-details-js .theme-shot img { 
    1637           width: 120px; 
    1638           height: 105px; 
    1639           border: 1px solid #fff; 
    1640           } 
    1641      #themes a:focus div, #themes a:hover div, 
    1642      #themes a:focus div.current-theme, #themes a:hover div.current-theme { 
    1643           background: #bee74b; 
    1644           } 
     1571} 
    16451572/* ------------------------------------------------------------------ categories.php */ 
    16461573#categories { 
     
    19471874          } 
    19481875/* -------------------------------------------------------------------- plugins.php */ 
    1949 #plugins td.action { 
     1876.modules td.module-actions, .modules td.module-icon { 
    19501877     vertical-align: middle; 
    19511878     } 
    1952 .distrib img { 
     1879.modules td.module-icon img:last-child { 
     1880     width: 16px; 
     1881     height: 16px; 
     1882     } 
     1883.modules td.module-icon img.expand { 
     1884     margin-bottom: 3px; 
     1885     } 
     1886.modules td.module-distrib img { 
    19531887     display: block; 
    19541888     float: right; 
    1955      margin-top: -1em; 
     1889     } 
     1890.modules dt { 
     1891     font-weight: bold; 
     1892     } 
     1893.modules a.module-details { 
     1894     background: transparent url(search.png) no-repeat 2px 2px; 
     1895     padding: 4px 4px 0 20px; 
     1896     } 
     1897.modules a.module-support { 
     1898     background: transparent url(../images/page_help.png) no-repeat 2px 2px; 
     1899     padding: 4px 4px 0 20px; 
     1900     } 
     1901#m_search {     
     1902     background: transparent url(search.png) no-repeat 4px center; 
     1903     padding-left: 20px; 
     1904     } 
     1905.modules tr.expand, .modules td.expand { 
     1906     background: #f7f7f7; 
     1907     border-color: #bee74b; 
     1908     } 
     1909.modules tr.expand td:first-child { 
     1910     font-weight: bold; 
     1911     background: #DFE5E7; 
     1912     } 
     1913.modules td.expand { 
     1914     padding: 0; 
     1915     } 
     1916.mod-more, .mod-more li { 
     1917     margin: .25em 0 0 1em; 
     1918     padding: 0; 
     1919     list-style-type: none; 
     1920     } 
     1921.mod-more { 
     1922     padding-top: .5em; 
    19561923     } 
    19571924/* ---------------------------------------------------------- post.php, page.php */ 
  • inc/admin/lib.dc.page.php

    r2191 r2196  
    571571          self::jsVar('dotclear.img_menu_on','images/menu_on.png'). 
    572572          self::jsVar('dotclear.img_menu_off','images/menu_off.png'). 
     573           
     574          self::jsVar('dotclear.img_plus_theme_src','images/plus-theme.png'). 
     575          self::jsVar('dotclear.img_plus_theme_alt',__('uncover')). 
     576          self::jsVar('dotclear.img_minus_theme_src','images/minus-theme.png'). 
     577          self::jsVar('dotclear.img_minus_theme_alt',__('hide')). 
    573578 
    574579          self::jsVar('dotclear.msg.help', 
     
    654659          self::jsVar('dotclear.msg.load_enhanced_uploader', 
    655660               __('Loading enhanced uploader, please wait.')). 
     661 
     662          self::jsVar('dotclear.msg.module_author', 
     663               __('Author:')). 
     664          self::jsVar('dotclear.msg.module_details', 
     665               __('Details')). 
     666          self::jsVar('dotclear.msg.module_support', 
     667               __('Support')). 
     668          self::jsVar('dotclear.msg.module_help', 
     669               __('Help:')). 
     670          self::jsVar('dotclear.msg.module_section', 
     671               __('Section:')). 
     672          self::jsVar('dotclear.msg.module_tags', 
     673               __('Tags:')). 
    656674               "\n//]]>\n". 
    657675          "</script>\n"; 
  • inc/prepend.php

    r1999 r2147  
    4646$__autoload['dcWorkspace']              = dirname(__FILE__).'/core/class.dc.workspace.php'; 
    4747$__autoload['dcPrefs']                  = dirname(__FILE__).'/core/class.dc.prefs.php'; 
     48$__autoload['dcRepository']             = dirname(__FILE__).'/core/class.dc.repository.php'; 
     49$__autoload['dcRepositoryReader']       = dirname(__FILE__).'/core/class.dc.repository.reader.php'; 
     50$__autoload['dcRepositoryParser']       = dirname(__FILE__).'/core/class.dc.repository.parser.php'; 
    4851 
    4952$__autoload['rsExtPost']                = dirname(__FILE__).'/core/class.dc.rs.extensions.php'; 
     
    6164$__autoload['dcPager']        = dirname(__FILE__).'/admin/lib.pager.php'; 
    6265$__autoload['dcAdminCombos']            = dirname(__FILE__).'/admin/lib.admincombos.php'; 
     66$__autoload['adminModulesList']              = dirname(__FILE__).'/admin/lib.moduleslist.php'; 
     67$__autoload['adminThemesList']               = dirname(__FILE__).'/admin/lib.moduleslist.php'; 
    6368 
    6469$__autoload['dcTemplate']               = dirname(__FILE__).'/public/class.dc.template.php'; 
  • plugins/maintenance/_admin.php

    r2177 r2196  
    2929$core->addBehavior('adminAfterDashboardOptionsUpdate', array('dcMaintenanceAdmin',   'adminAfterDashboardOptionsUpdate')); 
    3030$core->addBehavior('adminPageHelpBlock',     array('dcMaintenanceAdmin',   'adminPageHelpBlock')); 
     31$core->addBehavior('pluginsToolsHeaders',    array('dcMaintenanceAdmin',   'pluginsToolsHeaders')); 
    3132 
    3233/** 
     
    223224          $core->auth->user_prefs->maintenance->put('dashboard_item', !empty($_POST['maintenance_dashboard_item']), 'boolean'); 
    224225     } 
    225  
    226226 
    227227     /** 
     
    294294          } 
    295295     } 
     296 
     297     /** 
     298      * Add javascript for plugin configuration. 
     299      * 
     300      * @param $core     <b>dcCore</b>  dcCore instance 
     301      * @param $module   <b>mixed</b>   Module ID or false if none 
     302      * @return     <b>string</b>  Header code for js inclusion 
     303      */ 
     304     public static function pluginsToolsHeaders($core, $module) 
     305     { 
     306          if ($module == 'maintenance') { 
     307               return dcPage::jsLoad('index.php?pf=maintenance/js/settings.js'); 
     308          } 
     309     } 
    296310} 
  • plugins/maintenance/index.php

    r2166 r2175  
    2727$code = empty($_POST['code']) ? null : (integer) $_POST['code']; 
    2828$tab = empty($_REQUEST['tab']) ? '' : $_REQUEST['tab']; 
    29  
    30 // Save settings 
    31  
    32 if (!empty($_POST['settings'])) { 
    33  
    34      try { 
    35           $core->blog->settings->maintenance->put( 
    36                'plugin_message',  
    37                !empty($_POST['settings_plugin_message']),  
    38                'boolean',  
    39                'Display alert message of late tasks on plugin page',  
    40                true,  
    41                true 
    42           ); 
    43  
    44           foreach($tasks as $t) { 
    45                if (!empty($_POST['settings_recall_type']) && $_POST['settings_recall_type'] == 'all') { 
    46                     $ts = $_POST['settings_recall_time']; 
    47                } 
    48                else { 
    49                     $ts = empty($_POST['settings_ts_'.$t->id()]) ? 0 : $_POST['settings_ts_'.$t->id()]; 
    50                } 
    51                $core->blog->settings->maintenance->put( 
    52                     'ts_'.$t->id(),  
    53                     abs((integer) $ts),  
    54                     'integer',  
    55                     sprintf('Recall time for task %s', $t->id()),  
    56                     true,  
    57                     $t->blog() 
    58                ); 
    59           } 
    60            
    61           http::redirect($p_url.'&done=1&tab='.$tab.'#'.$tab); 
    62      } 
    63      catch(Exception $e) { 
    64           $core->error->add($e->getMessage()); 
    65      } 
    66 } 
    6729 
    6830// Get task object 
     
    287249          '</div>'; 
    288250     } 
    289  
    290      // Settings 
    291  
    292      echo  
    293      '<div id="settings" class="multi-part" title="'.__('Alert settings').'">'. 
    294      '<h3>'.__('Alert settings').'</h3>'. 
    295      '<form action="'.$p_url.'" method="post">'. 
    296  
    297      '<h4 class="pretty-title">'.__('Activation').'</h4>'. 
    298      '<p><label for="settings_plugin_message" class="classic">'. 
    299      form::checkbox('settings_plugin_message', 1, $core->blog->settings->maintenance->plugin_message). 
    300      __('Display alert messages on late tasks').'</label></p>'. 
    301  
    302      '<p class="info">'.sprintf( 
    303           __('You can place list of late tasks on your %s.'), 
    304           '<a href="preferences.php#user-favorites">'.__('Dashboard').'</a>' 
    305      ).'</p>'. 
    306  
    307      '<h4 class="pretty-title vertical-separator">'.__('Frequency').'</h4>'. 
    308  
    309      '<p class="vertical-separator">'.form::radio(array('settings_recall_type', 'settings_recall_all'), 'all').' '. 
    310      '<label class="classic" for="settings_recall_all">'. 
    311      '<strong>'.__('Use one recall time for all tasks').'</strong></label>'. 
    312  
    313      '<p class="field wide vertical-separator"><label for="settings_recall_time">'.__('Recall time for all tasks:').'</label>'. 
    314      form::combo('settings_recall_time', $combo_ts, 'seperate', 'recall-for-all'). 
    315      '</p>'. 
    316  
    317      '<p class="vertical-separator">'.form::radio(array('settings_recall_type', 'settings_recall_separate'), 'separate', 1).' '. 
    318      '<label class="classic" for="settings_recall_separate">'. 
    319      '<strong>'.__('Use one recall time per task').'</strong></label>'; 
    320  
    321      foreach($tasks as $t) 
    322      { 
    323           echo 
    324           '<div class="two-boxes">'. 
    325  
    326           '<p class="field wide"><label for="settings_ts_'.$t->id().'">'.$t->task().'</label>'. 
    327           form::combo('settings_ts_'.$t->id(), $combo_ts, $t->ts(), 'recall-per-task'). 
    328           '</p>'. 
    329  
    330           '</div>'; 
    331      } 
    332  
    333      echo  
    334      '<p class="field wide"><input type="submit" value="'.__('Save this settings').'" /> '. 
    335      form::hidden(array('tab'), 'settings'). 
    336      form::hidden(array('settings'), 1). 
    337      $core->formNonce().'</p>'. 
    338      '</form>'. 
    339      '</div>'; 
    340251} 
    341252 
Note: See TracChangeset for help on using the changeset viewer.

Sites map