update structure to php namespace (my first step in!)

This commit is contained in:
Jean-Christian Denis 2021-11-13 22:57:51 +01:00
parent c3102b3636
commit 4eba45e38f
Signed by: JcDenis
GPG key ID: 1B5B8C5B90B6C951
34 changed files with 1342 additions and 832 deletions

View file

@ -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

View file

@ -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);

View file

@ -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 '<div class="fieldset"><h4>' . __('List of disabled actions:') . '</h4>';
foreach ($this->getModules() as $name => $id) {
echo
'<p><label class="classic" title="' . $id . '">' .
form::checkbox(['disabled[]'], $id, ['checked' => array_key_exists($id, $this->improve->disabled())]) .
__($name) . '</label></p>';
}
echo
'</div><div class="fieldset"><h4>' . __('Options') . '</h4>' .
'<p><label class="classic">' .
form::checkbox('nodetails', '1', ['checked' => $this->core->blog->settings->improve->nodetails]) .
__('Hide details of rendered actions') . '</label></p>' .
'</div>';
}
}
echo '<div class="fieldset"><h4>' . __('List of disabled actions:') . '</h4>';
foreach ($combo_actions as $name => $id) {
echo
'<p><label class="classic" title="' . $id . '">' .
form::checkbox(['disabled[]'], $id, ['checked' => isset($disabled[$id])]) .
__($name) . '</label></p>';
}
echo
'</div><div class="fieldset"><h4>' . __('Options') . '</h4>' .
'<p><label class="classic">' .
form::checkbox('nodetails', '1', ['checked' => $core->blog->settings->improve->nodetails]) .
__('Hide details of rendered actions') . '</label></p>' .
'</div>';
/* process */
new config($core, $list);

View file

@ -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',
]
);

View file

@ -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());

View file

@ -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);

View file

@ -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();

View file

@ -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<action> $actions Loaded actions modules */
private $actions = [];
/** @var array<string> Disabled actions modules */
/** @var array<string> $disabled Disabled actions modules */
private $disabled = [];
/** @var array<string, array> Logs by actions modules */
/** @var array<string, array> $logs Logs by actions modules */
private $logs = [];
/** @var array<string, boolean> Has log of given type */
/** @var array<string, boolean> $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));
}
}

198
inc/core/module.php Normal file
View file

@ -0,0 +1,198 @@
<?php
/**
* @brief improve, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace plugins\improve;
/* clearbricks */
use path;
/**
* Improve module helper
*
* Help to load module configuration file (_define.php)
* and gather information about it.
*/
class module
{
/** @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
{
$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));
}
}

View file

@ -1,181 +0,0 @@
<?php
/**
* @brief improve, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class ImproveActionTab extends ImproveAction
{
protected function init(): bool
{
$this->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
'<p><label class="classic" for="newline_extensions">' .
__('List of files extension to work on:') . '<br />' .
form::field('newline_extensions', 65, 255, implode(',', $ext)) .
'</label></p><p class="form-note">' .
__('Use comma separated list of extensions without dot, recommand "php,js,xml,txt,md".') .
'</p>';
}
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
'<p><label class="classic" for="endoffile_psr2">' .
form::checkbox('endoffile_psr2', 255, $this->getSetting('psr2')) .
__('Add a blank line to the end of file') .
'</label></p><p class="form-note">' .
__('PSR2 must have a blank line, whereas PSR12 must not.') .
'</p>';
}
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;
}
}

View file

@ -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;

View file

@ -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
'<p class="info">' . __('File will be overwritten if it exists') . '</p>' .
'<p><label class="classic" for="dcstore_pattern">' .
__('Predictable URL to zip file on the external repository') . '<br />' .
form::field('dcstore_pattern', 160, 255, $this->getSetting('pattern')) . '</label>' .
form::field('dcstore_pattern', 160, 255, $this->pattern) . '</label>' .
'</p>' .
'<p class="form-note">' .
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
));
}
}

80
inc/module/endoffile.php Normal file
View file

@ -0,0 +1,80 @@
<?php
/**
* @brief improve, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace plugins\improve\module;
/* improve */
use plugins\improve\action;
/* clearbricks */
use form;
/**
* Improve action module end of file
*/
class endoffile extends action
{
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
'<p><label class="classic" for="endoffile_psr2">' .
form::checkbox('endoffile_psr2', 255, $this->getSetting('psr2')) .
__('Add a blank line to the end of file') .
'</label></p><p class="form-note">' .
__('PSR2 must have a blank line, whereas PSR12 must not.') .
'</p>';
}
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;
}
}

View file

@ -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 '
<p><label for="username">' . __('Your Github user name :') . '</label>' .
form::field('username', 60, 100, $this->getSetting('username')) . '
form::field('username', 60, 100, $this->username) . '
</p><p class="form-note">' . __('Used in your Github URL: http://github.com/username/module_id.') . '<br />' .
__('If you have badges not created by this tool in the README.md file you should remove them manually.') . '</p>
<p><label for="dotaddict">' .
form::checkbox('dotaddict', 1, !empty($this->getSetting('dotaddict'))) . ' ' .
form::checkbox('dotaddict', 1, $this->dotaddict) . ' ' .
__('Include Dotaddict badge') . '</label>
</p><p class="form-note">' . __('If your plugin or theme is on Dotaddict, you can add a badge to link to its details in Dotaddict.') . '</p>';
}
@ -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
));

View file

@ -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'));

104
inc/module/newline.php Normal file
View file

@ -0,0 +1,104 @@
<?php
/**
* @brief improve, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace plugins\improve\module;
/* improve */
use plugins\improve\action;
use plugins\improve\improve;
/* clearbricks */
use form;
/**
* Improve action module new line
*/
class newline extends action
{
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
'<p><label class="classic" for="newline_extensions">' .
__('List of files extension to work on:') . '<br />' .
form::field('newline_extensions', 65, 255, implode(',', $ext)) .
'</label></p><p class="form-note">' .
__('Use comma separated list of extensions without dot, recommand "php,js,xml,txt,md".') .
'</p>';
}
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;
}
}

View file

@ -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<int,string> 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
'<p><label class="classic" for="phpexe_path">' .
@ -89,11 +110,11 @@ class ImproveActionPhpcsfixer extends ImproveAction
'<p>' . form::textarea('file_content', 120, 60, [
'default' => html::escapeHTML($content),
'class' => 'maximal',
'extra_html' => 'readonly="true"'
'extra_html' => 'readonly="true"',
]) . '</p>' .
(
!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'],

View file

@ -1,23 +1,26 @@
<?php
/** @phpstan-ignore-next-line */
$finder = PhpCsFixer\Finder::create()
->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);

View file

@ -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 = <<<EOF
@brief %module_id%, a %module_type% for Dotclear 2
@brief %module_id%, a %module_type% for Dotclear 2
@package Dotclear
@subpackage \u%module_type%
@package Dotclear
@subpackage \u%module_type%
@author %module_author%
@author %module_author%
@copyright %user_cn%
@copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
EOF;
@copyright %user_cn%
@copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
EOF;
/** @var array<string> 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
)

View file

@ -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
'<p class="info">' . __('You must enable improve details to view analyse results !') . '</p>' .
@ -108,11 +129,11 @@ class ImproveActionPhpstan extends ImproveAction
'<p>' . form::textarea('file_content', 120, 14, [
'default' => html::escapeHTML($content),
'class' => 'maximal',
'extra_html' => 'readonly="true"'
'extra_html' => 'readonly="true"',
]) . '</p>' .
(
!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);

View file

@ -14,7 +14,7 @@ parameters:
- %MODULE_ROOT%/*/libs/*
bootstrapFiles:
- %BOOTSTRAP_ROOT%dc.phpstan.bootstrap.php
- %BOOTSTRAP_ROOT%/phpstan.bootstrap.php
fileExtensions:
- php

56
inc/module/tab.php Normal file
View file

@ -0,0 +1,56 @@
<?php
/**
* @brief improve, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace plugins\improve\module;
/* improve */
use plugins\improve\action;
/**
* Improve action module tab
*/
class tab extends action
{
protected function init(): bool
{
$this->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;
}
}

View file

@ -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;

484
index.php
View file

