Changeset 2171:bb80994ddeed
- Timestamp:
- 09/30/13 18:03:03 (12 years ago)
- Branch:
- dcRepo
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
admin/blog_theme.php
r1553 r2171 15 15 dcPage::check('admin'); 16 16 17 # Loading themes 17 # -------------------------------------------------- 18 # @todo Add settings to Dotclear update features 19 if ($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 -- 18 27 $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 -- 22 45 if (!empty($_GET['shot']) && $core->themes->moduleExists($_GET['shot'])) 23 46 { … … 43 66 } 44 67 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 http::redirect('blog_theme.php?upd=1'); 56 } 57 58 if ($can_install && !empty($_POST['theme']) && !empty($_POST['remove']) && empty($_REQUEST['conf'])) 59 { 60 try 61 { 62 if ($_POST['theme'] == 'default') { 63 throw new Exception(__('You can\'t remove default theme.')); 64 } 65 66 if (!$core->themes->moduleExists($_POST['theme'])) { 67 throw new Exception(__('Theme does not exist.')); 68 } 69 70 $theme = $core->themes->getModules($_POST['theme']); 71 72 # --BEHAVIOR-- themeBeforeDelete 73 $core->callBehavior('themeBeforeDelete',$theme); 74 75 $core->themes->deleteModule($_POST['theme']); 76 77 # --BEHAVIOR-- themeAfterDelete 78 $core->callBehavior('themeAfterDelete',$theme); 79 80 http::redirect('blog_theme.php?del=1'); 81 } 82 catch (Exception $e) 83 { 68 # -- Check for module configuration -- 69 $conf_file = false; 70 if (!empty($_REQUEST['conf']) && !empty($_REQUEST['module'])) { 71 if (!$core->themes->moduleExists($_REQUEST['module'])) { 72 $core->error->add(__('Unknow module ID')); 73 } 74 else { 75 $module = $core->themes->getModules($_REQUEST['module']); 76 $module = adminModulesList::setModuleInfo($_REQUEST['module'], $module); 77 78 if (!file_exists(path::real($module['root'].'/_config.php'))) { 79 $core->error->add(__('This module has no configuration file.')); 80 } 81 else { 82 $conf_file = path::real($module['root'].'/_config.php'); 83 } 84 } 85 } 86 87 # -- Display module configuration page -- 88 if ($conf_file) { 89 dcPage::open(__('Blog appearance'), 90 91 # --BEHAVIOR-- themesToolsHeaders 92 $core->callBehavior('themesToolsHeaders', $core, $module['id']), 93 94 dcPage::breadcrumb( 95 array( 96 html::escapeHTML($core->blog->name) => '', 97 __('Blog appearance') => 'blog_theme.php', 98 '<span class="page-title">'.__('Theme configuration').'</span>' => '' 99 )) 100 ); 101 102 if (!empty($_GET['done'])){ 103 dcPage::success(__('Theme successfully configured.')); 104 } 105 106 try { 107 if (!$module['standalone_config']) { 108 echo 109 '<form id="module_config" action="'.$list->getPageURL('conf=1').'" method="post" enctype="multipart/form-data">'. 110 '<h3>'.sprintf(__('Configure theme "%s"'), html::escapeHTML($module['name'])).'</h3>'. 111 '<p><a class="back" href="'.$list->getPageURL().'#themes">'.__('Back').'</a></p>'; 112 } 113 define('DC_CONTEXT_THEME', true); 114 115 include $conf_file; 116 117 if (!$module['standalone_config']) { 118 echo 119 '<p class="clear"><input type="submit" name="save" value="'.__('Save').'" />'. 120 form::hidden('module', $module['id']). 121 $core->formNonce().'</p>'. 122 '</form>'; 123 } 124 } 125 catch (Exception $e) { 126 echo '<div class="error"><p>'.$e->getMessage().'</p></div>'; 127 } 128 129 dcPage::close(); 130 131 # Stop reading code here 132 return; 133 } 134 135 # -- Execute actions -- 136 if (!empty($_POST) && empty($_REQUEST['conf']) && $core->auth->isSuperAdmin() && $list->isPathWritable()) { 137 try { 138 $list->executeAction('themes', $core->themes, $repository); 139 } 140 catch (Exception $e) { 84 141 $core->error->add($e->getMessage()); 85 142 } 86 143 } 87 144 88 # Theme upload 89 if ($can_install && $is_writable && ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || 90 (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url'])))) 91 { 92 try 93 { 94 if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY,$_POST['your_pwd']))) { 95 throw new Exception(__('Password verification failed')); 96 } 97 98 if (!empty($_POST['upload_pkg'])) 99 { 100 files::uploadStatus($_FILES['pkg_file']); 101 102 $dest = $core->blog->themes_path.'/'.$_FILES['pkg_file']['name']; 103 if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'],$dest)) { 104 throw new Exception(__('Unable to move uploaded file.')); 105 } 106 } 107 else 108 { 109 $url = urldecode($_POST['pkg_url']); 110 $dest = $core->blog->themes_path.'/'.basename($url); 111 112 try 113 { 114 $client = netHttp::initClient($url,$path); 115 $client->setUserAgent('Dotclear - http://www.dotclear.org/'); 116 $client->useGzip(false); 117 $client->setPersistReferers(false); 118 $client->setOutput($dest); 119 $client->get($path); 120 } 121 catch( Exception $e) 122 { 123 throw new Exception(__('An error occurred while downloading the file.')); 124 } 125 126 unset($client); 127 } 128 129 $ret_code = dcModules::installPackage($dest,$core->themes); 130 http::redirect('blog_theme.php?added='.$ret_code); 131 } 132 catch (Exception $e) 133 { 134 $core->error->add($e->getMessage()); 135 $default_tab = 'add-theme'; 136 } 137 } 138 139 $theme_conf_mode = false; 140 if (!empty($_REQUEST['conf'])) 141 { 142 $theme_conf_file = path::real($core->blog->themes_path.'/'.$core->blog->settings->system->theme).'/_config.php'; 143 if (file_exists($theme_conf_file)) { 144 $theme_conf_mode = true; 145 } 146 } 147 148 function display_theme_details($id,$details,$current) 149 { 150 global $core; 151 152 $screenshot = 'images/noscreenshot.png'; 153 if (file_exists($core->blog->themes_path.'/'.$id.'/screenshot.jpg')) { 154 $screenshot = 'blog_theme.php?shot='.rawurlencode($id); 155 } 156 157 $radio_id = 'theme_'.html::escapeHTML($id); 158 if (preg_match('#^http(s)?://#',$core->blog->settings->system->themes_url)) { 159 $theme_url = http::concatURL($core->blog->settings->system->themes_url,'/'.$id); 160 } else { 161 $theme_url = http::concatURL($core->blog->url,$core->blog->settings->system->themes_url.'/'.$id); 162 } 163 $has_conf = file_exists(path::real($core->blog->themes_path.'/'.$id).'/_config.php'); 164 $has_css = file_exists(path::real($core->blog->themes_path.'/'.$id).'/style.css'); 165 $parent = $core->themes->moduleInfo($id,'parent'); 166 $has_parent = (boolean)$parent; 167 if ($has_parent) { 168 $is_parent_present = $core->themes->moduleExists($parent); 169 } 170 171 $res = 172 '<div class="theme-details'.($current ? ' current-theme' : '').'">'. 173 '<div class="theme-shot"><img src="'.$screenshot.'" alt="" /></div>'. 174 '<div class="theme-info">'. 175 '<h4>'.form::radio(array('theme',$radio_id),html::escapeHTML($id),$current,'','',($has_parent && !$is_parent_present)).' '. 176 '<label class="classic" for="'.$radio_id.'">'. 177 html::escapeHTML($details['name']).'</label></h4>'. 178 '<p><span class="theme-desc">'.html::escapeHTML($details['desc']).'</span> '. 179 '<span class="theme-author">'.sprintf(__('by %s'),html::escapeHTML($details['author'])).'</span> '. 180 '<span class="theme-version">'.sprintf(__('version %s'),html::escapeHTML($details['version'])).'</span> '; 181 if ($has_parent) { 182 if ($is_parent_present) { 183 $res .= '<span class="theme-parent-ok">'.sprintf(__('(built on "%s")'),html::escapeHTML($parent)).'</span> '; 184 } else { 185 $res .= '<span class="theme-parent-missing">'.sprintf(__('(requires "%s")'),html::escapeHTML($parent)).'</span> '; 186 } 187 } 188 if ($has_css) { 189 $res .= '<span class="theme-css"><a href="'.$theme_url.'/style.css">'.__('Stylesheet').'</a></span>'; 190 } 191 $res .= '</p>'; 192 $res .= 193 '</div>'. 194 '<div class="theme-actions">'; 195 if ($current && $has_conf) { 196 $res .= '<p><a href="blog_theme.php?conf=1" class="button">'.__('Configure theme').'</a></p>'; 197 } 198 if ($current) { 199 # --BEHAVIOR-- adminCurrentThemeDetails 200 $res .= $core->callBehavior('adminCurrentThemeDetails',$core,$id,$details); 201 } 202 $res .= 203 '</div>'. 204 '</div>'; 205 206 return $res; 207 } 208 209 if (!$theme_conf_mode) 210 { 211 $breadcrumb = dcPage::breadcrumb( 145 # -- Page header -- 146 dcPage::open(__('Themes management'), 147 // (!$conf_file ? dcPage::jsLoad('js/_blog_theme.js') : ''). 148 dcPage::jsPageTabs(). 149 dcPage::jsColorPicker(), 150 151 # --BEHAVIOR-- themesToolsHeaders 152 $core->callBehavior('themesToolsHeaders', $core, false), 153 154 dcPage::breadcrumb( 212 155 array( 213 156 html::escapeHTML($core->blog->name) => '', 214 157 '<span class="page-title">'.__('Blog appearance').'</span>' => '' 215 )); 216 } else { 217 $breadcrumb = dcPage::breadcrumb( 218 array( 219 html::escapeHTML($core->blog->name) => '', 220 __('Blog appearance') => 'blog_theme.php', 221 '<span class="page-title">'.__('Theme configuration').'</span>' => '' 222 )); 223 } 224 225 dcPage::open(__('Blog appearance'), 226 (!$theme_conf_mode ? dcPage::jsLoad('js/_blog_theme.js') : ''). 227 dcPage::jsPageTabs($default_tab). 228 dcPage::jsColorPicker(), 229 $breadcrumb 158 )) 230 159 ); 231 160 232 if (!$theme_conf_mode) 233 { 234 if (!empty($_GET['upd'])) { 235 dcPage::success(__('Theme has been successfully changed.')); 236 } 237 238 if (!empty($_GET['added'])) { 239 dcPage::success(($_GET['added'] == 2 ? __('Theme has been successfully upgraded') : __('Theme has been successfully installed.'))); 240 } 241 242 if (!empty($_GET['del'])) { 243 dcPage::success(__('Theme has been successfully deleted.')); 244 } 245 246 # Themes list 247 echo '<div class="multi-part" id="themes-list" title="'.__('Themes').'">'. 248 '<h3>'.__('Available themes in your installation').'</h3>'; 249 250 $themes = $core->themes->getModules(); 251 if (isset($themes[$core->blog->settings->system->theme])) { 252 echo '<p>'.sprintf(__('You are currently using <strong>%s</strong>'),$themes[$core->blog->settings->system->theme]['name']).'.</p>'; 253 } 254 255 echo 256 '<form action="blog_theme.php" method="post" id="themes-form">'. 257 '<div id="themes">'; 258 259 if (isset($themes[$core->blog->settings->system->theme])) { 260 echo display_theme_details($core->blog->settings->system->theme,$themes[$core->blog->settings->system->theme],true); 261 } 262 263 foreach ($themes as $k => $v) 264 { 265 if ($core->blog->settings->system->theme == $k) { // Current theme 266 continue; 267 } 268 echo display_theme_details($k,$v,false); 269 } 270 271 echo '</div>'; 272 273 echo 274 '<div id="themes-actions">'. 275 276 '<p>'.$core->formNonce().'<input type="submit" name="select" value="'.__('Use selected theme').'" /> '; 277 if ($can_install) { 278 echo ' <input type="submit" class="delete" name="remove" value="'.__('Delete selected theme').'" />'; 279 } 280 echo '</p>'. 281 282 '</div>'. 283 '</form>'. 161 # -- Succes messages -- 162 if (!empty($_GET['msg'])) { 163 $list->displayMessage($_GET['msg']); 164 } 165 166 # -- Display modules lists -- 167 if ($core->auth->isSuperAdmin() && $list->isPathWritable()) { 168 169 # Updated modules from repo 170 $modules = $repository->get(true); 171 if (!empty($modules)) { 172 echo 173 '<div class="multi-part" id="update" title="'.html::escapeHTML(__('Update themes')).'">'. 174 '<h3>'.html::escapeHTML(__('Update themes')).'</h3>'. 175 '<p>'.sprintf( 176 __('There is one theme to update available from %2$s.', 'There are %s themes to update available from %s.', count($modules)), 177 count($modules), 178 '<a href="http://dotaddict.org/dc2/themes">Dotaddict</a>' 179 ).'</p>'; 180 181 $list 182 ->newList('theme-update') 183 ->setModules($modules) 184 ->setPageTab('update') 185 ->displayModulesList( 186 /*cols */ array('sshot', 'name', 'desc', 'author', 'version', 'current_version', 'parent'), 187 /* actions */ array('update') 188 ); 189 190 echo 191 '</div>'; 192 } 193 } 194 195 # List all active plugins 196 echo 197 '<div class="multi-part" id="themes" title="'.__('Installed themes').'">'; 198 199 $modules = $core->themes->getModules(); 200 if (!empty($modules)) { 201 202 echo 203 '<h3>'.__('Activated themes').'</h3>'. 204 '<p>'.__('Manage installed themes from this list.').'</p>'; 205 206 $list 207 ->newList('theme-activate') 208 ->setModules($modules) 209 ->setPageTab('themes') 210 ->displayModulesList( 211 /* cols */ array('sshot', 'name', 'config', 'desc', 'author', 'version', 'parent'), 212 /* actions */ array('deactivate', 'delete') 213 ); 214 } 215 216 echo 217 '</div>'; 218 219 if ($core->auth->isSuperAdmin() && $list->isPathWritable()) { 220 221 # New modules from repo 222 $search = $list->getSearchQuery(); 223 $modules = $search ? $repository->search($search) : $repository->get(); 224 225 echo 226 '<div class="multi-part" id="new" title="'.__('Add themes from Dotaddict').'">'. 227 '<h3>'.__('Add themes from Dotaddict repository').'</h3>'; 228 229 $list 230 ->newList('theme-new') 231 ->setModules($modules) 232 ->setPageTab('new') 233 ->displaySearchForm() 234 ->displayNavMenu() 235 ->displayModulesList( 236 /* cols */ array('expander', 'sshot', 'name', 'config', 'desc', 'author', 'version', 'parent'), 237 /* actions */ array('install'), 238 /* nav limit */ true 239 ); 240 241 echo 242 '<p class="info vertical-separator">'.sprintf( 243 __("Visit %s repository, the resources center for Dotclear."), 244 '<a href="http://dotaddict.org/dc2/themes">Dotaddict</a>' 245 ). 246 '</p>'. 247 284 248 '</div>'; 285 286 # Add a new theme 287 if ($can_install) 288 { 289 echo 290 '<div class="multi-part clear" id="add-theme" title="'.__('Install or upgrade a theme').'">'. 291 '<h3>'.__('Add themes to your installation').'</h3>'. 292 '<p class="form-note info">'.sprintf(__('You can find additional themes for your blog on %s.'), 293 '<a href="http://themes.dotaddict.org/galerie-dc2/">Dotaddict</a>').'</p>'; 294 295 if ($is_writable) 296 { 297 echo '<p>'.__('You can also install themes by uploading or downloading zip files.').'</p>'; 298 299 # 'Upload theme' form 300 echo 301 '<form method="post" action="blog_theme.php" id="uploadpkg" enctype="multipart/form-data" class="fieldset">'. 302 '<h4>'.__('Upload a zip file').'</h4>'. 303 '<p class="field"><label for="pkg_file" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Theme zip file:').'</label> '. 304 '<input type="file" name="pkg_file" id="pkg_file" /></p>'. 305 '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 306 form::password(array('your_pwd','your_pwd1'),20,255).'</p>'. 307 '<p><input type="submit" name="upload_pkg" value="'.__('Upload theme').'" />'. 308 $core->formNonce().'</p>'. 309 '</form>'; 310 311 # 'Fetch theme' form 312 echo 313 '<form method="post" action="blog_theme.php" id="fetchpkg" class="fieldset">'. 314 '<h4>'.__('Download a zip file').'</h4>'. 315 '<p class="field"><label for="pkg_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Theme zip file URL:').'</label> '. 316 form::field(array('pkg_url','pkg_url'),40,255).'</p>'. 317 '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 318 form::password(array('your_pwd','your_pwd2'),20,255).'</p>'. 319 '<p><input type="submit" name="fetch_pkg" value="'.__('Download theme').'" />'. 320 $core->formNonce().'</p>'. 321 '</form>'; 322 } 323 else 324 { 325 echo 326 '<p class="static-msg">'. 327 __('To enable this function, please give write access to your themes directory.'). 328 '</p>'; 329 } 330 echo '</div>'; 331 } 332 } 333 else 334 { 335 $theme_name = $core->themes->moduleInfo($core->blog->settings->system->theme,'name'); 336 $core->themes->loadModuleL10Nresources($core->blog->settings->system->theme,$_lang); 337 338 echo 339 '<p><a class="back" href="blog_theme.php">'.__('Back to Blog appearance').'</a></p>'; 340 341 try 342 { 343 # Let theme configuration set their own form(s) if required 344 $standalone_config = (boolean) $core->themes->moduleInfo($core->blog->settings->system->theme,'standalone_config'); 345 346 if (!$standalone_config) 347 echo '<form id="theme_config" action="blog_theme.php?conf=1" method="post" enctype="multipart/form-data">'; 348 349 include $theme_conf_file; 350 351 if (!$standalone_config) 352 echo 353 '<p class="clear"><input type="submit" value="'.__('Save').'" />'. 354 $core->formNonce().'</p>'. 355 '</form>'; 356 357 } 358 catch (Exception $e) 359 { 360 echo '<div class="error"><p>'.$e->getMessage().'</p></div>'; 361 } 249 250 # Add a new plugin 251 echo 252 '<div class="multi-part" id="addtheme" title="'.__('Install or upgrade manually').'">'; 253 254 echo '<p>'.__('You can install themes by uploading or downloading zip files.').'</p>'; 255 256 $list->displayManualForm(); 257 258 echo 259 '</div>'; 362 260 } 363 261 -
admin/js/_plugins.js
r2157 r2171 82 82 83 83 if (author) { 84 $(dl).append($('<li >'+dotclear.msg.module_author+' '+author+'</li>'));84 $(dl).append($('<li class="module-author">'+dotclear.msg.module_author+' '+author+'</li>')); 85 85 } 86 86 if (details) { 87 87 var dd = ''; 88 dd += '<a class=" details" href="'+details+'">'+dotclear.msg.module_details+'</a>';88 dd += '<a class="module-details" href="'+details+'">'+dotclear.msg.module_details+'</a>'; 89 89 if (support) { 90 90 dd += ' - '; 91 dd += '<a class=" support" href="'+support+'">'+dotclear.msg.module_support+'</a>';91 dd += '<a class="module-support" href="'+support+'">'+dotclear.msg.module_support+'</a>'; 92 92 } 93 93 $(dl).append($('<li>'+dotclear.msg.module_help+' '+dd+'</li>')); … … 104 104 105 105 if (section) { 106 $(dlb).append($('<li >'+dotclear.msg.module_section+' '+section+'</li>'));106 $(dlb).append($('<li class="module-section">'+dotclear.msg.module_section+' '+section+'</li>')); 107 107 } 108 108 if (tags) { 109 $(dlb).append($('<li >'+dotclear.msg.module_tags+' '+tags+'</li>'));109 $(dlb).append($('<li class="module-tags">'+dotclear.msg.module_tags+' '+tags+'</li>')); 110 110 } 111 111 $(td).append($(boxb).addClass('two-boxes').append(dlb)); -
admin/plugins.php
r2165 r2171 43 43 ); 44 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 )); 45 64 46 65 # -- Check for module configuration -- … … 112 131 113 132 # -- Execute actions -- 114 if (empty($_POST['conf']) && $core->auth->isSuperAdmin() && $list->isPathWritable()) { 115 116 # Plugin upload 117 if ((!empty($_POST['upload_pkg']) && !empty($_FILES['pkg_file'])) || 118 (!empty($_POST['fetch_pkg']) && !empty($_POST['pkg_url']))) 119 { 120 try 121 { 122 if (empty($_POST['your_pwd']) || !$core->auth->checkPassword(crypt::hmac(DC_MASTER_KEY, $_POST['your_pwd']))) { 123 throw new Exception(__('Password verification failed')); 124 } 125 126 if (!empty($_POST['upload_pkg'])) { 127 files::uploadStatus($_FILES['pkg_file']); 128 129 $dest = $list->getPath().'/'.$_FILES['pkg_file']['name']; 130 if (!move_uploaded_file($_FILES['pkg_file']['tmp_name'], $dest)) { 131 throw new Exception(__('Unable to move uploaded file.')); 132 } 133 } 134 else { 135 $url = urldecode($_POST['pkg_url']); 136 $dest = $list->getPath().'/'.basename($url); 137 $repository->download($url, $dest); 138 } 139 140 # --BEHAVIOR-- pluginBeforeAdd 141 $core->callBehavior('pluginsBeforeAdd', $plugin_id); 142 143 $ret_code = $core->plugins->installPackage($dest, $core->plugins); 144 145 # --BEHAVIOR-- pluginAfterAdd 146 $core->callBehavior('pluginsAfterAdd', $plugin_id); 147 148 http::redirect('plugins.php?msg='.($ret_code == 2 ? 'update' : 'install').'#plugins'); 149 } 150 catch (Exception $e) { 151 $core->error->add($e->getMessage()); 152 } 153 } 154 elseif (!empty($_POST['module'])) { 155 try { 156 $list->executeAction('plugins', $core->plugins, $repository); 157 } 158 catch (Exception $e) { 159 $core->error->add($e->getMessage()); 160 } 133 if (!empty($_POST) && empty($_REQUEST['conf']) && $core->auth->isSuperAdmin() && $list->isPathWritable()) { 134 try { 135 $list->executeAction('plugins', $core->plugins, $repository); 136 } 137 catch (Exception $e) { 138 $core->error->add($e->getMessage()); 161 139 } 162 140 } … … 185 163 # -- Succes messages -- 186 164 if (!empty($_GET['msg'])) { 187 $list->displayMessage($_GET['msg'] ,__('Plugins'));165 $list->displayMessage($_GET['msg']); 188 166 } 189 167 … … 318 296 echo '<p>'.__('You can install plugins by uploading or downloading zip files.').'</p>'; 319 297 320 # 'Upload plugin' form 321 echo 322 '<form method="post" action="plugins.php" id="uploadpkg" enctype="multipart/form-data" class="fieldset">'. 323 '<h4>'.__('Upload a zip file').'</h4>'. 324 '<p class="field"><label for="pkg_file" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Plugin zip file:').'</label> '. 325 '<input type="file" id="pkg_file" name="pkg_file" /></p>'. 326 '<p class="field"><label for="your_pwd1" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 327 form::password(array('your_pwd','your_pwd1'),20,255).'</p>'. 328 '<p><input type="submit" name="upload_pkg" value="'.__('Upload plugin').'" />'. 329 $core->formNonce(). 330 '</p>'. 331 '</form>'; 332 333 # 'Fetch plugin' form 334 echo 335 '<form method="post" action="plugins.php" id="fetchpkg" class="fieldset">'. 336 '<h4>'.__('Download a zip file').'</h4>'. 337 '<p class="field"><label for="pkg_url" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Plugin zip file URL:').'</label> '. 338 form::field(array('pkg_url','pkg_url'),40,255).'</p>'. 339 '<p class="field"><label for="your_pwd2" class="classic required"><abbr title="'.__('Required field').'">*</abbr> '.__('Your password:').'</label> '. 340 form::password(array('your_pwd','your_pwd2'),20,255).'</p>'. 341 '<p><input type="submit" name="fetch_pkg" value="'.__('Download plugin').'" />'. 342 $core->formNonce().'</p>'. 343 '</form>'; 298 $list->displayManualForm(); 344 299 345 300 echo -
admin/style/default.css
r2164 r2171 1532 1532 } 1533 1533 /* ------------------------------------------------------------------- blog_theme.php */ 1534 /* 1534 1535 #themes { 1535 1536 margin: 0; … … 1568 1569 margin-bottom: 3em; 1569 1570 } 1571 */ 1570 1572 /* Themes list, JS version */ 1573 /* 1571 1574 #themes-wrapper { 1572 1575 display: table; … … 1643 1646 background: #bee74b; 1644 1647 } 1648 */ 1645 1649 /* ------------------------------------------------------------------ categories.php */ 1646 1650 #categories { … … 1947 1951 } 1948 1952 /* -------------------------------------------------------------------- plugins.php */ 1949 .modules td. action, .modules td.icon {1953 .modules td.module-actions, .modules td.module-icon { 1950 1954 vertical-align: middle; 1951 1955 } 1952 .modules td. icon img:last-child {1956 .modules td.module-icon img:last-child { 1953 1957 width: 16px; 1954 1958 height: 16px; 1955 1959 } 1956 .modules td. icon img.expand {1960 .modules td.module-icon img.expand { 1957 1961 margin-bottom: 3px; 1958 1962 } 1959 .modules td. distrib img {1963 .modules td.module-distrib img { 1960 1964 display: block; 1961 1965 float: right; … … 1964 1968 font-weight: bold; 1965 1969 } 1966 .modules a. details {1970 .modules a.module-details { 1967 1971 background: transparent url(search.png) no-repeat 2px 2px; 1968 1972 padding: 4px 4px 0 20px; 1969 1973 } 1970 .modules a. support {1974 .modules a.module-support { 1971 1975 background: transparent url(../images/page_help.png) no-repeat 2px 2px; 1972 1976 padding: 4px 4px 0 20px; -
inc/admin/lib.moduleslist.php
r2163 r2171 7 7 8 8 public static $allow_multi_install; 9 public static $distributed_modules = array(); 9 10 10 11 protected $list_id = 'unknow'; … … 275 276 'section' => '', 276 277 'tags' => '', 277 'details' => '' 278 'details' => '', 279 'sshot' => '' 278 280 ), 279 281 # Module's values … … 290 292 } 291 293 294 public static function setDistributedModules($modules) 295 { 296 self::$distributed_modules = $modules; 297 } 298 292 299 public static function isDistributedModule($module) 293 300 { 294 return in_array($module, array( 295 'aboutConfig', 296 'akismet', 297 'antispam', 298 'attachments', 299 'blogroll', 300 'blowupConfig', 301 'daInstaller', 302 'fairTrackbacks', 303 'importExport', 304 'maintenance', 305 'pages', 306 'pings', 307 'simpleMenu', 308 'tags', 309 'themeEditor', 310 'userPref', 311 'widgets' 312 )); 301 $distributed_modules = self::$distributed_modules; 302 303 return is_array($distributed_modules) && in_array($module, $distributed_modules); 313 304 } 314 305 … … 385 376 386 377 echo 387 '<tr class="line" id="'.html::escapeHTML($this->list_id).'_m_'.html::escapeHTML($id).'" title="'. 388 sprintf(__('Configure module "%"'), html::escapeHTML($module['name'])).'">'; 378 '<tr class="line" id="'.html::escapeHTML($this->list_id).'_m_'.html::escapeHTML($id).'">'; 389 379 390 380 if (in_array('icon', $cols)) { 391 381 echo 392 '<td class=" nowrap icon">'.sprintf(382 '<td class="module-icon nowrap">'.sprintf( 393 383 '<img alt="%1$s" title="%1$s" src="%2$s" />', 394 384 html::escapeHTML($id), file_exists($module['root'].'/icon.png') ? 'index.php?pf='.$id.'/icon.png' : 'images/module.png' … … 400 390 401 391 echo 402 '<td class=" nowrap" scope="row">'.($config ?403 '<a href="'.$this->getPageURL('module='.$id.'&conf=1').'" >'.html::escapeHTML($module['name']).'</a>' :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>' : 404 394 html::escapeHTML($module['name']) 405 395 ).'</td>'; … … 407 397 if (in_array('version', $cols)) { 408 398 echo 409 '<td class=" nowrap count">'.html::escapeHTML($module['version']).'</td>';399 '<td class="module-version nowrap count">'.html::escapeHTML($module['version']).'</td>'; 410 400 } 411 401 412 402 if (in_array('current_version', $cols)) { 413 403 echo 414 '<td class=" nowrap count">'.html::escapeHTML($module['current_version']).'</td>';404 '<td class="module-current-version nowrap count">'.html::escapeHTML($module['current_version']).'</td>'; 415 405 } 416 406 417 407 if (in_array('desc', $cols)) { 418 408 echo 419 '<td class="m aximal">'.html::escapeHTML($module['desc']).'</td>';409 '<td class="module-desc maximal">'.html::escapeHTML($module['desc']).'</td>'; 420 410 } 421 411 422 412 if (in_array('distrib', $cols)) { 423 413 echo 424 '<td class=" distrib">'.(self::isDistributedModule($id) ?414 '<td class="module-distrib">'.(self::isDistributedModule($id) ? 425 415 '<img src="images/dotclear_pw.png" alt="'. 426 416 __('Module from official distribution').'" title="'. … … 431 421 if (!empty($actions) && $this->core->auth->isSuperAdmin()) { 432 422 echo 433 '<td class=" nowrap">';423 '<td class="module-actions nowrap">'; 434 424 435 425 $this->displayLineActions($id, $module, $actions); … … 453 443 } 454 444 455 protected function displayLineActions($id, $module, $actions )445 protected function displayLineActions($id, $module, $actions, $echo=true) 456 446 { 457 447 $submits = array(); … … 484 474 # Parse form 485 475 if (!empty($submits)) { 486 echo476 $res = 487 477 '<form action="'.$this->getPageURL().'" method="post">'. 488 478 '<div>'. … … 493 483 '</div>'. 494 484 '</form>'; 485 486 if (!$echo) { 487 return $res; 488 } 489 echo $res; 495 490 } 496 491 } … … 498 493 public function executeAction($prefix, dcModules $modules, dcRepository $repository) 499 494 { 500 if ( empty($_POST['module']) ||!$this->core->auth->isSuperAdmin() || !$this->isPathWritable()) {495 if (!$this->core->auth->isSuperAdmin() || !$this->isPathWritable()) { 501 496 return null; 502 497 } 503 498 504 $id = $_POST['module']; 505 506 if (!empty($_POST['activate'])) { 507 508 $enabled = $modules->getDisabledModules(); 509 if (!isset($enabled[$id])) { 510 throw new Exception(__('No such module.')); 511 } 512 513 # --BEHAVIOR-- moduleBeforeActivate 514 $this->core->callBehavior($type.'BeforeActivate', $id); 515 516 $modules->activateModule($id); 517 518 # --BEHAVIOR-- moduleAfterActivate 519 $this->core->callBehavior($type.'AfterActivate', $id); 520 521 http::redirect($this->getPageURL('msg=activate')); 522 } 523 524 if (!empty($_POST['deactivate'])) { 525 526 if (!$modules->moduleExists($id)) { 527 throw new Exception(__('No such module.')); 528 } 529 530 $module = $modules->getModules($id); 531 $module['id'] = $id; 532 533 if (!$module['root_writable']) { 534 throw new Exception(__('You don\'t have permissions to deactivate this module.')); 535 } 536 537 # --BEHAVIOR-- moduleBeforeDeactivate 538 $this->core->callBehavior($prefix.'BeforeDeactivate', $module); 539 540 $modules->deactivateModule($id); 541 542 # --BEHAVIOR-- moduleAfterDeactivate 543 $this->core->callBehavior($prefix.'AfterDeactivate', $module); 544 545 http::redirect($this->getPageURL('msg=deactivate')); 546 } 547 548 if (!empty($_POST['delete'])) { 549 550 $disabled = $modules->getDisabledModules(); 551 if (!isset($disabled[$id])) { 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'])) { 552 523 553 524 if (!$modules->moduleExists($id)) { … … 558 529 $module['id'] = $id; 559 530 560 if (!$this->isPathDeletable($module['root'])) { 561 throw new Exception(__("You don't have permissions to delete this module.")); 562 } 563 564 # --BEHAVIOR-- moduleBeforeDelete 565 $this->core->callBehavior($prefix.'BeforeDelete', $module); 566 567 $modules->deleteModule($id); 568 569 # --BEHAVIOR-- moduleAfterDelete 570 $this->core->callBehavior($prefix.'AfterDelete', $module); 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 } 571 650 } 572 651 else { 573 $modules->deleteModule($id, true); 574 } 575 576 http::redirect($this->getPageURL('msg=delete')); 577 } 578 579 if (!empty($_POST['update'])) { 580 581 $updated = $repository->get(); 582 if (!isset($updated[$id])) { 583 throw new Exception(__('No such module.')); 584 } 585 586 if (!$modules->moduleExists($id)) { 587 throw new Exception(__('No such module.')); 588 } 589 590 $module = $updated[$id]; 591 $module['id'] = $id; 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>'; 592 688 593 if (!self::$allow_multi_install) { 594 $dest = $module['root'].'/../'.basename($module['file']); 595 } 596 else { 597 $dest = $this->getPath().'/'.basename($module['file']); 598 if ($module['root'] != $dest) { 599 @file_put_contents($module['root'].'/_disabled', ''); 600 } 601 } 602 603 # --BEHAVIOR-- moduleBeforeUpdate 604 $this->core->callBehavior($type.'BeforeUpdate', $module); 605 606 $repository->process($module['file'], $dest); 607 608 # --BEHAVIOR-- moduleAfterUpdate 609 $this->core->callBehavior($type.'AfterUpdate', $module); 610 611 http::redirect($this->getPageURL('msg=upadte')); 612 } 613 614 if (!empty($_POST['install'])) { 615 616 $updated = $repository->get(); 617 if (!isset($updated[$id])) { 618 throw new Exception(__('No such module.')); 619 } 620 621 $module = $updated[$id]; 622 $module['id'] = $id; 623 624 $dest = $this->getPath().'/'.basename($module['file']); 625 626 # --BEHAVIOR-- moduleBeforeAdd 627 $this->core->callBehavior($type.'BeforeAdd', $module); 628 629 $ret_code = $repository->process($module['file'], $dest); 630 631 # --BEHAVIOR-- moduleAfterAdd 632 $this->core->callBehavior($type.'AfterAdd', $module); 633 634 http::redirect($this->getPageURL('msg='.($ret_code == 2 ? 'update' : 'install'))); 635 } 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>'; 636 701 } 637 702 … … 644 709 class adminThemesList extends adminModulesList 645 710 { 646 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 } 647 866 }
Note: See TracChangeset
for help on using the changeset viewer.