use namespace

master
Jean-Christian Paul Denis 2023-04-26 23:09:13 +02:00
parent ecad82c664
commit 774d719de5
Signed by: JcDenis
GPG Key ID: 1B5B8C5B90B6C951
10 changed files with 726 additions and 472 deletions

View File

@ -54,14 +54,14 @@
<nav class="pagination" aria-label="{{tpl:lang Pagination}}" role="navigation">
<tpl:Block name="_pagination-content-prev">
<tpl:ComListePaginationIf end="0">
<a href="{{tpl:ComListePaginationURL offset="+1"}}" class="prev"><span aria-hidden="true">&#171; </span>{{tpl:lang previous entries}}</a> -
<a href="{{tpl:ComListePaginationURL offset="+1"}}" class="prev"><span aria-hidden="true">&#171; </span>{{tpl:lang previous entries}}</a>
</tpl:ComListePaginationIf>
</tpl:Block>
<tpl:Block name="_pagination-content-current">
<span class="visually-hidden">{{tpl:lang Active page}}</span>{{tpl:lang page}} {{tpl:ComListePaginationCurrent}} {{tpl:lang of}} {{tpl:ComListePaginationCounter}}
</tpl:Block>
<tpl:Block name="_pagination-content-next">
<tpl:ComListePaginationIf start="0"> - <a href="{{tpl:ComListePaginationURL offset="-1"}}" class="next">
<tpl:ComListePaginationIf start="0"> <a href="{{tpl:ComListePaginationURL offset="-1"}}" class="next">
{{tpl:lang next entries}}<span aria-hidden="true"> &#187;</span></a>
</tpl:ComListePaginationIf>
</tpl:Block>

View File

@ -10,40 +10,75 @@
* @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);
require __DIR__ . '/_widgets.php';
namespace Dotclear\Plugin\comListe;
// Admin menu
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
__('Comments list'),
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
urldecode(dcPage::getPF(basename(__DIR__) . '/icon.png')),
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_ADMIN]), dcCore::app()->blog->id)
);
use ArrayObject;
use dcAdmin;
use dcCore;
use dcPage;
use dcFavorites;
use dcNsProcess;
dcCore::app()->addBehaviors([
// Dashboard favorites
'adminDashboardFavoritesV2' => function (dcFavorites $favs) {
$favs->register(basename(__DIR__), [
'title' => __('Comments list'),
'url' => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
'small-icon' => urldecode(dcPage::getPF(basename(__DIR__) . '/icon.png')),
'large-icon' => urldecode(dcPage::getPF(basename(__DIR__) . '/icon-big.png')),
'permissions' => dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_ADMIN]),
]);
},
'adminSimpleMenuAddType' => function (ArrayObject $items) {
$items[basename(__DIR__)] = new ArrayObject([__('Comments list'), false]);
},
'adminSimpleMenuBeforeEdit' => function ($type, $select, &$item) {
if (basename(__DIR__) == $type) {
$item[0] = __('Comments list');
$item[1] = dcCore::app()->blog->settings->get(basename(__DIR__))->get('page_title') ?? __('Comments list');
$item[2] = dcCore::app()->admin->__get('blog_url') . dcCore::app()->url->getURLFor(basename(__DIR__));
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;
}
},
]);
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->auth) || is_null(dcCore::app()->adminurl)) {
return false;
}
// Admin menu
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
My::name(),
dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
dcPage::getPF(My::id() . '/icon.png'),
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcCore::app()->auth::PERMISSION_ADMIN]), dcCore::app()->blog->id)
);
dcCore::app()->addBehaviors([
// Dashboard favorites
'adminDashboardFavoritesV2' => function (dcFavorites $favs): void {
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->adminurl)) {
return;
}
$favs->register(My::id(), [
'title' => My::name(),
'url' => dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
'small-icon' => dcPage::getPF(My::id() . '/icon.png'),
'large-icon' => dcPage::getPF(My::id() . '/icon-big.png'),
'permissions' => dcCore::app()->auth->makePermissions([dcCore::app()->auth::PERMISSION_ADMIN]),
]);
},
'adminSimpleMenuAddType' => function (ArrayObject $items): void {
$items[My::id()] = new ArrayObject([My::name(), false]);
},
'adminSimpleMenuBeforeEdit' => function (string $type, string $select, array &$item): void {
if (is_null(dcCore::app()->blog)) {
return;
}
if (My::id() == $type) {
$item[0] = My::name();
$item[1] = dcCore::app()->blog->settings->get(My::id())->get('page_title') ?? My::name();
$item[2] = dcCore::app()->admin->__get('blog_url') . dcCore::app()->url->getURLFor(My::id());
}
},
]);
return true;
}
}

View File

