From ee33fcb00e10e6766f49416261fae927fe9a31c0 Mon Sep 17 00:00:00 2001 From: Jean-Christian Denis Date: Sat, 25 Mar 2023 19:16:08 +0100 Subject: [PATCH] use namespace --- _prepend.php | 20 ---- src/Backend.php | 74 ++++++++---- src/Config.php | 223 ++++++++++++++++++++--------------- src/Install.php | 152 +++++++++--------------- src/Manage.php | 284 ++++++++++++++++++++++++++++++++------------- src/ManageList.php | 96 --------------- src/My.php | 53 +++++++++ src/Settings.php | 112 ++++++++++++++++++ src/Uninstall.php | 113 ++++++++++-------- src/Utils.php | 120 ++++++++++--------- 10 files changed, 731 insertions(+), 516 deletions(-) delete mode 100644 _prepend.php delete mode 100644 src/ManageList.php create mode 100644 src/My.php create mode 100644 src/Settings.php diff --git a/_prepend.php b/_prepend.php deleted file mode 100644 index c01f57a..0000000 --- a/_prepend.php +++ /dev/null @@ -1,20 +0,0 @@ -autoload([ - 'licenseBootstrap' => __DIR__ . '/inc/class.license.bootstrap.php', - 'libLicenseBootstrap' => __DIR__ . '/inc/lib.license.bootstrap.php', -]); diff --git a/src/Backend.php b/src/Backend.php index bd2ae54..3a2e295 100644 --- a/src/Backend.php +++ b/src/Backend.php @@ -10,32 +10,58 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); +namespace Dotclear\Plugin\licenseBootstrap; -dcCore::app()->addBehavior('adminDashboardFavoritesV2', function ($favs) { - $favs->register(basename(__DIR__), [ - 'title' => __('License bootstrap'), - 'url' => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)), - 'small-icon' => urldecode(dcPage::getPF(basename(__DIR__) . '/icon.svg')), - 'large-icon' => urldecode(dcPage::getPF(basename(__DIR__) . '/icon.svg')), - //'permissions' => dcCore::app()->auth->isSuperAdmin(), - ]); -}); +use dcAdmin; +use dcCore; +use dcFavorites; +use dcNsProcess; +use dcPage; -dcCore::app()->addBehavior('packmanBeforeCreatePackage', function ($module) { - if (dcCore::app()->blog->settings->get(basename(__DIR__))->get('behavior_packman')) { - licenseBootstrap::addLicense($module); +class Backend extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN') + && dcCore::app()->auth?->isSuperAdmin() + && My::phpCompliant(); + + return static::$init; } -}); -dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem( - __('License bootstrap'), - dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)), - urldecode(dcPage::getPF(basename(__DIR__) . '/icon.svg')), - preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/', $_SERVER['REQUEST_URI']), - dcCore::app()->auth->isSuperAdmin() -); + public static function process(): bool + { + if (!static::$init) { + return false; + } + + dcCore::app()->addBehaviors([ + 'adminDashboardFavoritesV2' => function (dcFavorites $favs): void { + $favs->register(My::id(), [ + 'title' => My::name(), + 'url' => dcCore::app()->adminurl->get('admin.plugin.' . My::id()), + 'small-icon' => dcPage::getPF(My::id() . '/icon.svg'), + 'large-icon' => dcPage::getPF(My::id() . '/icon.svg'), + //'permissions' => dcCore::app()->auth->isSuperAdmin(), + ]); + }, + 'packmanBeforeCreatePackage' => function ($module) { + if (Settings::init()->behavior_packman) { + Utils::addLicense($module); + } + }, + ]); + + dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem( + My::name(), + dcCore::app()->adminurl->get('admin.plugin.' . My::id()), + dcPage::getPF(My::id() . '/icon.svg'), + preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/', $_SERVER['REQUEST_URI']), + dcCore::app()->auth?->isSuperAdmin() + ); + + return true; + } +} diff --git a/src/Config.php b/src/Config.php index 978af2c..c7ade47 100644 --- a/src/Config.php +++ b/src/Config.php @@ -10,105 +10,140 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_MODULE')) { - return null; -} +declare(strict_types=1); -$redir = empty($_REQUEST['redir']) ? - dcCore::app()->admin->__get('list')->getURL() . '#plugins' : $_REQUEST['redir']; +namespace Dotclear\Plugin\licenseBootstrap; -# -- Get settings -- -$s = dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); +use dcCore; +use dcPage; +use dcNsProcess; +use Dotclear\Helper\Html\Form\{ + Checkbox, + Div, + Fieldset, + Label, + Legend, + Para, + Radio, + Textarea +}; +use Exception; -$lb_overwrite = (bool) $s->get('overwrite'); -$lb_write_full = (bool) $s->get('write_full'); -$lb_write_php = (bool) $s->get('write_php'); -$lb_write_js = (bool) $s->get('write_js'); -$lb_exclude_locales = (bool) $s->get('exclude_locales'); -$lb_license_name = licenseBootstrap::getName($s->get('license_name')); -$lb_license_head = licenseBootstrap::gethead($s->get('license_name'), licenseBootstrap::decode($s->get('license_head'))); +class Config extends dcNsProcess +{ + public static function init(): bool + { + static::$init == defined('DC_CONTEXT_ADMIN') + && dcCore::app()->auth?->isSuperAdmin() + && My::phpCompliant(); -# -- Set settings -- -if (!empty($_POST['save'])) { - try { - $lb_overwrite = !empty($_POST['lb_overwrite']); - $lb_write_full = !empty($_POST['lb_write_full']); - $lb_write_php = !empty($_POST['lb_write_php']); - $lb_write_js = !empty($_POST['lb_write_js']); - $lb_exclude_locales = !empty($_POST['lb_exclude_locales']); - $lb_license_name = $_POST['lb_license_name']; - $lb_license_head = licenseBootstrap::gethead($lb_license_name, !empty($_POST['lb_license_head_' . $lb_license_name]) ? $_POST['lb_license_head_' . $lb_license_name] : ''); + return static::$init; + } - $s->put('overwrite', $lb_overwrite); - $s->put('write_full', $lb_write_full); - $s->put('write_php', $lb_write_php); - $s->put('write_js', $lb_write_js); - $s->put('exclude_locales', $lb_exclude_locales); - $s->put('license_name', licenseBootstrap::getName($lb_license_name)); - $s->put('license_head', licenseBootstrap::encode($lb_license_head)); + public static function process(): bool + { + if (!static::$init) { + return false; + } - dcPage::addSuccessNotice( - __('Configuration has been successfully updated.') - ); - http::redirect( - dcCore::app()->admin->__get('list')->getURL('module=' . basename(__DIR__) . '&conf=1&redir=' . - dcCore::app()->admin->__get('list')->getRedir()) - ); - } catch (Exception $e) { - dcCore::app()->error->add($e->getMessage()); + if (empty($_POST['save'])) { + return true; + } + + $s = Settings::init(); + + # -- Set settings -- + try { + $license_name = $_POST['lb_license_name']; + $license_head = Utils::gethead( + $license_name, + !empty($_POST['lb_license_head_' . $license_name]) ? $_POST['lb_license_head_' . $license_name] : '' + ); + + $s->writeSetting('hide_distrib', !empty($_POST['lb_hide_distrib'])); + $s->writeSetting('overwrite', !empty($_POST['lb_overwrite'])); + $s->writeSetting('write_full', !empty($_POST['lb_write_full'])); + $s->writeSetting('write_php', !empty($_POST['lb_write_php'])); + $s->writeSetting('write_js', !empty($_POST['lb_write_js'])); + $s->writeSetting('exclude_locales', !empty($_POST['lb_exclude_locales'])); + $s->writeSetting('license_name', Utils::getName($license_name)); + $s->writeSetting('license_head', Utils::encode($license_head)); + + dcPage::addSuccessNotice( + __('Configuration has been successfully updated.') + ); + dcCore::app()->adminurl?->redirect('admin.plugins', [ + 'module' => My::id(), + 'conf' => '1', + 'redir' => dcCore::app()->admin->__get('list')->getRedir(), + ]); + } catch (Exception $e) { + dcCore::app()->error->add($e->getMessage()); + } + + return true; + } + + public static function render(): void + { + if (!static::$init) { + return; + } + + $s = Settings::init(); + + $licences = []; + foreach (Utils::getLicenses() as $name) { + $check = false; + $head = Utils::getHead($name); + if ($name == Utils::getName($s->license_name)) { + $check = true; + $head = Utils::getHead($name, Utils::getHead($s->license_name, Utils::decode($s->license_head))); + } + $licences[] = (new Para())->items([ + (new Radio(['lb_license_name', 'license_' . $name], $check))->value($name), + (new Label(sprintf(__('License %s:'), $name), Label::OUTSIDE_LABEL_AFTER))->for('license_' . $name)->class('classic'), + ]); + $licences[] = (new Para())->items([ + (new Textarea('lb_license_head_' . $name, $head))->class('maximal')->cols(50)->rows(10), + ]); + } + + echo + (new Div())->items([ + (new Fieldset())->class('fieldset')->legend((new Legend(__('Files'))))->fields([ + // hide_distrib + (new Para())->items([ + (new Checkbox('lb_hide_distrib', $s->hide_distrib))->value(1), + (new Label(__('Hide distributed modules from lists'), Label::OUTSIDE_LABEL_AFTER))->for('lb_hide_distrib')->class('classic'), + ]), + // overwrite + (new Para())->items([ + (new Checkbox('lb_overwrite', $s->overwrite))->value(1), + (new Label(__('Overwrite existing licenses'), Label::OUTSIDE_LABEL_AFTER))->for('lb_overwrite')->class('classic'), + ]), + // write_full + (new Para())->items([ + (new Checkbox('lb_write_full', $s->write_full))->value(1), + (new Label(__('Add full LICENSE file to module root'), Label::OUTSIDE_LABEL_AFTER))->for('lb_write_full')->class('classic'), + ]), + // write_php + (new Para())->items([ + (new Checkbox('lb_write_php', $s->write_php))->value(1), + (new Label(__('Add license block to PHP files'), Label::OUTSIDE_LABEL_AFTER))->for('lb_write_php')->class('classic'), + ]), + // write_js + (new Para())->items([ + (new Checkbox('lb_write_js', $s->write_js))->value(1), + (new Label(__('Add license block to JS files'), Label::OUTSIDE_LABEL_AFTER))->for('lb_write_js')->class('classic'), + ]), + // exclude_locales + (new Para())->items([ + (new Checkbox('lb_exclude_locales', $s->exclude_locales))->value(1), + (new Label(__('Do not add license block to files from locales folder'), Label::OUTSIDE_LABEL_AFTER))->for('lb_exclude_locales')->class('classic'), + ]), + ]), + (new Fieldset())->class('fieldset')->legend((new Legend(__('Licenses'))))->fields($licences), + ])->render(); } } - -# -- Display form -- -echo ' -
-

' . __('Files') . '

- -

- -

- -

- -

- -

- -
- -
-

' . __('Licenses') . '

'; - -foreach (licenseBootstrap::getLicenses() as $name) { - $check = false; - $head = licenseBootstrap::getHead($name); - if ($name == $lb_license_name) { - $check = true; - $head = licenseBootstrap::getHead($name, $lb_license_head); - } - echo ' -

-

' . - form::textarea('lb_license_head_' . $name, 50, 10, html::escapeHTML($head)) . ' -

'; -} - -echo ' -
'; diff --git a/src/Install.php b/src/Install.php index a9c32b8..c12a8b6 100644 --- a/src/Install.php +++ b/src/Install.php @@ -10,112 +10,66 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -# -- Module specs -- +namespace Dotclear\Plugin\licenseBootstrap; -$mod_conf = [ - [ - 'overwrite', - 'Overwrite existing licence', - false, - 'boolean', - ], - [ - 'write_full', - 'Add complete licence file', - true, - 'boolean', - ], - [ - 'write_php', - 'Write license into php files', - true, - 'boolean', - ], - [ - 'write_js', - 'Write license into js files', - false, - 'boolean', - ], - [ - 'exclude_locales', - 'Exclude locales from license', - true, - 'boolean', - ], - [ - 'license_name', - 'License short name', - 'gpl2', - 'string', - ], - [ - 'license_head', - 'File header licence text', - licenseBootstrap::encode( - licenseBootstrap::getHead('gpl2') - ), - 'string', - ], - [ - 'behavior_packman', - 'Add LicenceBootstrap to plugin pacKman', - false, - 'boolean', - ], -]; +use dcCore; +use dcNamespace; +use dcNsProcess; +use Exception; -# -- Nothing to change below -- +class Install extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN') + && My::phpCompliant() + && dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version')); -try { - # Check module version - if (!dcCore::app()->newVersion( - basename(__DIR__), - dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version') - )) { - return null; + return static::$init; } - // version < 2022.12.22 : upgrade settings ns and array - $current = dcCore::app()->getVersion(basename(__DIR__)); - if ($current && version_compare($current, '2022.12.22', '<')) { - $record = dcCore::app()->con->select( - 'SELECT * FROM ' . dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME . ' ' . - "WHERE setting_ns = 'licenseBootstrap' " - ); - $cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME); - while ($record->fetch()) { - if (in_array($record->setting_id, ['license_head'])) { - $cur->setting_value = (string) unserialize(base64_decode($record->setting_value)); - } - $cur->setting_ns = basename(__DIR__); - $cur->update( - "WHERE setting_id = '" . $record->setting_id . "' and setting_ns = 'licenseBootstrap' " . - 'AND blog_id ' . (null === $record->blog_id ? 'IS NULL ' : ("= '" . dcCore::app()->con->escape($record->blog_id) . "' ")) - ); - $cur->clean(); + public static function process(): bool + { + if (!static::$init) { + return false; + } + + try { + // Upgrade + self::growUp(); + + return true; + } catch (Exception $e) { + dcCore::app()->error->add($e->getMessage()); + + return false; } } - # Set module settings - dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); - foreach ($mod_conf as $v) { - dcCore::app()->blog->settings->__get(basename(__DIR__))->put( - $v[0], - $v[2], - $v[3], - $v[1], - false, - true - ); + + public static function growUp(): void + { + $current = dcCore::app()->getVersion(My::id()); + + // Update settings id, ns + if ($current && version_compare($current, '2022.12.22', '<')) { + $record = dcCore::app()->con->select( + 'SELECT * FROM ' . dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME . ' ' . + "WHERE setting_ns = 'licenseBootstrap' " + ); + $cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME); + while ($record->fetch()) { + if (in_array($record->f('setting_id'), ['license_head'])) { + $cur->setField('setting_value', (string) unserialize(base64_decode($record->f('setting_value')))); + } + $cur->setField('setting_ns', My::id()); + $cur->update( + "WHERE setting_id = '" . $record->f('setting_id') . "' and setting_ns = 'licenseBootstrap' " . + 'AND blog_id ' . (null === $record->f('blog_id') ? 'IS NULL ' : ("= '" . dcCore::app()->con->escapeStr($record->f('blog_id')) . "' ")) + ); + $cur->clean(); + } + } } - - return true; -} catch (Exception $e) { - dcCore::app()->error->add($e->getMessage()); - - return false; } diff --git a/src/Manage.php b/src/Manage.php index f650450..e7a29b4 100644 --- a/src/Manage.php +++ b/src/Manage.php @@ -10,94 +10,214 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -dcPage::checkSuper(); +namespace Dotclear\Plugin\licenseBootstrap; -# Queries -$action = $_POST['action'] ?? ''; -$type = isset($_POST['type']) && in_array($_POST['type'], ['plugins', 'themes']) ? $_POST['type'] : ''; +use dcCore; +use dcPage; +use dcThemes; +use dcNsProcess; +use Dotclear\Helper\Html\Html; +use Dotclear\Helper\Html\Form\{ + Checkbox, + Hidden, + Label, + Para, + Submit, + Text +}; +use Dotclear\Helper\File\Path; +use Exception; +use http; -# Settings -$s = dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); +class Manage extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN') + && dcCore::app()->auth?->isSuperAdmin() + && My::phpCompliant(); -# Modules -if (!(dcCore::app()->themes instanceof dcThemes)) { - dcCore::app()->themes = new dcThemes(); - dcCore::app()->themes->loadModules(dcCore::app()->blog->themes_path, null); -} -$themes = dcCore::app()->themes; -$plugins = dcCore::app()->plugins; + return static::$init; + } -# Rights -$is_editable = !empty($type) - && !empty($_POST['modules']) - && is_array($_POST['modules']); - -# Actions -try { - # Add license to modules - if ($action == 'addlicense' && $is_editable) { - $modules = array_keys($_POST['modules']); - - foreach ($modules as $id) { - if (!${$type}->moduleExists($id)) { - throw new Exception('No such module'); - } - - $module = ${$type}->getModules($id); - $module['id'] = $id; - $module['type'] = $type == 'themes' ? 'theme' : 'plugin'; - - licenseBootstrap::addLicense($module); + public static function process(): bool + { + if (!static::$init) { + return false; } - dcAdminNotices::addSuccessNotice( - __('License successfully added.') - ); - http::redirect( - empty($_POST['redir']) ? - dcCore::app()->admin->getPageURL() : $_POST['redir'] - ); + $type = in_array($_POST['type'] ?? '', ['plugins', 'themes']) ? $_POST['type'] : ''; + + if (($_POST['action'] ?? '') != 'addlicense' + || empty($type) + || empty($_POST['modules']) + || !is_array($_POST['modules']) + ) { + return true; + } + + $m = self::loadModules(); + + # Actions + try { + $modules = array_values($_POST['modules']); + + foreach ($modules as $id) { + if (!$m[$type]->moduleExists($id)) { + throw new Exception('No such module'); + } + + $module = $m[$type]->getModules($id); + $module['id'] = $id; + $module['type'] = $type == 'themes' ? 'theme' : 'plugin'; + + Utils::addLicense($module); + } + + dcPage::addSuccessNotice( + __('License successfully added.') + ); + http::redirect( + empty($_POST['redir']) ? + dcCore::app()->admin->getPageURL() : $_POST['redir'] + ); + } catch(Exception $e) { + dcCore::app()->error->add($e->getMessage()); + } + + return true; + } + + public static function render(): void + { + if (!static::$init) { + return; + } + + $m = self::loadModules(); + + # Display + dcPage::openModule( + My::name(), + dcPage::jsPageTabs() . + dcPage::jsModuleLoad(My::id() . '/js/licensebootstrap.js') . + + # --BEHAVIOR-- licenseBootstrapAdminHeader + dcCore::app()->callBehavior('licenseBootstrapAdminHeader') + ); + + echo + dcPage::breadcrumb([ + __('Plugins') => '', + My::name() => '', + ]) . + dcPage::notices(); + + self::displayModulesList( + $m['plugins']->getModules(), + 'plugins', + __('Installed plugins') + ); + + self::displayModulesList( + $m['themes']->getModules(), + 'themes', + __('Installed themes') + ); + + dcPage::helpBlock('licenseBootstrap'); + + dcPage::closeModule(); + } + + private static function displayModulesList(array $modules, string $type, string $title): void + { + if (Settings::init()->hide_distrib) { + $modules = array_diff_key($modules, array_flip(array_values(array_merge(explode(',', DC_DISTRIB_PLUGINS), explode(',', DC_DISTRIB_THEMES))))); + } + + echo + '
' . + '

