diff --git a/_define.php b/_define.php
index 7c551c1..5be80aa 100644
--- a/_define.php
+++ b/_define.php
@@ -10,7 +10,7 @@
* @copyright Jean-Christian Denis
* @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;
}
@@ -22,7 +22,7 @@ $this->registerModule(
[
'requires' => [['core', '2.24']],
'permissions' => dcCore::app()->auth->makePermissions([
- dcAuth::PERMISSION_CONTENT_ADMIN,
+ dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
initTemplator::PERMISSION_TEMPLATOR,
]),
'type' => 'plugin',
diff --git a/src/Backend.php b/src/Backend.php
index bba762a..8fc1661 100644
--- a/src/Backend.php
+++ b/src/Backend.php
@@ -10,161 +10,71 @@
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
-if (!defined('DC_CONTEXT_ADMIN')) {
- return null;
-}
+declare(strict_types=1);
-dcCore::app()->auth->setPermissionType(initTemplator::PERMISSION_TEMPLATOR, __('manage templates'));
+namespace Dotclear\Plugin\templator;
-dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
- __('Templates engine'),
- dcCore::app()->adminurl->get('admin.plugin.templator'),
- urldecode(dcPage::getPF('templator/icon.png')),
- preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.templator')) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
- dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
- dcAuth::PERMISSION_CONTENT_ADMIN,
- initTemplator::PERMISSION_TEMPLATOR,
- ]), dcCore::app()->blog->id)
-);
+use dcAdmin;
+use dcCore;
+use dcMenu;
+use dcNsProcess;
+use dcPage;
-if (dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
- 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
+class Backend extends dcNsProcess
{
- 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 ($post) {
- $post_meta = dcCore::app()->meta->getMetadata(['meta_type' => 'template', 'post_id' => $post->post_id]);
- $selected = $post_meta->isEmpty() ? '' : $post_meta->meta_id;
+ if (!static::$init) {
+ return false;
}
- $sidebar_items['options-box']['items']['templator'] = '
' .
- '
' . __('Template') . '
' .
- '
' .
- form::combo('post_tpl', self::getTemplateCombo(), $selected) . '
' .
- '
';
- }
-
- public static function adminBeforePostUpdate($cur, $post_id)
- {
- $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)
- {
- $pa->addAction(
- [
- __('Appearance') => [
- __('Select the template') => 'tpl',
- ],
- ],
- ['templatorBehaviors', 'adminPostsActionsCallback']
- );
- }
-
- public static function adminPostsActionsCallback(dcPostsActions $pa, ArrayObject $post)
- {
- # No entry
- $posts_ids = $pa->getIDs();
- if (empty($posts_ids)) {
- throw new Exception(__('No entry selected'));
+ // nullsafe
+ if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
+ return false;
}
- if (isset($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']);
- }
- }
-
- dcAdminNotices::addSuccessNotice(__('Entries template updated.'));
- $pa->redirect(true);
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
+ //backend sidebar menu icon
+ if ((dcCore::app()->menu[dcAdmin::MENU_PLUGINS] instanceof dcMenu)) {
+ dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
+ My::name(),
+ dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
+ urldecode(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,
+ My::PERMISSION_TEMPLATOR,
+ ]), dcCore::app()->blog->id)
+ );
}
- $pa->beginPage(
- dcPage::breadcrumb([
- html::escapeHTML(dcCore::app()->blog->name) => '',
- $pa->getCallerTitle() => $pa->getRedirection(true),
- __('Entry template') => '',
- ])
- );
+ dcCore::app()->addBehaviors([
+ 'adminPostHeaders' => [BackendBehaviors::class,'adminPostHeaders'],
+ 'adminPostFormItems' => [BackendBehaviors::class,'adminPostFormItems'],
+ 'adminPageHeaders' => [BackendBehaviors::class,'adminPostHeaders'],
+ 'adminPageFormItems' => [BackendBehaviors::class,'adminPostFormItems'],
+ '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'],
+ ]);
- echo
- '' . __('Select template for the selection') . '
' .
- '';
-
- $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;
+ return true;
}
}
diff --git a/src/BackendBehaviors.php b/src/BackendBehaviors.php
new file mode 100644
index 0000000..e647143
--- /dev/null
+++ b/src/BackendBehaviors.php
@@ -0,0 +1,157 @@
+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'] = '' .
+ '
' . __('Template') . '
' .
+ '
' .
+ form::combo('post_tpl', self::getTemplateCombo(), $selected) . '
' .
+ '
';
+ }
+
+ 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
+ '' . __('Select template for the selection') . '
' .
+ '';
+
+ $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
+ */
+ 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;
+ }
+}
diff --git a/src/Frontend.php b/src/Frontend.php
index 464cb32..525936e 100644
--- a/src/Frontend.php
+++ b/src/Frontend.php
@@ -10,33 +10,69 @@
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
-if (!defined('DC_RC_PATH')) {
- return null;
-}
+declare(strict_types=1);
-dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), dcCore::app()->templator->path);
-dcCore::app()->addBehavior('urlHandlerBeforeGetData', ['publicTemplatorBehaviors','BeforeGetData']);
+namespace Dotclear\Plugin\templator;
-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') {
- $params = [];
- $params['meta_type'] = 'template';
- $params['post_id'] = dcCore::app()->ctx->posts->post_id;
- $post_meta = dcCore::app()->meta->getMetadata($params);
+ static::$init = My::phpCompliant();
- if (!$post_meta->isEmpty() && dcCore::app()->tpl->getFilePath($post_meta->meta_id)) {
- dcCore::app()->ctx->current_tpl = $post_meta->meta_id;
- }
+ return static::$init;
+ }
+
+ public static function process(): bool
+ {
+ if (!static::$init) {
+ return false;
}
- if (dcCore::app()->ctx->current_tpl == 'category.html' && preg_match('/^[0-9]{1,}/', dcCore::app()->ctx->categories->cat_id, $cat_id)) {
- $tpl = 'category-' . $cat_id[0] . '.html';
- if (dcCore::app()->tpl->getFilePath($tpl)) {
- dcCore::app()->ctx->current_tpl = $tpl;
- }
- }
+ 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['meta_type'] = 'template';
+ $params['post_id'] = dcCore::app()->ctx->__get('posts')->f('post_id');
+ $post_meta = dcCore::app()->meta->getMetadata($params);
+
+ if (!$post_meta->isEmpty() && is_string($post_meta->f('meta_id')) && dcCore::app()->tpl->getFilePath($post_meta->f('meta_id'))) {
+ dcCore::app()->ctx->__set('current_tpl', $post_meta->f('meta_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';
+ if (dcCore::app()->tpl->getFilePath($tpl)) {
+ dcCore::app()->ctx->__set('current_tpl', $tpl);
+ }
+ }
+ },
+ 'initWidgets' => [Widgets::class, 'initWidgets'],
+ ]);
+
+ return true;
}
}
diff --git a/src/Manage.php b/src/Manage.php
index 31b7a25..0ffa8a8 100644
--- a/src/Manage.php
+++ b/src/Manage.php
@@ -10,621 +10,633 @@
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
-if (!defined('DC_CONTEXT_ADMIN')) {
- return null;
-}
+declare(strict_types=1);
-dcPage::check(dcCore::app()->auth->makePermissions([
- dcAuth::PERMISSION_CONTENT_ADMIN,
- initTemplator::PERMISSION_TEMPLATOR,
-]));
+namespace Dotclear\Plugin\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'])) {
- //Extend dcMedia to change settings to allow .html vs media_exclusion
- $media = new templatorMedia();
- $media->chdir(dcCore::app()->templator->template_dir_name);
- // For users with only templator permission, we use sudo.
- dcCore::app()->auth->sudo([$media,'getDir']);
- $dir = $media->dir;
- $items = array_values($dir['files']);
-}
+class Manage extends dcNsProcess
+{
+ public static function init(): bool
+ {
+ static::$init == defined('DC_CONTEXT_ADMIN')
+ && My::phpCompliant()
+ && !is_null(dcCore::app()->auth)
+ && !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'])) {
- $has_categories = false;
+ return static::$init;
+ }
- try {
- $categories = dcCore::app()->blog->getCategories(['post_type' => 'post']);
+ public static function process(): bool
+ {
+ if (!static::$init) {
+ return false;
+ }
- $categories_combo = [];
- $l = $categories->level;
- $full_name = [$categories->cat_title];
+ // nullsafe
+ if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
+ return false;
+ }
- while ($categories->fetch()) {
- if ($categories->level < $l) {
- $full_name = [];
- } elseif ($categories->level == $l) {
- array_pop($full_name);
+ // instances
+ $t = Templator::instance();
+ $v = ManageVars::instance();
+
+ /*
+ * Duplicate dc template
+ */
+ if ('new' == $v->part && !empty($_POST['filesource'])) {
+ try {
+ if ('category' == $_POST['filesource']) {
+ $name = 'category-' . $_POST['filecat'] . '.html';
+ } elseif (!empty($_POST['filename'])) {
+ $name = Files::tidyFileName($_POST['filename']) . '.html';
+ } else {
+ throw new Exception(__('Filename is empty.'));
+ }
+ $t->initializeTpl($name, $_POST['filesource']);
+
+ if (!dcCore::app()->error->flag()) {
+ dcPage::addSuccessNotice(__('The new template has been successfully created.'));
+ dcCore::app()->adminurl->redirect('admin.plugin.templator');
+ }
+ } catch (Exception $e) {
+ dcCore::app()->error->add($e->getMessage());
}
- $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 = [
- __('Empty template') => 'empty',
- 'post.html' => 'post',
- ];
-
- 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) {
- $combo_source['category.html'] = 'category';
- }
-}
-
-### Action ###
-
-/*
- * Duplicate dc template
- */
-if ('new' == $part && !empty($_POST['filesource'])) {
- try {
- if ('category' == $_POST['filesource']) {
- $name = 'category-' . $_POST['filecat'] . '.html';
- } elseif (!empty($_POST['filename'])) {
- $name = files::tidyFileName($_POST['filename']) . '.html';
- } else {
- throw new Exception(__('Filename is empty.'));
- }
- dcCore::app()->templator->initializeTpl($name, $_POST['filesource']);
-
- if (!dcCore::app()->error->flag()) {
- dcAdminNotices::addSuccessNotice(__('The new template has been successfully created.'));
- dcCore::app()->adminurl->redirect('admin.plugin.templator');
- }
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
-}
-
-/*
- * Copy tempaltor template
- */
-if ('copy' == $part && !empty($_POST['filename'])) {
- try {
- dcCore::app()->templator->copypasteTpl(
- rawurldecode($_POST['filename']) . '.html',
- rawurldecode($_POST['file'])
- );
-
- if (!dcCore::app()->error->flag()) {
- dcAdminNotices::addSuccessNotice(__('The template has been successfully copied.'));
- dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
- }
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
-}
-
-/*
- * Copy templator category template
- */
-if ('copycat' == $part && !empty($_POST['filecat'])) {
- try {
- dcCore::app()->templator->copypasteTpl(
- 'category-' . rawurldecode($_POST['filecat']) . '.html',
- rawurldecode($_POST['file'])
- );
-
- if (!dcCore::app()->error->flag()) {
- dcAdminNotices::addSuccessNotice(__('The template has been successfully copied.'));
- dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
- }
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
-}
-
-/*
- * Delete tempaltor template
- */
-if ('delete' == $part && !empty($_POST['file'])) {
- try {
- $file = rawurldecode($_POST['file']);
- $media->removeItem($file);
- dcCore::app()->meta->delMeta($file, 'template');
-
- if (!dcCore::app()->error->flag()) {
- dcAdminNotices::addSuccessNotice(__('The template has been successfully removed.'));
- dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
- }
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
-}
-
-### Display ###
-
-/*
- * Check
- */
-
-if (!dcCore::app()->templator->canUseRessources(true)) {
- dcCore::app()->error->add(__('The plugin is unusable with your configuration. You have to change file permissions.'));
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('New template') => '',
- ]) .
- dcPage::notices();
-
- /*
- * Duplicate dotclear template
- */
-} elseif ('new' == $part) {
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('New template') => '',
- ]) .
- dcPage::notices() .
-
- '';
-
- /*
- * Copy templator template
- */
-} elseif ('copy' == $part && !empty($_REQUEST['file'])) {
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Copy available template') => '',
- ]) .
- dcPage::notices() .
-
- '';
-
- /*
- * Copy templator category template
- */
-} elseif ('copycat' == $part && !empty($_REQUEST['file'])) {
- $category_id = (int) str_replace(['category-','.html'], '', $_REQUEST['file']);
- $cat_parents = dcCore::app()->blog->getCategoryParents($category_id);
- $full_name = '';
- while ($cat_parents->fetch()) {
- $full_name = $cat_parents->cat_title . ' › ';
- };
- $name = $full_name . dcCore::app()->blog->getCategory($category_id)->cat_title;
-
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Copy available template') => '',
- ]) .
- dcPage::notices() .
-
- '';
-
- /*
- * Delete templator template
- */
-} elseif ('delete' == $part && !empty($_REQUEST['file'])) {
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Delete available template') => '',
- ]) .
- dcPage::notices() .
-
- '';
-
- /*
- * List templator templates
- */
-} elseif ('files' == $part) {
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Available templates') => '',
- ]) .
- dcPage::notices() .
- '' . __('Available templates') . '
';
-
- if (count($items) == 0) {
- echo '' . __('No template.') . '
';
- } else {
- // reuse "used templatro template" filter settings
- $filter = new adminGenericFilterV2('templator');
- $filter->add(dcAdminFilters::getPageFilter());
-
- $pager = new dcPager($filter->page, count($items), $filter->nb, 10);
-
- echo
- '' .
- $pager->getLinks();
-
- for ($i = $pager->index_start, $j = 0; $i <= $pager->index_end; $i++, $j++) {
- echo templatorPager::templatorItemLine($items[$i], $j);
}
- echo
- $pager->getLinks() .
- '
';
- }
+ /*
+ * Copy tempaltor template
+ */
+ if ('copy' == $v->part && !empty($_POST['filename'])) {
+ try {
+ $t->copypasteTpl(
+ rawurldecode($_POST['filename']) . '.html',
+ rawurldecode($_POST['file'])
+ );
- /*
- * List Used templator template
- */
-} elseif ('used' == $part) {
- $tags = dcCore::app()->meta->getMetadata(['meta_type' => 'template']);
- $tags = dcCore::app()->meta->computeMetaStats($tags);
- $tags->sort('meta_id_lower', 'asc');
-
- $last_letter = null;
- $cols = ['',''];
- $col = 0;
-
- while ($tags->fetch()) {
- $letter = mb_strtoupper(mb_substr($tags->meta_id, 0, 1));
-
- if ($last_letter != $letter) {
- if ($tags->index() >= round($tags->count() / 2)) {
- $col = 1;
+ if (!dcCore::app()->error->flag()) {
+ dcPage::addSuccessNotice(__('The template has been successfully copied.'));
+ dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
+ }
+ } catch (Exception $e) {
+ dcCore::app()->error->add($e->getMessage());
}
- $cols[$col] .= '' . $letter . ' |
';
}
- $img = '';
- if (array_key_exists($tags->meta_id, dcCore::app()->templator->tpl)) {
- $img_status = sprintf($img, __('available template'), 'check-on.png');
- } else {
- $img_status = sprintf($img, __('missing template'), 'check-off.png');
- }
+ /*
+ * Copy templator category template
+ */
+ if ('copycat' == $v->part && !empty($_POST['filecat'])) {
+ try {
+ $t->copypasteTpl(
+ 'category-' . rawurldecode($_POST['filecat']) . '.html',
+ rawurldecode($_POST['file'])
+ );
- $cols[$col] .= '' .
- '' . $tags->meta_id . ' ' . $img_status . ' | ' .
- '' . $tags->count . ' ' .
- (($tags->count == 1) ? __('entry') : __('entries')) . ' | ' .
- '
';
-
- $last_letter = $letter;
- }
-
- $table = '';
-
- echo
- '' . __('Templator') . '' .
- dcPage::cssLoad(dcPage::getPF('tags/style.css')) .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Used templates') => '',
- ]) .
- dcPage::notices() .
- '' . __('Used templates') . '
';
-
- if ($cols[0]) {
- echo '';
- printf($table, $cols[0]);
- if ($cols[1]) {
- printf($table, $cols[1]);
- }
- echo '
';
- } else {
- echo '' . __('No specific templates on this blog.') . '
';
- }
-
- /*
- * Edit emplator template
- */
-} elseif ('edit' == $part && !empty($_REQUEST['file'])) {
- try {
- try {
- $name = rawurldecode($_REQUEST['file']);
- $file = dcCore::app()->templator->getSourceContent($name);
- $name = $file['f'];
-
- if (preg_match('/^category-(.+).html$/', $name, $cat_id)) {
- $category = dcCore::app()->blog->getCategory((int) $cat_id[1]);
- $full_name = '';
- $cat_parents = dcCore::app()->blog->getCategoryParents((int) $cat_id[1]);
- while ($cat_parents->fetch()) {
- $full_name = $cat_parents->cat_title . ' › ';
- };
- $name .= ' (' . $full_name . $category->cat_title . ')';
+ if (!dcCore::app()->error->flag()) {
+ dcPage::addSuccessNotice(__('The template has been successfully copied.'));
+ dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
+ }
+ } catch (Exception $e) {
+ dcCore::app()->error->add($e->getMessage());
}
- } catch (Exception $e) {
- $file = '';
-
- throw $e;
}
- # Write file
- if (!empty($_POST['write'])) {
- $file['c'] = $_POST['file_content'];
- dcCore::app()->templator->writeTpl($file['f'], $file['c']);
+
+ /*
+ * Delete tempaltor template
+ */
+ if ('delete' == $v->part && !empty($_POST['file'])) {
+ try {
+ $file = rawurldecode($_POST['file']);
+ $v->media->removeItem($file);
+ dcCore::app()->meta->delMeta($file, 'template');
+
+ if (!dcCore::app()->error->flag()) {
+ dcPage::addSuccessNotice(__('The template has been successfully removed.'));
+ dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'files']);
+ }
+ } catch (Exception $e) {
+ dcCore::app()->error->add($e->getMessage());
+ }
}
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
+
+ return true;
}
- dcCore::app()->auth->user_prefs->addWorkspace('interface');
+ public static function render(): void
+ {
+ if (!static::$init) {
+ return;
+ }
- echo
- '' . __('Templator') . '';
+ // 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;
+ }
- if (dcCore::app()->auth->user_prefs->interface->colorsyntax) {
- echo
- dcPage::jsJson('dotclear_colorsyntax', ['colorsyntax' => dcCore::app()->auth->user_prefs->interface->colorsyntax]);
- }
- echo
- dcPage::jsJson('theme_editor_msg', [
- 'saving_document' => __('Saving document...'),
- 'document_saved' => __('Document saved'),
- 'error_occurred' => __('An error occurred:'),
- 'confirm_reset_file' => __('Are you sure you want to reset this file?'),
- ]) .
- dcPage::jsModuleLoad('themeEditor/js/script.js') .
- dcPage::jsConfirmClose('file-form');
- if (dcCore::app()->auth->user_prefs->interface->colorsyntax) {
- echo
- dcPage::jsLoadCodeMirror(dcCore::app()->auth->user_prefs->interface->colorsyntax_theme);
- }
- echo
- dcPage::cssModuleLoad('themeEditor/style.css') .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Edit template') => '',
- ]) .
- dcPage::notices();
+ // instances
+ $t = Templator::instance();
+ $v = ManageVars::instance();
- if (($file['c'] !== null)) {
- echo
- '';
- if (dcCore::app()->auth->user_prefs->interface->colorsyntax) {
echo
- dcPage::jsJson('theme_editor_mode', ['mode' => 'html']) .
- dcPage::jsModuleLoad('themeEditor/js/mode.js') .
- dcPage::jsRunCodeMirror('editor', 'file_content', 'dotclear', dcCore::app()->auth->user_prefs->interface->colorsyntax_theme);
- }
- }
+ '' . __('Templator') . '' .
+ '' .
+ dcPage::breadcrumb([
+ __('Plugins') => '',
+ __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
+ __('Copy available template') => '',
+ ]) .
+ dcPage::notices() .
- /*
- * Edit posts options linked to a template
- */
-} elseif ('posts' == $part && (!empty($_REQUEST['file']) || $_REQUEST['file'] == '0')) {
- $file = $_REQUEST['file'];
- $redir = $_REQUEST['redir'] ?? dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']);
+ '';
- # Unselect the template
- if (!empty($_POST['action']) && 'unselecttpl' == $_POST['action'] && dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
- dcAuth::PERMISSION_PUBLISH,
- dcAuth::PERMISSION_CONTENT_ADMIN,
- ]), dcCore::app()->blog->id)) {
- try {
- dcCore::app()->meta->delMeta($file, 'template');
- dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'posts', 'file' => $file]);
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
- }
+ /*
+ * Delete templator template
+ */
+ } elseif ('delete' == $v->part && !empty($_REQUEST['file'])) {
+ echo
+ '' . __('Templator') . '' .
+ '' .
+ dcPage::breadcrumb([
+ __('Plugins') => '',
+ __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
+ __('Delete available template') => '',
+ ]) .
+ dcPage::notices() .
- $filter = new adminGenericFilterV2('templator');
- $filter->add(dcAdminFilters::getPageFilter());
- $filter->add('part', 'posts');
- $filter->add('file', $file);
- $filter->add('post_type', '');
+ '';
- $params = $filter->params();
- $params['no_content'] = true;
- $params['meta_id'] = $file;
- $params['meta_type'] = 'template';
+ /*
+ * List templator templates
+ */
+ } elseif ('files' == $v->part) {
+ echo
+ '' . __('Templator') . '' .
+ '' .
+ dcPage::breadcrumb([
+ __('Plugins') => '',
+ __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
+ __('Available templates') => '',
+ ]) .
+ dcPage::notices() .
+ '' . __('Available templates') . '
';
- # Get posts
- try {
- $posts = dcCore::app()->meta->getPostsByMeta($params);
- $counter = dcCore::app()->meta->getPostsByMeta($params, true);
- $post_list = new adminPostList($posts, $counter->f(0));
- } catch (Exception $e) {
- dcCore::app()->error->add($e->getMessage());
- }
+ if (count($v->items) == 0) {
+ echo '' . __('No template.') . '
';
+ } else {
+ // reuse "used templatro template" filter settings
+ $filter = new adminGenericFilterV2('templator');
+ $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;
- echo
- '' . __('Templator') . '' .
- dcPage::jsFilterControl($filter->show()) .
- dcPage::jsLoad(dcPage::getPF('templator/js/posts.js')) .
- $filter->js(dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'posts', 'file' => $file])) .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
- __('Unselect template') => '',
- ]) .
- dcPage::notices() .
+ $pager = new dcPager($page, count($v->items), $nb, 10);
- '' . sprintf(__('Unselect template "%s"'), '' . $file . '') . '
' .
- '' . __('Back') . '
';
+ echo
+ '';
+ }
+
+ /*
+ * List Used templator template
+ */
+ } elseif ('used' == $v->part) {
+ $tags = dcCore::app()->meta->getMetadata(['meta_type' => 'template']);
+ $tags = dcCore::app()->meta->computeMetaStats($tags);
+ $tags->sort('meta_id_lower', 'asc');
+
+ $last_letter = null;
+ $cols = ['',''];
+ $col = 0;
+
+ while ($tags->fetch()) {
+ $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 ($tags->index() >= round($tags->count() / 2)) {
+ $col = 1;
+ }
+ $cols[$col] .= '' . $letter . ' |
';
+ }
+
+ $img = '';
+ if (array_key_exists($meta_id, $t->getTpl())) {
+ $img_status = sprintf($img, __('available template'), 'check-on.png');
+ } else {
+ $img_status = sprintf($img, __('missing template'), 'check-off.png');
+ }
+
+ $cols[$col] .= '' .
+ '' . $meta_id . ' ' . $img_status . ' | ' .
+ '' . $count . ' ' .
+ (($count == 1) ? __('entry') : __('entries')) . ' | ' .
+ '
';
+
+ $last_letter = $letter;
+ }
+
+ $table = '';
+
+ echo
+ '' . __('Templator') . '' .
+ dcPage::cssLoad(dcPage::getPF('tags/style.css')) .
+ '' .
+ dcPage::breadcrumb([
+ __('Plugins') => '',
+ __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
+ __('Used templates') => '',
+ ]) .
+ dcPage::notices() .
+ '' . __('Used templates') . '
';
+
+ if ($cols[0]) {
+ echo '';
+ printf($table, $cols[0]);
+ if ($cols[1]) {
+ printf($table, $cols[1]);
+ }
+ echo '
';
+ } else {
+ echo '' . __('No specific templates on this blog.') . '
';
+ }
+
+ /*
+ * Edit emplator template
+ */
+ } elseif ('edit' == $v->part && !empty($_REQUEST['file'])) {
+ $file = ['c' => '', 'w' => false, 'f' => ''];
+ $name = '';
+
+ try {
+ try {
+ $name = rawurldecode($_REQUEST['file']);
+ $file = $t->getSourceContent($name);
+ $name = $file['f'];
+
+ if (preg_match('/^category-(.+).html$/', $name, $cat_id)) {
+ $category = dcCore::app()->blog->getCategory((int) $cat_id[1]);
+ $full_name = '';
+ $cat_parents = dcCore::app()->blog->getCategoryParents((int) $cat_id[1]);
+ while ($cat_parents->fetch()) {
+ $full_name = $cat_parents->f('cat_title') . ' › ';
+ };
+ $name .= ' (' . $full_name . $category->f('cat_title') . ')';
+ }
+ } catch (Exception $e) {
+ $file['c'] = null;
+
+ throw $e;
+ }
+ # Write file
+ if (!empty($_POST['write'])) {
+ $file['c'] = $_POST['file_content'] ?? null;
+ $t->writeTpl($file['f'], $file['c']);
+ }
+ } catch (Exception $e) {
+ dcCore::app()->error->add($e->getMessage());
+ }
+
+ echo
+ '' . __('Templator') . '';
+
+ if (dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')) {
+ echo
+ dcPage::jsJson('dotclear_colorsyntax', ['colorsyntax' => dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')]);
+ }
+ echo
+ dcPage::jsJson('theme_editor_msg', [
+ 'saving_document' => __('Saving document...'),
+ 'document_saved' => __('Document saved'),
+ 'error_occurred' => __('An error occurred:'),
+ 'confirm_reset_file' => __('Are you sure you want to reset this file?'),
+ ]) .
+ dcPage::jsModuleLoad('themeEditor/js/script.js') .
+ dcPage::jsConfirmClose('file-form');
+ if (dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')) {
+ $ict = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme');
+ echo
+ dcPage::jsLoadCodeMirror(is_string($ict) ? $ict : '');
+ }
+ echo
+ dcPage::cssModuleLoad('themeEditor/style.css') .
+ '' .
+ dcPage::breadcrumb([
+ __('Plugins') => '',
+ __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
+ __('Edit template') => '',
+ ]) .
+ dcPage::notices();
+
+ if (($file['c'] !== null)) {
+ echo
+ '';
+ if (dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax')) {
+ $ict = dcCore::app()->auth->user_prefs->get('interface')->get('colorsyntax_theme');
+ echo
+ dcPage::jsJson('theme_editor_mode', ['mode' => 'html']) .
+ dcPage::jsModuleLoad('themeEditor/js/mode.js') .
+ dcPage::jsRunCodeMirror('editor', 'file_content', 'dotclear', is_string($ict) ? $ict : '');
+ }
+ }
+
+ /*
+ * Edit posts options linked to a template
+ */
+ } elseif ('posts' == $v->part && (!empty($_REQUEST['file']) || $_REQUEST['file'] == '0')) {
+ $file = $_REQUEST['file'];
+ $redir = $_REQUEST['redir'] ?? dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']);
+
+ # Unselect the template
+ if (!empty($_POST['action']) && 'unselecttpl' == $_POST['action'] && dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
+ dcCore::app()->auth::PERMISSION_PUBLISH,
+ dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
+ ]), dcCore::app()->blog->id)) {
+ try {
+ dcCore::app()->meta->delMeta($file, 'template');
+ dcCore::app()->adminurl->redirect('admin.plugin.templator', ['part' => 'posts', 'file' => $file]);
+ } catch (Exception $e) {
+ dcCore::app()->error->add($e->getMessage());
+ }
+ }
+
+ $filter = new adminGenericFilterV2('templator');
+ $filter->add(dcAdminFilters::getPageFilter());
+ $filter->add('part', 'posts');
+ $filter->add('file', $file);
+ $filter->add('post_type', '');
+
+ $params = $filter->params();
+ $params['no_content'] = true;
+ $params['meta_id'] = $file;
+ $params['meta_type'] = 'template';
+
+ # Get posts
+ try {
+ $posts = dcCore::app()->meta->getPostsByMeta($params);
+ if (is_null($posts)) {
+ 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) {
+ dcCore::app()->error->add($e->getMessage());
+ }
+
+ echo
+ '' . __('Templator') . '' .
+ dcPage::jsFilterControl($filter->show()) .
+ dcPage::jsLoad(dcPage::getPF('templator/js/posts.js')) .
+ $filter->js(dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'posts', 'file' => $file])) .
+ '' .
+ dcPage::breadcrumb([
+ __('Plugins') => '',
+ __('Templates engine') => dcCore::app()->adminurl->get('admin.plugin.templator'),
+ __('Unselect template') => '',
+ ]) .
+ dcPage::notices() .
+
+ '' . sprintf(__('Unselect template "%s"'), '' . $file . '') . '
' .
+ '' . __('Back') . '
';
+
+ if (!dcCore::app()->error->flag() && isset($posts)) {
+ if ($posts->isEmpty() && !$filter->show()) {
+ echo '' . __('There is no entries') . '
';
+ } 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(
+ 'admin.plugin.templator',
+ form::hidden('p', 'templator') . form::hidden('part', 'posts') . form::hidden('file', $file)
+ );
+ # Show posts
+ $post_list->display(
+ $page,
+ $nb,
+ '',
+ $filter->show()
+ );
+ }
+ }
+
+ /*
+ * Default page
+ */
} else {
- $filter->display(
- 'admin.plugin.templator',
- form::hidden('p', 'templator') . form::hidden('part', 'posts') . form::hidden('file', $file)
- );
- # Show posts
- $post_list->display(
- $filter->page,
- $filter->nb,
- '',
- $filter->show(),
- dcCore::app()->adminurl->get('admin.plugin.templator', $filter->values())
+ $line = '%s';
+ echo '
+ ' . __('Manage additional templates') . '
' .
+ sprintf(
+ '',
+ sprintf(
+ $line,
+ dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']),
+ __('Available templates')
+ ) .
+ sprintf(
+ $line,
+ dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']),
+ __('Used templates')
+ ) .
+ sprintf(
+ $line,
+ dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'new']),
+ __('New template')
+ )
);
}
+
+ dcPage::helpBlock('templator');
+
+ dcPage::closeModule();
}
-
- /*
- * Default page
- */
-} else {
- echo
- '' . __('Templator') . '' .
- '' .
- dcPage::breadcrumb([
- __('Plugins') => '',
- __('Templates engine') => '',
- ]) .
- dcPage::notices();
-
- $line = '%s';
- echo '
- ' . __('Manage additional templates') . '
' .
- sprintf(
- '',
- sprintf(
- $line,
- dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']),
- __('Available templates')
- ) .
- sprintf(
- $line,
- dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'used']),
- __('Used templates')
- ) .
- sprintf(
- $line,
- dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'new']),
- __('New template')
- )
- );
}
-
-dcPage::helpBlock('templator');
-
-echo '';
diff --git a/src/ManageVars.php b/src/ManageVars.php
new file mode 100644
index 0000000..ea66467
--- /dev/null
+++ b/src/ManageVars.php
@@ -0,0 +1,147 @@
+ $items The media items */
+ public readonly array $items;
+
+ /** @var array $categories The blog categories list */
+ public readonly array $categories;
+
+ /** @var bool $has_categories Blog has categories */
+ public readonly bool $has_categories;
+
+ /** @var array $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] : '';
+ }
+}
diff --git a/src/Media.php b/src/Media.php
index 551773f..49ec97f 100644
--- a/src/Media.php
+++ b/src/Media.php
@@ -10,7 +10,13 @@
* @copyright Jean-Christian Denis
* @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
protected function isFileExclude(string $file): bool
diff --git a/src/My.php b/src/My.php
new file mode 100644
index 0000000..fb0b458
--- /dev/null
+++ b/src/My.php
@@ -0,0 +1,63 @@
+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, '>=');
+ }
+}
diff --git a/src/Pager.php b/src/Pager.php
index b9d0c3a..cc00e15 100644
--- a/src/Pager.php
+++ b/src/Pager.php
@@ -10,14 +10,24 @@
* @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);
-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();
$fname = $f->basename;
$count = '';
@@ -36,9 +46,9 @@ class templatorPager
$full_name = '';
$cat_parents = dcCore::app()->blog->getCategoryParents($cat_id);
while ($cat_parents->fetch()) {
- $full_name = $cat_parents->cat_title . ' › ';
+ $full_name = $cat_parents->f('cat_title') . ' › ';
};
- $fname = '' . __('Category') . ' : ' . $full_name . dcCore::app()->blog->getCategory($cat_id)->cat_title;
+ $fname = '' . __('Category') . ' : ' . $full_name . $category->f('cat_title');
$params['cat_id'] = $cat_id;
$params['post_type'] = '';
$icon = dcPage::getPF('templator/img/template-alt.png');
@@ -66,18 +76,19 @@ class templatorPager
$params['post_type'] = '';
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', [
'part' => 'posts',
'file' => $fname,
'redir' => dcCore::app()->adminurl->get('admin.plugin.templator', ['part' => 'files']),
]);
- if ($counter->f(0) == 0) {
+ if ($counter == 0) {
$count = __('No entry');
- } elseif ($counter->f(0) == 1) {
- $count = '' . $counter->f(0) . ' ' . __('entry') . '';
+ } elseif ($counter == 1) {
+ $count = '' . $counter . ' ' . __('entry') . '';
} else {
- $count = '' . $counter->f(0) . ' ' . __('entries') . '';
+ $count = '' . $counter . ' ' . __('entries') . '';
}
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
@@ -100,7 +111,7 @@ class templatorPager
$res .= '' . $count . '' .
'' .
$f->media_dtstr . ' - ' .
- files::size($f->size) .
+ Files::size($f->size) .
$details .
'';
}
diff --git a/src/Prepend.php b/src/Prepend.php
index 500167f..44924f1 100644
--- a/src/Prepend.php
+++ b/src/Prepend.php
@@ -10,40 +10,33 @@
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
-if (!defined('DC_RC_PATH')) {
- 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',
-]);
+declare(strict_types=1);
-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']);
- $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
-{
- public static function getDataTpl($w)
- {
- if (dcCore::app()->tpl->getFilePath($w->template)) {
- echo dcCore::app()->tpl->getData($w->template);
+ static::$init = My::phpCompliant();
+
+ return static::$init;
+ }
+
+ public static function process(): bool
+ {
+ if (!static::$init) {
+ return false;
}
+
+ dcCore::app()->auth?->setPermissionType(
+ My::PERMISSION_TEMPLATOR,
+ __('manage templates')
+ );
+
+ return true;
}
}
diff --git a/src/Templator.php b/src/Templator.php
index d381968..289c5a3 100644
--- a/src/Templator.php
+++ b/src/Templator.php
@@ -10,55 +10,116 @@
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
-if (!defined('DC_RC_PATH')) {
- return null;
-}
+declare(strict_types=1);
-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';
- protected $post_default_name = 'post.html';
- protected $page_default_name = 'page.html';
- protected $category_default_name = 'category.html';
+ /** @var string This plugin folder for templates */
+ public const MY_TPL_DIR = 'other-templates';
- public $template_dir_name = 'other-templates';
- public $path;
+ /** @var string The dotclear folder for templates */
+ public const DC_TPL_DIR = 'default-templates';
- public $tpl = [];
- public $theme_tpl = [];
+ /** @var string The themes folder for templates */
+ 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 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()
{
- $this->path = dcCore::app()->blog->public_path . '/' . $this->template_dir_name;
-
- // 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);
+ if (is_null(dcCore::app()->blog)) {
+ throw new Exception(__('Blog is not set'));
}
- $this->user_theme = dcCore::app()->blog->themes_path . '/' . dcCore::app()->blog->settings->system->theme;
- $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);
- $this->user_page_tpl = path::real($this->user_theme . '/tpl/' . $this->page_default_name);
+ $page_root = dcCore::app()->plugins->getDefine('pages')->get('root');
+
+ // Initial templates
+ $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();
}
+ 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
+ */
+ 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 ($create) {
- files::makeDir($this->path);
+ Files::makeDir($this->path);
}
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;
@@ -96,8 +157,8 @@ class dcTemplator
}
return [
- 'c' => file_get_contents($source[$f]),
- 'w' => $this->getDestinationFile($f) !== false,
+ 'c' => (string) file_get_contents($source[$f]),
+ 'w' => !empty($this->getDestinationFile($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;
@@ -117,7 +178,7 @@ class dcTemplator
foreach ($files as $k => $v) {
$li = sprintf('%s', $item);
- $list .= sprintf($li, $k, html::escapeHTML($k));
+ $list .= sprintf($li, $k, Html::escapeHTML($k));
}
return sprintf('', $list);
@@ -126,31 +187,31 @@ class dcTemplator
/**
*
*/
- public function initializeTpl($name, $type)
+ public function initializeTpl(string $name, string $type): void
{
if ($type == 'category') {
- if ($this->user_category_tpl) {
- $base = $this->user_category_tpl;
+ if ($this->user_tpl_category) {
+ $base = $this->user_tpl_category;
} else {
- $base = $this->category_tpl;
+ $base = $this->file_tpl_category;
}
} elseif ($type == 'page') {
- if ($this->user_page_tpl) {
- $base = $this->user_page_tpl;
+ if ($this->user_tpl_page) {
+ $base = $this->user_tpl_page;
} else {
- $base = $this->page_tpl;
+ $base = $this->file_tpl_page;
}
} else {
- if ($this->user_post_tpl) {
- $base = $this->user_post_tpl;
+ if ($this->user_tpl_post) {
+ $base = $this->user_tpl_post;
} else {
- $base = $this->post_tpl;
+ $base = $this->file_tpl_post;
}
}
$source = [
- 'c' => file_get_contents($base),
- 'w' => $this->getDestinationFile($name) !== false,
+ 'c' => (string) file_get_contents($base),
+ 'w' => !empty($this->getDestinationFile($name)),
];
if (!$source['w']) {
@@ -171,7 +232,7 @@ class dcTemplator
$content = $source['c'];
if (!is_dir(dirname($dest))) {
- files::makeDir(dirname($dest));
+ Files::makeDir(dirname($dest));
}
$fp = @fopen($dest, 'wb');
@@ -179,8 +240,8 @@ class dcTemplator
throw new Exception('tocatch');
}
- $content = preg_replace('/(\r?\n)/m', "\n", $content);
- $content = preg_replace('/\r/m', "\n", $content);
+ $content = (string) preg_replace('/(\r?\n)/m', "\n", $content);
+ $content = (string) preg_replace('/\r/m', "\n", $content);
fwrite($fp, $content);
fclose($fp);
@@ -192,7 +253,7 @@ class dcTemplator
/**
*
*/
- public function copypasteTpl($name, $source)
+ public function copypasteTpl(string $name, string $source): void
{
if ($name == $source) {
throw new Exception(__('File already exists.'));
@@ -202,7 +263,7 @@ class dcTemplator
$data = [
'c' => $file['c'],
- 'w' => $this->getDestinationFile($name) !== false,
+ 'w' => !empty($this->getDestinationFile($name)),
];
if (!$data['w']) {
@@ -219,7 +280,7 @@ class dcTemplator
$content = $data['c'];
if (!is_dir(dirname($dest))) {
- files::makeDir(dirname($dest));
+ Files::makeDir(dirname($dest));
}
$fp = @fopen($dest, 'wb');
@@ -227,8 +288,8 @@ class dcTemplator
throw new Exception('tocatch');
}
- $content = preg_replace('/(\r?\n)/m', "\n", $content);
- $content = preg_replace('/\r/m', "\n", $content);
+ $content = (string) preg_replace('/(\r?\n)/m', "\n", $content);
+ $content = (string) preg_replace('/\r/m', "\n", $content);
fwrite($fp, $content);
fclose($fp);
@@ -240,7 +301,7 @@ class dcTemplator
/**
*
*/
- public function writeTpl($name, $content)
+ public function writeTpl(string $name, string $content): void
{
try {
$dest = $this->getDestinationFile($name);
@@ -250,16 +311,17 @@ class dcTemplator
}
if (!is_dir(dirname($dest))) {
- files::makeDir(dirname($dest));
+ Files::makeDir(dirname($dest));
}
$fp = @fopen($dest, 'wb');
if (!$fp) {
//throw new Exception('tocatch');
+ return;
}
- $content = preg_replace('/(\r?\n)/m', "\n", $content);
- $content = preg_replace('/\r/m', "\n", $content);
+ $content = (string) preg_replace('/(\r?\n)/m', "\n", $content);
+ $content = (string) preg_replace('/\r/m', "\n", $content);
fwrite($fp, $content);
fclose($fp);
@@ -271,7 +333,7 @@ class dcTemplator
/**
*
*/
- public function copyTpl($name)
+ public function copyTpl(string $name): void
{
try {
$file = $this->getSourceContent($name);
@@ -282,7 +344,7 @@ class dcTemplator
}
if (!is_dir(dirname($dest))) {
- files::makeDir(dirname($dest));
+ Files::makeDir(dirname($dest));
}
$fp = @fopen($dest, 'wb');
@@ -290,7 +352,7 @@ class dcTemplator
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']);
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;
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)) {
@@ -315,27 +380,31 @@ class dcTemplator
return $dest;
}
- return false;
+ return '';
}
- protected function findTemplates()
+ protected function findTemplates(): void
{
$this->tpl = $this->getFilesInDir($this->path);
- //$this->theme_tpl = $this->getFilesInDir(path::real($this->user_theme).'/tpl');
uksort($this->tpl, [$this,'sortFilesHelper']);
- //uksort($this->theme_tpl,array($this,'sortFilesHelper'));
}
- protected function getFilesInDir($dir)
+ /**
+ * @return array
+ */
+ protected function getFilesInDir(string $dir): array
{
- $dir = path::real($dir);
+ $res = [];
+ $dir = Path::real($dir);
if (!$dir || !is_dir($dir) || !is_readable($dir)) {
- return [];
+ return $res;
}
- $d = dir($dir);
- $res = [];
+ $d = dir($dir);
+ if (!$d) {
+ return $res;
+ }
while (($f = $d->read()) !== false) {
if (is_file($dir . '/' . $f) && !preg_match('/^\./', $f)) {
$res[$f] = $dir . '/' . $f;
@@ -345,14 +414,14 @@ class dcTemplator
return $res;
}
- protected function sortFilesHelper($a, $b)
+ protected function sortFilesHelper(string $a, string $b): int
{
if ($a == $b) {
return 0;
}
- $ext_a = files::getExtension($a);
- $ext_b = files::getExtension($b);
+ $ext_a = Files::getExtension($a);
+ $ext_b = Files::getExtension($b);
return strcmp($ext_a . '.' . $a, $ext_b . '.' . $b);
}
diff --git a/src/Widgets.php b/src/Widgets.php
new file mode 100644
index 0000000..4f079a0
--- /dev/null
+++ b/src/Widgets.php
@@ -0,0 +1,59 @@
+ ''];
+ $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')) : '';
+ }
+}