use Tasks stack
This commit is contained in:
parent
93ff407d4f
commit
fbe10607b5
5 changed files with 96 additions and 144 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
131
src/Core.php
131
src/Core.php
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue