use namespace
This commit is contained in:
parent
dcd19778df
commit
f2e8775454
15 changed files with 407 additions and 1667 deletions
75
_config.php
75
_config.php
|
@ -1,75 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_CONTEXT_MODULE')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dcCore::app()->auth->isSuperAdmin()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_POST['save'])) {
|
|
||||||
try {
|
|
||||||
dcCore::app()->blog->settings->__get(basename(__DIR__))->dropEvery(
|
|
||||||
'dcAdvancedCleaner_behavior_active'
|
|
||||||
);
|
|
||||||
dcCore::app()->blog->settings->__get(basename(__DIR__))->put(
|
|
||||||
'dcAdvancedCleaner_behavior_active',
|
|
||||||
!empty($_POST['behavior_active']),
|
|
||||||
'boolean',
|
|
||||||
null,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
dcCore::app()->blog->settings->__get(basename(__DIR__))->dropEvery(
|
|
||||||
'dcAdvancedCleaner_dcproperty_hide'
|
|
||||||
);
|
|
||||||
dcCore::app()->blog->settings->__get(basename(__DIR__))->put(
|
|
||||||
'dcAdvancedCleaner_dcproperty_hide',
|
|
||||||
!empty($_POST['dcproperty_hide']),
|
|
||||||
'boolean',
|
|
||||||
null,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
|
||||||
__('Configuration successfully updated.')
|
|
||||||
);
|
|
||||||
dcCore::app()->adminurl->redirect(
|
|
||||||
'admin.plugins',
|
|
||||||
[
|
|
||||||
'module' => basename(__DIR__),
|
|
||||||
'conf' => 1,
|
|
||||||
'redir' => empty($_REQUEST['redir']) ? dcCore::app()->admin->list->getURL() . '#plugins' : $_REQUEST['redir'],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo '
|
|
||||||
<p><label class="classic" for="behavior_active">' .
|
|
||||||
form::checkbox(
|
|
||||||
'behavior_active',
|
|
||||||
1,
|
|
||||||
dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_behavior_active
|
|
||||||
) . ' ' . __('Activate behaviors') . '</label></p>
|
|
||||||
<p class="form-note">' . __('Enable actions set in _uninstall.php files.') . '</p>
|
|
||||||
<p><label class="classic" for="dcproperty_hide">' .
|
|
||||||
form::checkbox(
|
|
||||||
'dcproperty_hide',
|
|
||||||
1,
|
|
||||||
dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_dcproperty_hide
|
|
||||||
) . ' ' . __('Hide Dotclear default properties in actions tabs') . '</label></p>
|
|
||||||
<p class="form-note">' .
|
|
||||||
__('Prevent from deleting Dotclear important properties.') . '</p>';
|
|
47
_install.php
47
_install.php
|
@ -1,47 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!dcCore::app()->newVersion(
|
|
||||||
basename(__DIR__),
|
|
||||||
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
|
|
||||||
)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->blog->settings->get(basename(__DIR__))->put(
|
|
||||||
'dcAdvancedCleaner_behavior_active',
|
|
||||||
true,
|
|
||||||
'boolean',
|
|
||||||
'',
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
dcCore::app()->blog->settings->get(basename(__DIR__))->put(
|
|
||||||
'dcAdvancedCleaner_dcproperty_hide',
|
|
||||||
true,
|
|
||||||
'boolean',
|
|
||||||
'',
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
8
css/backend.css
Normal file
8
css/backend.css
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.offline label{
|
||||||
|
font-weight:bold;
|
||||||
|
color:#c44d58;
|
||||||
|
}
|
||||||
|
.module-distrib img {
|
||||||
|
with: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
|
@ -1,183 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
abstract class advancedCleaner
|
|
||||||
{
|
|
||||||
private static $exclude = [
|
|
||||||
'.', '..', '__MACOSX', '.svn', 'CVS', '.DS_Store', 'Thumbs.db',
|
|
||||||
];
|
|
||||||
|
|
||||||
private $properties = [
|
|
||||||
'id' => '',
|
|
||||||
'name' => '',
|
|
||||||
'desc' => '',
|
|
||||||
];
|
|
||||||
|
|
||||||
private $actions = [];
|
|
||||||
|
|
||||||
final public function __construct()
|
|
||||||
{
|
|
||||||
$this->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function create(arrayObject $o)
|
|
||||||
{
|
|
||||||
$c = get_called_class();
|
|
||||||
$o->append(new $c());
|
|
||||||
}
|
|
||||||
|
|
||||||
final public function __get(string $property)
|
|
||||||
{
|
|
||||||
return $this->getProperty($property);
|
|
||||||
}
|
|
||||||
|
|
||||||
final public function getProperty(string $property)
|
|
||||||
{
|
|
||||||
return $this->properties[$property] ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final protected function setProperties($property, $value = null): bool
|
|
||||||
{
|
|
||||||
$properties = is_array($property) ? $property : [$property => $value];
|
|
||||||
foreach ($properties as $k => $v) {
|
|
||||||
if (isset($this->properties[$k])) {
|
|
||||||
$this->properties[$k] = (string) $v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
final public function getActions()
|
|
||||||
{
|
|
||||||
return $this->actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
final protected function setActions($action, $name = null): bool
|
|
||||||
{
|
|
||||||
$actions = is_array($action) ? $action : [$action => $name];
|
|
||||||
foreach ($actions as $k => $v) {
|
|
||||||
$this->actions[$k] = (string) $v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected function init(): bool;
|
|
||||||
|
|
||||||
abstract public function error($action): string;
|
|
||||||
|
|
||||||
abstract public function official(): array;
|
|
||||||
|
|
||||||
abstract public function get(): array;
|
|
||||||
|
|
||||||
abstract public function set($action, $ns): bool;
|
|
||||||
|
|
||||||
# helpers
|
|
||||||
|
|
||||||
protected static function getDirs($roots)
|
|
||||||
{
|
|
||||||
if (!is_array($roots)) {
|
|
||||||
$roots = [$roots];
|
|
||||||
}
|
|
||||||
$rs = [];
|
|
||||||
$i = 0;
|
|
||||||
foreach ($roots as $root) {
|
|
||||||
$dirs = files::scanDir($root);
|
|
||||||
foreach ($dirs as $k) {
|
|
||||||
if ('.' == $k || '..' == $k || !is_dir($root . '/' . $k)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$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, '/')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!is_array($roots)) {
|
|
||||||
$roots = [$roots];
|
|
||||||
}
|
|
||||||
foreach ($roots as $root) {
|
|
||||||
if (file_exists($root . '/' . $folder)) {
|
|
||||||
return self::delTree($root . '/' . $folder, $delfolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function scanDir($path, $dir = '', $res = [])
|
|
||||||
{
|
|
||||||
$exclude = self::$exclude;
|
|
||||||
|
|
||||||
$path = path::real($path);
|
|
||||||
if (!is_dir($path) || !is_readable($path)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
$files = files::scandir($path);
|
|
||||||
|
|
||||||
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);
|
|
||||||
} else {
|
|
||||||
$res[] = empty($dir) ? $file : $dir . '/' . $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static function delTree($dir, $delroot = true)
|
|
||||||
{
|
|
||||||
if (!is_dir($dir) || !is_readable($dir)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (substr($dir, -1) != '/') {
|
|
||||||
$dir .= '/';
|
|
||||||
}
|
|
||||||
if (($d = @dir($dir)) === false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
while (($entryname = $d->read()) !== false) {
|
|
||||||
if ($entryname != '.' && $entryname != '..') {
|
|
||||||
if (is_dir($dir . '/' . $entryname)) {
|
|
||||||
if (!self::delTree($dir . '/' . $entryname)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!@unlink($dir . '/' . $entryname)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$d->close();
|
|
||||||
|
|
||||||
if ($delroot) {
|
|
||||||
return @rmdir($dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,75 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_ADMIN_CONTEXT')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class dcAdvancedCleaner
|
|
||||||
{
|
|
||||||
protected $cleaners = [];
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$cleaners = new arrayObject();
|
|
||||||
|
|
||||||
try {
|
|
||||||
dcCore::app()->callBehavior('advancedCleanerAdd', $cleaners);
|
|
||||||
|
|
||||||
foreach ($cleaners as $cleaner) {
|
|
||||||
if ($cleaner instanceof advancedCleaner && !isset($this->cleaners[$cleaner->id])) {
|
|
||||||
$this->cleaners[$cleaner->id] = $cleaner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get($type = null, $silent = false)
|
|
||||||
{
|
|
||||||
if (null === $type) {
|
|
||||||
return $this->cleaners;
|
|
||||||
}
|
|
||||||
if (isset($this->cleaners[$type])) {
|
|
||||||
return $this->cleaners[$type];
|
|
||||||
}
|
|
||||||
if ($silent) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new exception(sprintf(__('unknow cleaner type %s'), $type));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($type, $action, $ns)
|
|
||||||
{
|
|
||||||
if (!isset($this->cleaners[$type])) {
|
|
||||||
throw new exception(sprintf(__('unknow cleaner type %s'), $type));
|
|
||||||
}
|
|
||||||
if ($ns == basename(dirname('../' . __DIR__))) {
|
|
||||||
throw new exception(__("dcAdvancedCleaner can't remove itself"));
|
|
||||||
}
|
|
||||||
|
|
||||||
# BEHAVIOR dcAdvancedCleanerBeforeAction
|
|
||||||
dcCore::app()->callBehavior('dcAdvancedCleanerBeforeAction', $type, $action, $ns);
|
|
||||||
|
|
||||||
$ret = $this->cleaners[$type]->set($action, $ns);
|
|
||||||
|
|
||||||
if ($ret === false) {
|
|
||||||
$msg = $this->cleaners[$type]->error($action);
|
|
||||||
|
|
||||||
throw new Exception($msg ?? __('Unknow error'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,356 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_ADMIN_CONTEXT')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Localized l10n
|
|
||||||
__('delete table');
|
|
||||||
__('delete cache files');
|
|
||||||
__('delete plugin files');
|
|
||||||
__('delete theme files');
|
|
||||||
__('delete the version number');
|
|
||||||
__('Uninstall extensions');
|
|
||||||
__('delete %s blog settings');
|
|
||||||
__('delete %s global settings');
|
|
||||||
__('delete all %s settings');
|
|
||||||
__('delete %s table');
|
|
||||||
__('delete %s version number');
|
|
||||||
__('delete %s plugin files');
|
|
||||||
__('delete %s theme file');
|
|
||||||
__('delete %s cache files');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Modules uninstall features handler
|
|
||||||
*
|
|
||||||
* Provides an object to handle modules uninstall features
|
|
||||||
* (themes or plugins).
|
|
||||||
* This class used dcAdvancedCleaner.
|
|
||||||
*/
|
|
||||||
class dcUninstaller
|
|
||||||
{
|
|
||||||
protected $path;
|
|
||||||
|
|
||||||
protected $modules = [];
|
|
||||||
protected $actions = ['user' => [], 'callback' => []];
|
|
||||||
protected $callbacks = ['user' => [], 'callback' => []];
|
|
||||||
|
|
||||||
protected $id = null;
|
|
||||||
protected $mroot = null;
|
|
||||||
|
|
||||||
private $ac;
|
|
||||||
private $allowed_actions = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Object constructor.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->ac = new dcAdvancedCleaner();
|
|
||||||
|
|
||||||
$res = [];
|
|
||||||
foreach ($this->ac->get() as $cleaner) {
|
|
||||||
$res[$cleaner->id] = $cleaner->getActions();
|
|
||||||
}
|
|
||||||
$this->allowed_actions = $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAllowedActions()
|
|
||||||
{
|
|
||||||
return $this->allowed_actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads modules.
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
foreach ($this->path as $root) {
|
|
||||||
if (!is_dir($root) || !is_readable($root)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (substr($root, -1) != '/') {
|
|
||||||
$root .= '/';
|
|
||||||
}
|
|
||||||
if (($d = @dir($root)) === false) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
while (($entry = $d->read()) !== false) {
|
|
||||||
$full_entry = $root . '/' . $entry;
|
|
||||||
|
|
||||||
if ($entry != '.' && $entry != '..' && is_dir($full_entry)) {
|
|
||||||
$this->loadModule($full_entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$d->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sort modules by name
|
|
||||||
uasort($this->modules, [$this, 'sortModules']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load one 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->mroot = $root;
|
|
||||||
|
|
||||||
require $root . '/_define.php';
|
|
||||||
require $root . '/_uninstall.php';
|
|
||||||
|
|
||||||
$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
|
|
||||||
* @param string $version Module version
|
|
||||||
*/
|
|
||||||
public function registerModule($name, $desc, $author, $version, $properties = [])
|
|
||||||
{
|
|
||||||
if ($this->id) {
|
|
||||||
$this->modules[$this->id] = [
|
|
||||||
'root' => $this->mroot,
|
|
||||||
'name' => $name,
|
|
||||||
'desc' => $desc,
|
|
||||||
'author' => $author,
|
|
||||||
'version' => $version,
|
|
||||||
'root_writable' => is_writable($this->mroot),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all modules associative array or only one module if <var>$id</var>
|
|
||||||
* is present.
|
|
||||||
*
|
|
||||||
* @param string $id Optionnal module ID
|
|
||||||
*
|
|
||||||
* @return array Modules
|
|
||||||
*/
|
|
||||||
public function getModules($id = null)
|
|
||||||
{
|
|
||||||
if ($id && isset($this->modules[$id])) {
|
|
||||||
return $this->modules[$id];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->modules;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the module with ID <var>$id</var> exists.
|
|
||||||
*
|
|
||||||
* @param string $id Module ID
|
|
||||||
*
|
|
||||||
* @return boolean Success
|
|
||||||
*/
|
|
||||||
public function moduleExists($id)
|
|
||||||
{
|
|
||||||
return isset($this->modules[$id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* @param string $desc Description of action
|
|
||||||
*/
|
|
||||||
public function addUserAction($type, $action, $ns, $desc = '')
|
|
||||||
{
|
|
||||||
$this->addAction('user', $type, $action, $ns, $desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addDirectAction($type, $action, $ns, $desc = '')
|
|
||||||
{
|
|
||||||
$this->addAction('direct', $type, $action, $ns, $desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addAction($group, $type, $action, $ns, $desc)
|
|
||||||
{
|
|
||||||
$group = self::group($group);
|
|
||||||
|
|
||||||
if (null === $this->id) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (empty($type) || empty($ns)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!isset($this->allowed_actions[$type][$action])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (empty($desc)) {
|
|
||||||
$desc = __($action);
|
|
||||||
}
|
|
||||||
$this->actions[$group][$this->id][$type][] = [
|
|
||||||
'ns' => $ns,
|
|
||||||
'action' => $action,
|
|
||||||
'desc' => $desc,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns modules <var>$id</var> predefined actions associative array
|
|
||||||
*
|
|
||||||
* @param string $id Optionnal module ID
|
|
||||||
* @return array Modules id
|
|
||||||
*/
|
|
||||||
public function getUserActions($id)
|
|
||||||
{
|
|
||||||
return $this->getActions('user', $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDirectActions($id)
|
|
||||||
{
|
|
||||||
return $this->getActions('direct', $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getActions($group, $id)
|
|
||||||
{
|
|
||||||
$group = self::group($group);
|
|
||||||
|
|
||||||
if (!isset($this->actions[$group][$id])) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
$res = [];
|
|
||||||
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 = '')
|
|
||||||
{
|
|
||||||
$this->addCallback('user', $func, $desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function addDirectCallback($func, $desc = '')
|
|
||||||
{
|
|
||||||
$this->addCallback('direct', $func, $desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addCallback($group, $func, $desc)
|
|
||||||
{
|
|
||||||
$group = self::group($group);
|
|
||||||
|
|
||||||
if (null === $this->id) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (empty($desc)) {
|
|
||||||
$desc = __('extra action');
|
|
||||||
}
|
|
||||||
if (!is_callable($func)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$this->callbacks[$group][$this->id][] = [
|
|
||||||
'func' => $func,
|
|
||||||
'desc' => $desc,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns modules <var>$id</var> callback actions associative array
|
|
||||||
|
|
||||||
* @param string $id Optionnal module ID
|
|
||||||
*
|
|
||||||
* @return array Modules id
|
|
||||||
*/
|
|
||||||
public function getUserCallbacks($id)
|
|
||||||
{
|
|
||||||
return $this->getCallbacks('user', $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDirectCallbacks($id)
|
|
||||||
{
|
|
||||||
return $this->getCallbacks('direct', $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getCallbacks($group, $id)
|
|
||||||
{
|
|
||||||
$group = self::group($group);
|
|
||||||
|
|
||||||
if (!isset($this->callbacks[$group][$id])) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->callbacks[$group][$id];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* @return boolean Success
|
|
||||||
*/
|
|
||||||
public function execute($type, $action, $ns)
|
|
||||||
{
|
|
||||||
if (!isset($this->allowed_actions[$type][$action]) || empty($ns)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->ac->set($type, $action, $ns);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function sortModules($a, $b)
|
|
||||||
{
|
|
||||||
return strcasecmp($a['name'], $b['name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function group($group)
|
|
||||||
{
|
|
||||||
return in_array($group, ['user','direct']) ? $group : null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,519 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
class advancedCleanerSettings extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'settings',
|
|
||||||
'name' => __('Settings'),
|
|
||||||
'desc' => __('Namespaces registered in dcSettings'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete_global' => __('delete global settings'),
|
|
||||||
'delete_local' => __('delete blog settings'),
|
|
||||||
'delete_all' => __('delete all settings'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'delete_global') {
|
|
||||||
return __('Failed to delete global settings');
|
|
||||||
}
|
|
||||||
if ($action == 'delete_local') {
|
|
||||||
return __('Failed to delete local settings');
|
|
||||||
}
|
|
||||||
if ($action == 'delete_all') {
|
|
||||||
return __('Failed to delete all settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'akismet',
|
|
||||||
'antispam',
|
|
||||||
'breadcrumb',
|
|
||||||
'dcckeditor',
|
|
||||||
'dclegacyeditor',
|
|
||||||
'maintenance',
|
|
||||||
'pages',
|
|
||||||
'pings',
|
|
||||||
'system',
|
|
||||||
'themes',
|
|
||||||
'widgets',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
$res = dcCore::app()->con->select(
|
|
||||||
'SELECT setting_ns ' .
|
|
||||||
'FROM ' . dcCore::app()->prefix . 'setting ' .
|
|
||||||
'WHERE blog_id IS NULL ' .
|
|
||||||
'OR blog_id IS NOT NULL ' .
|
|
||||||
'GROUP BY setting_ns'
|
|
||||||
);
|
|
||||||
|
|
||||||
$rs = [];
|
|
||||||
$i = 0;
|
|
||||||
while ($res->fetch()) {
|
|
||||||
$rs[$i]['key'] = $res->setting_ns;
|
|
||||||
$rs[$i]['value'] = dcCore::app()->con->select(
|
|
||||||
'SELECT count(*) FROM ' . dcCore::app()->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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if ($action == 'delete_global') {
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . 'setting ' .
|
|
||||||
'WHERE blog_id IS NULL ' .
|
|
||||||
"AND setting_ns = '" . dcCore::app()->con->escapeStr((string) $ns) . "' "
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($action == 'delete_local') {
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . 'setting ' .
|
|
||||||
"WHERE blog_id = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog->id) . "' " .
|
|
||||||
"AND setting_ns = '" . dcCore::app()->con->escapeStr((string) $ns) . "' "
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($action == 'delete_all') {
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . 'setting ' .
|
|
||||||
"WHERE setting_ns = '" . dcCore::app()->con->escapeStr((string) $ns) . "' " .
|
|
||||||
"AND (blog_id IS NULL OR blog_id != '') "
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class advancedCleanerTables extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'tables',
|
|
||||||
'name' => __('Tables'),
|
|
||||||
'desc' => __('All database tables of Dotclear'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete' => __('delete'),
|
|
||||||
'empty' => __('empty'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
return __('Failed to empty table');
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
return __('Failed to delete table');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'blog',
|
|
||||||
'category',
|
|
||||||
'comment',
|
|
||||||
'link',
|
|
||||||
'log',
|
|
||||||
'media',
|
|
||||||
'meta',
|
|
||||||
'permissions',
|
|
||||||
'ping',
|
|
||||||
'post',
|
|
||||||
'post_media',
|
|
||||||
'pref',
|
|
||||||
'session',
|
|
||||||
'setting',
|
|
||||||
'spamrule',
|
|
||||||
'user',
|
|
||||||
'version',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
$object = dbSchema::init(dcCore::app()->con);
|
|
||||||
$res = $object->getTables();
|
|
||||||
|
|
||||||
$rs = [];
|
|
||||||
$i = 0;
|
|
||||||
foreach ($res as $k => $v) {
|
|
||||||
if ('' != dcCore::app()->prefix) {
|
|
||||||
if (!preg_match('/^' . preg_quote(dcCore::app()->prefix) . '(.*?)$/', $v, $m)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$v = $m[1];
|
|
||||||
}
|
|
||||||
$rs[$i]['key'] = $v;
|
|
||||||
$rs[$i]['value'] = dcCore::app()->con->select('SELECT count(*) FROM ' . $res[$k])->f(0);
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if (in_array($action, ['empty', 'delete'])) {
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->con->escapeSystem(dcCore::app()->prefix . $ns)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ($action == 'empty') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DROP TABLE ' . dcCore::app()->con->escapeSystem(dcCore::app()->prefix . $ns)
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class advancedCleanerVersions extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'versions',
|
|
||||||
'name' => __('Versions'),
|
|
||||||
'desc' => __('Versions registered in table "version" of Dotclear'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete' => __('delete'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'delete') {
|
|
||||||
return __('Failed to delete version');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'antispam',
|
|
||||||
'blogroll',
|
|
||||||
'blowupConfig',
|
|
||||||
'core',
|
|
||||||
'dcCKEditor',
|
|
||||||
'dcLegacyEditor',
|
|
||||||
'pages',
|
|
||||||
'pings',
|
|
||||||
'simpleMenu',
|
|
||||||
'tags',
|
|
||||||
'widgets',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
$res = dcCore::app()->con->select('SELECT * FROM ' . dcCore::app()->prefix . 'version');
|
|
||||||
|
|
||||||
$rs = [];
|
|
||||||
$i = 0;
|
|
||||||
while ($res->fetch()) {
|
|
||||||
$rs[$i]['key'] = $res->module;
|
|
||||||
$rs[$i]['value'] = $res->version;
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if ($action == 'delete') {
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . 'version ' .
|
|
||||||
"WHERE module = '" . dcCore::app()->con->escapeStr((string) $ns) . "' "
|
|
||||||
);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class advancedCleanerPlugins extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'plugins',
|
|
||||||
'name' => __('Plugins'),
|
|
||||||
'desc' => __('Folders from plugins directories'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete' => __('delete'),
|
|
||||||
'empty' => __('empty'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
return __('Failed to empty plugin folder');
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
return __('Failed to delete plugin folder');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return explode(',', DC_DISTRIB_PLUGINS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
$res = self::getDirs(explode(PATH_SEPARATOR, DC_PLUGINS_ROOT));
|
|
||||||
sort($res);
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
$res = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT);
|
|
||||||
self::delDir($res, $ns, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
$res = explode(PATH_SEPARATOR, DC_PLUGINS_ROOT);
|
|
||||||
self::delDir($res, $ns, true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class advancedCleanerThemes extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'themes',
|
|
||||||
'name' => __('Themes'),
|
|
||||||
'desc' => __('Folders from blog themes directory'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete' => __('delete'),
|
|
||||||
'empty' => __('empty'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
return __('Failed to empty themes folder');
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
return __('Failed to delete themes folder');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return explode(',', DC_DISTRIB_THEMES);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
$res = self::getDirs(dcCore::app()->blog->themes_path);
|
|
||||||
sort($res);
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
self::delDir(dcCore::app()->blog->themes_path, $ns, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
self::delDir(dcCore::app()->blog->themes_path, $ns, true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class advancedCleanerCaches extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'caches',
|
|
||||||
'name' => __('Cache'),
|
|
||||||
'desc' => __('Folders from cache directory'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete' => __('delete'),
|
|
||||||
'empty' => __('empty'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
return __('Failed to empty cache folder');
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
return __('Failed to delete cache folder');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return ['cbfeed', 'cbtpl', 'dcrepo', 'versions'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
return self::getDirs(DC_TPL_CACHE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if ($action == 'empty') {
|
|
||||||
self::delDir(DC_TPL_CACHE, $ns, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($action == 'delete') {
|
|
||||||
self::delDir(DC_TPL_CACHE, $ns, true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class advancedCleanerVars extends advancedCleaner
|
|
||||||
{
|
|
||||||
protected function init(): bool
|
|
||||||
{
|
|
||||||
$this->setProperties([
|
|
||||||
'id' => 'vars',
|
|
||||||
'name' => __('Var'),
|
|
||||||
'desc' => __('Folders from Dotclear VAR directory'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->setActions([
|
|
||||||
'delete' => __('delete'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function error($action): string
|
|
||||||
{
|
|
||||||
if ($action == 'delete') {
|
|
||||||
return __('Failed to delete var folder');
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function official(): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get(): array
|
|
||||||
{
|
|
||||||
return self::getDirs(DC_VAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($action, $ns): bool
|
|
||||||
{
|
|
||||||
if ($action == 'delete') {
|
|
||||||
self::delDir(DC_VAR, $ns, true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis and Contributors
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_RC_PATH')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class dcAdvancedCleanerActivityReportBehaviors
|
|
||||||
{
|
|
||||||
public static function maintenance($type, $action, $ns)
|
|
||||||
{
|
|
||||||
dcCore::app()->activityReport->addLog('dcadvancedcleaner', 'maintenance', [$type,$action, $ns]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function add()
|
|
||||||
{
|
|
||||||
// This file is used with plugin activityReport
|
|
||||||
dcCore::app()->activityReport->addGroup(
|
|
||||||
'dcadvancedcleaner',
|
|
||||||
__('Plugin dcAdvancedCleaner')
|
|
||||||
);
|
|
||||||
|
|
||||||
// from BEHAVIOR dcAdvancedCleanerBeforeAction
|
|
||||||
// in dcAdvancedCleaner/inc/class.dc.advanced.cleaner.php
|
|
||||||
dcCore::app()->activityReport->addAction(
|
|
||||||
'dcadvancedcleaner',
|
|
||||||
'maintenance',
|
|
||||||
__('Maintenance'),
|
|
||||||
__('New action from dcAdvancedCleaner has been made with type="%s", action="%s", ns="%s".'),
|
|
||||||
'dcAdvancedCleanerBeforeAction',
|
|
||||||
['dcAdvancedCleanerActivityReportBehaviors', 'maintenance']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
$('#parts_menu input[type=submit]').hide();
|
$('#parts_menu input[type=submit]').hide();
|
||||||
$('#parts_menu #part').on('change', function () {this.form.submit();});
|
$('#parts_menu #select_part').on('change', function () {this.form.submit();});
|
||||||
dotclear.condSubmit('#form-funcs td input[type=checkbox]', '#form-funcs #do-action');
|
dotclear.condSubmit('#form-funcs td input[type=checkbox]', '#form-funcs #do-action');
|
||||||
});
|
});
|
263
src/Backend.php
263
src/Backend.php
|
@ -10,232 +10,55 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
namespace Dotclear\Plugin\dcAdvancedCleaner;
|
||||||
__('Advanced cleaner'),
|
|
||||||
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
|
|
||||||
dcPage::getPF(basename(__DIR__) . '/icon.svg'),
|
|
||||||
preg_match(
|
|
||||||
'/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/',
|
|
||||||
$_SERVER['REQUEST_URI']
|
|
||||||
),
|
|
||||||
dcCore::app()->auth->isSuperAdmin()
|
|
||||||
);
|
|
||||||
|
|
||||||
dcCore::app()->addBehaviors([
|
use dcAdmin;
|
||||||
'adminDashboardFavoritesV2' => function ($favs) {
|
use dcCore;
|
||||||
$favs->register(basename(__DIR__), [
|
use dcFavorites;
|
||||||
'title' => __('Advanced cleaner'),
|
use dcNsProcess;
|
||||||
'url' => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
|
use dcPage;
|
||||||
'small-icon' => dcPage::getPF(basename(__DIR__) . '/icon.svg'),
|
|
||||||
'large-icon' => dcPage::getPF(basename(__DIR__) . '/icon-big.svg'),
|
|
||||||
//'permissions' => dcCore::app()->auth->isSuperAdmin(),
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
'pluginsToolsTabsV2' => function () {
|
class Backend extends dcNsProcess
|
||||||
if (!dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_behavior_active) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$path = DC_PLUGINS_ROOT;
|
|
||||||
$redir = dcCore::app()->adminurl->get('admin.plugins', [], '#uninstaller');
|
|
||||||
$title = '';
|
|
||||||
|
|
||||||
$uninstaller = new dcUninstaller();
|
|
||||||
$uninstaller->loadModules($path);
|
|
||||||
$modules = $uninstaller->getModules();
|
|
||||||
$props = $uninstaller->getAllowedActions();
|
|
||||||
|
|
||||||
echo '<div class="multi-part" id="uninstaller" title="' . __('Advanced uninstall') . '"><h3>' . __('Advanced uninstall') . '</h3>';
|
|
||||||
|
|
||||||
if (!count($modules)) {
|
|
||||||
echo '<p>' . __('There is no module with uninstall features') . '</p></div>';
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<p>' . __('List of modules with advanced uninstall features') . '</p>' .
|
|
||||||
'<form method="post" action="' . $redir . '">' .
|
|
||||||
'<table class="clear"><tr>' .
|
|
||||||
'<th colspan="2">' . __('module') . '</th>';
|
|
||||||
|
|
||||||
foreach ($props as $pro_id => $prop) {
|
|
||||||
echo '<th>' . __($pro_id) . '</th>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '<th>' . __('other') . '</th>' . '</tr>';
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach ($modules as $module_id => $module) {
|
|
||||||
echo
|
|
||||||
'<tr class="line">' .
|
|
||||||
'<td class="nowrap">' . $module_id . '</td>' .
|
|
||||||
'<td class="nowrap">' . $module['version'] . '</td>';
|
|
||||||
|
|
||||||
$actions = $uninstaller->getUserActions($module_id);
|
|
||||||
|
|
||||||
foreach ($props as $prop_id => $prop) {
|
|
||||||
echo '<td class="nowrap">';
|
|
||||||
|
|
||||||
if (!isset($actions[$prop_id])) {
|
|
||||||
echo '--</td>';
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$j = 0;
|
|
||||||
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'],
|
|
||||||
]));
|
|
||||||
|
|
||||||
echo '<label class="classic">' .
|
|
||||||
form::checkbox(['actions[' . $module_id . '][' . $j . ']'], $ret) .
|
|
||||||
' ' . $action['desc'] . '</label><br />';
|
|
||||||
|
|
||||||
$j++;
|
|
||||||
}
|
|
||||||
echo '</td>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '<td class="nowrap">';
|
|
||||||
|
|
||||||
$callbacks = $uninstaller->getUserCallbacks($module_id);
|
|
||||||
|
|
||||||
if (empty($callbacks)) {
|
|
||||||
echo '--';
|
|
||||||
}
|
|
||||||
|
|
||||||
$k = 0;
|
|
||||||
foreach ($callbacks as $callback_id => $callback) {
|
|
||||||
$ret = base64_encode(serialize($callback['func']));
|
|
||||||
|
|
||||||
echo '<label class="classic">' .
|
|
||||||
form::checkbox(['extras[' . $module_id . '][' . $k . ']'], $ret) .
|
|
||||||
' ' . $callback['desc'] . '</label><br />';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</td></tr>';
|
|
||||||
}
|
|
||||||
echo
|
|
||||||
'</table>' .
|
|
||||||
'<p>' .
|
|
||||||
dcCore::app()->formNonce() .
|
|
||||||
form::hidden(['path'], $path) .
|
|
||||||
form::hidden(['redir'], $redir) .
|
|
||||||
form::hidden(['action'], 'uninstall') .
|
|
||||||
'<input type="submit" name="submit" value="' . __('Perform selected actions') . '" /> ' .
|
|
||||||
'</p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
},
|
|
||||||
|
|
||||||
'adminModulesListDoActions' => function ($list, $modules, $type) {
|
|
||||||
if (!dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_behavior_active) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($_POST['action']) || $_POST['action'] != 'uninstall'
|
|
||||||
|| (empty($_POST['extras']) && empty($_POST['actions']))
|
|
||||||
) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$uninstaller = new dcUninstaller();
|
|
||||||
$uninstaller->loadModules($_POST['path']);
|
|
||||||
$modules = $uninstaller->getModules();
|
|
||||||
$props = $uninstaller->getAllowedActions();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Extras
|
|
||||||
if (!empty($_POST['extras'])) {
|
|
||||||
foreach ($_POST['extras'] as $module_id => $extras) {
|
|
||||||
foreach ($extras as $k => $sentence) {
|
|
||||||
$extra = @unserialize(@base64_decode($sentence));
|
|
||||||
|
|
||||||
if (!$extra || !is_callable($extra)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
call_user_func($extra, $module_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Actions
|
|
||||||
if (!empty($_POST['actions'])) {
|
|
||||||
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'])
|
|
||||||
|| !isset($action['ns'])
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$uninstaller->execute($action['type'], $action['action'], $action['ns']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dcAdminNotices::addSuccessNotice(__('Action successfuly excecuted'));
|
|
||||||
http::redirect($_POST['redir']);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'pluginsBeforeDelete' => function ($plugin) {
|
|
||||||
dcAdvancedCleanerModuleBeforeDelete($plugin);
|
|
||||||
},
|
|
||||||
|
|
||||||
'themeBeforeDelete' => function ($theme) {
|
|
||||||
dcAdvancedCleanerModuleBeforeDelete($theme);
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
function dcAdvancedCleanerModuleBeforeDelete($module)
|
|
||||||
{
|
{
|
||||||
if (!dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_behavior_active) {
|
public static function init(): bool
|
||||||
return null;
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant();
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
}
|
}
|
||||||
|
|
||||||
$done = false;
|
public static function process(): bool
|
||||||
|
{
|
||||||
$uninstaller = new dcUninstaller();
|
if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
|
||||||
$uninstaller->loadModule($module['root']);
|
return false;
|
||||||
|
|
||||||
$m_callbacks = $uninstaller->getDirectCallbacks($module['id']);
|
|
||||||
$m_actions = $uninstaller->getDirectActions($module['id']);
|
|
||||||
|
|
||||||
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) {
|
|
||||||
$uninstaller->execute($type, $v['action'], $v['ns']);
|
|
||||||
$done = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($done) {
|
|
||||||
if ('theme' == $module['type']) {
|
|
||||||
dcCore::app()->adminurl->redirect('admin.blog.theme', ['del' => 1]);
|
|
||||||
} else {
|
|
||||||
dcCore::app()->adminurl->redirect('admin.plugins', ['removed' => 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
||||||
|
My::name(),
|
||||||
|
dcCore::app()->adminurl?->get('admin.plugin.' . My::id()),
|
||||||
|
dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
|
preg_match(
|
||||||
|
'/' . preg_quote(dcCore::app()->adminurl?->get('admin.plugin.' . My::id())) . '(&.*)?$/',
|
||||||
|
$_SERVER['REQUEST_URI']
|
||||||
|
),
|
||||||
|
dcCore::app()->auth?->isSuperAdmin()
|
||||||
|
);
|
||||||
|
|
||||||
|
dcCore::app()->addBehaviors([
|
||||||
|
'adminDashboardFavoritesV2' => function (dcFavorites $favs): void {
|
||||||
|
$favs->register(My::id(), [
|
||||||
|
'title' => My::name(),
|
||||||
|
'url' => dcCore::app()->adminurl?->get('admin.plugin.' . My::id()),
|
||||||
|
'small-icon' => dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
|
'large-icon' => dcPage::getPF(My::id() . '/icon-big.svg'),
|
||||||
|
//'permissions' => dcCore::app()->auth?->isSuperAdmin(),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
283
src/Manage.php
283
src/Manage.php
|
@ -10,117 +10,196 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::checkSuper();
|
namespace Dotclear\Plugin\dcAdvancedCleaner;
|
||||||
|
|
||||||
$ac = new dcAdvancedCleaner();
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Form,
|
||||||
|
Hidden,
|
||||||
|
Label,
|
||||||
|
Note,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Submit
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
$cleaner = false;
|
class Manage extends dcNsProcess
|
||||||
$select_menu = [];
|
{
|
||||||
foreach ($ac->get() as $k) {
|
public static function init(): bool
|
||||||
$select_menu[$k->name] = $k->id;
|
{
|
||||||
if ($k->id == $_REQUEST['part']) {
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
$cleaner = $k;
|
&& dcCore::app()->auth?->isSuperAdmin()
|
||||||
|
&& My::phpCompliant();
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!$cleaner) {
|
|
||||||
if (!($cleaner = $ac->get('caches', true))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Actions
|
public static function process(): bool
|
||||||
if (!empty($_POST['entries']) && !empty($_POST['action'])) {
|
{
|
||||||
try {
|
if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
|
||||||
foreach ($_POST['entries'] as $ns) {
|
return false;
|
||||||
$ac->set($cleaner->id, $_POST['action'], $ns);
|
|
||||||
}
|
}
|
||||||
dcAdminNotices::addSuccessNotice(__('Action successfuly excecuted'));
|
|
||||||
dcCore::app()->adminurl->redirect(
|
$vars = ManageVars::init();
|
||||||
'admin.plugin.' . basename(__DIR__),
|
|
||||||
['part' => $cleaner->id]
|
if (!empty($_POST['option-action'])) {
|
||||||
|
dcCore::app()->blog?->settings->get(My::id())->dropEvery(
|
||||||
|
'dcproperty_hide'
|
||||||
|
);
|
||||||
|
dcCore::app()->blog?->settings->get(My::id())->put(
|
||||||
|
'dcproperty_hide',
|
||||||
|
!empty($_POST['dcproperty_hide']),
|
||||||
|
'boolean',
|
||||||
|
'Hide Dotclear default properties',
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
dcPage::addSuccessNotice(__('Configuration successfuly updated'));
|
||||||
|
dcCore::app()->adminurl?->redirect(
|
||||||
|
'admin.plugin.' . My::id(),
|
||||||
|
['part' => $vars->cleaner?->id]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($vars->entries) && !empty($vars->action)) {
|
||||||
|
try {
|
||||||
|
foreach ($vars->entries as $ns) {
|
||||||
|
$vars->cleaners->execute($vars->cleaner?->id, $vars->action, $ns);
|
||||||
|
}
|
||||||
|
dcPage::addSuccessNotice(__('Action successfuly excecuted'));
|
||||||
|
dcCore::app()->adminurl?->redirect(
|
||||||
|
'admin.plugin.' . My::id(),
|
||||||
|
['part' => $vars->cleaner?->id]
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars = ManageVars::init();
|
||||||
|
|
||||||
|
dcPage::openModule(
|
||||||
|
My::name(),
|
||||||
|
dcPage::cssModuleLoad(My::id() . '/css/backend.css') .
|
||||||
|
dcPage::jsModuleLoad(My::id() . '/js/backend.js')
|
||||||
);
|
);
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Display
|
# --BEHAVIOR-- dcAdvancedCleanerAdminHeader
|
||||||
echo '<html><head><title>' . __('Advanced cleaner') . '</title>' .
|
dcCore::app()->callBehavior('dcAdvancedCleanerAdminHeader');
|
||||||
dcPage::cssLoad(dcPage::getPF(basename(__DIR__) . '/style.css')) .
|
|
||||||
dcPage::jsLoad(dcPage::getPF(basename(__DIR__) . '/js/index.js'));
|
|
||||||
|
|
||||||
# --BEHAVIOR-- dcAdvancedCleanerAdminHeader
|
|
||||||
dcCore::app()->callBehavior('dcAdvancedCleanerAdminHeader');
|
|
||||||
|
|
||||||
echo '</head><body>' .
|
|
||||||
dcPage::breadcrumb([
|
|
||||||
__('Plugins') => '',
|
|
||||||
__('Advanced cleaner') => '',
|
|
||||||
]) .
|
|
||||||
dcPage::notices() .
|
|
||||||
|
|
||||||
'<form method="get" action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)) . '" id="parts_menu">' .
|
|
||||||
'<p class="anchor-nav"><label for="part" class="classic">' . __('Goto:') . ' </label>' .
|
|
||||||
form::combo('part', $select_menu, $cleaner->id) . ' ' .
|
|
||||||
'<input type="submit" value="' . __('Ok') . '" />' .
|
|
||||||
form::hidden('p', basename(__DIR__)) . '</p>' .
|
|
||||||
'</form>' .
|
|
||||||
|
|
||||||
'<h3>' . $cleaner->name . '</h3><p>' . $cleaner->desc . '</p>';
|
|
||||||
|
|
||||||
$rs = $cleaner->get();
|
|
||||||
|
|
||||||
if (empty($rs)) {
|
|
||||||
echo '<p>' . __('There is nothing to display') . '</p>';
|
|
||||||
} else {
|
|
||||||
echo
|
|
||||||
'<form method="post" action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)) . '" id="form-funcs">' .
|
|
||||||
'<div class="table-outer">' .
|
|
||||||
'<table><caption>' . sprintf(__('There are %s %s'), count($rs), __($cleaner->id)) . '</caption><thead><tr>' .
|
|
||||||
'<th colspan="2">' . __('Name') . '</th><th>' . __('Objects') . '</th>' .
|
|
||||||
'</tr></thead><tbody>';
|
|
||||||
|
|
||||||
foreach ($rs as $k => $v) {
|
|
||||||
$offline = in_array($v['key'], $cleaner->official());
|
|
||||||
|
|
||||||
if ($offline && dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_dcproperty_hide) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
echo
|
echo
|
||||||
'<tr class="line' . ($offline ? ' offline' : '') . '">' .
|
dcPage::breadcrumb([
|
||||||
'<td class="nowrap">' .
|
__('Plugins') => '',
|
||||||
form::checkbox(
|
My::name() => '',
|
||||||
['entries[' . $k . ']', 'entries_' . $k],
|
]) .
|
||||||
html::escapeHTML($v['key'])
|
dcPage::notices();
|
||||||
) . '</td> ' .
|
|
||||||
'<td class="nowrap"><label for="entries_' . $k . '" class="classic">' . $v['key'] . '</label></td>' .
|
if ($vars->cleaner === null) {
|
||||||
'<td class="nowrap maximal">' . $v['value'] . '</td>' .
|
dcPage::closeModule();
|
||||||
'</tr>';
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
(new Form('parts_menu'))->method('get')->action(dcCore::app()->adminurl?->get('admin.plugin.' . My::id()))->fields([
|
||||||
|
(new Para())->class('anchor-nav')->items([
|
||||||
|
(new Label(__('Goto:'), Label::OUTSIDE_LABEL_BEFORE))->for('part')->class('classic'),
|
||||||
|
(new Select(['part', 'select_part']))->default($vars->cleaner->id)->items($vars->combo),
|
||||||
|
(new Submit('go'))->value(__('Ok')),
|
||||||
|
(new Hidden(['p'], My::id())),
|
||||||
|
]),
|
||||||
|
])->render() .
|
||||||
|
|
||||||
|
'<h3>' . $vars->cleaner->name . '</h3><p>' . $vars->cleaner->desc . '</p>';
|
||||||
|
|
||||||
|
$rs = $vars->cleaner->values();
|
||||||
|
|
||||||
|
if (empty($rs)) {
|
||||||
|
echo '<p>' . __('There is nothing to display') . '</p>';
|
||||||
|
} else {
|
||||||
|
$combo_actions = [];
|
||||||
|
foreach ($vars->cleaner->actions as $descriptor) {
|
||||||
|
// exception
|
||||||
|
if ($descriptor->id == 'delete_related') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$combo_actions[$descriptor->select] = $descriptor->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
'<form method="post" action="' . dcCore::app()->adminurl?->get('admin.plugin.' . My::id()) . '" id="form-funcs">' .
|
||||||
|
'<div class="table-outer">' .
|
||||||
|
'<table><caption>' . sprintf(__('There are %s entries'), count($rs)) . '</caption><thead><tr>' .
|
||||||
|
'<th colspan="2">' . __('Name') . '</th><th colspan="2">' . __('Objects') . '</th>' .
|
||||||
|
'</tr></thead><tbody>';
|
||||||
|
|
||||||
|
foreach ($rs as $k => $v) {
|
||||||
|
$distrib = in_array($v['key'], $vars->cleaner->distributed());
|
||||||
|
|
||||||
|
if ($distrib && dcCore::app()->blog?->settings->get(My::id())->get('dcproperty_hide')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
echo
|
||||||
|
'<tr class="line' . ($distrib ? ' offline' : '') . '">' .
|
||||||
|
'<td class="nowrap">' .
|
||||||
|
(new Checkbox(['entries[' . $k . ']', 'entries_' . $k]))->value(Html::escapeHTML($v['key']))->render() .
|
||||||
|
'</td> ' .
|
||||||
|
'<td class="nowrap">' .
|
||||||
|
(new Label($v['key'], Label::OUTSIDE_LABEL_AFTER))->for('entries_' . $k)->class('classic')->render() .
|
||||||
|
'</td>' .
|
||||||
|
'<td class="nowrap">' . $v['value'] . '</td>' .
|
||||||
|
'<td class="module-distrib maximal">' . ($distrib ?
|
||||||
|
'<img src="images/dotclear-leaf.svg" alt="' .
|
||||||
|
__('Values from official distribution') . '" title="' .
|
||||||
|
__('Values from official distribution') . '" />'
|
||||||
|
: '') . '</td>' .
|
||||||
|
'</tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
'</tbody></table></div>' .
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Action on selected rows:'), Label::OUTSIDE_LABEL_BEFORE))->for('select_action'),
|
||||||
|
(new Select(['action', 'select_action']))->items($combo_actions),
|
||||||
|
(new Submit('do-action'))->value(__('ok')),
|
||||||
|
(new Hidden(['p'], My::id())),
|
||||||
|
(new Hidden(['part'], $vars->cleaner->id)),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
])->render() .
|
||||||
|
'<p class="warning">' .
|
||||||
|
__('Beware: All actions done here are irreversible and are directly applied') .
|
||||||
|
'</p>' .
|
||||||
|
'</form>';
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
(new Form('option'))->method('post')->action(dcCore::app()->adminurl?->get('admin.plugin.' . My::id()))->fields([
|
||||||
|
(new Para())->items([
|
||||||
|
(new Submit('option-action'))->value(dcCore::app()->blog?->settings->get(My::id())->get('dcproperty_hide') ? __('Show Dotclear default properties') : __('Hide Dotclear default properties')),
|
||||||
|
(new Hidden('dcproperty_hide', (string) (int) !dcCore::app()->blog->settings->get(My::id())->get('dcproperty_hide'))),
|
||||||
|
(new Hidden(['p'], My::id())),
|
||||||
|
(new Hidden(['part'], $vars->cleaner->id)),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
]),
|
||||||
|
])->render();
|
||||||
|
|
||||||
|
dcPage::closeModule();
|
||||||
}
|
}
|
||||||
echo
|
|
||||||
'</tbody></table></div>' .
|
|
||||||
'<p class="field">' . __('Action on selected rows:') . ' ' .
|
|
||||||
form::combo(['action'], array_flip($cleaner->getActions())) .
|
|
||||||
'<input id="do-action" type="submit" value="' . __('ok') . '" />' .
|
|
||||||
form::hidden(['p'], basename(__DIR__)) .
|
|
||||||
form::hidden(['part'], $cleaner->id) .
|
|
||||||
dcCore::app()->formNonce() . '</p>' .
|
|
||||||
'<p class="info">' .
|
|
||||||
__('Beware: All actions done here are irreversible and are directly applied') .
|
|
||||||
'</p>' .
|
|
||||||
'</form>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dcCore::app()->blog->settings->__get(basename(__DIR__))->dcAdvancedCleaner_dcproperty_hide) {
|
|
||||||
echo '<p class="info">' .
|
|
||||||
__('Default values of Dotclear are hidden. You can change this in settings') .
|
|
||||||
'</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::helpBlock('dcAdvancedCleaner');
|
|
||||||
|
|
||||||
echo '</body></html>';
|
|
||||||
|
|
72
src/ManageVars.php
Normal file
72
src/ManageVars.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and Contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\dcAdvancedCleaner;
|
||||||
|
|
||||||
|
use Dotclear\Plugin\Uninstaller\{
|
||||||
|
AbstractCleaner,
|
||||||
|
Cleaners,
|
||||||
|
Uninstaller
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class ManageVars
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var ManageVars self instance
|
||||||
|
*/
|
||||||
|
private static $container;
|
||||||
|
|
||||||
|
public readonly Cleaners $cleaners;
|
||||||
|
public readonly ?AbstractCleaner $cleaner;
|
||||||
|
public readonly array $entries;
|
||||||
|
public readonly string $action;
|
||||||
|
public readonly array $combo;
|
||||||
|
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
$this->cleaners = Uninstaller::instance()->cleaners;
|
||||||
|
|
||||||
|
$entries = $_REQUEST['entries'] ?? [];
|
||||||
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
|
$cleaner = null;
|
||||||
|
$combo = [];
|
||||||
|
foreach ($this->cleaners->dump() as $k) {
|
||||||
|
$combo[$k->name] = $k->id;
|
||||||
|
if ($k->id == $_REQUEST['part']) {
|
||||||
|
$cleaner = $k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($cleaner === null) {
|
||||||
|
if (!($cleaner = $this->cleaners->get('caches'))) {
|
||||||
|
throw new Exception(__('Failed to load cleaner'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cleaner = $cleaner;
|
||||||
|
$this->entries = is_array($entries) ? $entries : [];
|
||||||
|
$this->action = is_string($action) ? $action : '';
|
||||||
|
$this->combo = $combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function init(): ManageVars
|
||||||
|
{
|
||||||
|
if (!(self::$container instanceof self)) {
|
||||||
|
self::$container = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$container;
|
||||||
|
}
|
||||||
|
}
|
58
src/My.php
Normal file
58
src/My.php
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief dcAdvancedCleaner, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and Contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\dcAdvancedCleaner;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin definitions
|
||||||
|
*/
|
||||||
|
class My
|
||||||
|
{
|
||||||
|
/** @var string Required php version */
|
||||||
|
public const PHP_MIN = '8.1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module id
|
||||||
|
*/
|
||||||
|
public static function id(): string
|
||||||
|
{
|
||||||
|
return basename(dirname(__DIR__));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module name
|
||||||
|
*/
|
||||||
|
public static function name(): string
|
||||||
|
{
|
||||||
|
return __((string) dcCore::app()->plugins->moduleInfo(self::id(), 'name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This plugin root
|
||||||
|
*/
|
||||||
|
public static function root(): string
|
||||||
|
{
|
||||||
|
return dirname(__DIR__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check php version
|
||||||
|
*/
|
||||||
|
public static function phpCompliant(): bool
|
||||||
|
{
|
||||||
|
return version_compare(phpversion(), self::PHP_MIN, '>=');
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,40 +10,48 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
namespace Dotclear\Plugin\dcAdvancedCleaner;
|
||||||
|
|
||||||
# dcac class
|
use dcCore;
|
||||||
Clearbricks::lib()->autoload([
|
use dcNsProcess;
|
||||||
'advancedCleaner' => __DIR__ . '/inc/class.advanced.cleaner.php',
|
|
||||||
'dcAdvancedCleaner' => __DIR__ . '/inc/class.dc.advanced.cleaner.php',
|
class Prepend extends dcNsProcess
|
||||||
'behaviorsDcAdvancedCleaner' => __DIR__ . '/inc/lib.dc.advanced.cleaner.behaviors.php',
|
{
|
||||||
'dcUninstaller' => __DIR__ . '/inc/class.dc.uninstaller.php',
|
public static function init(): bool
|
||||||
'dcAdvancedCleanerActivityReportBehaviors' => __DIR__ . '/inc/lib.dc.advanced.cleaner.activityreport.php',
|
{
|
||||||
]);
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant()
|
||||||
# cleaners class
|
&& dcCore::app()->auth?->isSuperAdmin();
|
||||||
Clearbricks::lib()->autoload([
|
|
||||||
'advancedCleanerVersions' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
return static::$init;
|
||||||
'advancedCleanerSettings' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
}
|
||||||
'advancedCleanerTables' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
|
||||||
'advancedCleanerThemes' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
public static function process(): bool
|
||||||
'advancedCleanerPlugins' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
{
|
||||||
'advancedCleanerCaches' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
if (!static::$init) {
|
||||||
'advancedCleanerVars' => __DIR__ . '/inc/lib.advanced.cleaner.php',
|
return false;
|
||||||
]);
|
}
|
||||||
|
|
||||||
dcCore::app()->addBehaviors([
|
if (defined('ACTIVITY_REPORT_V2')) {
|
||||||
'advancedCleanerAdd' => ['advancedCleanerVersions', 'create'],
|
dcCore::app()->activityReport->addGroup(
|
||||||
'advancedCleanerAdd' => ['advancedCleanerSettings', 'create'],
|
My::id(),
|
||||||
'advancedCleanerAdd' => ['advancedCleanerTables', 'create'],
|
__('Plugin dcAdvancedCleaner')
|
||||||
'advancedCleanerAdd' => ['advancedCleanerThemes', 'create'],
|
);
|
||||||
'advancedCleanerAdd' => ['advancedCleanerPlugins', 'create'],
|
|
||||||
'advancedCleanerAdd' => ['advancedCleanerCaches', 'create'],
|
dcCore::app()->activityReport->addAction(
|
||||||
'advancedCleanerAdd' => ['advancedCleanerVars', 'create'],
|
My::id(),
|
||||||
]);
|
'maintenance',
|
||||||
|
__('Maintenance'),
|
||||||
if (defined('ACTIVITY_REPORT_V2')) {
|
__('New action from dcAdvancedCleaner has been made with type="%s", action="%s", ns="%s".'),
|
||||||
dcAdvancedCleanerActivityReportBehaviors::add();
|
'dcAdvancedCleanerBeforeAction',
|
||||||
|
function ($type, $action, $ns) {
|
||||||
|
dcCore::app()->activityReport->addLog(My::id(), 'maintenance', [$type,$action, $ns]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
10
style.css
10
style.css
|
@ -1,10 +0,0 @@
|
||||||
.listDcAdvancedCleaner {
|
|
||||||
padding:10px;
|
|
||||||
margin:10px 10px 0 0;
|
|
||||||
}
|
|
||||||
.bombDcAdvancedCleaner {
|
|
||||||
padding:14px 0 2px 36px;
|
|
||||||
background:url(index.php?pf=dcAdvancedCleaner/icon-b.png) no-repeat;
|
|
||||||
}
|
|
||||||
.offline {background: url("index.php?pf=dcAdvancedCleaner/dotclear.png") no-repeat scroll 18em 7px;}
|
|
||||||
.offline label{font-weight:bold;color:#c44d58;}
|
|
Loading…
Reference in a new issue