use namespace
This commit is contained in:
parent
c9790f2702
commit
a487e89601
12 changed files with 1319 additions and 856 deletions
|
@ -10,7 +10,7 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
if (!defined('DC_RC_PATH') || is_null(dcCore::app()->auth)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ $this->registerModule(
|
||||||
[
|
[
|
||||||
'requires' => [['core', '2.24']],
|
'requires' => [['core', '2.24']],
|
||||||
'permissions' => dcCore::app()->auth->makePermissions([
|
'permissions' => dcCore::app()->auth->makePermissions([
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
initTemplator::PERMISSION_TEMPLATOR,
|
initTemplator::PERMISSION_TEMPLATOR,
|
||||||
]),
|
]),
|
||||||
'type' => 'plugin',
|
'type' => 'plugin',
|
||||||
|
|
190
src/Backend.php
190
src/Backend.php
|
@ -10,161 +10,71 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->auth->setPermissionType(initTemplator::PERMISSION_TEMPLATOR, __('manage templates'));
|
namespace Dotclear\Plugin\templator;
|
||||||
|
|
||||||
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
use dcAdmin;
|
||||||
__('Templates engine'),
|
use dcCore;
|
||||||
dcCore::app()->adminurl->get('admin.plugin.templator'),
|
use dcMenu;
|
||||||
urldecode(dcPage::getPF('templator/icon.png')),
|
use dcNsProcess;
|
||||||
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.templator')) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
|
use dcPage;
|
||||||
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
|
||||||
initTemplator::PERMISSION_TEMPLATOR,
|
|
||||||
]), dcCore::app()->blog->id)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
class Backend extends dcNsProcess
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
|
||||||
initTemplator::PERMISSION_TEMPLATOR,
|
|
||||||
]), dcCore::app()->blog->id)) {
|
|
||||||
dcCore::app()->addBehavior('adminPostHeaders', ['templatorBehaviors','adminPostHeaders']);
|
|
||||||
dcCore::app()->addBehavior('adminPostFormItems', ['templatorBehaviors','adminPostFormItems']);
|
|
||||||
dcCore::app()->addBehavior('adminPageHeaders', ['templatorBehaviors','adminPostHeaders']);
|
|
||||||
dcCore::app()->addBehavior('adminPageFormItems', ['templatorBehaviors','adminPostFormItems']);
|
|
||||||
|
|
||||||
dcCore::app()->addBehavior('adminAfterPostCreate', ['templatorBehaviors','adminBeforePostUpdate']);
|
|
||||||
dcCore::app()->addBehavior('adminBeforePostUpdate', ['templatorBehaviors','adminBeforePostUpdate']);
|
|
||||||
dcCore::app()->addBehavior('adminAfterPageCreate', ['templatorBehaviors','adminBeforePostUpdate']);
|
|
||||||
dcCore::app()->addBehavior('adminBeforePageUpdate', ['templatorBehaviors','adminBeforePostUpdate']);
|
|
||||||
|
|
||||||
dcCore::app()->addBehavior('adminPostsActions', ['templatorBehaviors','adminPostsActions']);
|
|
||||||
dcCore::app()->addBehavior('adminPagesActions', ['templatorBehaviors','adminPostsActions']);
|
|
||||||
|
|
||||||
dcCore::app()->addBehavior('adminFiltersListsV2', function (ArrayObject $sorts) {
|
|
||||||
$sorts['templator'] = [
|
|
||||||
__('Templates engine'),
|
|
||||||
[
|
|
||||||
__('Date') => 'post_upddt',
|
|
||||||
__('Title') => 'post_title',
|
|
||||||
__('Category') => 'cat_id',
|
|
||||||
],
|
|
||||||
'post_upddt',
|
|
||||||
'desc',
|
|
||||||
[__('Entries per page'), 30],
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class templatorBehaviors
|
|
||||||
{
|
{
|
||||||
public static function adminPostHeaders()
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
return dcPage::jsLoad(dcPage::getPF('templator/js/admin.js'));
|
static::$init == defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& !is_null(dcCore::app()->blog) && !is_null(dcCore::app()->auth)
|
||||||
|
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
|
My::PERMISSION_TEMPLATOR,
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
]), dcCore::app()->blog->id);
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function adminPostFormItems(ArrayObject $main_items, ArrayObject $sidebar_items, $post)
|
public static function process(): bool
|
||||||
{
|
{
|
||||||
$selected = '';
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
if ($post) {
|
|
||||||
$post_meta = dcCore::app()->meta->getMetadata(['meta_type' => 'template', 'post_id' => $post->post_id]);
|
|
||||||
$selected = $post_meta->isEmpty() ? '' : $post_meta->meta_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sidebar_items['options-box']['items']['templator'] = '<div id="templator">' .
|
// nullsafe
|
||||||
'<h5>' . __('Template') . '</h5>' .
|
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
|
||||||
'<p><label for="post_tpl">' . __('Select template:') . '</label>' .
|
return false;
|
||||||
form::combo('post_tpl', self::getTemplateCombo(), $selected) . '</p>' .
|
|
||||||
'</div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function adminBeforePostUpdate($cur, $post_id)
|
//backend sidebar menu icon
|
||||||
{
|
if ((dcCore::app()->menu[dcAdmin::MENU_PLUGINS] instanceof dcMenu)) {
|
||||||
$post_id = (int) $post_id;
|
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
||||||
|
My::name(),
|
||||||
if (isset($_POST['post_tpl'])) {
|
dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||||
dcCore::app()->meta->delPostMeta($post_id, 'template');
|
urldecode(dcPage::getPF(My::id() . '/icon.png')),
|
||||||
if (!empty($_POST['post_tpl'])) {
|
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
|
||||||
dcCore::app()->meta->setPostMeta($post_id, 'template', $_POST['post_tpl']);
|
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
}
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
}
|
My::PERMISSION_TEMPLATOR,
|
||||||
}
|
]), dcCore::app()->blog->id)
|
||||||
|
|
||||||
public static function adminPostsActions(dcPostsActions $pa)
|
|
||||||
{
|
|
||||||
$pa->addAction(
|
|
||||||
[
|
|
||||||
__('Appearance') => [
|
|
||||||
__('Select the template') => 'tpl',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['templatorBehaviors', 'adminPostsActionsCallback']
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function adminPostsActionsCallback(dcPostsActions $pa, ArrayObject $post)
|
dcCore::app()->addBehaviors([
|
||||||
{
|
'adminPostHeaders' => [BackendBehaviors::class,'adminPostHeaders'],
|
||||||
# No entry
|
'adminPostFormItems' => [BackendBehaviors::class,'adminPostFormItems'],
|
||||||
$posts_ids = $pa->getIDs();
|
'adminPageHeaders' => [BackendBehaviors::class,'adminPostHeaders'],
|
||||||
if (empty($posts_ids)) {
|
'adminPageFormItems' => [BackendBehaviors::class,'adminPostFormItems'],
|
||||||
throw new Exception(__('No entry selected'));
|
'adminAfterPostCreate' => [BackendBehaviors::class,'adminBeforePostUpdate'],
|
||||||
}
|
'adminBeforePostUpdate' => [BackendBehaviors::class,'adminBeforePostUpdate'],
|
||||||
|
'adminAfterPageCreate' => [BackendBehaviors::class,'adminBeforePostUpdate'],
|
||||||
|
'adminBeforePageUpdate' => [BackendBehaviors::class,'adminBeforePostUpdate'],
|
||||||
|
'adminPostsActions' => [BackendBehaviors::class,'adminPostsActions'],
|
||||||
|
'adminPagesActions' => [BackendBehaviors::class,'adminPostsActions'],
|
||||||
|
'adminFiltersListsV2' => [BackendBehaviors::class, 'adminFiltersListsV2'],
|
||||||
|
'initWidgets' => [Widgets::class, 'initWidgets'],
|
||||||
|
]);
|
||||||
|
|
||||||
if (isset($post['post_tpl'])) {
|
return true;
|
||||||
try {
|
|
||||||
foreach ($posts_ids as $post_id) {
|
|
||||||
dcCore::app()->meta->delPostMeta($post_id, 'template');
|
|
||||||
if (!empty($post['post_tpl'])) {
|
|
||||||
dcCore::app()->meta->setPostMeta($post_id, 'template', $post['post_tpl']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(__('Entries template updated.'));
|
|
||||||
$pa->redirect(true);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$pa->beginPage(
|
|
||||||
dcPage::breadcrumb([
|
|
||||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
|
||||||
$pa->getCallerTitle() => $pa->getRedirection(true),
|
|
||||||
__('Entry template') => '',
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<h2 class="page-title">' . __('Select template for the selection') . '</h2>' .
|
|
||||||
'<form action="' . $pa->getURI() . '" method="post">' .
|
|
||||||
$pa->getCheckboxes() .
|
|
||||||
'<p><label class="classic">' . __('Select template:') . '</label> ' .
|
|
||||||
form::combo('post_tpl', self::getTemplateCombo()) . '</p>' .
|
|
||||||
|
|
||||||
'<p>' .
|
|
||||||
$pa->getHiddenFields() .
|
|
||||||
dcCore::app()->formNonce() .
|
|
||||||
form::hidden(['action'], 'tpl') .
|
|
||||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
$pa->endPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function getTemplateCombo()
|
|
||||||
{
|
|
||||||
$tpl = [__('No specific template') => ''];
|
|
||||||
|
|
||||||
foreach (dcCore::app()->templator->tpl as $k => $v) {
|
|
||||||
if (!preg_match('/^category-(.+)$/', $k) && !preg_match('/^list-(.+)$/', $k)) {
|
|
||||||
$tpl[$k] = $k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tpl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
157
src/BackendBehaviors.php
Normal file
157
src/BackendBehaviors.php
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief templator, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Osku 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\templator;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcCore;
|
||||||
|
use dcPage;
|
||||||
|
use dcPostsActions;
|
||||||
|
use Dotclear\Database\Cursor;
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
use form;
|
||||||
|
|
||||||
|
class BackendBehaviors
|
||||||
|
{
|
||||||
|
public static function adminPostHeaders(): string
|
||||||
|
{
|
||||||
|
return dcPage::jsModuleLoad(My::id() . '/js/admin.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function adminPostFormItems(ArrayObject $main_items, ArrayObject $sidebar_items, ?MetaRecord $post): void
|
||||||
|
{
|
||||||
|
$selected = '';
|
||||||
|
|
||||||
|
if (!is_null($post)) {
|
||||||
|
$post_meta = dcCore::app()->meta->getMetadata(['meta_type' => 'template', 'post_id' => $post->f('post_id')]);
|
||||||
|
$selected = $post_meta->isEmpty() ? '' : $post_meta->f('meta_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sidebar_items['options-box']['items']['templator'] = '<div id="templator">' .
|
||||||
|
'<h5>' . __('Template') . '</h5>' .
|
||||||
|
'<p><label for="post_tpl">' . __('Select template:') . '</label>' .
|
||||||
|
form::combo('post_tpl', self::getTemplateCombo(), $selected) . '</p>' .
|
||||||
|
'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function adminBeforePostUpdate(Cursor $cur, string|int $post_id): void
|
||||||
|
{
|
||||||
|
$post_id = (int) $post_id;
|
||||||
|
|
||||||
|
if (isset($_POST['post_tpl'])) {
|
||||||
|
dcCore::app()->meta->delPostMeta($post_id, 'template');
|
||||||
|
if (!empty($_POST['post_tpl'])) {
|
||||||
|
dcCore::app()->meta->setPostMeta($post_id, 'template', $_POST['post_tpl']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function adminPostsActions(dcPostsActions $pa): void
|
||||||
|
{
|
||||||
|
$pa->addAction(
|
||||||
|
[
|
||||||
|
__('Appearance') => [
|
||||||
|
__('Select the template') => 'tpl',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['templatorBehaviors', 'adminPostsActionsCallback']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function adminPostsActionsCallback(dcPostsActions $pa, ArrayObject $post): void
|
||||||
|
{
|
||||||
|
# No entry
|
||||||
|
$posts_ids = $pa->getIDs();
|
||||||
|
if (empty($posts_ids)) {
|
||||||
|
$pa->error(new Exception(__('No entry selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($post['post_tpl']) && is_string($post['post_tpl'])) {
|
||||||
|
try {
|
||||||
|
foreach ($posts_ids as $post_id) {
|
||||||
|
dcCore::app()->meta->delPostMeta($post_id, 'template');
|
||||||
|
if (!empty($post['post_tpl'])) {
|
||||||
|
dcCore::app()->meta->setPostMeta($post_id, 'template', $post['post_tpl']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::addSuccessNotice(__('Entries template updated.'));
|
||||||
|
$pa->redirect(true);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pa->beginPage(
|
||||||
|
dcPage::breadcrumb([
|
||||||
|
Html::escapeHTML((string) dcCore::app()->blog?->name) => '',
|
||||||
|
$pa->getCallerTitle() => $pa->getRedirection(true),
|
||||||
|
__('Entry template') => '',
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
echo
|
||||||
|
'<h2 class="page-title">' . __('Select template for the selection') . '</h2>' .
|
||||||
|
'<form action="' . $pa->getURI() . '" method="post">' .
|
||||||
|
$pa->getCheckboxes() .
|
||||||
|
'<p><label class="classic">' . __('Select template:') . '</label> ' .
|
||||||
|
form::combo('post_tpl', self::getTemplateCombo()) . '</p>' .
|
||||||
|
|
||||||
|
'<p>' .
|
||||||
|
$pa->getHiddenFields() .
|
||||||
|
dcCore::app()->formNonce() .
|
||||||
|
form::hidden(['action'], 'tpl') .
|
||||||
|
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
||||||
|
'</form>';
|
||||||
|
|
||||||
|
$pa->endPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function adminFiltersListsV2(ArrayObject $sorts): void
|
||||||
|
{
|
||||||
|
$sorts['templator'] = [
|
||||||
|
__('Templates engine'),
|
||||||
|
[
|
||||||
|
__('Date') => 'post_upddt',
|
||||||
|
__('Title') => 'post_title',
|
||||||
|
__('Category') => 'cat_id',
|
||||||
|
],
|
||||||
|
'post_upddt',
|
||||||
|
'desc',
|
||||||
|
[__('Entries per page'), 30],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
private static function getTemplateCombo(): array
|
||||||
|
{
|
||||||
|
$tpl = [__('No specific template') => ''];
|
||||||
|
|
||||||
|
$tpls = Templator::instance()->getTpl();
|
||||||
|
foreach ($tpls as $k => $v) {
|
||||||
|
if (!preg_match('/^category-(.+)$/', $k) && !preg_match('/^list-(.+)$/', $k)) {
|
||||||
|
$tpl[$k] = $k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tpl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,33 +10,69 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), dcCore::app()->templator->path);
|
namespace Dotclear\Plugin\templator;
|
||||||
dcCore::app()->addBehavior('urlHandlerBeforeGetData', ['publicTemplatorBehaviors','BeforeGetData']);
|
|
||||||
|
|
||||||
class publicTemplatorBehaviors
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frontend prepend.
|
||||||
|
*/
|
||||||
|
class Frontend extends dcNsProcess
|
||||||
{
|
{
|
||||||
public static function BeforeGetData($_)
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
if (array_key_exists(dcCore::app()->url->type, dcCore::app()->getPostTypes()) || dcCore::app()->url->type == 'pages') {
|
static::$init = My::phpCompliant();
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dcCore::app()->tpl->setPath(
|
||||||
|
dcCore::app()->tpl->getPath(),
|
||||||
|
Templator::instance()->getPath()
|
||||||
|
);
|
||||||
|
|
||||||
|
dcCore::app()->addBehaviors([
|
||||||
|
'urlHandlerBeforeGetData' => function ($_): void {
|
||||||
|
if (is_null(dcCore::app()->ctx)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dcCore::app()->ctx->__get('posts') instanceof MetaRecord)
|
||||||
|
&& (array_key_exists(dcCore::app()->url->type, dcCore::app()->getPostTypes()) || dcCore::app()->url->type == 'pages')) {
|
||||||
$params = [];
|
$params = [];
|
||||||
$params['meta_type'] = 'template';
|
$params['meta_type'] = 'template';
|
||||||
$params['post_id'] = dcCore::app()->ctx->posts->post_id;
|
$params['post_id'] = dcCore::app()->ctx->__get('posts')->f('post_id');
|
||||||
$post_meta = dcCore::app()->meta->getMetadata($params);
|
$post_meta = dcCore::app()->meta->getMetadata($params);
|
||||||
|
|
||||||
if (!$post_meta->isEmpty() && dcCore::app()->tpl->getFilePath($post_meta->meta_id)) {
|
if (!$post_meta->isEmpty() && is_string($post_meta->f('meta_id')) && dcCore::app()->tpl->getFilePath($post_meta->f('meta_id'))) {
|
||||||
dcCore::app()->ctx->current_tpl = $post_meta->meta_id;
|
dcCore::app()->ctx->__set('current_tpl', $post_meta->f('meta_id'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dcCore::app()->ctx->current_tpl == 'category.html' && preg_match('/^[0-9]{1,}/', dcCore::app()->ctx->categories->cat_id, $cat_id)) {
|
if (dcCore::app()->ctx->__get('current_tpl') == 'category.html'
|
||||||
|
&& (dcCore::app()->ctx->__get('categories') instanceof MetaRecord)
|
||||||
|
&& is_string(dcCore::app()->ctx->__get('categories')->f('cat_id'))
|
||||||
|
&& preg_match('/^[0-9]{1,}/', dcCore::app()->ctx->__get('categories')->f('cat_id'), $cat_id)
|
||||||
|
) {
|
||||||
$tpl = 'category-' . $cat_id[0] . '.html';
|
$tpl = 'category-' . $cat_id[0] . '.html';
|
||||||
if (dcCore::app()->tpl->getFilePath($tpl)) {
|
if (dcCore::app()->tpl->getFilePath($tpl)) {
|
||||||
dcCore::app()->ctx->current_tpl = $tpl;
|
dcCore::app()->ctx->__set('current_tpl', $tpl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
'initWidgets' => [Widgets::class, 'initWidgets'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
290
src/Manage.php
290
src/Manage.php
|
@ -10,157 +10,156 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::check(dcCore::app()->auth->makePermissions([
|
namespace Dotclear\Plugin\templator;
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
|
||||||
initTemplator::PERMISSION_TEMPLATOR,
|
|
||||||
]));
|
|
||||||
|
|
||||||
$part = $_REQUEST['part'] ?? '';
|
use adminGenericFilterV2;
|
||||||
|
use adminPostList;
|
||||||
|
use dcAdminFilters;
|
||||||
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use dcPage;
|
||||||
|
use dcPager;
|
||||||
|
use Dotclear\Helper\File\Files;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
### grab info ###
|
use form;
|
||||||
|
|
||||||
if (in_array($part, ['files', 'delete'])) {
|
class Manage extends dcNsProcess
|
||||||
//Extend dcMedia to change settings to allow .html vs media_exclusion
|
{
|
||||||
$media = new templatorMedia();
|
public static function init(): bool
|
||||||
$media->chdir(dcCore::app()->templator->template_dir_name);
|
{
|
||||||
// For users with only templator permission, we use sudo.
|
static::$init == defined('DC_CONTEXT_ADMIN')
|
||||||
dcCore::app()->auth->sudo([$media,'getDir']);
|
&& My::phpCompliant()
|
||||||
$dir = $media->dir;
|
&& !is_null(dcCore::app()->auth)
|
||||||
$items = array_values($dir['files']);
|
&& !is_null(dcCore::app()->blog)
|
||||||
}
|
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
My::PERMISSION_TEMPLATOR,
|
||||||
|
]), dcCore::app()->blog->id);
|
||||||
|
|
||||||
if (in_array($part, ['new', 'copycat'])) {
|
return static::$init;
|
||||||
$has_categories = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
$categories = dcCore::app()->blog->getCategories(['post_type' => 'post']);
|
|
||||||
|
|
||||||
$categories_combo = [];
|
|
||||||
$l = $categories->level;
|
|
||||||
$full_name = [$categories->cat_title];
|
|
||||||
|
|
||||||
while ($categories->fetch()) {
|
|
||||||
if ($categories->level < $l) {
|
|
||||||
$full_name = [];
|
|
||||||
} elseif ($categories->level == $l) {
|
|
||||||
array_pop($full_name);
|
|
||||||
}
|
|
||||||
$full_name[] = html::escapeHTML($categories->cat_title);
|
|
||||||
|
|
||||||
$categories_combo[implode(' › ', $full_name)] = $categories->cat_id;
|
|
||||||
|
|
||||||
$l = $categories->level;
|
|
||||||
}
|
|
||||||
$has_categories = !$categories->isEmpty();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$combo_source = [
|
public static function process(): bool
|
||||||
__('Empty template') => 'empty',
|
{
|
||||||
'post.html' => 'post',
|
if (!static::$init) {
|
||||||
];
|
return false;
|
||||||
|
|
||||||
if (dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcPages::PERMISSION_PAGES]), dcCore::app()->blog->id) && dcCore::app()->plugins->moduleExists('pages')) {
|
|
||||||
$combo_source['page.html'] = 'page';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($has_categories) {
|
// nullsafe
|
||||||
$combo_source['category.html'] = 'category';
|
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
### Action ###
|
// instances
|
||||||
|
$t = Templator::instance();
|
||||||
|
$v = ManageVars::instance();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Duplicate dc template
|
* Duplicate dc template
|
||||||
*/
|
*/
|
||||||
if ('new' == $part && !empty($_POST['filesource'])) {
|
if ('new' == $v->part && !empty($_POST['filesource'])) {
|
||||||
try {
|
try {
|
||||||
if ('category' == $_POST['filesource']) {
|
if ('category' == $_POST['filesource']) {
|
||||||
$name = 'category-' . $_POST['filecat'] . '.html';
|
$name = 'category-' . $_POST['filecat'] . '.html';
|
||||||
} elseif (!empty($_POST['filename'])) {
|
} elseif (!empty($_POST['filename'])) {
|
||||||
$name = files::tidyFileName($_POST['filename']) . '.html';
|
$name = Files::tidyFileName($_POST['filename']) . '.html';
|
||||||
} else {
|
} else {
|
||||||
throw new Exception(__('Filename is empty.'));
|
throw new Exception(__('Filename is empty.'));
|
||||||
}
|
}
|
||||||
dcCore::app()->templator->initializeTpl($name, $_POST['filesource']);
|
$t->initializeTpl($name, $_POST['filesource']);
|
||||||
|
|
||||||
if (!dcCore::app()->error->flag()) {
|
if (!dcCore::app()->error->flag()) {
|
||||||
dcAdminNotices::addSuccessNotice(__('The new template has been successfully created.'));
|
dcPage::addSuccessNotice(__('The new template has been successfully created.'));
|
||||||
dcCore::app()->adminurl->redirect('admin.plugin.templator');
|
dcCore::app()->adminurl->redirect('admin.plugin.templator');
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy tempaltor template
|
* Copy tempaltor template
|
||||||
*/
|
*/
|
||||||
if ('copy' == $part && !empty($_POST['filename'])) {
|
if ('copy' == $v->part && !empty($_POST['filename'])) {
|
||||||
try {
|
try {
|
||||||
dcCore::app()->templator->copypasteTpl(
|
$t->copypasteTpl(
|
||||||
rawurldecode($_POST['filename']) . '.html',
|
rawurldecode($_POST['filename']) . '.html',
|
||||||
rawurldecode($_POST['file'])
|
rawurldecode($_POST['file'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!dcCore::app()->error->flag()) {
|
if (!dcCore::app()->error->flag()) {
|
||||||
dcAdminNotices::addSuccessNotice(__('The template has been successfully copied.'));
|
dcPage::addSuccessNotice(__('The template has been successfully copied.'));
|
||||||
dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
|
dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy templator category template
|
* Copy templator category template
|
||||||
*/
|
*/
|
||||||
if ('copycat' == $part && !empty($_POST['filecat'])) {
|
if ('copycat' == $v->part && !empty($_POST['filecat'])) {
|
||||||
try {
|
try {
|
||||||
dcCore::app()->templator->copypasteTpl(
|
$t->copypasteTpl(
|
||||||
'category-' . rawurldecode($_POST['filecat']) . '.html',
|
'category-' . rawurldecode($_POST['filecat']) . '.html',
|
||||||
rawurldecode($_POST['file'])
|
rawurldecode($_POST['file'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!dcCore::app()->error->flag()) {
|
if (!dcCore::app()->error->flag()) {
|
||||||
dcAdminNotices::addSuccessNotice(__('The template has been successfully copied.'));
|
dcPage::addSuccessNotice(__('The template has been successfully copied.'));
|
||||||
dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
|
dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete tempaltor template
|
* Delete tempaltor template
|
||||||
*/
|
*/
|
||||||
if ('delete' == $part && !empty($_POST['file'])) {
|
if ('delete' == $v->part && !empty($_POST['file'])) {
|
||||||
try {
|
try {
|
||||||
$file = rawurldecode($_POST['file']);
|
$file = rawurldecode($_POST['file']);
|
||||||
$media->removeItem($file);
|
$v->media->removeItem($file);
|
||||||
dcCore::app()->meta->delMeta($file, 'template');
|
dcCore::app()->meta->delMeta($file, 'template');
|
||||||
|
|
||||||
if (!dcCore::app()->error->flag()) {
|
if (!dcCore::app()->error->flag()) {
|
||||||
dcAdminNotices::addSuccessNotice(__('The template has been successfully removed.'));
|
dcPage::addSuccessNotice(__('The template has been successfully removed.'));
|
||||||
dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
|
dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
### Display ###
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl) || is_null(dcCore::app()->auth->user_prefs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// instances
|
||||||
|
$t = Templator::instance();
|
||||||
|
$v = ManageVars::instance();
|
||||||
|
|
||||||
|
/*
|
||||||
* Check
|
* Check
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!dcCore::app()->templator->canUseRessources(true)) {
|
if (!$t->canUseRessources(true)) {
|
||||||
dcCore::app()->error->add(__('The plugin is unusable with your configuration. You have to change file permissions.'));
|
dcCore::app()->error->add(__('The plugin is unusable with your configuration. You have to change file permissions.'));
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
'<html><head><title>' . __('Templator') . '</title>' .
|
||||||
|
@ -175,7 +174,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
/*
|
/*
|
||||||
* Duplicate dotclear template
|
* Duplicate dotclear template
|
||||||
*/
|
*/
|
||||||
} elseif ('new' == $part) {
|
} elseif ('new' == $v->part) {
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
'<html><head><title>' . __('Templator') . '</title>' .
|
||||||
'</head><body>' .
|
'</head><body>' .
|
||||||
|
@ -189,15 +188,15 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'new']) . '" method="post" id="add-template">' .
|
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'new']) . '" method="post" id="add-template">' .
|
||||||
'<h3>' . __('New template') . '</h3>' .
|
'<h3>' . __('New template') . '</h3>' .
|
||||||
'<p><label for="filesource" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Template source:') . '</label> ' .
|
'<p><label for="filesource" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Template source:') . '</label> ' .
|
||||||
form::combo('filesource', $combo_source) . '</p>' .
|
form::combo('filesource', $v->sources) . '</p>' .
|
||||||
'<p><label for="filename" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Filename:') . '</label> ' .
|
'<p><label for="filename" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Filename:') . '</label> ' .
|
||||||
form::field('filename', 25, 255) . '</p>' .
|
form::field('filename', 25, 255) . '</p>' .
|
||||||
'<p class="form-note">' . __('Extension .html is automatically added to filename.') . '</p>';
|
'<p class="form-note">' . __('Extension .html is automatically added to filename.') . '</p>';
|
||||||
|
|
||||||
if ($has_categories) {
|
if ($v->has_categories) {
|
||||||
echo
|
echo
|
||||||
'<p><label for="filecat" class="required"><abbr title="' . __('Required field') . '">*</abbr>' . __('Category:') . '</label> ' .
|
'<p><label for="filecat" class="required"><abbr title="' . __('Required field') . '">*</abbr>' . __('Category:') . '</label> ' .
|
||||||
form::combo('filecat', $categories_combo, '') . '</p>' .
|
form::combo('filecat', $v->categories, '') . '</p>' .
|
||||||
'<p class="form-note">' . __('Required only for category template.') . '</p>';
|
'<p class="form-note">' . __('Required only for category template.') . '</p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +209,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
/*
|
/*
|
||||||
* Copy templator template
|
* Copy templator template
|
||||||
*/
|
*/
|
||||||
} elseif ('copy' == $part && !empty($_REQUEST['file'])) {
|
} elseif ('copy' == $v->part && !empty($_REQUEST['file'])) {
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
'<html><head><title>' . __('Templator') . '</title>' .
|
||||||
'</head><body>' .
|
'</head><body>' .
|
||||||
|
@ -224,29 +223,29 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'copy']) . '" method="post">' .
|
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'copy']) . '" method="post">' .
|
||||||
'<h3>' . __('Copy available template') . '</h3>' .
|
'<h3>' . __('Copy available template') . '</h3>' .
|
||||||
'<p><label for="filename" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('New filename:') . '</label> ' .
|
'<p><label for="filename" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('New filename:') . '</label> ' .
|
||||||
form::field('filename', 25, 255) . '<code>' . html::escapeHTML('.html') . '</code></p> ' .
|
form::field('filename', 25, 255) . '<code>' . Html::escapeHTML('.html') . '</code></p> ' .
|
||||||
'<p class="form-note">' . sprintf(
|
'<p class="form-note">' . sprintf(
|
||||||
__('To copy the template <strong>%s</strong>, you need to fill a new filename.'),
|
__('To copy the template <strong>%s</strong>, you need to fill a new filename.'),
|
||||||
html::escapeHTML($_REQUEST['file'])
|
Html::escapeHTML($_REQUEST['file'])
|
||||||
) . '</p>' .
|
) . '</p>' .
|
||||||
'<p>' .
|
'<p>' .
|
||||||
'<input type="submit" name="submit" value="' . __('Copy') . '" /> ' .
|
'<input type="submit" name="submit" value="' . __('Copy') . '" /> ' .
|
||||||
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
||||||
dcCore::app()->formNonce() .
|
dcCore::app()->formNonce() .
|
||||||
form::hidden('file', html::escapeHTML($_REQUEST['file'])) . '</p>' .
|
form::hidden('file', Html::escapeHTML($_REQUEST['file'])) . '</p>' .
|
||||||
'</form>';
|
'</form>';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy templator category template
|
* Copy templator category template
|
||||||
*/
|
*/
|
||||||
} elseif ('copycat' == $part && !empty($_REQUEST['file'])) {
|
} elseif ('copycat' == $v->part && !empty($_REQUEST['file'])) {
|
||||||
$category_id = (int) str_replace(['category-','.html'], '', $_REQUEST['file']);
|
$category_id = (int) str_replace(['category-','.html'], '', $_REQUEST['file']);
|
||||||
$cat_parents = dcCore::app()->blog->getCategoryParents($category_id);
|
$cat_parents = dcCore::app()->blog->getCategoryParents($category_id);
|
||||||
$full_name = '';
|
$full_name = '';
|
||||||
while ($cat_parents->fetch()) {
|
while ($cat_parents->fetch()) {
|
||||||
$full_name = $cat_parents->cat_title . ' › ';
|
$full_name = $cat_parents->f('cat_title') . ' › ';
|
||||||
};
|
};
|
||||||
$name = $full_name . dcCore::app()->blog->getCategory($category_id)->cat_title;
|
$name = $full_name . dcCore::app()->blog->getCategory($category_id)->f('cat_title');
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
'<html><head><title>' . __('Templator') . '</title>' .
|
||||||
|
@ -261,22 +260,22 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'copycat']) . '" method="post">' .
|
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'copycat']) . '" method="post">' .
|
||||||
'<h3>' . __('Copy available template') . '</h3>' .
|
'<h3>' . __('Copy available template') . '</h3>' .
|
||||||
'<p><label for="filecat" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Target category:') . '</label> ' .
|
'<p><label for="filecat" class="required"><abbr title="' . __('Required field') . '">*</abbr> ' . __('Target category:') . '</label> ' .
|
||||||
form::combo('filecat', $categories_combo, '') . '</p>' .
|
form::combo('filecat', $v->categories, '') . '</p>' .
|
||||||
'<p class="form-note">' . sprintf(
|
'<p class="form-note">' . sprintf(
|
||||||
__('To copy the template <strong>%s</strong> (%s), you need to choose a category.'),
|
__('To copy the template <strong>%s</strong> (%s), you need to choose a category.'),
|
||||||
html::escapeHTML($_GET['file']),
|
Html::escapeHTML($_GET['file']),
|
||||||
$name
|
$name
|
||||||
) . '</p>' .
|
) . '</p>' .
|
||||||
'<input type="submit" name="submit" value="' . __('Copy') . '" /> ' .
|
'<input type="submit" name="submit" value="' . __('Copy') . '" /> ' .
|
||||||
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
||||||
dcCore::app()->formNonce() .
|
dcCore::app()->formNonce() .
|
||||||
form::hidden('file', html::escapeHTML($_REQUEST['file'])) . '</p>' .
|
form::hidden('file', Html::escapeHTML($_REQUEST['file'])) . '</p>' .
|
||||||
'</form>';
|
'</form>';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete templator template
|
* Delete templator template
|
||||||
*/
|
*/
|
||||||
} elseif ('delete' == $part && !empty($_REQUEST['file'])) {
|
} elseif ('delete' == $v->part && !empty($_REQUEST['file'])) {
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
'<html><head><title>' . __('Templator') . '</title>' .
|
||||||
'</head><body>' .
|
'</head><body>' .
|
||||||
|
@ -291,18 +290,18 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<h3>' . __('Delete available template') . '</h3>' .
|
'<h3>' . __('Delete available template') . '</h3>' .
|
||||||
'<p>' . sprintf(
|
'<p>' . sprintf(
|
||||||
__('Are you sure you want to remove the template "%s"?'),
|
__('Are you sure you want to remove the template "%s"?'),
|
||||||
html::escapeHTML($_GET['file'])
|
Html::escapeHTML($_GET['file'])
|
||||||
) . '</p>' .
|
) . '</p>' .
|
||||||
'<p><input type="submit" class="delete" value="' . __('Delete') . '" /> ' .
|
'<p><input type="submit" class="delete" value="' . __('Delete') . '" /> ' .
|
||||||
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
||||||
dcCore::app()->formNonce() .
|
dcCore::app()->formNonce() .
|
||||||
form::hidden('file', html::escapeHTML($_GET['file'])) . '</p>' .
|
form::hidden('file', Html::escapeHTML($_GET['file'])) . '</p>' .
|
||||||
'</form>';
|
'</form>';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List templator templates
|
* List templator templates
|
||||||
*/
|
*/
|
||||||
} elseif ('files' == $part) {
|
} elseif ('files' == $v->part) {
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
'<html><head><title>' . __('Templator') . '</title>' .
|
||||||
'</head><body>' .
|
'</head><body>' .
|
||||||
|
@ -314,21 +313,23 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
dcPage::notices() .
|
dcPage::notices() .
|
||||||
'<h3>' . __('Available templates') . '</h3>';
|
'<h3>' . __('Available templates') . '</h3>';
|
||||||
|
|
||||||
if (count($items) == 0) {
|
if (count($v->items) == 0) {
|
||||||
echo '<p><strong>' . __('No template.') . '</strong></p>';
|
echo '<p><strong>' . __('No template.') . '</strong></p>';
|
||||||
} else {
|
} else {
|
||||||
// reuse "used templatro template" filter settings
|
// reuse "used templatro template" filter settings
|
||||||
$filter = new adminGenericFilterV2('templator');
|
$filter = new adminGenericFilterV2('templator');
|
||||||
$filter->add(dcAdminFilters::getPageFilter());
|
$filter->add(dcAdminFilters::getPageFilter());
|
||||||
|
$page = is_numeric($filter->value('page')) ? (int) $filter->value('page') : 1;
|
||||||
|
$nb = is_numeric($filter->value('nb')) ? (int) $filter->value('nb') : 1;
|
||||||
|
|
||||||
$pager = new dcPager($filter->page, count($items), $filter->nb, 10);
|
$pager = new dcPager($page, count($v->items), $nb, 10);
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<div class="media-list">' .
|
'<div class="media-list">' .
|
||||||
$pager->getLinks();
|
$pager->getLinks();
|
||||||
|
|
||||||
for ($i = $pager->index_start, $j = 0; $i <= $pager->index_end; $i++, $j++) {
|
for ($i = $pager->index_start, $j = 0; $i <= $pager->index_end; $i++, $j++) {
|
||||||
echo templatorPager::templatorItemLine($items[$i], $j);
|
echo Pager::line($v->items[$i], $j);
|
||||||
}
|
}
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
@ -339,7 +340,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
/*
|
/*
|
||||||
* List Used templator template
|
* List Used templator template
|
||||||
*/
|
*/
|
||||||
} elseif ('used' == $part) {
|
} elseif ('used' == $v->part) {
|
||||||
$tags = dcCore::app()->meta->getMetadata(['meta_type' => 'template']);
|
$tags = dcCore::app()->meta->getMetadata(['meta_type' => 'template']);
|
||||||
$tags = dcCore::app()->meta->computeMetaStats($tags);
|
$tags = dcCore::app()->meta->computeMetaStats($tags);
|
||||||
$tags->sort('meta_id_lower', 'asc');
|
$tags->sort('meta_id_lower', 'asc');
|
||||||
|
@ -349,7 +350,9 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
$col = 0;
|
$col = 0;
|
||||||
|
|
||||||
while ($tags->fetch()) {
|
while ($tags->fetch()) {
|
||||||
$letter = mb_strtoupper(mb_substr($tags->meta_id, 0, 1));
|
$meta_id = is_string($tags->f('meta_id')) ? $tags->f('meta_id') : '';
|
||||||
|
$count = is_numeric($tags->f('count')) ? (int) $tags->f('count') : 1;
|
||||||
|
$letter = mb_strtoupper(mb_substr($meta_id, 0, 1));
|
||||||
|
|
||||||
if ($last_letter != $letter) {
|
if ($last_letter != $letter) {
|
||||||
if ($tags->index() >= round($tags->count() / 2)) {
|
if ($tags->index() >= round($tags->count() / 2)) {
|
||||||
|
@ -359,7 +362,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
|
$img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
|
||||||
if (array_key_exists($tags->meta_id, dcCore::app()->templator->tpl)) {
|
if (array_key_exists($meta_id, $t->getTpl())) {
|
||||||
$img_status = sprintf($img, __('available template'), 'check-on.png');
|
$img_status = sprintf($img, __('available template'), 'check-on.png');
|
||||||
} else {
|
} else {
|
||||||
$img_status = sprintf($img, __('missing template'), 'check-off.png');
|
$img_status = sprintf($img, __('missing template'), 'check-off.png');
|
||||||
|
@ -369,11 +372,11 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<td class="maximal"><a href="' .
|
'<td class="maximal"><a href="' .
|
||||||
dcCore::app()->adminurl->get('admin.plugin.templator', [
|
dcCore::app()->adminurl->get('admin.plugin.templator', [
|
||||||
'part' => 'posts',
|
'part' => 'posts',
|
||||||
'file' => $tags->meta_id,
|
'file' => $meta_id,
|
||||||
'redir' => dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']),
|
'redir' => dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']),
|
||||||
]) . '">' . $tags->meta_id . '</a> ' . $img_status . '</td>' .
|
]) . '">' . $meta_id . '</a> ' . $img_status . '</td>' .
|
||||||
'<td class="nowrap"><strong>' . $tags->count . '</strong> ' .
|
'<td class="nowrap"><strong>' . $count . '</strong> ' .
|
||||||
(($tags->count == 1) ? __('entry') : __('entries')) . '</td>' .
|
(($count == 1) ? __('entry') : __('entries')) . '</td>' .
|
||||||
'</tr>';
|
'</tr>';
|
||||||
|
|
||||||
$last_letter = $letter;
|
$last_letter = $letter;
|
||||||
|
@ -407,11 +410,14 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
/*
|
/*
|
||||||
* Edit emplator template
|
* Edit emplator template
|
||||||
*/
|
*/
|
||||||
} elseif ('edit' == $part && !empty($_REQUEST['file'])) {
|
} elseif ('edit' == $v->part && !empty($_REQUEST['file'])) {
|
||||||
|
$file = ['c' => '', 'w' => false, 'f' => ''];
|
||||||
|
$name = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
$name = rawurldecode($_REQUEST['file']);
|
$name = rawurldecode($_REQUEST['file']);
|
||||||
$file = dcCore::app()->templator->getSourceContent($name);
|
$file = $t->getSourceContent($name);
|
||||||
$name = $file['f'];
|
$name = $file['f'];
|
||||||
|
|
||||||
if (preg_match('/^category-(.+).html$/', $name, $cat_id)) {
|
if (preg_match('/^category-(.+).html$/', $name, $cat_id)) {
|
||||||
|
@ -419,32 +425,30 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
$full_name = '';
|
$full_name = '';
|
||||||
$cat_parents = dcCore::app()->blog->getCategoryParents((int) $cat_id[1]);
|
$cat_parents = dcCore::app()->blog->getCategoryParents((int) $cat_id[1]);
|
||||||
while ($cat_parents->fetch()) {
|
while ($cat_parents->fetch()) {
|
||||||
$full_name = $cat_parents->cat_title . ' › ';
|
$full_name = $cat_parents->f('cat_title') . ' › ';
|
||||||
};
|
};
|
||||||
$name .= '</strong> (' . $full_name . $category->cat_title . ')<strong>';
|
$name .= '</strong> (' . $full_name . $category->f('cat_title') . ')<strong>';
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$file = '';
|
$file['c'] = null;
|
||||||
|
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
# Write file
|
# Write file
|
||||||
if (!empty($_POST['write'])) {
|
if (!empty($_POST['write'])) {
|
||||||
$file['c'] = $_POST['file_content'];
|
$file['c'] = $_POST['file_content'] ?? null;
|
||||||
dcCore::app()->templator->writeTpl($file['f'], $file['c']);
|
$t->writeTpl($file['f'], $file['c']);
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
dcCore::app()->auth->user_prefs->addWorkspace('interface');
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>';
|
'<html><head><title>' . __('Templator') . '</title>';
|
||||||
|
|
||||||
if (dcCore::app()->auth->user_prefs->interface->colorsyntax) {
|
if (dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')) {
|
||||||
echo
|
echo
|
||||||
dcPage::jsJson('dotclear_colorsyntax', ['colorsyntax' => dcCore::app()->auth->user_prefs->interface->colorsyntax]);
|
dcPage::jsJson('dotclear_colorsyntax', ['colorsyntax' => dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')]);
|
||||||
}
|
}
|
||||||
echo
|
echo
|
||||||
dcPage::jsJson('theme_editor_msg', [
|
dcPage::jsJson('theme_editor_msg', [
|
||||||
|
@ -455,9 +459,10 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
]) .
|
]) .
|
||||||
dcPage::jsModuleLoad('themeEditor/js/script.js') .
|
dcPage::jsModuleLoad('themeEditor/js/script.js') .
|
||||||
dcPage::jsConfirmClose('file-form');
|
dcPage::jsConfirmClose('file-form');
|
||||||
if (dcCore::app()->auth->user_prefs->interface->colorsyntax) {
|
if (dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')) {
|
||||||
|
$ict = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme');
|
||||||
echo
|
echo
|
||||||
dcPage::jsLoadCodeMirror(dcCore::app()->auth->user_prefs->interface->colorsyntax_theme);
|
dcPage::jsLoadCodeMirror(is_string($ict) ? $ict : '');
|
||||||
}
|
}
|
||||||
echo
|
echo
|
||||||
dcPage::cssModuleLoad('themeEditor/style.css') .
|
dcPage::cssModuleLoad('themeEditor/style.css') .
|
||||||
|
@ -474,7 +479,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<form id="file-form" action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'edit', 'file' => $name]) . '" method="post">' .
|
'<form id="file-form" action="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'edit', 'file' => $name]) . '" method="post">' .
|
||||||
'<div><h3><label for="file_content">' . sprintf(__('Editing file %s'), '<strong>' . $name) . '</strong></label></h3>' .
|
'<div><h3><label for="file_content">' . sprintf(__('Editing file %s'), '<strong>' . $name) . '</strong></label></h3>' .
|
||||||
'<p>' . form::textarea('file_content', 72, 25, [
|
'<p>' . form::textarea('file_content', 72, 25, [
|
||||||
'default' => html::escapeHTML($file['c']),
|
'default' => Html::escapeHTML($file['c']),
|
||||||
'class' => 'maximal',
|
'class' => 'maximal',
|
||||||
'disabled' => !$file['w'],
|
'disabled' => !$file['w'],
|
||||||
]) . '</p>';
|
]) . '</p>';
|
||||||
|
@ -484,7 +489,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<p><input type="submit" name="write" value="' . __('Save') . '" accesskey="s" /> ' .
|
'<p><input type="submit" name="write" value="' . __('Save') . '" accesskey="s" /> ' .
|
||||||
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
'<a class="button" href="' . dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']) . '">' . __('Cancel') . '</a>' .
|
||||||
dcCore::app()->formNonce() .
|
dcCore::app()->formNonce() .
|
||||||
form::hidden(['file_id'], html::escapeHTML($file['f'])) .
|
form::hidden(['file_id'], Html::escapeHTML($file['f'])) .
|
||||||
'</p>';
|
'</p>';
|
||||||
} else {
|
} else {
|
||||||
echo '<p>' . __('This file is not writable. Please check your files permissions.') . '</p>';
|
echo '<p>' . __('This file is not writable. Please check your files permissions.') . '</p>';
|
||||||
|
@ -492,25 +497,26 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'</div></form>';
|
'</div></form>';
|
||||||
if (dcCore::app()->auth->user_prefs->interface->colorsyntax) {
|
if (dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')) {
|
||||||
|
$ict = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme');
|
||||||
echo
|
echo
|
||||||
dcPage::jsJson('theme_editor_mode', ['mode' => 'html']) .
|
dcPage::jsJson('theme_editor_mode', ['mode' => 'html']) .
|
||||||
dcPage::jsModuleLoad('themeEditor/js/mode.js') .
|
dcPage::jsModuleLoad('themeEditor/js/mode.js') .
|
||||||
dcPage::jsRunCodeMirror('editor', 'file_content', 'dotclear', dcCore::app()->auth->user_prefs->interface->colorsyntax_theme);
|
dcPage::jsRunCodeMirror('editor', 'file_content', 'dotclear', is_string($ict) ? $ict : '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Edit posts options linked to a template
|
* Edit posts options linked to a template
|
||||||
*/
|
*/
|
||||||
} elseif ('posts' == $part && (!empty($_REQUEST['file']) || $_REQUEST['file'] == '0')) {
|
} elseif ('posts' == $v->part && (!empty($_REQUEST['file']) || $_REQUEST['file'] == '0')) {
|
||||||
$file = $_REQUEST['file'];
|
$file = $_REQUEST['file'];
|
||||||
$redir = $_REQUEST['redir'] ?? dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']);
|
$redir = $_REQUEST['redir'] ?? dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']);
|
||||||
|
|
||||||
# Unselect the template
|
# Unselect the template
|
||||||
if (!empty($_POST['action']) && 'unselecttpl' == $_POST['action'] && dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
if (!empty($_POST['action']) && 'unselecttpl' == $_POST['action'] && dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
dcAuth::PERMISSION_PUBLISH,
|
dcCore::app()->auth::PERMISSION_PUBLISH,
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
]), dcCore::app()->blog->id)) {
|
]), dcCore::app()->blog->id)) {
|
||||||
try {
|
try {
|
||||||
dcCore::app()->meta->delMeta($file, 'template');
|
dcCore::app()->meta->delMeta($file, 'template');
|
||||||
|
@ -534,8 +540,12 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
# Get posts
|
# Get posts
|
||||||
try {
|
try {
|
||||||
$posts = dcCore::app()->meta->getPostsByMeta($params);
|
$posts = dcCore::app()->meta->getPostsByMeta($params);
|
||||||
$counter = dcCore::app()->meta->getPostsByMeta($params, true);
|
if (is_null($posts)) {
|
||||||
$post_list = new adminPostList($posts, $counter->f(0));
|
throw new Exception(__('Failed to get posts meta'));
|
||||||
|
}
|
||||||
|
$counter = dcCore::app()->meta->getPostsByMeta($params, true)?->f(0);
|
||||||
|
$counter = is_numeric($counter) ? (int) $counter : 0;
|
||||||
|
$post_list = new adminPostList($posts, $counter);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
|
@ -556,18 +566,20 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
'<h3>' . sprintf(__('Unselect template "%s"'), '<strong>' . $file . '</strong>') . '</h3>' .
|
'<h3>' . sprintf(__('Unselect template "%s"'), '<strong>' . $file . '</strong>') . '</h3>' .
|
||||||
'<p><a class ="back" href="' . $redir . '">' . __('Back') . '</a></p>';
|
'<p><a class ="back" href="' . $redir . '">' . __('Back') . '</a></p>';
|
||||||
|
|
||||||
if (!dcCore::app()->error->flag()) {
|
if (!dcCore::app()->error->flag() && isset($posts)) {
|
||||||
if ($posts->isEmpty() && !$filter->show()) {
|
if ($posts->isEmpty() && !$filter->show()) {
|
||||||
echo '<p>' . __('There is no entries') . '</p>';
|
echo '<p>' . __('There is no entries') . '</p>';
|
||||||
} else {
|
} else {
|
||||||
|
$page = is_numeric($filter->value('page')) ? (int) $filter->value('page') : 1;
|
||||||
|
$nb = is_numeric($filter->value('nb')) ? (int) $filter->value('nb') : 0;
|
||||||
$filter->display(
|
$filter->display(
|
||||||
'admin.plugin.templator',
|
'admin.plugin.templator',
|
||||||
form::hidden('p', 'templator') . form::hidden('part', 'posts') . form::hidden('file', $file)
|
form::hidden('p', 'templator') . form::hidden('part', 'posts') . form::hidden('file', $file)
|
||||||
);
|
);
|
||||||
# Show posts
|
# Show posts
|
||||||
$post_list->display(
|
$post_list->display(
|
||||||
$filter->page,
|
$page,
|
||||||
$filter->nb,
|
$nb,
|
||||||
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator') . '" method="post" id="form-entries">' .
|
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.templator') . '" method="post" id="form-entries">' .
|
||||||
|
|
||||||
'%s' .
|
'%s' .
|
||||||
|
@ -583,8 +595,7 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
dcCore::app()->formNonce() .
|
dcCore::app()->formNonce() .
|
||||||
'</div>' .
|
'</div>' .
|
||||||
'</form>',
|
'</form>',
|
||||||
$filter->show(),
|
$filter->show()
|
||||||
dcCore::app()->adminurl->get('admin.plugin.templator', $filter->values())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,10 +603,9 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
/*
|
/*
|
||||||
* Default page
|
* Default page
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
|
dcPage::openModule(My::name());
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Templator') . '</title>' .
|
|
||||||
'</head><body>' .
|
|
||||||
dcPage::breadcrumb([
|
dcPage::breadcrumb([
|
||||||
__('Plugins') => '',
|
__('Plugins') => '',
|
||||||
__('Templates engine') => '',
|
__('Templates engine') => '',
|
||||||
|
@ -623,8 +633,10 @@ if (!dcCore::app()->templator->canUseRessources(true)) {
|
||||||
__('New template')
|
__('New template')
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::helpBlock('templator');
|
||||||
|
|
||||||
|
dcPage::closeModule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dcPage::helpBlock('templator');
|
|
||||||
|
|
||||||
echo '</body></html>';
|
|
||||||
|
|
147
src/ManageVars.php
Normal file
147
src/ManageVars.php
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief templator, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Osku 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\templator;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Helper\File\File;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
use initPages;
|
||||||
|
|
||||||
|
class ManageVars
|
||||||
|
{
|
||||||
|
/** @var ManageVars $container Self instance */
|
||||||
|
private static $container;
|
||||||
|
|
||||||
|
/** @var string $name The requested manage part name*/
|
||||||
|
public readonly string $name;
|
||||||
|
|
||||||
|
/** @var string $part The requested manage part */
|
||||||
|
public readonly string $part;
|
||||||
|
|
||||||
|
/** @var Media $media The limited media instance */
|
||||||
|
public readonly Media $media;
|
||||||
|
|
||||||
|
/** @var array<int,File> $items The media items */
|
||||||
|
public readonly array $items;
|
||||||
|
|
||||||
|
/** @var array<string,int> $categories The blog categories list */
|
||||||
|
public readonly array $categories;
|
||||||
|
|
||||||
|
/** @var bool $has_categories Blog has categories */
|
||||||
|
public readonly bool $has_categories;
|
||||||
|
|
||||||
|
/** @var array<string,string> $sources The templates list */
|
||||||
|
public readonly array $sources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructo sets properties.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
// manage page
|
||||||
|
$name = $this->getPartName(($_REQUEST['part'] ?? ''));
|
||||||
|
$this->name = empty($name) ? __('Home') : $name;
|
||||||
|
$this->part = empty($name) ? '' : $_REQUEST['part'];
|
||||||
|
|
||||||
|
// Extend dcMedia to change settings to allow .html vs media_exclusion
|
||||||
|
$this->media = new Media();
|
||||||
|
$this->media->chdir(Templator::MY_TPL_DIR);
|
||||||
|
// For users with only templator permission, we use sudo.
|
||||||
|
dcCore::app()->auth?->sudo([$this->media,'getDir']);
|
||||||
|
$dir = $this->media->dir;
|
||||||
|
$this->items = array_values($dir['files']);
|
||||||
|
|
||||||
|
// categories
|
||||||
|
$categories_combo = [];
|
||||||
|
$has_categories = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$categories = dcCore::app()->blog?->getCategories(['post_type' => 'post']);
|
||||||
|
if (!is_null($categories)) {
|
||||||
|
$l = is_numeric($categories->f('level')) ? (int) $categories->f('level') : 1;
|
||||||
|
$full_name = [is_string($categories->f('cat_title')) ? $categories->f('cat_title') : ''];
|
||||||
|
|
||||||
|
while ($categories->fetch()) {
|
||||||
|
$id = is_numeric($categories->f('cat_id')) ? (int) $categories->f('cat_id') : 1;
|
||||||
|
$level = is_numeric($categories->f('level')) ? (int) $categories->f('level') : 1;
|
||||||
|
$title = is_string($categories->f('cat_title')) ? $categories->f('cat_title') : '';
|
||||||
|
|
||||||
|
if ($level < $l) {
|
||||||
|
$full_name = [];
|
||||||
|
} elseif ($level == $l) {
|
||||||
|
array_pop($full_name);
|
||||||
|
}
|
||||||
|
$full_name[] = Html::escapeHTML($title);
|
||||||
|
|
||||||
|
$categories_combo[implode(' › ', $full_name)] = $id;
|
||||||
|
|
||||||
|
$l = $level;
|
||||||
|
}
|
||||||
|
$has_categories = !$categories->isEmpty();
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
$this->categories = $categories_combo;
|
||||||
|
$this->has_categories = $has_categories;
|
||||||
|
|
||||||
|
// sources
|
||||||
|
$sources_combo = [
|
||||||
|
__('Empty template') => 'empty',
|
||||||
|
'post.html' => 'post',
|
||||||
|
];
|
||||||
|
|
||||||
|
if (dcCore::app()->plugins->moduleExists('pages')
|
||||||
|
&& dcCore::app()->auth?->check(dcCore::app()->auth->makePermissions([initPages::PERMISSION_PAGES]), dcCore::app()->blog?->id)
|
||||||
|
) {
|
||||||
|
$sources_combo['page.html'] = 'page';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($has_categories) {
|
||||||
|
$sources_combo['category.html'] = 'category';
|
||||||
|
}
|
||||||
|
$this->sources = $sources_combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get self instance.
|
||||||
|
*
|
||||||
|
* @return ManageVars Self instance
|
||||||
|
*/
|
||||||
|
public static function instance(): ManageVars
|
||||||
|
{
|
||||||
|
if (!(self::$container instanceof self)) {
|
||||||
|
self::$container = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$container;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getPartName(string $part): string
|
||||||
|
{
|
||||||
|
$parts = [
|
||||||
|
'new' => __('New template'),
|
||||||
|
'copy' => __('Copy available template'),
|
||||||
|
'copycat' => __('Copy available category template'),
|
||||||
|
'delete' => __('Delete available template'),
|
||||||
|
'files' => __('Available templates'),
|
||||||
|
'used' => __('Used templates'),
|
||||||
|
'edit' => __('Edit template'),
|
||||||
|
'posts' => __('Unselect template'),
|
||||||
|
];
|
||||||
|
|
||||||
|
return array_key_exists($part, $parts) ? $parts[$part] : '';
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,13 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
class templatorMedia extends dcMedia
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\templator;
|
||||||
|
|
||||||
|
use dcMedia;
|
||||||
|
|
||||||
|
class Media extends dcMedia
|
||||||
{
|
{
|
||||||
// limit to html files
|
// limit to html files
|
||||||
protected function isFileExclude(string $file): bool
|
protected function isFileExclude(string $file): bool
|
||||||
|
|
63
src/My.php
Normal file
63
src/My.php
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief templator, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Osku 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\templator;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module definitions.
|
||||||
|
*/
|
||||||
|
class My
|
||||||
|
{
|
||||||
|
/** @var string This module permission */
|
||||||
|
public const PERMISSION_TEMPLATOR = 'templator';
|
||||||
|
|
||||||
|
/** @var string This module required php version */
|
||||||
|
public const PHP_MIN = '8.1';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module id.
|
||||||
|
*/
|
||||||
|
public static function id(): string
|
||||||
|
{
|
||||||
|
return basename(dirname(__DIR__));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module name.
|
||||||
|
*/
|
||||||
|
public static function name(): string
|
||||||
|
{
|
||||||
|
$name = dcCore::app()->plugins->moduleInfo(self::id(), 'name');
|
||||||
|
|
||||||
|
return __(is_string($name) ? $name : self::id());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module path.
|
||||||
|
*/
|
||||||
|
public static function path(): string
|
||||||
|
{
|
||||||
|
return dirname(__DIR__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check this module PHP version compliant.
|
||||||
|
*/
|
||||||
|
public static function phpCompliant(): bool
|
||||||
|
{
|
||||||
|
return version_compare(phpversion(), self::PHP_MIN, '>=');
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,14 +10,24 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
class templatorPager
|
namespace Dotclear\Plugin\templator;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Helper\File\File;
|
||||||
|
use Dotclear\Helper\File\Files;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
class Pager
|
||||||
{
|
{
|
||||||
public static function templatorItemLine($f, $i)
|
public static function line(File $f, int $i): string
|
||||||
{
|
{
|
||||||
|
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
$p_url = dcCore::app()->admin->getPageURL();
|
$p_url = dcCore::app()->admin->getPageURL();
|
||||||
$fname = $f->basename;
|
$fname = $f->basename;
|
||||||
$count = '';
|
$count = '';
|
||||||
|
@ -36,9 +46,9 @@ class templatorPager
|
||||||
$full_name = '';
|
$full_name = '';
|
||||||
$cat_parents = dcCore::app()->blog->getCategoryParents($cat_id);
|
$cat_parents = dcCore::app()->blog->getCategoryParents($cat_id);
|
||||||
while ($cat_parents->fetch()) {
|
while ($cat_parents->fetch()) {
|
||||||
$full_name = $cat_parents->cat_title . ' › ';
|
$full_name = $cat_parents->f('cat_title') . ' › ';
|
||||||
};
|
};
|
||||||
$fname = '<strong>' . __('Category') . '</strong> : ' . $full_name . dcCore::app()->blog->getCategory($cat_id)->cat_title;
|
$fname = '<strong>' . __('Category') . '</strong> : ' . $full_name . $category->f('cat_title');
|
||||||
$params['cat_id'] = $cat_id;
|
$params['cat_id'] = $cat_id;
|
||||||
$params['post_type'] = '';
|
$params['post_type'] = '';
|
||||||
$icon = dcPage::getPF('templator/img/template-alt.png');
|
$icon = dcPage::getPF('templator/img/template-alt.png');
|
||||||
|
@ -66,18 +76,19 @@ class templatorPager
|
||||||
$params['post_type'] = '';
|
$params['post_type'] = '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$counter = dcCore::app()->meta->getPostsByMeta($params, true);
|
$counter = dcCore::app()->meta->getPostsByMeta($params, true)?->f(0);
|
||||||
|
$counter = is_numeric($counter) ? (int) $counter : 0;
|
||||||
$url = dcCore::app()->adminurl->get('admin.plugin.templator', [
|
$url = dcCore::app()->adminurl->get('admin.plugin.templator', [
|
||||||
'part' => 'posts',
|
'part' => 'posts',
|
||||||
'file' => $fname,
|
'file' => $fname,
|
||||||
'redir' => dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']),
|
'redir' => dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']),
|
||||||
]);
|
]);
|
||||||
if ($counter->f(0) == 0) {
|
if ($counter == 0) {
|
||||||
$count = __('No entry');
|
$count = __('No entry');
|
||||||
} elseif ($counter->f(0) == 1) {
|
} elseif ($counter == 1) {
|
||||||
$count = '<strong>' . $counter->f(0) . '</strong> <a href="' . $url . '">' . __('entry') . '</a>';
|
$count = '<strong>' . $counter . '</strong> <a href="' . $url . '">' . __('entry') . '</a>';
|
||||||
} else {
|
} else {
|
||||||
$count = '<strong>' . $counter->f(0) . '</strong> <a href="' . $url . '">' . __('entries') . '</a>';
|
$count = '<strong>' . $counter . '</strong> <a href="' . $url . '">' . __('entries') . '</a>';
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
@ -100,7 +111,7 @@ class templatorPager
|
||||||
$res .= '<li>' . $count . '</li>' .
|
$res .= '<li>' . $count . '</li>' .
|
||||||
'<li>' .
|
'<li>' .
|
||||||
$f->media_dtstr . ' - ' .
|
$f->media_dtstr . ' - ' .
|
||||||
files::size($f->size) .
|
Files::size($f->size) .
|
||||||
$details .
|
$details .
|
||||||
'</li>';
|
'</li>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,40 +10,33 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Clearbricks::lib()->autoload([
|
|
||||||
'dcTemplator' => __DIR__ . '/inc/class.templator.php',
|
|
||||||
'templatorMedia' => __DIR__ . '/inc/class.templator.media.php',
|
|
||||||
'templatorPager' => __DIR__ . '/inc/class.templator.pager.php',
|
|
||||||
]);
|
|
||||||
|
|
||||||
dcCore::app()->templator = new dcTemplator();
|
namespace Dotclear\Plugin\templator;
|
||||||
|
|
||||||
dcCore::app()->addBehavior('initWidgets', ['templatorWidgets', 'initWidgets']);
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
|
||||||
class templatorWidgets
|
class Prepend extends dcNsProcess
|
||||||
{
|
{
|
||||||
public static function initWidgets($w)
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
$w->create('templatorWidget', __('Templator › Rendering'), ['widgetTemplator', 'getDataTpl']);
|
static::$init = My::phpCompliant();
|
||||||
$tpl = [' .html' => ''];
|
|
||||||
foreach (dcCore::app()->templator->tpl as $k => $v) {
|
|
||||||
if (preg_match('/^widget-(.+)$/', $k)) {
|
|
||||||
$tpl = array_merge($tpl, [$k => $k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$w->templatorWidget->setting('template', __('Template:'), '', 'combo', $tpl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class widgetTemplator
|
return static::$init;
|
||||||
{
|
|
||||||
public static function getDataTpl($w)
|
|
||||||
{
|
|
||||||
if (dcCore::app()->tpl->getFilePath($w->template)) {
|
|
||||||
echo dcCore::app()->tpl->getData($w->template);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dcCore::app()->auth?->setPermissionType(
|
||||||
|
My::PERMISSION_TEMPLATOR,
|
||||||
|
__('manage templates')
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,55 +10,116 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class dcTemplator
|
namespace Dotclear\Plugin\templator;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Helper\File\Files;
|
||||||
|
use Dotclear\Helper\File\Path;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Templator main class.
|
||||||
|
*/
|
||||||
|
class Templator
|
||||||
{
|
{
|
||||||
protected $tpls_default_name = 'dotty';
|
/** @var string This plugin folder for templates */
|
||||||
protected $post_default_name = 'post.html';
|
public const MY_TPL_DIR = 'other-templates';
|
||||||
protected $page_default_name = 'page.html';
|
|
||||||
protected $category_default_name = 'category.html';
|
|
||||||
|
|
||||||
public $template_dir_name = 'other-templates';
|
/** @var string The dotclear folder for templates */
|
||||||
public $path;
|
public const DC_TPL_DIR = 'default-templates';
|
||||||
|
|
||||||
public $tpl = [];
|
/** @var string The themes folder for templates */
|
||||||
public $theme_tpl = [];
|
public const THEME_TPL_DIR = 'tpl';
|
||||||
|
|
||||||
|
/** @var string The default tplset */
|
||||||
|
public const DEFAULT_TPLSET = 'dotty';
|
||||||
|
|
||||||
|
/** @var string The default post template */
|
||||||
|
public const DEFAULT_TPL_POST = 'post.html';
|
||||||
|
|
||||||
|
/** @var string The default page template */
|
||||||
|
public const DEFAULT_TPL_PAGE = 'page.html';
|
||||||
|
|
||||||
|
/** @var string The default category tempalte */
|
||||||
|
public const DEFAULT_TPL_CATEGORY = 'category.html';
|
||||||
|
|
||||||
|
/** @var Templator Self instance */
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
/** @var string $path This plugin templates directory path */
|
||||||
|
private string $path = '';
|
||||||
|
|
||||||
|
/** @var array<string,string> The known templates files */
|
||||||
|
private array $tpl = [];
|
||||||
|
|
||||||
|
private string $file_tpl_post = '';
|
||||||
|
private string $file_tpl_page = '';
|
||||||
|
private string $file_tpl_category = '';
|
||||||
|
|
||||||
|
private string $user_path_theme = '';
|
||||||
|
private string $user_tpl_post = '';
|
||||||
|
private string $user_tpl_category = '';
|
||||||
|
private string $user_tpl_page = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Constructor sets properties.
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->path = dcCore::app()->blog->public_path . '/' . $this->template_dir_name;
|
if (is_null(dcCore::app()->blog)) {
|
||||||
|
throw new Exception(__('Blog is not set'));
|
||||||
// Initial templates
|
|
||||||
$this->post_tpl = DC_ROOT . '/inc/public/default-templates/' . $this->tpls_default_name . '/' . $this->post_default_name;
|
|
||||||
$this->category_tpl = DC_ROOT . '/inc/public/default-templates/' . $this->tpls_default_name . '/' . $this->category_default_name;
|
|
||||||
|
|
||||||
if (dcCore::app()->plugins->moduleExists('pages')) {
|
|
||||||
$plugin_page = dcCore::app()->plugins->getModules('pages');
|
|
||||||
$this->page_tpl = path::real($plugin_page['root'] . '/default-templates/' . $this->tpls_default_name . '/' . $this->page_default_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->user_theme = dcCore::app()->blog->themes_path . '/' . dcCore::app()->blog->settings->system->theme;
|
$page_root = dcCore::app()->plugins->getDefine('pages')->get('root');
|
||||||
$this->user_post_tpl = path::real($this->user_theme . '/tpl/' . $this->post_default_name);
|
|
||||||
$this->user_category_tpl = path::real($this->user_theme . '/tpl/' . $this->category_default_name);
|
// Initial templates
|
||||||
$this->user_page_tpl = path::real($this->user_theme . '/tpl/' . $this->page_default_name);
|
$this->path = implode(DIRECTORY_SEPARATOR, [dcCore::app()->blog->public_path, self::MY_TPL_DIR]);
|
||||||
|
$this->file_tpl_post = implode(DIRECTORY_SEPARATOR, [DC_ROOT, 'inc', 'public', self::DC_TPL_DIR, self::DEFAULT_TPLSET, self::DEFAULT_TPL_POST]);
|
||||||
|
$this->file_tpl_category = implode(DIRECTORY_SEPARATOR, [DC_ROOT, 'inc', 'public', self::DC_TPL_DIR, self::DEFAULT_TPLSET, self::DEFAULT_TPL_CATEGORY]);
|
||||||
|
$this->file_tpl_page = Path::real(implode(DIRECTORY_SEPARATOR, [$page_root, self::DC_TPL_DIR, self::DEFAULT_TPLSET, self::DEFAULT_TPL_PAGE])) ?: '';
|
||||||
|
|
||||||
|
// user templates
|
||||||
|
$this->user_path_theme = dcCore::app()->blog->themes_path . DIRECTORY_SEPARATOR . dcCore::app()->blog->settings->get('system')->get('theme');
|
||||||
|
$this->user_tpl_post = Path::real(implode(DIRECTORY_SEPARATOR, [$this->user_path_theme, self::THEME_TPL_DIR, self::DEFAULT_TPL_POST])) ?: '';
|
||||||
|
$this->user_tpl_category = Path::real(implode(DIRECTORY_SEPARATOR, [$this->user_path_theme, self::THEME_TPL_DIR, self::DEFAULT_TPL_CATEGORY])) ?: '';
|
||||||
|
$this->user_tpl_page = Path::real(implode(DIRECTORY_SEPARATOR, [$this->user_path_theme, self::THEME_TPL_DIR, self::DEFAULT_TPL_PAGE])) ?: '';
|
||||||
|
|
||||||
$this->findTemplates();
|
$this->findTemplates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function instance(): Templator
|
||||||
|
{
|
||||||
|
if (!(self::$instance instanceof Templator)) {
|
||||||
|
self::$instance = new Templator();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPath(): string
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public function getTpl(): array
|
||||||
|
{
|
||||||
|
return $this->tpl;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function canUseRessources($create = false)
|
public function canUseRessources(bool $create = false): bool
|
||||||
{
|
{
|
||||||
if (!is_dir($this->path)) {
|
if (!is_dir($this->path)) {
|
||||||
if ($create) {
|
if ($create) {
|
||||||
files::makeDir($this->path);
|
Files::makeDir($this->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -80,9 +141,9 @@ class dcTemplator
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return array{c: string, w: bool, f: string}
|
||||||
*/
|
*/
|
||||||
public function getSourceContent($f)
|
public function getSourceContent(string $f): array
|
||||||
{
|
{
|
||||||
$source = $this->tpl;
|
$source = $this->tpl;
|
||||||
|
|
||||||
|
@ -96,8 +157,8 @@ class dcTemplator
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'c' => file_get_contents($source[$f]),
|
'c' => (string) file_get_contents($source[$f]),
|
||||||
'w' => $this->getDestinationFile($f) !== false,
|
'w' => !empty($this->getDestinationFile($f)),
|
||||||
'f' => $f,
|
'f' => $f,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -105,7 +166,7 @@ class dcTemplator
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function filesList($item = '%1$s')
|
public function filesList(string $item = '%1$s'): string
|
||||||
{
|
{
|
||||||
$files = $this->tpl;
|
$files = $this->tpl;
|
||||||
|
|
||||||
|
@ -117,7 +178,7 @@ class dcTemplator
|
||||||
foreach ($files as $k => $v) {
|
foreach ($files as $k => $v) {
|
||||||
$li = sprintf('<li>%s</li>', $item);
|
$li = sprintf('<li>%s</li>', $item);
|
||||||
|
|
||||||
$list .= sprintf($li, $k, html::escapeHTML($k));
|
$list .= sprintf($li, $k, Html::escapeHTML($k));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf('<ul>%s</ul>', $list);
|
return sprintf('<ul>%s</ul>', $list);
|
||||||
|
@ -126,31 +187,31 @@ class dcTemplator
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function initializeTpl($name, $type)
|
public function initializeTpl(string $name, string $type): void
|
||||||
{
|
{
|
||||||
if ($type == 'category') {
|
if ($type == 'category') {
|
||||||
if ($this->user_category_tpl) {
|
if ($this->user_tpl_category) {
|
||||||
$base = $this->user_category_tpl;
|
$base = $this->user_tpl_category;
|
||||||
} else {
|
} else {
|
||||||
$base = $this->category_tpl;
|
$base = $this->file_tpl_category;
|
||||||
}
|
}
|
||||||
} elseif ($type == 'page') {
|
} elseif ($type == 'page') {
|
||||||
if ($this->user_page_tpl) {
|
if ($this->user_tpl_page) {
|
||||||
$base = $this->user_page_tpl;
|
$base = $this->user_tpl_page;
|
||||||
} else {
|
} else {
|
||||||
$base = $this->page_tpl;
|
$base = $this->file_tpl_page;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($this->user_post_tpl) {
|
if ($this->user_tpl_post) {
|
||||||
$base = $this->user_post_tpl;
|
$base = $this->user_tpl_post;
|
||||||
} else {
|
} else {
|
||||||
$base = $this->post_tpl;
|
$base = $this->file_tpl_post;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$source = [
|
$source = [
|
||||||
'c' => file_get_contents($base),
|
'c' => (string) file_get_contents($base),
|
||||||
'w' => $this->getDestinationFile($name) !== false,
|
'w' => !empty($this->getDestinationFile($name)),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!$source['w']) {
|
if (!$source['w']) {
|
||||||
|
@ -171,7 +232,7 @@ class dcTemplator
|
||||||
$content = $source['c'];
|
$content = $source['c'];
|
||||||
|
|
||||||
if (!is_dir(dirname($dest))) {
|
if (!is_dir(dirname($dest))) {
|
||||||
files::makeDir(dirname($dest));
|
Files::makeDir(dirname($dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fp = @fopen($dest, 'wb');
|
$fp = @fopen($dest, 'wb');
|
||||||
|
@ -179,8 +240,8 @@ class dcTemplator
|
||||||
throw new Exception('tocatch');
|
throw new Exception('tocatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = preg_replace('/(\r?\n)/m', "\n", $content);
|
$content = (string) preg_replace('/(\r?\n)/m', "\n", $content);
|
||||||
$content = preg_replace('/\r/m', "\n", $content);
|
$content = (string) preg_replace('/\r/m', "\n", $content);
|
||||||
|
|
||||||
fwrite($fp, $content);
|
fwrite($fp, $content);
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
@ -192,7 +253,7 @@ class dcTemplator
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function copypasteTpl($name, $source)
|
public function copypasteTpl(string $name, string $source): void
|
||||||
{
|
{
|
||||||
if ($name == $source) {
|
if ($name == $source) {
|
||||||
throw new Exception(__('File already exists.'));
|
throw new Exception(__('File already exists.'));
|
||||||
|
@ -202,7 +263,7 @@ class dcTemplator
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'c' => $file['c'],
|
'c' => $file['c'],
|
||||||
'w' => $this->getDestinationFile($name) !== false,
|
'w' => !empty($this->getDestinationFile($name)),
|
||||||
];
|
];
|
||||||
|
|
||||||
if (!$data['w']) {
|
if (!$data['w']) {
|
||||||
|
@ -219,7 +280,7 @@ class dcTemplator
|
||||||
$content = $data['c'];
|
$content = $data['c'];
|
||||||
|
|
||||||
if (!is_dir(dirname($dest))) {
|
if (!is_dir(dirname($dest))) {
|
||||||
files::makeDir(dirname($dest));
|
Files::makeDir(dirname($dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fp = @fopen($dest, 'wb');
|
$fp = @fopen($dest, 'wb');
|
||||||
|
@ -227,8 +288,8 @@ class dcTemplator
|
||||||
throw new Exception('tocatch');
|
throw new Exception('tocatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = preg_replace('/(\r?\n)/m', "\n", $content);
|
$content = (string) preg_replace('/(\r?\n)/m', "\n", $content);
|
||||||
$content = preg_replace('/\r/m', "\n", $content);
|
$content = (string) preg_replace('/\r/m', "\n", $content);
|
||||||
|
|
||||||
fwrite($fp, $content);
|
fwrite($fp, $content);
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
@ -240,7 +301,7 @@ class dcTemplator
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function writeTpl($name, $content)
|
public function writeTpl(string $name, string $content): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$dest = $this->getDestinationFile($name);
|
$dest = $this->getDestinationFile($name);
|
||||||
|
@ -250,16 +311,17 @@ class dcTemplator
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_dir(dirname($dest))) {
|
if (!is_dir(dirname($dest))) {
|
||||||
files::makeDir(dirname($dest));
|
Files::makeDir(dirname($dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fp = @fopen($dest, 'wb');
|
$fp = @fopen($dest, 'wb');
|
||||||
if (!$fp) {
|
if (!$fp) {
|
||||||
//throw new Exception('tocatch');
|
//throw new Exception('tocatch');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = preg_replace('/(\r?\n)/m', "\n", $content);
|
$content = (string) preg_replace('/(\r?\n)/m', "\n", $content);
|
||||||
$content = preg_replace('/\r/m', "\n", $content);
|
$content = (string) preg_replace('/\r/m', "\n", $content);
|
||||||
|
|
||||||
fwrite($fp, $content);
|
fwrite($fp, $content);
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
@ -271,7 +333,7 @@ class dcTemplator
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function copyTpl($name)
|
public function copyTpl(string $name): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$file = $this->getSourceContent($name);
|
$file = $this->getSourceContent($name);
|
||||||
|
@ -282,7 +344,7 @@ class dcTemplator
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_dir(dirname($dest))) {
|
if (!is_dir(dirname($dest))) {
|
||||||
files::makeDir(dirname($dest));
|
Files::makeDir(dirname($dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
$fp = @fopen($dest, 'wb');
|
$fp = @fopen($dest, 'wb');
|
||||||
|
@ -290,7 +352,7 @@ class dcTemplator
|
||||||
throw new Exception('tocatch');
|
throw new Exception('tocatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = preg_replace('/(\r?\n)/m', "\n", $file['c']);
|
$content = (string) preg_replace('/(\r?\n)/m', "\n", $file['c']);
|
||||||
$content = preg_replace('/\r/m', "\n", $file['c']);
|
$content = preg_replace('/\r/m', "\n", $file['c']);
|
||||||
|
|
||||||
fwrite($fp, $file['c']);
|
fwrite($fp, $file['c']);
|
||||||
|
@ -300,11 +362,14 @@ class dcTemplator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getDestinationFile($f, $totheme = false)
|
/**
|
||||||
|
* @return string The destination or empty string on error
|
||||||
|
*/
|
||||||
|
protected function getDestinationFile(string $f, bool $totheme = false): string
|
||||||
{
|
{
|
||||||
$dest = $this->path . '/' . $f;
|
$dest = $this->path . '/' . $f;
|
||||||
if ($totheme) {
|
if ($totheme) {
|
||||||
$dest = $this->user_theme . '/tpl/' . $f;
|
$dest = implode(DIRECTORY_SEPARATOR, [$this->user_path_theme, self::THEME_TPL_DIR, $f]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists($dest) && is_writable($dest)) {
|
if (file_exists($dest) && is_writable($dest)) {
|
||||||
|
@ -315,27 +380,31 @@ class dcTemplator
|
||||||
return $dest;
|
return $dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function findTemplates()
|
protected function findTemplates(): void
|
||||||
{
|
{
|
||||||
$this->tpl = $this->getFilesInDir($this->path);
|
$this->tpl = $this->getFilesInDir($this->path);
|
||||||
//$this->theme_tpl = $this->getFilesInDir(path::real($this->user_theme).'/tpl');
|
|
||||||
|
|
||||||
uksort($this->tpl, [$this,'sortFilesHelper']);
|
uksort($this->tpl, [$this,'sortFilesHelper']);
|
||||||
//uksort($this->theme_tpl,array($this,'sortFilesHelper'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getFilesInDir($dir)
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
protected function getFilesInDir(string $dir): array
|
||||||
{
|
{
|
||||||
$dir = path::real($dir);
|
$res = [];
|
||||||
|
$dir = Path::real($dir);
|
||||||
if (!$dir || !is_dir($dir) || !is_readable($dir)) {
|
if (!$dir || !is_dir($dir) || !is_readable($dir)) {
|
||||||
return [];
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
$d = dir($dir);
|
$d = dir($dir);
|
||||||
$res = [];
|
if (!$d) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
while (($f = $d->read()) !== false) {
|
while (($f = $d->read()) !== false) {
|
||||||
if (is_file($dir . '/' . $f) && !preg_match('/^\./', $f)) {
|
if (is_file($dir . '/' . $f) && !preg_match('/^\./', $f)) {
|
||||||
$res[$f] = $dir . '/' . $f;
|
$res[$f] = $dir . '/' . $f;
|
||||||
|
@ -345,14 +414,14 @@ class dcTemplator
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sortFilesHelper($a, $b)
|
protected function sortFilesHelper(string $a, string $b): int
|
||||||
{
|
{
|
||||||
if ($a == $b) {
|
if ($a == $b) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ext_a = files::getExtension($a);
|
$ext_a = Files::getExtension($a);
|
||||||
$ext_b = files::getExtension($b);
|
$ext_b = Files::getExtension($b);
|
||||||
|
|
||||||
return strcmp($ext_a . '.' . $a, $ext_b . '.' . $b);
|
return strcmp($ext_a . '.' . $a, $ext_b . '.' . $b);
|
||||||
}
|
}
|
||||||
|
|
59
src/Widgets.php
Normal file
59
src/Widgets.php
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief templator, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Osku 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\templator;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Plugin\widgets\WidgetsStack;
|
||||||
|
use Dotclear\Plugin\widgets\WidgetsElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widgets.
|
||||||
|
*/
|
||||||
|
class Widgets
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param WidgetsStack $w WidgetsStack instance
|
||||||
|
*/
|
||||||
|
public static function initWidgets(WidgetsStack $w): void
|
||||||
|
{
|
||||||
|
$tpl = [' .html' => ''];
|
||||||
|
$tpls = Templator::instance()->getTpl();
|
||||||
|
foreach ($tpls as $k => $v) {
|
||||||
|
if (preg_match('/^widget-(.+)$/', $k)) {
|
||||||
|
$tpl = array_merge($tpl, [$k => $k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$w
|
||||||
|
->create(
|
||||||
|
'templatorWidget',
|
||||||
|
__('Templator › Rendering'),
|
||||||
|
[self::class, 'getDataTpl']
|
||||||
|
)
|
||||||
|
->setting(
|
||||||
|
'template',
|
||||||
|
__('Template:'),
|
||||||
|
'',
|
||||||
|
'combo',
|
||||||
|
$tpl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDataTpl(WidgetsElement $w): string
|
||||||
|
{
|
||||||
|
return is_string($w->__get('template')) && dcCore::app()->tpl->getFilePath($w->__get('template')) ?
|
||||||
|
dcCore::app()->tpl->getData($w->__get('template')) : '';
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue