use iterable stacks

This commit is contained in:
Jean-Christian Paul Denis 2023-05-01 15:48:06 +02:00
parent 8d32477761
commit 9f2f04673b
Signed by: JcDenis
GPG Key ID: 1B5B8C5B90B6C951
19 changed files with 290 additions and 92 deletions

View File

@ -42,7 +42,7 @@ class ActionDescriptor
/** /**
* Get descriptor properties. * Get descriptor properties.
* *
* @return array<string,string> The properties * @return array<string,mixed> The properties
*/ */
public function dump(): array public function dump(): array
{ {

View File

@ -0,0 +1,79 @@
<?php
/**
* @brief Uninstaller, 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\Uninstaller;
use Countable;
use Iterator;
/**
* Cleaner actions cleaners stack.
*
* @implements Iterator<int,ActionDescriptor>
*/
class ActionsCleanersStack implements Countable, Iterator
{
/** @var array<int,ActionDescriptor> $stack The stack */
private array $stack = [];
public function exists(int $offset): bool
{
return isset($this->stack[$offset]);
}
public function get(int $offset): ?ActionDescriptor
{
return $this->stack[$offset] ?? null;
}
public function set(ActionDescriptor $value): void
{
$this->stack[] = $value;
}
public function unset(int $offset): void
{
unset($this->stack[$offset]);
}
public function rewind(): void
{
reset($this->stack);
}
public function current(): false|ActionDescriptor
{
return current($this->stack);
}
public function key(): ?int
{
return key($this->stack);
}
public function next(): void
{
next($this->stack);
}
public function valid(): bool
{
return key($this->stack) !== null;
}
public function count(): int
{
return count($this->stack);
}
}

83
src/ActionsStack.php Normal file
View File

@ -0,0 +1,83 @@
<?php
/**
* @brief Uninstaller, 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\Uninstaller;
use Countable;
use Iterator;
/**
* Cleaner actions stack.
*
* @implements Iterator<string,ActionsCleanersStack>
*/
class ActionsStack implements Countable, Iterator
{
/** @var array<string,ActionsCleanersStack> $stack The stack */
private array $stack = [];
public function exists(string $offset): bool
{
return isset($this->stack[$offset]);
}
public function get(string $offset): ActionsCleanersStack
{
if (!$this->exists($offset)) {
$this->set($offset, new ActionsCleanersStack());
}
return $this->stack[$offset];
}
public function set(string $offset, ActionsCleanersStack $value): void
{
$this->stack[$offset] = $value;
}
public function unset(string $offset): void
{
unset($this->stack[$offset]);
}
public function rewind(): void
{
reset($this->stack);
}
public function current(): false|ActionsCleanersStack
{
return current($this->stack);
}
public function key(): ?string
{
return key($this->stack);
}
public function next(): void
{
next($this->stack);
}
public function valid(): bool
{
return key($this->stack) !== null;
}
public function count(): int
{
return count($this->stack);
}
}

View File

@ -46,7 +46,7 @@ class Backend extends dcNsProcess
return ''; return '';
} }
return empty(Uninstaller::instance()->loadModules([$define])->getUserActions($define->getId())) ? '' : return !count(Uninstaller::instance()->loadModules([$define])->getUserActions($define->getId())) ? '' :
sprintf( sprintf(
' <a href="%s" class="button delete uninstall_module_button">' . __('Uninstall') . '</a>', ' <a href="%s" class="button delete uninstall_module_button">' . __('Uninstall') . '</a>',
dcCore::app()->adminurl?->get('admin.plugin.' . My::id(), ['type' => $define->get('type'), 'id' => $define->getId()]) dcCore::app()->adminurl?->get('admin.plugin.' . My::id(), ['type' => $define->get('type'), 'id' => $define->getId()])
@ -90,10 +90,10 @@ class Backend extends dcNsProcess
$done = []; $done = [];
foreach ($uninstaller->getDirectActions($define->getId()) as $cleaner => $stack) { foreach ($uninstaller->getDirectActions($define->getId()) as $cleaner => $stack) {
foreach ($stack as $action) { foreach ($stack as $action) {
if ($uninstaller->execute($cleaner, $action['action'], $action['ns'])) { if ($uninstaller->execute($cleaner, $action->id, $action->ns)) {
$done[] = $action['success']; $done[] = $action->success;
} else { } else {
dcCore::app()->error->add($action['error']); dcCore::app()->error->add($action->error);
} }
} }
} }

View File

@ -15,9 +15,9 @@ declare(strict_types=1);
namespace Dotclear\Plugin\Uninstaller\Cleaner; namespace Dotclear\Plugin\Uninstaller\Cleaner;
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
TraitCleanerDir, TraitCleanerDir,
ValueDescriptor ValueDescriptor
}; };
@ -28,7 +28,7 @@ use Dotclear\Plugin\Uninstaller\{
* It allows modules to delete an entire sub folder * It allows modules to delete an entire sub folder
* of DC_TPL_CACHE directory path. * of DC_TPL_CACHE directory path.
*/ */
class Caches extends AbstractCleaner class Caches extends CleanerParent
{ {
use TraitCleanerDir; use TraitCleanerDir;

View File

@ -21,9 +21,9 @@ use Dotclear\Database\Statement\{
SelectStatement SelectStatement
}; };
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor ValueDescriptor
}; };
@ -33,7 +33,7 @@ use Dotclear\Plugin\Uninstaller\{
* It allows modules to delete a "log_table" * It allows modules to delete a "log_table"
* of Dotclear dcLog::LOG_TABLE_NAME database table. * of Dotclear dcLog::LOG_TABLE_NAME database table.
*/ */
class Logs extends AbstractCleaner class Logs extends CleanerParent
{ {
public function __construct() public function __construct()
{ {

View File

@ -15,9 +15,9 @@ declare(strict_types=1);
namespace Dotclear\Plugin\Uninstaller\Cleaner; namespace Dotclear\Plugin\Uninstaller\Cleaner;
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor, ValueDescriptor,
TraitCleanerDir TraitCleanerDir
}; };
@ -27,7 +27,7 @@ use Dotclear\Plugin\Uninstaller\{
* *
* It allows modules to delete their own folder. * It allows modules to delete their own folder.
*/ */
class Plugins extends AbstractCleaner class Plugins extends CleanerParent
{ {
use TraitCleanerDir; use TraitCleanerDir;

View File

@ -21,9 +21,9 @@ use Dotclear\Database\Statement\{
SelectStatement SelectStatement
}; };
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor ValueDescriptor
}; };
@ -33,7 +33,7 @@ use Dotclear\Plugin\Uninstaller\{
* It allows modules to delete for users or global a preference workspace. * It allows modules to delete for users or global a preference workspace.
* It also allows to pick-up specific preference id by using delete_related action. * It also allows to pick-up specific preference id by using delete_related action.
*/ */
class Preferences extends AbstractCleaner class Preferences extends CleanerParent
{ {
public function __construct() public function __construct()
{ {

View File

@ -21,9 +21,9 @@ use Dotclear\Database\Statement\{
SelectStatement SelectStatement
}; };
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor ValueDescriptor
}; };
@ -33,7 +33,7 @@ use Dotclear\Plugin\Uninstaller\{
* It allows modules to delete for blogs or global a settings namespace. * It allows modules to delete for blogs or global a settings namespace.
* It also allows to pick-up specific setting id by using delete_related action. * It also allows to pick-up specific setting id by using delete_related action.
*/ */
class Settings extends AbstractCleaner class Settings extends CleanerParent
{ {
public function __construct() public function __construct()
{ {

View File

@ -25,9 +25,9 @@ use Dotclear\Database\Statement\{
SelectStatement SelectStatement
}; };
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor ValueDescriptor
}; };
@ -36,7 +36,7 @@ use Dotclear\Plugin\Uninstaller\{
* *
* It allows modules to delete or truncate a database table. * It allows modules to delete or truncate a database table.
*/ */
class Tables extends AbstractCleaner class Tables extends CleanerParent
{ {
public function __construct() public function __construct()
{ {

View File

@ -16,9 +16,9 @@ namespace Dotclear\Plugin\Uninstaller\Cleaner;
use dcCore; use dcCore;
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor, ValueDescriptor,
TraitCleanerDir TraitCleanerDir
}; };
@ -28,7 +28,7 @@ use Dotclear\Plugin\Uninstaller\{
* *
* It allows modules to delete their own folder. * It allows modules to delete their own folder.
*/ */
class Themes extends AbstractCleaner class Themes extends CleanerParent
{ {
use TraitCleanerDir; use TraitCleanerDir;

View File

@ -15,9 +15,9 @@ declare(strict_types=1);
namespace Dotclear\Plugin\Uninstaller\Cleaner; namespace Dotclear\Plugin\Uninstaller\Cleaner;
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
CleanerParent,
ValueDescriptor, ValueDescriptor,
TraitCleanerDir TraitCleanerDir
}; };
@ -28,7 +28,7 @@ use Dotclear\Plugin\Uninstaller\{
* It allows modules to delete an entire sub folder * It allows modules to delete an entire sub folder
* of DC_VAR directory path. * of DC_VAR directory path.
*/ */
class Vars extends AbstractCleaner class Vars extends CleanerParent
{ {
use TraitCleanerDir; use TraitCleanerDir;

View File

@ -17,7 +17,7 @@ namespace Dotclear\Plugin\Uninstaller\Cleaner;
use dcCore; use dcCore;
use Dotclear\Database\Statement\SelectStatement; use Dotclear\Database\Statement\SelectStatement;
use Dotclear\Plugin\Uninstaller\{ use Dotclear\Plugin\Uninstaller\{
AbstractCleaner, CleanerParent,
ActionDescriptor, ActionDescriptor,
CleanerDescriptor, CleanerDescriptor,
ValueDescriptor ValueDescriptor
@ -29,7 +29,7 @@ use Dotclear\Plugin\Uninstaller\{
* It allows modules to delete their versions * It allows modules to delete their versions
* from Dotclear dcCore::VERSION_TABLE_NAME database table. * from Dotclear dcCore::VERSION_TABLE_NAME database table.
*/ */
class Versions extends AbstractCleaner class Versions extends CleanerParent
{ {
public function __construct() public function __construct()
{ {

View File

@ -20,7 +20,7 @@ namespace Dotclear\Plugin\Uninstaller;
* Cleaner manages only one part of uninstall process. * Cleaner manages only one part of uninstall process.
* For exemple Settings, Caches, db, etc... * For exemple Settings, Caches, db, etc...
*/ */
abstract class AbstractCleaner abstract class CleanerParent
{ {
/** @var string $id The cleaner Id */ /** @var string $id The cleaner Id */
public readonly string $id; public readonly string $id;

View File

@ -14,62 +14,82 @@ declare(strict_types=1);
namespace Dotclear\Plugin\Uninstaller; namespace Dotclear\Plugin\Uninstaller;
use Countable;
use dcCore; use dcCore;
use Iterator;
use Exception; use Exception;
/** /**
* The cleaners stack. * The cleaners stack.
*
* @implements Iterator<string,CleanerParent>
*/ */
class Cleaners class CleanersStack implements Countable, Iterator
{ {
/** @var array<string,AbstractCleaner> $cleaners The cleaner stack */ /** @var array<string,CleanerParent> $stack The cleaner stack */
private array $cleaners = []; private array $stack = [];
/** /**
* Contructor load cleaners. * Contructor load cleaners.
*/ */
public function __construct() public function __construct()
{ {
# --BEHAVIOR-- UninstallerCleanersConstruct: Cleaners # --BEHAVIOR-- UninstallerCleanersConstruct: CleanersStack
dcCore::app()->callBehavior('UninstallerCleanersConstruct', $this); dcCore::app()->callBehavior('UninstallerCleanersConstruct', $this);
} }
/** public function exists(string $offset): bool
* Add a cleaner.
*
* @param AbstractCleaner $cleaner The cleaner instance
*
* @return Cleaners Self instance
*/
public function add(AbstractCleaner $cleaner): Cleaners
{ {
if (!isset($this->cleaners[$cleaner->id])) { return isset($this->stack[$offset]);
$this->cleaners[$cleaner->id] = $cleaner; }
public function get(string $offset): ?CleanerParent
{
return $this->stack[$offset] ?? null;
}
public function set(CleanerParent $value): CleanersStack
{
if (!isset($this->stack[$value->id])) {
$this->stack[$value->id] = $value;
} }
return $this; return $this;
} }
/** public function unset(string $offset): void
* Get all clearners.
*
* @return array<string,AbstractCleaner> The cleaners
*/
public function dump(): array
{ {
return $this->cleaners; unset($this->stack[$offset]);
} }
/** public function rewind(): void
* Get a cleaner.
*
* @param string $id The cleaner id
*
* @return null|AbstractCleaner The cleaner
*/
public function get(string $id): ?AbstractCleaner
{ {
return $this->cleaners[$id] ?? null; reset($this->stack);
}
public function current(): false|CleanerParent
{
return current($this->stack);
}
public function key(): ?string
{
return key($this->stack);
}
public function next(): void
{
next($this->stack);
}
public function valid(): bool
{
return key($this->stack) !== null;
}
public function count(): int
{
return count($this->stack);
} }
/** /**
@ -83,7 +103,7 @@ class Cleaners
*/ */
public function execute(string $id, string $action, string $ns): bool public function execute(string $id, string $action, string $ns): bool
{ {
if (!isset($this->cleaners[$id])) { if (!isset($this->stack[$id])) {
throw new Exception(sprintf(__('Unknown cleaner "%s"'), $id)); throw new Exception(sprintf(__('Unknown cleaner "%s"'), $id));
} }
if (in_array($ns, [My::id(), My::root()])) { if (in_array($ns, [My::id(), My::root()])) {
@ -93,6 +113,6 @@ class Cleaners
# --BEHAVIOR-- UninstallerBeforeAction: string, string, string # --BEHAVIOR-- UninstallerBeforeAction: string, string, string
dcCore::app()->callBehavior('UninstallerBeforeAction', $id, $action, $ns); dcCore::app()->callBehavior('UninstallerBeforeAction', $id, $action, $ns);
return $this->cleaners[$id]->execute($action, $ns); return $this->stack[$id]->execute($action, $ns);
} }
} }

View File

@ -25,6 +25,7 @@ use Dotclear\Helper\Html\Form\{
Form, Form,
Hidden, Hidden,
Label, Label,
Link,
Para, Para,
Submit, Submit,
Text Text
@ -69,7 +70,7 @@ class Manage extends dcNsProcess
// load uninstaller for selected module and check if it has action // load uninstaller for selected module and check if it has action
$uninstaller = Uninstaller::instance()->loadModules([$define]); $uninstaller = Uninstaller::instance()->loadModules([$define]);
$actions = $uninstaller->getUserActions($define->getId()); $actions = $uninstaller->getUserActions($define->getId());
if (empty($actions)) { if (!count($actions)) {
dcCore::app()->error->add(__('There are no uninstall actions for this module')); dcCore::app()->error->add(__('There are no uninstall actions for this module'));
self::doRedirect(); self::doRedirect();
} }
@ -151,12 +152,12 @@ class Manage extends dcNsProcess
} }
// submit // submit
$fields[] = (new Para())->items([ $fields[] = (new Para())->separator(' ')->items([
dcCore::app()->formNonce(false), dcCore::app()->formNonce(false),
(new Hidden(['type'], self::getType())), (new Hidden(['type'], self::getType())),
(new Hidden(['id'], $define->getId())), (new Hidden(['id'], $define->getId())),
(new Submit(['do']))->value(__('Perform selected actions'))->class('delete'), (new Submit(['do']))->value(__('Perform selected actions'))->class('delete'),
(new Text('', ' <a class="button" href="' . self::getRedirect() . '">' . __('Cancel') . '</a>')), (new Link())->class('button')->text(__('Cancel'))->href(self::getRedirect()),
]); ]);
// display form // display form

View File

@ -35,17 +35,17 @@ class Prepend extends dcNsProcess
} }
// Add cleaners to Uninstaller // Add cleaners to Uninstaller
dcCore::app()->addBehavior('UninstallerCleanersConstruct', function (Cleaners $cleaners): void { dcCore::app()->addBehavior('UninstallerCleanersConstruct', function (CleanersStack $cleaners): void {
$cleaners $cleaners
->add(new Cleaner\Settings()) ->set(new Cleaner\Settings())
->add(new Cleaner\Preferences()) ->set(new Cleaner\Preferences())
->add(new Cleaner\Tables()) ->set(new Cleaner\Tables())
->add(new Cleaner\Versions()) ->set(new Cleaner\Versions())
->add(new Cleaner\Logs()) ->set(new Cleaner\Logs())
->add(new Cleaner\Caches()) ->set(new Cleaner\Caches())
->add(new Cleaner\Vars()) ->set(new Cleaner\Vars())
->add(new Cleaner\Themes()) ->set(new Cleaner\Themes())
->add(new Cleaner\Plugins()) ->set(new Cleaner\Plugins())
; ;
}); });

View File

@ -29,8 +29,8 @@ class Uninstaller
/** @var string The Uninstall class name */ /** @var string The Uninstall class name */
public const UNINSTALL_CLASS_NAME = 'Uninstall'; public const UNINSTALL_CLASS_NAME = 'Uninstall';
/** @var Cleaners $cleaners The cleaners stack */ /** @var CleanersStack $cleaners The cleaners stack */
public readonly Cleaners $cleaners; public readonly CleanersStack $cleaners;
/** @var null|dcModuleDefine $module Current module */ /** @var null|dcModuleDefine $module Current module */
private ?dcModuleDefine $module = null; private ?dcModuleDefine $module = null;
@ -41,8 +41,11 @@ class Uninstaller
/** @var array<int,string> List of modules with custom actions render */ /** @var array<int,string> List of modules with custom actions render */
private array $renders = []; private array $renders = [];
/** @var array List of registered actions */ /** @var array<string,ActionsStack> List of registered user actions */
private array $actions = ['user' => [], 'direct' => []]; private array $user_actions = [];
/** @var array<string,ActionsStack> List of registered direct actions */
private array $direct_actions = [];
/** @var Uninstaller $uninstaller Uninstaller instance */ /** @var Uninstaller $uninstaller Uninstaller instance */
private static $uninstaller; private static $uninstaller;
@ -52,7 +55,7 @@ class Uninstaller
*/ */
public function __construct() public function __construct()
{ {
$this->cleaners = new Cleaners(); $this->cleaners = new CleanersStack();
} }
/** /**
@ -84,7 +87,8 @@ class Uninstaller
$this->module = null; $this->module = null;
$this->modules = []; $this->modules = [];
$this->renders = []; $this->renders = [];
$this->actions = ['user' => [], 'direct' => []]; $this->user_actions = [];
$this->direct_actions = [];
foreach ($modules as $module) { foreach ($modules as $module) {
if (!($module instanceof dcModuleDefine)) { if (!($module instanceof dcModuleDefine)) {
@ -138,7 +142,12 @@ class Uninstaller
*/ */
public function addUserAction(string $cleaner, string $action, string $ns): Uninstaller public function addUserAction(string $cleaner, string $action, string $ns): Uninstaller
{ {
$this->addAction('user', $cleaner, $action, $ns); if (null !== $this->module && null !== ($res = $this->addAction($cleaner, $action, $ns))) {
if (!isset($this->user_actions[$this->module->getId()])) {
$this->user_actions[$this->module->getId()] = new ActionsStack();
}
$this->user_actions[$this->module->getId()]->get($cleaner)->set($res);
}
return $this; return $this;
} }
@ -159,7 +168,12 @@ class Uninstaller
*/ */
public function addDirectAction(string $cleaner, string $action, string $ns): Uninstaller public function addDirectAction(string $cleaner, string $action, string $ns): Uninstaller
{ {
$this->addAction('direct', $cleaner, $action, $ns); if (null !== $this->module && null !== ($res = $this->addAction($cleaner, $action, $ns))) {
if (!isset($this->direct_actions[$this->module->getId()])) {
$this->direct_actions[$this->module->getId()] = new ActionsStack();
}
$this->direct_actions[$this->module->getId()]->get($cleaner)->set($res);
}
return $this; return $this;
} }
@ -169,11 +183,11 @@ class Uninstaller
* *
* @param string $id The module ID * @param string $id The module ID
* *
* @return array List module user actions group by cleaner * @return ActionsStack List module user actions group by cleaner
*/ */
public function getUserActions(string $id): array public function getUserActions(string $id): ActionsStack
{ {
return $this->actions['user'][$id] ?? []; return $this->user_actions[$id] ?? new ActionsStack();
} }
/** /**
@ -181,11 +195,11 @@ class Uninstaller
* *
* @param string $id The module ID * @param string $id The module ID
* *
* @return array List module direct actions group by cleaner * @return ActionsStack List module direct actions group by cleaner
*/ */
public function getDirectActions(string $id): array public function getDirectActions(string $id): ActionsStack
{ {
return $this->actions['direct'][$id] ?? []; return $this->direct_actions[$id] ?? new ActionsStack();
} }
/** /**
@ -240,12 +254,13 @@ class Uninstaller
/** /**
* Add a predefined action to unsintall features. * Add a predefined action to unsintall features.
* *
* @param string $group The group (user or direct)
* @param string $cleaner The cleaner ID * @param string $cleaner The cleaner ID
* @param string $action The action ID * @param string $action The action ID
* @param string $ns Name of setting related to module. * @param string $ns Name of setting related to module.
*
* @return null|ActionDescriptor The action description
*/ */
private function addAction(string $group, string $cleaner, string $action, string $ns): void private function addAction(string $cleaner, string $action, string $ns): ?ActionDescriptor
{ {
// no current module or no cleaner id or no ns or unknown cleaner action // no current module or no cleaner id or no ns or unknown cleaner action
if (null === $this->module if (null === $this->module
@ -253,11 +268,11 @@ class Uninstaller
|| empty($ns) || empty($ns)
|| !isset($this->cleaners->get($cleaner)->actions[$action]) || !isset($this->cleaners->get($cleaner)->actions[$action])
) { ) {
return; return null;
} }
// fill action properties // fill action properties
$this->actions[$group][$this->module->getId()][$cleaner][] = new ActionDescriptor( return new ActionDescriptor(
id: $action, id: $action,
ns: $ns, ns: $ns,
select: $this->cleaners->get($cleaner)->actions[$action]->select, select: $this->cleaners->get($cleaner)->actions[$action]->select,

View File

@ -17,8 +17,8 @@ namespace Dotclear\Plugin\Uninstaller;
/** /**
* Cleaner value descriptor. * Cleaner value descriptor.
* *
* Description of a value from AbstractCleaner::value() * Description of a value from CleanerParent::value()
* and AbstractCleaner::related() * and CleanerParent::related()
*/ */
class ValueDescriptor class ValueDescriptor
{ {