@ -10,316 +10,62 @@
* @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 (!dcCore::app()->blog->settings->get(basename(__DIR__))->get('enable')) {
return null;
}
namespace Dotclear\Plugin\comListe;
require __DIR__ . '/_widgets.php';
use dcCore;
use dcNsProcess;
dcCore::app()->tpl->addValue('ComListeURL', [tplComListe::class,'comListeURL']);
dcCore::app()->tpl->addValue('ComListePageTitle', [tplComListe::class,'comListePageTitle']);
dcCore::app()->tpl->addValue('ComListeNbComments', [tplComListe::class,'comListeNbComments']);
dcCore::app()->tpl->addValue('ComListeNbCommentsPerPage', [tplComListe::class,'comListeNbCommentsPerPage']);
dcCore::app()->tpl->addBlock('ComListeCommentsEntries', [tplComListe::class,'comListeCommentsEntries']);
dcCore::app()->tpl->addValue('ComListePaginationLinks', [tplComListe::class,'comListePaginationLinks']);
dcCore::app()->tpl->addValue('ComListeOpenPostTitle', [tplComListe::class,'comListeOpenPostTitle']);
dcCore::app()->tpl->addValue('ComListeCommentOrderNumber', [tplComListe::class,'comListeCommentOrderNumber']);
dcCore::app()->tpl->addBlock('ComListePagination', [tplComListe::class,'comListePagination']);
dcCore::app()->tpl->addValue('ComListePaginationCounter', [tplComListe::class,'comListePaginationCounter']);
dcCore::app()->tpl->addValue('ComListePaginationCurrent', [tplComListe::class,'comListePaginationCurrent']);
dcCore::app()->tpl->addBlock('ComListePaginationIf', [tplComListe::class,'comListePaginationIf']);
dcCore::app()->tpl->addValue('ComListePaginationURL', [tplComListe::class,'comListePaginationURL']);
dcCore::app()->addBehaviors([
'publicBreadcrumb' => function ($context, $separator) {
if ($context == 'comListe') {
return __('Comments list');
}
},
]);
class tplComListe
class Frontend extends dcNsProcess
{
public $html_prev = '&#171;prev.';
public $html_next = 'next&#187;';
/* ComListeURL --------------------------------------- */
public static function comListeURL($attr)
public static function init(): bool
{
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'dcCore::app()->blog->url.dcCore::app()->url->getBase("comListe")') . '; ?>';
static::$init = My::phpCompliant();
return static::$init;
}
/* ComListePageTitle --------------------------------------- */
public static function comListePageTitle($attr)
public static function process(): bool
{
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'dcCore::app()->blog->settings->get("' . basename(__DIR__) . '")->get("page_title")') . '; ?>';
}
/* ComListeNbCommentsPerPage --------------------------------------- */
public static function comListeNbCommentsPerPage($attr)
{
dcCore::app()->ctx->__set('nb_comment_per_page', (int) dcCore::app()->blog->settings->get(basename(__DIR__))->get('nb_comments_per_page'));
return html::escapeHTML((string) dcCore::app()->ctx->__get('nb_comment_per_page'));
}
/* comListeNbComments --------------------------------------- */
public static function comListeNbComments($attr)
{
if (!dcCore::app()->ctx->exists('pagination')) {
dcCore::app()->ctx->__set('pagination', dcCore::app()->blog->getComments([], true));
}
$nb_comments = dcCore::app()->ctx->__get('pagination')->f(0);
return html::escapeHTML((string) $nb_comments);
}
/* ComListeCommentsEntries --------------------------------------- */
public static function comListeCommentsEntries($attr, $content)
{
$p = 'if (dcCore::app()->ctx->posts !== null) { ' .
"\$params['post_id'] = dcCore::app()->ctx->posts->post_id; " .
"dcCore::app()->blog->withoutPassword(false);\n" .
"}\n";
if (empty($attr['with_pings'])) {
$p .= "\$params['comment_trackback'] = false;\n";
if (!static::$init) {
return false;
}
$lastn = 0;
if (isset($attr['lastn'])) {
$lastn = abs((int) $attr['lastn']) + 0;
if (is_null(dcCore::app()->blog)) {
return false;
}
if ($lastn > 0) {
$p .= "\$params['limit'] = " . $lastn . ";\n";
} else {
$p .= "if (dcCore::app()->ctx->nb_comment_per_page !== null) { \$params['limit'] = dcCore::app()->ctx->nb_comment_per_page; }\n";
if (!dcCore::app()->blog->settings->get(My::id())->get('enable')) {
return false;
}
$p .= "\$params['limit'] = array(((dcCore::app()->public->getPageNumber()-1)*\$params['limit']),\$params['limit']);\n";
dcCore::app()->tpl->addValue('ComListeURL', [Template::class,'comListeURL']);
dcCore::app()->tpl->addValue('ComListePageTitle', [Template::class,'comListePageTitle']);
dcCore::app()->tpl->addValue('ComListeNbComments', [Template::class,'comListeNbComments']);
dcCore::app()->tpl->addValue('ComListeNbCommentsPerPage', [Template::class,'comListeNbCommentsPerPage']);
dcCore::app()->tpl->addBlock('ComListeCommentsEntries', [Template::class,'comListeCommentsEntries']);
dcCore::app()->tpl->addValue('ComListePaginationLinks', [Template::class,'comListePaginationLinks']);
dcCore::app()->tpl->addValue('ComListeOpenPostTitle', [Template::class,'comListeOpenPostTitle']);
dcCore::app()->tpl->addValue('ComListeCommentOrderNumber', [Template::class,'comListeCommentOrderNumber']);
if (empty($attr['no_context'])) {
$p .= 'if (dcCore::app()->ctx->exists("categories")) { ' .
"\$params['cat_id'] = dcCore::app()->ctx->categories->cat_id; " .
"}\n";
dcCore::app()->tpl->addBlock('ComListePagination', [Template::class,'comListePagination']);
dcCore::app()->tpl->addValue('ComListePaginationCounter', [Template::class,'comListePaginationCounter']);
dcCore::app()->tpl->addValue('ComListePaginationCurrent', [Template::class,'comListePaginationCurrent']);
dcCore::app()->tpl->addBlock('ComListePaginationIf', [Template::class,'comListePaginationIf']);
dcCore::app()->tpl->addValue('ComListePaginationURL', [Template::class,'comListePaginationURL']);
$p .= 'if (dcCore::app()->ctx->exists("langs")) { ' .
"\$params['sql'] = \"AND P.post_lang = '\".dcCore::app()->blog->con->escape(dcCore::app()->langs->post_lang).\"' \"; " .
"}\n";
}
dcCore::app()->addBehavior(
'publicBreadcrumb',
function (string $context, string $separator): ?string {
if ($context == 'comListe') {
return __('Comments list');
}
// Sens de tri issu des paramètres du plugin
$order = dcCore::app()->blog->settings->get(basename(__DIR__))->get('comments_order');
if (isset($attr['order']) && preg_match('/^(desc|asc)$/i', $attr['order'])) {
$order = $attr['order'];
}
return null;
},
);
$p .= "\$params['order'] = 'comment_dt " . $order . "';\n";
if (isset($attr['no_content']) && $attr['no_content']) {
$p .= "\$params['no_content'] = true;\n";
}
$res = "<?php\n";
$res .= $p;
$res .= 'dcCore::app()->ctx->comments_params = $params; ';
$res .= 'dcCore::app()->ctx->comments = dcCore::app()->blog->getComments($params); unset($params);' . "\n";
$res .= "if (dcCore::app()->ctx->posts !== null) { dcCore::app()->blog->withoutPassword(true);}\n";
if (!empty($attr['with_pings'])) {
$res .= 'dcCore::app()->ctx->pings = dcCore::app()->ctx->comments;' . "\n";
}
$res .= "?>\n";
$res .= '<?php while (dcCore::app()->ctx->comments->fetch()) : ?>' . $content . '<?php endwhile; dcCore::app()->ctx->pop("comments"); ?>';
return $res;
}
/* ComListePaginationLinks --------------------------------------- */
/* Reprise et adaptation de la fonction PaginationLinks du plugin advancedPagination-1.9 */
public static function comListePaginationLinks($attr)
{
$p = '<?php
function comListeMakePageLink($pageNumber, $linkText) {
if ($pageNumber != dcCore::app()->public->getPageNumber()) {
$args = $_SERVER["URL_REQUEST_PART"];
$args = preg_replace("#(^|/)page/([0-9]+)$#","",$args);
$url = dcCore::app()->blog->url.$args;
if ($pageNumber > 1) {
$url = preg_replace("#/$#","",$url);
$url .= "/page/".$pageNumber;
}
if (!empty($_GET["q"])) {
$s = strpos($url,"?") !== false ? "&amp;" : "?";
$url .= $s."q=".rawurlencode($_GET["q"]);
}
return "<a href=\"".$url."\">".$linkText."</a>&nbsp;";
} else {
return $linkText."&nbsp;";
}
}
$current = dcCore::app()->public->getPageNumber();
if(empty($params)) {
dcCore::app()->ctx->pagination = dcCore::app()->blog->getComments(null,true);
} else {
dcCore::app()->ctx->pagination = dcCore::app()->blog->getComments($params,true);
unset($params);
}
if (dcCore::app()->ctx->exists("pagination")) {
$nb_comments = dcCore::app()->ctx->pagination->f(0);
}
$nb_per_page = abs((integer) dcCore::app()->blog->settings->get("' . basename(__DIR__) . '")->get("nb_comments_per_page"));
$nb_pages = ceil($nb_comments/$nb_per_page);
$nb_max_pages = 10;
$nb_sequence = 2*3+1;
$quick_distance = 10;
if($nb_pages <= $nb_max_pages) {
/* less or equal than 10 pages, simple links */
for ($i = 1; $i <= $nb_pages; $i++) {
echo comListeMakePageLink($i,$i);
}
} else {
/* more than 10 pages, smart links */
echo comListeMakePageLink(1,1);
$min_page = max($current - ($nb_sequence - 1) / 2, 2);
$max_page = min($current + ($nb_sequence - 1) / 2, $nb_pages - 1);
if ($min_page > 2) {
echo "...";
echo "&nbsp;";
}
for ($i = $min_page; $i <= $max_page ; $i++) {
echo comListeMakePageLink($i,$i);
}
if ($max_page < $nb_pages - 1) {
echo "...";
echo "&nbsp;";
}
echo comListeMakePageLink($nb_pages,$nb_pages);
/* quick navigation links */
if($current >= 1 + $quick_distance) {
echo "&nbsp;";
echo comListeMakePageLink($current - $quick_distance, "<<");
}
if($current <= $nb_pages - $quick_distance) {
echo "&nbsp;";
echo comListeMakePageLink($current + $quick_distance, ">> ");
}
}
?>';
return $p;
}
/* ComListeOpenPostTitle --------------------------------------- */
public static function comListeOpenPostTitle($attr)
{
return __('open post');
}
public static function comListeCommentOrderNumber(ArrayObject $attr): string
{
return
'<?php echo ' .
'dcCore::app()->ctx->comments->index() + 1 +' .
'(dcCore::app()->public->getPageNumber() - 1) * ' .
'abs((integer) dcCore::app()->blog->settings->get("' . basename(__DIR__) . '")->get("nb_comments_per_page"));' .
'?>';
}
public static function comListePagination(ArrayObject $attr, string $content): string
{
$params = "<?php\n" .
'$params = dcCore::app()->ctx->comments_params;' . "\n" .
dcCore::app()->callBehavior(
'templatePrepareParams',
[
'tag' => 'Pagination',
'method' => 'comListe::getComments',
],
$attr,
$content
) .
'dcCore::app()->ctx->pagination = dcCore::app()->blog->getComments($params,true); unset($params);' . "\n" .
"?>\n";
if (isset($attr['no_context']) && $attr['no_context']) {
return $params . $content;
}
return
"<?php\n" .
'$bakcup_old_nbpp = dcCore::app()->ctx->nb_entry_per_page; ' . "\n" .
'dcCore::app()->ctx->nb_entry_per_page = abs((integer) dcCore::app()->blog->settings->get("' . basename(__DIR__) . '")->get("nb_comments_per_page"));' . "\n" .
"?>\n" .
$params .
'<?php if (dcCore::app()->ctx->pagination->f(0) > dcCore::app()->ctx->comments->count()) : ?>' .
$content .
"<?php endif;\n" .
'dcCore::app()->ctx->nb_entry_per_page = $bakcup_old_nbpp; ' . "\n" .
'?>';
}
public static function comListePaginationCounter(ArrayObject $attr): string
{
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'context::PaginationNbPages()') . '; ?>';
}
public static function comListePaginationCurrent(ArrayObject $attr): string
{
$offset = isset($attr['offset']) ? (int) $attr['offset'] : 0;
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'context::PaginationPosition(' . $offset . ')') . '; ?>';
}
public static function comListePaginationIf(ArrayObject $attr, string $content): string
{
$if = [];
if (isset($attr['start'])) {
$sign = (bool) $attr['start'] ? '' : '!';
$if[] = $sign . 'context::PaginationStart()';
}
if (isset($attr['end'])) {
$sign = (bool) $attr['end'] ? '' : '!';
$if[] = $sign . 'context::PaginationEnd()';
}
if (count($if)) {
return '<?php if(' . implode(' && ', $if) . ') : ?>' . $content . '<?php endif; ?>';
}
return $content;
}
public static function comListePaginationURL(ArrayObject $attr): string
{
$offset = 0;
if (isset($attr['offset'])) {
$offset = (int) $attr['offset'];
}
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'context::PaginationURL(' . $offset . ')') . '; ?>';
return true;
}
}

