Compare commits

..

No commits in common. "master" and "v1.0" have entirely different histories.
master ... v1.0

9 changed files with 136 additions and 217 deletions

View File

@ -1,16 +1,3 @@
tweakStores 1.2 - 2023.11.04
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Code review
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 tweakStores 1.0 - 2023.08.14
=========================================================== ===========================================================
* Require Dotclear 2.27 * Require Dotclear 2.27

View File

@ -1,22 +1,25 @@
# README # README
[![Release](https://img.shields.io/badge/release-1.2-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/tweakStores/releases) [![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.11.04-c44d58.svg) [![Date](https://img.shields.io/badge/date-2023.08.15-c44d58.svg)](https://git.dotclear.watch/JcDenis/tweakStores/releases)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.28-137bbb.svg)](https://fr.dotclear.org/download) [![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) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/tweakStores)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/LICENSE) [![License](https://img.shields.io/github/license/JcDenis/tweakStores)](https://git.dotclear.watch/JcDenis/tweakStores/blob/master/LICENSE)
## ABOUT ## WHAT IS TWEAKSTORES ?
_tweakStores_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org). "tweakStores" is a plugin for the open-source
web publishing software called Dotclear.
> Help devs to manage dcstore.xml file. It helps devs to manage dcstore.xml file.
## REQUIREMENTS ## REQUIREMENTS
* Dotclear 2.28 _tweakStores_ requires:
* superadmin permissions
* Dotclear 2.27
* PHP 8.1+ * PHP 8.1+
* Dotclear superadmin permissions
## USAGE ## USAGE
@ -29,10 +32,9 @@ package creation.
## LINKS ## LINKS
* [License](https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/LICENSE) * License : [GNU GPL v2](https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html)
* [Packages & details](https://git.dotclear.watch/JcDenis/tweakStores/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/tweakStores)) * Source & contribution : [Gitea Page](https://git.dotclear.watch/JcDenis/tweakStores) or [GitHub Page](https://github.com/JcDenis/tweakStores)
* [Sources & contributions](https://git.dotclear.watch/JcDenis/tweakStores) (or on [GitHub](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)
* [Issues & security](https://git.dotclear.watch/JcDenis/tweakStores/issues) (or on [GitHub](https://github.com/JcDenis/tweakStores/issues))
## CONTRIBUTORS ## CONTRIBUTORS

View File

@ -1,26 +1,30 @@
<?php <?php
/** /**
* @file * @brief tweakStores, a plugin for Dotclear 2
* @brief The plugin tweakStores definition
* @ingroup tweakStores
* *
* @defgroup tweakStores Plugin tweakStores. * @package Dotclear
* @subpackage Plugin
* *
* Helper to manage external repositories. * @author Jean-Christian Denis and Contributors
* *
* @author Jean-Christian Denis * @copyright Jean-Christian Denis
* @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
*/ */
declare(strict_types=1); if (!defined('DC_RC_PATH')) {
return null;
}
$this->registerModule( $this->registerModule(
'Tweak stores', 'Tweak stores',
'Helper to manage external repositories', 'Helper to manage external repositories',
'Jean-Christian Denis and Contributors', 'Jean-Christian Denis and Contributors',
'1.2', '1.0',
[ [
'requires' => [['core', '2.28']], 'requires' => [
'permissions' => 'My', ['php', '8.1'],
['core', '2.27'],
],
'permissions' => null,
'type' => 'plugin', 'type' => 'plugin',
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues', 'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues',
'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md', 'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md',

View File

@ -2,11 +2,11 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="tweakStores"> <module id="tweakStores">
<name>Tweak stores</name> <name>Tweak stores</name>
<version>1.2</version> <version>1.0</version>
<author>Jean-Christian Denis and Contributors</author> <author>Jean-Christian Denis and Contributors</author>
<desc>Helper to manage external repositories</desc> <desc>Helper to manage external repositories</desc>
<file>https://git.dotclear.watch/JcDenis/tweakStores/releases/download/v1.2/plugin-tweakStores.zip</file> <file>https://git.dotclear.watch/JcDenis/tweakStores/releases/download/v1.0/plugin-tweakStores.zip</file>
<da:dcmin>2.28</da:dcmin> <da:dcmin>2.27</da:dcmin>
<da:details>https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/README.md</da:details> <da:details>https://git.dotclear.watch/JcDenis/tweakStores/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/JcDenis/tweakStores/issues</da:support> <da:support>https://git.dotclear.watch/JcDenis/tweakStores/issues</da:support>
</module> </module>

View File

@ -1,19 +1,22 @@
<?php <?php
/**
* @brief tweakStores, 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); declare(strict_types=1);
namespace Dotclear\Plugin\tweakStores; namespace Dotclear\Plugin\tweakStores;
use Dotclear\App; use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/**
* @brief tweakStores backend class.
* @ingroup tweakStores
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Backend extends Process class Backend extends Process
{ {
public static function init(): bool public static function init(): bool
@ -27,15 +30,15 @@ class Backend extends Process
return false; return false;
} }
App::behavior()->addBehaviors([ dcCore::app()->addBehaviors([
// addd some js // addd some js
'pluginsToolsHeadersV2' => BackendBehaviors::modulesToolsHeaders(...), 'pluginsToolsHeadersV2' => [BackendBehaviors::class, 'modulesToolsHeaders'],
'themesToolsHeadersV2' => BackendBehaviors::modulesToolsHeaders(...), 'themesToolsHeadersV2' => [BackendBehaviors::class, 'modulesToolsHeaders'],
// admin modules page tab // admin modules page tab
'pluginsToolsTabsV2' => BackendBehaviors::pluginsToolsTabsV2(...), 'pluginsToolsTabsV2' => [BackendBehaviors::class, 'pluginsToolsTabsV2'],
'themesToolsTabsV2' => BackendBehaviors::themesToolsTabsV2(...), 'themesToolsTabsV2' => [BackendBehaviors::class, 'themesToolsTabsV2'],
// add to plugin pacKman // add to plugin pacKman
'packmanBeforeCreatePackage' => BackendBehaviors::packmanBeforeCreatePackage(...), 'packmanBeforeCreatePackage' => [BackendBehaviors::class, 'packmanBeforeCreatePackage'],
]); ]);
return true; return true;

View File

@ -1,12 +1,22 @@
<?php <?php
/**
* @brief tweakStores, 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); declare(strict_types=1);
namespace Dotclear\Plugin\tweakStores; namespace Dotclear\Plugin\tweakStores;
use Dotclear\App; use dcCore;
use Dotclear\Module\ModuleDefine; use dcModuleDefine;
use Dotclear\Interface\Module\ModulesInterface; use dcModules;
use Dotclear\Core\Backend\{ use Dotclear\Core\Backend\{
Notices, Notices,
Page Page
@ -33,41 +43,17 @@ use Dotclear\Helper\Text;
use DOMDocument; use DOMDocument;
use Exception; use Exception;
/**
* @brief tweakStores backend behaviors class.
* @ingroup tweakStores
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class BackendBehaviors class BackendBehaviors
{ {
/** /** @var array List of notice messages */
* List of notice messages.
*
* @var array<int, string> $notice
*/
private static $notice = []; private static $notice = [];
/** /** @var array List of failed messages */
* List of failed messages.
*
* @var array<int, string> $failed
*/
private static $failed = []; private static $failed = [];
/** /** @var Settings Module settings */
* Module settings.
*
* @var Settings $settings
*/
private static $settings; private static $settings;
/**
* Get settings instance.
*
* @return Settings Settings helper instance
*/
private static function settings(): Settings private static function settings(): Settings
{ {
if (!(self::$settings instanceof Settings)) { if (!(self::$settings instanceof Settings)) {
@ -77,13 +63,6 @@ class BackendBehaviors
return self::$settings; return self::$settings;
} }
/**
* Plugin pacKman behavior.
*
* Add dcstore.xml file on the fly on pacKman package creation.
*
* @param array<string, string> $module
*/
public static function packmanBeforeCreatePackage(array $module): void public static function packmanBeforeCreatePackage(array $module): void
{ {
if (self::settings()->packman) { if (self::settings()->packman) {
@ -91,37 +70,27 @@ class BackendBehaviors
} }
// move from array to dcModuleDefine object // move from array to dcModuleDefine object
$modules = $module['type'] == 'theme' ? App::themes() : App::plugins(); $modules = $module['type'] == 'theme' ? dcCore::app()->themes : dcCore::app()->plugins;
$define = $modules->getDefine($module['id']); $define = $modules->getDefine($module['id']);
self::writeXML($define, self::settings()->file_pattern); 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 public static function modulesToolsHeaders(bool $is_theme): string
{ {
//save settings (before page header sent) //save settings (before page header sent)
if (!empty($_POST['tweakstore_save'])) { if (!empty($_POST['tweakstore_save'])) {
try { try {
foreach (self::settings()->dump() as $key => $value) { foreach (self::settings()->dump() as $key => $value) {
if (!is_string($key)) {
continue;
}
self::settings()->set($key, $_POST['ts_' . $key] ?? $value); self::settings()->set($key, $_POST['ts_' . $key] ?? $value);
} }
Notices::addSuccessNotice( Notices::addSuccessNotice(
__('Configuration successfully updated') __('Configuration successfully updated')
); );
App::backend()->url()->redirect($is_theme ? 'admin.blog.theme' : 'admin.plugins', ['tab' => My::id()]); dcCore::app()->admin->url->redirect($is_theme ? 'admin.blog.theme' : 'admin.plugins', ['tab' => My::id()]);
} catch (Exception $e) { } catch (Exception $e) {
App::error()->add($e->getMessage()); dcCore::app()->error->add($e->getMessage());
} }
} }
@ -129,40 +98,28 @@ class BackendBehaviors
Page::jsJson('tweakstore_copied', ['alert' => __('Copied to clipboard')]) . Page::jsJson('tweakstore_copied', ['alert' => __('Copied to clipboard')]) .
My::jsLoad('backend') . My::jsLoad('backend') .
( (
!App::auth()->prefs()->get('interface')->get('colorsyntax') ? '' : !dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax') ? '' :
Page::jsLoadCodeMirror(App::auth()->prefs()->get('interface')->get('colorsyntax_theme')) . Page::jsLoadCodeMirror(dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme')) .
My::jsLoad('cms') My::jsLoad('cms')
); );
} }
/**
* Plugins tab.
*/
public static function pluginsToolsTabsV2(): void public static function pluginsToolsTabsV2(): void
{ {
self::modulesToolsTabs(App::plugins(), (string) App::backend()->url()->get('admin.plugins')); self::modulesToolsTabs(dcCore::app()->plugins, (string) dcCore::app()->admin->url->get('admin.plugins'));
} }
/**
* Themes tab.
*/
public static function themesToolsTabsV2(): void public static function themesToolsTabsV2(): void
{ {
self::modulesToolsTabs(App::themes(), (string) App::backend()->url()->get('admin.blog.theme')); self::modulesToolsTabs(dcCore::app()->themes, (string) dcCore::app()->admin->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 // settings
$page_url .= '#' . My::id(); $page_url .= '#' . My::id();
$user_ui_colorsyntax = App::auth()->prefs()->get('interface')->get('colorsyntax'); $user_ui_colorsyntax = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax');
$user_ui_colorsyntax_theme = App::auth()->prefs()->get('interface')->get('colorsyntax_theme'); $user_ui_colorsyntax_theme = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme');
$file_pattern = self::settings()->file_pattern; $file_pattern = self::settings()->file_pattern;
$local_content = $distant_content = ''; $local_content = $distant_content = '';
@ -205,12 +162,12 @@ class BackendBehaviors
// write dcstore.xml file // write dcstore.xml file
if (!empty($_POST['tweakstore_write'])) { if (!empty($_POST['tweakstore_write'])) {
if (empty($_POST['your_pwd']) || !App::auth()->checkPassword($_POST['your_pwd'])) { if (empty($_POST['your_pwd']) || !dcCore::app()->auth->checkPassword($_POST['your_pwd'])) {
App::error()->add(__('Password verification failed')); dcCore::app()->error->add(__('Password verification failed'));
} else { } else {
self::writeXML($module, self::settings()->file_pattern); self::writeXML($module, self::settings()->file_pattern);
if (!empty(self::$failed)) { if (!empty(self::$failed)) {
App::error()->add(implode(' ', self::$failed)); dcCore::app()->error->add(implode(' ', self::$failed));
} }
} }
} }
@ -295,16 +252,16 @@ class BackendBehaviors
); );
if ($module->get('root_writable') if ($module->get('root_writable')
&& App::auth()->isSuperAdmin() && dcCore::app()->auth->isSuperAdmin()
) { ) {
echo echo
(new Para())->class('field')->items([ (new Para())->class('field')->items([
(new Label(__('Your password:')))->for('tweakstore_pwd')->class('required'), (new Label(__('Your password:')))->for('tweakstore_pwd')->class('required'),
(new Password(['your_pwd', 'tweakstore_pwd']))->size(20)->maxlength(255)->required(true)->placeholder(__('Password'))->autocomplete('current-password'), (new Password(['your_pwd', 'tweakstore_pwd']))->size(20)->maxlenght(255)->required(true)->placeholder(__('Password'))->autocomplete('current-password'),
])->render() . ])->render() .
'<p><input type="submit" name="tweakstore_write" id="tweakstore_write" value="' . __('Save to module directory') . '" /> ' . '<p><input type="submit" name="tweakstore_write" id="tweakstore_write" value="' . __('Save to module directory') . '" /> ' .
'<a class="hidden-if-no-js button" href="#' . My::id() . '" id="tweakstore_copy">' . __('Copy to clipboard') . '</a>' . '<a class="hidden-if-no-js button" href="#' . My::id() . '" id="tweakstore_copy">' . __('Copy to clipboard') . '</a>' .
App::nonce()->getFormNonce() . '</p>'; dcCore::app()->formNonce() . '</p>';
} }
echo echo
@ -316,7 +273,7 @@ class BackendBehaviors
(new Para())->items([ (new Para())->items([
(new Submit('tweakstore_submit'))->value(__('Check')), (new Submit('tweakstore_submit'))->value(__('Check')),
(new Hidden('tweakstore_do', '1')), (new Hidden('tweakstore_do', '1')),
App::nonce()->formNonce(), dcCore::app()->formNonce(false),
])->render() . ])->render() .
'</form>' . '</form>' .
@ -329,7 +286,7 @@ class BackendBehaviors
// s_file_pattern // s_file_pattern
(new Para())->items([ (new Para())->items([
(new Label(__('Predictable URL to zip file on the external repository')))->for('ts_file_pattern'), (new Label(__('Predictable URL to zip file on the external repository')))->for('ts_file_pattern'),
(new Input('ts_file_pattern'))->size(65)->maxlength(255)->class('maximal')->value(self::settings()->file_pattern), (new Input('ts_file_pattern'))->size(65)->maxlenght(255)->class('maximal')->value(self::settings()->file_pattern),
]), ]),
(new Note())->text(__('You can use widcard like %author%, %type%, %id%, %version%.'))->class('form-note'), (new Note())->text(__('You can use widcard like %author%, %type%, %id%, %version%.'))->class('form-note'),
(new Note())->text(__('For example on github https://github.com/MyGitName/%id%/releases/download/v%version%/%type%-%id%.zip'))->class('form-note'), (new Note())->text(__('For example on github https://github.com/MyGitName/%id%/releases/download/v%version%/%type%-%id%.zip'))->class('form-note'),
@ -344,7 +301,7 @@ class BackendBehaviors
(new Para())->items([ (new Para())->items([
(new Submit('tweakstore_save'))->value(__('Save')), (new Submit('tweakstore_save'))->value(__('Save')),
App::nonce()->formNonce(), dcCore::app()->formNonce(false),
])->render() . ])->render() .
'</div>' . '</div>' .
@ -352,12 +309,8 @@ class BackendBehaviors
'</div>'; '</div>';
} }
/** # create list of module for combo and remove official modules
* Create list of module for combo and remove official modules. private static function comboModules(dcModules $modules): array
*
* @return array<string, string>
*/
private static function comboModules(ModulesInterface $modules): array
{ {
$combo = []; $combo = [];
foreach ($modules->getDefines() as $module) { foreach ($modules->getDefines() as $module) {
@ -372,15 +325,7 @@ class BackendBehaviors
return array_merge([__('Select a module') => '0'], $combo); 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( return Text::tidyURL(str_replace(
[ [
@ -399,15 +344,7 @@ 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'); $rsp = new XmlTag('module');
@ -421,10 +358,10 @@ class BackendBehaviors
$rsp->insertAttr('id', $module->get('id')); $rsp->insertAttr('id', $module->get('id'));
# name # name
if (empty($module->get('label'))) { if (empty($module->get('name'))) {
self::$failed[] = 'no module name set in _define.php'; self::$failed[] = 'no module name set in _define.php';
} }
$rsp->insertNode(new XmlTag('name', $module->get('label'))); $rsp->insertNode(new XmlTag('name', $module->get('name')));
# version # version
if (empty($module->get('version'))) { if (empty($module->get('version'))) {
@ -500,15 +437,7 @@ class BackendBehaviors
return self::prettyXML($res->toXML()); 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 = []; self::$failed = [];
if (!$module->get('root_writable')) { if (!$module->get('root_writable')) {
@ -530,13 +459,6 @@ class BackendBehaviors
return true; return true;
} }
/**
* Arrange XML content.
*
* @param string $str The content
*
* @return string The pretty content
*/
private static function prettyXML(string $str): string private static function prettyXML(string $str): string
{ {
if (class_exists('DOMDocument')) { if (class_exists('DOMDocument')) {

View File

@ -1,27 +1,29 @@
<?php <?php
/**
* @brief tweakStores, 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); declare(strict_types=1);
namespace Dotclear\Plugin\tweakStores; namespace Dotclear\Plugin\tweakStores;
use Dotclear\App; use dcCore;
use Dotclear\Module\MyPlugin; use Dotclear\Module\MyPlugin;
/** /**
* @brief tweakStores My helper. * This module definitions.
* @ingroup tweakStores
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class My extends MyPlugin class My extends MyPlugin
{ {
public static function checkCustomContext(int $context): ?bool public static function checkCustomContext(int $context): ?bool
{ {
return match ($context) { return $context === My::BACKEND ? dcCore::app()->auth->isSuperAdmin() : null;
// Limit ot super admin
self::MODULE => App::auth()->isSuperAdmin(),
default => null,
};
} }
} }

View File

@ -1,30 +1,25 @@
<?php <?php
/**
* @brief tweakStores, 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); declare(strict_types=1);
namespace Dotclear\Plugin\tweakStores; namespace Dotclear\Plugin\tweakStores;
/**
* @brief tweakStores settings helper.
* @ingroup tweakStores
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Settings class Settings
{ {
/** // Enable plugin pacKman behavior
* Enable plugin pacKman behavior.
*
* @var bool $packman
*/
public readonly bool $packman; public readonly bool $packman;
/** // Predictable dcstore url
* Predictable dcstore url.
*
* @var string $v
*/
public readonly string $file_pattern; public readonly string $file_pattern;
/** /**
@ -42,7 +37,7 @@ class Settings
* @param string $key The setting ID * @param string $key The setting ID
* @param mixed $value The setting value * @param mixed $value The setting value
* *
* @return bool True on success * @return bool True on success
*/ */
public function set(string $key, mixed $value): bool public function set(string $key, mixed $value): bool
{ {
@ -59,7 +54,7 @@ class Settings
/** /**
* List defined settings keys * List defined settings keys
* *
* @return array<string, bool|string> The settings keys * @return array The settings keys
*/ */
public function dump(): array public function dump(): array
{ {

View File

@ -1,19 +1,23 @@
<?php <?php
/**
* @brief tweakStores, 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); declare(strict_types=1);
namespace Dotclear\Plugin\tweakStores; namespace Dotclear\Plugin\tweakStores;
use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Plugin\Uninstaller\Uninstaller; use Dotclear\Plugin\Uninstaller\Uninstaller;
/**
* @brief tweakStores uninstall class.
* @ingroup tweakStores
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Uninstall extends Process class Uninstall extends Process
{ {
public static function init(): bool public static function init(): bool
@ -23,7 +27,7 @@ class Uninstall extends Process
public static function process(): bool public static function process(): bool
{ {
if (!self::status()) { if (!self::status() || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
return false; return false;
} }