Compare commits
10 Commits
4df184ca2f
...
45ea1216dc
Author | SHA1 | Date |
---|---|---|
Jean-Christian Paul Denis | 45ea1216dc | |
Jean-Christian Paul Denis | 97b7362842 | |
Jean-Christian Paul Denis | b3f9dd1bce | |
Jean-Christian Paul Denis | 28ccb5fd0c | |
Jean-Christian Paul Denis | 1b1ea26327 | |
Jean-Christian Paul Denis | acbabf5b18 | |
Jean-Christian Paul Denis | c9abe4063d | |
Jean-Christian Paul Denis | a5a684506f | |
Jean-Christian Paul Denis | 0ec5933f13 | |
Jean-Christian Paul Denis | 87d6ada2e3 |
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,6 +1,17 @@
|
||||||
dev
|
dev
|
||||||
- [ ] literal rank of writer depending of num of com
|
- [ ] literal rank of writer depending of num of com
|
||||||
|
|
||||||
|
1.2 - 2023.04.23
|
||||||
|
- require dotclear 2.26
|
||||||
|
- use latest dotclear namespace
|
||||||
|
- use sql statement
|
||||||
|
- fix plural translations
|
||||||
|
- fix nullsafe warnings
|
||||||
|
|
||||||
|
1.1 - 2023.03.21
|
||||||
|
- require Dotclear 2.25
|
||||||
|
- use namespace
|
||||||
|
|
||||||
1.0 - 2022.12.23
|
1.0 - 2022.12.23
|
||||||
- use dotclear methods for widgets
|
- use dotclear methods for widgets
|
||||||
- fix permissions
|
- fix permissions
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
[![Release](https://img.shields.io/github/v/release/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/releases)
|
[![Release](https://img.shields.io/github/v/release/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/releases)
|
||||||
[![Date](https://img.shields.io/github/release-date/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/releases)
|
[![Date](https://img.shields.io/github/release-date/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/releases)
|
||||||
[![Issues](https://img.shields.io/github/issues/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/issues)
|
[![Issues](https://img.shields.io/github/issues/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/issues)
|
||||||
[![Dotclear](https://img.shields.io/badge/dotclear-v2.24-blue.svg)](https://fr.dotclear.org/download)
|
[![Dotclear](https://img.shields.io/badge/dotclear-v2.26-blue.svg)](https://fr.dotclear.org/download)
|
||||||
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-green.svg)](https://plugins.dotaddict.org/dc2/details/topWriter)
|
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-green.svg)](https://plugins.dotaddict.org/dc2/details/topWriter)
|
||||||
[![License](https://img.shields.io/github/license/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/blob/master/LICENSE)
|
[![License](https://img.shields.io/github/license/JcDenis/topWriter)](https://github.com/JcDenis/topWriter/blob/master/LICENSE)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ Show most active contributor on a widget.
|
||||||
_topWriter_ requires:
|
_topWriter_ requires:
|
||||||
|
|
||||||
* permissions to manage widgets
|
* permissions to manage widgets
|
||||||
* Dotclear 2.24
|
* Dotclear 2.26
|
||||||
|
|
||||||
## USAGE
|
## USAGE
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
if (!defined('DC_RC_PATH') || is_null(dcCore::app()->auth)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@ $this->registerModule(
|
||||||
'Top writer',
|
'Top writer',
|
||||||
'Ranking of the most prolific writers and/or commentators',
|
'Ranking of the most prolific writers and/or commentators',
|
||||||
'Jean-Christian Denis, Pierre Van Glabeke',
|
'Jean-Christian Denis, Pierre Van Glabeke',
|
||||||
'1.0',
|
'1.2',
|
||||||
[
|
[
|
||||||
'requires' => [['core', '2.24']],
|
'requires' => [['core', '2.26']],
|
||||||
'permissions' => dcCore::app()->auth->makePermissions([
|
'permissions' => dcCore::app()->auth->makePermissions([
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
]),
|
]),
|
||||||
'type' => 'plugin',
|
'type' => 'plugin',
|
||||||
'support' => 'http://forum.dotclear.org/viewtopic.php?pid=333002#p333002',
|
'support' => 'http://forum.dotclear.org/viewtopic.php?pid=333002#p333002',
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
<modules xmlns:da="http://dotaddict.org/da/">
|
<modules xmlns:da="http://dotaddict.org/da/">
|
||||||
<module id="topWriter">
|
<module id="topWriter">
|
||||||
<name>Top writer</name>
|
<name>Top writer</name>
|
||||||
<version>1.0</version>
|
<version>1.2</version>
|
||||||
<author>Jean-Christian Denis, Pierre Van Glabeke</author>
|
<author>Jean-Christian Denis, Pierre Van Glabeke</author>
|
||||||
<desc>Ranking of the most prolific writers and/or commentators</desc>
|
<desc>Ranking of the most prolific writers and/or commentators</desc>
|
||||||
<file>https://github.com/JcDenis/topWriter/releases/download/v1.0/plugin-topWriter.zip</file>
|
<file>https://github.com/JcDenis/topWriter/releases/download/v1.2/plugin-topWriter.zip</file>
|
||||||
<da:dcmin>2.24</da:dcmin>
|
<da:dcmin>2.26</da:dcmin>
|
||||||
<da:details>http://plugins.dotaddict.org/dc2/details/topWriter</da:details>
|
<da:details>http://plugins.dotaddict.org/dc2/details/topWriter</da:details>
|
||||||
<da:support>http://forum.dotclear.org/viewtopic.php?pid=333002#p333002</da:support>
|
<da:support>http://forum.dotclear.org/viewtopic.php?pid=333002#p333002</da:support>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -9,26 +9,32 @@
|
||||||
# DOT NOT MODIFY THIS FILE !
|
# DOT NOT MODIFY THIS FILE !
|
||||||
#
|
#
|
||||||
|
|
||||||
l10n::$locales['Top writer: entries'] = 'Top rédacteur : billets';
|
use Dotclear\Helper\L10n;
|
||||||
l10n::$locales['Top writer: comments'] = 'Top rédacteur : commentaires';
|
|
||||||
l10n::$locales['Period:'] = 'Période :';
|
L10n::$locales['Top writer: entries'] = 'Top rédacteur : billets';
|
||||||
l10n::$locales['Limit:'] = 'Limite :';
|
L10n::$locales['Top writer: comments'] = 'Top rédacteur : commentaires';
|
||||||
l10n::$locales['List users who write more comments'] = 'Liste les utilisateurs qui ont écrit le plus de commentaires';
|
L10n::$locales['Period:'] = 'Période :';
|
||||||
l10n::$locales['Top comments'] = 'Top commentaires';
|
L10n::$locales['Limit:'] = 'Limite :';
|
||||||
l10n::$locales['Exclude post writer from list'] = 'Exclure de la liste les auteurs de billets';
|
L10n::$locales['List users who write more comments'] = 'Liste les utilisateurs qui ont écrit le plus de commentaires';
|
||||||
l10n::$locales['List users who write more posts'] = 'Liste les utilisateurs qui ont écrit le plus de billets';
|
L10n::$locales['Top comments'] = 'Top commentaires';
|
||||||
l10n::$locales['Top entries'] = 'Top billets';
|
L10n::$locales['Exclude post writer from list'] = 'Exclure de la liste les auteurs de billets';
|
||||||
l10n::$locales['Author posts'] = 'Billets de l\'auteur';
|
L10n::$locales['List users who write more posts'] = 'Liste les utilisateurs qui ont écrit le plus de billets';
|
||||||
l10n::$locales['Author link'] = 'Lien vers l\'auteur';
|
L10n::$locales['Top entries'] = 'Top billets';
|
||||||
l10n::$locales['no entries'] = 'aucun billet';
|
L10n::$locales['Author posts'] = 'Billets de l\'auteur';
|
||||||
l10n::$locales['one entry'][0] = 'une publication';
|
L10n::$locales['Author link'] = 'Lien vers l\'auteur';
|
||||||
l10n::$locales['one entry'][1] = '%s publications';
|
L10n::$locales['no entries'] = 'aucun billet';
|
||||||
l10n::$locales['no comments'] = 'aucun commentaire';
|
L10n::$locales['one entry'] = [
|
||||||
l10n::$locales['one comment'][0] = 'un commentaire';
|
'une publication',
|
||||||
l10n::$locales['one comment'][1] = '%s commentaires';
|
'%s publications',
|
||||||
l10n::$locales['last day'] = 'dernier jour';
|
];
|
||||||
l10n::$locales['last week'] = 'dernière semaine';
|
L10n::$locales['no comments'] = 'aucun commentaire';
|
||||||
l10n::$locales['last month'] = 'dernier mois';
|
L10n::$locales['one comment'] = [
|
||||||
l10n::$locales['last year'] = 'dernière année';
|
'un commentaire',
|
||||||
l10n::$locales['from begining'] = 'depuis le début';
|
'%s commentaires',
|
||||||
l10n::$locales['Ranking of the most prolific writers and/or commentators'] = 'Classement des plus prolifiques rédacteurs et/ou commentateurs';
|
];
|
||||||
|
L10n::$locales['last day'] = 'dernier jour';
|
||||||
|
L10n::$locales['last week'] = 'dernière semaine';
|
||||||
|
L10n::$locales['last month'] = 'dernier mois';
|
||||||
|
L10n::$locales['last year'] = 'dernière année';
|
||||||
|
L10n::$locales['from begining'] = 'depuis le début';
|
||||||
|
L10n::$locales['Ranking of the most prolific writers and/or commentators'] = 'Classement des plus prolifiques rédacteurs et/ou commentateurs';
|
||||||
|
|
|
@ -16,8 +16,16 @@ namespace Dotclear\Plugin\topWriter;
|
||||||
|
|
||||||
use ArrayObject;
|
use ArrayObject;
|
||||||
use dcCore;
|
use dcCore;
|
||||||
use form;
|
use Dotclear\Helper\Html\Form\{
|
||||||
use html;
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Label,
|
||||||
|
Number,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_TOPWRITER
|
* @ingroup DC_PLUGIN_TOPWRITER
|
||||||
|
@ -41,7 +49,7 @@ class BackendBehaviors
|
||||||
|
|
||||||
# Display
|
# Display
|
||||||
$__dashboard_items[0][] = '<div class="box small" id="topWriterPostsItems">' .
|
$__dashboard_items[0][] = '<div class="box small" id="topWriterPostsItems">' .
|
||||||
'<h3>' . html::escapeHTML(__('Top writer: entries')) . '</h3>' .
|
'<h3>' . Html::escapeHTML(__('Top writer: entries')) . '</h3>' .
|
||||||
'<ul>' . implode('', $li) . '</ul>' .
|
'<ul>' . implode('', $li) . '</ul>' .
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
@ -58,7 +66,7 @@ class BackendBehaviors
|
||||||
|
|
||||||
# Display
|
# Display
|
||||||
$__dashboard_items[0][] = '<div class="box small" id="topWriterCommentsItems">' .
|
$__dashboard_items[0][] = '<div class="box small" id="topWriterCommentsItems">' .
|
||||||
'<h3>' . html::escapeHTML(__('Top writer: comments')) . '</h3>' .
|
'<h3>' . Html::escapeHTML(__('Top writer: comments')) . '</h3>' .
|
||||||
'<ul>' . implode('', $li) . '</ul>' .
|
'<ul>' . implode('', $li) . '</ul>' .
|
||||||
'</div>';
|
'</div>';
|
||||||
}
|
}
|
||||||
|
@ -70,31 +78,47 @@ class BackendBehaviors
|
||||||
$pref = self::setDefaultPref();
|
$pref = self::setDefaultPref();
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<div class="fieldset">' .
|
(new Div())->items([
|
||||||
'<h4>' . __('Top writer: entries') . '</h4>' .
|
(new Div())->class('fieldset')->items([
|
||||||
'<p><label class="classic" for="topWriterPostsItems">' .
|
(new Text('h4', __('Top writer: entries'))),
|
||||||
form::checkbox('topWriterPostsItems', 1, $pref['topWriterPostsItems']) . ' ' .
|
(new Para())->items([
|
||||||
__('Show') . '</label></p>' .
|
(new Checkbox('topWriterPostsItems', $pref['topWriterPostsItems']))->value(1),
|
||||||
'<p><label class="classic" for="topWriterPostsPeriod">' . __('Period:') . ' </label>' .
|
(new Label(__('Show'), Label::OUTSIDE_LABEL_AFTER))->for('topWriterPostsItems')->class('classic'),
|
||||||
form::combo('topWriterPostsPeriod', Utils::periods(), $pref['topWriterPostsPeriod']) . '</p>' .
|
]),
|
||||||
'<p><label class="classic" for="topWriterPostsLimit">' . __('Limit:') . ' </label>' .
|
(new Para())->class('field')->items([
|
||||||
form::number('topWriterPostsLimit', ['min' => 1, 'max' => 20, 'default' => $pref['topWriterPostsLimit']]) . '</p>' .
|
(new Label(__('Period:'), Label::OUTSIDE_LABEL_BEFORE))->for('topWriterPostsPeriod'),
|
||||||
'</div>' .
|
(new Select('topWriterPostsPeriod'))->default($pref['topWriterPostsPeriod'])->items(Utils::periods()),
|
||||||
|
]),
|
||||||
'<div class="fieldset">' .
|
(new Para())->class('field')->items([
|
||||||
'<h4>' . __('Top writer: comments') . '</h4>' .
|
(new Label(__('Limit:'), Label::OUTSIDE_LABEL_BEFORE))->for('topWriterPostsLimit'),
|
||||||
'<p><label class="classic" for="topWriterCommentsItems">' .
|
(new Number('topWriterPostsLimit'))->min(1)->max(20)->value($pref['topWriterPostsLimit']),
|
||||||
form::checkbox('topWriterCommentsItems', 1, $pref['topWriterCommentsItems']) . ' ' .
|
]),
|
||||||
__('Show') . '</label></p>' .
|
]),
|
||||||
'<p><label class="classic" for="topWriterCommentsPeriod">' . __('Period:') . ' </label>' .
|
(new Div())->class('fieldset')->items([
|
||||||
form::combo('topWriterCommentsPeriod', Utils::periods(), $pref['topWriterCommentsPeriod']) . '</p>' .
|
(new Text('h4', __('Top writer: comments'))),
|
||||||
'<p><label class="classic" for="topWriterCommentsLimit">' . __('Limit:') . ' </label>' .
|
(new Para())->items([
|
||||||
form::number('topWriterCommentsLimit', ['min' => 1, 'max' => 20, 'default' => $pref['topWriterCommentsLimit']]) . '</p>' .
|
(new Checkbox('topWriterCommentsItems', $pref['topWriterCommentsItems']))->value(1),
|
||||||
'</div>';
|
(new Label(__('Show'), Label::OUTSIDE_LABEL_AFTER))->for('topWriterCommentsItems')->class('classic'),
|
||||||
|
]),
|
||||||
|
(new Para())->class('field')->items([
|
||||||
|
(new Label(__('Period:'), Label::OUTSIDE_LABEL_BEFORE))->for('topWriterCommentsPeriod'),
|
||||||
|
(new Select('topWriterCommentsPeriod'))->default($pref['topWriterCommentsPeriod'])->items(Utils::periods()),
|
||||||
|
]),
|
||||||
|
(new Para())->class('field')->items([
|
||||||
|
(new Label(__('Limit:'), Label::OUTSIDE_LABEL_BEFORE))->for('topWriterCommentsLimit'),
|
||||||
|
(new Number('topWriterCommentsLimit'))->min(1)->max(20)->value($pref['topWriterCommentsLimit']),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
])->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function adminAfterDashboardOptionsUpdate(?string $user_id): void
|
public static function adminAfterDashboardOptionsUpdate(?string $user_id): void
|
||||||
{
|
{
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->auth->user_prefs)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dcCore::app()->auth->user_prefs->get('dashboard')->put(
|
dcCore::app()->auth->user_prefs->get('dashboard')->put(
|
||||||
'topWriterPostsItems',
|
'topWriterPostsItems',
|
||||||
!empty($_POST['topWriterPostsItems']),
|
!empty($_POST['topWriterPostsItems']),
|
||||||
|
@ -130,6 +154,11 @@ class BackendBehaviors
|
||||||
|
|
||||||
private static function setDefaultPref(): array
|
private static function setDefaultPref(): array
|
||||||
{
|
{
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->auth->user_prefs)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
if (!dcCore::app()->auth->user_prefs->get('dashboard')->prefExists('topWriterPostsItems')) {
|
if (!dcCore::app()->auth->user_prefs->get('dashboard')->prefExists('topWriterPostsItems')) {
|
||||||
dcCore::app()->auth->user_prefs->get('dashboard')->put(
|
dcCore::app()->auth->user_prefs->get('dashboard')->put(
|
||||||
'topWriterPostsItems',
|
'topWriterPostsItems',
|
||||||
|
|
169
src/Utils.php
169
src/Utils.php
|
@ -18,42 +18,69 @@ use dcAuth;
|
||||||
use dcBlog;
|
use dcBlog;
|
||||||
use dcCore;
|
use dcCore;
|
||||||
use dcUtils;
|
use dcUtils;
|
||||||
use dt;
|
use Dotclear\Database\Statement\{
|
||||||
|
JoinStatement,
|
||||||
|
SelectStatement
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
|
||||||
class Utils
|
class Utils
|
||||||
{
|
{
|
||||||
public static function posts(string $period, int $limit, bool $sort_desc = true): array
|
public static function posts(string $period, int $limit, bool $sort_desc = true): array
|
||||||
{
|
{
|
||||||
$req = 'SELECT COUNT(*) AS count, U.user_id ' .
|
// nullsafe
|
||||||
'FROM ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ' .
|
if (is_null(dcCore::app()->blog)) {
|
||||||
'INNER JOIN ' . dcCore::app()->prefix . dcAuth::USER_TABLE_NAME . ' U ON U.user_id = P.user_id ' .
|
return [];
|
||||||
"WHERE blog_id='" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " .
|
}
|
||||||
'AND post_status=1 AND user_status=1 ' .
|
|
||||||
self::period('post_dt', $period) .
|
|
||||||
'GROUP BY U.user_id ' .
|
|
||||||
'ORDER BY count ' . ($sort_desc ? 'DESC' : 'ASC') . ' , U.user_id ASC ' .
|
|
||||||
dcCore::app()->con->limit(abs((int) $limit));
|
|
||||||
|
|
||||||
$rs = dcCore::app()->con->select($req);
|
$sql = new SelectStatement();
|
||||||
if ($rs->isEmpty()) {
|
$sql
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME, 'P'))
|
||||||
|
->columns([
|
||||||
|
$sql->count('*', 'count'),
|
||||||
|
'U.user_id',
|
||||||
|
])
|
||||||
|
->join(
|
||||||
|
(new JoinStatement())
|
||||||
|
->inner()
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME, 'U'))
|
||||||
|
->on('U.user_id = P.user_id')
|
||||||
|
->statement()
|
||||||
|
)
|
||||||
|
->where('blog_id = ' . $sql->quote(dcCore::app()->blog->id))
|
||||||
|
->and('post_status = ' . dcBlog::POST_PUBLISHED)
|
||||||
|
->and('user_status = 1')
|
||||||
|
->group('U.user_id')
|
||||||
|
->order('count ' . ($sort_desc ? 'DESC' : 'ASC') . ' , U.user_id ASC')
|
||||||
|
->limit(abs((int) $limit));
|
||||||
|
|
||||||
|
self::period($sql, $period, 'post_dt');
|
||||||
|
|
||||||
|
$rs = $sql->select();
|
||||||
|
|
||||||
|
if (is_null($rs) || $rs->isEmpty()) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = [];
|
$res = [];
|
||||||
$i = 0;
|
$i = 0;
|
||||||
while ($rs->fetch()) {
|
while ($rs->fetch()) {
|
||||||
$user = dcCore::app()->con->select(
|
$sql = new SelectStatement();
|
||||||
'SELECT * FROM ' . dcCore::app()->prefix . dcAuth::USER_TABLE_NAME . " WHERE user_id='" . $rs->user_id . "' "
|
$user = $sql
|
||||||
);
|
->from(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME)
|
||||||
if ($user->isEmpty()) {
|
->column('*')
|
||||||
|
->where('user_id = ' . $sql->quote($rs->f('user_id')))
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if (is_null($user) || $user->isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$author = dcUtils::getUserCN(
|
$author = dcUtils::getUserCN(
|
||||||
$user->user_id,
|
$user->f('user_id'),
|
||||||
$user->user_name,
|
$user->f('user_name'),
|
||||||
$user->user_firstname,
|
$user->f('user_firstname'),
|
||||||
$user->user_displayname
|
$user->f('user_displayname')
|
||||||
);
|
);
|
||||||
if (empty($author)) {
|
if (empty($author)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -62,18 +89,18 @@ class Utils
|
||||||
$i++;
|
$i++;
|
||||||
if (dcCore::app()->blog->settings->get('authormode')->get('authormode_active')) {
|
if (dcCore::app()->blog->settings->get('authormode')->get('authormode_active')) {
|
||||||
$res[$i]['author_link'] = '<a href="' .
|
$res[$i]['author_link'] = '<a href="' .
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase('author') . '/' . $user->user_id . '" ' .
|
dcCore::app()->blog->url . dcCore::app()->url->getBase('author') . '/' . $user->f('user_id') . '" ' .
|
||||||
'title="' . __('Author posts') . '">' . $author . '</a>';
|
'title="' . __('Author posts') . '">' . $author . '</a>';
|
||||||
} elseif ($user->user_url) {
|
} elseif ($user->f('user_url')) {
|
||||||
$res[$i]['author_link'] = '<a href="' . $user->user_url . '" title="' .
|
$res[$i]['author_link'] = '<a href="' . $user->f('user_url') . '" title="' .
|
||||||
__('Author link') . '">' . $author . '</a>';
|
__('Author link') . '">' . $author . '</a>';
|
||||||
}
|
}
|
||||||
$res[$i]['author'] = $author;
|
$res[$i]['author'] = $author;
|
||||||
|
|
||||||
if ($rs->count == 0) {
|
if ((int) $rs->f('count') == 0) {
|
||||||
$res[$i]['count'] = __('no entries');
|
$res[$i]['count'] = __('no entries');
|
||||||
} else {
|
} else {
|
||||||
$res[$i]['count'] = sprintf(__('one entry', '%s entries', (int) $rs->count), $rs->count);
|
$res[$i]['count'] = sprintf(__('one entry', '%s entries', (int) $rs->f('count')), $rs->f('count'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,63 +109,87 @@ class Utils
|
||||||
|
|
||||||
public static function comments(string $period, int $limit, bool $sort_desc = true, bool $exclude = false): array
|
public static function comments(string $period, int $limit, bool $sort_desc = true, bool $exclude = false): array
|
||||||
{
|
{
|
||||||
$req = 'SELECT COUNT(*) AS count, comment_email ' .
|
// nullsafe
|
||||||
'FROM ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P, ' . dcCore::app()->prefix . dcBlog::COMMENT_TABLE_NAME . ' C ' .
|
if (is_null(dcCore::app()->blog)) {
|
||||||
'WHERE P.post_id=C.post_id ' .
|
return [];
|
||||||
"AND blog_id='" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " .
|
|
||||||
'AND post_status=1 AND comment_status=1 ' .
|
|
||||||
self::period('comment_dt', $period);
|
|
||||||
|
|
||||||
if ($exclude) {
|
|
||||||
$req .= 'AND comment_email NOT IN (' .
|
|
||||||
' SELECT U.user_email ' .
|
|
||||||
' FROM ' . dcCore::app()->prefix . dcAuth::USER_TABLE_NAME . ' U' .
|
|
||||||
' INNER JOIN ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ON P.user_id = U.user_id ' .
|
|
||||||
" WHERE blog_id='" . dcCore::app()->con->escape(dcCore::app()->blog->id) . "' " .
|
|
||||||
' GROUP BY U.user_email) ';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$req .= 'GROUP BY comment_email ' .
|
$sql = new SelectStatement();
|
||||||
'ORDER BY count ' . ($sort_desc ? 'DESC' : 'ASC') . ' ' .
|
$sql
|
||||||
dcCore::app()->con->limit(abs((int) $limit));
|
->from($sql->as(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME, 'P'))
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcBlog::COMMENT_TABLE_NAME, 'C'))
|
||||||
|
->columns([
|
||||||
|
$sql->count('*', 'count'),
|
||||||
|
'comment_email',
|
||||||
|
])
|
||||||
|
->where('blog_id = ' . $sql->quote(dcCore::app()->blog->id))
|
||||||
|
->and('P.post_id = C.post_id')
|
||||||
|
->and('post_status = ' . dcBlog::POST_PUBLISHED)
|
||||||
|
->and('comment_status = ' . dcBlog::COMMENT_PUBLISHED)
|
||||||
|
->group('comment_email')
|
||||||
|
->order('count ' . ($sort_desc ? 'DESC' : 'ASC'))
|
||||||
|
->limit(abs((int) $limit))
|
||||||
|
;
|
||||||
|
|
||||||
$rs = dcCore::app()->con->select($req);
|
self::period($sql, $period, 'comment_dt');
|
||||||
if ($rs->isEmpty()) {
|
|
||||||
|
if ($exclude) {
|
||||||
|
$sql->and('comment_email NOT IN (' .
|
||||||
|
(new SelectStatement())
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME, 'U'))
|
||||||
|
->column('U.user_email')
|
||||||
|
->join(
|
||||||
|
(new JoinStatement())
|
||||||
|
->inner()
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME, 'P'))
|
||||||
|
->on('P.user_id = U.user_id')
|
||||||
|
->statement()
|
||||||
|
)
|
||||||
|
->where('blog_id = ' . $sql->quote(dcCore::app()->blog->id))
|
||||||
|
->group('U.user_email')
|
||||||
|
->statement() .
|
||||||
|
')');
|
||||||
|
}
|
||||||
|
|
||||||
|
$rs = $sql->select();
|
||||||
|
if (is_null($rs) || $rs->isEmpty()) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = [];
|
$res = [];
|
||||||
$i = 0;
|
$i = 0;
|
||||||
while ($rs->fetch()) {
|
while ($rs->fetch()) {
|
||||||
$user = dcCore::app()->con->select(
|
$sql = new SelectStatement();
|
||||||
'SELECT * FROM ' . dcCore::app()->prefix . dcBlog::COMMENT_TABLE_NAME . ' ' .
|
$user = $sql
|
||||||
"WHERE comment_email='" . $rs->comment_email . "' " .
|
->from(dcCore::app()->prefix . dcBlog::COMMENT_TABLE_NAME)
|
||||||
'ORDER BY comment_dt DESC'
|
->column('*')
|
||||||
);
|
->where('comment_email = ' . $sql->quote($rs->f('comment_email')))
|
||||||
|
->order('comment_dt DESC')
|
||||||
|
->select();
|
||||||
|
|
||||||
if (!$user->comment_author) {
|
if (is_null($user) || !$user->f('comment_author')) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$i++;
|
$i++;
|
||||||
|
|
||||||
if ($user->comment_site) {
|
if ($user->f('comment_site')) {
|
||||||
$res[$i]['author_link'] = '<a href="' . $user->comment_site . '" title="' .
|
$res[$i]['author_link'] = '<a href="' . $user->f('comment_site') . '" title="' .
|
||||||
__('Author link') . '">' . $user->comment_author . '</a>';
|
__('Author link') . '">' . $user->f('comment_author') . '</a>';
|
||||||
}
|
}
|
||||||
$res[$i]['author'] = $user->comment_author;
|
$res[$i]['author'] = $user->f('comment_author');
|
||||||
|
|
||||||
if ($rs->count == 0) {
|
if ((int) $rs->f('count') == 0) {
|
||||||
$res[$i]['count'] = __('no comments');
|
$res[$i]['count'] = __('no comments');
|
||||||
} else {
|
} else {
|
||||||
$res[$i]['count'] = sprintf(__('one comment', '%s comments', (int) $rs->count), $rs->count);
|
$res[$i]['count'] = sprintf(__('one comment', '%s comments', (int) $rs->f('count')), $rs->f('count'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $i ? $res : [];
|
return $i ? $res : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function period(string $field, string $period): string
|
private static function period(SelectStatement $sql, string $period, string $field): void
|
||||||
{
|
{
|
||||||
$pattern = '%Y-%m-%d %H:%M:%S';
|
$pattern = '%Y-%m-%d %H:%M:%S';
|
||||||
$time = 0;
|
$time = 0;
|
||||||
|
@ -164,10 +215,10 @@ class Utils
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return '';
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "AND $field > TIMESTAMP '" . dt::str($pattern, time() - $time) . "' ";
|
$sql->and($field . ' > TIMESTAMP ' . $sql->quote(Date::str($pattern, time() - $time)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function periods(): array
|
public static function periods(): array
|
||||||
|
|
|
@ -15,9 +15,9 @@ declare(strict_types=1);
|
||||||
namespace Dotclear\Plugin\topWriter;
|
namespace Dotclear\Plugin\topWriter;
|
||||||
|
|
||||||
use dcCore;
|
use dcCore;
|
||||||
|
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;
|
||||||
use html;
|
|
||||||
|
|
||||||
class Widgets
|
class Widgets
|
||||||
{
|
{
|
||||||
|
@ -133,7 +133,7 @@ class Widgets
|
||||||
(bool) $w->content_only,
|
(bool) $w->content_only,
|
||||||
'topcomments ' . $w->class,
|
'topcomments ' . $w->class,
|
||||||
'',
|
'',
|
||||||
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') .
|
($w->title ? $w->renderTitle(Html::escapeHTML($w->title)) : '') .
|
||||||
sprintf('<ul>%s</ul>', implode('', self::lines($lines, 'comments', $w->text)))
|
sprintf('<ul>%s</ul>', implode('', self::lines($lines, 'comments', $w->text)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ class Widgets
|
||||||
(bool) $w->content_only,
|
(bool) $w->content_only,
|
||||||
'topentries ' . $w->class,
|
'topentries ' . $w->class,
|
||||||
'',
|
'',
|
||||||
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') .
|
($w->title ? $w->renderTitle(Html::escapeHTML($w->title)) : '') .
|
||||||
sprintf('<ul>%s</ul>', implode('', self::lines($lines, 'posts', $w->text)))
|
sprintf('<ul>%s</ul>', implode('', self::lines($lines, 'posts', $w->text)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue