Fix errors from phpstan analyze

This commit is contained in:
Jean-Christian Denis 2021-11-08 00:59:52 +01:00
parent 3b8651b1cb
commit 5417d20742
Signed by: JcDenis
GPG key ID: 1B5B8C5B90B6C951
12 changed files with 380 additions and 199 deletions

View file

@ -37,7 +37,7 @@ $_menu['Plugins']->addItem(
class ImproveBehaviors class ImproveBehaviors
{ {
public static function adminDashboardFavorites($core, $favs) public static function adminDashboardFavorites(dcCore $core, dcFavorites $favs): void
{ {
$favs->register( $favs->register(
'improve', 'improve',

View file

@ -21,7 +21,7 @@ $improve = new Improve($core);
$combo_actions = []; $combo_actions = [];
foreach ($improve->modules() as $action) { foreach ($improve->modules() as $action) {
$combo_actions[$action->name] = $action->id; $combo_actions[$action->get('name')] = $action->get('id');
} }
$disabled = $improve->disabled(); $disabled = $improve->disabled();
if (!empty($disabled)) { if (!empty($disabled)) {

View file

@ -28,14 +28,31 @@
*/ */
abstract class ImproveAction abstract class ImproveAction
{ {
/** @var dcCore dcCore instance */
protected $core; protected $core;
protected $module = [];
protected $path_full = '';
protected $path_extension = '';
protected $path_is_dir = null;
private $logs = ['success' => [], 'warning' => [], 'error' => []]; /** @var array<string> Current module */
private $settings = []; protected $module = [];
/** @var string Current full path */
protected $path_full = '';
/** @var string Current file extension */
protected $path_extension = '';
/** @var boolean Current path is directory */
protected $path_is_dir = null;
/** @var string The child class name */
private $class_name = '';
/** @var array<string, array> Messages logs */
private $logs = ['success' => [], 'warning' => [], 'error' => []];
/** @var array<string> Action module settings */
private $settings = [];
/** @var array<mixed> Action module properties */
private $properties = [ private $properties = [
'id' => '', 'id' => '',
'name' => '', 'name' => '',
@ -48,33 +65,35 @@ abstract class ImproveAction
/** /**
* ImproveAction constructor inits properpties and settings of a child class. * ImproveAction constructor inits properpties and settings of a child class.
* *
* @param string $core dcCore instance * @param dcCore $core dcCore instance
*/ */
final public function __construct(dcCore $core) final public function __construct(dcCore $core)
{ {
$this->core = $core; $this->core = $core;
$this->class_name = get_called_class();
$settings = @unserialize($core->blog->settings->improve->get('settings_' . get_called_class())); $settings = @unserialize($core->blog->settings->improve->get('settings_' . $this->class_name));
$this->settings = is_array($settings) ? $settings : []; $this->settings = is_array($settings) ? $settings : [];
$this->init(); $this->init();
// can overload priority by settings // can overload priority by settings
if (1 < ($p = (int) $core->blog->settings->improve->get('priority_' . get_called_class()))) { if (1 < ($p = (int) $core->blog->settings->improve->get('priority_' . $this->class_name))) {
$this->priority = $p; $this->properties['priority'] = $p;
} }
} }
/** /**
* Helper to create an instance of a ImproveAction child class. * Helper to create an instance of a ImproveAction child class.
* *
* @param string $o ArrayObject of actions list * @param ArrayObject $list ArrayObject of actions list
* @param string $core dcCore instance * @param dcCore $core dcCore instance
*/ */
public static function create(arrayObject $o, dcCore $core) final public static function create(arrayObject $list, dcCore $core): void
{ {
$c = get_called_class(); $child = static::class;
$o->append(new $c($core)); $class = new $child($core);
$list->append($class);
} }
/** /**
@ -90,11 +109,21 @@ abstract class ImproveAction
/// @name Properties methods /// @name Properties methods
//@{ //@{
/** /**
* @see getProperty(); * Get a definition property of action class
*
* @param string $key a property or setting id
*
* @return mixed Value of property or setting of action.
*/ */
final public function __get(string $property) final public function get(string $key)
{ {
return $this->getProperty($property); if (isset($this->properties[$key])) {
return $this->properties[$key];
} elseif (isset($this->settings[$key])) {
return $this->settings[$key];
}
return null;
} }
/** /**
@ -118,10 +147,10 @@ abstract class ImproveAction
* - config : as configuration gui, false = none, true = internal, string = ext url * - config : as configuration gui, false = none, true = internal, string = ext url
* - types : array of supported type of module, can : be plugins and/or themes * - types : array of supported type of module, can : be plugins and/or themes
* *
* @param mixed $property one or more definition * @param mixed $property one or more definition
* @param dtring $value value for a single property * @param mixed $value value for a single property
* *
* @return mixed A property of action definition. * @return boolean Success
*/ */
final protected function setProperties($property, $value = null): bool final protected function setProperties($property, $value = null): bool
{ {
@ -157,7 +186,7 @@ abstract class ImproveAction
* Set one or more setting of action class * Set one or more setting of action class
* *
* @param mixed $settings one or more settings * @param mixed $settings one or more settings
* @param string $value value for a single setting * @param mixed $value value for a single setting
* *
* @return mixed A setting of action. * @return mixed A setting of action.
*/ */
@ -178,10 +207,10 @@ abstract class ImproveAction
* *
* @param string $url redirect url after settings update * @param string $url redirect url after settings update
*/ */
final protected function redirect(string $url) final protected function redirect(string $url): bool
{ {
$this->core->blog->settings->improve->put( $this->core->blog->settings->improve->put(
'settings_' . get_called_class(), 'settings_' . $this->class_name,
serialize($this->settings), serialize($this->settings),
'string', 'string',
null, null,
@ -191,6 +220,8 @@ abstract class ImproveAction
$this->core->blog->triggerBlog(); $this->core->blog->triggerBlog();
dcPage::addSuccessNotice(__('Configuration successfully updated')); dcPage::addSuccessNotice(__('Configuration successfully updated'));
http::redirect($url); http::redirect($url);
return true;
} }
/** /**
@ -219,9 +250,9 @@ abstract class ImproveAction
* This function is also called to redirect form * This function is also called to redirect form
* after validation with $this->redirect($url); * after validation with $this->redirect($url);
* *
* @param string $url post form redirect url * @param string $url post form redirect url
* *
* @return mixed A setting of action. * @return string|null A setting of action.
*/ */
public function configure(string $url): ?string public function configure(string $url): ?string
{ {
@ -234,25 +265,29 @@ abstract class ImproveAction
* *
* @see Improve::sanitizeModule() * @see Improve::sanitizeModule()
* *
* @param array $module Full array of module definitons * @param array<string> $module Full array of module definitons
*/ */
final public function setModule(array $module) final public function setModule(array $module): bool
{ {
$this->module = $module; $this->module = $module;
return true;
} }
/** /**
* Set in class var current path definitons. * Set in class var current path definitons.
* *
* @param string $path_full Full path * @param string $path_full Full path
* @param string $path_extension Path extension (if it is a file) * @param string $path_extension Path extension (if it is a file)
* @param string $path_is_dir True if path is a directory * @param boolean $path_is_dir True if path is a directory
*/ */
final public function setPath(string $path_full, string $path_extension, bool $path_is_dir) final public function setPath(string $path_full, string $path_extension, bool $path_is_dir): bool
{ {
$this->path_full = $path_full; $this->path_full = $path_full;
$this->path_extension = $path_extension; $this->path_extension = $path_extension;
$this->path_is_dir = $path_is_dir; $this->path_is_dir = $path_is_dir;
return true;
} }
/// @name Fix methods /// @name Fix methods
@ -372,9 +407,9 @@ abstract class ImproveAction
/** /**
* Set a log of type error. * Set a log of type error.
*/ */
final public function setError(string $message) final public function setError(string $message): bool
{ {
$this->setLog('error', $message); return $this->setLog('error', $message);
} }
/** /**
@ -396,9 +431,9 @@ abstract class ImproveAction
/** /**
* Set a log of type warning. * Set a log of type warning.
*/ */
final public function setWarning(string $message) final public function setWarning(string $message): bool
{ {
$this->setLog('warning', $message); return $this->setLog('warning', $message);
} }
/** /**
@ -420,9 +455,9 @@ abstract class ImproveAction
/** /**
* Set a log of type success. * Set a log of type success.
*/ */
final public function setSuccess(string $message) final public function setSuccess(string $message): bool
{ {
$this->setLog('success', $message); return $this->setLog('success', $message);
} }
/** /**

View file

@ -15,31 +15,47 @@
*/ */
class Improve class Improve
{ {
/** @var array Allowed file extensions to open */
public static $readfile_extensions = [ public static $readfile_extensions = [
'php', 'xml', 'js', 'css', 'csv', 'html', 'htm', 'txt', 'md' 'php', 'xml', 'js', 'css', 'csv', 'html', 'htm', 'txt', 'md'
]; ];
private $core;
private $actions = [];
private $disabled = [];
private $logs = [];
private $has_log = ['success' => false, 'warning' => false, 'error' => false];
/** @var dcCore dcCore instance */
private $core;
/** @var ImproveAction[] Loaded actions modules */
private $actions = [];
/** @var array<string> Disabled actions modules */
private $disabled = [];
/** @var array<string, array> Logs by actions modules */
private $logs = [];
/** @var array<string, boolean> Has log of given type */
private $has_log = ['success' => false, 'warning' => false, 'error' => false];
/**
* Constructor
*
* @param dcCore $core dcCore instance
*/
public function __construct(dcCore $core) public function __construct(dcCore $core)
{ {
$this->core = &$core;
$core->blog->settings->addNamespace('improve'); $core->blog->settings->addNamespace('improve');
$disabled = explode(';', (string) $core->blog->settings->improve->disabled); $this->core = &$core;
$list = new arrayObject(); $disabled = explode(';', (string) $core->blog->settings->improve->disabled);
$list = new arrayObject();
try { try {
$this->core->callBehavior('improveAddAction', $list, $this->core); $this->core->callBehavior('improveAddAction', $list, $this->core);
foreach ($list as $action) { foreach ($list as $action) {
if ($action instanceof ImproveAction && !isset($this->actions[$action->id])) { if (is_a($action, 'ImproveAction') && !isset($this->actions[$action->get('id')])) {
if (in_array($action->id, $disabled)) { if (in_array($action->get('id'), $disabled)) {
$this->disabled[$action->id] = $action->name; $this->disabled[$action->get('id')] = $action->get('name');
} else { } else {
$this->actions[$action->id] = $action; $this->actions[$action->get('id')] = $action;
} }
} }
} }
@ -117,24 +133,37 @@ class Improve
return $lines; return $lines;
} }
/**
* Get a loaded action module
*
* @param string $id Module id
*
* @return ImproveAction ImproveAction instance
*/
public function module(string $id): ?ImproveAction public function module(string $id): ?ImproveAction
{ {
if (empty($id)) { if (empty($id)) {
return $this->actions; return null;
} }
return $this->actions[$id] ?? null; return $this->actions[$id] ?? null;
} }
public function modules(): ?array /**
* Get all loaded action modules
*
* @return ImproveAction[] ImproveAction instance
*/
public function modules(): array
{ {
if (empty($id)) { return $this->actions;
return $this->actions;
}
return $this->actions[$id] ?? null;
} }
/**
* Get disabled action modules
*
* @return array Array of id/name modules
*/
public function disabled(): array public function disabled(): array
{ {
return $this->disabled; return $this->disabled;
@ -153,7 +182,7 @@ class Improve
} }
foreach ($workers as $action) { foreach ($workers as $action) {
// trace all path and action in logs // trace all path and action in logs
$this->logs['improve'][__('Begin')][] = $action->id; $this->logs['improve'][__('Begin')][] = $action->get('id');
// info: set current module // info: set current module
$action->setModule($module); $action->setModule($module);
$action->setPath(__('Begin'), '', true); $action->setPath(__('Begin'), '', true);
@ -170,7 +199,7 @@ class Improve
} }
foreach ($workers as $action) { foreach ($workers as $action) {
// trace all path and action in logs // trace all path and action in logs
$this->logs['improve'][$file[0]][] = $action->id; $this->logs['improve'][$file[0]][] = $action->get('id');
// info: set current path // info: set current path
$action->setPath($file[0], $file[1], $file[2]); $action->setPath($file[0], $file[1], $file[2]);
} }
@ -194,7 +223,7 @@ class Improve
throw new Exception(sprintf( throw new Exception(sprintf(
__('File content has been removed: %s by %s'), __('File content has been removed: %s by %s'),
$file[0], $file[0],
$action->name $action->get('name')
)); ));
} }
} }
@ -209,7 +238,7 @@ class Improve
} }
foreach ($workers as $action) { foreach ($workers as $action) {
// trace all path and action in logs // trace all path and action in logs
$this->logs['improve'][__('End')][] = $action->id; $this->logs['improve'][__('End')][] = $action->get('id');
// info: set current module // info: set current module
$action->setPath(__('End'), '', true); $action->setPath(__('End'), '', true);
// action: close module // action: close module
@ -217,7 +246,7 @@ class Improve
} }
// info: get acions reports // info: get acions reports
foreach ($workers as $action) { foreach ($workers as $action) {
$this->logs[$action->id] = $action->getLogs(); $this->logs[$action->get('id')] = $action->getLogs();
foreach ($this->has_log as $type => $v) { foreach ($this->has_log as $type => $v) {
if ($action->hasLog($type)) { if ($action->hasLog($type)) {
$this->has_log[$type] = true; $this->has_log[$type] = true;
@ -225,12 +254,15 @@ class Improve
} }
} }
return substr(microtime(true) - $time_start, 0, 5); return round(microtime(true) - $time_start, 5);
} }
private static function getModuleFiles(string $path, string $dir = '', array $res = []): array private static function getModuleFiles(string $path, string $dir = '', array $res = []): array
{ {
$path = path::real($path); $path = path::real($path);
if (!$path) {
return [];
}
if (!is_dir($path) || !is_readable($path)) { if (!is_dir($path) || !is_readable($path)) {
return []; return [];
} }
@ -251,7 +283,7 @@ class Improve
$res $res
); );
} else { } else {
$res[] = [empty($dir) ? $file : $dir . '/' . $file, files::getExtension($file), true]; $res[] = [$dir . '/' . $file, files::getExtension($file), true];
} }
} }
@ -263,7 +295,7 @@ class Improve
return $this->core->adminurl->get('admin.plugin.improve', $params, '&'); return $this->core->adminurl->get('admin.plugin.improve', $params, '&');
} }
public static function cleanExtensions($in): array public static function cleanExtensions(string|array $in): array
{ {
$out = []; $out = [];
if (!is_array($in)) { if (!is_array($in)) {
@ -281,32 +313,61 @@ class Improve
return $out; return $out;
} }
private function sortModules(improveAction $a, improveAction $b): int /**
* Sort modules by priority then name
*
* @param ImproveAction $a ImproveAction instance
* @param ImproveAction $b ImproveAction instance
*
* @return integer Is higher
*/
private function sortModules(ImproveAction $a, ImproveAction $b): int
{ {
if ($a->priority == $b->priority) { if ($a->get('priority') == $b->get('priority')) {
return strcasecmp($a->name, $b->name); return strcasecmp($a->get('name'), $b->get('name'));
} }
return $a->priority < $b->priority ? -1 : 1; return $a->get('priority') < $b->get('priority') ? -1 : 1;
} }
} }
class ImproveDefinition class ImproveDefinition
{ {
/** @var array Current module properties */
private $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 = []) public function __construct(string $type, string $id, array $properties = [])
{ {
$this->loadDefine($id, $properties['root']); $this->loadDefine($id, $properties['root']);
$this->properties = array_merge($this->properties, self::sanitizeModule($type, $id, $properties)); $this->properties = array_merge($this->properties, self::sanitizeModule($type, $id, $properties));
} }
public function get() /**
* Get module properties
*
* @return array The properties
*/
public function get(): array
{ {
return $this->properties; 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 public static function clean(string $type, string $id, array $properties): array
{ {
$p = new self($type, $id, $properties); $p = new self($type, $id, $properties);
@ -314,19 +375,37 @@ class ImproveDefinition
return $p->get(); return $p->get();
} }
private function loadDefine($id, $root) /**
* 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')) { if (file_exists($root . '/_define.php')) {
$this->id = $id;
$this->mroot = $root;
ob_start(); ob_start();
require $root . '/_define.php'; require $root . '/_define.php';
ob_end_clean(); ob_end_clean();
} }
return true;
} }
# adapt from class.dc.modules.php /**
private function registerModule($name, $desc, $author, $version, $properties = []) * 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, string|array $properties = []): bool // @phpstan-ignore-line
{ {
if (!is_array($properties)) { if (!is_array($properties)) {
$args = func_get_args(); $args = func_get_args();
@ -352,9 +431,19 @@ class ImproveDefinition
], ],
$properties $properties
); );
return true;
} }
# adapt from lib.moduleslist.php /**
* 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 public static function sanitizeModule(string $type, string $id, array $properties): array
{ {
$label = empty($properties['label']) ? $id : $properties['label']; $label = empty($properties['label']) ? $id : $properties['label'];
@ -402,9 +491,15 @@ class ImproveDefinition
); );
} }
# taken from lib.moduleslist.php /**
* Replicate adminModulesList::sanitizeString
*
* @param string $str String to sanitize
*
* @return string Sanitized string
*/
public static function sanitizeString(string $str): string public static function sanitizeString(string $str): string
{ {
return preg_replace('/[^A-Za-z0-9\@\#+_-]/', '', strtolower($str)); return (string) preg_replace('/[^A-Za-z0-9\@\#+_-]/', '', strtolower($str));
} }
} }

View file

@ -74,7 +74,7 @@ class ImproveActionDcstore extends ImproveAction
return true; return true;
} }
public function generateXML() public function generateXML(): string
{ {
$xml = ['<modules xmlns:da="http://dotaddict.org/da/">']; $xml = ['<modules xmlns:da="http://dotaddict.org/da/">'];
$rsp = new xmlTag('module'); $rsp = new xmlTag('module');
@ -179,13 +179,13 @@ class ImproveActionDcstore extends ImproveAction
$dom->formatOutput = true; $dom->formatOutput = true;
$dom->loadXML($str); $dom->loadXML($str);
return $dom->saveXML(); return (string) $dom->saveXML();
} }
return str_replace('><', ">\n<", $str); return str_replace('><', ">\n<", $str);
} }
private function parseFilePattern() private function parseFilePattern(): string
{ {
return text::tidyURL(str_replace( return text::tidyURL(str_replace(
[ [

View file

@ -12,11 +12,19 @@
*/ */
class ImproveActionGitshields extends ImproveAction class ImproveActionGitshields extends ImproveAction
{ {
private $stop_scan = false; /** @var boolean Stop scaning files */
private $stop_scan = false;
/** @var array Parsed bloc */
private $blocs = [];
/** @var array Search patterns */
protected $bloc_pattern = [ protected $bloc_pattern = [
'remove' => '/\[!\[Release(.*)LICENSE\)/ms', 'remove' => '/\[!\[Release(.*)LICENSE\)/ms',
'target' => '/^([^\n]+)[\r\n|\n]{1,}/ms' 'target' => '/^([^\n]+)[\r\n|\n]{1,}/ms'
]; ];
/** @var array Shields patterns */
protected $bloc_content = [ protected $bloc_content = [
'release' => '[![Release](https://img.shields.io/github/v/release/%username%/%module%)](https://github.com/%username%/%module%/releases)', 'release' => '[![Release](https://img.shields.io/github/v/release/%username%/%module%)](https://github.com/%username%/%module%/releases)',
'date' => '[![Date](https://img.shields.io/github/release-date/%username%/%module%)](https://github.com/%username%/%module%/releases)', 'date' => '[![Date](https://img.shields.io/github/release-date/%username%/%module%)](https://github.com/%username%/%module%/releases)',
@ -87,14 +95,14 @@ class ImproveActionGitshields extends ImproveAction
return true; return true;
} }
private function replaceInfo() private function replaceInfo(): void
{ {
$bloc = []; $blocs = [];
foreach ($this->bloc_content as $k => $v) { foreach ($this->bloc_content as $k => $v) {
if ($k == 'dotaddict' && empty($this->getSetting('dotaddict'))) { if ($k == 'dotaddict' && empty($this->getSetting('dotaddict'))) {
continue; continue;
} }
$bloc[$k] = trim(str_replace( $blocs[$k] = trim(str_replace(
[ [
'%username%', '%username%',
'%module%', '%module%',
@ -112,11 +120,11 @@ class ImproveActionGitshields extends ImproveAction
$v $v
)); ));
} }
$this->bloc = $bloc; $this->blocs = $blocs;
$this->setSuccess(__('Prepare custom shield info')); $this->setSuccess(__('Prepare custom shield info'));
} }
private function getDotclearVersion() private function getDotclearVersion(): string
{ {
$version = null; $version = null;
if (!empty($this->module['requires']) && is_array($this->module['requires'])) { if (!empty($this->module['requires']) && is_array($this->module['requires'])) {
@ -137,23 +145,23 @@ class ImproveActionGitshields extends ImproveAction
return $version ?: $this->core->getVersion('core'); return $version ?: $this->core->getVersion('core');
} }
private function writeShieldsBloc($content) private function writeShieldsBloc(string $content): string
{ {
$res = preg_replace( $res = preg_replace(
$this->bloc_pattern['target'], $this->bloc_pattern['target'],
'$1' . "\n\n" . trim(implode("\n", $this->bloc)) . "\n\n", '$1' . "\n\n" . trim(implode("\n", $this->blocs)) . "\n\n",
$content, $content,
1, 1,
$count $count
); );
if ($count) { if ($count && $res) {
$this->setSuccess(__('Write new shield bloc')); $this->setSuccess(__('Write new shield bloc'));
} }
return $res; return (string) $res;
} }
private function deleteShieldsBloc($content) private function deleteShieldsBloc(string $content): string
{ {
$res = preg_replace( $res = preg_replace(
$this->bloc_pattern['remove'], $this->bloc_pattern['remove'],
@ -162,10 +170,10 @@ class ImproveActionGitshields extends ImproveAction
1, 1,
$count $count
); );
if ($count) { if ($count && $res) {
$this->setSuccess(__('Delete old shield bloc')); $this->setSuccess(__('Delete old shield bloc'));
} }
return $res; return (string) $res;
} }
} }

View file

@ -12,14 +12,18 @@
*/ */
class ImproveActionLicensefile extends ImproveAction class ImproveActionLicensefile extends ImproveAction
{ {
/** @var array Possible license filenames */
protected static $license_filenames = [ protected static $license_filenames = [
'license', 'license',
'license.md', 'license.md',
'license.txt' 'license.txt'
]; ];
/** @var array Possible license names */
private $action_version = []; private $action_version = [];
private $action_full = [];
private $stop_scan = false; /** @var array Action */
private $action_full = [];
protected function init(): bool protected function init(): bool
{ {
@ -90,7 +94,7 @@ class ImproveActionLicensefile extends ImproveAction
return null; return null;
} }
private function writeFullLicense() private function writeFullLicense(): ?bool
{ {
try { try {
$full = file_get_contents(dirname(__FILE__) . '/license/' . $this->getSetting('action_version') . '.full.txt'); $full = file_get_contents(dirname(__FILE__) . '/license/' . $this->getSetting('action_version') . '.full.txt');
@ -110,7 +114,7 @@ class ImproveActionLicensefile extends ImproveAction
return true; return true;
} }
private function deleteFullLicense($only_one = false) private function deleteFullLicense(bool $only_one = false): bool
{ {
foreach (self::fileExists($this->module['root']) as $file) { foreach (self::fileExists($this->module['root']) as $file) {
if ($only_one && $file != 'LICENSE') { if ($only_one && $file != 'LICENSE') {
@ -128,7 +132,7 @@ class ImproveActionLicensefile extends ImproveAction
return true; return true;
} }
private static function fileExists($root) private static function fileExists(string $root): array
{ {
$existing = []; $existing = [];
foreach (self::$license_filenames as $file) { foreach (self::$license_filenames as $file) {

View file

@ -47,8 +47,6 @@ class ImproveActionTab extends ImproveAction
class ImproveActionNewline extends ImproveAction class ImproveActionNewline extends ImproveAction
{ {
private $extensions = ['php', 'js', 'xml', 'md', 'txt'];
protected function init(): bool protected function init(): bool
{ {
$this->setProperties([ $this->setProperties([
@ -98,19 +96,19 @@ class ImproveActionNewline extends ImproveAction
'</p>'; '</p>';
} }
public function readFile(&$content): ?bool public function readFile(string &$content): ?bool
{ {
$ext = $this->getSetting('extensions'); $ext = $this->getSetting('extensions');
if (!is_array($ext) || !in_array($this->path_extension, $ext)) { if (!is_array($ext) || !in_array($this->path_extension, $ext)) {
return null; return null;
} }
$clean = preg_replace( $clean = (string) preg_replace(
'/(\n\s+\n)/', '/(\n\s+\n)/',
"\n\n", "\n\n",
preg_replace( (string) preg_replace(
'/(\n\n+)/', '/(\n\n+)/',
"\n\n", "\n\n",
str_replace( (string) str_replace(
["\r\n", "\r"], ["\r\n", "\r"],
"\n", "\n",
$content $content
@ -128,8 +126,6 @@ class ImproveActionNewline extends ImproveAction
class ImproveActionEndoffile extends ImproveAction class ImproveActionEndoffile extends ImproveAction
{ {
private $psr2 = false;
protected function init(): bool protected function init(): bool
{ {
$this->setProperties([ $this->setProperties([

View file

@ -12,6 +12,7 @@
*/ */
class ImproveActionPhpcsfixer extends ImproveAction class ImproveActionPhpcsfixer extends ImproveAction
{ {
/** @var array<int,string> Type of runtime errors */
protected static $errors = [ protected static $errors = [
0 => 'OK.', 0 => 'OK.',
1 => 'General error (or PHP minimal requirement not matched).', 1 => 'General error (or PHP minimal requirement not matched).',
@ -21,7 +22,11 @@ class ImproveActionPhpcsfixer extends ImproveAction
32 => 'Configuration error of a Fixer.', 32 => 'Configuration error of a Fixer.',
64 => 'Exception raised within the application' 64 => 'Exception raised within the application'
]; ];
protected static $user_ui_colorsyntax = false;
/** @var boolean User pref to use colored synthax */
protected static $user_ui_colorsyntax = false;
/** @var string User pref for colored synthax theme */
protected static $user_ui_colorsyntax_theme = 'default'; protected static $user_ui_colorsyntax_theme = 'default';
protected function init(): bool protected function init(): bool
@ -64,7 +69,7 @@ class ImproveActionPhpcsfixer extends ImproveAction
]); ]);
$this->redirect($url); $this->redirect($url);
} }
$content = file_get_contents(dirname(__FILE__) . '/libs/dc.phpcsfixer.rules.php'); $content = (string) file_get_contents(dirname(__FILE__) . '/libs/dc.phpcsfixer.rules.php');
return return
'<p><label class="classic" for="phpexe_path">' . '<p><label class="classic" for="phpexe_path">' .
@ -124,13 +129,18 @@ class ImproveActionPhpcsfixer extends ImproveAction
} }
} }
private function getPhpPath() /**
* Get php executable path
*
* @return string The path
*/
private function getPhpPath(): string
{ {
$phpexe_path = $this->getSetting('phpexe_path'); $phpexe_path = $this->getSetting('phpexe_path');
if (empty($phpexe_path) && !empty(PHP_BINDIR)) { if (empty($phpexe_path) && !empty(PHP_BINDIR)) {
$phpexe_path = PHP_BINDIR; $phpexe_path = PHP_BINDIR;
} }
return path::real($phpexe_path); return (string) path::real($phpexe_path);
} }
} }

View file

@ -12,7 +12,8 @@
*/ */
class ImproveActionPhpheader extends ImproveAction class ImproveActionPhpheader extends ImproveAction
{ {
private static $exemple = " /** @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 @package Dotclear
@ -21,8 +22,10 @@ class ImproveActionPhpheader extends ImproveAction
@author %module_author% @author %module_author%
@copyright %user_cn% @copyright %user_cn%
@copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html"; @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
EOF;
/** @var array<string> Allowed bloc replacement */
private $bloc_wildcards = [ private $bloc_wildcards = [
'%year%', '%year%',
'%module_id%', '%module_id%',
@ -34,10 +37,15 @@ class ImproveActionPhpheader extends ImproveAction
'%user_email%', '%user_email%',
'%user_url%' '%user_url%'
]; ];
private $bloc_action = [];
private $bloc_content = ''; /** @var array Allowed action for header */
private $stop_scan = false; private $action_bloc = [];
/** @var string Parsed bloc */
private $bloc = '';
/** @var boolean Stop parsing files */
private $stop_scan = false;
protected function init(): bool protected function init(): bool
{ {
@ -106,9 +114,47 @@ class ImproveActionPhpheader extends ImproveAction
public function openModule(): ?bool public function openModule(): ?bool
{ {
$this->replaceInfo(); $bloc = trim($this->getSetting('bloc_content'));
return null; if (empty($bloc)) {
$this->setWarning(__('bloc is empty'));
return null;
}
$bloc = trim(str_replace("\r\n", "\n", $bloc));
try {
$this->bloc = (string) preg_replace_callback(
// use \u in bloc content for first_upper_case
'/(\\\u([a-z]{1}))/',
function ($str) {
return ucfirst($str[2]);
},
str_replace(
$this->bloc_wildcards,
[
date('Y'),
$this->module['id'],
$this->module['name'],
$this->module['author'],
$this->module['type'],
$this->core->auth->getInfo('user_cn'),
$this->core->auth->getinfo('user_name'),
$this->core->auth->getInfo('user_email'),
$this->core->auth->getInfo('user_url')
],
(string) $bloc
)
);
$this->setSuccess(__('Prepare header info'));
return null;
} catch (Exception $e) {
$this->setError(__('Failed to parse bloc'));
return null;
}
} }
public function openDirectory(): ?bool public function openDirectory(): ?bool
@ -155,50 +201,13 @@ class ImproveActionPhpheader extends ImproveAction
return true; return true;
} }
private function replaceInfo() /**
{ * Write bloc content in file content
$bloc = trim($this->getSetting('bloc_content')); *
* @param string $content Old content
if (empty($bloc)) { * @return string New content
$this->setWarning(__('bloc is empty')); */
private function writeDocBloc(string $content): string
return null;
}
$bloc = trim(str_replace("\r\n", "\n", $bloc));
try {
$this->bloc = preg_replace_callback(
// use \u in bloc content for first_upper_case
'/(\\\u([a-z]{1}))/',
function ($str) {
return ucfirst($str[2]);
},
str_replace(
$this->bloc_wildcards,
[
date('Y'),
$this->module['id'],
$this->module['name'],
$this->module['author'],
$this->module['type'],
$this->core->auth->getInfo('user_cn'),
$this->core->auth->getinfo('user_name'),
$this->core->auth->getInfo('user_email'),
$this->core->auth->getInfo('user_url')
],
$bloc
)
);
$this->setSuccess(__('Prepare header info'));
} catch (Exception $e) {
$this->setError(__('Failed to parse bloc'));
return null;
}
}
private function writeDocBloc($content)
{ {
$res = preg_replace( $res = preg_replace(
'/^(\<\?php[\n|\r\n]+)/', '/^(\<\?php[\n|\r\n]+)/',
@ -207,15 +216,21 @@ class ImproveActionPhpheader extends ImproveAction
1, 1,
$count $count
); );
if ($count) { if ($count && $res) {
$res = str_replace("\n * \n", "\n *\n", $res); $res = str_replace("\n * \n", "\n *\n", $res);
$this->setSuccess(__('Write new doc bloc content')); $this->setSuccess(__('Write new doc bloc content'));
} }
return $res; return (string) $res;
} }
private function deleteDocBloc($content) /**
* Delete bloc content in file content
*
* @param string $content Old content
* @return string New content
*/
private function deleteDocBloc(string $content): string
{ {
$res = preg_replace( $res = preg_replace(
'/^(\<\?php\s*[\n|\r\n]{0,1}\s*\/\*\*.*?\s*\*\/\s*[\n|\r\n]+)/msi', '/^(\<\?php\s*[\n|\r\n]{0,1}\s*\/\*\*.*?\s*\*\/\s*[\n|\r\n]+)/msi',
@ -228,10 +243,16 @@ class ImproveActionPhpheader extends ImproveAction
$this->setSuccess(__('Delete old doc bloc content')); $this->setSuccess(__('Delete old doc bloc content'));
} }
return $res; return (string) $res;
} }
private function deleteOldBloc($content) /**
* Delete old style bloc content in file content
*
* @param string $content Old content
* @return string New content
*/
private function deleteOldBloc(string $content): string
{ {
$res = preg_replace( $res = preg_replace(
'/((# -- BEGIN LICENSE BLOCK ([-]+))(.*?)(# -- END LICENSE BLOCK ([-]+))([\n|\r\n]{1,}))/msi', '/((# -- BEGIN LICENSE BLOCK ([-]+))(.*?)(# -- END LICENSE BLOCK ([-]+))([\n|\r\n]{1,}))/msi',
@ -244,6 +265,6 @@ class ImproveActionPhpheader extends ImproveAction
$this->setSuccess(__('Delete old style bloc content')); $this->setSuccess(__('Delete old style bloc content'));
} }
return $res; return (string) $res;
} }
} }

View file

@ -12,6 +12,7 @@
*/ */
class ImproveActionZip extends ImproveAction class ImproveActionZip extends ImproveAction
{ {
/** @var array List of excluded file pattern */
public static $exclude = [ public static $exclude = [
'.', '.',
'..', '..',
@ -24,6 +25,8 @@ class ImproveActionZip extends ImproveAction
'Thumbs.db', 'Thumbs.db',
'_disabled' '_disabled'
]; ];
/** @var array Replacement wildcards */
public static $filename_wildcards = [ public static $filename_wildcards = [
'%type%', '%type%',
'%id%', '%id%',
@ -32,8 +35,6 @@ class ImproveActionZip extends ImproveAction
'%time%' '%time%'
]; ];
private $package = '';
protected function init(): bool protected function init(): bool
{ {
$this->setProperties([ $this->setProperties([
@ -137,7 +138,7 @@ class ImproveActionZip extends ImproveAction
return null; return null;
} }
private function zipModule(string $file, array $exclude) private function zipModule(string $file, array $exclude): void
{ {
$file = str_replace( $file = str_replace(
self::$filename_wildcards, self::$filename_wildcards,
@ -158,12 +159,12 @@ class ImproveActionZip extends ImproveAction
if (file_exists($path) && empty($this->getSetting('pack_overwrite'))) { if (file_exists($path) && empty($this->getSetting('pack_overwrite'))) {
$this->setWarning(__('Destination filename already exists')); $this->setWarning(__('Destination filename already exists'));
return null; return;
} }
if (!is_dir(dirname($path)) || !is_writable(dirname($path))) { if (!is_dir(dirname($path)) || !is_writable(dirname($path))) {
$this->setError(__('Destination path is not writable')); $this->setError(__('Destination path is not writable'));
return null; return;
} }
@set_time_limit(300); @set_time_limit(300);
$fp = fopen($path, 'wb'); $fp = fopen($path, 'wb');
@ -187,24 +188,34 @@ class ImproveActionZip extends ImproveAction
$this->setSuccess(sprintf(__('Zip module into "%s"'), $path)); $this->setSuccess(sprintf(__('Zip module into "%s"'), $path));
return null;
} }
} }
class ImproveZipFileZip extends fileZip class ImproveZipFileZip extends fileZip
{ {
/** @var boolean Should remove comments from files */
public static $remove_comment = false; public static $remove_comment = false;
/**
* Replace clearbrick fileZip::writeFile
*
* @param string $name Name
* @param string $file File
* @param int $size Size
* @param int $mtime Mtime
*
* @return void
*/
protected function writeFile($name, $file, $size, $mtime) protected function writeFile($name, $file, $size, $mtime)
{ {
if (!isset($this->entries[$name])) { if (!isset($this->entries[$name])) {
return null; return;
} }
$size = filesize($file); $size = filesize($file);
$this->memoryAllocate($size * 3); $this->memoryAllocate($size * 3);
$content = file_get_contents($file); $content = (string) file_get_contents($file);
if (self::$remove_comment && substr($file, -4) == '.php') { if (self::$remove_comment && substr($file, -4) == '.php') {
$content = self::removePHPComment($content); $content = self::removePHPComment($content);
@ -212,7 +223,7 @@ class ImproveZipFileZip extends fileZip
$unc_len = strlen($content); $unc_len = strlen($content);
$crc = crc32($content); $crc = crc32($content);
$zdata = gzdeflate($content); $zdata = (string) gzdeflate($content);
$c_len = strlen($zdata); $c_len = strlen($zdata);
unset($content); unset($content);
@ -267,7 +278,7 @@ class ImproveZipFileZip extends fileZip
$this->ctrl_dir[] = $cdrec; $this->ctrl_dir[] = $cdrec;
} }
protected static function removePHPComment($content) protected static function removePHPComment(string $content): string
{ {
$comment = [T_COMMENT]; $comment = [T_COMMENT];
if (defined('T_DOC_COMMENT')) { if (defined('T_DOC_COMMENT')) {

View file

@ -31,8 +31,8 @@ if (!empty($_POST['save_preferences'])) {
$preferences[$type] = []; $preferences[$type] = [];
if (!empty($_POST['actions'])) { if (!empty($_POST['actions'])) {
foreach ($improve->modules() as $action) { foreach ($improve->modules() as $action) {
if (in_array($type, $action->types) && in_array($action->id, $_POST['actions'])) { if (in_array($type, $action->get('types')) && in_array($action->get('id'), $_POST['actions'])) {
$preferences[$type][] = $action->id; $preferences[$type][] = $action->get('id');
} }
} }
} }
@ -141,18 +141,18 @@ if (!empty($_REQUEST['config'])) {
$back_url = $_REQUEST['redir'] ?? $core->adminurl->get('admin.plugin.improve', ['type' => $type]); $back_url = $_REQUEST['redir'] ?? $core->adminurl->get('admin.plugin.improve', ['type' => $type]);
if (null !== $action) { if (null !== $action) {
$redir = $_REQUEST['redir'] ?? $core->adminurl->get('admin.plugin.improve', ['type' => $type, 'config' => $action->id]); $redir = $_REQUEST['redir'] ?? $core->adminurl->get('admin.plugin.improve', ['type' => $type, 'config' => $action->get('id')]);
$res = $action->configure($redir); $res = $action->configure($redir);
echo ' echo '
<h3>' . sprintf(__('Configure module "%s"'), $action->name) . '</h3> <h3>' . sprintf(__('Configure module "%s"'), $action->get('name')) . '</h3>
<p><a class="back" href="' . $back_url . '">' . __('Back') . '</a></p> <p><a class="back" href="' . $back_url . '">' . __('Back') . '</a></p>
<p class="info">' . html::escapeHTML($action->desc) . '</p> <p class="info">' . html::escapeHTML($action->get('desc')) . '</p>
<form action="' . $core->adminurl->get('admin.plugin.improve') . '" method="post" id="form-actions">' . <form action="' . $core->adminurl->get('admin.plugin.improve') . '" method="post" id="form-actions">' .
(empty($res) ? '<p class="message">' . __('Nothing to configure') . '</p>' : $res) . ' (empty($res) ? '<p class="message">' . __('Nothing to configure') . '</p>' : $res) . '
<p class="clear"><input type="submit" name="save" value="' . __('Save') . '" />' . <p class="clear"><input type="submit" name="save" value="' . __('Save') . '" />' .
form::hidden('type', $type) . form::hidden('type', $type) .
form::hidden('config', $action->id) . form::hidden('config', $action->get('id')) .
form::hidden('redir', $redir) . form::hidden('redir', $redir) .
$core->formNonce() . '</p>' . $core->formNonce() . '</p>' .
'</form>'; '</form>';
@ -173,31 +173,31 @@ if (!empty($_REQUEST['config'])) {
(DC_DEBUG ? '<th scope="col">' . __('Priority') . '</td>' : '') . (DC_DEBUG ? '<th scope="col">' . __('Priority') . '</td>' : '') .
'</tr></thead><tbody>'; '</tr></thead><tbody>';
foreach ($improve->modules() as $action) { foreach ($improve->modules() as $action) {
if (!in_array($type, $action->types)) { if (!in_array($type, $action->get('types'))) {
continue; continue;
} }
echo echo
'<tr class="line' . ($action->isConfigured() ? '' : ' offline') . '">' . '<tr class="line' . ($action->isConfigured() ? '' : ' offline') . '">' .
'<td class="minimal">' . form::checkbox( '<td class="minimal">' . form::checkbox(
['actions[]', ['actions[]',
'action_' . $action->id], 'action_' . $action->get('id')],
$action->id, $action->get('id'),
in_array($action->id, $preferences[$type]) && $action->isConfigured(), in_array($action->get('id'), $preferences[$type]) && $action->isConfigured(),
'', '',
'', '',
!$action->isConfigured() !$action->isConfigured()
) . '</td>' . ) . '</td>' .
'<td class="minimal nowrap">' . '<td class="minimal nowrap">' .
'<label for="action_' . $action->id . '" class="classic">' . html::escapeHTML($action->name) . '</label>' . '<label for="action_' . $action->get('id') . '" class="classic">' . html::escapeHTML($action->get('name')) . '</label>' .
'</td>' . '</td>' .
'<td class="maximal">' . $action->desc . '</td>' . '<td class="maximal">' . $action->get('desc') . '</td>' .
'<td class="minimal nowrap modules">' . ( '<td class="minimal nowrap modules">' . (
false === $action->config ? '' : false === $action->get('config') ? '' :
'<a class="module-config" href="' . '<a class="module-config" href="' .
(true === $action->config ? $core->adminurl->get('admin.plugin.improve', ['type' => $type, 'config' => $action->id]) : $action->config) . (true === $action->get('config') ? $core->adminurl->get('admin.plugin.improve', ['type' => $type, 'config' => $action->get('id')]) : $action->get('config')) .
'" title="' . sprintf(__("Configure action '%s'"), $action->name) . '">' . __('Configure') . '</a>' '" title="' . sprintf(__("Configure action '%s'"), $action->get('name')) . '">' . __('Configure') . '</a>'
) . '</td>' . ) . '</td>' .
(DC_DEBUG ? '<td class="minimal"><span class="debug">' . $action->priority . '</span></td>' : '') . (DC_DEBUG ? '<td class="minimal"><span class="debug">' . $action->get('priority') . '</span></td>' : '') .
'</tr>'; '</tr>';
} }
@ -226,7 +226,8 @@ if (!empty($_REQUEST['config'])) {
foreach ($types as $type => $tools) { foreach ($types as $type => $tools) {
echo '<div class="' . $type . '"><ul>'; echo '<div class="' . $type . '"><ul>';
foreach ($tools as $tool => $msgs) { foreach ($tools as $tool => $msgs) {
echo '<li>' . $improve->module($tool)->name . '<ul>'; $a = $improve->module($tool);
echo '<li>' . ($a !== null ? $a->get('name') : 'unknow') . '<ul>';
foreach ($msgs as $msg) { foreach ($msgs as $msg) {
echo '<li>' . $msg . '</li>'; echo '<li>' . $msg . '</li>';
} }