' . $title . '

'; + + if (empty($modules)) { + echo + '

' . __('There are no modules.') . '

' . + '
'; + + return; + } + + echo + '
' . + '' . + '' . + '' . + '' . + '' . + ''; + + foreach (self::sortModules($modules) as $id => $module) { + echo + '' . + '' . + '' . + '' . + '' . + ''; + } + + echo + '
' . __('Id') . '' . __('Version') . '' . __('Name') . '' . __('Root') . '
' . + (new Para())->items([ + (new Checkbox(['modules[]', 'modules_' . Html::escapeHTML($id)], false))->value(Html::escapeHTML($id)), + (new Label(Html::escapeHTML($id), Label::OUTSIDE_LABEL_AFTER))->for('modules_' . Html::escapeHTML($id))->class('classic'), + ])->render() . + '' . + Html::escapeHTML($module['version']) . + '' . + __(Html::escapeHTML($module['name'])) . + '' . + dirname((string) Path::real($module['root'], false)) . + '
' . + '

' . + (new Para())->items([ + (new Hidden(['redir'], empty($_REQUEST['redir']) ? '' : Html::escapeHTML($_REQUEST['redir']))), + (new Hidden(['p'], My::id())), + (new Hidden(['type'], $type)), + (new Hidden(['action'], 'addlicense')), + (new Submit('addlicense'))->accesskey('s')->value(__('Add license to selected modules')), + dcCore::app()->formNonce(false), + ])->render() . + '
' . + + '
'; + } + + private static function sortModules(array $modules): array + { + $sorter = []; + foreach ($modules as $id => $module) { + $sorter[$id] = $id; + } + array_multisort($sorter, SORT_ASC, $modules); + + return $modules; + } + + private static function loadModules(): array + { + if (!(dcCore::app()->themes instanceof dcThemes)) { + dcCore::app()->themes = new dcThemes(); + dcCore::app()->themes->loadModules(dcCore::app()->blog->themes_path, null); + } + + return [ + 'themes' => dcCore::app()->themes, + 'plugins' => dcCore::app()->plugins, + ]; } -} catch(Exception $e) { - dcCore::app()->error->add($e->getMessage()); } - -# Display -echo -'' . __('License bootstrap') . '' . -dcPage::jsPageTabs() . -dcPage::jsModuleLoad(basename(__DIR__) . '/js/licensebootstrap.js') . - -# --BEHAVIOR-- licenseBootstrapAdminHeader -dcCore::app()->callBehavior('licenseBootstrapAdminHeader') . - -'' . - -dcPage::breadcrumb( - [ - __('Plugins') => '', - __('License bootstrap') => '', - ] -) . -dcPage::notices(); - -libLicenseBootstrap::modules( - $plugins->getModules(), - 'plugins', - __('Installed plugins') -); - -libLicenseBootstrap::modules( - $themes->getModules(), - 'themes', - __('Installed themes') -); - -dcPage::helpBlock('licenseBootstrap'); - -echo -''; diff --git a/src/ManageList.php b/src/ManageList.php deleted file mode 100644 index fc355b1..0000000 --- a/src/ManageList.php +++ /dev/null @@ -1,96 +0,0 @@ -' . - '

