use namespace
parent
dd618e229e
commit
114d443f88
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @brief arlequin, a plugin for Dotclear 2
|
||||
*
|
||||
* @package Dotclear
|
||||
* @subpackage Plugin
|
||||
*
|
||||
* @author Oleksandr Syenchuk, Pierre Van Glabeke and contributors
|
||||
*
|
||||
* @copyright Jean-Crhistian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mt_models = [];
|
||||
|
||||
/* Syntaxe pour ajouter vos propres modèles prédéfinis :
|
||||
|
||||
$mt_models[] = array(
|
||||
'name'=>__('Model name'), // Nom du modèle prédéfini, éventuellement
|
||||
// traduit dans un fichier de langue
|
||||
's_html'=>'[HTML code]', // Code HTML du sélecteur de thème
|
||||
'e_html'=>'[HTML code]', // Code HTML d'un item pouvant être sélectionné
|
||||
'a_html'=>'[HTML code]' // Code HTML d'un item actif (thème sélectionné)
|
||||
);
|
||||
|
||||
//*/
|
||||
|
||||
$mt_models[] = [
|
||||
'name' => __('Bullets list'),
|
||||
's_html' => '<ul>%2$s</ul>',
|
||||
'e_html' => '<li><a href="%1$s%2$s%3$s">%4$s</a></li>',
|
||||
'a_html' => '<li><strong>%4$s</strong></li>',
|
||||
];
|
||||
|
||||
$mt_models[] = [
|
||||
'name' => __('Scrolled list'),
|
||||
's_html' => '<form action="%1$s" method="post">' . "\n" .
|
||||
'<p><select name="theme">' . "\n" .
|
||||
'%2$s' . "\n" .
|
||||
'</select>' . "\n" .
|
||||
'<input type="submit" value="' . __('ok') . '"/></p>' . "\n" .
|
||||
'</form>',
|
||||
'e_html' => '<option value="%3$s">%4$s</option>',
|
||||
'a_html' => '<option value="%3$s" selected="selected" disabled="disabled">%4$s (' . __('active theme') . ')</option>',
|
||||
];
|
|
@ -7,38 +7,66 @@
|
|||
*
|
||||
* @author Oleksandr Syenchuk, Pierre Van Glabeke and contributors
|
||||
*
|
||||
* @copyright Jean-Crhistian Denis
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\arlequin;
|
||||
|
||||
use dcAdmin;
|
||||
use dcCore;
|
||||
use dcFavorites;
|
||||
use dcNsProcess;
|
||||
use dcPage;
|
||||
|
||||
class Backend extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||
&& My::phpCompliant()
|
||||
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||
]), dcCore::app()->blog->id);
|
||||
|
||||
return static::$init;
|
||||
}
|
||||
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!static::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dcCore::app()->menu[dcAdmin::MENU_BLOG]->addItem(
|
||||
My::name(),
|
||||
dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||
dcPage::getPF(My::id() . '/icon.png'),
|
||||
preg_match(
|
||||
'/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/',
|
||||
$_SERVER['REQUEST_URI']
|
||||
),
|
||||
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||
]), dcCore::app()->blog->id)
|
||||
);
|
||||
|
||||
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.png'),
|
||||
'large-icon' => dcPage::getPF(My::id() . '/icon-big.png'),
|
||||
'permissions' => dcCore::app()->auth->makePermissions([
|
||||
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||
]),
|
||||
]);
|
||||
},
|
||||
'initWidgets' => [Widgets::class, 'initWidgets'],
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
require __DIR__ . '/_widgets.php';
|
||||
|
||||
// Admin sidebar menu
|
||||
dcCore::app()->menu[dcAdmin::MENU_BLOG]->addItem(
|
||||
__('Arlequin'),
|
||||
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
|
||||
dcPage::getPF(basename(__DIR__) . '/icon.png'),
|
||||
preg_match(
|
||||
'/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/',
|
||||
$_SERVER['REQUEST_URI']
|
||||
),
|
||||
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
||||
]), dcCore::app()->blog->id)
|
||||
);
|
||||
|
||||
// Admin dashbaord favorite
|
||||
dcCore::app()->addBehavior('adminDashboardFavoritesV2', function ($favs) {
|
||||
$favs->register(basename(__DIR__), [
|
||||
'title' => __('Arlequin'),
|
||||
'url' => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
|
||||
'small-icon' => dcPage::getPF(basename(__DIR__) . '/icon.png'),
|
||||
'large-icon' => dcPage::getPF(basename(__DIR__) . '/icon-big.png'),
|
||||
'permissions' => dcCore::app()->auth->makePermissions([
|
||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
||||
]),
|
||||
]);
|
||||
});
|
||||
|
|
185
src/Frontend.php
185
src/Frontend.php
|
@ -7,168 +7,81 @@
|
|||
*
|
||||
* @author Oleksandr Syenchuk, Pierre Van Glabeke and contributors
|
||||
*
|
||||
* @copyright Jean-Crhistian Denis
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_RC_PATH')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
require __DIR__ . '/_widgets.php';
|
||||
namespace Dotclear\Plugin\arlequin;
|
||||
|
||||
publicArlequinEngine::init();
|
||||
dcCore::app()->addBehavior('publicBeforeDocumentV2', ['publicArlequinEngine','adjustCache']);
|
||||
dcCore::app()->tpl->addValue('themesList', ['publicArlequinInterface','template']);
|
||||
use dcCore;
|
||||
use dcNsProcess;
|
||||
use Dotclear\Helper\Network\Http;
|
||||
|
||||
class publicArlequinEngine
|
||||
class Frontend extends dcNsProcess
|
||||
{
|
||||
public static $cookie_theme;
|
||||
public static $cookie_upddt;
|
||||
public const COOKIE_THEME_PREFIX = 'dc_theme_';
|
||||
public const COOKIE_UPDDT_PREFIX = 'dc_user_upddt_';
|
||||
|
||||
public static function init()
|
||||
public static function init(): bool
|
||||
{
|
||||
$cname = base_convert(dcCore::app()->blog->uid, 16, 36);
|
||||
self::$cookie_theme = 'dc_theme_' . $cname;
|
||||
self::$cookie_upddt = 'dc_user_upddt_' . $cname;
|
||||
static::$init = true;
|
||||
|
||||
return static::$init;
|
||||
}
|
||||
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!static::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($_REQUEST['theme'])) {
|
||||
# Set cookie for 365 days
|
||||
setcookie(self::$cookie_theme, $_REQUEST['theme'], time() + 31536000, '/');
|
||||
setcookie(self::$cookie_upddt, (string) time(), time() + 31536000, '/');
|
||||
setcookie(self::COOKIE_THEME_PREFIX . self::cookieSuffix(), $_REQUEST['theme'], time() + 31536000, '/');
|
||||
setcookie(self::COOKIE_UPDDT_PREFIX . self::cookieSuffix(), (string) time(), time() + 31536000, '/');
|
||||
|
||||
# Redirect if needed
|
||||
if (isset($_GET['theme'])) {
|
||||
$p = '/(\?|&)theme(=.*)?$/';
|
||||
http::redirect(preg_replace($p, '', http::getSelfURI()));
|
||||
Http::redirect(preg_replace($p, '', Http::getSelfURI()));
|
||||
}
|
||||
|
||||
# Switch theme
|
||||
self::switchTheme($_REQUEST['theme']);
|
||||
} elseif (!empty($_COOKIE[self::$cookie_theme])) {
|
||||
self::switchTheme($_COOKIE[self::$cookie_theme]);
|
||||
} elseif (!empty($_COOKIE[self::COOKIE_THEME_PREFIX . self::cookieSuffix()])) {
|
||||
self::switchTheme($_COOKIE[self::COOKIE_THEME_PREFIX . self::cookieSuffix()]);
|
||||
}
|
||||
|
||||
dcCore::app()->addBehaviors([
|
||||
'publicBeforeDocumentV2' => [self::class, 'adjustCache'],
|
||||
'initWidgets' => [Widgets::class, 'initWidgets'],
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static function cookieSuffix(): string
|
||||
{
|
||||
return base_convert(dcCore::app()->blog->uid, 16, 36);
|
||||
}
|
||||
|
||||
public static function adjustCache(): void
|
||||
{
|
||||
if (!empty($_COOKIE[self::COOKIE_UPDDT_PREFIX . self::cookieSuffix()])) {
|
||||
dcCore::app()->cache['mod_ts'][] = (int) $_COOKIE[self::COOKIE_UPDDT_PREFIX . self::cookieSuffix()];
|
||||
}
|
||||
}
|
||||
|
||||
public static function adjustCache()
|
||||
public static function switchTheme(string $theme): void
|
||||
{
|
||||
if (!empty($_COOKIE[self::$cookie_upddt])) {
|
||||
dcCore::app()->cache['mod_ts'][] = (int) $_COOKIE[self::$cookie_upddt];
|
||||
}
|
||||
}
|
||||
|
||||
public static function switchTheme($theme)
|
||||
{
|
||||
if (dcCore::app()->blog->settings->arlequinMulti->mt_exclude) {
|
||||
if (in_array($theme, explode('/', dcCore::app()->blog->settings->arlequinMulti->mt_exclude))) {
|
||||
if (dcCore::app()->blog->settings->get(My::id())->get('mt_exclude')) {
|
||||
if (in_array($theme, explode('/', dcCore::app()->blog->settings->get(My::id())->get('mt_exclude')))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dcCore::app()->public->theme = dcCore::app()->blog->settings->system->theme = $theme;
|
||||
}
|
||||
}
|
||||
|
||||
class publicArlequinInterface
|
||||
{
|
||||
public static function arlequinWidget($w)
|
||||
{
|
||||
return self::getHTML($w);
|
||||
}
|
||||
|
||||
public static function template($attr)
|
||||
{
|
||||
return '<?php echo publicArlequinInterface::getHTML(); ?>';
|
||||
}
|
||||
|
||||
public static function getHTML($w = false)
|
||||
{
|
||||
if ($w->offline) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$w->checkHomeOnly(dcCore::app()->url->type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cfg = @unserialize(dcCore::app()->blog->settings->arlequinMulti->get('mt_cfg'));
|
||||
if ($cfg === false || ($names = self::getNames()) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Current page URL and the associated query string. Note : the URL for
|
||||
# the switcher ($s_url) is different to the URL for an item ($e_url)
|
||||
$s_url = $e_url = http::getSelfURI();
|
||||
|
||||
# If theme setting is already present in URL, we will replace its value
|
||||
$replace = preg_match('/(\\?|&)theme\\=[^&]*/', $e_url);
|
||||
|
||||
# URI extension to send theme setting by query string
|
||||
if ($replace) {
|
||||
$ext = '';
|
||||
} elseif (strpos($e_url, '?') === false) {
|
||||
$ext = '?theme=';
|
||||
} else {
|
||||
$ext = (substr($e_url, -1) == '?' ? '' : '&') . 'theme=';
|
||||
}
|
||||
|
||||
$res = '';
|
||||
foreach ($names as $k => $v) {
|
||||
if ($k == dcCore::app()->public->theme) {
|
||||
$format = $cfg['a_html'];
|
||||
} else {
|
||||
$format = $cfg['e_html'];
|
||||
}
|
||||
|
||||
if ($replace) {
|
||||
$e_url = preg_replace(
|
||||
'/(\\?|&)(theme\\=)([^&]*)/',
|
||||
'$1${2}' . addcslashes($k, '$\\'),
|
||||
$e_url
|
||||
);
|
||||
$val = '';
|
||||
} else {
|
||||
$val = html::escapeHTML(rawurlencode($k));
|
||||
}
|
||||
$res .= sprintf(
|
||||
$format,
|
||||
$e_url,
|
||||
$ext,
|
||||
$val,
|
||||
html::escapeHTML($v['name']),
|
||||
html::escapeHTML($v['desc']),
|
||||
html::escapeHTML($k)
|
||||
);
|
||||
}
|
||||
|
||||
# Nothing to display
|
||||
if (!trim($res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$res = sprintf($cfg['s_html'], $s_url, $res);
|
||||
|
||||
if ($w) {
|
||||
return $w->renderDiv(
|
||||
$w->content_only,
|
||||
'arlequin ' . $w->class,
|
||||
'',
|
||||
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') . $res
|
||||
);
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function getNames()
|
||||
{
|
||||
$mt_exclude = dcCore::app()->blog->settings->arlequinMulti->mt_exclude;
|
||||
$exclude = [];
|
||||
if (!empty($mt_exclude)) {
|
||||
$exclude = array_flip(explode('/', dcCore::app()->blog->settings->arlequinMulti->mt_exclude));
|
||||
}
|
||||
|
||||
$names = array_diff_key(dcCore::app()->themes->getModules(), $exclude);
|
||||
|
||||
return empty($names) ? false : $names;
|
||||
dcCore::app()->blog->settings->get('system')->set('theme', $theme);
|
||||
dcCore::app()->public->theme = $theme;
|
||||
}
|
||||
}
|
||||
|
|
280
src/Manage.php
280
src/Manage.php
|
@ -7,109 +7,183 @@
|
|||
*
|
||||
* @author Oleksandr Syenchuk, Pierre Van Glabeke and contributors
|
||||
*
|
||||
* @copyright Jean-Crhistian Denis
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
||||
return;
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\arlequin;
|
||||
|
||||
use ArrayObject;
|
||||
use dcCore;
|
||||
use dcNsProcess;
|
||||
use dcPage;
|
||||
use Dotclear\Helper\Html\Form\{
|
||||
Div,
|
||||
Form,
|
||||
Input,
|
||||
Label,
|
||||
Note,
|
||||
Para,
|
||||
Submit,
|
||||
Text,
|
||||
Textarea
|
||||
};
|
||||
use Dotclear\Helper\Html\Html;
|
||||
use Exception;
|
||||
|
||||
class Manage extends dcNsProcess
|
||||
{
|
||||
public static function init(): bool
|
||||
{
|
||||
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||
&& My::phpCompliant()
|
||||
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||
]), dcCore::app()->blog->id);
|
||||
|
||||
return static::$init;
|
||||
}
|
||||
|
||||
public static function process(): bool
|
||||
{
|
||||
if (!static::$init) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$s = dcCore::app()->blog->settings->get(My::id());
|
||||
|
||||
$model = json_decode((string) $s->get('model'), true);
|
||||
$exclude = $s->get('exclude');
|
||||
|
||||
// initialize settings
|
||||
$initialized = false;
|
||||
if ($model === false || $exclude === null || !(isset($model['e_html']) && isset($model['a_html']) && isset($model['s_html']))) {
|
||||
$model = My::defaultModel();
|
||||
$s->put('model', json_encode($model), 'string', 'Arlequin configuration');
|
||||
$s->put('exclude', 'customCSS', 'string', 'Excluded themes');
|
||||
|
||||
dcPage::AddSuccessNotice(__('Settings have been reinitialized.'));
|
||||
dcCore::app()->blog->triggerBlog();
|
||||
}
|
||||
|
||||
// collect settings
|
||||
if (isset($_POST['mt_action_config'])) {
|
||||
$model['e_html'] = $_POST['e_html'];
|
||||
$model['a_html'] = $_POST['a_html'];
|
||||
$model['s_html'] = $_POST['s_html'];
|
||||
$exclude = $_POST['exclude'];
|
||||
}
|
||||
|
||||
// save settings
|
||||
if (isset($_POST['mt_action_config'])) {
|
||||
$s->put('model', json_encode($model));
|
||||
$s->put('exclude', $exclude);
|
||||
|
||||
dcPage::AddSuccessNotice(__('System settings have been updated.'));
|
||||
dcCore::app()->blog->triggerBlog();
|
||||
dcCore::app()->adminurl->redirect('admin.plugin.' . My::id(), ['config' => 1]);
|
||||
}
|
||||
|
||||
// restore settings
|
||||
if (isset($_POST['mt_action_restore'])) {
|
||||
$s->drop('model');
|
||||
$s->drop('exclude');
|
||||
|
||||
dcPage::AddSuccessNotice(__('Settings have been reinitialized.'));
|
||||
dcCore::app()->blog->triggerBlog();
|
||||
dcCore::app()->adminurl->redirect('admin.plugin.' . My::id(), ['restore' => 1]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function render(): void
|
||||
{
|
||||
if (!static::$init) {
|
||||
return;
|
||||
}
|
||||
|
||||
$models = new ArrayObject(My::distributedModels());
|
||||
|
||||
dcCore::app()->callBehavior('arlequinAddModels', $models);
|
||||
|
||||
$models = iterator_to_array($models);
|
||||
$s = dcCore::app()->blog->settings->get(My::id());
|
||||
$model = json_decode((string) $s->get('model'), true);
|
||||
$header = '';
|
||||
|
||||
foreach ($models as $m) {
|
||||
$header .= "\t" .
|
||||
'arlequin.addModel(' .
|
||||
'"' . Html::escapeJS($m['name']) . '",' .
|
||||
'"' . addcslashes($m['s_html'], "\n\"\'") . '",' .
|
||||
'"' . addcslashes($m['e_html'], "\n\"\'") . '",' .
|
||||
'"' . addcslashes($m['a_html'], "\n\"\'") . '"' .
|
||||
");\n";
|
||||
}
|
||||
|
||||
dcPage::openModule(
|
||||
My::name(),
|
||||
dcPage::jsModuleLoad(My::id() . '/js/models.js') . '
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
arlequin.msg.predefined_models = "' . Html::escapeJS(__('Predefined models')) . '";
|
||||
arlequin.msg.select_model = "' . Html::escapeJS(__('Select a model')) . '";
|
||||
arlequin.msg.user_defined = "' . Html::escapeJS(__('User defined')) . '";
|
||||
$(function() {
|
||||
arlequin.addDefault();
|
||||
' . $header . '
|
||||
});
|
||||
//]]>
|
||||
</script>'
|
||||
);
|
||||
|
||||
echo
|
||||
dcPage::breadcrumb([
|
||||
Html::escapeHTML(dcCore::app()->blog->name) => '',
|
||||
My::name() => '',
|
||||
]) .
|
||||
dcPage::notices() .
|
||||
|
||||
(new Form(My::id() . 'form'))->method('post')->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->fields([
|
||||
(new Text('h4', __('Switcher display format'))),
|
||||
(new Div())->id('models'),
|
||||
(new Div())->class('two-boxes odd')->items([
|
||||
(new Para())->items([
|
||||
(new Label(__('Switcher HTML code:'), Label::OUTSIDE_LABEL_BEFORE))->for('s_html'),
|
||||
(new Textarea('s_html', Html::escapeHTML($model['s_html'])))->cols(50)->rows(10),
|
||||
]),
|
||||
]),
|
||||
(new Div())->class('two-boxes even')->items([
|
||||
(new Para())->items([
|
||||
(new Label(__('Item HTML code:'), Label::OUTSIDE_LABEL_BEFORE))->for('e_html'),
|
||||
(new Input('e_html'))->size(50)->maxlenght(200)->value(Html::escapeHTML($model['e_html'])),
|
||||
]),
|
||||
(new Para())->items([
|
||||
(new Label(__('Active item HTML code:'), Label::OUTSIDE_LABEL_BEFORE))->for('a_html'),
|
||||
(new Input('a_html'))->size(50)->maxlenght(200)->value(Html::escapeHTML($model['a_html'])),
|
||||
]),
|
||||
]),
|
||||
(new Div())->class('two-boxes odd')->items([
|
||||
(new Para())->items([
|
||||
(new Label(__('Excluded themes:'), Label::OUTSIDE_LABEL_BEFORE))->for('exclude'),
|
||||
(new Input('exclude'))->size(50)->maxlenght(200)->value(Html::escapeHTML($s->exclude)),
|
||||
]),
|
||||
(new Note())->class('form-note')->text('Semicolon separated list of themes IDs (theme folder name). Ex: ductile;berlin'),
|
||||
]),
|
||||
(new Para())->separator(' ')->items([
|
||||
dcCore::app()->formNonce(false),
|
||||
(new Submit(['mt_action_config']))->value(__('Save')),
|
||||
(new Submit(['mt_action_restore']))->value(__('Restore defaults')),
|
||||
]),
|
||||
])->render();
|
||||
|
||||
dcPage::helpBlock('arlequin');
|
||||
dcPage::closeModule();
|
||||
}
|
||||
}
|
||||
|
||||
$mt_models = [];
|
||||
|
||||
try {
|
||||
include __DIR__ . '/inc/models.php';
|
||||
|
||||
// Initialisation
|
||||
dcCore::app()->blog->settings->addNamespace('arlequinMulti');
|
||||
[$mt_cfg, $mt_exclude] = adminArlequin::loadSettings(dcCore::app()->blog->settings);
|
||||
if (adminArlequin::$initialized) {
|
||||
dcAdminNotices::AddSuccessNotice(__('Settings have been reinitialized.'));
|
||||
}
|
||||
|
||||
// Enregistrement des données depuis les formulaires
|
||||
if (isset($_POST['mt_action_config'])) {
|
||||
$mt_cfg['e_html'] = $_POST['e_html'];
|
||||
$mt_cfg['a_html'] = $_POST['a_html'];
|
||||
$mt_cfg['s_html'] = $_POST['s_html'];
|
||||
$mt_exclude = $_POST['mt_exclude'];
|
||||
}
|
||||
|
||||
// Traitement des requêtes
|
||||
if (isset($_POST['mt_action_config'])) {
|
||||
dcCore::app()->blog->settings->arlequinMulti->put('mt_cfg', serialize($mt_cfg));
|
||||
dcCore::app()->blog->settings->arlequinMulti->put('mt_exclude', $mt_exclude);
|
||||
dcAdminNotices::AddSuccessNotice(__('System settings have been updated.'));
|
||||
dcCore::app()->blog->triggerBlog();
|
||||
dcCore::app()->adminurl->redirect('admin.plugin.' . basename(__DIR__), ['config' => 1]);
|
||||
}
|
||||
if (isset($_POST['mt_action_restore'])) {
|
||||
dcCore::app()->blog->settings->arlequinMulti->drop('mt_cfg');
|
||||
dcCore::app()->blog->settings->arlequinMulti->drop('mt_exclude');
|
||||
dcAdminNotices::AddSuccessNotice(__('Settings have been reinitialized.'));
|
||||
dcCore::app()->blog->triggerBlog();
|
||||
dcCore::app()->adminurl->redirect('admin.plugin.' . basename(__DIR__), ['restore' => 1]);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dcCore::app()->error->add($e->getMessage());
|
||||
}
|
||||
|
||||
// Headers
|
||||
$jsModels = '';
|
||||
$cslashes = "\n\"\'";
|
||||
foreach ($mt_models as $m) { // @phpstan-ignore-line
|
||||
$jsModels .= "\t" .
|
||||
'arlequin.addModel(' .
|
||||
'"' . html::escapeJS($m['name']) . '",' .
|
||||
'"' . addcslashes($m['s_html'], $cslashes) . '",' .
|
||||
'"' . addcslashes($m['e_html'], $cslashes) . '",' .
|
||||
'"' . addcslashes($m['a_html'], $cslashes) . '"' .
|
||||
");\n";
|
||||
}
|
||||
|
||||
// DISPLAY
|
||||
echo '
|
||||
<html><head><title>' . __('Arlequin') . '</title>' .
|
||||
dcPage::jsLoad(dcPage::getPF(basename(__DIR__) . '/js/models.js')) . '
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
arlequin.msg.predefined_models = "' . html::escapeJS(__('Predefined models')) . '";
|
||||
arlequin.msg.select_model = "' . html::escapeJS(__('Select a model')) . '";
|
||||
arlequin.msg.user_defined = "' . html::escapeJS(__('User defined')) . '";
|
||||
$(function() {
|
||||
arlequin.addDefault();
|
||||
' . $jsModels . '
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
</head><body>' .
|
||||
dcPage::breadcrumb([
|
||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
||||
'<span class="page-title">' . __('Arlequin') . '</span>' => '',
|
||||
]) .
|
||||
dcPage::notices() . '
|
||||
|
||||
<form action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)) . '" method="post">
|
||||
<h4>' . __('Switcher display format') . '</h4>
|
||||
<div id="models"></div>
|
||||
|
||||
<div class="two-boxes odd">
|
||||
<p><label for="s_html">' . __('Switcher HTML code:') . '</label> ' .
|
||||
form::textArea('s_html', 50, 10, html::escapeHTML($mt_cfg['s_html'])) . '</p>
|
||||
</div><div class="two-boxes even">
|
||||
<p><label for="e_html">' . __('Item HTML code:') . '</label> ' .
|
||||
form::field('e_html', 50, 200, html::escapeHTML($mt_cfg['e_html'])) . '</p>
|
||||
<p><label for="a_html">' . __('Active item HTML code:') . '</label> ' .
|
||||
form::field('a_html', 50, 200, html::escapeHTML($mt_cfg['a_html'])) . '</p>
|
||||
</div><div class="two-boxes odd">
|
||||
<p><label for="mt_exclude">' . __("Excluded themes (separated by slashs '/'):") . '</label> ' .
|
||||
form::field('mt_exclude', 50, 200, html::escapeHTML($mt_exclude)) . '</p>
|
||||
<p class="info">' . __('The names to be taken into account are those of the theme files.') . '</p>
|
||||
</div>
|
||||
<p>
|
||||
<input type="submit" name="mt_action_config" value="' . __('Save') . '" />
|
||||
<input type="submit" name="mt_action_restore" value="' . __('Restore defaults') . '" />' .
|
||||
dcCore::app()->formNonce() . '</p>
|
||||
</form>';
|
||||
|
||||
dcPage::helpBlock('arlequin'); ?>
|
||||
</body></html>
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
/**
|
||||
* @brief arlequin, a plugin for Dotclear 2
|
||||
*
|
||||
* @package Dotclear
|
||||
* @subpackage Plugin
|
||||
*
|
||||
* @author Oleksandr Syenchuk, Pierre Van Glabeke and contributors
|
||||
*
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Dotclear\Plugin\arlequin;
|
||||
|
||||
use dcCore;
|
||||
|
||||
/**
|
||||
* Plugin definitions.
|
||||
*/
|
||||
class My
|
||||
{
|
||||
/** @var string Required php version */
|
||||
public const PHP_MIN = '7.4';
|
||||
|
||||
/**
|
||||
* This module id.
|
||||
*/
|
||||
public static function id(): string
|
||||
{
|
||||
return basename(dirname(__DIR__));
|
||||
}
|
||||
|
||||
/**
|
||||
* This module name.
|
||||
*/
|
||||
public static function name(): string
|
||||
{
|
||||
return __((string) dcCore::app()->plugins->moduleInfo(self::id(), 'name'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check php version.
|
||||
*/
|
||||
public static function phpCompliant(): bool
|
||||
{
|
||||
return version_compare(phpversion(), self::PHP_MIN, '>=');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get distributed models.
|
||||
*
|
||||
* Use Behavior arlequinAddModels to add models with synthax:
|
||||
* [
|
||||
* 'name'=>__('Model name'), // Nom du modèle prédéfini
|
||||
* 's_html'=>'[HTML code]', // Code HTML du sélecteur de thème
|
||||
* 'e_html'=>'[HTML code]', // Code HTML d'un item pouvant être sélectionné
|
||||
* 'a_html'=>'[HTML code]' // Code HTML d'un item actif (thème sélectionné)
|
||||
* ]
|
||||
*/
|
||||
public static function distributedModels(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'name' => __('Bullets list'),
|
||||
's_html' => '<ul>%2$s</ul>',
|
||||
'e_html' => '<li><a href="%1$s%2$s%3$s">%4$s</a></li>',
|
||||
'a_html' => '<li><strong>%4$s</strong></li>',
|
||||
],
|
||||
[
|
||||
'name' => __('Scrolled list'),
|
||||
's_html' => '<form action="%1$s" method="post">' . "\n" .
|
||||
'<p><select name="theme">' . "\n" .
|
||||
'%2$s' . "\n" .
|
||||
'</select>' . "\n" .
|
||||
'<input type="submit" value="' . __('ok') . '"/></p>' . "\n" .
|
||||
'</form>',
|
||||
'e_html' => '<option value="%3$s">%4$s</option>',
|
||||
'a_html' => '<option value="%3$s" selected="selected" disabled="disabled">%4$s (' . __('active theme') . ')</option>',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function defaultModel(): array
|
||||
{
|
||||
return [
|
||||
'e_html' => '<li><a href="%1$s%2$s%3$s">%4$s</a></li>',
|
||||
'a_html' => '<li><strong>%4$s</strong></li>',
|
||||
's_html' => '<ul>%2$s</ul>',
|
||||
];
|
||||
}
|
||||
}
|
120
src/Widgets.php
120
src/Widgets.php
|
@ -7,25 +7,28 @@
|
|||
*
|
||||
* @author Oleksandr Syenchuk, Pierre Van Glabeke and contributors
|
||||
*
|
||||
* @copyright Jean-Crhistian Denis
|
||||
* @copyright Jean-Christian Denis
|
||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||
*/
|
||||
if (!defined('DC_RC_PATH')) {
|
||||
return;
|
||||
}
|
||||
declare(strict_types=1);
|
||||
|
||||
dcCore::app()->addBehavior('initWidgets', ['adminArlequin','initWidgets']);
|
||||
namespace Dotclear\Plugin\arlequin;
|
||||
|
||||
class adminArlequin
|
||||
use dcCore;
|
||||
use dcModuleDefine;
|
||||
use Dotclear\Helper\Html\Html;
|
||||
use Dotclear\Helper\Network\Http;
|
||||
use Dotclear\Plugin\widgets\WidgetsStack;
|
||||
use Dotclear\Plugin\widgets\WidgetsElement;
|
||||
|
||||
class Widgets
|
||||
{
|
||||
public static $initialized = false;
|
||||
|
||||
public static function initWidgets($w)
|
||||
public static function initWidgets(WidgetsStack $w): void
|
||||
{
|
||||
$w->create(
|
||||
'arlequin',
|
||||
__('Arlequin'),
|
||||
['publicArlequinInterface','arlequinWidget'],
|
||||
My::name(),
|
||||
[self::class,'parseWidget'],
|
||||
null,
|
||||
__('Theme switcher')
|
||||
)
|
||||
|
@ -36,31 +39,80 @@ class adminArlequin
|
|||
->addOffline();
|
||||
}
|
||||
|
||||
public static function getDefaults()
|
||||
public static function parseWidget(WidgetsElement $w): string
|
||||
{
|
||||
return [
|
||||
'e_html' => '<li><a href="%1$s%2$s%3$s">%4$s</a></li>',
|
||||
'a_html' => '<li><strong>%4$s</strong></li>',
|
||||
's_html' => '<ul>%2$s</ul>',
|
||||
];
|
||||
}
|
||||
|
||||
public static function loadSettings($settings)
|
||||
{
|
||||
self::$initialized = false;
|
||||
$mt_cfg = @unserialize($settings->arlequinMulti->get('mt_cfg'));
|
||||
$mt_exclude = $settings->arlequinMulti->get('mt_exclude');
|
||||
|
||||
// Paramètres corrompus ou inexistants
|
||||
if ($mt_cfg === false || $mt_exclude === null || !(isset($mt_cfg['e_html']) && isset($mt_cfg['a_html']) && isset($mt_cfg['s_html']))) {
|
||||
$mt_cfg = adminArlequin::getDefaults();
|
||||
$settings->addNamespace('arlequinMulti');
|
||||
$settings->arlequinMulti->put('mt_cfg', serialize($mt_cfg), 'string', 'Arlequin configuration');
|
||||
$settings->arlequinMulti->put('mt_exclude', 'customCSS', 'string', 'Excluded themes');
|
||||
self::$initialized = true;
|
||||
dcCore::app()->blog->triggerBlog();
|
||||
if ($w->offline || !$w->checkHomeOnly(dcCore::app()->url->type)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return [$mt_cfg,$mt_exclude];
|
||||
$model = json_decode((string) dcCore::app()->blog->settings->get(My::id())->get('model'), true);
|
||||
$names = self::getNames();
|
||||
if (!is_array($model) || empty($names)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
# Current page URL and the associated query string. Note : the URL for
|
||||
# the switcher ($s_url) is different to the URL for an item ($e_url)
|
||||
$s_url = $e_url = Http::getSelfURI();
|
||||
|
||||
# If theme setting is already present in URL, we will replace its value
|
||||
$replace = preg_match('/(\\?|&)theme\\=[^&]*/', $e_url);
|
||||
|
||||
# URI extension to send theme setting by query string
|
||||
if ($replace) {
|
||||
$ext = '';
|
||||
} elseif (strpos($e_url, '?') === false) {
|
||||
$ext = '?theme=';
|
||||
} else {
|
||||
$ext = (substr($e_url, -1) == '?' ? '' : '&') . 'theme=';
|
||||
}
|
||||
|
||||
$res = '';
|
||||
foreach ($names as $k => $v) {
|
||||
if ($k == dcCore::app()->public->theme) {
|
||||
$format = $model['a_html'];
|
||||
} else {
|
||||
$format = $model['e_html'];
|
||||
}
|
||||
|
||||
if ($replace) {
|
||||
$e_url = preg_replace(
|
||||
'/(\\?|&)(theme\\=)([^&]*)/',
|
||||
'$1${2}' . addcslashes($k, '$\\'),
|
||||
$e_url
|
||||
);
|
||||
$val = '';
|
||||
} else {
|
||||
$val = Html::escapeHTML(rawurlencode($k));
|
||||
}
|
||||
$res .= sprintf(
|
||||
$format,
|
||||
$e_url,
|
||||
$ext,
|
||||
$val,
|
||||
Html::escapeHTML($v['name']),
|
||||
Html::escapeHTML($v['desc']),
|
||||
Html::escapeHTML($k)
|
||||
);
|
||||
}
|
||||
|
||||
# Nothing to display
|
||||
if (!trim($res)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $w->renderDiv(
|
||||
(bool) $w->content_only,
|
||||
'arlequin ' . $w->class,
|
||||
'',
|
||||
($w->title ? $w->renderTitle(Html::escapeHTML($w->title)) : '') . sprintf($model['s_html'], $s_url, $res)
|
||||
);
|
||||
}
|
||||
|
||||
public static function getNames(): array
|
||||
{
|
||||
$exclude = explode(';', (string) dcCore::app()->blog->settings->get(My::id())->get('exclude'));
|
||||
|
||||
return array_diff_key(dcCore::app()->themes->getDefines(['state' => dcModuleDefine::STATE_ENABLED], true), array_flip($exclude));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue