diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fdd4b0..c1dc69f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ dev - [ ] add module to check directory structure - [ ] add module to create full README file - [ ] write documentation of php class +- update structure to php namespace +- update php cs fixer rules to dc2.21 / php7.4 +- update phpstan to 1.1.2 0.7.1 - 2021.11.08 - Fix php < 8 _ thanks @Gvx- _ closes #5 diff --git a/_admin.php b/_admin.php index 0095e0f..e3b9222 100644 --- a/_admin.php +++ b/_admin.php @@ -10,33 +10,73 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -$core->blog->settings->addNamespace('improve'); +declare(strict_types=1); -$core->addBehavior('adminDashboardFavorites', ['ImproveBehaviors', 'adminDashboardFavorites']); +namespace plugins\improve; -$core->addBehavior('improveAddAction', ['ImproveActionDcdeprecated', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionDcstore', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionEndoffile', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionGitshields', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionLicensefile', 'create']); -//$core->addBehavior('improveAddAction', ['ImproveActionLicense', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionNewline', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionPhpcsfixer', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionPhpheader', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionPhpstan', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionTab', 'create']); -$core->addBehavior('improveAddAction', ['ImproveActionZip', 'create']); +if (!defined('DC_CONTEXT_ADMIN')) { + return; +} -$_menu['Plugins']->addItem( - __('improve'), - $core->adminurl->get('admin.plugin.improve'), - dcPage::getPF('improve/icon.png'), - preg_match('/' . preg_quote($core->adminurl->get('admin.plugin.improve')) . '(&.*)?$/', $_SERVER['REQUEST_URI']), - $core->auth->isSuperAdmin() -); +/* dotclear */ +use dcCore; +use dcPage; +use dcFavorites; -class ImproveBehaviors +/* clearbricks */ +use files; + +/* php */ +use ArrayObject; + +/** + * Improve admin class + * + * Add menu and dashboard icons, load Improve action modules. + */ +class admin { + public static function process(dcCore $core, ArrayObject $_menu): void + { + self::addSettingsNamespace($core); + self::addAdminBehaviors($core); + self::addAdminMenu($core, $_menu); + self::addImproveActions($core); + } + + private static function addSettingsNamespace(dcCore $core): void + { + $core->blog->settings->addNamespace('improve'); + } + + private static function addAdminBehaviors(dcCore $core): void + { + $core->addBehavior('adminDashboardFavorites', __NAMESPACE__ . '\admin::adminDashboardFavorites'); + } + + private static function addAdminMenu(dcCore $core, ArrayObject $_menu): void + { + $_menu['Plugins']->addItem( + __('improve'), + $core->adminurl->get('admin.plugin.improve'), + dcPage::getPF('improve/icon.png'), + preg_match('/' . preg_quote($core->adminurl->get('admin.plugin.improve')) . '(&.*)?$/', $_SERVER['REQUEST_URI']), + $core->auth->isSuperAdmin() + ); + } + + private static function addImproveActions(dcCore $core): void + { + global $__autoload; + + foreach (files::scandir(prepend::getActionsDir()) as $file) { + if (is_file(prepend::getActionsDir() . $file) && '.php' == substr($file, -4)) { + $__autoload[prepend::getActionsNS() . substr($file, 0, -4)] = prepend::getActionsDir() . $file; + $core->addBehavior('improveAddAction', [prepend::getActionsNS() . substr($file, 0, -4), 'create']); /* @phpstan-ignore-line */ + } + } + } + public static function adminDashboardFavorites(dcCore $core, dcFavorites $favs): void { $favs->register( @@ -46,8 +86,11 @@ class ImproveBehaviors 'url' => $core->adminurl->get('admin.plugin.improve'), 'small-icon' => dcPage::getPF('improve/icon.png'), 'large-icon' => dcPage::getPF('improve/icon-b.png'), - 'permissions' => null + 'permissions' => null, ] ); } } + +/* process */ +admin::process($core, $_menu); diff --git a/_config.php b/_config.php index 0a15a3e..2a4afbd 100644 --- a/_config.php +++ b/_config.php @@ -10,54 +10,105 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ +declare(strict_types=1); + +namespace plugins\improve; + if (!defined('DC_CONTEXT_ADMIN')) { return; } -# Check user perms -dcPage::checkSuper(); +/* dotclear */ +use dcCore; +use adminModulesList; +use dcPage; -$improve = new Improve($core); +/* clearbricks */ +use form; -$combo_actions = []; -foreach ($improve->modules() as $action) { - $combo_actions[$action->name()] = $action->id(); -} -$disabled = $improve->disabled(); -if (!empty($disabled)) { - $combo_actions = array_merge($combo_actions, array_flip($disabled)); -} +/* php */ +use Exception; -if (!empty($_POST['save'])) { - try { - $pdisabled = ''; - if (!empty($_POST['disabled'])) { - $pdisabled = implode(';', $_POST['disabled']); +/** + * Admin Improve configuration class + * + * Set preference for this plugin. + */ +class config +{ + /** @var dcCore $core dcCore instance */ + private $core = null; + /** @var adminModulesList $list adminModulesList instance */ + private $list = null; + /** @var improve $improve improve core instance */ + private $improve = null; + + public function __construct(dcCore $core, adminModulesList $list) + { + dcPage::checkSuper(); + + $this->core = $core; + $this->list = $list; + $this->improve = new improve($core); + + $this->saveConfig(); + $this->displayConfig(); + } + + private function getModules(): array + { + $modules = []; + foreach ($this->improve->modules() as $action) { + $modules[$action->name()] = $action->id(); } - $core->blog->settings->improve->put('disabled', $pdisabled); - $core->blog->settings->improve->put('nodetails', !empty($_POST['nodetails'])); - dcPage::addSuccessNotice(__('Configuration successfully updated')); + $modules = array_merge($modules, array_flip($this->improve->disabled())); - $core->adminurl->redirect( - 'admin.plugins', - ['module' => 'improve', 'conf' => 1, 'chk' => 1, 'redir' => $list->getRedir()] - ); - } catch (Exception $e) { - $core->error->add($e->getMessage()); + return $modules; + } + + private function saveConfig(): void + { + if (empty($_POST['save'])) { + return; + } + + try { + $pdisabled = ''; + if (!empty($_POST['disabled']) && is_array($_POST['disabled'])) { + $pdisabled = implode(';', $_POST['disabled']); + } + $this->core->blog->settings->improve->put('disabled', $pdisabled); + $this->core->blog->settings->improve->put('nodetails', !empty($_POST['nodetails'])); + + dcPage::addSuccessNotice(__('Configuration successfully updated')); + + $this->core->adminurl->redirect( + 'admin.plugins', + ['module' => 'improve', 'conf' => 1, 'chk' => 1, 'redir' => $this->list->getRedir()] + ); + } catch (Exception $e) { + $this->core->error->add($e->getMessage()); + } + } + + private function displayConfig(): void + { + echo '

' . __('List of disabled actions:') . '

'; + + foreach ($this->getModules() as $name => $id) { + echo + '

'; + } + echo + '

' . __('Options') . '

' . + '

' . + '
'; } } -echo '

' . __('List of disabled actions:') . '

'; - -foreach ($combo_actions as $name => $id) { - echo - '

'; -} -echo -'

' . __('Options') . '

' . -'

