diff --git a/CHANGELOG.md b/CHANGELOG.md index b73b743..1bba8ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,11 @@ 0.8.1 - dev - [ ] orphan media cleaner +- fix permissions - move actions to independent tools - add var folder - update admin page to a lighter interface +- update translation (and remove .lang.php file) +- update to PSR12 0.8 - 2021.09.07 - update DC official values (themes,settings,tables...) diff --git a/_admin.php b/_admin.php index cfc8b34..4428711 100644 --- a/_admin.php +++ b/_admin.php @@ -1,16 +1,15 @@ addItem( $core->adminurl->get('admin.plugin.dcAdvancedCleaner'), dcPage::getPF('dcAdvancedCleaner/icon.png'), preg_match( - '/' . preg_quote($core->adminurl->get('admin.plugin.dcAdvancedCleaner')) . '(&.*)?$/', + '/' . preg_quote($core->adminurl->get('admin.plugin.dcAdvancedCleaner')) . '(&.*)?$/', $_SERVER['REQUEST_URI'] ), $core->auth->isSuperAdmin() -); \ No newline at end of file +); diff --git a/_config.php b/_config.php index 3f20ca4..e013ee4 100644 --- a/_config.php +++ b/_config.php @@ -1,16 +1,15 @@ blog->settings->dcAdvancedCleaner->put( - 'dcAdvancedCleaner_behavior_active', - !empty($_POST['behavior_active']), + 'dcAdvancedCleaner_behavior_active', + !empty($_POST['behavior_active']), 'boolean', null, true, @@ -36,8 +35,8 @@ if (!empty($_POST['save'])) { 'dcAdvancedCleaner_dcproperty_hide' ); $core->blog->settings->dcAdvancedCleaner->put( - 'dcAdvancedCleaner_dcproperty_hide', - !empty($_POST['dcproperty_hide']), + 'dcAdvancedCleaner_dcproperty_hide', + !empty($_POST['dcproperty_hide']), 'boolean', null, true, @@ -47,31 +46,30 @@ if (!empty($_POST['save'])) { __('Configuration successfully updated.') ); $core->adminurl->redirect( - 'admin.plugins', + 'admin.plugins', [ - 'module' => 'dcAdvancedCleaner', - 'conf' => 1, - 'redir' => empty($_REQUEST['redir']) ? $list->getURL() . '#plugins' : $_REQUEST['redir'] + 'module' => 'dcAdvancedCleaner', + 'conf' => 1, + 'redir' => empty($_REQUEST['redir']) ? $list->getURL() . '#plugins' : $_REQUEST['redir'] ] ); - } - catch(Exception $e) { + } catch (Exception $e) { $core->error->add($e->getMessage()); } } echo '
' . __('Enable actions set in _uninstall.php files.') . '
-' . -__('Prevent from deleting Dotclear important properties.') . '
'; \ No newline at end of file +' . +__('Prevent from deleting Dotclear important properties.') . '
'; diff --git a/_define.php b/_define.php index 6732f9a..30804dc 100644 --- a/_define.php +++ b/_define.php @@ -1,16 +1,15 @@ registerModule( 'Jean-Christian Denis and Contributors', '0.8.1', [ - 'requires' => [['core', '2.19']], + 'requires' => [['core', '2.19']], 'permissions' => null, - 'type' => 'plugin', - 'support' => 'https://github.com/JcDenis/dcAdvancedCleaner', - 'details' => 'https://plugins.dotaddict.org/dc2/details/dcAdvancedCleaner', - 'repository' => 'https://raw.githubusercontent.com/JcDenis/dcAdvancedCleaner/master/dcstore.xml' + 'type' => 'plugin', + 'support' => 'https://github.com/JcDenis/dcAdvancedCleaner', + 'details' => 'https://plugins.dotaddict.org/dc2/details/dcAdvancedCleaner', + 'repository' => 'https://raw.githubusercontent.com/JcDenis/dcAdvancedCleaner/master/dcstore.xml' ] -); \ No newline at end of file +); diff --git a/_install.php b/_install.php index eb79510..f5db60a 100644 --- a/_install.php +++ b/_install.php @@ -1,16 +1,15 @@ error->add($e->getMessage()); + return false; -} \ No newline at end of file +} diff --git a/_prepend.php b/_prepend.php index 2d135ed..4dd2069 100644 --- a/_prepend.php +++ b/_prepend.php @@ -1,16 +1,15 @@ addBehavior('themeBeforeDelete', ['behaviorsDcAdvancedCleaner', 'themeBef if (defined('ACTIVITY_REPORT')) { dcAdvancedCleanerActivityReportBehaviors::add($core); -} \ No newline at end of file +} diff --git a/inc/class.advanced.cleaner.php b/inc/class.advanced.cleaner.php index ed6add0..65331ce 100644 --- a/inc/class.advanced.cleaner.php +++ b/inc/class.advanced.cleaner.php @@ -1,16 +1,15 @@ core = $core; $this->init(); - } public static function create(arrayObject $o, dcCore $core) @@ -54,11 +52,12 @@ abstract class advancedCleaner final protected function setProperties($property, $value = null): bool { $properties = is_array($property) ? $property : [$property => $value]; - foreach($properties as $k => $v) { + foreach ($properties as $k => $v) { if (isset($this->properties[$k])) { $this->properties[$k] = (string) $v; } } + return true; } @@ -70,7 +69,7 @@ abstract class advancedCleaner final protected function setActions($action, $name = null): bool { $actions = is_array($action) ? $action : [$action => $name]; - foreach($actions as $k => $v) { + foreach ($actions as $k => $v) { $this->actions[$k] = (string) $v; } @@ -95,33 +94,36 @@ abstract class advancedCleaner $roots = [$roots]; } $rs = []; - $i = 0; + $i = 0; foreach ($roots as $root) { $dirs = files::scanDir($root); - foreach($dirs as $k) { - if ('.' == $k || '..' == $k || !is_dir($root .'/' . $k)) { + foreach ($dirs as $k) { + if ('.' == $k || '..' == $k || !is_dir($root . '/' . $k)) { continue; } - $rs[$i]['key'] = $k; + $rs[$i]['key'] = $k; $rs[$i]['value'] = count(self::scanDir($root . '/' . $k)); $i++; } } + return $rs; } protected static function delDir($roots, $folder, $delfolder = true) { - if (strpos($folder,'/')) { + if (strpos($folder, '/')) { return false; } if (!is_array($roots)) { $roots = [$roots]; } foreach ($roots as $root) { - if (file_exists($root . '/' . $folder)) + if (file_exists($root . '/' . $folder)) { return self::delTree($root . '/' . $folder, $delfolder); + } } + return false; } @@ -135,17 +137,18 @@ abstract class advancedCleaner } $files = files::scandir($path); - foreach($files AS $file) { + foreach ($files as $file) { if (in_array($file, $exclude)) { continue; } if (is_dir($path . '/' . $file)) { $res[] = $file; - $res = self::scanDir($path . '/' . $file, $dir . '/' . $file, $res); + $res = self::scanDir($path . '/' . $file, $dir . '/' . $file, $res); } else { $res[] = empty($dir) ? $file : $dir . '/' . $file; } } + return $res; } @@ -154,7 +157,7 @@ abstract class advancedCleaner if (!is_dir($dir) || !is_readable($dir)) { return false; } - if (substr($dir,-1) != '/') { + if (substr($dir, -1) != '/') { $dir .= '/'; } if (($d = @dir($dir)) === false) { @@ -163,7 +166,8 @@ abstract class advancedCleaner while (($entryname = $d->read()) !== false) { if ($entryname != '.' && $entryname != '..') { if (is_dir($dir . '/' . $entryname)) { - if (!self::delTree($dir . '/' . $entryname)) {return false; + if (!self::delTree($dir . '/' . $entryname)) { + return false; } } else { if (!@unlink($dir . '/' . $entryname)) { @@ -176,8 +180,8 @@ abstract class advancedCleaner if ($delroot) { return @rmdir($dir); - } else { - return true; } + + return true; } -} \ No newline at end of file +} diff --git a/inc/class.dc.advanced.cleaner.php b/inc/class.dc.advanced.cleaner.php index 8f9aee1..8cd287c 100644 --- a/inc/class.dc.advanced.cleaner.php +++ b/inc/class.dc.advanced.cleaner.php @@ -1,16 +1,15 @@ core = $core; - $cleaners = new arrayObject(); + $cleaners = new arrayObject(); try { $this->core->callBehavior('advancedCleanerAdd', $cleaners, $this->core); - foreach($cleaners as $cleaner) { - if ($cleaner instanceOf advancedCleaner && !isset($this->cleaners[$cleaner->id])) { + foreach ($cleaners as $cleaner) { + if ($cleaner instanceof advancedCleaner && !isset($this->cleaners[$cleaner->id])) { $this->cleaners[$cleaner->id] = $cleaner; } } @@ -49,6 +48,7 @@ class dcAdvancedCleaner if ($silent) { return false; } + throw new exception(sprintf(__('unknow cleaner type %s'), $type)); } @@ -68,9 +68,10 @@ class dcAdvancedCleaner if ($ret === false) { $msg = $this->cleaners[$type]->error($action); + throw new Exception($msg ?? __('Unknow error')); } return true; } -} \ No newline at end of file +} diff --git a/inc/class.dc.uninstaller.php b/inc/class.dc.uninstaller.php index e3d2040..f34418e 100644 --- a/inc/class.dc.uninstaller.php +++ b/inc/class.dc.uninstaller.php @@ -1,16 +1,15 @@ [], 'callback' => []]; + protected $modules = []; + protected $actions = ['user' => [], 'callback' => []]; protected $callbacks = ['user' => [], 'callback' => []]; - protected $id = null; + protected $id = null; protected $mroot = null; public $core; @@ -55,16 +54,16 @@ class dcUninstaller /** * Object constructor. - * + * * @param dcCore $core dcCore instance */ public function __construct(dcCore $core) { - $this->core =& $core; - $this->ac = new dcAdvancedCleaner($core); + $this->core = & $core; + $this->ac = new dcAdvancedCleaner($core); $res = []; - foreach($this->ac->get() as $cleaner) { + foreach ($this->ac->get() as $cleaner) { $res[$cleaner->id] = $cleaner->getActions(); } $this->allowed_actions = $res; @@ -77,16 +76,16 @@ class dcUninstaller /** * Loads modules. - * - * Files _defines.php and _uninstall.php must be present on module + * + * Files _defines.php and _uninstall.php must be present on module * to be recognized. * (path separator depends on your OS). - * + * * @param string $path Separated list of paths */ public function loadModules($path) { - $this->path = explode(PATH_SEPARATOR,$path); + $this->path = explode(PATH_SEPARATOR, $path); foreach ($this->path as $root) { if (!is_dir($root) || !is_readable($root)) { @@ -114,31 +113,30 @@ class dcUninstaller /** * Load one module. - * - * Files _defines.php and _uninstall.php must be present on module + * + * Files _defines.php and _uninstall.php must be present on module * to be recognized. - * + * * @param string $root path of module */ public function loadModule($root) { if (file_exists($root . '/_define.php') && file_exists($root . '/_uninstall.php')) { - - $this->id = basename($root); + $this->id = basename($root); $this->mroot = $root; require $root . '/_define.php'; require $root . '/_uninstall.php'; - $this->id = null; + $this->id = null; $this->mroot = null; } } /** * This method registers a module in modules list. - * + * * @param string $name Module name * @param string $desc Module description * @param string $author Module author name @@ -148,11 +146,11 @@ class dcUninstaller { if ($this->id) { $this->modules[$this->id] = [ - 'root' => $this->mroot, - 'name' => $name, - 'desc' => $desc, - 'author' => $author, - 'version' => $version, + 'root' => $this->mroot, + 'name' => $name, + 'desc' => $desc, + 'author' => $author, + 'version' => $version, 'root_writable' => is_writable($this->mroot) ]; } @@ -161,9 +159,9 @@ class dcUninstaller /** * Returns all modules associative array or only one module if $id * is present. - * + * * @param string $id Optionnal module ID - * + * * @return array Modules */ public function getModules($id = null) @@ -171,14 +169,15 @@ class dcUninstaller if ($id && isset($this->modules[$id])) { return $this->modules[$id]; } + return $this->modules; } /** * Returns true if the module with ID $id exists. - * + * * @param string $idModule ID - * + * * @return boolean Success */ public function moduleExists($id) @@ -188,9 +187,9 @@ class dcUninstaller /** * Add a predefined action to unsintall features. - * + * * This action is set in _uninstall.php. - * + * * @param string $type Type of action (from $allowed_actions) * @param string $action Action (from $allowed_actions) * @param string $ns Name of setting related to module. @@ -231,7 +230,7 @@ class dcUninstaller /** * Returns modules $id predefined actions associative array - * + * * @param string $id Optionnal module ID * @return array Modules id */ @@ -253,24 +252,25 @@ class dcUninstaller return []; } $res = []; - foreach($this->allowed_actions as $k => $v) { + foreach ($this->allowed_actions as $k => $v) { if (!isset($this->actions[$group][$id][$k])) { continue; } $res[$k] = $this->actions[$group][$id][$k]; } + return $res; } /** * Add a callable function for unsintall features. - * + * * This action is set in _uninstall.php. - * + * * @param string $func Callable function * @param string $desc Description of action */ - protected function addUserCallback($func, $desc= '') + protected function addUserCallback($func, $desc = '') { $this->addCallback('user', $func, $desc); } @@ -303,7 +303,7 @@ class dcUninstaller * Returns modules $id callback actions associative array * @param string $id Optionnal module ID - * + * * @return array Modules id */ public function getUserCallbacks($id) @@ -323,14 +323,15 @@ class dcUninstaller if (!isset($this->callbacks[$group][$id])) { return []; } + return $this->callbacks[$group][$id]; } /** - * Execute a predifined action. - * + * Execute a predifined action. + * * This function call dcAdvancedCleaner to do actions. - * + * * @param string $type Type of action (from $allowed_actions) * @param string $action Action (from $allowed_actions) * @param string $ns Name of setting related to module. @@ -356,4 +357,4 @@ class dcUninstaller { return in_array($group, ['user','direct']) ? $group : null; } -} \ No newline at end of file +} diff --git a/inc/lib.advanced.cleaner.php b/inc/lib.advanced.cleaner.php index d317d25..c54bb81 100644 --- a/inc/lib.advanced.cleaner.php +++ b/inc/lib.advanced.cleaner.php @@ -1,16 +1,15 @@ core->prefix . 'setting ' . 'WHERE blog_id IS NULL ' . - "OR blog_id IS NOT NULL " . + 'OR blog_id IS NOT NULL ' . 'GROUP BY setting_ns' ); $rs = []; - $i = 0; - while($res->fetch()) { - $rs[$i]['key'] = $res->setting_ns; + $i = 0; + while ($res->fetch()) { + $rs[$i]['key'] = $res->setting_ns; $rs[$i]['value'] = $this->core->con->select( - 'SELECT count(*) FROM ' . $this->core->prefix .'setting ' . - "WHERE setting_ns = '" . $res->setting_ns ."' " . - "AND (blog_id IS NULL OR blog_id IS NOT NULL) " . - "GROUP BY setting_ns " + 'SELECT count(*) FROM ' . $this->core->prefix . 'setting ' . + "WHERE setting_ns = '" . $res->setting_ns . "' " . + 'AND (blog_id IS NULL OR blog_id IS NOT NULL) ' . + 'GROUP BY setting_ns ' )->f(0); $i++; } @@ -92,7 +91,7 @@ class advancedCleanerSettings extends advancedCleaner { if ($action == 'delete_global') { $this->core->con->execute( - 'DELETE FROM ' .$this->core->prefix . 'setting ' . + 'DELETE FROM ' . $this->core->prefix . 'setting ' . 'WHERE blog_id IS NULL ' . "AND setting_ns = '" . $this->core->con->escape($ns) . "' " ); @@ -110,7 +109,7 @@ class advancedCleanerSettings extends advancedCleaner } if ($action == 'delete_all') { $this->core->con->execute( - 'DELETE FROM ' .$this->core->prefix . 'setting ' . + 'DELETE FROM ' . $this->core->prefix . 'setting ' . "WHERE setting_ns = '" . $this->core->con->escape($ns) . "' " . "AND (blog_id IS NULL OR blog_id != '') " ); @@ -148,6 +147,7 @@ class advancedCleanerTables extends advancedCleaner if ($action == 'delete') { return __('Failed to delete table'); } + return ''; } @@ -177,18 +177,18 @@ class advancedCleanerTables extends advancedCleaner public function get(): array { $object = dbSchema::init($this->core->con); - $res = $object->getTables(); + $res = $object->getTables(); $rs = []; - $i = 0; - foreach($res as $k => $v) { + $i = 0; + foreach ($res as $k => $v) { if ('' != $this->core->prefix) { if (!preg_match('/^' . preg_quote($this->core->prefix) . '(.*?)$/', $v, $m)) { continue; } $v = $m[1]; } - $rs[$i]['key'] = $v; + $rs[$i]['key'] = $v; $rs[$i]['value'] = $this->core->con->select('SELECT count(*) FROM ' . $res[$k])->f(0); $i++; } @@ -266,9 +266,9 @@ class advancedCleanerVersions extends advancedCleaner $res = $this->core->con->select('SELECT * FROM ' . $this->core->prefix . 'version'); $rs = []; - $i = 0; + $i = 0; while ($res->fetch()) { - $rs[$i]['key'] = $res->module; + $rs[$i]['key'] = $res->module; $rs[$i]['value'] = $res->version; $i++; } @@ -280,7 +280,7 @@ class advancedCleanerVersions extends advancedCleaner { if ($action == 'delete') { $this->core->con->execute( - 'DELETE FROM '. $this->core->prefix . 'version ' . + 'DELETE FROM ' . $this->core->prefix . 'version ' . "WHERE module = '" . $this->core->con->escape($ns) . "' " ); @@ -317,6 +317,7 @@ class advancedCleanerPlugins extends advancedCleaner if ($action == 'delete') { return __('Failed to delete plugin folder'); } + return ''; } @@ -378,6 +379,7 @@ class advancedCleanerThemes extends advancedCleaner if ($action == 'delete') { return __('Failed to delete themes folder'); } + return ''; } @@ -437,6 +439,7 @@ class advancedCleanerCaches extends advancedCleaner if ($action == 'delete') { return __('Failed to delete cache folder'); } + return ''; } @@ -489,6 +492,7 @@ class advancedCleanerVars extends advancedCleaner if ($action == 'delete') { return __('Failed to delete var folder'); } + return ''; } @@ -512,4 +516,4 @@ class advancedCleanerVars extends advancedCleaner return false; } -} \ No newline at end of file +} diff --git a/inc/lib.dc.advanced.cleaner.activityreport.php b/inc/lib.dc.advanced.cleaner.activityreport.php index 77d2359..5447e54 100644 --- a/inc/lib.dc.advanced.cleaner.activityreport.php +++ b/inc/lib.dc.advanced.cleaner.activityreport.php @@ -1,16 +1,15 @@ activityReport->addLog('dcadvancedcleaner', 'maintenance', [$type ,$action, $ns]); + $GLOBALS['core']->activityReport->addLog('dcadvancedcleaner', 'maintenance', [$type,$action, $ns]); } public static function add($core) @@ -27,10 +26,10 @@ class dcAdvancedCleanerActivityReportBehaviors // This file is used with plugin activityReport $core->activityReport->addGroup( 'dcadvancedcleaner', - __('Plugin dcAdvancedCleaner') - ); + __('Plugin dcAdvancedCleaner') + ); - // from BEHAVIOR dcAdvancedCleanerBeforeAction + // from BEHAVIOR dcAdvancedCleanerBeforeAction // in dcAdvancedCleaner/inc/class.dc.advanced.cleaner.php $core->activityReport->addAction( 'dcadvancedcleaner', @@ -41,4 +40,4 @@ class dcAdvancedCleanerActivityReportBehaviors ['dcAdvancedCleanerActivityReportBehaviors', 'maintenance'] ); } -} \ No newline at end of file +} diff --git a/inc/lib.dc.advanced.cleaner.behaviors.php b/inc/lib.dc.advanced.cleaner.behaviors.php index c23ae39..44fdea9 100644 --- a/inc/lib.dc.advanced.cleaner.behaviors.php +++ b/inc/lib.dc.advanced.cleaner.behaviors.php @@ -1,16 +1,15 @@ loadModule($module['root']); $m_callbacks = $uninstaller->getDirectCallbacks($module['id']); - $m_actions = $uninstaller->getDirectActions($module['id']); + $m_actions = $uninstaller->getDirectActions($module['id']); - foreach($m_callbacks as $k => $callback) { + foreach ($m_callbacks as $k => $callback) { if (!isset($callback['func']) || !is_callable($callback['func'])) { continue; } call_user_func($callback['func'], $module); $done = true; } - foreach($m_actions as $type => $actions) { - foreach($actions as $v) { + foreach ($m_actions as $type => $actions) { + foreach ($actions as $v) { $uninstaller->execute($type, $v['action'], $v['ns']); $done = true; } @@ -86,12 +85,13 @@ class behaviorsDcAdvancedCleaner $uninstaller = new dcUninstaller($core); $uninstaller->loadModules($path); $modules = $uninstaller->getModules(); - $props = $uninstaller->getAllowedActions(); + $props = $uninstaller->getAllowedActions(); echo '' . __('There is no module with uninstall features') . '
' . __('module') . ' | '; - foreach($props as $pro_id => $prop) { + foreach ($props as $pro_id => $prop) { echo '' . __($pro_id) . ' | '; } echo '' . __('other') . ' | ' . '|
---|---|---|---|
' . $module_id . ' | ' . @@ -116,27 +116,27 @@ class behaviorsDcAdvancedCleaner $actions = $uninstaller->getUserActions($module_id); - foreach($props as $prop_id => $prop) { + foreach ($props as $prop_id => $prop) { echo ''; if (!isset($actions[$prop_id])) { echo '-- | '; + continue; } $j = 0; - foreach($actions[$prop_id] as $action_id => $action) { - + foreach ($actions[$prop_id] as $action_id => $action) { if (!isset($props[$prop_id][$action['action']])) { continue; } $ret = base64_encode(serialize([ - 'type' => $prop_id, - 'action'=> $action['action'], - 'ns'=> $action['ns'] + 'type' => $prop_id, + 'action' => $action['action'], + 'ns' => $action['ns'] ])); - echo '
' . $core->formNonce() . @@ -199,8 +198,8 @@ class behaviorsDcAdvancedCleaner try { // Extras if (!empty($_POST['extras'])) { - foreach($_POST['extras'] as $module_id => $extras) { - foreach($extras as $k => $sentence) { + foreach ($_POST['extras'] as $module_id => $extras) { + foreach ($extras as $k => $sentence) { $extra = @unserialize(@base64_decode($sentence)); if (!$extra || !is_callable($extra)) { @@ -212,13 +211,13 @@ class behaviorsDcAdvancedCleaner } // Actions if (!empty($_POST['actions'])) { - foreach($_POST['actions'] as $module_id => $actions) { - foreach($actions as $k => $sentence) { + foreach ($_POST['actions'] as $module_id => $actions) { + foreach ($actions as $k => $sentence) { $action = @unserialize(@base64_decode($sentence)); - if (!$action - || !isset($action['type']) - || !isset($action['action']) + if (!$action + || !isset($action['type']) + || !isset($action['action']) || !isset($action['ns']) ) { continue; @@ -229,8 +228,8 @@ class behaviorsDcAdvancedCleaner } dcPage::addSuccessNotice(__('Action successfuly excecuted')); http::redirect($_POST['redir']); - } catch(Exception $e) { + } catch (Exception $e) { $list->core->error->add($e->getMessage()); } } -} \ No newline at end of file +} diff --git a/index.php b/index.php index 2b399d2..d2adabc 100644 --- a/index.php +++ b/index.php @@ -1,16 +1,15 @@ get() as $k) { +foreach ($ac->get() as $k) { $select_menu[$k->name] = $k->id; if ($k->id == $_REQUEST['part']) { $cleaner = $k; @@ -36,16 +35,15 @@ if (!$cleaner) { # Actions if (!empty($_POST['entries']) && !empty($_POST['action'])) { try { - foreach($_POST['entries'] as $ns) { + foreach ($_POST['entries'] as $ns) { $ac->set($cleaner->id, $_POST['action'], $ns); } dcPage::addSuccessNotice(__('Action successfuly excecuted')); $core->adminurl->redirect( - 'admin.plugin.dcAdvancedCleaner', + 'admin.plugin.dcAdvancedCleaner', ['part' => $cleaner->id] ); - } - catch(Exception $e) { + } catch (Exception $e) { $core->error->add($e->getMessage()); } } @@ -60,9 +58,9 @@ $core->callBehavior('dcAdvancedCleanerAdminHeader', $core); echo '
' . dcPage::breadcrumb([ - __('Plugins') => '', + __('Plugins') => '', __('Advanced cleaner') => '' -]) . +]) . dcPage::notices() . '