View File

@ -10,27 +10,47 @@
* @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);
try {
if (!dcCore::app()->newVersion(
basename(__DIR__),
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
)) {
return null;
namespace Dotclear\Plugin\comListe;
use dcCore;
use dcNsProcess;
use Exception;
class Install extends dcNsProcess
{
public static function init(): bool
{
static::$init = defined('DC_CONTEXT_ADMIN')
&& My::phpCompliant()
&& dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version'));
return static::$init;
}
$s = dcCore::app()->blog->settings->get(basename(__DIR__));
$s->put('enable', false, 'boolean', 'Enable comListe', false, true);
$s->put('page_title', 'Comments list', 'string', 'Public page title', false, true);
$s->put('nb_comments_per_page', 10, 'integer', 'Number of comments per page', false, true);
$s->put('comments_order', 'desc', 'string', 'Comments order', false, true);
public static function process(): bool
{
if (!static::$init) {
return false;
}
return true;
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
if (is_null(dcCore::app()->blog)) {
return false;
}
try {
$s = dcCore::app()->blog->settings->get(My::id());
$s->put('enable', false, 'boolean', 'Enable comListe', false, true);
$s->put('page_title', 'Comments list', 'string', 'Public page title', false, true);
$s->put('nb_comments_per_page', 10, 'integer', 'Number of comments per page', false, true);
$s->put('comments_order', 'desc', 'string', 'Comments order', false, true);
return true;
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
return false;
}
}
}
return false;

View File

@ -10,87 +10,136 @@
* @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_ADMIN,
]));
namespace Dotclear\Plugin\comListe;
$s = dcCore::app()->blog->settings->get(basename(__dir__));
$action = $_REQUEST['action'] ?? null;
$order_combo = [
__('Ascending') => 'asc',
__('Descending') => 'desc',
];
use dcCore;
use dcNsProcess;
use dcPage;
use Dotclear\Helper\Html\Form\{
Checkbox,
Div,
Form,
Hidden,
Input,
Label,
Number,
Para,
Select,
Submit,
Text
};
use Dotclear\Helper\Html\Html;
use Exception;
if ($action == 'saveconfig') {
try {
if (empty($_POST['comliste_page_title'])) {
throw new Exception(__('No page title.'));
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_ADMIN,
]), dcCore::app()->blog->id);
return static::$init;
}
public static function process(): bool
{
if (!static::$init) {
return false;
}
$s->put('enable', !empty($_POST['comliste_enable']));
$s->put('page_title', $_POST['comliste_page_title']);
$s->put('nb_comments_per_page', $_POST['comliste_nb_comments_per_page'] ?? 10);
$s->put('comments_order', $_POST['comliste_comments_order'] == 'asc' ? 'asc' : 'desc');
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
return false;
}
dcCore::app()->blog->triggerBlog();
if (($_REQUEST['action'] ?? null) != 'saveconfig') {
return true;
}
dcAdminNotices::addSuccessNotice(
__('Configuration successfully updated.')
);
try {
if (empty($_POST['comliste_page_title'])) {
throw new Exception(__('No page title.'));
}
$s = dcCore::app()->blog->settings->get(My::id());
$s->put('enable', !empty($_POST['comliste_enable']));
$s->put('page_title', $_POST['comliste_page_title']);
$s->put('nb_comments_per_page', $_POST['comliste_nb_comments_per_page'] ?? 10);
$s->put('comments_order', $_POST['comliste_comments_order'] == 'asc' ? 'asc' : 'desc');
dcCore::app()->adminurl->redirect(
'admin.plugin.' . basename(__DIR__)
);
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
dcCore::app()->blog->triggerBlog();
dcPage::addSuccessNotice(
__('Configuration successfully updated.')
);
dcCore::app()->adminurl->redirect(
'admin.plugin.' . My::id()
);
} catch (Exception $e) {
dcCore::app()->error->add($e->getMessage());
}
return true;
}
public static function render(): void
{
if (!static::$init) {
return;
}
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
return;
}
$s = dcCore::app()->blog->settings->get(My::id());
dcPage::openModule(My::name());
echo dcPage::breadcrumb([
Html::escapeHTML(dcCore::app()->blog->name) => '',
My::name() => '',
]) .
dcPage::notices() .
(new Form('setting_form'))->method('post')->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->separator('')->fields([
(new Div())->class('fieldset')->items([
(new Text('h4', __('Plugin activation'))),
(new Para())->items([
(new Checkbox('comliste_enable', (bool) $s->get('enable')))->value(1),
(new Label(__('Enable comListe'), Label::OUTSIDE_LABEL_AFTER))->for('comliste_enable')->class('classic'),
]),
]),
(new Div())->class('fieldset')->items([
(new Text('h4', __('General options'))),
(new Para())->items([
(new Label(__('Public page title:'), Label::OUTSIDE_LABEL_BEFORE))->for('comliste_page_title'),
(new Input('comliste_page_title'))->size(30)->maxlenght(255)->value((string) $s->get('page_title')),
]),
(new Para())->items([
(new Label(__('Number of comments per page:'), Label::OUTSIDE_LABEL_BEFORE))->for('comliste_nb_comments_per_page'),
(new Number('comliste_nb_comments_per_page'))->min(0)->max(99)->value((int) $s->get('nb_comments_per_page')),
]),
(new Label(__('Comments order:'), Label::OUTSIDE_LABEL_BEFORE))->for('comliste_comments_order'),
(new Select('comliste_comments_order'))
->items([__('Ascending') => 'asc', __('Descending') => 'desc'])
->default($s->get('comments_order') == 'asc' ? 'asc' : 'desc'),
]),
(new Para())->class('clear')->items([
(new Submit(['do']))->value(__('Save')),
(new Hidden(['action'], 'saveconfig')),
(new Hidden(['p'], My::id())),
dcCOre::app()->formNonce(false),
]),
])->render();
dcPage::helpBlock('comListe');
dcPage::closeModule();
}
}
echo '
<html><head><title>' . __('Comments list') . '</title></head><body>' .
dcPage::breadcrumb([
html::escapeHTML(dcCore::app()->blog->name) => '',
__('Comments list') => '',
]) .
dcPage::notices() .
'<form method="post" action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)) . '">' .
'<div class="fieldset"><h4>' . __('Plugin activation') . '</h4>' .
'<p class="field"><label for="comliste_enable" class="classic">' .
form::checkbox('comliste_enable', 1, (bool) $s->get('enable')) .
__('Enable comListe') . '</label></p>' .
'</div>' .
'<div class="fieldset"><h4>' . __('General options') . '</h4>' .
'<p><label for="comliste_page_title">' . __('Public page title:') . ' </label>' .
form::field('comliste_page_title', 30, 255, (string) $s->get('page_title')) .
'</label></p>' .
'<p><label for="comliste_nb_comments_per_page">' .
__('Number of comments per page:') . '</label>' .
form::number('comliste_nb_comments_per_page', ['min' => 0, 'max' => 99, 'default' => (int) $s->get('nb_comments_per_page')]) .
'</p>' .
'<p><label for="comliste_comments_order">' . __('Comments order:') . '</label>' .
form::combo('comliste_comments_order', $order_combo, $s->get('comments_order') == 'asc' ? 'asc' : 'desc') .
'</p>' .
'</div>
<p class="clear">' .
form::hidden(['action'], 'saveconfig') .
dcCore::app()->formNonce() . '
<input id="new-action" type="submit" name="save" value="' . __('Save') . '" />
</p>
</form>';
dcPage::helpBlock('comListe');
echo '</body></html>';