' . $title . '

'; - - if (empty($modules) && !is_array($modules)) { - echo - '

' . __('There are no modules.') . '

' . - '
'; - - return null; - } - - echo - '
' . - '' . - '' . - '' . - '' . - '' . - ''; - - foreach (self::sort($modules) as $id => $module) { - echo - '' . - '' . - '' . - '' . - '' . - ''; - } - - echo - '
' . __('Id') . '' . __('Version') . '' . __('Name') . '' . __('Root') . '
' . - html::escapeHTML($module['version']) . - '' . - __(html::escapeHTML($module['name'])) . - '' . - dirname(path::real($module['root'], false)) . - '
' . - '

' . - '

' . - ( - !empty($_REQUEST['redir']) ? - form::hidden( - ['redir'], - html::escapeHTML($_REQUEST['redir']) - ) : '' - ) . - form::hidden(['p'], 'licenseBootstrap') . - form::hidden(['type'], $type) . - form::hidden(['action'], 'addlicense') . - '' . - dcCore::app()->formNonce() . '

' . - '
' . - - '
'; - } - - protected static function sort($modules) - { - $sorter = []; - foreach ($modules as $id => $module) { - $sorter[$id] = $id; - } - array_multisort($sorter, SORT_ASC, $modules); - - return $modules; - } -} diff --git a/src/My.php b/src/My.php new file mode 100644 index 0000000..e2cb11e --- /dev/null +++ b/src/My.php @@ -0,0 +1,53 @@ +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..e2af96c --- /dev/null +++ b/src/Settings.php @@ -0,0 +1,112 @@ +blog?->settings->get(My::id()); + + $this->hide_distrib = (bool) ($s?->get('hide_distrib') ?? false); + $this->overwrite = (bool) ($s?->get('overwrite') ?? false); + $this->write_full = (bool) ($s?->get('write_full') ?? true); + $this->write_php = (bool) ($s?->get('pack_overwrite') ?? true); + $this->write_js = (bool) ($s?->get('pack_filename') ?? false); + $this->exclude_locales = (bool) ($s?->get('exclude_locales') ?? true); + $this->license_name = (string) ($s?->get('license_name') ?? 'gpl2'); + $this->license_head = (string) ($s?->get('license_head') ?? Utils::encode(Utils::getHead('gpl2'))); + $this->behavior_packman = (bool) ($s?->get('behavior_packman') ?? false); + } + + public static function init(): Settings + { + if (!(self::$settings instanceof self)) { + self::$settings = new self(); + } + + return self::$settings; + } + + 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)); + } +} diff --git a/src/Uninstall.php b/src/Uninstall.php index 0af5e4a..1199970 100644 --- a/src/Uninstall.php +++ b/src/Uninstall.php @@ -10,50 +10,71 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; +declare(strict_types=1); + +namespace Dotclear\Plugin\licenseBootstrap; + +class Uninstall +{ + protected static $init = false; + + public static function init(): bool + { + self::$init = defined('DC_RC_PATH'); + + return self::$init; + } + + public static function process($uninstaller): ?bool + { + if (!self::$init) { + return false; + } + + $uninstaller->addUserAction( + /* type */ + 'settings', + /* action */ + 'delete_all', + /* ns */ + My::id(), + /* desc */ + __('delete all settings') + ); + + $uninstaller->addUserAction( + /* type */ + 'plugins', + /* action */ + 'delete', + /* ns */ + My::id(), + /* desc */ + __('delete plugin files') + ); + + $uninstaller->addDirectAction( + /* type */ + 'settings', + /* action */ + 'delete_all', + /* ns */ + My::id(), + /* desc */ + sprintf(__('delete all %s settings'), My::id()) + ); + + $uninstaller->addDirectAction( + /* type */ + 'plugins', + /* action */ + 'delete', + /* ns */ + My::id(), + /* desc */ + sprintf(__('delete %s plugin files'), My::id()) + ); + + return true; + } } - -$this->addUserAction( - /* type */ - 'settings', - /* action */ - 'delete_all', - /* ns */ - basename(__DIR__), - /* desc */ - __('delete all settings') -); - -$this->addUserAction( - /* type */ - 'plugins', - /* action */ - 'delete', - /* ns */ - basename(__DIR__), - /* desc */ - __('delete plugin files') -); - -$this->addDirectAction( - /* type */ - 'settings', - /* action */ - 'delete_all', - /* ns */ - basename(__DIR__), - /* desc */ - sprintf(__('delete all %s settings'), basename(__DIR__)) -); - -$this->addDirectAction( - /* type */ - 'plugins', - /* action */ - 'delete', - /* ns */ - basename(__DIR__), - /* desc */ - sprintf(__('delete %s plugin files'), basename(__DIR__)) -); diff --git a/src/Utils.php b/src/Utils.php index 2879680..5500a8c 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -10,13 +10,19 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return null; -} +declare(strict_types=1); -class licenseBootstrap +namespace Dotclear\Plugin\licenseBootstrap; + +use dcAuth; +use dcCore; +use Dotclear\Helper\File\Files; +use Dotclear\Helper\File\Path; +use Exception; + +class Utils { - protected static $licenses = []; + protected static array $licenses = []; /** * Add license to a module. @@ -26,9 +32,9 @@ class licenseBootstrap * * @param array $module Module info */ - public static function addLicense($module) + public static function addLicense(array $module): void { - $s = dcCore::app()->blog->settings->get(basename(__DIR__)); + $s = Settings::init(); # --BEHAVIOR-- licenseBootstrapBeforeAddLicense dcCore::app()->callBehavior( @@ -36,22 +42,22 @@ class licenseBootstrap $module ); - if ($s->get('write_full')) { - licenseBootstrap::writeFullContent( - $s->get('license_name'), + if ($s->write_full) { + self::writeFullContent( + $s->license_name, $module, - $s->get('overwrite') + $s->overwrite ); } - licenseBootstrap::writeHeadContent( - $s->get('license_name'), - licenseBootstrap::decode($s->get('license_head')), + self::writeHeadContent( + $s->license_name, + self::decode($s->license_head), $module, dcCore::app()->auth, - $s->get('overwrite'), - $s->get('write_php'), - $s->get('write_js'), - $s->get('exclude_locales') + $s->overwrite, + $s->write_php, + $s->write_js, + $s->exclude_locales ); # --BEHAVIOR-- licenseBootstrapAfterAddLicense @@ -66,20 +72,20 @@ class licenseBootstrap * * @return array List of licenses names */ - public static function getLicenses() + public static function getLicenses(): array { - if (empty(licenseBootstrap::$licenses)) { + if (empty(self::$licenses)) { $file_reg = '/^([a-z0-9]+)\.head\.txt$/'; $res = []; - foreach (files::scandir(dirname(__FILE__) . '/licenses/') as $file) { + foreach (Files::scandir(__DIR__ . DIRECTORY_SEPARATOR . My::TEMPLATE_FOLDER . DIRECTORY_SEPARATOR) as $file) { if (preg_match($file_reg, $file, $matches)) { $res[] = $matches[1]; } } - licenseBootstrap::$licenses = $res; + self::$licenses = $res; } - return licenseBootstrap::$licenses; + return self::$licenses; } /** @@ -90,7 +96,7 @@ class licenseBootstrap * @param string $name License name * @return string License name */ - public static function getName($name = 'gpl2') + public static function getName(string $name = 'gpl2'): string { return in_array($name, self::getLicenses()) ? $name : 'gpl2'; } @@ -102,7 +108,7 @@ class licenseBootstrap * @param string $content Header content * @return string Header content */ - public static function getHead($name = 'gpl2', $content = '') + public static function getHead(string $name = 'gpl2', string $content = ''): string { if (!in_array($name, self::getLicenses())) { $name = 'gpl2'; @@ -119,7 +125,7 @@ class licenseBootstrap * @param string $name License name * @return string Full license content */ - public static function getFull($name = 'gpl2') + public static function getFull(string $name = 'gpl2'): string { return self::getContent($name, 'full'); } @@ -131,7 +137,7 @@ class licenseBootstrap * @param string $part License part (head or full) * @return string License content */ - public static function getContent($name = 'gpl2', $part = 'head') + public static function getContent(string $name = 'gpl2', string $part = 'head'): string { if (!in_array($name, self::getLicenses())) { $name = 'gpl2'; @@ -140,8 +146,8 @@ class licenseBootstrap $part = 'head'; } - return file_get_contents( - dirname(__FILE__) . '/licenses/' . $name . '.' . $part . '.txt' + return (string) file_get_contents( + implode(DIRECTORY_SEPARATOR, [__DIR__, My::TEMPLATE_FOLDER, $name . '.' . $part . '.txt']) ); } @@ -151,13 +157,13 @@ class licenseBootstrap * @param string $name License name * @param string $content License block content * @param array $module Module info - * @param object $user dcAuth instance + * @param dcAuth $user dcAuth instance * @param boolean $overwrite Overwrite existing license * @param boolean $php Write license in PHP * @param boolean $js Write license in JS * @param boolean $locales Excludes locales folder */ - public static function writeHeadContent($name, $content, $module, $user, $overwrite, $php, $js, $locales) + public static function writeHeadContent(string $name, string $content, array $module, dcAuth $user, bool $overwrite, bool $php, bool $js, bool $locales): void { if (!isset($module['root']) || !is_writable($module['root'])) { throw new Exception(); @@ -174,14 +180,14 @@ class licenseBootstrap continue; } - $path = $module['root'] . '/' . $file; - $extension = files::getExtension($file); + $path = $module['root'] . DIRECTORY_SEPARATOR . $file; + $extension = Files::getExtension($file); if ($php && $extension == 'php') { file_put_contents( $file, self::replacePhpContent( - file_get_contents($file), + (string) file_get_contents($file), $license, $overwrite ) @@ -190,7 +196,7 @@ class licenseBootstrap file_put_contents( $file, self::replaceJsContent( - file_get_contents($file), + (string) file_get_contents($file), $license, $overwrite ) @@ -206,17 +212,17 @@ class licenseBootstrap * @param array $module Module info * @param boolean $overwrite Overwrite existing license */ - public static function writeFullContent($name, $module, $overwrite) + public static function writeFullContent(string $name, array $module, bool $overwrite): void { if (!isset($module['root']) || !is_writable($module['root'])) { throw new Exception(); } - if (file_exists($module['root'] . '/LICENSE') && !$overwrite) { - return null; + if (file_exists($module['root'] . DIRECTORY_SEPARATOR . 'LICENSE') && !$overwrite) { + return; } file_put_contents( - $module['root'] . '/LICENSE', + $module['root'] . DIRECTORY_SEPARATOR . 'LICENSE', self::getFull($name) ); } @@ -229,7 +235,7 @@ class licenseBootstrap * @param boolean $overwrite Overwrite existing license * @return string File content */ - protected static function replacePhpContent($content, $license, $overwrite) + protected static function replacePhpContent(string $content, string $license, bool $overwrite): string { $clean = preg_replace( '/((# -- BEGIN LICENSE BLOCK ([-]+))(.*?)' . @@ -263,7 +269,7 @@ class licenseBootstrap * @param boolean $overwrite Overwrite existing license * @return string File content */ - protected static function replaceJsContent($content, $license, $overwrite) + protected static function replaceJsContent(string $content, string $license, bool $overwrite): string { $clean = preg_replace( '/((\/\* -- BEGIN LICENSE BLOCK ([-]+))(.*?)' . @@ -290,10 +296,10 @@ class licenseBootstrap * * @param string $content License content * @param array $module Module info - * @param object $user User info + * @param dcAuth $user User info * @return string License content */ - protected static function replaceInfo($content, $module, $user) + protected static function replaceInfo(string $content, array $module, dcAuth $user): string { return str_replace( [ @@ -330,10 +336,10 @@ class licenseBootstrap * @param array $res Ignore * @return array List of files */ - protected static function getModuleFiles($path, $dir = '', $res = []) + protected static function getModuleFiles(string $path, string $dir = '', array $res = []): array { - $path = path::real($path); - if (!is_dir($path) || !is_readable($path)) { + $path = Path::real($path); + if ($path === false || !is_dir($path) || !is_readable($path)) { return []; } @@ -341,34 +347,38 @@ class licenseBootstrap $dir = $path; } - $files = files::scandir($path); + $files = Files::scandir($path); foreach ($files as $file) { if (substr($file, 0, 1) == '.') { continue; } - if (is_dir($path . '/' . $file)) { + if (is_dir($path . DIRECTORY_SEPARATOR . $file)) { $res = self::getModuleFiles( - $path . '/' . $file, - $dir . '/' . $file, + $path . DIRECTORY_SEPARATOR . $file, + $dir . DIRECTORY_SEPARATOR . $file, $res ); } else { - $res[] = empty($dir) ? $file : $dir . '/' . $file; + $res[] = empty($dir) ? $file : $dir . DIRECTORY_SEPARATOR . $file; } } return $res; } - public static function encode($a) + public static function encode(string $a): string { - return json_encode($a); + $r = json_encode($a); + + return $r === false ? '' : $r; } - public static function decode($a) + public static function decode(string $a): string { - return json_decode($a, true); + $r = json_decode($a, true); + + return $r === false ? '' : $r; } }