diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad31f6b..05f59e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+tweakStores 1.1 - 2023.10.21
+===========================================================
+* Require Dotclear 2.28
+* Require PHP 8.1
+* Upgrade to Dotclear 2.28
+* Code review (phpstan)
+
tweakStores 1.0 - 2023.08.14
===========================================================
* Require Dotclear 2.27
diff --git a/README.md b/README.md
index ef69184..72a9800 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,22 @@
# README
[![Release](https://img.shields.io/badge/release-1.0-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/tweakStores/releases)
-[![Date](https://img.shields.io/badge/date-2023.08.15-c44d58.svg)](https://git.dotclear.watch/JcDenis/tweakStores/releases)
+![Date](https://img.shields.io/badge/date-2023.08.15-c44d58.svg)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.27-137bbb.svg)](https://fr.dotclear.org/download)
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/tweakStores)
-[![License](https://img.shields.io/github/license/JcDenis/tweakStores)](https://git.dotclear.watch/JcDenis/tweakStores/blob/master/LICENSE)
+[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/LICENSE)
-## WHAT IS TWEAKSTORES ?
+## ABOUT
-"tweakStores" is a plugin for the open-source
-web publishing software called Dotclear.
+_tweakStores_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org).
-It helps devs to manage dcstore.xml file.
+> Help devs to manage dcstore.xml file.
## REQUIREMENTS
-_tweakStores_ requires:
-
-* superadmin permissions
-* Dotclear 2.27
+* Dotclear 2.28
* PHP 8.1+
+* Dotclear superadmin permissions
## USAGE
@@ -32,9 +29,10 @@ package creation.
## LINKS
-* License : [GNU GPL v2](https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html)
-* Source & contribution : [Gitea Page](https://git.dotclear.watch/JcDenis/tweakStores) or [GitHub Page](https://github.com/JcDenis/tweakStores)
-* Packages & details: [Gitea Page](https://git.dotclear.watch/JcDenis/tweakStores/releases) or [Dotaddict Page](https://plugins.dotaddict.org/dc2/details/tweakStores)
+* [License](https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/LICENSE)
+* [Packages & details](https://git.dotclear.watch/JcDenis/tweakStores/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/tweakStores))
+* [Sources & contributions](https://git.dotclear.watch/JcDenis/tweakStores) (or on [GitHub](https://github.com/JcDenis/tweakStores))
+* [Issues & security](https://git.dotclear.watch/JcDenis/tweakStores/issues) (or on [GitHub](https://github.com/JcDenis/tweakStores/issues))
## CONTRIBUTORS
diff --git a/_define.php b/_define.php
index 4073cea..04b03b7 100644
--- a/_define.php
+++ b/_define.php
@@ -1,30 +1,26 @@
registerModule(
'Tweak stores',
'Helper to manage external repositories',
'Jean-Christian Denis and Contributors',
- '1.0',
+ '1.1',
[
- 'requires' => [
- ['php', '8.1'],
- ['core', '2.27'],
- ],
- 'permissions' => null,
+ 'requires' => [['core', '2.28']],
+ 'permissions' => 'My',
'type' => 'plugin',
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues',
'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md',
diff --git a/dcstore.xml b/dcstore.xml
index 60343d9..7872c19 100644
--- a/dcstore.xml
+++ b/dcstore.xml
@@ -2,11 +2,11 @@
Tweak stores
- 1.0
+ 1.1
Jean-Christian Denis and Contributors
Helper to manage external repositories
- https://git.dotclear.watch/JcDenis/tweakStores/releases/download/v1.0/plugin-tweakStores.zip
- 2.27
+ https://git.dotclear.watch/JcDenis/tweakStores/releases/download/v1.1/plugin-tweakStores.zip
+ 2.28
https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/README.md
https://git.dotclear.watch/JcDenis/tweakStores/issues
diff --git a/src/Backend.php b/src/Backend.php
index 19e4ca6..3ff3d01 100644
--- a/src/Backend.php
+++ b/src/Backend.php
@@ -1,22 +1,19 @@
addBehaviors([
+ App::behavior()->addBehaviors([
// addd some js
- 'pluginsToolsHeadersV2' => [BackendBehaviors::class, 'modulesToolsHeaders'],
- 'themesToolsHeadersV2' => [BackendBehaviors::class, 'modulesToolsHeaders'],
+ 'pluginsToolsHeadersV2' => BackendBehaviors::modulesToolsHeaders(...),
+ 'themesToolsHeadersV2' => BackendBehaviors::modulesToolsHeaders(...),
// admin modules page tab
- 'pluginsToolsTabsV2' => [BackendBehaviors::class, 'pluginsToolsTabsV2'],
- 'themesToolsTabsV2' => [BackendBehaviors::class, 'themesToolsTabsV2'],
+ 'pluginsToolsTabsV2' => BackendBehaviors::pluginsToolsTabsV2(...),
+ 'themesToolsTabsV2' => BackendBehaviors::themesToolsTabsV2(...),
// add to plugin pacKman
- 'packmanBeforeCreatePackage' => [BackendBehaviors::class, 'packmanBeforeCreatePackage'],
+ 'packmanBeforeCreatePackage' => BackendBehaviors::packmanBeforeCreatePackage(...),
]);
return true;
diff --git a/src/BackendBehaviors.php b/src/BackendBehaviors.php
index 0be0d67..02c9dcd 100644
--- a/src/BackendBehaviors.php
+++ b/src/BackendBehaviors.php
@@ -1,22 +1,12 @@
$notice
+ */
private static $notice = [];
- /** @var array List of failed messages */
+ /**
+ * List of failed messages.
+ *
+ * @var array $failed
+ */
private static $failed = [];
- /** @var Settings Module settings */
+ /**
+ * Module settings.
+ *
+ * @var Settings $settings
+ */
private static $settings;
+ /**
+ * Get settings instance.
+ *
+ * @return Settings Settings helper instance
+ */
private static function settings(): Settings
{
if (!(self::$settings instanceof Settings)) {
@@ -63,6 +77,13 @@ class BackendBehaviors
return self::$settings;
}
+ /**
+ * Plugin pacKman behavior.
+ *
+ * Add dcstore.xml file on the fly on pacKman package creation.
+ *
+ * @param array $module
+ */
public static function packmanBeforeCreatePackage(array $module): void
{
if (self::settings()->packman) {
@@ -70,27 +91,37 @@ class BackendBehaviors
}
// move from array to dcModuleDefine object
- $modules = $module['type'] == 'theme' ? dcCore::app()->themes : dcCore::app()->plugins;
+ $modules = $module['type'] == 'theme' ? App::themes() : App::plugins();
$define = $modules->getDefine($module['id']);
self::writeXML($define, self::settings()->file_pattern);
}
+ /**
+ * Add list headers and save settings.
+ *
+ * @param bool $is_theme Is on themes list
+ *
+ * @return string HTML header code
+ */
public static function modulesToolsHeaders(bool $is_theme): string
{
//save settings (before page header sent)
if (!empty($_POST['tweakstore_save'])) {
try {
foreach (self::settings()->dump() as $key => $value) {
+ if (!is_string($key)) {
+ continue;
+ }
self::settings()->set($key, $_POST['ts_' . $key] ?? $value);
}
Notices::addSuccessNotice(
__('Configuration successfully updated')
);
- dcCore::app()->admin->url->redirect($is_theme ? 'admin.blog.theme' : 'admin.plugins', ['tab' => My::id()]);
+ App::backend()->url()->redirect($is_theme ? 'admin.blog.theme' : 'admin.plugins', ['tab' => My::id()]);
} catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
+ App::error()->add($e->getMessage());
}
}
@@ -98,28 +129,40 @@ class BackendBehaviors
Page::jsJson('tweakstore_copied', ['alert' => __('Copied to clipboard')]) .
My::jsLoad('backend') .
(
- !dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax') ? '' :
- Page::jsLoadCodeMirror(dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme')) .
+ !App::auth()->prefs()->get('interface')->get('colorsyntax') ? '' :
+ Page::jsLoadCodeMirror(App::auth()->prefs()->get('interface')->get('colorsyntax_theme')) .
My::jsLoad('cms')
);
}
+ /**
+ * Plugins tab.
+ */
public static function pluginsToolsTabsV2(): void
{
- self::modulesToolsTabs(dcCore::app()->plugins, (string) dcCore::app()->admin->url->get('admin.plugins'));
+ self::modulesToolsTabs(App::plugins(), (string) App::backend()->url()->get('admin.plugins'));
}
+ /**
+ * Themes tab.
+ */
public static function themesToolsTabsV2(): void
{
- self::modulesToolsTabs(dcCore::app()->themes, (string) dcCore::app()->admin->url->get('admin.blog.theme'));
+ self::modulesToolsTabs(App::themes(), (string) App::backend()->url()->get('admin.blog.theme'));
}
- private static function modulesToolsTabs(dcModules $modules, string $page_url): void
+ /**
+ * Modules tab.
+ *
+ * @param ModulesInterface $modules The modules
+ * @param string $page_url The page URL
+ */
+ private static function modulesToolsTabs(ModulesInterface $modules, string $page_url): void
{
// settings
$page_url .= '#' . My::id();
- $user_ui_colorsyntax = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax');
- $user_ui_colorsyntax_theme = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme');
+ $user_ui_colorsyntax = App::auth()->prefs()->get('interface')->get('colorsyntax');
+ $user_ui_colorsyntax_theme = App::auth()->prefs()->get('interface')->get('colorsyntax_theme');
$file_pattern = self::settings()->file_pattern;
$local_content = $distant_content = '';
@@ -162,12 +205,12 @@ class BackendBehaviors
// write dcstore.xml file
if (!empty($_POST['tweakstore_write'])) {
- if (empty($_POST['your_pwd']) || !dcCore::app()->auth->checkPassword($_POST['your_pwd'])) {
- dcCore::app()->error->add(__('Password verification failed'));
+ if (empty($_POST['your_pwd']) || !App::auth()->checkPassword($_POST['your_pwd'])) {
+ App::error()->add(__('Password verification failed'));
} else {
self::writeXML($module, self::settings()->file_pattern);
if (!empty(self::$failed)) {
- dcCore::app()->error->add(implode(' ', self::$failed));
+ App::error()->add(implode(' ', self::$failed));
}
}
}
@@ -252,7 +295,7 @@ class BackendBehaviors
);
if ($module->get('root_writable')
- && dcCore::app()->auth->isSuperAdmin()
+ && App::auth()->isSuperAdmin()
) {
echo
(new Para())->class('field')->items([
@@ -261,7 +304,7 @@ class BackendBehaviors
])->render() .
' ' .
'' . __('Copy to clipboard') . '' .
- dcCore::app()->formNonce() . '
';
+ App::nonce()->getFormNonce() . '
';
}
echo
@@ -273,7 +316,7 @@ class BackendBehaviors
(new Para())->items([
(new Submit('tweakstore_submit'))->value(__('Check')),
(new Hidden('tweakstore_do', '1')),
- dcCore::app()->formNonce(false),
+ App::nonce()->formNonce(),
])->render() .
'' .
@@ -301,7 +344,7 @@ class BackendBehaviors
(new Para())->items([
(new Submit('tweakstore_save'))->value(__('Save')),
- dcCore::app()->formNonce(false),
+ App::nonce()->formNonce(),
])->render() .
'' .
@@ -309,8 +352,12 @@ class BackendBehaviors
'';
}
- # create list of module for combo and remove official modules
- private static function comboModules(dcModules $modules): array
+ /**
+ * Create list of module for combo and remove official modules.
+ *
+ * @return array
+ */
+ private static function comboModules(ModulesInterface $modules): array
{
$combo = [];
foreach ($modules->getDefines() as $module) {
@@ -325,7 +372,15 @@ class BackendBehaviors
return array_merge([__('Select a module') => '0'], $combo);
}
- private static function parseFilePattern(dcModuleDefine $module, string $file_pattern): string
+ /**
+ * Parse dcstore content.
+ *
+ * @param ModuleDefine $module The module
+ * @param string $file_pattern The file pattern
+ *
+ * @return string The parsed file content
+ */
+ private static function parseFilePattern(ModuleDefine $module, string $file_pattern): string
{
return Text::tidyURL(str_replace(
[
@@ -344,7 +399,15 @@ class BackendBehaviors
));
}
- private static function generateXML(dcModuleDefine $module, string $file_pattern): string
+ /**
+ * Generate XML content from module.
+ *
+ * @param ModuleDefine $module The module
+ * @param string $file_pattern The file pattern
+ *
+ * @return string The XML content
+ */
+ private static function generateXML(ModuleDefine $module, string $file_pattern): string
{
$rsp = new XmlTag('module');
@@ -358,10 +421,10 @@ class BackendBehaviors
$rsp->insertAttr('id', $module->get('id'));
# name
- if (empty($module->get('name'))) {
+ if (empty($module->get('label'))) {
self::$failed[] = 'no module name set in _define.php';
}
- $rsp->insertNode(new XmlTag('name', $module->get('name')));
+ $rsp->insertNode(new XmlTag('name', $module->get('label')));
# version
if (empty($module->get('version'))) {
@@ -437,7 +500,15 @@ class BackendBehaviors
return self::prettyXML($res->toXML());
}
- private static function writeXML(dcModuleDefine $module, string $file_pattern): bool
+ /**
+ * Write XML content to dcstore file.
+ *
+ * @param ModuleDefine $module The module
+ * @param string $file_pattern The file pattern
+ *
+ * @return bool True on success
+ */
+ private static function writeXML(ModuleDefine $module, string $file_pattern): bool
{
self::$failed = [];
if (!$module->get('root_writable')) {
@@ -459,6 +530,13 @@ class BackendBehaviors
return true;
}
+ /**
+ * Arrange XML content.
+ *
+ * @param string $str The content
+ *
+ * @return string The pretty content
+ */
private static function prettyXML(string $str): string
{
if (class_exists('DOMDocument')) {
diff --git a/src/My.php b/src/My.php
index f0c6116..af83785 100644
--- a/src/My.php
+++ b/src/My.php
@@ -1,29 +1,26 @@
auth->isSuperAdmin() : null;
+ return match ($context) {
+ self::MODULE => App::auth()->isSuperAdmin(),
+ default => null,
+ };
}
}
diff --git a/src/Settings.php b/src/Settings.php
index 9873002..fd890a9 100644
--- a/src/Settings.php
+++ b/src/Settings.php
@@ -1,25 +1,30 @@
The settings keys
*/
public function dump(): array
{
diff --git a/src/Uninstall.php b/src/Uninstall.php
index 4918d51..b030273 100644
--- a/src/Uninstall.php
+++ b/src/Uninstall.php
@@ -1,23 +1,19 @@
plugins->moduleExists('Uninstaller')) {
+ if (!self::status()) {
return false;
}