58
src/My.php 100644
View File

@ -0,0 +1,58 @@
<?php
/**
* @brief comListe, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Benoit de Marne, Pierre Van Glabeke and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\comListe;
use dcCore;
/**
* Plugin definitions
*/
class My
{
/** @var string Required php version */
public const PHP_MIN = '7.4';
/**
* This module id
*/
public static function id(): string
{
return basename(dirname(__DIR__));
}
/**
* This module name
*/
public static function name(): string
{
return __((string) dcCore::app()->plugins->moduleInfo(self::id(), 'name'));
}
/**
* This module directory path
*/
public static function path(): string
{
return dirname(__DIR__);
}
/**
* Check php version
*/
public static function phpCompliant(): bool
{
return version_compare(phpversion(), self::PHP_MIN, '>=');
}
}

View File

@ -10,45 +10,35 @@
* @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()->url->register(
'comListe',
'comListe',
'^comListe(?:/(.+))?$',
[urlcomListe::class,'comListe']
);
namespace Dotclear\Plugin\comListe;
class urlcomListe extends dcUrlHandlers
use dcCore;
use dcNsProcess;
class Prepend extends dcNsProcess
{
public static function comListe($args)
public static function init(): bool
{
$args = (string) $args;
static::$init = My::phpCompliant();
if (!dcCore::app()->blog->settings->get(basename(__DIR__))->get('enable')) {
self::p404();
return static::$init;
}
return null;
public static function process(): bool
{
if (!static::$init) {
return false;
}
$n = self::getPageNumber($args);
if (!$n) {
$n = 1;
}
dcCore::app()->url->register(
'comListe',
'comListe',
'^comListe(?:/(.+))?$',
[UrlHandler::class, 'comListe']
);
dcCore::app()->public->setPageNumber($n);
dcCore::app()->ctx->__set('nb_comment_per_page', (int) dcCore::app()->blog->settings->get(basename(__DIR__))->get('nb_comments_per_page'));
$tplset = dcCore::app()->themes->moduleInfo(dcCore::app()->blog->settings->get('system')->get('theme'), 'tplset');
if (!empty($tplset) && is_dir(implode(DIRECTORY_SEPARATOR, [__DIR__, 'default-templates', $tplset]))) {
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), implode(DIRECTORY_SEPARATOR, [__DIR__, 'default-templates', $tplset]));
} else {
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), implode(DIRECTORY_SEPARATOR, [__DIR__, 'default-templates', DC_DEFAULT_TPLSET]));
}
self::serveDocument('comListe.html');
exit;
return true;
}
}

306
src/Template.php 100644
View File

@ -0,0 +1,306 @@
<?php
/**
* @brief comListe, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Benoit de Marne, Pierre Van Glabeke and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\comListe;
use ArrayObject;
use dcCore;
use Dotclear\Helper\Html\Html;
class Template
{
public string $html_prev = '&#171;prev.';
public string $html_next = 'next&#187;';
/* ComListeURL --------------------------------------- */
public static function comListeURL(ArrayObject $attr): string
{
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'dcCore::app()->blog->url.dcCore::app()->url->getBase("comListe")') . '; ?>';
}
/* ComListePageTitle --------------------------------------- */
public static function comListePageTitle(ArrayObject $attr): string
{
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'dcCore::app()->blog->settings->get("' . My::id() . '")->get("page_title")') . '; ?>';
}
/* ComListeNbCommentsPerPage --------------------------------------- */
public static function comListeNbCommentsPerPage(ArrayObject $attr): string
{
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->ctx)) {
return '10';
}
dcCore::app()->ctx->__set('nb_comment_per_page', (int) dcCore::app()->blog->settings->get(My::id())->get('nb_comments_per_page'));
return Html::escapeHTML((string) dcCore::app()->ctx->__get('nb_comment_per_page'));
}
/* comListeNbComments --------------------------------------- */
public static function comListeNbComments(ArrayObject$attr): string
{
if (is_null(dcCore::app()->blog) || is_null(dcCore::app()->ctx)) {
return '0';
}
if (!dcCore::app()->ctx->exists('pagination')) {
dcCore::app()->ctx->__set('pagination', dcCore::app()->blog->getComments([], true));
}
$nb_comments = dcCore::app()->ctx->__get('pagination')->f(0);
return Html::escapeHTML((string) $nb_comments);
}
/* ComListeCommentsEntries --------------------------------------- */
public static function comListeCommentsEntries(ArrayObject $attr, string $content): string
{
$p = 'if (dcCore::app()->ctx->posts !== null) { ' .
"\$params['post_id'] = dcCore::app()->ctx->posts->post_id; " .
"dcCore::app()->blog->withoutPassword(false);\n" .
"}\n";
if (empty($attr['with_pings'])) {
$p .= "\$params['comment_trackback'] = false;\n";
}
$lastn = 0;
if (isset($attr['lastn'])) {
$lastn = abs((int) $attr['lastn']) + 0;
}
if ($lastn > 0) {
$p .= "\$params['limit'] = " . $lastn . ";\n";
} else {
$p .= "if (dcCore::app()->ctx->nb_comment_per_page !== null) { \$params['limit'] = dcCore::app()->ctx->nb_comment_per_page; }\n";
}
$p .= "\$params['limit'] = array(((dcCore::app()->public->getPageNumber()-1)*\$params['limit']),\$params['limit']);\n";
if (empty($attr['no_context'])) {
$p .= 'if (dcCore::app()->ctx->exists("categories")) { ' .
"\$params['cat_id'] = dcCore::app()->ctx->categories->cat_id; " .
"}\n";
$p .= 'if (dcCore::app()->ctx->exists("langs")) { ' .
"\$params['sql'] = \"AND P.post_lang = '\".dcCore::app()->blog->con->escapeStr((string) dcCore::app()->langs->post_lang).\"' \"; " .
"}\n";
}
// Sens de tri issu des paramètres du plugin
$order = is_null(dcCore::app()->blog) ? 'desc' : dcCore::app()->blog->settings->get(My::id())->get('comments_order');
if (isset($attr['order']) && preg_match('/^(desc|asc)$/i', $attr['order'])) {
$order = $attr['order'];
}
$p .= "\$params['order'] = 'comment_dt " . ($order ?? 'desc') . "';\n";
if (isset($attr['no_content']) && $attr['no_content']) {
$p .= "\$params['no_content'] = true;\n";
}
$res = "<?php\n";
$res .= $p;
$res .= 'dcCore::app()->ctx->comments_params = $params; ';
$res .= 'dcCore::app()->ctx->comments = dcCore::app()->blog->getComments($params); unset($params);' . "\n";
$res .= "if (dcCore::app()->ctx->posts !== null) { dcCore::app()->blog->withoutPassword(true);}\n";
if (!empty($attr['with_pings'])) {
$res .= 'dcCore::app()->ctx->pings = dcCore::app()->ctx->comments;' . "\n";
}
$res .= "?>\n";
$res .= '<?php while (dcCore::app()->ctx->comments->fetch()) : ?>' . $content . '<?php endwhile; dcCore::app()->ctx->pop("comments"); ?>';
return $res;
}
/* ComListePaginationLinks --------------------------------------- */
/* Reprise et adaptation de la fonction PaginationLinks du plugin advancedPagination-1.9 */
public static function comListePaginationLinks(ArrayObject $attr): string
{
$p = '<?php
function comListeMakePageLink($pageNumber, $linkText) {
if ($pageNumber != dcCore::app()->public->getPageNumber()) {
$args = $_SERVER["URL_REQUEST_PART"];
$args = preg_replace("#(^|/)page/([0-9]+)$#","",$args);
$url = dcCore::app()->blog->url.$args;
if ($pageNumber > 1) {
$url = preg_replace("#/$#","",$url);
$url .= "/page/".$pageNumber;
}
if (!empty($_GET["q"])) {
$s = strpos($url,"?") !== false ? "&amp;" : "?";
$url .= $s."q=".rawurlencode($_GET["q"]);
}
return "<a href=\"".$url."\">".$linkText."</a>&nbsp;";
} else {
return $linkText."&nbsp;";
}
}
$current = dcCore::app()->public->getPageNumber();
if(empty($params)) {
dcCore::app()->ctx->pagination = dcCore::app()->blog->getComments(null,true);
} else {
dcCore::app()->ctx->pagination = dcCore::app()->blog->getComments($params,true);
unset($params);
}
if (dcCore::app()->ctx->exists("pagination")) {
$nb_comments = dcCore::app()->ctx->pagination->f(0);
}
$nb_per_page = abs((integer) dcCore::app()->blog->settings->get("' . My::id() . '")->get("nb_comments_per_page"));
$nb_pages = ceil($nb_comments/$nb_per_page);
$nb_max_pages = 10;
$nb_sequence = 2*3+1;
$quick_distance = 10;
if($nb_pages <= $nb_max_pages) {
/* less or equal than 10 pages, simple links */
for ($i = 1; $i <= $nb_pages; $i++) {
echo comListeMakePageLink($i,$i);
}
} else {
/* more than 10 pages, smart links */
echo comListeMakePageLink(1,1);
$min_page = max($current - ($nb_sequence - 1) / 2, 2);
$max_page = min($current + ($nb_sequence - 1) / 2, $nb_pages - 1);
if ($min_page > 2) {
echo "...";
echo "&nbsp;";
}
for ($i = $min_page; $i <= $max_page ; $i++) {
echo comListeMakePageLink($i,$i);
}
if ($max_page < $nb_pages - 1) {
echo "...";
echo "&nbsp;";
}
echo comListeMakePageLink($nb_pages,$nb_pages);
/* quick navigation links */
if($current >= 1 + $quick_distance) {
echo "&nbsp;";
echo comListeMakePageLink($current - $quick_distance, "<<");
}
if($current <= $nb_pages - $quick_distance) {
echo "&nbsp;";
echo comListeMakePageLink($current + $quick_distance, ">> ");
}
}
?>';
return $p;
}
/* ComListeOpenPostTitle --------------------------------------- */
public static function comListeOpenPostTitle(ArrayObject $attr): string
{
return __('open post');
}
public static function comListeCommentOrderNumber(ArrayObject $attr): string
{
return
'<?php echo ' .
'dcCore::app()->ctx->comments->index() + 1 +' .
'(dcCore::app()->public->getPageNumber() - 1) * ' .
'abs((integer) dcCore::app()->blog->settings->get("' . My::id() . '")->get("nb_comments_per_page"));' .
'?>';
}
public static function comListePagination(ArrayObject $attr, string $content): string
{
$params = "<?php\n" .
'$params = dcCore::app()->ctx->comments_params;' . "\n" .
dcCore::app()->callBehavior(
'templatePrepareParams',
[
'tag' => 'Pagination',
'method' => 'comListe::getComments',
],
$attr,
$content
) .
'dcCore::app()->ctx->pagination = dcCore::app()->blog->getComments($params,true); unset($params);' . "\n" .
"?>\n";
if (isset($attr['no_context']) && $attr['no_context']) {
return $params . $content;
}
return
"<?php\n" .
'$bakcup_old_nbpp = dcCore::app()->ctx->nb_entry_per_page; ' . "\n" .
'dcCore::app()->ctx->nb_entry_per_page = abs((integer) dcCore::app()->blog->settings->get("' . My::id() . '")->get("nb_comments_per_page"));' . "\n" .
"?>\n" .
$params .
'<?php if (dcCore::app()->ctx->pagination->f(0) > dcCore::app()->ctx->comments->count()) : ?>' .
$content .
"<?php endif;\n" .
'dcCore::app()->ctx->nb_entry_per_page = $bakcup_old_nbpp; ' . "\n" .
'?>';
}
public static function comListePaginationCounter(ArrayObject $attr): string
{
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'context::PaginationNbPages()') . '; ?>';
}
public static function comListePaginationCurrent(ArrayObject $attr): string
{
$offset = isset($attr['offset']) ? (int) $attr['offset'] : 0;
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'context::PaginationPosition(' . $offset . ')') . '; ?>';
}
public static function comListePaginationIf(ArrayObject $attr, string $content): string
{
$if = [];
if (isset($attr['start'])) {
$sign = (bool) $attr['start'] ? '' : '!';
$if[] = $sign . 'context::PaginationStart()';
}
if (isset($attr['end'])) {
$sign = (bool) $attr['end'] ? '' : '!';
$if[] = $sign . 'context::PaginationEnd()';
}
if (count($if)) {
return '<?php if(' . implode(' && ', $if) . ') : ?>' . $content . '<?php endif; ?>';
}
return $content;
}
public static function comListePaginationURL(ArrayObject $attr): string
{
$offset = 0;
if (isset($attr['offset'])) {
$offset = (int) $attr['offset'];
}
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($attr), 'context::PaginationURL(' . $offset . ')') . '; ?>';
}
}

