use Tasks stack

This commit is contained in:
Jean-Christian Denis 2023-04-28 01:05:13 +02:00
parent 93ff407d4f
commit fbe10607b5
Signed by: JcDenis
GPG key ID: 1B5B8C5B90B6C951
5 changed files with 96 additions and 144 deletions

View file

@ -22,15 +22,8 @@ use Dotclear\Helper\Network\Http;
/** /**
* Improve action class helper * Improve action class helper
*
* Action class must extends class action.
* If your class signature is myActionClass extends plugins\improve\class\action,
* do dcCore::app()->addBehavior('ImproveAddAction'), ['myClass', 'create']);
* your action class is automatically created,
* then function init() of your class wil be called.
* One class must manage only one action.
*/ */
abstract class Action abstract class AbstractTask
{ {
/** @var dcModuleDefine Current module */ /** @var dcModuleDefine Current module */
protected $module; protected $module;
@ -56,6 +49,9 @@ abstract class Action
/** @var array List of allowed properties */ /** @var array List of allowed properties */
protected static $allowed_properties = ['id', 'name', 'description', 'priority', 'configurator', 'types']; protected static $allowed_properties = ['id', 'name', 'description', 'priority', 'configurator', 'types'];
/** @var bool Is disabled action */
private $disabled = false;
/** @var string Module id */ /** @var string Module id */
private $id = ''; private $id = '';
@ -79,7 +75,7 @@ abstract class Action
*/ */
final public function __construct() final public function __construct()
{ {
$this->class_name = str_replace(__NAMESPACE__ . '\\Module\\', '', get_called_class()); $this->class_name = str_replace(__NAMESPACE__ . '\\Task\\', '', get_called_class());
$this->module = new dcModuleDefine('undefined'); $this->module = new dcModuleDefine('undefined');
$settings = dcCore::app()->blog?->settings->get(My::id())->get('settings_' . $this->class_name); $settings = dcCore::app()->blog?->settings->get(My::id())->get('settings_' . $this->class_name);
@ -97,15 +93,21 @@ abstract class Action
} }
/** /**
* Helper to create an instance of a ImproveAction child class. * Set action as disabled.
*
* @param ArrayObject $list ArrayObject of actions list
*/ */
final public static function create(ArrayObject $list): void final public function disable()
{ {
$child = static::class; $this->disabled = true;
$class = new $child(); }
$list->append($class);
/**
* Check if actio is disabled.
*
* @return bool True on disabled
*/
final public function isDisabled()
{
return $this->disabled;
} }
/** /**

View file

@ -19,6 +19,7 @@ use dcCore;
use dcPage; use dcPage;
use dcFavorites; use dcFavorites;
use dcNsProcess; use dcNsProcess;
use Dotclear\App;
use Dotclear\Helper\File\Files; use Dotclear\Helper\File\Files;
/** /**
@ -56,29 +57,31 @@ class Backend extends dcNsProcess
dcCore::app()->auth->isSuperAdmin() dcCore::app()->auth->isSuperAdmin()
); );
dcCore::app()->addBehavior('adminDashboardFavoritesV2', function (dcFavorites $favs): void { dcCore::app()->addBehaviors([
$favs->register( 'adminDashboardFavoritesV2' => function (dcFavorites $favs): void {
My::id(), $favs->register(
[ My::id(),
'title' => My::name(), [
'url' => dcCore::app()->adminurl?->get('admin.plugin.' . My::id()), 'title' => My::name(),
'small-icon' => dcPage::getPF(My::id() . '/icon.svg'), 'url' => dcCore::app()->adminurl?->get('admin.plugin.' . My::id()),
'large-icon' => dcPage::getPF(My::id() . '/icon.svg'), 'small-icon' => dcPage::getPF(My::id() . '/icon.svg'),
//'permissions' => null, 'large-icon' => dcPage::getPF(My::id() . '/icon.svg'),
] //'permissions' => null,
); ]
}); );
},
$dir = __DIR__ . DIRECTORY_SEPARATOR . 'module' . DIRECTORY_SEPARATOR; // Add actions to improve
$ns = __NAMESPACE__ . '\\Module\\'; 'improveTaskAdd' => function (Tasks $actions): void {
$dir = __DIR__ . DIRECTORY_SEPARATOR . 'Task' . DIRECTORY_SEPARATOR;
dcCore::app()->autoload->addNamespace($ns, $dir); foreach (Files::scandir($dir) as $file) {
if (str_ends_with($file, '.php') && is_file($dir . $file)) {
foreach (Files::scandir($dir) as $file) { $class = __NAMESPACE__ . '\\Task\\' . basename($file, '.php');
if (str_ends_with($file, '.php') && is_file($dir . $file)) { $actions->add(new $class());
dcCore::app()->addBehavior('improveAddAction', [$ns . basename($file, '.php'), 'create']); /* @phpstan-ignore-line */ }
} }
} },
]);
return true; return true;
} }

View file

@ -93,18 +93,14 @@ class Config extends dcNsProcess
return; return;
} }
$improve = new Core(); $improve = Core::instance();
$modules = $items = []; $items = [];
$settings = dcCore::app()->blog->settings->get(My::id()); $settings = dcCore::app()->blog->settings->get(My::id());
foreach ($improve->modules() as $action) { foreach ($improve->tasks->dump() as $action) {
$modules[$action->name()] = $action->id();
}
foreach (array_merge($modules, array_flip($improve->disabled())) as $name => $id) {
$items[] = (new Para())->items([ $items[] = (new Para())->items([
(new Checkbox(['disabled[]', 'disabled_' . $id], array_key_exists($id, $improve->disabled())))->value($id), (new Checkbox(['disabled[]', 'disabled_' . $action->id()], $action->isDisabled()))->value($action->id()),
(new Label($id, Label::OUTSIDE_LABEL_AFTER))->class('classic')->for('disabled_' . $id), (new Label($action->id(), Label::OUTSIDE_LABEL_AFTER))->class('classic')->for('disabled_' . $action->id()),
]); ]);
} }

View file

@ -29,57 +29,59 @@ use Exception;
*/ */
class Core class Core
{ {
/** @var array Allowed file extensions to open */ /** @var Tasks $tasks The tasks stack instance */
public readonly Tasks $tasks;
/** @var array<int,string> $disabled Disabled tasks modules */
private $disabled = [];
/** @var array<string,array> $logs Logs by actions modules */
private $logs = [];
/** @var array<string,boolean> $has_log Has log of given type */
private $has_log = ['success' => false, 'warning' => false, 'error' => false];
/** @var array $readfile_extensions Allowed file extensions to open */
private static $readfile_extensions = [ private static $readfile_extensions = [
'php', 'xml', 'js', 'css', 'csv', 'html', 'htm', 'txt', 'md', 'po', 'php', 'xml', 'js', 'css', 'csv', 'html', 'htm', 'txt', 'md', 'po',
]; ];
/** @var array<Action> $actions Loaded actions modules */ /** @var Core $instance Core instance */
private $actions = []; private static $instance;
/** @var array<string> $disabled Disabled actions modules */
private $disabled = [];
/** @var array<string, array> $logs Logs by actions modules */
private $logs = [];
/** @var array<string, boolean> $has_log Has log of given type */
private $has_log = ['success' => false, 'warning' => false, 'error' => false];
/** /**
* Constructor * Constructor
*/ */
public function __construct() protected function __construct()
{ {
$disabled = explode(';', (string) dcCore::app()->blog?->settings->get(My::id())->get('disabled')); $this->tasks = new Tasks();
$list = new ArrayObject(); $disable = explode(';', (string) dcCore::app()->blog?->settings->get(My::id())->get('disabled'));
foreach($disable as $id) {
try { $this->tasks->get($id)?->disable();
dcCore::app()->callBehavior('improveAddAction', $list);
foreach ($list as $action) {
if (($action instanceof Action) && !isset($this->actions[$action->id()])) {
if (in_array($action->id(), $disabled)) {
$this->disabled[$action->id()] = $action->name();
} else {
$this->actions[$action->id()] = $action;
}
}
}
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
} }
uasort($this->actions, [$this, 'sortModules']);
} }
public static function id(): string protected function __clone()
{ {
return basename(dirname(__DIR__));
} }
public static function name(): string public function __wakeup()
{ {
return __((string) dcCore::app()->plugins->moduleInfo(My::id(), 'name')); throw new Exception('nope');
}
/**
* Get singleton instance.
*
* @return Core Core instance
*/
public static function instance(): Core
{
if (!is_a(self::$instance, Core::class)) {
self::$instance = new Core();
}
return self::$instance;
} }
public function getLogs(): array public function getLogs(): array
@ -151,50 +153,16 @@ class Core
return $lines; return $lines;
} }
/**
* Get a loaded action module
*
* @param string $id Module id
*
* @return Action action instance
*/
public function module(string $id): ?Action
{
if (empty($id)) {
return null;
}
return $this->actions[$id] ?? null;
}
/**
* Get all loaded action modules
*
* @return Action[] action instance
*/
public function modules(): array
{
return $this->actions;
}
/**
* Get disabled action modules
*
* @return array Array of id/name modules
*/
public function disabled(): array
{
return $this->disabled;
}
public function fixModule(dcModuleDefine $module, array $actions): float public function fixModule(dcModuleDefine $module, array $actions): float
{ {
$time_start = microtime(true); $time_start = microtime(true);
$workers = []; $workers = [];
foreach ($actions as $action) { foreach ($actions as $action) {
if (isset($this->actions[$action]) && $this->actions[$action]->isConfigured()) { if ($this->tasks->get($action)?->isConfigured()
$workers[] = $this->actions[$action]; && $this->tasks->get($action)?->isDisabled() === false
) {
$workers[] = $this->tasks->get($action);
} }
} }
foreach ($workers as $action) { foreach ($workers as $action) {
@ -330,21 +298,4 @@ class Core
return $out; return $out;
} }
/**
* Sort modules by priority then name
*
* @param Action $a ImproveAction instance
* @param Action $b ImproveAction instance
*
* @return integer Is higher
*/
private function sortModules(Action $a, Action $b): int
{
if ($a->priority() == $b->priority()) {
return strcasecmp($a->name(), $b->name());
}
return $a->priority() < $b->priority() ? -1 : 1;
}
} }

View file

@ -78,7 +78,7 @@ class Manage extends dcNsProcess
private static function getAction(): ?Action private static function getAction(): ?Action
{ {
return empty($_REQUEST['config']) ? null : self::$improve->module($_REQUEST['config']); return empty($_REQUEST['config']) ? null : self::$improve->tasks->get($_REQUEST['config']);
} }
private static function getPreference(bool $all = false): array private static function getPreference(bool $all = false): array
@ -105,8 +105,8 @@ class Manage extends dcNsProcess
$preferences = self::getPreference(true); $preferences = self::getPreference(true);
$preferences[self::$type] = []; $preferences[self::$type] = [];
if (!empty($_POST['actions'])) { if (!empty($_POST['actions'])) {
foreach (self::$improve->modules() as $action) { foreach (self::$improve->tasks->dump() as $action) {
if (in_array(self::$type, $action->types()) && in_array($action->id(), $_POST['actions'])) { if (!$action->isDisabled() && in_array(self::$type, $action->types()) && in_array($action->id(), $_POST['actions'])) {
$preferences[self::$type][] = $action->id(); $preferences[self::$type][] = $action->id();
} }
} }
@ -158,7 +158,7 @@ class Manage extends dcNsProcess
return false; return false;
} }
self::$improve = new Core(); self::$improve = Core::instance();
self::$type = self::getType(); self::$type = self::getType();
self::$module = self::getModule(); self::$module = self::getModule();
self::$action = self::getAction(); self::$action = self::getAction();
@ -288,8 +288,8 @@ class Manage extends dcNsProcess
'<th scope="col">' . __('Configuration') . '</td>' . '<th scope="col">' . __('Configuration') . '</td>' .
(DC_DEBUG ? '<th scope="col">' . __('Priority') . '</td>' : '') . /* @phpstan-ignore-line */ (DC_DEBUG ? '<th scope="col">' . __('Priority') . '</td>' : '') . /* @phpstan-ignore-line */
'</tr></thead><tbody>'; '</tr></thead><tbody>';
foreach (self::$improve->modules() as $action) { foreach (self::$improve->tasks->dump() as $action) {
if (!in_array(self::$type, $action->types())) { if ($action->isDisabled() || !in_array(self::$type, $action->types())) {
continue; continue;
} }
echo echo
@ -340,7 +340,7 @@ class Manage extends dcNsProcess
foreach ($types as $type => $tools) { foreach ($types as $type => $tools) {
echo '<div class="' . $type . '"><ul>'; echo '<div class="' . $type . '"><ul>';
foreach ($tools as $tool => $msgs) { foreach ($tools as $tool => $msgs) {
$a = self::$improve->module($tool); $a = self::$improve->tasks->get($tool);
if (null !== $a) { if (null !== $a) {
echo '<li>' . $a->name() . '<ul>'; echo '<li>' . $a->name() . '<ul>';
foreach ($msgs as $msg) { foreach ($msgs as $msg) {