@ -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 '<html><head><title>' . __('improve') . '</title>' .
dcPage::jsLoad(dcPage::getPF('improve/js/index.js')) .
$header .
'</head><body>' .
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 method="get" action="' . $core->adminurl->get('admin.plugin.improve') . '" id="improve_menu">' .
'<p class="anchor-nav"><label for="type" class="classic">' . __('Goto:') . ' </label>' .
form::combo('type', [__('Plugins') => 'plugin', __('Themes') => 'theme'], $type) . ' ' .
'<input type="submit" value="' . __('Ok') . '" />' .
form::hidden('p', 'improve') . '</p>' .
'</form>';
}
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 '
<h3>' . sprintf(__('Configure module "%s"'), $action->name()) . '</h3>
<p><a class="back" href="' . $back_url . '">' . __('Back') . '</a></p>
<p class="info">' . html::escapeHTML($action->description()) . '</p>
<form action="' . $core->adminurl->get('admin.plugin.improve') . '" method="post" id="form-actions">' .
(empty($res) ? '<p class="message">' . __('Nothing to configure') . '</p>' : $res) . '
<p class="clear"><input type="submit" name="save" value="' . __('Save') . '" />' .
form::hidden('type', $type) .
form::hidden('config', $action->id()) .
form::hidden('redir', $redir) .
$core->formNonce() . '</p>' .
'</form>';
} else {
echo '
<p class="warning">' . __('Unknow module') . '</p>
<p><a class="back" href="' . $back_url . '">' . __('Back') . '</a></p>';
}
} else {
if (count($combo_modules) == 1) {
echo '<p class="message">' . __('No module to manage') . '</p>';
} else {
echo '<form action="' . $core->adminurl->get('admin.plugin.improve') . '" method="post" id="form-actions">' .
'<table><caption class="hidden">' . __('Actions') . '</caption><thead><tr>' .
'<th colspan="2" class="first">' . __('Action') . '</td>' .
'<th scope="col">' . __('Description') . '</td>' .
'<th scope="col">' . __('Configuration') . '</td>' .
(DC_DEBUG ? '<th scope="col">' . __('Priority') . '</td>' : '') .
'</tr></thead><tbody>';
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
'<tr class="line' . ($action->isConfigured() ? '' : ' offline') . '">' .
'<td class="minimal">' . form::checkbox(
['actions[]',
'action_' . $action->id()],
$action->id(),
in_array($action->id(), $preferences[$type]) && $action->isConfigured(),
'',
'',
!$action->isConfigured()
) . '</td>' .
'<td class="minimal nowrap">' .
'<label for="action_' . $action->id() . '" class="classic">' . html::escapeHTML($action->name()) . '</label>' .
'</td>' .
'<td class="maximal">' . $action->description() . '</td>' .
'<td class="minimal nowrap modules">' . (
false === $action->configurator() ? '' :
'<a class="module-config" href="' . $core->adminurl->get('admin.plugin.improve', ['type' => $type, 'config' => $action->id()]) .
'" title="' . sprintf(__("Configure action '%s'"), $action->name()) . '">' . __('Configure') . '</a>'
) . '</td>' .
(DC_DEBUG ? '<td class="minimal"><span class="debug">' . $action->priority() . '</span></td>' : '') .
'</tr>';
$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 '<html><head><title>' . __('improve') . '</title>' .
dcPage::jsLoad(dcPage::getPF('improve/js/index.js')) .
($this->action === null ? '' : $this->action->header()) .
'</head><body>' .
dcPage::notices() .
dcPage::breadcrumb([
__('Plugins') => '',
__('improve') => '',
$bc => '',
]);
if (empty($_REQUEST['config'])) {
$this->displayActions();
} else {
$this->displayConfigurator();
}
echo '</tbody></table>
<div class="two-cols">
<p class="col left"><label for="save_preferences" class="classic">' .
form::checkbox('save_preferences', 1, !empty($_POST['save_preferences'])) .
__('Save fields selection as preference') . '</label></p>
<p class="col right"><label for="module" class="classic">' . __('Select a module:') . ' </label>' .
form::combo('module', $combo_modules, $module) .
' <input type="submit" name="fix" value="' . __('Fix it') . '" />' .
form::hidden(['type'], $type) .
$core->formNonce() . '
</p>
</div>
<br class="clear" />
</form>';
echo '</body></html>';
}
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 '<div class="fieldset"><h4>' . __('Details') . '</h4>';
foreach ($logs as $path => $types) {
echo '<h5>' . $path . '</h5>';
foreach ($types as $type => $tools) {
echo '<div class="' . $type . '"><ul>';
foreach ($tools as $tool => $msgs) {
$a = $improve->module($tool);
echo '<li>' . ($a !== null ? $a->name() : 'unknow') . '<ul>';
foreach ($msgs as $msg) {
echo '<li>' . $msg . '</li>';
}
echo '</ul></li>';
}
echo '</ul></div>';
}
echo '';
if (null === $this->action) {
echo '
<p class="warning">' . __('Unknow module') . '</p>
<p><a class="back" href="' . $back_url . '">' . __('Back') . '</a></p>';
} else {
$redir = $_REQUEST['redir'] ?? $this->core->adminurl->get('admin.plugin.improve', ['type' => $this->type, 'config' => $this->action->id()]);
$res = $this->action->configure($redir);
echo '
<h3>' . sprintf(__('Configure module "%s"'), $this->action->name()) . '</h3>
<p><a class="back" href="' . $back_url . '">' . __('Back') . '</a></p>
<p class="info">' . html::escapeHTML($this->action->description()) . '</p>
<form action="' . $this->core->adminurl->get('admin.plugin.improve') . '" method="post" id="form-actions">' .
(empty($res) ? '<p class="message">' . __('Nothing to configure') . '</p>' : $res) . '
<p class="clear"><input type="submit" name="save" value="' . __('Save') . '" />' .
form::hidden('type', $this->type) .
form::hidden('config', $this->action->id()) .
form::hidden('redir', $redir) .
$this->core->formNonce() . '</p>' .
'</form>';
}
}
private function displayActions(): void
{
echo
'<form method="get" action="' . $this->core->adminurl->get('admin.plugin.improve') . '" id="improve_menu">' .
'<p class="anchor-nav"><label for="type" class="classic">' . __('Goto:') . ' </label>' .
form::combo('type', [__('Plugins') => 'plugin', __('Themes') => 'theme'], $this->type) . ' ' .
'<input type="submit" value="' . __('Ok') . '" />' .
form::hidden('p', 'improve') . '</p>' .
'</form>';
$combo_modules = $this->comboModules();
if (count($combo_modules) == 1) {
echo '<p class="message">' . __('No module to manage') . '</p>';
} else {
echo '<form action="' . $this->core->adminurl->get('admin.plugin.improve') . '" method="post" id="form-actions">' .
'<table><caption class="hidden">' . __('Actions') . '</caption><thead><tr>' .
'<th colspan="2" class="first">' . __('Action') . '</td>' .
'<th scope="col">' . __('Description') . '</td>' .
'<th scope="col">' . __('Configuration') . '</td>' .
(DC_DEBUG ? '<th scope="col">' . __('Priority') . '</td>' : '') . /* @phpstan-ignore-line */
'</tr></thead><tbody>';
foreach ($this->improve->modules() as $action) {
if (!in_array($this->type, $action->types())) {
continue;
}
echo
'<tr class="line' . ($action->isConfigured() ? '' : ' offline') . '">' .
'<td class="minimal">' . form::checkbox(
['actions[]',
'action_' . $action->id(), ],
$action->id(),
in_array($action->id(), $this->getPreference()) && $action->isConfigured(),
'',
'',
!$action->isConfigured()
) . '</td>' .
'<td class="minimal nowrap">' .
'<label for="action_' . $action->id() . '" class="classic">' . html::escapeHTML($action->name()) . '</label>' .
'</td>' .
'<td class="maximal">' . $action->description() . '</td>' .
'<td class="minimal nowrap modules">' . (
false === $action->configurator() ? '' :
'<a class="module-config" href="' . $this->core->adminurl->get('admin.plugin.improve', ['type' => $this->type, 'config' => $action->id()]) .
'" title="' . sprintf(__("Configure action '%s'"), $action->name()) . '">' . __('Configure') . '</a>'
) . '</td>' .
(DC_DEBUG ? '<td class="minimal"><span class="debug">' . $action->priority() . '</span></td>' : '') . /* @phpstan-ignore-line */
'</tr>';
}
echo '</tbody></table>
<div class="two-cols">
<p class="col left"><label for="save_preferences" class="classic">' .
form::checkbox('save_preferences', 1, !empty($_POST['save_preferences'])) .
__('Save fields selection as preference') . '</label></p>
<p class="col right"><label for="module" class="classic">' . __('Select a module:') . ' </label>' .
form::combo('module', $combo_modules, $this->module) .
' <input type="submit" name="fix" value="' . __('Fix it') . '" />' .
form::hidden(['type'], $this->type) .
$this->core->formNonce() . '
</p>
</div>
<br class="clear" />
</form>';
if (!empty($_REQUEST['upd']) && !$this->core->blog->settings->improve->nodetails) {
$logs = $this->improve->parseLogs((int) $_REQUEST['upd']);
if (!empty($logs)) {
echo '<div class="fieldset"><h4>' . __('Details') . '</h4>';
foreach ($logs as $path => $types) {
echo '<h5>' . $path . '</h5>';
foreach ($types as $type => $tools) {
echo '<div class="' . $type . '"><ul>';
foreach ($tools as $tool => $msgs) {
$a = $this->improve->module($tool);
if (null !== $a) {
echo '<li>' . $a->name() . '<ul>';
foreach ($msgs as $msg) {
echo '<li>' . $msg . '</li>';
}
}
echo '</ul></li>';
}
echo '</ul></div>';
}
echo '';
}
echo '</div>';
}
echo '</div>';
}
}
}
}
echo '</body></html>';
/* process */
new index($core);

View file

@ -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"