46
src/UrlHandler.php 100644
View File

@ -0,0 +1,46 @@
<?php
/**
* @brief comListe, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Benoit de Marne, Pierre Van Glabeke and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\comListe;
use dcCore;
use dcUrlHandlers;
class UrlHandler extends dcUrlHandlers
{
public static function comListe(?string $args): void
{
$args = (string) $args;
if (is_null(dcCore::app()->blog)
|| is_null(dcCore::app()->ctx)
|| !dcCore::app()->blog->settings->get(My::id())->get('enable')
) {
self::p404();
}
dcCore::app()->public->setPageNumber(self::getPageNumber($args) ?: 1);
dcCore::app()->ctx->__set('nb_comment_per_page', (int) dcCore::app()->blog->settings->get(My::id())->get('nb_comments_per_page'));
$tplset = dcCore::app()->themes->moduleInfo(dcCore::app()->blog->settings->get('system')->get('theme'), 'tplset');
if (!empty($tplset) && is_dir(implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', $tplset]))) {
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', $tplset]));
} else {
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', DC_DEFAULT_TPLSET]));
}
self::serveDocument('comListe.html');
exit;
}
}

View File

@ -10,28 +10,31 @@
* @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', [comListeWidget::class,'initWidget']);
namespace Dotclear\Plugin\comListe;
class comListeWidget
use dcCore;
use Dotclear\Helper\Html\Html;
use Dotclear\Plugin\widgets\WidgetsStack;
use Dotclear\Plugin\widgets\WidgetsElement;
class Widgets
{
public static function initWidget($w)
public static function initWidgets(WidgetsStack $w): void
{
$w->create(
'comListe',
__('Comments list'),
['comListeWidget','publicWidget'],
My::id(),
My::name(),
[self::class, 'parseWidget'],
null,
__('Link to comments list public page')
)
->addTitle(__('Comments list'))
->addTitle(My::name())
->setting(
'link_title',
__('Link title: (leave empty to use page title'),
__('Comments list')
My::name()
)
->addHomeOnly()
->addContentOnly()
@ -39,24 +42,25 @@ class comListeWidget
->addOffline();
}
public static function publicWidget($w)
public static function parseWidget(WidgetsElement $w): string
{
if ($w->offline
|| !$w->checkHomeOnly(dcCore::app()->url->type)
|| !dcCore::app()->blog->settings->get(basename(__DIR__))->get('enable')
if (is_null(dcCore::app()->blog)
|| $w->__get('offline')
|| !$w->checkHomeOnly(dcCore::app()->url->type)
|| !dcCore::app()->blog->settings->get(My::id())->get('enable')
) {
return null;
return '';
}
return $w->renderDiv(
$w->content_only,
'comliste ' . $w->class,
(bool) $w->__get('content_only'),
My::id() . ' ' . $w->__get('class'),
'',
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') .
($w->__get('title') ? $w->renderTitle(Html::escapeHTML($w->__get('title'))) : '') .
sprintf(
'<p><a href="%s">%s</a></p>',
dcCore::app()->blog->url . dcCore::app()->url->getBase('comListe'),
$w->link_title ? html::escapeHTML($w->link_title) : (dcCore::app()->blog->settings->get(basename(__DIR__))->get('page_title') ?? __('Comments list'))
$w->__get('link_title') ? Html::escapeHTML($w->__get('link_title')) : (dcCore::app()->blog->settings->get(My::id())->get('page_title') ?? My::name())
)
);
}