' . -'
'; +/* process */ +new config($core, $list); diff --git a/_define.php b/_define.php index 256234b..d8b7174 100644 --- a/_define.php +++ b/_define.php @@ -25,6 +25,6 @@ $this->registerModule( 'type' => 'plugin', 'support' => 'https://github.com/JcDenis/improve', 'details' => 'https://github.com/JcDenis/improve', - 'repository' => 'https://raw.githubusercontent.com/JcDenis/improve/master/dcstore.xml' + 'repository' => 'https://raw.githubusercontent.com/JcDenis/improve/master/dcstore.xml', ] ); diff --git a/_install.php b/_install.php index 8951d3b..42b12ef 100644 --- a/_install.php +++ b/_install.php @@ -10,66 +10,118 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ +declare(strict_types=1); + +namespace plugins\improve; + if (!defined('DC_CONTEXT_ADMIN')) { - return null; + return; } -# -- Module specs -- +/* dotclear */ +use dcCore; +use dcUtils; -$dc_min = '2.19'; -$mod_id = 'improve'; -$mod_conf = [ - [ +/* php */ +use Exception; + +/** + * Improve install class + * + * Set default settings and version + * and manage changes on updates. + */ +class install +{ + /** @var string Dotclear minimal version */ + private static $dotclear_version = '2.19'; + /** @var array Improve default settings */ + private static $default_settings = [[ 'disabled', 'List of hidden action modules', 'tab;newline;endoffile', - 'string' - ] -]; + 'string', + ]]; -# -- Nothing to change below -- + public static function process(dcCore $core): ?bool + { + if (!self::checkModuleVersion($core)) { + return null; + } + if (!self::checkDotclearVersion($core)) { + throw new Exception(sprintf( + '%s requires Dotclear %s', + 'improve', + self::$dotclear_version + )); + } -try { + $core->blog->settings->addNamespace('improve'); + self::update_0_8_0($core); + self::putSettings($core); + self::setVersion($core); - # Check module version - if (version_compare( - $core->getVersion($mod_id), - $core->plugins->moduleInfo($mod_id, 'version'), - '>=' - )) { - return null; + return true; } - # Check Dotclear version - if (!method_exists('dcUtils', 'versionsCompare') - || dcUtils::versionsCompare(DC_VERSION, $dc_min, '<', false)) { - throw new Exception(sprintf( - '%s requires Dotclear %s', - $mod_id, - $dc_min - )); + private static function getInstalledVersion(dcCore $core): string + { + $version = $core->getVersion('improve'); + + return is_string($version) ? $version : '0'; } - # Set module settings - $core->blog->settings->addNamespace($mod_id); - foreach ($mod_conf as $v) { - $core->blog->settings->{$mod_id}->put( - $v[0], - $v[2], - $v[3], - $v[1], - false, - true + private static function checkModuleVersion(dcCore $core): bool + { + return version_compare( + self::getInstalledVersion($core), + $core->plugins->moduleInfo('improve', 'version'), + '<' ); } - # Set module version - $core->setVersion( - $mod_id, - $core->plugins->moduleInfo($mod_id, 'version') - ); + private static function checkDotclearVersion(dcCore $core): bool + { + return method_exists('dcUtils', 'versionsCompare') + && dcUtils::versionsCompare(DC_VERSION, self::$dotclear_version, '>=', false); + } - return true; + private static function putSettings(dcCore $core): void + { + foreach (self::$default_settings as $v) { + $core->blog->settings->improve->put( + $v[0], + $v[2], + $v[3], + $v[1], + false, + true + ); + } + } + + private static function setVersion(dcCore $core): void + { + $core->setVersion('improve', $core->plugins->moduleInfo('improve', 'version')); + } + + /** Update improve < 0.8 : action modules settings name */ + private static function update_0_8_0(dcCore $core): void + { + if (version_compare(self::getInstalledVersion($core), '0.8', '<')) { + foreach ($core->blog->settings->improve->dumpGlobalSettings() as $id => $values) { + $newId = str_replace('ImproveAction', '', $id); + if ($id != $newId) { + $core->blog->settings->improve->rename($id, strtolower($newId)); + } + } + } + } +} + +/* process */ +try { + return install::process($core); } catch (Exception $e) { $core->error->add($e->getMessage()); diff --git a/_prepend.php b/_prepend.php index 1a8ad7d..ab40098 100644 --- a/_prepend.php +++ b/_prepend.php @@ -10,27 +10,38 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_RC_PATH')) { +declare(strict_types=1); + +namespace plugins\improve; + +if (!defined('DC_RC_PATH') || !defined('DC_CONTEXT_ADMIN')) { return; } -$improve_libs = [ - 'Improve' => 'class.improve.php', - 'ImproveAction' => 'class.improve.action.php', +/** + * Improve prepend class + * + * Manage autoload and some action module helpers. + */ +class prepend +{ + public static function process(array &$__autoload): void + { + foreach (['improve', 'action', 'module'] as $class) { + $__autoload['plugins\\improve\\' . $class] = dirname(__FILE__) . '/inc/core/' . $class . '.php'; + } + } - 'ImproveActionDcdeprecated' => 'lib.improve.action.dcdeprecated.php', - 'ImproveActionDcstore' => 'lib.improve.action.dcstore.php', - 'ImproveActionEndoffile' => 'lib.improve.action.php', - 'ImproveActionGitshields' => 'lib.improve.action.gitshields.php', - 'ImproveActionLicensefile' => 'lib.improve.action.licensefile.php', - 'ImproveActionNewline' => 'lib.improve.action.php', - 'ImproveActionPhpcsfixer' => 'lib.improve.action.phpcsfixer.php', - 'ImproveActionPhpheader' => 'lib.improve.action.phpheader.php', - 'ImproveActionPhpstan' => 'lib.improve.action.phpstan.php', - 'ImproveActionTab' => 'lib.improve.action.php', - 'ImproveActionZip' => 'lib.improve.action.zip.php', - 'ImproveZipFileZip' => 'lib.improve.action.zip.php' -]; -foreach ($improve_libs as $class => $file) { - $__autoload[$class] = dirname(__FILE__) . '/inc/' . $file; + public static function getActionsDir(): string + { + return dirname(__FILE__) . '/inc/module/'; + } + + public static function getActionsNS(): string + { + return 'plugins\\improve\\module\\'; + } } + +/* process */ +prepend::process($__autoload); diff --git a/inc/class.improve.action.php b/inc/core/action.php similarity index 94% rename from inc/class.improve.action.php rename to inc/core/action.php index 5940c87..58daeeb 100644 --- a/inc/class.improve.action.php +++ b/inc/core/action.php @@ -10,23 +10,31 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ +declare(strict_types=1); + +namespace plugins\improve; + +/* dotclear */ +use dcCore; +use dcPage; + +/* clearbricks */ +use http; + +/* php */ +use arrayObject; + /** - * @brief Plugin improve action class + * Improve action class helper * - * Action class must extends class ImproveAction. - * If your class signature is myActionClass extends ImproveAction, + * Action class must extends class action. + * If your class signature is myActionClass extends plugins\improve\class\action, * do $core->addBehavior('ImproveAddAction'), ['myClass', 'create']); - * yoru action class is automatically created, + * your action class is automatically created, * then function init() of your class wil be called. * One class must manage only one action. - * - * @package Plugin_improve - * @subpackage Action - * - * @copyright Jean-Christian Denis - * @copyright GPL-2.0-only */ -abstract class ImproveAction +abstract class action { /** @var dcCore dcCore instance */ protected $core; @@ -74,16 +82,19 @@ abstract class ImproveAction private $types = ['plugin']; /** - * ImproveAction constructor inits properpties and settings of a child class. + * Action constructor inits properties and settings of a child class. * * @param dcCore $core dcCore instance */ final public function __construct(dcCore $core) { $this->core = $core; - $this->class_name = get_called_class(); + $this->class_name = str_replace(prepend::getActionsNS(), '', get_called_class()); - $settings = @unserialize($core->blog->settings->improve->get('settings_' . $this->class_name)); + $settings = $core->blog->settings->improve->get('settings_' . $this->class_name); + if (null != $settings) { + $settings = unserialize($settings); + } $this->settings = is_array($settings) ? $settings : []; $this->init(); diff --git a/inc/class.improve.php b/inc/core/improve.php similarity index 59% rename from inc/class.improve.php rename to inc/core/improve.php index d42c4da..2a327d0 100644 --- a/inc/class.improve.php +++ b/inc/core/improve.php @@ -10,29 +10,44 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ +declare(strict_types=1); + +namespace plugins\improve; + +/* dotclear */ +use dcCore; + +/* clearbricks */ +use path; +use files; + +/* php */ +use arrayObject; +use Exception; + /** - * This class manage all actions sub-class + * Improve main class */ -class Improve +class improve { /** @var array Allowed file extensions to open */ - public static $readfile_extensions = [ - 'php', 'xml', 'js', 'css', 'csv', 'html', 'htm', 'txt', 'md' + private static $readfile_extensions = [ + 'php', 'xml', 'js', 'css', 'csv', 'html', 'htm', 'txt', 'md', ]; - /** @var dcCore dcCore instance */ + /** @var dcCore $core dcCore instance */ private $core; - /** @var ImproveAction[] Loaded actions modules */ + /** @var array $actions Loaded actions modules */ private $actions = []; - /** @var array Disabled actions modules */ + /** @var array $disabled Disabled actions modules */ private $disabled = []; - /** @var array Logs by actions modules */ + /** @var array $logs Logs by actions modules */ private $logs = []; - /** @var array Has log of given type */ + /** @var array $has_log Has log of given type */ private $has_log = ['success' => false, 'warning' => false, 'error' => false]; /** @@ -42,7 +57,6 @@ class Improve */ public function __construct(dcCore $core) { - $core->blog->settings->addNamespace('improve'); $this->core = &$core; $disabled = explode(';', (string) $core->blog->settings->improve->disabled); $list = new arrayObject(); @@ -51,7 +65,7 @@ class Improve $this->core->callBehavior('improveAddAction', $list, $this->core); foreach ($list as $action) { - if (is_a($action, 'ImproveAction') && !isset($this->actions[$action->id()])) { + if ($action instanceof action && !isset($this->actions[$action->id()])) { if (in_array($action->id(), $disabled)) { $this->disabled[$action->id()] = $action->name(); } else { @@ -75,10 +89,10 @@ class Improve return array_key_exists($type, $this->has_log) && $this->has_log[$type]; } - public function writeLogs(): string + public function writeLogs(): int { if (empty($this->logs)) { - return ''; + return 0; } $cur = $this->core->con->openCursor($this->core->prefix . 'log'); $cur->log_msg = serialize($this->logs); @@ -140,9 +154,9 @@ class Improve * * @param string $id Module id * - * @return ImproveAction ImproveAction instance + * @return action action instance */ - public function module(string $id): ?ImproveAction + public function module(string $id): ?action { if (empty($id)) { return null; @@ -154,7 +168,7 @@ class Improve /** * Get all loaded action modules * - * @return ImproveAction[] ImproveAction instance + * @return action[] action instance */ public function modules(): array { @@ -174,7 +188,7 @@ class Improve public function fixModule(string $type, string $id, array $properties, array $actions): float { $time_start = microtime(true); - $module = ImproveDefinition::clean($type, $id, $properties); + $module = module::clean($type, $id, $properties); $workers = []; foreach ($actions as $action) { @@ -324,12 +338,12 @@ class Improve /** * Sort modules by priority then name * - * @param ImproveAction $a ImproveAction instance - * @param ImproveAction $b ImproveAction instance + * @param action $a ImproveAction instance + * @param action $b ImproveAction instance * * @return integer Is higher */ - private function sortModules(ImproveAction $a, ImproveAction $b): int + private function sortModules(action $a, action $b): int { if ($a->priority() == $b->priority()) { return strcasecmp($a->name(), $b->name()); @@ -338,176 +352,3 @@ class Improve return $a->priority() < $b->priority() ? -1 : 1; } } - -class ImproveDefinition -{ - /** @var array Current module properties */ - private $properties = []; - - /** - * Constructor - * - * @param string $type Module type, plugin or theme - * @param string $id Module id - * @param array $properties Module properties - */ - public function __construct(string $type, string $id, array $properties = []) - { - $this->loadDefine($id, $properties['root']); - $this->properties = array_merge($this->properties, self::sanitizeModule($type, $id, $properties)); - } - - /** - * Get module properties - * - * @return array The properties - */ - public function get(): array - { - return $this->properties; - } - - /** - * Get clean properties of registered module - * - * @param string $type Module type, plugin or theme - * @param string $id Module id - * @param array $properties Module properties - * - * @return array Module properties - */ - public static function clean(string $type, string $id, array $properties): array - { - $p = new self($type, $id, $properties); - - return $p->get(); - } - - /** - * Replicate dcModule::loadDefine - * - * @param string $id Module id - * @param string $root Module path - * - * @return boolean Success - */ - private function loadDefine(string $id, string $root): bool - { - if (file_exists($root . '/_define.php')) { - ob_start(); - require $root . '/_define.php'; - ob_end_clean(); - } - - return true; - } - - /** - * Replicate dcModule::registerModule - * - * @param string $name The module name - * @param string $desc The module description - * @param string $author The module author - * @param string $version The module version - * @param string|array $properties The properties - * - * @return boolean Success - */ - private function registerModule(string $name, string $desc, string $author, string $version, $properties = []): bool - { - if (!is_array($properties)) { - $args = func_get_args(); - $properties = []; - if (isset($args[4])) { - $properties['permissions'] = $args[4]; - } - if (isset($args[5])) { - $properties['priority'] = (int) $args[5]; - } - } - - $this->properties = array_merge( - [ - 'permissions' => null, - 'priority' => 1000, - 'standalone_config' => false, - 'type' => null, - 'enabled' => true, - 'requires' => [], - 'settings' => [], - 'repository' => '' - ], - $properties - ); - - return true; - } - - /** - * Replicate adminModulesList::sanitizeModule - * - * @param string $type Module type - * @param string $id Module id - * @param array $properties Module properties - * - * @return array Sanitized module properties - */ - public static function sanitizeModule(string $type, string $id, array $properties): array - { - $label = empty($properties['label']) ? $id : $properties['label']; - $name = __(empty($properties['name']) ? $label : $properties['name']); - $oname = empty($properties['name']) ? $label : $properties['name']; - - return array_merge( - # Default values - [ - 'desc' => '', - 'author' => '', - 'version' => 0, - 'current_version' => 0, - 'root' => '', - 'root_writable' => false, - 'permissions' => null, - 'parent' => null, - 'priority' => 1000, - 'standalone_config' => false, - 'support' => '', - 'section' => '', - 'tags' => '', - 'details' => '', - 'sshot' => '', - 'score' => 0, - 'type' => null, - 'requires' => [], - 'settings' => [], - 'repository' => '', - 'dc_min' => 0 - ], - # Module's values - $properties, - # Clean up values - [ - 'id' => $id, - 'sid' => self::sanitizeString($id), - 'type' => $type, - 'label' => $label, - 'name' => $name, - 'oname' => $oname, - 'sname' => self::sanitizeString($name), - 'sroot' => path::real($properties['root']) - ] - ); - } - - /** - * Replicate adminModulesList::sanitizeString - * - * @param string $str String to sanitize - * - * @return string Sanitized string - */ - public static function sanitizeString(string $str): string - { - return (string) preg_replace('/[^A-Za-z0-9\@\#+_-]/', '', strtolower($str)); - } -} diff --git a/inc/core/module.php b/inc/core/module.php new file mode 100644 index 0000000..ff256b4 --- /dev/null +++ b/inc/core/module.php @@ -0,0 +1,198 @@ +loadDefine($id, $properties['root']); + $this->properties = array_merge($this->properties, self::sanitizeModule($type, $id, $properties)); + } + + /** + * Get module properties + * + * @return array The properties + */ + public function get(): array + { + return $this->properties; + } + + /** + * Get clean properties of registered module + * + * @param string $type Module type, plugin or theme + * @param string $id Module id + * @param array $properties Module properties + * + * @return array Module properties + */ + public static function clean(string $type, string $id, array $properties): array + { + $module = new self($type, $id, $properties); + + return $module->get(); + } + + /** + * Replicate dcModule::loadDefine + * + * @param string $id Module id + * @param string $root Module path + * + * @return boolean Success + */ + private function loadDefine(string $id, string $root): bool + { + if (file_exists($root . '/_define.php')) { + ob_start(); + require $root . '/_define.php'; + ob_end_clean(); + } + + return true; + } + + /** + * Replicate dcModule::registerModule + * + * @param string $name The module name + * @param string $desc The module description + * @param string $author The module author + * @param string $version The module version + * @param string|array $properties The properties + * + * @return boolean Success + * @phpstan-ignore-next-line + */ + private function registerModule(string $name, string $desc, string $author, string $version, $properties = []): bool + { + if (!is_array($properties)) { + $args = func_get_args(); + $properties = []; + if (isset($args[4])) { + $properties['permissions'] = $args[4]; + } + if (isset($args[5])) { + $properties['priority'] = (int) $args[5]; + } + } + + $this->properties = array_merge( + [ + 'permissions' => null, + 'priority' => 1000, + 'standalone_config' => false, + 'type' => null, + 'enabled' => true, + 'requires' => [], + 'settings' => [], + 'repository' => '', + ], + $properties + ); + + return true; + } + + /** + * Replicate adminModulesList::sanitizeModule + * + * @param string $type Module type + * @param string $id Module id + * @param array $properties Module properties + * + * @return array Sanitized module properties + */ + public static function sanitizeModule(string $type, string $id, array $properties): array + { + $label = empty($properties['label']) ? $id : $properties['label']; + $name = __(empty($properties['name']) ? $label : $properties['name']); + $oname = empty($properties['name']) ? $label : $properties['name']; + + return array_merge( + # Default values + [ + 'desc' => '', + 'author' => '', + 'version' => 0, + 'current_version' => 0, + 'root' => '', + 'root_writable' => false, + 'permissions' => null, + 'parent' => null, + 'priority' => 1000, + 'standalone_config' => false, + 'support' => '', + 'section' => '', + 'tags' => '', + 'details' => '', + 'sshot' => '', + 'score' => 0, + 'type' => null, + 'requires' => [], + 'settings' => [], + 'repository' => '', + 'dc_min' => 0, + ], + # Module's values + $properties, + # Clean up values + [ + 'id' => $id, + 'sid' => self::sanitizeString($id), + 'type' => $type, + 'label' => $label, + 'name' => $name, + 'oname' => $oname, + 'sname' => self::sanitizeString($name), + 'sroot' => path::real($properties['root']), + ] + ); + } + + /** + * Replicate adminModulesList::sanitizeString + * + * @param string $str String to sanitize + * + * @return string Sanitized string + */ + public static function sanitizeString(string $str): string + { + return (string) preg_replace('/[^A-Za-z0-9\@\#+_-]/', '', strtolower($str)); + } +} diff --git a/inc/lib.improve.action.php b/inc/lib.improve.action.php deleted file mode 100644 index da54745..0000000 --- a/inc/lib.improve.action.php +++ /dev/null @@ -1,181 +0,0 @@ -setProperties([ - 'id' => 'tab', - 'name' => __('Tabulations'), - 'description' => __('Replace tabulation by four space in php files'), - 'priority' => 820, - 'types' => ['plugin', 'theme'] - ]); - - return true; - } - - public function readFile(&$content): ?bool - { - if (!in_array($this->path_extension, ['php', 'md'])) { - return null; - } - $clean = preg_replace('/(\t)/', ' ', $content);// . "\n"; - if ($content != $clean) { - $this->setSuccess(__('Replace tabulation by spaces')); - $content = $clean; - } - - return true; - } - - public function isConfigured(): bool - { - return true; - } -} - -class ImproveActionNewline extends ImproveAction -{ - protected function init(): bool - { - $this->setProperties([ - 'id' => 'newline', - 'name' => __('Newlines'), - 'description' => __('Replace bad and repetitive and empty newline by single newline in files'), - 'priority' => 840, - 'configurator' => true, - 'types' => ['plugin', 'theme'] - ]); - /* - $ext = @unserialize($this->core->blog->settings->improve->newline_extensions); - $ext = Improve::cleanExtensions($ext); - if (!empty($ext)) { - $this->extensions = $ext; - } - */ - return true; - } - - public function isConfigured(): bool - { - return !empty($this->getSetting('extensions')); - } - - public function configure($url): ?string - { - if (!empty($_POST['save']) && !empty($_POST['newline_extensions'])) { - $this->setSettings( - 'extensions', - Improve::cleanExtensions($_POST['newline_extensions']) - ); - $this->redirect($url); - } - - $ext = $this->getSetting('extensions'); - if (!is_array($ext)) { - $ext = []; - } - - return - '

' . - __('Use comma separated list of extensions without dot, recommand "php,js,xml,txt,md".') . - '

'; - } - - public function readFile(string &$content): ?bool - { - $ext = $this->getSetting('extensions'); - if (!is_array($ext) || !in_array($this->path_extension, $ext)) { - return null; - } - $clean = (string) preg_replace( - '/(\n\s+\n)/', - "\n\n", - (string) preg_replace( - '/(\n\n+)/', - "\n\n", - (string) str_replace( - ["\r\n", "\r"], - "\n", - $content - ) - ) - ); - if ($content != $clean) { - $this->setSuccess(__('Replace bad new lines')); - $content = $clean; - } - - return true; - } -} - -class ImproveActionEndoffile extends ImproveAction -{ - protected function init(): bool - { - $this->setProperties([ - 'id' => 'endoffile', - 'name' => __('End of files'), - 'description' => __('Remove php tag and empty lines from end of files'), - 'priority' => 860, - 'configurator' => true, - 'types' => ['plugin', 'theme'] - ]); - - return true; - } - - public function isConfigured(): bool - { - return true; - } - - public function configure($url): ?string - { - if (!empty($_POST['save'])) { - $this->setSettings('psr2', !empty($_POST['endoffile_psr2'])); - $this->redirect($url); - } - - return - '

' . - __('PSR2 must have a blank line, whereas PSR12 must not.') . - '

