Compare commits

..

No commits in common. "master" and "v2023.08.13" have entirely different histories.

15 changed files with 261 additions and 254 deletions

View File

@ -1,15 +1,3 @@
saba 2023.11.04
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Code review (phpstan)
saba 2023.10.20
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Upgrade to Dotclear 2.28
saba 2023.08.13 saba 2023.08.13
=========================================================== ===========================================================
* Require Dotclear 2.27 * Require Dotclear 2.27

View File

@ -1,23 +1,27 @@
# README # README
[![Release](https://img.shields.io/badge/release-2023.11.04-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/saba/releases) [![Release](https://img.shields.io/badge/release-2023.08.13-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/saba/releases)
![Date](https://img.shields.io/badge/date-2023.11.04-c44d58.svg) [![Date](https://img.shields.io/badge/date-2023.08.13-c44d58.svg)](https://git.dotclear.watch/JcDenis/saba/releases)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.28-137bbb.svg)](https://fr.dotclear.org/download) [![Dotclear](https://img.shields.io/badge/dotclear-v2.27-137bbb.svg)](https://fr.dotclear.org/download)
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/saba) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/saba)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/saba/src/branch/master/LICENSE) [![License](https://img.shields.io/github/license/JcDenis/saba)](https://git.dotclear.watch/JcDenis/saba/blob/master/LICENSE)
## ABOUT ## WHAT IS SABA ?
_saba_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org). _saba_ : Search Across Blog's Archive is a plugins for the open-source
web publishing software called Dotclear.
> Replace public search page and 404 page by a custom page that show related entries to visitor. It replaces public search page and 404 page by a custom page that
show related entries to visitor.
## REQUIREMENTS ## REQUIREMENTS
* Dotclear 2.28 _saba_ requires:
* PHP 8.1
* administrator permissions
* Dotclear 2.27
* PHP 7.4
* Custom templates if default theme is not used. * Custom templates if default theme is not used.
* Dotclear administrator permissions
## USAGE ## USAGE
@ -33,13 +37,12 @@ You can find exemple in plugins/saba/default-tempaltes.
## MORE ## MORE
* [License](https://git.dotclear.watch/JcDenis/saba/src/branch/master/LICENSE) * License : [GNU GPL v2](https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html)
* [Packages & details](https://git.dotclear.watch/JcDenis/saba/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/saba)) * Source & contribution : [Gitea Page](https://git.dotclear.watch/JcDenis/saba) or [GitHub Page](https://github.com/JcDenis/saba)
* [Sources & contributions](https://git.dotclear.watch/JcDenis/saba) (or on [GitHub](https://github.com/JcDenis/saba)) * Packages & details: [Gitea Page](https://git.dotclear.watch/JcDenis/saba/releases) or [Dotaddict Page](https://plugins.dotaddict.org/dc2/details/saba)
* [Issues & security](https://git.dotclear.watch/JcDenis/saba/issues) (or on [GitHub](https://github.com/JcDenis/saba/issues))
## CONTRIBUTORS ## CONTRIBUTORS
* Jean-Christian Denis (author) * Jean-Christian Denis
You are welcome to contribute to this code. You are welcome to contribute to this code.

View File

@ -1,26 +1,29 @@
<?php <?php
/** /**
* @file * @brief saba, a plugin for Dotclear 2
* @brief The plugin saba definition
* @ingroup saba
* *
* @defgroup saba Plugin saba. * @package Dotclear
* @subpackage Plugin
* *
* Search across blog archive. * @author Jean-Christian Denis and Contributors
* *
* @author 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
*/ */
declare(strict_types=1); if (!defined('DC_RC_PATH')) {
return null;
}
$this->registerModule( $this->registerModule(
'saba', 'saba',
'Search across blog archive', 'Search across blog archive',
'Jean-Christian Denis and Contributors', 'Jean-Christian Denis and Contributors',
'2023.11.04', '2023.08.13',
[ [
'requires' => [['core', '2.28']], 'requires' => [['core', '2.27']],
'permissions' => 'My', 'permissions' => dcCore::app()->auth->makePermissions([
dcCore::app()->auth::PERMISSION_ADMIN,
]),
'type' => 'plugin', 'type' => 'plugin',
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues', 'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues',
'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md', 'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md',

View File

@ -2,11 +2,11 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="saba"> <module id="saba">
<name>saba</name> <name>saba</name>
<version>2023.11.04</version> <version>2023.08.13</version>
<author>Jean-Christian Denis and Contributors</author> <author>Jean-Christian Denis and Contributors</author>
<desc>Search across blog archive</desc> <desc>Search across blog archive</desc>
<file>https://git.dotclear.watch/JcDenis/saba/releases/download/v2023.11.04/plugin-saba.zip</file> <file>https://git.dotclear.watch/JcDenis/saba/releases/download/v2023.08.13/plugin-saba.zip</file>
<da:dcmin>2.28</da:dcmin> <da:dcmin>2.27</da:dcmin>
<da:details>https://git.dotclear.watch/JcDenis/saba/src/branch/master/README.md</da:details> <da:details>https://git.dotclear.watch/JcDenis/saba/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/JcDenis/saba/issues</da:support> <da:support>https://git.dotclear.watch/JcDenis/saba/issues</da:support>
</module> </module>

View File

@ -1,12 +1,19 @@
<?php <?php
/** /**
* @file * @brief saba, a plugin for Dotclear 2
* @brief The plugin saba locales resources
* @ingroup saba
* *
* @author Jean-Christian Denis * @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @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 (!empty($_REQUEST['module']) && $_REQUEST['module'] == 'saba') { if (!defined('DC_RC_PATH')) {
\Dotclear\App::backend()->resources()->set('help', 'core_plugins_conf', __DIR__ . '/help/help.html'); return null;
}
if (!empty($_REQUEST['module']) && $_REQUEST['module'] == 'saba') {
dcCore::app()->resources['help']['core_plugins_conf'] = __DIR__ . '/help/help.html';
} }

View File

@ -1,54 +0,0 @@
<?php
declare(strict_types=1);
namespace Dotclear\Plugin\saba;
use Dotclear\App;
use Dotclear\Core\Process;
use Dotclear\Plugin\activityReport\{
Action,
ActivityReport,
Group
};
/**
* @brief saba plugin activityReport class.
* @ingroup saba
*
* Add 404 to activity report
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class ActivityReportAction extends Process
{
public static function init(): bool
{
return self::status(true);
}
public static function process(): bool
{
if (!self::status()) {
return false;
}
$group = new Group(My::id(), My::name());
$group->add(new Action(
'saba404',
__('404 error (saba)'),
__('New 404 error page at "%s"'),
'sabaBeforeErrorDocument',
function () {
$logs = [App::blog()->url() . urldecode($_SERVER['QUERY_STRING'])];
ActivityReport::instance()->addLog(My::id(), 'saba404', $logs);
}
));
ActivityReport::instance()->groups->add($group);
return true;
}
}

View File

@ -1,25 +1,28 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use Dotclear\App; use dcCore;
use dcSettings;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Helper\Html\Form\{ use Dotclear\Helper\Html\Form\{
Checkbox, Checkbox,
Label, Label,
Para Para
}; };
use Dotclear\Interface\Core\BlogSettingsInterface;
/**
* @brief saba backend class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Backend extends Process class Backend extends Process
{ {
public static function init(): bool public static function init(): bool
@ -33,9 +36,9 @@ class Backend extends Process
return false; return false;
} }
App::behavior()->addBehaviors([ dcCore::app()->addBehaviors([
// add blog preferences form // add blog preferences form
'adminBlogPreferencesFormV2' => function (BlogSettingsInterface $blog_settings): void { 'adminBlogPreferencesFormV2' => function (dcSettings $blog_settings): void {
echo echo
'<div class="fieldset">' . '<div class="fieldset">' .
'<h4 id="saba_params">' . __('Search Across Blog Archive') . '</h4>' . '<h4 id="saba_params">' . __('Search Across Blog Archive') . '</h4>' .
@ -57,12 +60,12 @@ class Backend extends Process
'</div>'; '</div>';
}, },
// save blog preference form // save blog preference form
'adminBeforeBlogSettingsUpdate' => function (BlogSettingsInterface $blog_settings): void { 'adminBeforeBlogSettingsUpdate' => function (dcSettings $blog_settings): void {
$blog_settings->get(My::id())->put('active', !empty($_POST['saba_active'])); $blog_settings->get(My::id())->put('active', !empty($_POST['saba_active']));
$blog_settings->get(My::id())->put('error', !empty($_POST['saba_error'])); $blog_settings->get(My::id())->put('error', !empty($_POST['saba_error']));
}, },
// init widget // init widget
'initWidgets' => Widgets::initWidgets(...), 'initWidgets' => [Widgets::class, 'initWidgets'],
]); ]);
return true; return true;

View File

@ -1,19 +1,22 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use Dotclear\App; use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/**
* @brief saba frontend class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Frontend extends Process class Frontend extends Process
{ {
public static function init(): bool public static function init(): bool
@ -27,21 +30,21 @@ class Frontend extends Process
return false; return false;
} }
if (!My::settings()->get('active')) { if (My::settings()->get('active')) {
return false; return false;
} }
if (My::settings()->get('error')) { if (My::settings()->get('error')) {
App::url()->registerError(UrlHandler::error(...)); dcCore::app()->url->registerError([UrlHandler::class, 'error']);
} }
App::frontend()->template()->appendPath(My::path() . DIRECTORY_SEPARATOR . 'default-templates'); dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), My::path() . DIRECTORY_SEPARATOR . 'default-templates');
App::behavior()->addBehaviors([ dcCore::app()->addBehaviors([
'templateCustomSortByAlias' => FrontendBehaviors::templateCustomSortByAlias(...), 'templateCustomSortByAlias' => [FrontendBehaviors::class, 'templateCustomSortByAlias'],
'urlHandlerBeforeGetData' => FrontendBehaviors::urlHandlerBeforeGetData(...), 'urlHandlerBeforeGetData' => [FrontendBehaviors::class, 'urlHandlerBeforeGetData'],
'coreBlogBeforeGetPosts' => FrontendBehaviors::coreBlogBeforeGetPosts(...), 'coreBlogBeforeGetPosts' => [FrontendBehaviors::class, 'coreBlogBeforeGetPosts'],
'initWidgets' => Widgets::initWidgets(...), 'initWidgets' => [Widgets::class, 'initWidgets'],
]); ]);
return true; return true;

View File

@ -1,28 +1,28 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use ArrayObject; use ArrayObject;
use Dotclear\App; use dcCore;
use Dotclear\Helper\Date; use Dotclear\Helper\Date;
use Dotclear\Helper\Text; use Dotclear\Helper\Text;
use Dotclear\Core\Frontend\Ctx; use context;
/**
* @brief saba frontend behaviors class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class FrontendBehaviors class FrontendBehaviors
{ {
/**
* @param ArrayObject<string, mixed> $alias
*/
public static function templateCustomSortByAlias(ArrayObject $alias): void public static function templateCustomSortByAlias(ArrayObject $alias): void
{ {
$alias['post'] = [ $alias['post'] = [
@ -37,9 +37,9 @@ class FrontendBehaviors
]; ];
} }
public static function urlHandlerBeforeGetData(Ctx $_): void public static function urlHandlerBeforeGetData(context $_): void
{ {
if (!App::blog()->isDefined()) { if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->ctx)) {
return; return;
} }
@ -47,11 +47,11 @@ class FrontendBehaviors
if (!empty($_GET['q']) && 1 < strlen($_GET['q'])) { if (!empty($_GET['q']) && 1 < strlen($_GET['q'])) {
# pagintaion # pagintaion
$_page_number = App::frontend()->getPageNumber(); $_page_number = dcCore::app()->public->getPageNumber();
if ($_page_number < 1) { if ($_page_number < 1) {
$_page_number = 1; $_page_number = 1;
} }
$limit = (int) App::frontend()->context()->__get('nb_entry_per_page'); $limit = (int) dcCore::app()->ctx->__get('nb_entry_per_page');
$params = [ $params = [
'limit' => [(($_page_number - 1) * $limit), $limit], 'limit' => [(($_page_number - 1) * $limit), $limit],
@ -65,30 +65,25 @@ class FrontendBehaviors
$options['q'] = rawurldecode($_GET['q']); $options['q'] = rawurldecode($_GET['q']);
# count # count
App::frontend()->search = rawurldecode($_GET['q']); dcCore::app()->public->search = rawurldecode($_GET['q']);
if (App::frontend()->search) { if (dcCore::app()->public->search) {
App::frontend()->search_count = App::blog()->getPosts($params, true)->f(0); dcCore::app()->public->search_count = dcCore::app()->blog->getPosts($params, true)->f(0);
} }
# get posts # get posts
$posts = App::blog()->getPosts($params); $posts = dcCore::app()->blog->getPosts($params);
if ($posts->isEmpty()) { // hack: don't breack context if ($posts->isEmpty()) { // hack: don't breack context
$params = ['limit' => $params['limit']]; $params = ['limit' => $params['limit']];
$posts = App::blog()->getPosts($params); $posts = dcCore::app()->blog->getPosts($params);
} }
App::frontend()->context()->__set('post_params', $params); dcCore::app()->ctx->__set('post_params', $params);
App::frontend()->context()->__set('posts', $posts); dcCore::app()->ctx->__set('posts', $posts);
unset($params); unset($params);
} }
App::frontend()->context()->__set('saba_options', $options); dcCore::app()->ctx->__set('saba_options', $options);
} }
/**
* @param ArrayObject<string, mixed> $params
*
* @return array<string, mixed>
*/
public static function getPostsParams(ArrayObject $params): array public static function getPostsParams(ArrayObject $params): array
{ {
if (!isset($params['sql'])) { if (!isset($params['sql'])) {
@ -99,7 +94,7 @@ class FrontendBehaviors
# retreive _GET # retreive _GET
$qs = $_SERVER['QUERY_STRING']; $qs = $_SERVER['QUERY_STRING'];
$qs = (string) preg_replace('#(^|/)page/([0-9]+)#', '', $qs); $qs = preg_replace('#(^|/)page/([0-9]+)#', '', $qs);
parse_str($qs, $get); parse_str($qs, $get);
# search string # search string
@ -140,7 +135,7 @@ class FrontendBehaviors
# post types # post types
if (!empty($get['q_type']) && is_array($get['q_type'])) { if (!empty($get['q_type']) && is_array($get['q_type'])) {
$types = App::postTypes()->getPostTypes(); $types = dcCore::app()->getPostTypes();
foreach ($get['q_type'] as $v) { foreach ($get['q_type'] as $v) {
if (!$types[$v]) { if (!$types[$v]) {
continue; continue;
@ -173,7 +168,7 @@ class FrontendBehaviors
if (!empty($get['q_user']) && is_array($get['q_user'])) { if (!empty($get['q_user']) && is_array($get['q_user'])) {
$users = []; $users = [];
foreach ($get['q_user'] as $v) { foreach ($get['q_user'] as $v) {
$users[] = "U.user_id = '" . App::con()->escapeStr((string) $v) . "'"; $users[] = "U.user_id = '" . dcCore::app()->con->escapeStr((string) $v) . "'";
$options['q_user'][] = $v; $options['q_user'][] = $v;
} }
$params['sql'] .= 'AND (' . implode(' OR ', $users) . ') '; $params['sql'] .= 'AND (' . implode(' OR ', $users) . ') ';
@ -188,7 +183,7 @@ class FrontendBehaviors
$orders = Utils::getSabaFormOrders(); $orders = Utils::getSabaFormOrders();
if (!empty($get['q_order']) && in_array($get['q_order'], $orders)) { if (!empty($get['q_order']) && in_array($get['q_order'], $orders)) {
$options['q_order'] = $get['q_order']; $options['q_order'] = $get['q_order'];
$params['order'] = App::frontend()->template()->getSortByStr( $params['order'] = dcCore::app()->tpl->getSortByStr(
new ArrayObject(['sortby' => $get['q_order'], 'order' => $sort]), new ArrayObject(['sortby' => $get['q_order'], 'order' => $sort]),
'post' 'post'
); //?! post_type ); //?! post_type
@ -197,11 +192,7 @@ class FrontendBehaviors
return $options; return $options;
} }
/** # Ajouter la condition "ou" à la recherche
* Ajouter la condition "ou" à la recherche.
*
* @param ArrayObject<string, mixed> $p
*/
public static function coreBlogBeforeGetPosts(ArrayObject $p): void public static function coreBlogBeforeGetPosts(ArrayObject $p): void
{ {
if (empty($p['search'])) { if (empty($p['search'])) {
@ -220,7 +211,7 @@ class FrontendBehaviors
$AND = []; $AND = [];
$words = Text::splitWords($sentence); $words = Text::splitWords($sentence);
foreach ($words as $word) { foreach ($words as $word) {
$AND[] = "post_words LIKE '%" . App::con()->escapeStr((string) $word) . "%'"; $AND[] = "post_words LIKE '%" . dcCore::app()->con->escapeStr((string) $word) . "%'";
} }
if (!empty($AND)) { if (!empty($AND)) {
$OR[] = ' (' . implode(' AND ', $AND) . ') '; $OR[] = ' (' . implode(' AND ', $AND) . ') ';

View File

@ -1,5 +1,15 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
@ -7,13 +17,8 @@ namespace Dotclear\Plugin\saba;
use Dotclear\Module\MyPlugin; use Dotclear\Module\MyPlugin;
/** /**
* @brief saba My helper. * This module definitions.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class My extends MyPlugin class My extends MyPlugin
{ {
// Use default permissions
} }

58
src/Prepend.php Normal file
View File

@ -0,0 +1,58 @@
<?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis 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\saba;
use dcCore;
use Dotclear\Core\Process;
use Dotclear\Plugin\activityReport\{
Action,
ActivityReport,
Group
};
class Prepend extends Process
{
public static function init(): bool
{
return self::status(My::checkContext(My::PREPEND));
}
public static function process(): bool
{
if (!self::status()) {
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;
}
}

View File

@ -1,19 +1,23 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Plugin\Uninstaller\Uninstaller; use Dotclear\Plugin\Uninstaller\Uninstaller;
/**
* @brief saba uninstall class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Uninstall extends Process class Uninstall extends Process
{ {
public static function init(): bool public static function init(): bool
@ -23,7 +27,7 @@ class Uninstall extends Process
public static function process(): bool public static function process(): bool
{ {
if (!self::status()) { if (!self::status() || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
return false; return false;
} }

View File

@ -1,21 +1,24 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use Dotclear\App; use dcCore;
use Dotclear\Core\Frontend\Url; use dcUrlHandlers;
use Exception; use Exception;
/** class UrlHandler extends dcUrlHandlers
* @brief saba frontend URL handler class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class UrlHandler extends Url
{ {
public static function error(?string $args, string $type, Exception $e): void public static function error(?string $args, string $type, Exception $e): void
{ {
@ -25,7 +28,7 @@ class UrlHandler extends Url
return; return;
} }
App::behavior()->callBehavior('sabaBeforeErrorDocument'); dcCore::app()->callBehavior('sabaBeforeErrorDocument');
# Clean URI # Clean URI
$_GET['q'] = implode('%20', $q); $_GET['q'] = implode('%20', $q);

View File

@ -1,23 +1,23 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use Dotclear\App; use dcCore;
/**
* @brief saba utils class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Utils class Utils
{ {
/**
* @return array<string, mixed>
*/
public static function getSabaDefaultPostsOptions(): array public static function getSabaDefaultPostsOptions(): array
{ {
return [ return [
@ -32,9 +32,6 @@ class Utils
]; ];
} }
/**
* @return array<string, string>
*/
public static function getSabaFormOptions(): array public static function getSabaFormOptions(): array
{ {
return [ return [
@ -44,9 +41,6 @@ class Utils
]; ];
} }
/**
* @return array<string, string>
*/
public static function getSabaFormOrders(): array public static function getSabaFormOrders(): array
{ {
return [ return [
@ -60,9 +54,6 @@ class Utils
]; ];
} }
/**
* @return array<string, string>
*/
public static function getSabaFormAges(): array public static function getSabaFormAges(): array
{ {
return [ return [
@ -74,9 +65,6 @@ class Utils
]; ];
} }
/**
* @return array<string, string>
*/
public static function getSabaFormTypes(): array public static function getSabaFormTypes(): array
{ {
$know = [ $know = [
@ -88,7 +76,7 @@ class Utils
// todo: add behavior for unknow types // todo: add behavior for unknow types
$rs = []; $rs = [];
$types = App::postTypes()->getPostTypes(); $types = dcCore::app()->getPostTypes();
foreach ($types as $k => $v) { foreach ($types as $k => $v) {
if (!$v['public_url']) { if (!$v['public_url']) {

View File

@ -1,21 +1,25 @@
<?php <?php
/**
* @brief saba, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and Contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1); declare(strict_types=1);
namespace Dotclear\Plugin\saba; namespace Dotclear\Plugin\saba;
use Dotclear\App; use dcCore;
use dcUtils;
use Dotclear\Helper\Html\Html; use Dotclear\Helper\Html\Html;
use Dotclear\Plugin\widgets\WidgetsStack; use Dotclear\Plugin\widgets\WidgetsStack;
use Dotclear\Plugin\widgets\WidgetsElement; use Dotclear\Plugin\widgets\WidgetsElement;
/**
* @brief saba widgets class.
* @ingroup saba
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Widgets class Widgets
{ {
/** /**
@ -29,7 +33,7 @@ class Widgets
->create( ->create(
'saba', 'saba',
__('Advanced search'), __('Advanced search'),
self::parseWidget(...), [self::class, 'parseWidget'],
null, null,
__('Add more search options on public side') __('Add more search options on public side')
) )
@ -86,22 +90,23 @@ class Widgets
*/ */
public static function parseWidget(WidgetsElement $w): string public static function parseWidget(WidgetsElement $w): string
{ {
if (!App::blog()->isDefined() if (is_null(dcCore::app()->blog)
|| !App::blog()->settings()->get(My::id())->get('active') || is_null(dcCore::app()->ctx)
|| !App::blog()->settings()->get(My::id())->get('error') && App::url()->type == '404' || !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') || $w->__get('offline')
) { ) {
return ''; return '';
} }
$saba_options = App::frontend()->context()->__get('saba_options') ?? []; $saba_options = dcCore::app()->ctx->__get('saba_options') ?? [];
if (!is_array($saba_options) || empty($saba_options)) { if (!is_array($saba_options) || empty($saba_options)) {
$saba_options = Utils::getSabaDefaultPostsOptions(); $saba_options = Utils::getSabaDefaultPostsOptions();
} }
$res = ''; $res = '';
# advanced search only on search page # advanced search only on search page
if (App::url()->type == 'search') { if (dcCore::app()->url->type == 'search') {
# order # order
if (!$w->__get('saba_filter_orders')) { if (!$w->__get('saba_filter_orders')) {
$ct = ''; $ct = '';
@ -110,7 +115,7 @@ class Widgets
$ct .= '<li><label><input name="q_order" type="radio" value="' . $ct .= '<li><label><input name="q_order" type="radio" value="' .
$v . '" ' . $v . '" ' .
($v == $saba_options['q_order'] ? 'checked="checked" ' : '') . ($v == $saba_options['q_order'] ? 'checked="checked" ' : '') .
'/> ' . Html::escapeHTML((string) $k) . '</label></li>'; '/> ' . Html::escapeHTML($k) . '</label></li>';
} }
if (!empty($ct)) { if (!empty($ct)) {
$ct .= '<li><label><input name="q_rev" type="checkbox" value="1" ' . $ct .= '<li><label><input name="q_rev" type="checkbox" value="1" ' .
@ -132,7 +137,7 @@ class Widgets
$ct .= '<li><label><input name="q_opt[]" type="checkbox" value="' . $ct .= '<li><label><input name="q_opt[]" type="checkbox" value="' .
$v . '" ' . $v . '" ' .
(in_array($v, $saba_options['q_opt']) ? 'checked="checked" ' : '') . (in_array($v, $saba_options['q_opt']) ? 'checked="checked" ' : '') .
'/> ' . Html::escapeHTML((string) $k) . '</label></li>'; '/> ' . Html::escapeHTML($k) . '</label></li>';
} }
if (!empty($ct)) { if (!empty($ct)) {
$res .= $w->renderTitle(__('Filter options')) . sprintf('<ul>%s</ul>', $ct); $res .= $w->renderTitle(__('Filter options')) . sprintf('<ul>%s</ul>', $ct);
@ -147,7 +152,7 @@ class Widgets
$ct .= '<li><label><input name="q_age" type="radio" value="' . $ct .= '<li><label><input name="q_age" type="radio" value="' .
$v . '" ' . $v . '" ' .
($v == $saba_options['q_age'] ? 'checked="checked" ' : '') . ($v == $saba_options['q_age'] ? 'checked="checked" ' : '') .
'/> ' . Html::escapeHTML((string) $k) . '</label></li>'; '/> ' . Html::escapeHTML($k) . '</label></li>';
} }
if (!empty($ct)) { if (!empty($ct)) {
$res .= $w->renderTitle(__('Filter by age')) . sprintf('<ul>%s</ul>', $ct); $res .= $w->renderTitle(__('Filter by age')) . sprintf('<ul>%s</ul>', $ct);
@ -166,7 +171,7 @@ class Widgets
$ct .= '<li><label><input name="q_type[]" type="checkbox" value="' . $ct .= '<li><label><input name="q_type[]" type="checkbox" value="' .
$v . '" ' . $v . '" ' .
(in_array($v, $saba_options['q_type']) ? 'checked="checked" ' : '') . (in_array($v, $saba_options['q_type']) ? 'checked="checked" ' : '') .
'/> ' . Html::escapeHTML((string) $k) . '</label></li>'; '/> ' . Html::escapeHTML($k) . '</label></li>';
} }
if (!empty($ct)) { if (!empty($ct)) {
$res .= $w->renderTitle(__('Filter by type')) . sprintf('<ul>%s</ul>', $ct); $res .= $w->renderTitle(__('Filter by type')) . sprintf('<ul>%s</ul>', $ct);
@ -177,7 +182,7 @@ class Widgets
if (!$w->__get('saba_filter_categories')) { if (!$w->__get('saba_filter_categories')) {
$ct = ''; $ct = '';
$rm = explode(',', $w->__get('saba_remove_categories')); $rm = explode(',', $w->__get('saba_remove_categories'));
$rs = App::blog()->getCategories(); $rs = dcCore::app()->blog->getCategories();
while ($rs->fetch()) { while ($rs->fetch()) {
if (in_array($rs->f('cat_id'), $rm) || in_array($rs->f('cat_url'), $rm)) { if (in_array($rs->f('cat_id'), $rm) || in_array($rs->f('cat_url'), $rm)) {
@ -186,7 +191,7 @@ class Widgets
$ct .= '<li><label><input name="q_cat[]" type="checkbox" value="' . $ct .= '<li><label><input name="q_cat[]" type="checkbox" value="' .
$rs->f('cat_id') . '" ' . $rs->f('cat_id') . '" ' .
(in_array($rs->f('cat_id'), $saba_options['q_cat']) ? 'checked="checked" ' : '') . (in_array($rs->f('cat_id'), $saba_options['q_cat']) ? 'checked="checked" ' : '') .
'/> ' . Html::escapeHTML((string) $rs->f('cat_title')) . '</label></li>'; '/> ' . Html::escapeHTML($rs->f('cat_title')) . '</label></li>';
} }
if (!empty($ct)) { if (!empty($ct)) {
$res .= $w->renderTitle(__('Filter by category')) . sprintf('<ul>%s</ul>', $ct); $res .= $w->renderTitle(__('Filter by category')) . sprintf('<ul>%s</ul>', $ct);
@ -197,7 +202,7 @@ class Widgets
if (!$w->__get('saba_filter_authors')) { if (!$w->__get('saba_filter_authors')) {
$ct = ''; $ct = '';
$rm = explode(',', $w->__get('saba_remove_authors')); $rm = explode(',', $w->__get('saba_remove_authors'));
$rs = App::blog()->getPostsUsers(); $rs = dcCore::app()->blog->getPostsUsers();
while ($rs->fetch()) { while ($rs->fetch()) {
if (in_array($rs->f('user_id'), $rm)) { if (in_array($rs->f('user_id'), $rm)) {
@ -207,7 +212,7 @@ class Widgets
'<li><label><input name="q_user[]" type="checkbox" value="%s" %s/> %s</label></li>', '<li><label><input name="q_user[]" type="checkbox" value="%s" %s/> %s</label></li>',
$rs->f('user_id'), $rs->f('user_id'),
in_array($rs->f('user_id'), $saba_options['q_user']) ? 'checked="checked" ' : '', in_array($rs->f('user_id'), $saba_options['q_user']) ? 'checked="checked" ' : '',
Html::escapeHTML(App::users()->getUserCN($rs->f('user_id'), $rs->f('user_name'), $rs->f('user_firstname'), $rs->f('user_displayname'))) Html::escapeHTML(dcUtils::getUserCN($rs->f('user_id'), $rs->f('user_name'), $rs->f('user_firstname'), $rs->f('user_displayname')))
); );
} }
if (!empty($ct)) { if (!empty($ct)) {
@ -221,7 +226,7 @@ class Widgets
$w->__get('class'), $w->__get('class'),
'id="search"', 'id="search"',
($w->__get('title') ? $w->renderTitle('<label for="q">' . Html::escapeHTML($w->__get('title')) . '</label>') : '') . ($w->__get('title') ? $w->renderTitle('<label for="q">' . Html::escapeHTML($w->__get('title')) . '</label>') : '') .
'<form action="' . App::blog()->url() . '" method="get" role="search">' . '<form action="' . dcCore::app()->blog->url . '" method="get" role="search">' .
'<p><input type="text" size="10" maxlength="255" id="q" name="q" value="' . '<p><input type="text" size="10" maxlength="255" id="q" name="q" value="' .
Html::escapeHTML($saba_options['q']) . '" ' . Html::escapeHTML($saba_options['q']) . '" ' .
($w->__get('placeholder') ? 'placeholder="' . Html::escapeHTML($w->__get('placeholder')) . '"' : '') . ($w->__get('placeholder') ? 'placeholder="' . Html::escapeHTML($w->__get('placeholder')) . '"' : '') .