From 326e1a72cf812de9896020c586a06d75038becdd Mon Sep 17 00:00:00 2001 From: Jean-Christian Denis Date: Tue, 25 Apr 2023 18:36:48 +0200 Subject: [PATCH] use namespace --- .../saba_404.html} | 0 .../saba_404.html} | 0 .../{saba_404_default.html => saba_404.html} | 0 src/Backend.php | 93 +++-- src/Frontend.php | 345 ++---------------- src/FrontendBehaviors.php | 225 ++++++++++++ src/My.php | 58 +++ src/Prepend.php | 59 ++- src/UrlHandler.php | 47 +++ src/Utils.php | 90 +++++ src/Widgets.php | 117 +++--- 11 files changed, 620 insertions(+), 414 deletions(-) rename default-templates/{saba_404_dotty.html => dotty/saba_404.html} (100%) rename default-templates/{saba_404_mustek.html => mustek/saba_404.html} (100%) rename default-templates/{saba_404_default.html => saba_404.html} (100%) create mode 100644 src/FrontendBehaviors.php create mode 100644 src/My.php create mode 100644 src/UrlHandler.php create mode 100644 src/Utils.php diff --git a/default-templates/saba_404_dotty.html b/default-templates/dotty/saba_404.html similarity index 100% rename from default-templates/saba_404_dotty.html rename to default-templates/dotty/saba_404.html diff --git a/default-templates/saba_404_mustek.html b/default-templates/mustek/saba_404.html similarity index 100% rename from default-templates/saba_404_mustek.html rename to default-templates/mustek/saba_404.html diff --git a/default-templates/saba_404_default.html b/default-templates/saba_404.html similarity index 100% rename from default-templates/saba_404_default.html rename to default-templates/saba_404.html diff --git a/src/Backend.php b/src/Backend.php index 7279244..bd323e8 100644 --- a/src/Backend.php +++ b/src/Backend.php @@ -10,34 +10,67 @@ * @copyright Jean-Christian Denis * @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html */ -if (!defined('DC_CONTEXT_ADMIN')) { - return; +declare(strict_types=1); + +namespace Dotclear\Plugin\saba; + +use dcCore; +use dcNsProcess; +use dcSettings; +use Dotclear\Helper\Html\Form\{ + Checkbox, + Label, + Para +}; + +class Backend extends dcNsProcess +{ + public static function init(): bool + { + static::$init = defined('DC_CONTEXT_ADMIN') + && My::phpCompliant(); + + return static::$init; + } + + public static function process(): bool + { + if (!static::$init) { + return false; + } + + dcCore::app()->addBehaviors([ + // add blog preferences form + 'adminBlogPreferencesFormV2' => function (dcSettings $blog_settings): void { + echo + '
' . + '

' . __('Search Across Blog Archive') . '

' . + + // saba_active + (new Para())->items([ + (new Checkbox('saba_active', (bool) $blog_settings->get(My::id())->get('active')))->value(1), + (new Label(__('Enable advanced search on this blog'), Label::OUTSIDE_LABEL_AFTER))->for('saba_active')->class('classic'), + ])->render() . + // saba_error + (new Para())->items([ + (new Checkbox('saba_error', (bool) $blog_settings->get(My::id())->get('error')))->value(1), + (new Label(__('Enable suggestion for page 404'), Label::OUTSIDE_LABEL_AFTER))->for('saba_error')->class('classic'), + ])->render() . + + '

' . + __('This suggests visitors some posts on page 404.') . + '

' . + '
'; + }, + // save blog preference form + 'adminBeforeBlogSettingsUpdate' => function (dcSettings $blog_settings): void { + $blog_settings->get(My::id())->put('active', !empty($_POST['saba_active'])); + $blog_settings->get(My::id())->put('error', !empty($_POST['saba_error'])); + }, + // init widget + 'initWidgets' => [Widgets::class, 'initWidgets'], + ]); + + return true; + } } - -# settings namespace -dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); - -# widget -require __DIR__ . '/_widgets.php'; - -# behaviors -dcCore::app()->addBehavior('adminBlogPreferencesFormV2', function ($blog_settings) { - echo - '
' . - '

' . __('Search Across Blog Archive') . '

' . - '

' . - '

' . - '

' . - __('This suggests visitors some posts on page 404.') . - '

' . - '
'; -}); - -dcCore::app()->addBehavior('adminBeforeBlogSettingsUpdate', function ($blog_settings) { - $blog_settings->get(basename(__DIR__))->put('active', !empty($_POST['saba_active'])); - $blog_settings->get(basename(__DIR__))->put('error', !empty($_POST['saba_error'])); -}); diff --git a/src/Frontend.php b/src/Frontend.php index 4ed86ef..a77024d 100644 --- a/src/Frontend.php +++ b/src/Frontend.php @@ -10,342 +10,45 @@ * @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); -# setting -dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); +namespace Dotclear\Plugin\saba; -if (!dcCore::app()->blog->settings->get(basename(__DIR__))->get('active')) { - return null; -} +use dcCore; +use dcNsProcess; -# translation -l10n::set(__DIR__ . '/locales/' . dcCore::app()->lang . '/public'); - -# widget -require __DIR__ . '/_widgets.php'; - -# template path -dcCore::app()->tpl->setPath( - dcCore::app()->tpl->getPath(), - __DIR__ . '/default-templates/' -); - -# behavior -dcCore::app()->addBehavior( - 'templateCustomSortByAlias', - ['pubSaba', 'templateCustomSortByAlias'] -); -dcCore::app()->addBehavior( - 'urlHandlerBeforeGetData', - ['pubSaba', 'urlHandlerBeforeGetData'] -); -dcCore::app()->addBehavior( - 'coreBlogBeforeGetPosts', - ['pubSaba', 'coreBlogBeforeGetPosts'] -); - -# url -if (dcCore::app()->blog->settings->get(basename(__DIR__))->get('error')) { - dcCore::app()->url->registerError(['urlSaba', 'error']); -} - -class pubSaba +class Frontend extends dcNsProcess { - public static function templateCustomSortByAlias($alias) + public static function init(): bool { - $alias['post'] = [ - 'title' => 'post_title', - 'selected' => 'post_selected', - 'author' => 'user_id', - 'date' => 'post_dt', - 'update' => 'post_upddt', - 'id' => 'post_id', - 'comment' => 'nb_comment', - 'trackback' => 'nb_trackback', - ]; + static::$init = My::phpCompliant(); + + return static::$init; } - public static function urlHandlerBeforeGetData($_) + public static function process(): bool { - $options = tplSaba::getSabaDefaultPostsOptions(); - - if (!empty($_GET['q']) && 1 < strlen($_GET['q'])) { - # search string - $params = new ArrayObject(['search' => rawurldecode($_GET['q'])]); - - $options = self::getPostsParams($params); - $options['q'] = rawurldecode($_GET['q']); - - # count - dcCore::app()->public->search = rawurldecode($_GET['q']); - if (dcCore::app()->public->search) { - dcCore::app()->public->search_count = dcCore::app()->blog->getPosts($params, true)->f(0); - } - - # pagintaion - $_page_number = dcCore::app()->public->getPageNumber(); - if ($_page_number < 1) { - $_page_number = 1; - } - $params['limit'] = dcCore::app()->ctx->__get('nb_entry_per_page'); - $params['limit'] = [(($_page_number - 1) * $params['limit']), $params['limit']]; - - # get posts - $posts = dcCore::app()->blog->getPosts($params); - if ($posts->isEmpty()) { // hack: don't breack context - $params = ['limit' => $params['limit']]; - $posts = dcCore::app()->blog->getPosts($params); - } - dcCore::app()->ctx->__set('post_params', $params); - dcCore::app()->ctx->__set('posts', $posts); - - unset($params); - } - dcCore::app()->ctx->__set('saba_options', $options); - } - - public static function getPostsParams(&$params) - { - if (!isset($params['sql'])) { - $params['sql'] = ''; + if (!static::$init) { + return false; } - $params['post_type'] = []; - - # retreive _GET - $qs = $_SERVER['QUERY_STRING']; - $qs = preg_replace('#(^|/)page/([0-9]+)#', '', $qs); - parse_str($qs, $get); - - # search string - $options = tplSaba::getSabaDefaultPostsOptions(); - $options['q'] = $params['search']; - - # options - if (!empty($get['q_opt'])) { - if (in_array('selected', $get['q_opt'])) { - $options['q_opt'][] = 'selected'; - $params['post_selected'] = 1; - } - if (in_array('comment', $get['q_opt'])) { - $options['q_opt'][] = 'comment'; - $params['sql'] = 'AND nb_comment > 0 '; - } - if (in_array('trackback', $get['q_opt'])) { - $options['q_opt'][] = 'trackback'; - $params['sql'] = 'AND nb_trackback > 0'; - } + if (is_null(dcCore::app()->blog) || !dcCore::app()->blog->settings->get(My::id())->get('active')) { + return false; } - # categories - if (!empty($get['q_cat'])) { - $cats = []; - foreach ($get['q_cat'] as $v) { - $v = abs((int) $v); - if (!$v) { - continue; - } - $cats[] = "C.cat_id = '" . $v . "'"; - $options['q_cat'][] = $v; - } - if (!empty($cats)) { - $params['sql'] .= 'AND (' . implode(' OR ', $cats) . ') '; - } + if (dcCore::app()->blog->settings->get(My::id())->get('error')) { + dcCore::app()->url->registerError([UrlHandler::class, 'error']); } - # post types - if (!empty($get['q_type'])) { - $types = dcCore::app()->getPostTypes(); - foreach ($get['q_type'] as $v) { - if (!$types[$v]) { - continue; - } - $options['q_type'][] = $v; - $params['post_type'][] = $v; - } - } else { - $params['post_type'][] = 'post'; - } + dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), My::path() . DIRECTORY_SEPARATOR . 'default-templates'); - # age - $ages = tplSaba::getSabaFormAges(); - if (!empty($get['q_age']) && in_array($get['q_age'], $ages)) { - $age = explode(',', $get['q_age']); - $ts = time(); - $options['q_age'] = $get['q_age']; + dcCore::app()->addBehaviors([ + 'templateCustomSortByAlias' => [FrontendBehaviors::class, 'templateCustomSortByAlias'], + 'urlHandlerBeforeGetData' => [FrontendBehaviors::class, 'urlHandlerBeforeGetData'], + 'coreBlogBeforeGetPosts' => [FrontendBehaviors::class, 'coreBlogBeforeGetPosts'], + 'initWidgets' => [Widgets::class, 'initWidgets'], + ]); - if ($age[0]) { - $params['sql'] .= "AND P.post_dt < '" . - dt::str('%Y-%m-%d %H:%m:%S', $ts - (int) $age[0]) . "' "; - } - if ($age[1]) { - $params['sql'] .= "AND P.post_dt > '" . - dt::str('%Y-%m-%d %H:%m:%S', $ts - (int) $age[1]) . "' "; - } - } - - # user - if (!empty($get['q_user'])) { - $users = []; - foreach ($get['q_user'] as $v) { - $users[] = "U.user_id = '" . dcCore::app()->con->escape($v) . "'"; - $options['q_user'][] = $v; - } - if (!empty($users)) { - $params['sql'] .= 'AND (' . implode(' OR ', $users) . ') '; - } - } - - #order - $sort = 'desc'; - if (!empty($get['q_rev'])) { - $options['q_rev'] = '1'; - $sort = 'asc'; - } - $orders = tplSaba::getSabaFormOrders(); - if (!empty($get['q_order']) && in_array($get['q_order'], $orders)) { - $options['q_order'] = $get['q_order']; - $params['order'] = dcCore::app()->tpl->getSortByStr( - new ArrayObject(['sortby' => $get['q_order'], 'order' => $sort]), - 'post' - ); //?! post_type - } - - return $options; - } - - # Ajouter la condition "ou" à la recherche - public static function coreBlogBeforeGetPosts($p) - { - if (empty($p['search'])) { - return; - } - - self::getPostsParams($p); - - $OR = []; - # decoupe un peu plus la recherche - $splits = preg_split("#[\s//,-_]+#", $p['search']); - if (!$splits) { - $splits = explode(',', $p['search']); - } - foreach ($splits as $sentence) { - $AND = []; - $words = text::splitWords($sentence); - foreach ($words as $word) { - $AND[] = "post_words LIKE '%" . dcCore::app()->con->escape($word) . "%'"; - } - if (!empty($AND)) { - $OR[] = ' (' . implode(' AND ', $AND) . ') '; - } - } - if (!empty($OR)) { - $p['search'] = ''; - $p['sql'] .= 'AND (' . implode(' OR ', $OR) . ') '; - } - } -} - -class urlSaba extends dcUrlHandlers -{ - public static function error($args, $type, $e) - { - if ($e->getCode() == 404) { - $q = explode('/', $args); - if (empty($q)) { - return false; - } - - dcCore::app()->callBehavior('sabaBeforeErrorDocument'); - - # Clean URI - $_GET['q'] = implode('%20', $q); - $_SERVER['QUERY_STRING'] = ''; - - # Claim comes from 404 - $GLOBALS['_from_error'] = true; - - # Serve saba - $tplset = dcCore::app()->themes->moduleInfo(dcCore::app()->blog->settings->get('system')->get('theme'), 'tplset'); - self::serveDocument('saba_404_' . (!empty($tplset) && in_array($tplset, ['dotty', 'mustek']) ? $tplset : 'default') . '.html'); - - return true; - } - } -} - -class tplSaba -{ - public static function getSabaDefaultPostsOptions() - { - return [ - 'q' => '', - 'q_opt' => [], - 'q_cat' => [], - 'q_age' => '0,0', - 'q_user' => [], - 'q_order' => 'date', - 'q_rev' => '0', - 'q_type' => [], - ]; - } - - public static function getSabaFormOptions() - { - return [ - __('Selected entry') => 'selected', - __('With comments') => 'comment', - __('With trackbacks') => 'trackback', - ]; - } - - public static function getSabaFormOrders() - { - return [ - __('Title') => 'title', - __('Selected entry') => 'selected', - __('Author') => 'author', - __('Date') => 'date', - __('Update') => 'update', - __('Comments count') => 'comment', - __('Trackbacks count') => 'trackback', - ]; - } - - public static function getSabaFormAges() - { - return [ - __('All') => '0,0', - __('Less than a month') => '0,2592000', - __('From 1 to 6 month') => '2592000,15552000', - __('From 6 to 12 month') => '15552000,31536000', - __('More than a year') => '31536000,0', - ]; - } - - public static function getSabaFormTypes() - { - $know = [ - 'post' => __('Entry'), - 'page' => __('Page'), - 'pollsfactory' => __('Poll'), - 'eventhandler' => __('Event'), - ]; - // todo: add behavior for unknow types - - $rs = []; - $types = dcCore::app()->getPostTypes(); - - foreach ($types as $k => $v) { - if (!$v['public_url']) { - continue; - } - $rs[$know[$k] ?? __($k)] = $k; - } - - return $rs; + return true; } } diff --git a/src/FrontendBehaviors.php b/src/FrontendBehaviors.php new file mode 100644 index 0000000..6d0e11c --- /dev/null +++ b/src/FrontendBehaviors.php @@ -0,0 +1,225 @@ + 'post_title', + 'selected' => 'post_selected', + 'author' => 'user_id', + 'date' => 'post_dt', + 'update' => 'post_upddt', + 'id' => 'post_id', + 'comment' => 'nb_comment', + 'trackback' => 'nb_trackback', + ]; + } + + public static function urlHandlerBeforeGetData(context $_): void + { + if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->ctx)) { + return; + } + + $options = Utils::getSabaDefaultPostsOptions(); + + if (!empty($_GET['q']) && 1 < strlen($_GET['q'])) { + # pagintaion + $_page_number = dcCore::app()->public->getPageNumber(); + if ($_page_number < 1) { + $_page_number = 1; + } + $limit = (int) dcCore::app()->ctx->__get('nb_entry_per_page'); + + $params = [ + 'limit' => [(($_page_number - 1) * $limit), $limit], + 'search' => rawurldecode($_GET['q']), + ]; + + # search string + $params = new ArrayObject($params); + + $options = self::getPostsParams($params); + $options['q'] = rawurldecode($_GET['q']); + + # count + dcCore::app()->public->search = rawurldecode($_GET['q']); + if (dcCore::app()->public->search) { + dcCore::app()->public->search_count = dcCore::app()->blog->getPosts($params, true)->f(0); + } + + # get posts + $posts = dcCore::app()->blog->getPosts($params); + if ($posts->isEmpty()) { // hack: don't breack context + $params = ['limit' => $params['limit']]; + $posts = dcCore::app()->blog->getPosts($params); + } + dcCore::app()->ctx->__set('post_params', $params); + dcCore::app()->ctx->__set('posts', $posts); + + unset($params); + } + dcCore::app()->ctx->__set('saba_options', $options); + } + + public static function getPostsParams(ArrayObject $params): array + { + if (!isset($params['sql'])) { + $params['sql'] = ''; + } + + $params['post_type'] = []; + + # retreive _GET + $qs = $_SERVER['QUERY_STRING']; + $qs = preg_replace('#(^|/)page/([0-9]+)#', '', $qs); + parse_str($qs, $get); + + # search string + $options = Utils::getSabaDefaultPostsOptions(); + $options['q'] = $params['search']; + + # options + if (!empty($get['q_opt']) && is_array($get['q_opt'])) { + if (in_array('selected', $get['q_opt'])) { + $options['q_opt'][] = 'selected'; + $params['post_selected'] = 1; + } + if (in_array('comment', $get['q_opt'])) { + $options['q_opt'][] = 'comment'; + $params['sql'] = 'AND nb_comment > 0 '; + } + if (in_array('trackback', $get['q_opt'])) { + $options['q_opt'][] = 'trackback'; + $params['sql'] = 'AND nb_trackback > 0'; + } + } + + # categories + if (!empty($get['q_cat']) && is_array($get['q_cat'])) { + $cats = []; + foreach ($get['q_cat'] as $v) { + $v = abs((int) $v); + if (!$v) { + continue; + } + $cats[] = "C.cat_id = '" . $v . "'"; + $options['q_cat'][] = $v; + } + if (!empty($cats)) { + $params['sql'] .= 'AND (' . implode(' OR ', $cats) . ') '; + } + } + + # post types + if (!empty($get['q_type']) && is_array($get['q_type'])) { + $types = dcCore::app()->getPostTypes(); + foreach ($get['q_type'] as $v) { + if (!$types[$v]) { + continue; + } + $options['q_type'][] = $v; + $params['post_type'][] = $v; + } + } else { + $params['post_type'][] = 'post'; + } + + # age + $ages = Utils::getSabaFormAges(); + if (!empty($get['q_age']) && is_string($get['q_age']) && in_array($get['q_age'], $ages)) { + $age = explode(',', $get['q_age']); + $ts = time(); + $options['q_age'] = $get['q_age']; + + if ($age[0]) { + $params['sql'] .= "AND P.post_dt < '" . + Date::str('%Y-%m-%d %H:%m:%S', $ts - (int) $age[0]) . "' "; + } + if ($age[1]) { + $params['sql'] .= "AND P.post_dt > '" . + Date::str('%Y-%m-%d %H:%m:%S', $ts - (int) $age[1]) . "' "; + } + } + + # user + if (!empty($get['q_user']) && is_array($get['q_user'])) { + $users = []; + foreach ($get['q_user'] as $v) { + $users[] = "U.user_id = '" . dcCore::app()->con->escapeStr((string) $v) . "'"; + $options['q_user'][] = $v; + } + $params['sql'] .= 'AND (' . implode(' OR ', $users) . ') '; + } + + #order + $sort = 'desc'; + if (!empty($get['q_rev'])) { + $options['q_rev'] = '1'; + $sort = 'asc'; + } + $orders = Utils::getSabaFormOrders(); + if (!empty($get['q_order']) && in_array($get['q_order'], $orders)) { + $options['q_order'] = $get['q_order']; + $params['order'] = dcCore::app()->tpl->getSortByStr( + new ArrayObject(['sortby' => $get['q_order'], 'order' => $sort]), + 'post' + ); //?! post_type + } + + return $options; + } + + # Ajouter la condition "ou" à la recherche + public static function coreBlogBeforeGetPosts(ArrayObject $p): void + { + if (empty($p['search'])) { + return; + } + + self::getPostsParams($p); + + $OR = []; + # decoupe un peu plus la recherche + $splits = preg_split("#[\s//,-_]+#", $p['search']); + if (!$splits) { + $splits = explode(',', $p['search']); + } + foreach ($splits as $sentence) { + $AND = []; + $words = Text::splitWords($sentence); + foreach ($words as $word) { + $AND[] = "post_words LIKE '%" . dcCore::app()->con->escapeStr((string) $word) . "%'"; + } + if (!empty($AND)) { + $OR[] = ' (' . implode(' AND ', $AND) . ') '; + } + } + if (!empty($OR)) { + $p['search'] = ''; + $p['sql'] .= 'AND (' . implode(' OR ', $OR) . ') '; + } + } +} diff --git a/src/My.php b/src/My.php new file mode 100644 index 0000000..6ca72f4 --- /dev/null +++ b/src/My.php @@ -0,0 +1,58 @@ +plugins->moduleInfo(self::id(), 'name')); + } + + /** + * This module root path + */ + public static function path(): string + { + return dirname(__DIR__); + } + + /** + * Check php version + */ + public static function phpCompliant(): bool + { + return version_compare(phpversion(), self::PHP_MIN, '>='); + } +} diff --git a/src/Prepend.php b/src/Prepend.php index 2d17883..65bf8f1 100644 --- a/src/Prepend.php +++ b/src/Prepend.php @@ -10,20 +10,51 @@ * @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); -if (defined('ACTIVITY_REPORT_V2')) { - dcCore::app()->__get('activityReport')->addAction( - 'blog', - 'saba404', - __('404 error (saba)'), - __('New 404 error page at "%s"'), - 'sabaBeforeErrorDocument', - function () { - $logs = [dcCore::app()->blog->url . urldecode($_SERVER['QUERY_STRING'])]; - dcCore::app()->__get('activityReport')->addLog('blog', 'saba404', $logs); +namespace Dotclear\Plugin\saba; + +use dcCore; +use dcNsProcess; +use Dotclear\Plugin\activityReport\{ + Action, + ActivityReport, + Group +}; + +class Prepend extends dcNsProcess +{ + public static function init(): bool + { + static::$init = My::phpCompliant(); + + return static::$init; + } + + public static function process(): bool + { + if (!static::$init) { + return false; } - ); + + // log frontend page 404 intercepted by saba + if (defined('ACTIVITY_REPORT') && ACTIVITY_REPORT == 3) { + $group = new Group(My::id(), My::name()); + $group->add(new Action( + 'saba404', + __('404 error (saba)'), + __('New 404 error page at "%s"'), + 'sabaBeforeErrorDocument', + function () { + $url = is_null(dcCore::app()->blog) ? '' : dcCore::app()->blog->url; + + $logs = [$url . urldecode($_SERVER['QUERY_STRING'])]; + ActivityReport::instance()->addLog(My::id(), 'saba404', $logs); + } + )); + ActivityReport::instance()->groups->add($group); + } + + return true; + } } diff --git a/src/UrlHandler.php b/src/UrlHandler.php new file mode 100644 index 0000000..95a69f4 --- /dev/null +++ b/src/UrlHandler.php @@ -0,0 +1,47 @@ +getCode() == 404) { + $q = explode('/', (string) $args); + if (count($q) < 2) { + return; + } + + dcCore::app()->callBehavior('sabaBeforeErrorDocument'); + + # Clean URI + $_GET['q'] = implode('%20', $q); + $_SERVER['QUERY_STRING'] = ''; + + # Claim comes from 404 + $GLOBALS['_from_error'] = true; + + # Serve saba + self::serveDocument('saba_404.html'); + + # stop here + exit(1); + } + } +} diff --git a/src/Utils.php b/src/Utils.php new file mode 100644 index 0000000..1d5dc13 --- /dev/null +++ b/src/Utils.php @@ -0,0 +1,90 @@ + '', + 'q_opt' => [], + 'q_cat' => [], + 'q_age' => '0,0', + 'q_user' => [], + 'q_order' => 'date', + 'q_rev' => '0', + 'q_type' => [], + ]; + } + + public static function getSabaFormOptions(): array + { + return [ + __('Selected entry') => 'selected', + __('With comments') => 'comment', + __('With trackbacks') => 'trackback', + ]; + } + + public static function getSabaFormOrders(): array + { + return [ + __('Title') => 'title', + __('Selected entry') => 'selected', + __('Author') => 'author', + __('Date') => 'date', + __('Update') => 'update', + __('Comments count') => 'comment', + __('Trackbacks count') => 'trackback', + ]; + } + + public static function getSabaFormAges(): array + { + return [ + __('All') => '0,0', + __('Less than a month') => '0,2592000', + __('From 1 to 6 month') => '2592000,15552000', + __('From 6 to 12 month') => '15552000,31536000', + __('More than a year') => '31536000,0', + ]; + } + + public static function getSabaFormTypes(): array + { + $know = [ + 'post' => __('Entry'), + 'page' => __('Page'), + 'pollsfactory' => __('Poll'), + 'eventhandler' => __('Event'), + ]; + // todo: add behavior for unknow types + + $rs = []; + $types = dcCore::app()->getPostTypes(); + + foreach ($types as $k => $v) { + if (!$v['public_url']) { + continue; + } + $rs[$know[$k] ?? __($k)] = $k; + } + + return $rs; + } +} diff --git a/src/Widgets.php b/src/Widgets.php index 668aea8..60f82f3 100644 --- a/src/Widgets.php +++ b/src/Widgets.php @@ -10,21 +10,30 @@ * @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()->addBehavior('initWidgets', ['sabaWidget', 'setWidget']); +namespace Dotclear\Plugin\saba; -class sabaWidget +use dcCore; +use dcUtils; +use Dotclear\Helper\Html\Html; +use Dotclear\Plugin\widgets\WidgetsStack; +use Dotclear\Plugin\widgets\WidgetsElement; + +class Widgets { - public static function setWidget($w) + /** + * Widget initialisation. + * + * @param WidgetsStack $w WidgetsStack instance + */ + public static function initWidgets(WidgetsStack $w): void { $w ->create( 'saba', __('Advanced search'), - ['sabaWidget', 'getWidget'], + [self::class, 'parseWidget'], null, __('Add more search options on public side') ) @@ -74,31 +83,39 @@ class sabaWidget ->addOffline(); } - public static function getWidget($w) + /** + * Public part for widget + * + * @param WidgetsElement $w WidgetsElement instance + */ + public static function parseWidget(WidgetsElement $w): string { - $s = dcCore::app()->blog->settings->addNamespace(basename(__DIR__)); - - if (!$s->get('active') - || !$s->get('error') && dcCore::app()->url->type == '404' - || $w->offline + if (is_null(dcCore::app()->blog) + || is_null(dcCore::app()->ctx) + || !dcCore::app()->blog->settings->get(My::id())->get('active') + || !dcCore::app()->blog->settings->get(My::id())->get('error') && dcCore::app()->url->type == '404' + || $w->__get('offline') ) { - return; + return ''; } - $saba_options = dcCore::app()->ctx->saba_options ?? tplSaba::getSabaDefaultPostsOptions(); - $res = ''; + $saba_options = dcCore::app()->ctx->__get('saba_options') ?? []; + if (!is_array($saba_options) || empty($saba_options)) { + $saba_options = Utils::getSabaDefaultPostsOptions(); + } + $res = ''; - # advenced search only on search page + # advanced search only on search page if (dcCore::app()->url->type == 'search') { # order - if (!$w->saba_filter_orders) { + if (!$w->__get('saba_filter_orders')) { $ct = ''; - foreach (tplSaba::getSabaFormOrders() as $k => $v) { + foreach (Utils::getSabaFormOrders() as $k => $v) { $ct .= '
  • '; + '/> ' . Html::escapeHTML($k) . ''; } if (!empty($ct)) { $ct .= '
  • '; + '/> ' . Html::escapeHTML($k) . ''; } if (!empty($ct)) { $res .= $w->renderTitle(__('Filter options')) . sprintf('', $ct); @@ -128,14 +145,14 @@ class sabaWidget } # ages - if (!$w->saba_filter_ages) { + if (!$w->__get('saba_filter_ages')) { $ct = ''; - foreach (tplSaba::getSabaFormAges() as $k => $v) { + foreach (Utils::getSabaFormAges() as $k => $v) { $ct .= '
  • '; + '/> ' . Html::escapeHTML($k) . ''; } if (!empty($ct)) { $res .= $w->renderTitle(__('Filter by age')) . sprintf('', $ct); @@ -143,18 +160,18 @@ class sabaWidget } # types - if (!$w->saba_filter_types) { + if (!$w->__get('saba_filter_types')) { $ct = ''; - $rm = explode(',', $w->saba_remove_types); + $rm = explode(',', $w->__get('saba_remove_types')); - foreach (tplSaba::getSabaFormTypes() as $k => $v) { + foreach (Utils::getSabaFormTypes() as $k => $v) { if (in_array($v, $rm)) { continue; } $ct .= '
  • '; + '/> ' . Html::escapeHTML($k) . ''; } if (!empty($ct)) { $res .= $w->renderTitle(__('Filter by type')) . sprintf('', $ct); @@ -162,19 +179,19 @@ class sabaWidget } # categories - if (!$w->saba_filter_categories) { + if (!$w->__get('saba_filter_categories')) { $ct = ''; - $rm = explode(',', $w->saba_remove_categories); + $rm = explode(',', $w->__get('saba_remove_categories')); $rs = dcCore::app()->blog->getCategories(); while ($rs->fetch()) { - if (in_array($rs->cat_id, $rm) || in_array($rs->cat_url, $rm)) { + if (in_array($rs->f('cat_id'), $rm) || in_array($rs->f('cat_url'), $rm)) { continue; } $ct .= '
  • '; + $rs->f('cat_id') . '" ' . + (in_array($rs->f('cat_id'), $saba_options['q_cat']) ? 'checked="checked" ' : '') . + '/> ' . Html::escapeHTML($rs->f('cat_title')) . ''; } if (!empty($ct)) { $res .= $w->renderTitle(__('Filter by category')) . sprintf('', $ct); @@ -182,19 +199,21 @@ class sabaWidget } # authors - if (!$w->saba_filter_authors) { + if (!$w->__get('saba_filter_authors')) { $ct = ''; - $rm = explode(',', $w->saba_remove_authors); + $rm = explode(',', $w->__get('saba_remove_authors')); $rs = dcCore::app()->blog->getPostsUsers(); while ($rs->fetch()) { - if (in_array($rs->user_id, $rm)) { + if (in_array($rs->f('user_id'), $rm)) { continue; } - $ct .= '
  • '; + $ct .= sprintf( + '
  • ', + $rs->f('user_id'), + in_array($rs->f('user_id'), $saba_options['q_user']) ? 'checked="checked" ' : '', + Html::escapeHTML(dcUtils::getUserCN($rs->f('user_id'), $rs->f('user_name'), $rs->f('user_firstname'), $rs->f('user_displayname'))) + ); } if (!empty($ct)) { $res .= $w->renderTitle(__('Filter by author')) . sprintf('', $ct); @@ -203,14 +222,14 @@ class sabaWidget } return $w->renderDiv( - $w->content_only, - $w->class, + (bool) $w->__get('content_only'), + $w->__get('class'), 'id="search"', - ($w->title ? $w->renderTitle('') : '') . + ($w->__get('title') ? $w->renderTitle('') : '') . '
    ' . '

    placeholder ? 'placeholder="' . html::escapeHTML($w->placeholder) . '"' : '') . + Html::escapeHTML($saba_options['q']) . '" ' . + ($w->__get('placeholder') ? 'placeholder="' . Html::escapeHTML($w->__get('placeholder')) . '"' : '') . ' aria-label="' . __('Search') . '"/> ' . '

    ' . $res .