'; - } - - public function readFile(&$content): ?bool - { - if (!in_array($this->path_extension, ['php', 'md'])) { - return null; - } - $clean = preg_replace( - ['/(\s*)(\?>\s*)$/', '/\n+$/'], - '', - $content - ) . ($this->getSetting('psr2') ? "\n" : ''); - if ($content != $clean) { - $this->setSuccess(__('Replace end of file')); - $content = $clean; - } - - return true; - } -} diff --git a/inc/lib.improve.action.dcdeprecated.php b/inc/module/dcdeprecated.php similarity index 92% rename from inc/lib.improve.action.dcdeprecated.php rename to inc/module/dcdeprecated.php index cbaa528..1e362ea 100644 --- a/inc/lib.improve.action.dcdeprecated.php +++ b/inc/module/dcdeprecated.php @@ -10,7 +10,17 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionDcdeprecated extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/** + * Improve action module Dotclear depreciated + */ +class dcdeprecated extends action { /** @var array Deprecated functions [filetype [pattern, deprecated, replacement, version]] */ private static $deprecated = [ @@ -44,7 +54,7 @@ class ImproveActionDcdeprecated extends ImproveAction ['adminPostForm[^I]', 'adminPostForm', 'adminPostFormItems'], ['adminPostFormSidebar', 'adminPostFormSidebar', 'adminPostFormItems'], - ['three-cols', 'three-cols', 'three-boxes', '2.6'] + ['three-cols', 'three-cols', 'three-boxes', '2.6'], ], 'js' => [ ['\sstoreLocalData', 'storeLocalData', 'dotclear.storeLocalData'], @@ -55,8 +65,8 @@ class ImproveActionDcdeprecated extends ImproveAction ['\smergeDeep', 'mergeDeep', 'dotclear.mergeDeep'], ['\sgetCookie', 'getCookie', 'dotclear.getCookie'], ['\ssetCookie', 'setCookie', 'dotclear.setCookie'], - ['\sdeleteCookie', 'deleteCookie', 'dotclear.deleteCookie'] - ] + ['\sdeleteCookie', 'deleteCookie', 'dotclear.deleteCookie'], + ], ]; protected function init(): bool @@ -66,7 +76,7 @@ class ImproveActionDcdeprecated extends ImproveAction 'name' => __('Dotclear deprecated'), 'description' => __('Search for use of deprecated Dotclear functions'), 'priority' => 520, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); return true; diff --git a/inc/lib.improve.action.dcstore.php b/inc/module/dcstore.php similarity index 89% rename from inc/lib.improve.action.dcstore.php rename to inc/module/dcstore.php index b77173d..6414fcc 100644 --- a/inc/lib.improve.action.dcstore.php +++ b/inc/module/dcstore.php @@ -10,8 +10,31 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionDcstore extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* clearbricks */ +use form; +use files; +use text; +use xmlTag; +use DOMDocument; + +/* php */ +use Exception; + +/** + * Improve action module dcstore.xml + */ +class dcstore extends action { + /** @var string Settings dcstore zip url pattern */ + private $pattern = ''; + protected function init(): bool { $this->setProperties([ @@ -20,9 +43,12 @@ class ImproveActionDcstore extends ImproveAction 'description' => __('Re-create dcstore.xml file according to _define.php variables'), 'priority' => 420, 'configurator' => true, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); + $pattern = $this->getSetting('pattern'); + $this->pattern = is_string($pattern) ? $pattern : ''; + return true; } @@ -42,7 +68,7 @@ class ImproveActionDcstore extends ImproveAction '

' . __('File will be overwritten if it exists') . '

' . '

' . + form::field('dcstore_pattern', 160, 255, $this->pattern) . '' . '

' . '

' . sprintf(__('You can use wildcards %s'), '%author%, %type%, %id%, %version%.') . @@ -187,25 +213,20 @@ class ImproveActionDcstore extends ImproveAction private function parseFilePattern(): string { - $str = $this->getSetting('pattern'); - if (!is_string($str)) { - return ''; - } - return text::tidyURL(str_replace( [ '%type%', '%id%', '%version%', - '%author%' + '%author%', ], [ $this->module['type'], $this->module['id'], $this->module['version'], - $this->module['author'] + $this->module['author'], ], - $str + $this->pattern )); } } diff --git a/inc/module/endoffile.php b/inc/module/endoffile.php new file mode 100644 index 0000000..96c2b25 --- /dev/null +++ b/inc/module/endoffile.php @@ -0,0 +1,80 @@ +setProperties([ + 'id' => 'endoffile', + 'name' => __('End of files'), + 'description' => __('Remove php tag and empty lines from end of files'), + 'priority' => 860, + 'configurator' => true, + 'types' => ['plugin', 'theme'], + ]); + + return true; + } + + public function isConfigured(): bool + { + return true; + } + + public function configure($url): ?string + { + if (!empty($_POST['save'])) { + $this->setSettings('psr2', !empty($_POST['endoffile_psr2'])); + $this->redirect($url); + } + + return + '

' . + __('PSR2 must have a blank line, whereas PSR12 must not.') . + '

'; + } + + public function readFile(&$content): ?bool + { + if (!in_array($this->path_extension, ['php', 'md'])) { + return null; + } + $clean = preg_replace( + ['/(\s*)(\?>\s*)$/', '/\n+$/'], + '', + $content + ) . ($this->getSetting('psr2') ? "\n" : ''); + if ($content != $clean) { + $this->setSuccess(__('Replace end of file')); + $content = $clean; + } + + return true; + } +} diff --git a/inc/lib.improve.action.gitshields.php b/inc/module/gitshields.php similarity index 83% rename from inc/lib.improve.action.gitshields.php rename to inc/module/gitshields.php index eba9080..3bafafd 100644 --- a/inc/lib.improve.action.gitshields.php +++ b/inc/module/gitshields.php @@ -10,8 +10,27 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionGitshields extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* clearbricks */ +use form; + +/** + * Improve action module Github shields.io + */ +class gitshields extends action { + /** @var string Username of git repo */ + private $username = ''; + + /** @var boolean add Dotaddict shield */ + private $dotaddict = false; + /** @var boolean Stop scaning files */ private $stop_scan = false; @@ -21,7 +40,7 @@ class ImproveActionGitshields extends ImproveAction /** @var array Search patterns */ protected $bloc_pattern = [ 'remove' => '/\[!\[Release(.*)LICENSE\)/ms', - 'target' => '/^([^\n]+)[\r\n|\n]{1,}/ms' + 'target' => '/^([^\n]+)[\r\n|\n]{1,}/ms', ]; /** @var array Shields patterns */ @@ -31,7 +50,7 @@ class ImproveActionGitshields extends ImproveAction 'issues' => '[![Issues](https://img.shields.io/github/issues/%username%/%module%)](https://github.com/%username%/%module%/issues)', 'dotclear' => '[![Dotclear](https://img.shields.io/badge/dotclear-v%dotclear%-blue.svg)](https://fr.dotclear.org/download)', 'dotaddict' => '[![Dotaddict](https://img.shields.io/badge/dotaddict-official-green.svg)](https://%type%s.dotaddict.org/dc2/details/%module%)', - 'license' => '[![License](https://img.shields.io/github/license/%username%/%module%)](https://github.com/%username%/%module%/blob/master/LICENSE)' + 'license' => '[![License](https://img.shields.io/github/license/%username%/%module%)](https://github.com/%username%/%module%/blob/master/LICENSE)', ]; protected function init(): bool @@ -42,9 +61,13 @@ class ImproveActionGitshields extends ImproveAction 'description' => __('Add and maintain shields.io badges to the REDAME.md file'), 'priority' => 380, 'configurator' => true, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); + $username = $this->getSetting('username'); + $this->username = is_string($username) ? $username : ''; + $this->dotaddict = (bool) $this->getSetting('dotaddict'); + return true; } @@ -58,19 +81,19 @@ class ImproveActionGitshields extends ImproveAction if (!empty($_POST['save']) && !empty($_POST['username'])) { $this->setSettings([ 'username' => (string) $_POST['username'], - 'dotaddict' => !empty($_POST['dotaddict']) + 'dotaddict' => !empty($_POST['dotaddict']), ]); $this->redirect($url); } return '

' . - form::field('username', 60, 100, $this->getSetting('username')) . ' + form::field('username', 60, 100, $this->username) . '

' . __('Used in your Github URL: http://github.com/username/module_id.') . '
' . __('If you have badges not created by this tool in the README.md file you should remove them manually.') . '

' . __('If your plugin or theme is on Dotaddict, you can add a badge to link to its details in Dotaddict.') . '

'; } @@ -99,7 +122,7 @@ class ImproveActionGitshields extends ImproveAction { $blocs = []; foreach ($this->bloc_content as $k => $v) { - if ($k == 'dotaddict' && empty($this->getSetting('dotaddict'))) { + if ($k == 'dotaddict' && !$this->dotaddict) { continue; } $blocs[$k] = trim(str_replace( @@ -108,14 +131,14 @@ class ImproveActionGitshields extends ImproveAction '%module%', '%dotclear%', '%type%', - "\r\n", "\n" + "\r\n", "\n", ], [ - $this->getSetting('username'), + $this->username, $this->module['id'], $dotclear = $this->getDotclearVersion(), $this->module['type'], - '', '' + '', '', ], $v )); diff --git a/inc/lib.improve.action.licensefile.php b/inc/module/licensefile.php similarity index 90% rename from inc/lib.improve.action.licensefile.php rename to inc/module/licensefile.php index bc6f180..3063ec3 100644 --- a/inc/lib.improve.action.licensefile.php +++ b/inc/module/licensefile.php @@ -10,13 +10,30 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionLicensefile extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* clearbricks */ +use form; +use files; + +/* php */ +use Exception; + +/** + * Improve action module license file + */ +class licensefile extends action { /** @var array Possible license filenames */ protected static $license_filenames = [ 'license', 'license.md', - 'license.txt' + 'license.txt', ]; /** @var array Possible license names */ @@ -33,21 +50,21 @@ class ImproveActionLicensefile extends ImproveAction 'description' => __('Add or remove full license file to module root'), 'priority' => 330, 'configurator' => true, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); $this->action_version = [ __('no version selected') => '', __('gpl2 - GNU General Public License v2') => 'gpl2', __('gpl3 - GNU General Public License v3') => 'gpl3', __('lgpl3 - GNU Lesser General Public License v3') => 'lgpl3', - __('Massachusetts Institute of Technolog mit') => 'mit' + __('Massachusetts Institute of Technolog mit') => 'mit', ]; $this->action_full = [ __('Do nothing') => 0, __('Add file if it does not exist') => 'create', __('Add file even if it exists') => 'overwrite', __('Add file and remove others') => 'full', - __('Remove license files') => 'remove' + __('Remove license files') => 'remove', ]; return true; @@ -63,7 +80,7 @@ class ImproveActionLicensefile extends ImproveAction if (!empty($_POST['save'])) { $this->setSettings([ 'action_version' => !empty($_POST['action_version']) ? $_POST['action_version'] : '', - 'action_full' => !empty($_POST['action_full']) ? $_POST['action_full'] : '' + 'action_full' => !empty($_POST['action_full']) ? $_POST['action_full'] : '', ]); $this->redirect($url); } @@ -97,7 +114,7 @@ class ImproveActionLicensefile extends ImproveAction private function writeFullLicense(): ?bool { try { - $full = file_get_contents(dirname(__FILE__) . '/license/' . $this->getSetting('action_version') . '.full.txt'); + $full = file_get_contents(dirname(__FILE__) . '/licensefile/' . $this->getSetting('action_version') . '.full.txt'); if (empty($full)) { $this->setError(__('Failed to load license content')); diff --git a/inc/license/gpl2.full.txt b/inc/module/licensefile/gpl2.full.txt similarity index 100% rename from inc/license/gpl2.full.txt rename to inc/module/licensefile/gpl2.full.txt diff --git a/inc/license/gpl3.full.txt b/inc/module/licensefile/gpl3.full.txt similarity index 100% rename from inc/license/gpl3.full.txt rename to inc/module/licensefile/gpl3.full.txt diff --git a/inc/license/lgpl3.full.txt b/inc/module/licensefile/lgpl3.full.txt similarity index 100% rename from inc/license/lgpl3.full.txt rename to inc/module/licensefile/lgpl3.full.txt diff --git a/inc/license/mit.full.txt b/inc/module/licensefile/mit.full.txt similarity index 100% rename from inc/license/mit.full.txt rename to inc/module/licensefile/mit.full.txt diff --git a/inc/module/newline.php b/inc/module/newline.php new file mode 100644 index 0000000..949633f --- /dev/null +++ b/inc/module/newline.php @@ -0,0 +1,104 @@ +setProperties([ + 'id' => 'newline', + 'name' => __('Newlines'), + 'description' => __('Replace bad and repetitive and empty newline by single newline in files'), + 'priority' => 840, + 'configurator' => true, + 'types' => ['plugin', 'theme'], + ]); + /* + $ext = @unserialize($this->core->blog->settings->improve->newline_extensions); + $ext = Improve::cleanExtensions($ext); + if (!empty($ext)) { + $this->extensions = $ext; + } + */ + return true; + } + + public function isConfigured(): bool + { + return !empty($this->getSetting('extensions')); + } + + public function configure($url): ?string + { + if (!empty($_POST['save']) && !empty($_POST['newline_extensions'])) { + $this->setSettings( + 'extensions', + improve::cleanExtensions($_POST['newline_extensions']) + ); + $this->redirect($url); + } + + $ext = $this->getSetting('extensions'); + if (!is_array($ext)) { + $ext = []; + } + + return + '

' . + __('Use comma separated list of extensions without dot, recommand "php,js,xml,txt,md".') . + '

'; + } + + public function readFile(string &$content): ?bool + { + $ext = $this->getSetting('extensions'); + if (!is_array($ext) || !in_array($this->path_extension, $ext)) { + return null; + } + $clean = (string) preg_replace( + '/(\n\s+\n)/', + "\n\n", + (string) preg_replace( + '/(\n\n+)/', + "\n\n", + (string) str_replace( + ["\r\n", "\r"], + "\n", + $content + ) + ) + ); + if ($content != $clean) { + $this->setSuccess(__('Replace bad new lines')); + $content = $clean; + } + + return true; + } +} diff --git a/inc/lib.improve.action.phpcsfixer.php b/inc/module/phpcsfixer.php similarity index 85% rename from inc/lib.improve.action.phpcsfixer.php rename to inc/module/phpcsfixer.php index a88ef09..dfa6f4c 100644 --- a/inc/lib.improve.action.phpcsfixer.php +++ b/inc/module/phpcsfixer.php @@ -10,7 +10,28 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionPhpcsfixer extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* dotclear */ +use dcPage; + +/* clearbricks */ +use html; +use form; +use path; + +/* php */ +use Exception; + +/** + * Improve action module PHP CS Fixer + */ +class phpcsfixer extends action { /** @var array Type of runtime errors */ protected static $errors = [ @@ -20,7 +41,7 @@ class ImproveActionPhpcsfixer extends ImproveAction 8 => 'Some files need fixing (only in dry-run mode).', 16 => 'Configuration error of the application.', 32 => 'Configuration error of a Fixer.', - 64 => 'Exception raised within the application' + 64 => 'Exception raised within the application', ]; /** @var boolean User pref to use colored synthax */ @@ -40,7 +61,7 @@ class ImproveActionPhpcsfixer extends ImproveAction 'description' => __('Fix PSR coding style using Php CS Fixer'), 'priority' => 920, 'configurator' => true, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); $this->getPhpPath(); @@ -70,11 +91,11 @@ class ImproveActionPhpcsfixer extends ImproveAction { if (!empty($_POST['save'])) { $this->setSettings([ - 'phpexe_path' => !empty($_POST['phpexe_path']) ? $_POST['phpexe_path'] : '' + 'phpexe_path' => !empty($_POST['phpexe_path']) ? $_POST['phpexe_path'] : '', ]); $this->redirect($url); } - $content = (string) file_get_contents(dirname(__FILE__) . '/libs/dc.phpcsfixer.rules.php'); + $content = (string) file_get_contents(dirname(__FILE__) . '/phpcsfixer/phpcsfixer.rules.php'); return '

' . form::textarea('file_content', 120, 60, [ 'default' => html::escapeHTML($content), 'class' => 'maximal', - 'extra_html' => 'readonly="true"' + 'extra_html' => 'readonly="true"', ]) . '

' . ( !self::$user_ui_colorsyntax ? '' : - dcPage::jsLoad(dcPage::getPF('improve/inc/lib.improve.action.phpcsfixer.js')) . + dcPage::jsLoad(dcPage::getPF('improve/inc/module/phpcsfixer/phpcsfixer.improve.js')) . dcPage::jsRunCodeMirror('editor', 'file_content', 'dotclear', self::$user_ui_colorsyntax_theme) ); } @@ -101,7 +122,7 @@ class ImproveActionPhpcsfixer extends ImproveAction public function closeModule(): ?bool { $command = sprintf( - '%sphp %s/libs/php-cs-fixer.phar fix %s --config=%s/libs/dc.phpcsfixer.rules.php --using-cache=no', + '%sphp %s/phpcsfixer/libs/php-cs-fixer.phar fix %s --config=%s/phpcsfixer/phpcsfixer.rules.php --using-cache=no', $this->phpexe_path, dirname(__FILE__), $this->module['sroot'], diff --git a/inc/libs/php-cs-fixer.phar b/inc/module/phpcsfixer/libs/php-cs-fixer.phar similarity index 100% rename from inc/libs/php-cs-fixer.phar rename to inc/module/phpcsfixer/libs/php-cs-fixer.phar diff --git a/inc/lib.improve.action.phpcsfixer.js b/inc/module/phpcsfixer/phpcsfixer.improve.js similarity index 100% rename from inc/lib.improve.action.phpcsfixer.js rename to inc/module/phpcsfixer/phpcsfixer.improve.js diff --git a/inc/libs/dc.phpcsfixer.rules.php b/inc/module/phpcsfixer/phpcsfixer.rules.php similarity index 81% rename from inc/libs/dc.phpcsfixer.rules.php rename to inc/module/phpcsfixer/phpcsfixer.rules.php index 059b618..b845a5f 100644 --- a/inc/libs/dc.phpcsfixer.rules.php +++ b/inc/module/phpcsfixer/phpcsfixer.rules.php @@ -1,23 +1,26 @@ exclude('node_modules') ->exclude('vendor') ->exclude('libs') ->in(__DIR__); +/** @phpstan-ignore-next-line */ $config = new PhpCsFixer\Config(); +/* @phpstan-ignore-next-line */ return $config ->setRules([ '@PSR12' => true, + '@PHP74Migration' => true, 'array_indentation' => true, - 'array_syntax' => ['syntax' => 'short'], 'binary_operator_spaces' => [ 'default' => 'align_single_space_minimal', 'operators' => [ '=>' => 'align_single_space_minimal', - ] + ], ], 'blank_line_before_statement' => true, 'braces' => ['allow_single_line_closure' => true], @@ -33,15 +36,10 @@ return $config 'no_unused_imports' => true, 'no_useless_else' => true, 'no_useless_return' => true, - 'no_whitespace_before_comma_in_array' => true, - 'normalize_index_brace' => true, 'phpdoc_indent' => true, 'phpdoc_to_comment' => true, 'phpdoc_trim' => true, - 'return_type_declaration' => ['space_before' => 'none'], 'single_quote' => true, - 'ternary_to_null_coalescing' => true, - 'trailing_comma_in_multiline' => false, 'trim_array_spaces' => true, ]) ->setFinder($finder); diff --git a/inc/lib.improve.action.phpheader.php b/inc/module/phpheader.php similarity index 91% rename from inc/lib.improve.action.phpheader.php rename to inc/module/phpheader.php index e4f1614..90c3994 100644 --- a/inc/lib.improve.action.phpheader.php +++ b/inc/module/phpheader.php @@ -10,20 +10,37 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionPhpheader extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* clearbricks */ +use form; +use html; + +/* php */ +use Exception; + +/** + * Improve action module php header + */ +class phpheader extends action { /** @var string Exemple of header */ private static $exemple = << Allowed bloc replacement */ private $bloc_wildcards = [ @@ -35,7 +52,7 @@ EOF; '%user_cn%', '%user_name%', '%user_email%', - '%user_url%' + '%user_url%', ]; /** @var array Allowed action for header */ @@ -58,7 +75,7 @@ EOF; 'description' => __('Add or remove phpdoc header bloc from php file'), 'priority' => 340, 'configurator' => true, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); $this->action_bloc = [ @@ -66,7 +83,7 @@ EOF; __('Add bloc if it does not exist') => 'create', __('Add and overwrite bloc') => 'overwrite', __('Overwrite bloc only if it exists') => 'replace', - __('Remove existing bloc header') => 'remove' + __('Remove existing bloc header') => 'remove', ]; $bloc_content = $this->getSetting('bloc_content'); @@ -87,7 +104,7 @@ EOF; 'bloc_action' => !empty($_POST['bloc_action']) ? $_POST['bloc_action'] : '', 'bloc_content' => !empty($_POST['bloc_content']) ? $_POST['bloc_content'] : '', 'remove_old' => !empty($_POST['remove_old']), - 'exclude_locales' => !empty($_POST['exclude_locales']) + 'exclude_locales' => !empty($_POST['exclude_locales']), ]); $this->redirect($url); } @@ -148,7 +165,7 @@ EOF; $this->core->auth->getInfo('user_cn'), $this->core->auth->getinfo('user_name'), $this->core->auth->getInfo('user_email'), - $this->core->auth->getInfo('user_url') + $this->core->auth->getInfo('user_url'), ], (string) $bloc ) diff --git a/inc/lib.improve.action.phpstan.php b/inc/module/phpstan.php similarity index 90% rename from inc/lib.improve.action.phpstan.php rename to inc/module/phpstan.php index 5d26cb8..55783bb 100644 --- a/inc/lib.improve.action.phpstan.php +++ b/inc/module/phpstan.php @@ -10,7 +10,28 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionPhpstan extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* dotclear */ +use dcPage; + +/* clearbricks */ +use html; +use form; +use path; + +/* php */ +use Exception; + +/** + * Improve action module PHPStan + */ +class phpstan extends action { /** @var boolean User pref to use colored synthax */ protected static $user_ui_colorsyntax = false; @@ -35,7 +56,7 @@ class ImproveActionPhpstan extends ImproveAction 'description' => __('Analyse php code using PHPStan'), 'priority' => 910, 'configurator' => true, - 'types' => ['plugin'] + 'types' => ['plugin'], ]); $this->getPhpPath(); @@ -74,11 +95,11 @@ class ImproveActionPhpstan extends ImproveAction 'phpexe_path' => (!empty($_POST['phpexe_path']) ? $_POST['phpexe_path'] : ''), 'run_level' => (int) $_POST['run_level'], 'ignored_vars' => (!empty($_POST['ignored_vars']) ? $_POST['ignored_vars'] : ''), - 'split_report' => !empty($_POST['split_report']) + 'split_report' => !empty($_POST['split_report']), ]); $this->redirect($url); } - $content = (string) file_get_contents(dirname(__FILE__) . '/libs/dc.phpstan.rules.conf'); + $content = (string) file_get_contents(dirname(__FILE__) . '/phpstan/phpstan.rules.conf'); return '

' . __('You must enable improve details to view analyse results !') . '

' . @@ -108,11 +129,11 @@ class ImproveActionPhpstan extends ImproveAction '

' . form::textarea('file_content', 120, 14, [ 'default' => html::escapeHTML($content), 'class' => 'maximal', - 'extra_html' => 'readonly="true"' + 'extra_html' => 'readonly="true"', ]) . '

' . ( !self::$user_ui_colorsyntax ? '' : - dcPage::jsLoad(dcPage::getPF('improve/inc/lib.improve.action.phpstan.js')) . + dcPage::jsLoad(dcPage::getPF('improved/inc/module/phpstan/phpstan.improve.js')) . dcPage::jsRunCodeMirror('editor', 'file_content', 'dotclear', self::$user_ui_colorsyntax_theme) ); } @@ -158,7 +179,7 @@ class ImproveActionPhpstan extends ImproveAction } $command = sprintf( - '%sphp %s/libs/phpstan.phar analyse ' . $path . '--configuration=%s', + '%sphp %s/phpstan/libs/phpstan.phar analyse ' . $path . '--configuration=%s', $this->phpexe_path, dirname(__FILE__), DC_VAR . '/phpstan.neon' @@ -179,6 +200,7 @@ class ImproveActionPhpstan extends ImproveAction return true; } catch (Exception $e) { $this->setError(__('Failed to run phpstan')); + pdump($e); return false; } @@ -210,15 +232,15 @@ class ImproveActionPhpstan extends ImproveAction '%LEVEL%', '%MODULE_ROOT%', '%DC_ROOT%', - '%BOOTSTRAP_ROOT%' + '%BOOTSTRAP_ROOT%', ], [ $this->run_level, $this->module['sroot'], DC_ROOT, - dirname(__FILE__) . '/libs/' + dirname(__FILE__) . '/phpstan', ], - (string) file_get_contents(dirname(__FILE__) . '/libs/dc.phpstan.rules.conf') + (string) file_get_contents(dirname(__FILE__) . '/phpstan/phpstan.rules.conf') ); $ignored = explode(';', $this->ignored_vars); diff --git a/inc/libs/phpstan.phar b/inc/module/phpstan/libs/phpstan.phar similarity index 96% rename from inc/libs/phpstan.phar rename to inc/module/phpstan/libs/phpstan.phar index 418c8d7..306020e 100644 Binary files a/inc/libs/phpstan.phar and b/inc/module/phpstan/libs/phpstan.phar differ diff --git a/inc/libs/dc.phpstan.bootstrap.php b/inc/module/phpstan/phpstan.bootstrap.php similarity index 100% rename from inc/libs/dc.phpstan.bootstrap.php rename to inc/module/phpstan/phpstan.bootstrap.php diff --git a/inc/lib.improve.action.phpstan.js b/inc/module/phpstan/phpstan.improve.js similarity index 100% rename from inc/lib.improve.action.phpstan.js rename to inc/module/phpstan/phpstan.improve.js diff --git a/inc/libs/dc.phpstan.rules.conf b/inc/module/phpstan/phpstan.rules.conf similarity index 98% rename from inc/libs/dc.phpstan.rules.conf rename to inc/module/phpstan/phpstan.rules.conf index 75b95f3..a45cf6e 100644 --- a/inc/libs/dc.phpstan.rules.conf +++ b/inc/module/phpstan/phpstan.rules.conf @@ -14,7 +14,7 @@ parameters: - %MODULE_ROOT%/*/libs/* bootstrapFiles: - - %BOOTSTRAP_ROOT%dc.phpstan.bootstrap.php + - %BOOTSTRAP_ROOT%/phpstan.bootstrap.php fileExtensions: - php diff --git a/inc/module/tab.php b/inc/module/tab.php new file mode 100644 index 0000000..ea8dfa8 --- /dev/null +++ b/inc/module/tab.php @@ -0,0 +1,56 @@ +setProperties([ + 'id' => 'tab', + 'name' => __('Tabulations'), + 'description' => __('Replace tabulation by four space in php files'), + 'priority' => 820, + 'types' => ['plugin', 'theme'], + ]); + + return true; + } + + public function readFile(&$content): ?bool + { + if (!in_array($this->path_extension, ['php', 'md'])) { + return null; + } + $clean = preg_replace('/(\t)/', ' ', $content);// . "\n"; + if ($content != $clean) { + $this->setSuccess(__('Replace tabulation by spaces')); + $content = $clean; + } + + return true; + } + + public function isConfigured(): bool + { + return true; + } +} diff --git a/inc/lib.improve.action.zip.php b/inc/module/zip.php similarity index 95% rename from inc/lib.improve.action.zip.php rename to inc/module/zip.php index 7a16fdd..0593b66 100644 --- a/inc/lib.improve.action.zip.php +++ b/inc/module/zip.php @@ -10,7 +10,23 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -class ImproveActionZip extends ImproveAction +declare(strict_types=1); + +namespace plugins\improve\module; + +/* improve */ +use plugins\improve\action; + +/* clearbricks */ +use form; +use path; +use files; +use fileZip; + +/** + * Improve action module zip + */ +class zip extends action { /** @var array List of excluded file pattern */ public static $exclude = [ @@ -23,7 +39,7 @@ class ImproveActionZip extends ImproveAction 'CVS', '.DS_Store', 'Thumbs.db', - '_disabled' + '_disabled', ]; /** @var array Replacement wildcards */ @@ -32,7 +48,7 @@ class ImproveActionZip extends ImproveAction '%id%', '%version%', '%author%', - '%time%' + '%time%', ]; /** @var string Settings Excluded files */ @@ -52,7 +68,7 @@ class ImproveActionZip extends ImproveAction 'description' => __('Compress module into a ready to install package'), 'priority' => 980, 'configurator' => true, - 'types' => ['plugin', 'theme'] + 'types' => ['plugin', 'theme'], ]); $pack_excludefiles = $this->getSetting('pack_excludefiles'); @@ -81,7 +97,7 @@ class ImproveActionZip extends ImproveAction 'secondpack_filename' => !empty($_POST['secondpack_filename']) ? $_POST['secondpack_filename'] : '', 'pack_overwrite' => !empty($_POST['pack_overwrite']), 'pack_excludefiles' => !empty($_POST['pack_excludefiles']) ? $_POST['pack_excludefiles'] : '', - 'pack_nocomment' => !empty($_POST['pack_nocomment']) + 'pack_nocomment' => !empty($_POST['pack_nocomment']), ]); $this->redirect($url); } @@ -143,7 +159,7 @@ class ImproveActionZip extends ImproveAction ); $this->setSuccess(sprintf(__('Prepare excluded files "%s"'), implode(', ', $exclude))); if (!empty($this->getSetting('pack_nocomment'))) { - ImproveZipFileZip::$remove_comment = true; + zipFileZip::$remove_comment = true; $this->setSuccess(__('Prepare comment removal')); } if (!empty($this->getSetting('pack_filename'))) { @@ -165,7 +181,7 @@ class ImproveActionZip extends ImproveAction $this->module['id'], $this->module['version'], $this->module['author'], - time() + time(), ], $file ); @@ -186,7 +202,7 @@ class ImproveActionZip extends ImproveAction } @set_time_limit(300); $fp = fopen($path, 'wb'); - $zip = new ImproveZipFileZip($fp); + $zip = new zipFileZip($fp); foreach ($exclude as $e) { $e = '#(^|/)(' . str_replace( ['.', '*'], @@ -208,7 +224,7 @@ class ImproveActionZip extends ImproveAction } } -class ImproveZipFileZip extends fileZip +class zipFileZip extends fileZip { /** @var boolean Should remove comments from files */ public static $remove_comment = false; diff --git a/index.php b/index.php index 8831c13..576f468 100644 --- a/index.php +++ b/index.php @@ -10,236 +10,320 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ +declare(strict_types=1); + +namespace plugins\improve; + if (!defined('DC_CONTEXT_ADMIN')) { return; } -dcPage::checkSuper(); +/* dotclear */ +use dcCore; +use dcPage; +use dcThemes; +use dcUtils; -$improve = new Improve($core); +/* clearbricks */ +use html; +use form; -$show_filters = false; -$type = $_REQUEST['type'] ?? 'plugin'; +/* php */ +use Exception; -$preferences = @unserialize($core->blog->settings->improve->preferences); -if (!is_array($preferences)) { - $preferences = []; -} -$preferences = array_merge(['plugin' => [], 'theme' => []], $preferences); +/** + * Improve page class + * + * Display page and configure modules + * and launch action. + */ +class index +{ + /** @var dcCore $core dcCore instance */ + private $core = null; + /** @var improve $improve improve core instance */ + private $improve = null; + /** @var string $type Current module(s) type */ + private $type = 'plugin'; + /** @var string $module Current module id */ + private $module = '-'; + /** @var action|null $action Current action module */ + private $action = null; -if (!empty($_POST['save_preferences'])) { - $preferences[$type] = []; - if (!empty($_POST['actions'])) { - foreach ($improve->modules() as $action) { - if (in_array($type, $action->types()) && in_array($action->id(), $_POST['actions'])) { - $preferences[$type][] = $action->id(); - } + public function __construct(dcCore $core) + { + dcPage::checkSuper(); + + $this->core = $core; + $this->improve = new improve($core); + $this->type = $this->getType(); + $this->module = $this->getModule(); + $this->action = $this->getAction(); + + $this->doAction(); + $this->displayPage(); + } + + private function getType(): string + { + return $_REQUEST['type'] ?? 'plugin'; + } + + private function getModule(): string + { + $module = $_REQUEST['module'] ?? ''; + if (!in_array($module, $this->comboModules())) { + $module = '-'; } + + return $module; } - $core->blog->settings->improve->put('preferences', serialize($preferences), 'string', null, true, true); - dcPage::addSuccessNotice(__('Configuration successfully updated')); -} -$allow_distrib = (bool) $core->blog->settings->improve->allow_distrib; -$official = [ - 'plugin' => explode(',', DC_DISTRIB_PLUGINS), - 'theme' => explode(',', DC_DISTRIB_THEMES) -]; - -if (!isset($core->themes)) { - $core->themes = new dcThemes($core); - $core->themes->loadModules($core->blog->themes_path, null); -} - -$combo_modules = []; -$modules = $type == 'plugin' ? $core->plugins->getModules() : $core->themes->getModules(); -foreach ($modules as $id => $m) { - if (!$m['root_writable'] || !$allow_distrib && in_array($id, $official[$type])) { - continue; + private function getAction(): ?action + { + return empty($_REQUEST['config']) ? null : $this->improve->module($_REQUEST['config']); } - $combo_modules[__($m['name'])] = $id; -} -dcUtils::lexicalKeySort($combo_modules); -$combo_modules = array_merge([__('Select a module') => '-'], $combo_modules); -$module = $_REQUEST['module'] ?? ''; -if (!in_array($module, $combo_modules)) { - $module = '-'; -} - -if (!empty($_POST['fix'])) { - if (empty($_POST['actions'])) { - dcPage::addWarningNotice(__('No action selected')); - } elseif ($module == '-') { - dcPage::addWarningNotice(__('No module selected')); - } else { + private function getPreference(): array + { try { - $time = $improve->fixModule( - $type, - $module, - $type == 'plugin' ? $core->plugins->getModules($module) : $core->themes->getModules($module), - $_POST['actions'] - ); - $log_id = $improve->writeLogs(); - $core->blog->triggerBlog(); - - if ($improve->hasLog('error')) { - $notice = ['type' => 'error', 'msg' => __('Fix of "%s" complete in %s secondes with errors')]; - } elseif ($improve->hasLog('warning')) { - $notice = ['type' => 'warning', 'msg' => __('Fix of "%s" complete in %s secondes with warnings')]; - } elseif ($improve->hasLog('success')) { - $notice = ['type' => 'success', 'msg' => __('Fix of "%s" complete in %s secondes')]; - } else { - $notice = ['type' => 'success', 'msg' => __('Fix of "%s" complete in %s secondes without messages')]; + if (!empty($this->type)) { + $preferences = unserialize($this->core->blog->settings->improve->preferences); + if (is_array($preferences)) { + return array_key_exists($this->type, $preferences) ? $preferences[$this->type] : []; + } } - dcPage::addNotice($notice['type'], sprintf($notice['msg'], $module, $time)); - - $core->adminurl->redirect('admin.plugin.improve', ['type' => $type, 'module' => $module, 'upd' => $log_id]); } catch (Exception $e) { - $core->error->add($e->getMessage()); + } + + return []; + } + + private function setPreferences(): void + { + if (!empty($_POST['save_preferences'])) { + $preferences[$this->type] = []; + if (!empty($_POST['actions'])) { + foreach ($this->improve->modules() as $action) { + if (in_array($this->type, $action->types()) && in_array($action->id(), $_POST['actions'])) { + $preferences[$this->type][] = $action->id(); + } + } + } + $this->core->blog->settings->improve->put('preferences', serialize($preferences), 'string', null, true, true); + dcPage::addSuccessNotice(__('Configuration successfully updated')); } } -} -$action = null; -$header = ''; -$breadcrumb = []; -if (!empty($_REQUEST['config'])) { - $breadcrumb = [ - __('Configure module') => '' - ]; - if (null !== ($action = $improve->module($_REQUEST['config']))) { - $header = $action->header(); - } -} else { - $breadcrumb[$type == 'theme' ? __('Themes actions') : __('Plugins actions')] = ''; -} + private function comboModules(): array + { + $allow_distrib = (bool) $this->core->blog->settings->improve->allow_distrib; + $official = [ + 'plugin' => explode(',', DC_DISTRIB_PLUGINS), + 'theme' => explode(',', DC_DISTRIB_THEMES), + ]; -# display header -echo '' . __('improve') . '' . -dcPage::jsLoad(dcPage::getPF('improve/js/index.js')) . -$header . -'' . -dcPage::breadcrumb(array_merge([ - __('Plugins') => '', - __('improve') => '' -], $breadcrumb)) . -dcPage::notices(); + if (!isset($this->core->themes)) { + $this->core->themes = new dcThemes($this->core); + $this->core->themes->loadModules($this->core->blog->themes_path, null); + } -# Menu list -if (empty($_REQUEST['config'])) { - echo - '
' . - '

' . - form::combo('type', [__('Plugins') => 'plugin', __('Themes') => 'theme'], $type) . ' ' . - '' . - form::hidden('p', 'improve') . '

' . - '
'; -} - -if (!empty($_REQUEST['config'])) { - $back_url = $_REQUEST['redir'] ?? $core->adminurl->get('admin.plugin.improve', ['type' => $type]); - - if (null !== $action) { - $redir = $_REQUEST['redir'] ?? $core->adminurl->get('admin.plugin.improve', ['type' => $type, 'config' => $action->id()]); - $res = $action->configure($redir); - - echo ' -

' . sprintf(__('Configure module "%s"'), $action->name()) . '

-

' . __('Back') . '

-

' . html::escapeHTML($action->description()) . '

-
' . - (empty($res) ? '

' . __('Nothing to configure') . '

' : $res) . ' -

' . - form::hidden('type', $type) . - form::hidden('config', $action->id()) . - form::hidden('redir', $redir) . - $core->formNonce() . '

' . - '
'; - } else { - echo ' -

' . __('Unknow module') . '

-

' . __('Back') . '

'; - } -} else { - if (count($combo_modules) == 1) { - echo '

' . __('No module to manage') . '

'; - } else { - echo '
' . - '' . - ''; - foreach ($improve->modules() as $action) { - if (!in_array($type, $action->types())) { + $combo_modules = []; + $modules = $this->type == 'plugin' ? $this->core->plugins->getModules() : $this->core->themes->getModules(); + foreach ($modules as $id => $m) { + if (!$m['root_writable'] || !$allow_distrib && in_array($id, $official[$this->type])) { continue; } - echo - '' . - '' . - '' . - '' . - '' . - (DC_DEBUG ? '' : '') . - ''; + $combo_modules[__($m['name'])] = $id; + } + dcUtils::lexicalKeySort($combo_modules); + + return array_merge([__('Select a module') => '-'], $combo_modules); + } + + private function doAction(): void + { + if (!empty($_POST['fix'])) { + if (empty($_POST['actions'])) { + dcPage::addWarningNotice(__('No action selected')); + } elseif ($this->module == '-') { + dcPage::addWarningNotice(__('No module selected')); + } else { + try { + $time = $this->improve->fixModule( + $this->type, + $this->module, + $this->type == 'plugin' ? $this->core->plugins->getModules($this->module) : $this->core->themes->getModules($this->module), + $_POST['actions'] + ); + $log_id = $this->improve->writeLogs(); + $this->core->blog->triggerBlog(); + + if ($this->improve->hasLog('error')) { + $notice = ['type' => 'error', 'msg' => __('Fix of "%s" complete in %s secondes with errors')]; + } elseif ($this->improve->hasLog('warning')) { + $notice = ['type' => 'warning', 'msg' => __('Fix of "%s" complete in %s secondes with warnings')]; + } elseif ($this->improve->hasLog('success')) { + $notice = ['type' => 'success', 'msg' => __('Fix of "%s" complete in %s secondes')]; + } else { + $notice = ['type' => 'success', 'msg' => __('Fix of "%s" complete in %s secondes without messages')]; + } + dcPage::addNotice($notice['type'], sprintf($notice['msg'], $this->module, $time)); + + $this->core->adminurl->redirect('admin.plugin.improve', ['type' => $this->type, 'module' => $this->module, 'upd' => $log_id]); + } catch (Exception $e) { + $this->core->error->add($e->getMessage()); + } + } + } + } + + private function displayPage(): void + { + $bc = empty($_REQUEST['config']) ? + ($this->type == 'theme' ? __('Themes actions') : __('Plugins actions')) : + __('Configure module'); + + echo '' . __('improve') . '' . + dcPage::jsLoad(dcPage::getPF('improve/js/index.js')) . + ($this->action === null ? '' : $this->action->header()) . + '' . + dcPage::notices() . + dcPage::breadcrumb([ + __('Plugins') => '', + __('improve') => '', + $bc => '', + ]); + + if (empty($_REQUEST['config'])) { + $this->displayActions(); + } else { + $this->displayConfigurator(); } - echo '
' . __('Action') . '' . - '' . __('Description') . '' . - '' . __('Configuration') . '' . - (DC_DEBUG ? '' . __('Priority') . '' : '') . - '
' . form::checkbox( - ['actions[]', - 'action_' . $action->id()], - $action->id(), - in_array($action->id(), $preferences[$type]) && $action->isConfigured(), - '', - '', - !$action->isConfigured() - ) . '' . - '' . - '' . $action->description() . '' . ( - false === $action->configurator() ? '' : - 'name()) . '">' . __('Configure') . '' - ) . '' . $action->priority() . '
-
-

-

' . - form::combo('module', $combo_modules, $module) . - ' ' . - form::hidden(['type'], $type) . - $core->formNonce() . ' -

-
-
-
'; + echo ''; + } - if (!empty($_REQUEST['upd']) && !$core->blog->settings->improve->nodetails) { - $logs = $improve->parseLogs($_REQUEST['upd']); + private function displayConfigurator(): void + { + $back_url = $_REQUEST['redir'] ?? $this->core->adminurl->get('admin.plugin.improve', ['type' => $this->type]); - if (!empty($logs)) { - echo '

' . __('Details') . '

'; - foreach ($logs as $path => $types) { - echo '
' . $path . '
'; - foreach ($types as $type => $tools) { - echo '
    '; - foreach ($tools as $tool => $msgs) { - $a = $improve->module($tool); - echo '
  • ' . ($a !== null ? $a->name() : 'unknow') . '
      '; - foreach ($msgs as $msg) { - echo '
    • ' . $msg . '
    • '; - } - echo '
  • '; - } - echo '
'; - } - echo ''; + if (null === $this->action) { + echo ' +

' . __('Unknow module') . '

+

' . __('Back') . '

'; + } else { + $redir = $_REQUEST['redir'] ?? $this->core->adminurl->get('admin.plugin.improve', ['type' => $this->type, 'config' => $this->action->id()]); + $res = $this->action->configure($redir); + + echo ' +

' . sprintf(__('Configure module "%s"'), $this->action->name()) . '

+

' . __('Back') . '

+

' . html::escapeHTML($this->action->description()) . '

+
' . + (empty($res) ? '

' . __('Nothing to configure') . '

' : $res) . ' +

' . + form::hidden('type', $this->type) . + form::hidden('config', $this->action->id()) . + form::hidden('redir', $redir) . + $this->core->formNonce() . '

' . + '
'; + } + } + + private function displayActions(): void + { + echo + '
' . + '

' . + form::combo('type', [__('Plugins') => 'plugin', __('Themes') => 'theme'], $this->type) . ' ' . + '' . + form::hidden('p', 'improve') . '

' . + '
'; + + $combo_modules = $this->comboModules(); + if (count($combo_modules) == 1) { + echo '

' . __('No module to manage') . '

'; + } else { + echo '
' . + '' . + ''; + foreach ($this->improve->modules() as $action) { + if (!in_array($this->type, $action->types())) { + continue; + } + echo + '' . + '' . + '' . + '' . + '' . + (DC_DEBUG ? '' : '') . /* @phpstan-ignore-line */ + ''; + } + + echo '
' . __('Action') . '' . + '' . __('Description') . '' . + '' . __('Configuration') . '' . + (DC_DEBUG ? '' . __('Priority') . '' : '') . /* @phpstan-ignore-line */ + '
' . form::checkbox( + ['actions[]', + 'action_' . $action->id(), ], + $action->id(), + in_array($action->id(), $this->getPreference()) && $action->isConfigured(), + '', + '', + !$action->isConfigured() + ) . '' . + '' . + '' . $action->description() . '' . ( + false === $action->configurator() ? '' : + 'name()) . '">' . __('Configure') . '' + ) . '' . $action->priority() . '
+
+

