diff --git a/_admin.php b/_admin.php
deleted file mode 100644
index 065bd9f..0000000
--- a/_admin.php
+++ /dev/null
@@ -1,18 +0,0 @@
- '',
- '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
- $module,
- # Clean up values
- [
- 'id' => $id,
- 'sid' => self::sanitizeString($id),
- 'label' => $label,
- 'name' => $name,
- 'oname' => $oname,
- 'sname' => self::sanitizeString($name),
- ]
- );
- }
-
- # taken from lib.moduleslist.php
- public static function sanitizeString(string $str): string
- {
- return (string) preg_replace('/[^A-Za-z0-9\@\#+_-]/', '', strtolower($str));
- }
-
- public static function parseFilePattern(string $id, array $module, string $file_pattern): string
- {
- $module = self::sanitizeModule($id, $module);
-
- return text::tidyURL(str_replace(
- [
- '%type%',
- '%id%',
- '%version%',
- '%author%',
- ],
- [
- $module['type'],
- $module['id'],
- $module['version'],
- $module['author'],
- ],
- $file_pattern
- ));
- }
-
- public static function generateXML(string $id, array $module, string $file_pattern): string
- {
- if (!is_array($module) || empty($module)) {
- return '';
- }
- $module = self::sanitizeModule($id, $module);
- $rsp = new xmlTag('module');
-
- self::$notice = [];
- self::$failed = [];
-
- # id
- if (empty($module['id'])) {
- self::$failed[] = 'unknow module';
- }
- $rsp->id = $module['id'];
-
- # name
- if (empty($module['name'])) {
- self::$failed[] = 'no module name set in _define.php';
- }
- $rsp->name($module['oname']);
-
- # version
- if (empty($module['version'])) {
- self::$failed[] = 'no module version set in _define.php';
- }
- $rsp->version($module['version']);
-
- # author
- if (empty($module['author'])) {
- self::$failed[] = 'no module author set in _define.php';
- }
- $rsp->author($module['author']);
-
- # desc
- if (empty($module['desc'])) {
- self::$failed[] = 'no module description set in _define.php';
- }
- $rsp->desc($module['desc']);
-
- # repository
- if (empty($module['repository'])) {
- self::$failed[] = 'no repository set in _define.php';
- }
-
- # file
- $file_pattern = self::parseFilePattern($id, $module, $file_pattern);
- if (empty($file_pattern)) {
- self::$failed[] = 'no zip file pattern set in Tweak Store configuration';
- }
- $rsp->file($file_pattern);
-
- # da dc_min or requires core
- if (!empty($module['requires']) && is_array($module['requires'])) {
- foreach ($module['requires'] as $req) {
- if (!is_array($req)) {
- $req = [$req];
- }
- if ($req[0] == 'core') {
- $module['dc_min'] = $req[1];
-
- break;
- }
- }
- }
- if (empty($module['dc_min'])) {
- self::$notice[] = 'no minimum dotclear version';
- } else {
- $rsp->insertNode(new xmlTag('da:dcmin', $module['dc_min']));
- }
-
- # details
- if (empty($module['details'])) {
- self::$notice[] = 'no details URL';
- } else {
- $rsp->insertNode(new xmlTag('da:details', $module['details']));
- }
-
- # section
- if (!empty($module['section'])) {
- $rsp->insertNode(new xmlTag('da:section', $module['section']));
- }
-
- # support
- if (empty($module['support'])) {
- self::$notice[] = 'no support URL';
- } else {
- $rsp->insertNode(new xmlTag('da:support', $module['support']));
- }
-
- $res = new xmlTag('modules', $rsp);
- $res->insertAttr('xmlns:da', 'http://dotaddict.org/da/');
-
- return self::prettyXML($res->toXML());
- }
-
- public static function writeXML(string $id, array $module, string $file_pattern): bool
- {
- self::$failed = [];
- if (!$module['root_writable']) {
- return false;
- }
- $content = self::generateXML($id, $module, $file_pattern);
- if (!empty(self::$failed)) {
- return false;
- }
-
- try {
- files::putContent($module['root'] . '/dcstore.xml', $content);
- } catch (Exception $e) {
- self::$failed[] = $e->getMessage();
-
- return false;
- }
-
- return true;
- }
-
- public static function prettyXML(string $str): string
- {
- if (class_exists('DOMDocument')) {
- $dom = new DOMDocument('1.0');
- $dom->preserveWhiteSpace = false;
- $dom->formatOutput = true;
- $dom->loadXML($str);
-
- return (string) $dom->saveXML();
- }
-
- return (string) str_replace('><', ">\n<", $str);
- }
-}
diff --git a/inc/Prepend.php b/inc/Prepend.php
deleted file mode 100644
index e66f63f..0000000
--- a/inc/Prepend.php
+++ /dev/null
@@ -1,50 +0,0 @@
-autoload([
- __NAMESPACE__ . '\\' . $lib => __DIR__ . DIRECTORY_SEPARATOR . $lib . '.php',
- ]);
- }
-
- return true;
- }
-}
diff --git a/src/Backend.php b/src/Backend.php
index 2d5a82b..9815955 100644
--- a/src/Backend.php
+++ b/src/Backend.php
@@ -14,270 +14,38 @@ declare(strict_types=1);
namespace Dotclear\Plugin\tweakStores;
-/* dotclear ns */
use dcCore;
-use dcPage;
+use dcNsProcess;
-/* clearbricks ns */
-use form;
-use html;
-
-/* php ns */
-use Exception;
-
-class Admin
+class Backend extends dcNsProcess
{
- private static $pid = '';
- protected static $init = false;
-
public static function init(): bool
{
- if (defined('DC_CONTEXT_ADMIN')
- && dcCore::app()->auth->isSuperAdmin()
- && dcCore::app()->blog->settings->get(basename(__NAMESPACE__))->get('active')
- ) {
- dcCore::app()->auth->user_prefs->addWorkspace('interface');
- self::$pid = basename(dirname(__DIR__));
- self::$init = true;
- }
+ static::$init = My::phpCompliant()
+ && defined('DC_CONTEXT_ADMIN')
+ && dcCore::app()->auth->isSuperAdmin()
+ && dcCore::app()->blog->settings->get(My::id())->get('active');
- return self::$init;
+ return static::$init;
}
- public static function process(): ?bool
+ public static function process(): bool
{
- if (!self::$init) {
+ if (!static::$init) {
return false;
}
- if (dcCore::app()->blog->settings->get(self::$pid)->get('packman')) {
- // create dcstore.xml file on the fly when plugin packman pack a module
- dcCore::app()->addBehavior('packmanBeforeCreatePackage', function (array $module): void {
- Core::writeXML($module['id'], $module, dcCore::app()->blog->settings->get(self::$pid)->get('file_pattern'));
- });
- }
-
dcCore::app()->addBehaviors([
// addd some js
- 'pluginsToolsHeadersV2' => [self::class, 'modulesToolsHeaders'],
- 'themesToolsHeadersV2' => [self::class, 'modulesToolsHeaders'],
- // admin plugins page tab
- 'pluginsToolsTabsV2' => function (): void {
- self::modulesToolsTabs(dcCore::app()->plugins->getModules(), explode(',', DC_DISTRIB_PLUGINS), dcCore::app()->adminurl->get('admin.plugins'));
- },
- // admin themes page tab
- 'themesToolsTabsV2' => function (): void {
- self::modulesToolsTabs(dcCore::app()->themes->getModules(), explode(',', DC_DISTRIB_THEMES), dcCore::app()->adminurl->get('admin.blog.theme'));
- },
+ 'pluginsToolsHeadersV2' => [BackendBehaviors::class, 'modulesToolsHeaders'],
+ 'themesToolsHeadersV2' => [BackendBehaviors::class, 'modulesToolsHeaders'],
+ // admin modules page tab
+ 'pluginsToolsTabsV2' => [BackendBehaviors::class, 'pluginsToolsTabsV2'],
+ 'themesToolsTabsV2' => [BackendBehaviors::class, 'themesToolsTabsV2'],
+ // add to plugin pacKman
+ 'packmanBeforeCreatePackage' => [BackendBehaviors::class, 'packmanBeforeCreatePackage'],
]);
return true;
}
-
- public static function modulesToolsHeaders(bool $is_plugin): string
- {
- return
- dcPage::jsJson('ts_copied', ['alert' => __('Copied to clipboard')]) .
- dcPage::jsModuleLoad(self::$pid . '/js/admin.js') .
- (
- !dcCore::app()->auth->user_prefs->interface->colorsyntax ? '' :
- dcPage::jsLoadCodeMirror(dcCore::app()->auth->user_prefs->interface->colorsyntax_theme) .
- dcPage::jsModuleLoad(self::$pid . '/js/cms.js')
- );
- }
-
- protected static function modulesToolsTabs(array $modules, array $excludes, string $page_url): void
- {
- $page_url .= '#' . self::$pid;
- $user_ui_colorsyntax = dcCore::app()->auth->user_prefs->interface->colorsyntax;
- $user_ui_colorsyntax_theme = dcCore::app()->auth->user_prefs->interface->colorsyntax_theme;
- $combo = self::comboModules($modules, $excludes);
- $file_pattern = dcCore::app()->blog->settings->get(self::$pid)->get('file_pattern');
-
- # check dcstore repo
- $url = '';
- if (!empty($_POST['checkxml_id']) && in_array($_POST['checkxml_id'], $combo)) {
- if (empty($modules[$_POST['checkxml_id']]['repository'])) {
- $url = __('This module has no repository set in its _define.php file.');
- } else {
- try {
- $url = $modules[$_POST['checkxml_id']]['repository'];
- if (false === strpos($url, 'dcstore.xml')) {
- $url .= '/dcstore.xml';
- }
- if (function_exists('curl_init')) {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_HEADER, false);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_REFERER, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- $file_content = curl_exec($ch);
- curl_close($ch);
- } else {
- $file_content = file_get_contents($url);
- }
- } catch (Exception $e) {
- $file_content = __('Failed to read third party repository');
- }
- }
- }
-
- # generate xml code
- if (!empty($_POST['buildxml_id']) && in_array($_POST['buildxml_id'], $combo)) {
- $xml_content = Core::generateXML($_POST['buildxml_id'], $modules[$_POST['buildxml_id']], $file_pattern);
- }
-
- # write dcstore.xml file
- if (!empty($_POST['write_xml'])) {
- if (empty($_POST['your_pwd']) || !dcCore::app()->auth->checkPassword($_POST['your_pwd'])) {
- dcCore::app()->error->add(__('Password verification failed'));
- } else {
- $ret = Core::writeXML($_POST['buildxml_id'], $modules[$_POST['buildxml_id']], $file_pattern);
- if (!empty(Core::$failed)) {
- dcCore::app()->error->add(implode(' ', Core::$failed));
- }
- }
- }
- echo
- '
' .
- '
' . __('Tweak third-party repositories') . ' ';
-
- if (!empty($_POST['write_xml'])) {
- if (dcCore::app()->error->flag()) {
- echo dcCore::app()->error->toHTML();
- } else {
- echo '
' . __('File successfully written') . '
';
- }
- }
- if (count($combo) < 2) {
- echo
- '
' . __('There is no module to tweak') . '
' .
- '
';
-
- return;
- }
-
- echo
- '';
-
- if (!empty($url)) {
- echo
- '' .
- '
' . __('Repositiory contents') . ' ' .
- '
' . $url . '
' .
- (
- empty($file_content) ? '' :
- '
' . form::textArea('file_xml', 165, 14, [
- 'default' => html::escapeHTML(Core::prettyXML($file_content)),
- 'class' => 'maximal',
- 'extra_html' => 'readonly="true"',
- ]) . ' ' .
- (
- !$user_ui_colorsyntax ? '' :
- dcPage::jsRunCodeMirror('editor', 'file_xml', 'dotclear', $user_ui_colorsyntax_theme)
- )
- ) .
- '
';
- }
-
- if (empty($file_pattern)) {
- echo sprintf(
- '' . __('Generate xml code') . ' %s
',
- dcCore::app()->adminurl->get('admin.plugins', ['module' => self::$pid, 'conf' => 1, 'redir' => $page_url]),
- __('You must configure zip file pattern to complete xml code automatically.')
- );
- } else {
- echo
- '';
- }
- if (!empty($_POST['buildxml_id'])) {
- echo
- '';
- }
- echo
- '';
- }
-
- # create list of module for combo and remove official modules
- protected static function comboModules(array $modules, array $excludes): array
- {
- $combo = [__('Select a module') => '0'];
- foreach ($modules as $id => $module) {
- if (in_array($id, $excludes)) {
- continue;
- }
- $combo[$module['name'] . ' ' . $module['version']] = $id;
- }
-
- return $combo;
- }
}
diff --git a/src/BackendBehaviors.php b/src/BackendBehaviors.php
new file mode 100644
index 0000000..cfdb8a3
--- /dev/null
+++ b/src/BackendBehaviors.php
@@ -0,0 +1,421 @@
+blog->settings->get(My::id())->get('packman')) {
+ return;
+ }
+
+ // move from array to dcModuleDefine object
+ $modules = $module['type'] == 'theme' ? dcCore::app()->themes : dcCore::app()->plugins;
+ $define = $modules->getDefine($module['id']);
+
+ self::writeXML($define, dcCore::app()->blog->settings->get(My::id())->get('file_pattern'));
+ }
+
+ public static function modulesToolsHeaders(bool $is_plugin): string
+ {
+ return
+ dcPage::jsJson('ts_copied', ['alert' => __('Copied to clipboard')]) .
+ dcPage::jsModuleLoad(My::id() . '/js/backend.js') .
+ (
+ !dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax') ? '' :
+ dcPage::jsLoadCodeMirror(dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme')) .
+ dcPage::jsModuleLoad(My::id() . '/js/cms.js')
+ );
+ }
+
+ public static function pluginsToolsTabsV2(): void
+ {
+ self::modulesToolsTabs(dcCore::app()->plugins, explode(',', DC_DISTRIB_PLUGINS), dcCore::app()->adminurl->get('admin.plugins'));
+ }
+
+ public static function themesToolsTabsV2(): void
+ {
+ self::modulesToolsTabs(dcCore::app()->themes, explode(',', DC_DISTRIB_THEMES), dcCore::app()->adminurl->get('admin.blog.theme'));
+ }
+
+ private static function modulesToolsTabs(dcModules $modules, array $excludes, string $page_url): void
+ {
+ $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');
+ $file_pattern = (new Settings())->file_pattern;
+
+ $module = $modules->getDefine($_POST['ts_id'] ?? '-');
+ $combo = self::comboModules($modules, $excludes);
+ $form = '' .
+ '* ' . __('Module to parse:') . ' ' .
+ form::combo('ts_id', $combo, $module->isDefined() ? html::escapeHTML($module->get('id')) : '-') .
+ '
';
+
+ # check dcstore repo
+ $url = '';
+ if (!empty($_POST['check_xml']) && $module->isDefined()) {
+ if (empty($module->get('repository'))) {
+ $url = __('This module has no repository set in its _define.php file.');
+ } else {
+ try {
+ $url = $module->get('repository');
+ if (false === strpos($url, 'dcstore.xml')) {
+ $url .= '/dcstore.xml';
+ }
+ if (function_exists('curl_init')) {
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_REFERER, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $file_content = curl_exec($ch);
+ curl_close($ch);
+ } else {
+ $file_content = file_get_contents($url);
+ }
+ } catch (Exception $e) {
+ $file_content = __('Failed to read third party repository');
+ }
+ }
+ }
+
+ # generate xml code
+ if (!empty($_POST['build_xml']) && $module->isDefined()) {
+ $xml_content = self::generateXML($module, $file_pattern);
+ }
+
+ # write dcstore.xml file
+ if (!empty($_POST['write_xml'])) {
+ if (empty($_POST['your_pwd']) || !dcCore::app()->auth->checkPassword($_POST['your_pwd'])) {
+ dcCore::app()->error->add(__('Password verification failed'));
+ } else {
+ $ret = self::writeXML($module, $file_pattern);
+ if (!empty(self::$failed)) {
+ dcCore::app()->error->add(implode(' ', self::$failed));
+ }
+ }
+ }
+ echo
+ '' .
+ '
' . __('Tweak third-party repositories') . ' ';
+
+ if (!empty($_POST['write_xml'])) {
+ if (dcCore::app()->error->flag()) {
+ echo dcCore::app()->error->toHTML();
+ } else {
+ echo '
' . __('File successfully written') . '
';
+ }
+ }
+ if (count($combo) < 2) {
+ echo
+ '
' . __('There is no module to tweak') . '
' .
+ '
';
+
+ return;
+ }
+
+ echo
+ '';
+
+ if (!empty($url)) {
+ echo
+ '' .
+ '
' . __('Repositiory contents') . ' ' .
+ '
' . $url . '
' .
+ (
+ empty($file_content) ? '' :
+ '
' . form::textArea('file_xml', 165, 14, [
+ 'default' => html::escapeHTML(self::prettyXML($file_content)),
+ 'class' => 'maximal',
+ 'extra_html' => 'readonly="true"',
+ ]) . ' ' .
+ (
+ !$user_ui_colorsyntax ? '' :
+ dcPage::jsRunCodeMirror('editor', 'file_xml', 'dotclear', $user_ui_colorsyntax_theme)
+ )
+ ) .
+ '
';
+ }
+
+ if (empty($file_pattern)) {
+ echo sprintf(
+ '' . __('Generate xml code') . ' %s
',
+ dcCore::app()->adminurl->get('admin.plugins', ['module' => My::id(), 'conf' => 1, 'redir' => $page_url]),
+ __('You must configure zip file pattern to complete xml code automatically.')
+ );
+ } else {
+ echo
+ '';
+ }
+ if (!empty($_POST['build_xml'])) {
+ echo
+ '';
+ }
+ echo
+ '';
+ }
+
+ # create list of module for combo and remove official modules
+ private static function comboModules(dcModules $modules, array $excludes): array
+ {
+ $combo = [__('Select a module') => '0'];
+ foreach ($modules->getDefines() as $module) {
+ if (in_array($module->get('id'), $excludes)) {
+ continue;
+ }
+ $combo[$module->get('name') . ' ' . $module->get('version')] = $module->get('id');
+ }
+
+ return $combo;
+ }
+
+ private static function parseFilePattern(dcModuleDefine $module, string $file_pattern): string
+ {
+ return text::tidyURL(str_replace(
+ [
+ '%type%',
+ '%id%',
+ '%version%',
+ '%author%',
+ ],
+ [
+ $module->get('type'),
+ $module->get('id'),
+ $module->get('version'),
+ $module->get('author'),
+ ],
+ $file_pattern
+ ));
+ }
+
+ private static function generateXML(dcModuleDefine $module, string $file_pattern): string
+ {
+ $rsp = new xmlTag('module');
+
+ self::$notice = [];
+ self::$failed = [];
+
+ # id
+ if (!$module->isDefined()) {
+ self::$failed[] = 'unknow module';
+ }
+ $rsp->id = $module->get('id');
+
+ # name
+ if (empty($module->get('name'))) {
+ self::$failed[] = 'no module name set in _define.php';
+ }
+ $rsp->name($module->get('name'));
+
+ # version
+ if (empty($module->get('version'))) {
+ self::$failed[] = 'no module version set in _define.php';
+ }
+ $rsp->version($module->get('version'));
+
+ # author
+ if (empty($module->get('author'))) {
+ self::$failed[] = 'no module author set in _define.php';
+ }
+ $rsp->author($module->get('author'));
+
+ # desc
+ if (empty($module->get('desc'))) {
+ self::$failed[] = 'no module description set in _define.php';
+ }
+ $rsp->desc($module->get('desc'));
+
+ # repository
+ if (empty($module->get('repository'))) {
+ self::$failed[] = 'no repository set in _define.php';
+ }
+
+ # file
+ $file_pattern = self::parseFilePattern($module, $file_pattern);
+ if (empty($file_pattern)) {
+ self::$failed[] = 'no zip file pattern set in Tweak Store configuration';
+ }
+ $rsp->file($file_pattern);
+
+ # da dc_min or requires core
+ if (!empty($module->get('requires')) && is_array($module->get('requires'))) {
+ foreach ($module->get('requires') as $req) {
+ if (!is_array($req)) {
+ $req = [$req];
+ }
+ if ($req[0] == 'core') {
+ $module->set('dc_min', $req[1]);
+
+ break;
+ }
+ }
+ }
+ if (empty($module->get('dc_min'))) {
+ self::$notice[] = 'no minimum dotclear version';
+ } else {
+ $rsp->insertNode(new xmlTag('da:dcmin', $module->get('dc_min')));
+ }
+
+ # details
+ if (empty($module->get('details'))) {
+ self::$notice[] = 'no details URL';
+ } else {
+ $rsp->insertNode(new xmlTag('da:details', $module->get('details')));
+ }
+
+ # section
+ if (!empty($module->get('section'))) {
+ $rsp->insertNode(new xmlTag('da:section', $module->get('section')));
+ }
+
+ # support
+ if (empty($module->get('support'))) {
+ self::$notice[] = 'no support URL';
+ } else {
+ $rsp->insertNode(new xmlTag('da:support', $module->get('support')));
+ }
+
+ $res = new xmlTag('modules', $rsp);
+ $res->insertAttr('xmlns:da', 'http://dotaddict.org/da/');
+
+ return self::prettyXML($res->toXML());
+ }
+
+ private static function writeXML(dcModuleDefine $module, string $file_pattern): bool
+ {
+ self::$failed = [];
+ if (!$module->get('root_writable')) {
+ return false;
+ }
+ $content = self::generateXML($module, $file_pattern);
+ if (!empty(self::$failed)) {
+ return false;
+ }
+
+ try {
+ files::putContent($module->get('root') . DIRECTORY_SEPARATOR . 'dcstore.xml', $content);
+ } catch (Exception $e) {
+ self::$failed[] = $e->getMessage();
+
+ return false;
+ }
+
+ return true;
+ }
+
+ private static function prettyXML(string $str): string
+ {
+ if (class_exists('DOMDocument')) {
+ $dom = new DOMDocument('1.0');
+ $dom->preserveWhiteSpace = false;
+ $dom->formatOutput = true;
+ $dom->loadXML($str);
+
+ return (string) $dom->saveXML();
+ }
+
+ return (string) str_replace('><', ">\n<", $str);
+ }
+}
diff --git a/src/Config.php b/src/Config.php
index fdaff7d..ac36b9b 100644
--- a/src/Config.php
+++ b/src/Config.php
@@ -16,89 +16,98 @@ namespace Dotclear\Plugin\tweakStores;
/* dotclear ns */
use dcCore;
+use dcNsProcess;
use dcPage;
-
-/* clearbricks ns */
-use form;
-use http;
+use Dotclear\Helper\Html\Form\{
+ Checkbox,
+ Div,
+ Fieldset,
+ Input,
+ Label,
+ Legend,
+ Note,
+ Para
+};
/* php ns */
use Exception;
-class Config
+class Config extends dcNsProcess
{
- private static $pid = '';
- protected static $init = false;
-
public static function init(): bool
{
- if (defined('DC_CONTEXT_ADMIN') && defined('DC_CONTEXT_MODULE')) {
- dcPage::checkSuper();
- self::$pid = basename(dirname(__DIR__));
- self::$init = true;
- }
+ static::$init = My::phpCompliant()
+ && defined('DC_CONTEXT_ADMIN')
+ && defined('DC_CONTEXT_MODULE')
+ && dcCore::app()->auth->isSuperAdmin();
- return self::$init;
+ return static::$init;
}
- public static function process(): ?bool
+ public static function process(): bool
{
- if (!self::$init) {
+ if (!static::$init) {
return false;
}
if (empty($_POST['save'])) {
- return null;
+ return true;
}
+ $s = new Settings();
+
try {
- $s = dcCore::app()->blog->settings->get(self::$pid);
- $s->put('active', !empty($_POST['s_active']));
- $s->put('packman', !empty($_POST['s_packman']));
- $s->put('file_pattern', $_POST['s_file_pattern']);
+ foreach ($s->listSettings() as $key) {
+ $s->writeSetting($key, $_POST['ts_' . $key] ?? '');
+ }
dcPage::addSuccessNotice(
__('Configuration successfully updated')
);
- http::redirect(
- dcCore::app()->admin->__get('list')->getURL('module=' . self::$pid . '&conf=1&redir=' . dcCore::app()->admin->__get('list')->getRedir())
+ dcCore::app()->adminurl->redirect(
+ 'admin.plugins',
+ ['module' => My::id(), 'conf' => 1, 'redir' => dcCore::app()->admin->__get('list')->getRedir()]
);
-
- return true;
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
}
- return null;
+ return true;
}
public static function render(): void
{
- $s = dcCore::app()->blog->settings->get(self::$pid);
+ if (!static::$init) {
+ return;
+ }
- echo '
-
-
' . dcCore::app()->plugins->moduleInfo(self::$pid, 'name') . '
+ $s = new Settings();
-
' .
- form::checkbox('s_active', 1, (bool) $s->get('active')) . ' ' .
- __('Enable plugin') . '
-
' . __('If enabled, new tab "Tweak stores" allows your to perfom actions relative to third-party repositories.') . '
-
-
' .
- form::checkbox('s_packman', 1, (bool) $s->get('packman')) . ' ' .
- __('Enable packman behaviors') . '
-
' . __('If enabled, plugin pacKman will (re)generate on the fly dcstore.xml file at root directory of the module.') . '
-
-
' . __('Predictable URL to zip file on the external repository') .
- form::field('s_file_pattern', 65, 255, (string) $s->get('file_pattern'), 'maximal') . '
-
-
' .
- __('You can use widcard like %author%, %type%, %id%, %version%.') . ' ' .
- __('For example on github https://github.com/MyGitName/%id%/releases/download/v%version%/%type%-%id%.zip') . ' ' .
- __('Note: on github, you must create a release and join to it the module zip file.') . '
-
-
-
';
+ echo (new Div())->items([
+ (new Fieldset())->class('fieldset')->legend(new Legend(__('Interface')))->fields([
+ // s_active
+ (new Para())->items([
+ (new Checkbox('ts_active', $s->active))->value(1),
+ (new Label(__('Enable plugin'), Label::OUTSIDE_LABEL_AFTER))->for('ts_active')->class('classic'),
+ ]),
+ (new Note())->text(__('If enabled, new tab "Tweak stores" allows your to perfom actions relative to third-party repositories.'))->class('form-note'),
+ // s_file_pattern
+ (new Para())->items([
+ (new Label(__('Predictable URL to zip file on the external repository')))->for('ts_file_pattern'),
+ (new Input('ts_file_pattern'))->size(65)->maxlenght(255)->value($s->file_pattern),
+ ]),
+ (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(__('Note: on github, you must create a release and join to it the module zip file.'))->class('form-note'),
+ ]),
+ (new Fieldset())->class('fieldset')->legend(new Legend(__('Behaviors')))->fields([
+ // s_packman
+ (new Para())->items([
+ (new Checkbox('ts_packman', $s->packman))->value(1),
+ (new Label(__('Enable packman behaviors'), Label::OUTSIDE_LABEL_AFTER))->for('ts_packman')->class('classic'),
+ ]),
+ (new Note())->text(__('If enabled, plugin pacKman will (re)generate on the fly dcstore.xml file at root directory of the module.'))->class('form-note'),
+ ]),
+ ])->render();
}
}
diff --git a/src/My.php b/src/My.php
new file mode 100644
index 0000000..ab6211e
--- /dev/null
+++ b/src/My.php
@@ -0,0 +1,50 @@
+plugins->moduleInfo(self::id(), 'name'));
+ }
+
+ /**
+ * Check php version
+ */
+ public static function phpCompliant(): bool
+ {
+ return version_compare(phpversion(), self::PHP_MIN, '>=');
+ }
+}
diff --git a/src/Settings.php b/src/Settings.php
new file mode 100644
index 0000000..6fd8cda
--- /dev/null
+++ b/src/Settings.php
@@ -0,0 +1,76 @@
+blog->settings->get(My::id());
+
+ $this->active = (bool) ($s->get('active') ?? false);
+ $this->packman = (bool) ($s->get('packman') ?? false);
+ $this->file_pattern = (string) ($s->get('file_pattern') ?? '');
+ }
+
+ public function getSetting(string $key): mixed
+ {
+ return $this->{$key} ?? null;
+ }
+
+ /**
+ * Overwrite a plugin settings (in db)
+ *
+ * @param string $key The setting ID
+ * @param mixed $value The setting value
+ *
+ * @return bool True on success
+ */
+ public function writeSetting(string $key, mixed $value): bool
+ {
+ if (property_exists($this, $key) && settype($value, gettype($this->{$key})) === true) {
+ dcCore::app()->blog->settings->get(My::id())->drop($key);
+ dcCore::app()->blog->settings->get(My::id())->put($key, $value, gettype($this->{$key}), '', true, true);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * List defined settings keys
+ *
+ * @return array The settings keys
+ */
+ public function listSettings(): array
+ {
+ return array_keys(get_class_vars(Settings::class));
+ }
+}