+

' . + form::combo('module', $combo_modules, $this->module) . + ' ' . + form::hidden(['type'], $this->type) . + $this->core->formNonce() . ' +

+
+
+
'; + + if (!empty($_REQUEST['upd']) && !$this->core->blog->settings->improve->nodetails) { + $logs = $this->improve->parseLogs((int) $_REQUEST['upd']); + + if (!empty($logs)) { + echo '

' . __('Details') . '

'; + foreach ($logs as $path => $types) { + echo '
' . $path . '
'; + foreach ($types as $type => $tools) { + echo '
    '; + foreach ($tools as $tool => $msgs) { + $a = $this->improve->module($tool); + if (null !== $a) { + echo '
  • ' . $a->name() . '
      '; + foreach ($msgs as $msg) { + echo '
    • ' . $msg . '
    • '; + } + } + echo '
  • '; + } + echo '
'; + } + echo ''; + } + echo '
'; } - echo '
'; } } } } -echo ''; +/* process */ +new index($core); diff --git a/locales/fr/main.po b/locales/fr/main.po index 20cc60b..c3d6e2f 100644 --- a/locales/fr/main.po +++ b/locales/fr/main.po @@ -1,9 +1,9 @@ msgid "" msgstr "" "Content-Type: text/plain; charset=UTF-8\n" -"Project-Id-Version: improve 0.6\n" +"Project-Id-Version: improve 0.7.3\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-11-07T17:50:41+00:00\n" +"PO-Revision-Date: 2021-11-13T21:51:37+00:00\n" "Last-Translator: Jean-Christian Denis\n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -94,6 +94,21 @@ msgstr "Lien de détail non défini" msgid "no support URL" msgstr "Lien de support non défini" +msgid "End of files" +msgstr "Fin de fichiers" + +msgid "Remove php tag and empty lines from end of files" +msgstr "Supprimer le tag PHP et les lignes vides de fin de fichiers" + +msgid "Add a blank line to the end of file" +msgstr "Ajouter une ligne vide en fin de fichier" + +msgid "PSR2 must have a blank line, whereas PSR12 must not." +msgstr "PSR2 doit avoir une ligne vide, alors que PSR12 non." + +msgid "Replace end of file" +msgstr "Remplacer les fins de fichiers" + msgid "Shields badges" msgstr "Badges Shields.io" @@ -175,15 +190,6 @@ msgstr "Impossible de supprimer l'ancien fichier de licence (%s)" msgid "Delete old license file \"%s\"" msgstr "Effacer l'ancien fichier de Licence \"%s\"" -msgid "Tabulations" -msgstr "Tabulations" - -msgid "Replace tabulation by four space in php files" -msgstr "Remplace les tabulation par quatre espaces dans les fichiers php" - -msgid "Replace tabulation by spaces" -msgstr "Remplacer les tabulations" - msgid "Newlines" msgstr "Retour à la ligne" @@ -199,21 +205,6 @@ msgstr "Utiliser une liste d'extensions séparé par des virgules et sans le poi msgid "Replace bad new lines" msgstr "Remplacer les retours à la ligne" -msgid "End of files" -msgstr "Fin de fichiers" - -msgid "Remove php tag and empty lines from end of files" -msgstr "Supprimer le tag PHP et les lignes vides de fin de fichiers" - -msgid "Add a blank line to the end of file" -msgstr "Ajouter une ligne vide en fin de fichier" - -msgid "PSR2 must have a blank line, whereas PSR12 must not." -msgstr "PSR2 doit avoir une ligne vide, alors que PSR12 non." - -msgid "Replace end of file" -msgstr "Remplacer les fins de fichiers" - msgid "Fix PSR coding style using Php CS Fixer" msgstr "Corrige le style du code suivant les règles PSR en utilisant Php CS Fixer" @@ -262,9 +253,6 @@ msgstr "Contenu du bloc :" msgid "Do not put structural elements to the begining of lines." msgstr "Ne pas mettre d'élément de structure en début de ligne" -msgid "Skip directory" -msgstr "Ignorer le répertoire" - msgid "bloc is empty" msgstr "le bloc est vide" @@ -274,6 +262,9 @@ msgstr "Préparer les informations d'entête" msgid "Failed to parse bloc" msgstr "Impossible de préparer le bloc" +msgid "Skip directory" +msgstr "Ignorer le répertoire" + msgid "Write new doc bloc content" msgstr "Ecrire le nouveau contenu de bloc" @@ -286,6 +277,9 @@ msgstr "Effacer l'ancien contenu de type ancien" msgid "Analyse php code using PHPStan" msgstr "Analyse le code PHP en utilisant PHPStan" +msgid "You must enable improve details to view analyse results !" +msgstr "Vous devez activer l'affichage des détails de l'analyse dans les paramètres d'improve." + msgid "Level:" msgstr "Niveau :" @@ -307,12 +301,27 @@ msgstr "Scinder le rapport par fichier plutôt qu'un seul à la fin." msgid "Enable this can cause timeout." msgstr "Activer ceci peut causer de Timeout." -msgid "You must enable improve details to view analyse results !" -msgstr "Vous devez activer l'affichage des détails de l'analyse dans les paramètres d'improve." +msgid "PHPStan configuration file:" +msgstr "Fichier de configuration de PHPStan :" + +msgid "Failed to write phpstan configuration" +msgstr "Impossible d'écrire la configuration de PHPStan" msgid "No errors found" msgstr "Aucune erreur trouvé" +msgid "Failed to run phpstan" +msgstr "Impossible d'exécuter PHPStan" + +msgid "Tabulations" +msgstr "Tabulations" + +msgid "Replace tabulation by four space in php files" +msgstr "Remplace les tabulation par quatre espaces dans les fichiers php" + +msgid "Replace tabulation by spaces" +msgstr "Remplacer les tabulations" + msgid "Zip module" msgstr "Zipper le module" @@ -388,17 +397,17 @@ msgstr "Fixe de \"%s\" complété en %s secondes" msgid "Fix of \"%s\" complete in %s secondes without messages" msgstr "Fixe de \"%s\" complété en %s secondes sans message" -msgid "Configure module" -msgstr "Configurer le module" - msgid "Themes actions" msgstr "Actions sur les thèmes" msgid "Plugins actions" msgstr "Actions sur les plugins" -msgid "Themes" -msgstr "Thèmes" +msgid "Configure module" +msgstr "Configurer le module" + +msgid "Unknow module" +msgstr "Module inconnu" msgid "Configure module \"%s\"" msgstr "Configurer le module \"%s\"" @@ -406,8 +415,8 @@ msgstr "Configurer le module \"%s\"" msgid "Nothing to configure" msgstr "Rien à configurer" -msgid "Unknow module" -msgstr "Module inconnu" +msgid "Themes" +msgstr "Thèmes" msgid "No module to manage" msgstr "Aucun module à gérer" @@ -418,6 +427,9 @@ msgstr "Priorité" msgid "Configure action '%s'" msgstr "Configurer l'action \"%s\"" +msgid "Configure" +msgstr "Configurer" + msgid "Save fields selection as preference" msgstr "Enregistrer la sélection comme préférence"