Compare commits

...

4 Commits

27 changed files with 421 additions and 578 deletions

View File

@ -1,3 +1,10 @@
activityReport 3.4 - 2023.10.18
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Upgrade to Dotclear 2.28
* Use namespace to load modules activities
activityReport 3.3 - 2023.08.17 activityReport 3.3 - 2023.08.17
=========================================================== ===========================================================
* Require Dotclear 2.27 * Require Dotclear 2.27

View File

@ -1,10 +1,10 @@
# README # README
[![Release](https://img.shields.io/badge/release-3.3-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/activityReport/releases) [![Release](https://img.shields.io/badge/release-3.4-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/activityReport/releases)
![Date](https://img.shields.io/badge/date-2023.08.17-c44d58.svg) ![Date](https://img.shields.io/badge/date-2023.10.18-c44d58.svg)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.27-137bbb.svg)](https://fr.dotclear.org/download) [![Dotclear](https://img.shields.io/badge/dotclear-v2.28-137bbb.svg)](https://fr.dotclear.org/download)
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/activityReport) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/activityReport)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/activityReport/blob/master/LICENSE) [![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/activityReport/src/branch/master/LICENSE)
## ABOUT ## ABOUT
@ -14,7 +14,7 @@ _activityReport_ is a plugin for the open-source web publishing software called
## REQUIREMENTS ## REQUIREMENTS
* Dotclear 2.27 * Dotclear 2.28
* PHP 8.1+ * PHP 8.1+
* System permissions to add table on database * System permissions to add table on database
* System permissions to send email * System permissions to send email
@ -33,7 +33,7 @@ Once it's done you can manage your reports from menu
## LINKS ## LINKS
* [License](https://git.dotclear.watch/JcDenis/activityReport/blob/master/LICENSE) * [License](https://git.dotclear.watch/JcDenis/activityReport/src/branch/master/LICENSE)
* [Packages & details](https://git.dotclear.watch/JcDenis/activityReport/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/activityReport)) * [Packages & details](https://git.dotclear.watch/JcDenis/activityReport/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/activityReport))
* [Sources & contributions](https://git.dotclear.watch/JcDenis/activityReport) (or on [GitHub](https://github.com/JcDenis/activityReport)) * [Sources & contributions](https://git.dotclear.watch/JcDenis/activityReport) (or on [GitHub](https://github.com/JcDenis/activityReport))
* [Issues & security](https://git.dotclear.watch/JcDenis/activityReport/issues) (or on [GitHub](https://github.com/JcDenis/activityReport/issues)) * [Issues & security](https://git.dotclear.watch/JcDenis/activityReport/issues) (or on [GitHub](https://github.com/JcDenis/activityReport/issues))

View File

@ -1,38 +1,30 @@
<?php <?php
/** /**
* @brief activityReport, a plugin for Dotclear 2 * @file
* @brief The plugin activityReport definition
* @ingroup activityReport
* *
* @package Dotclear * @defgroup activityReport Plugin activityReport.
* @subpackage Plugin
* *
* @author Jean-Christian Denis and contributors * Log and receive your blog activity by email, feed, or on dashboard.
* *
* @copyright Jean-Christian Denis * @author Jean-Christian Denis (author)
* @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')) { declare(strict_types=1);
return null;
}
$this->registerModule( $this->registerModule(
'Activity log', 'Activity log',
'Log and receive your blog activity by email, feed, or on dashboard', 'Log and receive your blog activity by email, feed, or on dashboard',
'Jean-Christian Denis and contributors', 'Jean-Christian Denis and contributors',
'3.3', '3.4',
[ [
'requires' => [ 'requires' => [['core', '2.28']],
['php', '8.1'], 'permissions' => 'My',
['core', '2.27'], 'priority' => 2,
], 'type' => 'plugin',
'permissions' => dcCore::app()->auth->makePermissions([ 'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues',
dcCore::app()->auth::PERMISSION_USAGE, 'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md',
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN, 'repository' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/raw/branch/master/dcstore.xml',
dcCore::app()->auth::PERMISSION_ADMIN,
]),
'priority' => 2,
'type' => 'plugin',
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues',
'details' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/src/branch/master/README.md',
'repository' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/raw/branch/master/dcstore.xml',
] ]
); );

View File

@ -1,20 +0,0 @@
<?php
/**
* @brief activityReport, 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
*/
if (!defined('DC_RC_PATH')) {
return null;
}
class initActivityReport
{
public const ACTIVITY_TABLE_NAME = 'activity';
}

View File

@ -2,11 +2,11 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="activityReport"> <module id="activityReport">
<name>Activity log</name> <name>Activity log</name>
<version>3.3</version> <version>3.4</version>
<author>Jean-Christian Denis and contributors</author> <author>Jean-Christian Denis and contributors</author>
<desc>Log and receive your blog activity by email, feed, or on dashboard</desc> <desc>Log and receive your blog activity by email, feed, or on dashboard</desc>
<file>https://git.dotclear.watch/JcDenis/activityReport/releases/download/v3.3/plugin-activityReport.zip</file> <file>https://git.dotclear.watch/JcDenis/activityReport/releases/download/v3.4/plugin-activityReport.zip</file>
<da:dcmin>2.27</da:dcmin> <da:dcmin>2.28</da:dcmin>
<da:details>https://git.dotclear.watch/JcDenis/activityReport/src/branch/master/README.md</da:details> <da:details>https://git.dotclear.watch/JcDenis/activityReport/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/JcDenis/activityReport/issues</da:support> <da:support>https://git.dotclear.watch/JcDenis/activityReport/issues</da:support>
</module> </module>

View File

@ -1,33 +1,27 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore; use Dotclear\App;
/** /**
* Action descriptor. * @brief activityReport action descriptor class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Action class Action
{ {
/** /**
* Constructor sets action description. * Constructor sets action description.
* *
* @param string $id The action ID * @param string $id The action ID
* @param string $title The action title * @param string $title The action title
* @param string $message The action message * @param string $message The action message
* @param string $behavior The behavior name * @param string $behavior The behavior name
* @param null|callable $function The callback function * @param null|callable $function The callback function
*/ */
public function __construct( public function __construct(
@ -39,7 +33,7 @@ class Action
) { ) {
// fake action has no behavior // fake action has no behavior
if (!is_null($function)) { if (!is_null($function)) {
dcCore::app()->addBehavior($behavior, $function); App::behavior()->addBehavior($behavior, $function);
} }
} }
} }

View File

@ -1,23 +1,12 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use dcAuth; use Dotclear\App;
use dcBlog; use Dotclear\Core\Process;
use dcCore;
use Dotclear\Database\MetaRecord; use Dotclear\Database\MetaRecord;
use Dotclear\Database\Statement\{ use Dotclear\Database\Statement\{
DeleteStatement, DeleteStatement,
@ -34,12 +23,24 @@ use Dotclear\Helper\File\{
use Dotclear\Helper\Network\Mail\Mail; use Dotclear\Helper\Network\Mail\Mail;
use Dotclear\Helper\Text; use Dotclear\Helper\Text;
use Exception; use Exception;
use Throwable;
/** /**
* Activity report main class. * @brief activityReport main class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class ActivityReport class ActivityReport
{ {
/**
* Third party plugins ActivityReport class name.
*
* @var string ACTIVITYREPORT_CLASS_NAME
*/
public const ACTIVITYREPORT_CLASS_NAME = 'ActivityReportAction';
/** @var int activity marked as pending mail report */ /** @var int activity marked as pending mail report */
public const STATUS_PENDING = 0; public const STATUS_PENDING = 0;
@ -80,6 +81,23 @@ class ActivityReport
$this->obsoleteLogs(); $this->obsoleteLogs();
} }
public static function init(): void
{
foreach (App::plugins()->getDefines() as $module) {
$class = $module->get('namespace') . '\\' . self::ACTIVITYREPORT_CLASS_NAME;
try {
if (is_a($class, Process::class, true)) {
// check class prerequiretics
if ($class::init()) {
$class::process();
}
}
} catch (Throwable $e) {
}
}
}
/** /**
* Get singleton instance. * Get singleton instance.
* *
@ -134,11 +152,11 @@ class ActivityReport
]); ]);
} }
$sql $sql
->from($sql->as(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME, 'E'), false, true) ->from($sql->as(App::con()->prefix() . My::ACTIVITY_TABLE_NAME, 'E'), false, true)
->join( ->join(
(new JoinStatement()) (new JoinStatement())
->left() ->left()
->from($sql->as(dcCore::app()->prefix . dcBlog::BLOG_TABLE_NAME, 'B')) ->from($sql->as(App::con()->prefix() . App::blog()::BLOG_TABLE_NAME, 'B'))
->on('E.blog_id = B.blog_id') ->on('E.blog_id = B.blog_id')
->statement() ->statement()
); );
@ -169,7 +187,7 @@ class ActivityReport
} }
$sql->and('E.blog_id' . $sql->in($params['blog_id'])); $sql->and('E.blog_id' . $sql->in($params['blog_id']));
} else { } else {
$sql->and('E.blog_id = ' . $sql->quote((string) dcCore::app()->blog?->id)); $sql->and('E.blog_id = ' . $sql->quote(App::blog()->id()));
} }
if (isset($params['activity_status']) && is_numeric($params['activity_status'])) { if (isset($params['activity_status']) && is_numeric($params['activity_status'])) {
@ -201,8 +219,8 @@ class ActivityReport
if (!empty($params['requests'])) { if (!empty($params['requests'])) {
$or = []; $or = [];
foreach ($this->settings->requests as $group => $actions) { foreach ($this->settings->requests as $group => $actions) {
foreach ($actions as $action) { foreach (array_keys($actions) as $action) {
$or[] = $sql->andGroup(['activity_group = ' . $sql->quote($group), 'activity_action = ' . $sql->quote($action)]); $or[] = $sql->andGroup(['activity_group = ' . $sql->quote((string) $group), 'activity_action = ' . $sql->quote((string) $action)]);
} }
} }
if (!empty($or)) { if (!empty($or)) {
@ -240,12 +258,12 @@ class ActivityReport
public function addLog(string $group, string $action, array $logs): void public function addLog(string $group, string $action, array $logs): void
{ {
try { try {
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME); $cur = App::con()->openCursor(App::con()->prefix() . My::ACTIVITY_TABLE_NAME);
dcCore::app()->con->writeLock(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME); App::con()->writeLock(App::con()->prefix() . My::ACTIVITY_TABLE_NAME);
$cur->setField('activity_id', $this->getNextId()); $cur->setField('activity_id', $this->getNextId());
$cur->setField('activity_type', $this->type); $cur->setField('activity_type', $this->type);
$cur->setField('blog_id', (string) dcCore::app()->blog?->id); $cur->setField('blog_id', App::blog()->id());
$cur->setField('activity_group', $group); $cur->setField('activity_group', $group);
$cur->setField('activity_action', $action); $cur->setField('activity_action', $action);
$cur->setField('activity_logs', json_encode($logs)); $cur->setField('activity_logs', json_encode($logs));
@ -253,13 +271,13 @@ class ActivityReport
$cur->setField('activity_status', self::STATUS_PENDING); $cur->setField('activity_status', self::STATUS_PENDING);
$cur->insert(); $cur->insert();
dcCore::app()->con->unlock(); App::con()->unlock();
# --BEHAVIOR-- coreAfterCategoryCreate -- ActivityReport, cursor # --BEHAVIOR-- coreAfterCategoryCreate -- ActivityReport, cursor
dcCore::app()->callBehavior('activityReportAfteAddLog', $this, $cur); App::behavior()->callBehavior('activityReportAfteAddLog', $this, $cur);
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->con->unlock(); App::con()->unlock();
dcCore::app()->error->add($e->getMessage()); App::error()->add($e->getMessage());
} }
// Test if email report is needed // Test if email report is needed
@ -301,7 +319,7 @@ class ActivityReport
$from = time(); $from = time();
$to = 0; $to = 0;
$res = $blog_name = $blog_url = $group = ''; $res = $blog_name = $blog_url = $group = '';
$tz = dcCore::app()->blog?->settings->get('system')->get('blog_timezone'); $tz = App::blog()->settings()->get('system')->get('blog_timezone');
$tz = is_string($tz) ? $tz : 'UTC'; $tz = is_string($tz) ? $tz : 'UTC';
$dt = empty($this->settings->dateformat) ? '%Y-%m-%d %H:%M:%S' : $this->settings->dateformat; $dt = empty($this->settings->dateformat) ? '%Y-%m-%d %H:%M:%S' : $this->settings->dateformat;
$format = $this->formats->get($this->formats->has($this->settings->mailformat) ? $this->settings->mailformat : 'plain'); $format = $this->formats->get($this->formats->has($this->settings->mailformat) ? $this->settings->mailformat : 'plain');
@ -394,7 +412,7 @@ class ActivityReport
{ {
// Get blogs and logs count // Get blogs and logs count
$sql = new SelectStatement(); $sql = new SelectStatement();
$sql->from(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME) $sql->from(App::con()->prefix() . My::ACTIVITY_TABLE_NAME)
->column('blog_id') ->column('blog_id')
->where('activity_type =' . $sql->quote($this->type)) ->where('activity_type =' . $sql->quote($this->type))
->group('blog_id'); ->group('blog_id');
@ -410,16 +428,16 @@ class ActivityReport
$obs = Date::str('%Y-%m-%d %H:%M:%S', $ts - (int) $this->settings->obsolete); $obs = Date::str('%Y-%m-%d %H:%M:%S', $ts - (int) $this->settings->obsolete);
if (is_string($rs->f('blog_id'))) { if (is_string($rs->f('blog_id'))) {
$sql = new DeleteStatement(); $sql = new DeleteStatement();
$sql->from(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME) $sql->from(App::con()->prefix() . My::ACTIVITY_TABLE_NAME)
->where('activity_type =' . $sql->quote($this->type)) ->where('activity_type =' . $sql->quote($this->type))
->and('activity_dt < TIMESTAMP ' . $sql->quote($obs)) ->and('activity_dt < TIMESTAMP ' . $sql->quote($obs))
->and('blog_id = ' . $sql->quote($rs->f('blog_id'))) ->and('blog_id = ' . $sql->quote($rs->f('blog_id')))
->delete(); ->delete();
if (dcCore::app()->con->changes()) { if (App::con()->changes()) {
try { try {
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME); $cur = App::con()->openCursor(App::con()->prefix() . My::ACTIVITY_TABLE_NAME);
dcCore::app()->con->writeLock(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME); App::con()->writeLock(App::con()->prefix() . My::ACTIVITY_TABLE_NAME);
$cur->setField('activity_id', $this->getNextId()); $cur->setField('activity_id', $this->getNextId());
$cur->setField('activity_type', $this->type); $cur->setField('activity_type', $this->type);
@ -431,10 +449,10 @@ class ActivityReport
$cur->setField('activity_status', self::STATUS_PENDING); $cur->setField('activity_status', self::STATUS_PENDING);
$cur->insert(); $cur->insert();
dcCore::app()->con->unlock(); App::con()->unlock();
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->con->unlock(); App::con()->unlock();
dcCore::app()->error->add($e->getMessage()); App::error()->add($e->getMessage());
} }
} }
} }
@ -456,7 +474,7 @@ class ActivityReport
$sql->and('activity_status = ' . self::STATUS_REPORTED); $sql->and('activity_status = ' . self::STATUS_REPORTED);
} }
return $sql->from(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME) return $sql->from(App::con()->prefix() . My::ACTIVITY_TABLE_NAME)
->where('activity_type = ' . $sql->quote($this->type)) ->where('activity_type = ' . $sql->quote($this->type))
->delete(); ->delete();
} }
@ -470,10 +488,10 @@ class ActivityReport
private function updateStatus(int $from_date_ts, int $to_date_ts): void private function updateStatus(int $from_date_ts, int $to_date_ts): void
{ {
$sql = new UpdateStatement(); $sql = new UpdateStatement();
$sql->from(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME) $sql->from(App::con()->prefix() . My::ACTIVITY_TABLE_NAME)
->column('activity_status') ->column('activity_status')
->set((string) self::STATUS_REPORTED) ->set((string) self::STATUS_REPORTED)
->where('blog_id = ' . $sql->quote((string) dcCore::app()->blog?->id)) ->where('blog_id = ' . $sql->quote(App::blog()->id()))
->and('activity_type =' . $sql->quote($this->type)) ->and('activity_type =' . $sql->quote($this->type))
->and('activity_dt >= TIMESTAMP ' . $sql->quote(date('Y-m-d H:i:s', $from_date_ts))) ->and('activity_dt >= TIMESTAMP ' . $sql->quote(date('Y-m-d H:i:s', $from_date_ts)))
->and('activity_dt < TIMESTAMP ' . $sql->quote(date('Y-m-d H:i:s', $to_date_ts))) ->and('activity_dt < TIMESTAMP ' . $sql->quote(date('Y-m-d H:i:s', $to_date_ts)))
@ -488,7 +506,7 @@ class ActivityReport
public function getNextId(): int public function getNextId(): int
{ {
$sql = new SelectStatement(); $sql = new SelectStatement();
$sql->from(dcCore::app()->prefix . My::ACTIVITY_TABLE_NAME) $sql->from(App::con()->prefix() . My::ACTIVITY_TABLE_NAME)
->column($sql->max('activity_id')); ->column($sql->max('activity_id'));
return (int) $sql->select()?->f(0) + 1; return (int) $sql->select()?->f(0) + 1;
@ -503,14 +521,14 @@ class ActivityReport
{ {
try { try {
# Cache writable ? # Cache writable ?
if (!is_writable(DC_TPL_CACHE)) { if (!is_writable(App::config()->cacheRoot())) {
throw new Exception("Can't write in cache fodler"); throw new Exception("Can't write in cache fodler");
} }
# Set file path # Set file path
$f_md5 = md5((string) dcCore::app()->blog?->id); $f_md5 = md5(App::blog()->id());
$file = sprintf( $file = sprintf(
'%s/%s/%s/%s/%s.txt', '%s/%s/%s/%s/%s.txt',
DC_TPL_CACHE, App::config()->cacheRoot(),
My::id(), My::id(),
substr($f_md5, 0, 2), substr($f_md5, 0, 2),
substr($f_md5, 2, 2), substr($f_md5, 2, 2),
@ -591,7 +609,7 @@ class ActivityReport
$params = new ArrayObject([ $params = new ArrayObject([
'from_date_ts' => $lastreport, 'from_date_ts' => $lastreport,
'to_date_ts' => $now, 'to_date_ts' => $now,
'blog_id' => dcCore::app()->blog?->id, 'blog_id' => App::blog()->id(),
'activity_status' => self::STATUS_PENDING, 'activity_status' => self::STATUS_PENDING,
'requests' => true, 'requests' => true,
'order' => 'activity_group ASC, activity_action ASC, activity_dt ASC ', 'order' => 'activity_group ASC, activity_action ASC, activity_dt ASC ',
@ -612,7 +630,7 @@ class ActivityReport
$this->updateStatus($lastreport, $now); $this->updateStatus($lastreport, $now);
$this->settings->set('lastreport', $now); $this->settings->set('lastreport', $now);
dcCore::app()->callBehavior('messageActivityReport', 'Activity report has been successfully send by mail.'); App::behavior()->callBehavior('messageActivityReport', 'Activity report has been successfully send by mail.');
} }
} }
@ -658,20 +676,20 @@ class ActivityReport
# Sending mails # Sending mails
try { try {
$subject = mb_encode_mimeheader( $subject = mb_encode_mimeheader(
sprintf(__('Blog "%s" activity report'), dcCore::app()->blog?->name), sprintf(__('Blog "%s" activity report'), App::blog()->name()),
'UTF-8', 'UTF-8',
'B' 'B'
); );
$headers = []; $headers = [];
$headers[] = 'From: ' . (defined('DC_ADMIN_MAILFROM') && str_contains(DC_ADMIN_MAILFROM, '@') ? DC_ADMIN_MAILFROM : 'dotclear@local'); $headers[] = 'From: ' . (defined('DC_ADMIN_MAILFROM') && str_contains(App::config()->adminMailFrom(), '@') ? App::config()->adminMailFrom() : 'dotclear@local');
$headers[] = 'Content-Type: text/' . $mailformat . '; charset=UTF-8;'; $headers[] = 'Content-Type: text/' . $mailformat . '; charset=UTF-8;';
//$headers[] = 'MIME-Version: 1.0'; //$headers[] = 'MIME-Version: 1.0';
//$headers[] = 'X-Originating-IP: ' . mb_encode_mimeheader(Http::realIP(), 'UTF-8', 'B'); //$headers[] = 'X-Originating-IP: ' . mb_encode_mimeheader(Http::realIP(), 'UTF-8', 'B');
//$headers[] = 'X-Mailer: Dotclear'; //$headers[] = 'X-Mailer: Dotclear';
//$headers[] = 'X-Blog-Id: ' . mb_encode_mimeheader(dcCore::app()->blog->id), 'UTF-8', 'B'); //$headers[] = 'X-Blog-Id: ' . mb_encode_mimeheader(App::blog()->id()), 'UTF-8', 'B');
//$headers[] = 'X-Blog-Name: ' . mb_encode_mimeheader(dcCore::app()->blog->name), 'UTF-8', 'B'); //$headers[] = 'X-Blog-Name: ' . mb_encode_mimeheader(App::blog()->name()), 'UTF-8', 'B');
//$headers[] = 'X-Blog-Url: ' . mb_encode_mimeheader(dcCore::app()->blog->url), 'UTF-8', 'B'); //$headers[] = 'X-Blog-Url: ' . mb_encode_mimeheader(App::>blog()->url()), 'UTF-8', 'B');
$done = true; $done = true;
foreach ($recipients as $email) { foreach ($recipients as $email) {
@ -693,9 +711,9 @@ class ActivityReport
*/ */
public function getUserCode(): string public function getUserCode(): string
{ {
$id = is_string(dcCore::app()->auth->userID()) ? dcCore::app()->auth->userID() : ''; $id = is_string(App::auth()->userID()) ? App::auth()->userID() : '';
$pw = is_string(dcCore::app()->auth->getInfo('user_pwd')) ? dcCore::app()->auth->getInfo('user_pwd') : ''; $pw = is_string(App::auth()->getInfo('user_pwd')) ? App::auth()->getInfo('user_pwd') : '';
$code = pack('a32', $id) . pack('H*', Crypt::hmac(DC_MASTER_KEY, $pw)); $code = pack('a32', $id) . pack('H*', Crypt::hmac(App::config()->masterKey(), $pw));
return bin2hex($code); return bin2hex($code);
} }
@ -721,7 +739,7 @@ class ActivityReport
$pwd = $pwd['hex']; $pwd = $pwd['hex'];
$sql = new SelectStatement(); $sql = new SelectStatement();
$sql->from(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME) $sql->from(App::con()->prefix() . App::auth()::USER_TABLE_NAME)
->columns(['user_id', 'user_pwd']) ->columns(['user_id', 'user_pwd'])
->where('user_id =' . $sql->quote($user_id)); ->where('user_id =' . $sql->quote($user_id));
@ -731,7 +749,7 @@ class ActivityReport
return false; return false;
} }
if (Crypt::hmac(DC_MASTER_KEY, $rs->f('user_pwd')) != $pwd) { if (Crypt::hmac(App::config()->masterKey(), $rs->f('user_pwd')) != $pwd) {
return false; return false;
} }

View File

@ -1,23 +1,13 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use dcBlog; use Dotclear\App;
use dcCore; use Dotclear\Core\Process;
use dcUtils; use Dotclear\Interface\Core\BlogInterface;
use Dotclear\Database\{ use Dotclear\Database\{
Cursor, Cursor,
MetaRecord MetaRecord
@ -25,12 +15,27 @@ use Dotclear\Database\{
use Dotclear\Helper\Network\Http; use Dotclear\Helper\Network\Http;
/** /**
* @brief activityReport register class.
* @ingroup activityReport
*
* Register default activities and export mail formats. * Register default activities and export mail formats.
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class ActivityBehaviors class ActivityReportAction extends Process
{ {
public static function register(): void public static function init(): bool
{ {
return self::status(true);
}
public static function process(): bool
{
if (!self::status()) {
return false;
}
$my = new Group(My::id(), __('ActivityReport messages')); $my = new Group(My::id(), __('ActivityReport messages'));
$blog = new Group('blog', __('Actions on blog')); $blog = new Group('blog', __('Actions on blog'));
$post = new Group('post', __('Actions on posts')); $post = new Group('post', __('Actions on posts'));
@ -45,7 +50,7 @@ class ActivityBehaviors
__('Special messages'), __('Special messages'),
__('%s'), __('%s'),
'messageActivityReport', 'messageActivityReport',
[self::class, 'messageActivityReport'] self::messageActivityReport(...)
)); ));
// Not use as it is global : BEHAVIOR adminAfterBlogCreate in admin/blog.php // Not use as it is global : BEHAVIOR adminAfterBlogCreate in admin/blog.php
@ -56,7 +61,7 @@ class ActivityBehaviors
__('updating blog'), __('updating blog'),
__('Blog was updated by "%s"'), __('Blog was updated by "%s"'),
'adminAfterBlogUpdate', 'adminAfterBlogUpdate',
[self::class, 'blogUpdate'] self::blogUpdate(...)
)); ));
// from BEHAVIOR publicHeadContent in template // from BEHAVIOR publicHeadContent in template
@ -65,7 +70,7 @@ class ActivityBehaviors
__('404 error'), __('404 error'),
__('New 404 error page at "%s"'), __('New 404 error page at "%s"'),
'publicHeadContent', 'publicHeadContent',
[self::class, 'blogP404'] self::blogP404(...)
)); ));
// from BEHAVIOR coreAfterPostCreate in inc/core/class.dc.blog.php (DC 2.2) // from BEHAVIOR coreAfterPostCreate in inc/core/class.dc.blog.php (DC 2.2)
@ -76,7 +81,7 @@ class ActivityBehaviors
__('post creation'), __('post creation'),
__('A new post called "%s" was created by "%s" at %s'), __('A new post called "%s" was created by "%s" at %s'),
'adminAfterPostCreate', 'adminAfterPostCreate',
[self::class, 'postCreate'] self::postCreate(...)
)); ));
// Plugin contribute // Plugin contribute
@ -86,7 +91,7 @@ class ActivityBehaviors
__('post creation'), __('post creation'),
__('A new post called "%s" was created by "%s" at %s'), __('A new post called "%s" was created by "%s" at %s'),
'publicAfterPostCreate', 'publicAfterPostCreate',
[self::class, 'postCreate'] self::postCreate(...)
)); ));
// from BEHAVIOR coreAfterPostUpdate in inc/core/class.dc.blog.php (DC2.2) // from BEHAVIOR coreAfterPostUpdate in inc/core/class.dc.blog.php (DC2.2)
@ -96,7 +101,7 @@ class ActivityBehaviors
__('updating post'), __('updating post'),
__('Post called "%s" has been updated by "%s" at %s'), __('Post called "%s" has been updated by "%s" at %s'),
'adminAfterPostUpdate', 'adminAfterPostUpdate',
[self::class, 'postUpdate'] self::postUpdate(...)
)); ));
// from BEHAVIOR adminBeforePostDelete in admin/post.php // from BEHAVIOR adminBeforePostDelete in admin/post.php
@ -105,7 +110,7 @@ class ActivityBehaviors
__('post deletion'), __('post deletion'),
__('Post called "%s" has been deleted by "%s"'), __('Post called "%s" has been deleted by "%s"'),
'adminBeforePostDelete', 'adminBeforePostDelete',
[self::class, 'postDelete'] self::postDelete(...)
)); ));
// Wrong attempt on passworded enrty // Wrong attempt on passworded enrty
@ -115,7 +120,7 @@ class ActivityBehaviors
__('Post protection'), __('Post protection'),
__('An attempt failed on a passworded post with password "%s" at "%s"'), __('An attempt failed on a passworded post with password "%s" at "%s"'),
'urlHandlerServeDocument', 'urlHandlerServeDocument',
[self::class, 'postPasswordAttempt'] self::postPasswordAttempt(...)
)); ));
// from BEHAVIOR coreAfterCommentCreate in inc/core/class.dc.blog.php // from BEHAVIOR coreAfterCommentCreate in inc/core/class.dc.blog.php
@ -126,7 +131,7 @@ class ActivityBehaviors
__('comment creation'), __('comment creation'),
__('A new comment was created by "%s" on post "%s" at %s'), __('A new comment was created by "%s" on post "%s" at %s'),
'coreAfterCommentCreate', 'coreAfterCommentCreate',
[self::class, 'commentCreate'] self::commentCreate(...)
)); ));
// from BEHAVIOR coreAfterCommentUpdate in inc/core/class.dc.blog.php // from BEHAVIOR coreAfterCommentUpdate in inc/core/class.dc.blog.php
@ -136,7 +141,7 @@ class ActivityBehaviors
__('updating comment'), __('updating comment'),
__('Comment has been updated by "%s" at %s'), __('Comment has been updated by "%s" at %s'),
'coreAfterCommentUpdate', 'coreAfterCommentUpdate',
[self::class, 'commentUpdate'] self::commentUpdate(...)
)); ));
// Missing coreBeforeCommentDelete in inc/core/class.dc.blog.php // Missing coreBeforeCommentDelete in inc/core/class.dc.blog.php
@ -149,7 +154,7 @@ class ActivityBehaviors
__('trackback creation'), __('trackback creation'),
__('A new trackback to "%" at "%s" was created on post "%s" at %s'), __('A new trackback to "%" at "%s" was created on post "%s" at %s'),
'coreAfterCommentCreate', 'coreAfterCommentCreate',
[self::class, 'trackbackCreate'] self::trackbackCreate(...)
)); ));
// from BEHAVIOR adminAfterCategoryCreate in admin/category.php // from BEHAVIOR adminAfterCategoryCreate in admin/category.php
@ -158,7 +163,7 @@ class ActivityBehaviors
__('category creation'), __('category creation'),
__('A new category called "%s" was created by "%s" at %s'), __('A new category called "%s" was created by "%s" at %s'),
'adminAfterCategoryCreate', 'adminAfterCategoryCreate',
[self::class, 'categoryCreate'] self::categoryCreate(...)
)); ));
// from BEHAVIOR adminAfterCategoryUpdate in admin/category.php // from BEHAVIOR adminAfterCategoryUpdate in admin/category.php
@ -167,7 +172,7 @@ class ActivityBehaviors
__('updating category'), __('updating category'),
__('Category called "%s" has been updated by "%s" at %s'), __('Category called "%s" has been updated by "%s" at %s'),
'adminAfterCategoryUpdate', 'adminAfterCategoryUpdate',
[self::class, 'categoryUpdate'] self::categoryUpdate(...)
)); ));
// Missing adminBeforeCategoryDelete in admin/category.php // Missing adminBeforeCategoryDelete in admin/category.php
@ -178,7 +183,7 @@ class ActivityBehaviors
__('user creation'), __('user creation'),
__('A new user named "%s" was created by "%s"'), __('A new user named "%s" was created by "%s"'),
'adminAfterUserCreate', 'adminAfterUserCreate',
[self::class, 'userCreate'] self::userCreate(...)
)); ));
// from BEHAVIOR adminAfterUserUpdated in admin/user.php // from BEHAVIOR adminAfterUserUpdated in admin/user.php
@ -187,7 +192,7 @@ class ActivityBehaviors
__('updating user'), __('updating user'),
__('User named "%s" has been updated by "%s"'), __('User named "%s" has been updated by "%s"'),
'adminAfterUserUpdate', 'adminAfterUserUpdate',
[self::class, 'userUpdate'] self::userUpdate(...)
)); ));
// from BEHAVIOR adminAfterUserProfileUpdate in admin/preferences.php // from BEHAVIOR adminAfterUserProfileUpdate in admin/preferences.php
@ -196,21 +201,21 @@ class ActivityBehaviors
__('updating user preference'), __('updating user preference'),
__('"%s" user preference has been updated'), __('"%s" user preference has been updated'),
'adminAfterUserProfileUpdate', 'adminAfterUserProfileUpdate',
[self::class, 'userPreference'] self::userPreference(...)
)); ));
$user->add(new Action( $user->add(new Action(
'preference', 'preference',
__('updating user preference'), __('updating user preference'),
__('"%s" user preference has been updated'), __('"%s" user preference has been updated'),
'adminAfterUserOptionsUpdate', 'adminAfterUserOptionsUpdate',
[self::class, 'userPreference'] self::userPreference(...)
)); ));
$user->add(new Action( $user->add(new Action(
'preference', 'preference',
__('updating user preference'), __('updating user preference'),
__('"%s" user preference has been updated'), __('"%s" user preference has been updated'),
'adminAfterDashboardOptionsUpdate', 'adminAfterDashboardOptionsUpdate',
[self::class, 'userOption'] self::userOption(...)
)); ));
// from BEHAVIOR adminBeforeUserDelete in admin/users.php // from BEHAVIOR adminBeforeUserDelete in admin/users.php
@ -219,7 +224,7 @@ class ActivityBehaviors
__('user deletion'), __('user deletion'),
__('User named "%s" has been deleted by "%"'), __('User named "%s" has been deleted by "%"'),
'adminBeforeUserDelete', 'adminBeforeUserDelete',
[self::class, 'userDelete'] self::userDelete(...)
)); ));
ActivityReport::instance()->groups ActivityReport::instance()->groups
@ -264,6 +269,8 @@ class ActivityBehaviors
'<div class="foot"><p>Powered by <a href="https://github.com/JcDenis/activityReport">activityReport</a></p></div>' . '<div class="foot"><p>Powered by <a href="https://github.com/JcDenis/activityReport">activityReport</a></p></div>' .
'</body></html>', '</body></html>',
])); ]));
return true;
} }
public static function messageActivityReport(string $message): void public static function messageActivityReport(string $message): void
@ -274,26 +281,26 @@ class ActivityBehaviors
public static function blogUpdate(Cursor $cur, string $blog_id): void public static function blogUpdate(Cursor $cur, string $blog_id): void
{ {
$logs = [self::str(dcCore::app()->auth->getInfo('user_cn'))]; $logs = [self::str(App::auth()->getInfo('user_cn'))];
ActivityReport::instance()->addLog('blog', 'update', $logs); ActivityReport::instance()->addLog('blog', 'update', $logs);
} }
public static function blogP404(): void public static function blogP404(): void
{ {
if (dcCore::app()->url->type != '404') { if (App::url()->type != '404') {
return; return;
} }
$logs = [self::str(dcCore::app()->blog?->url) . $_SERVER['QUERY_STRING']]; $logs = [self::str(App::blog()->url()) . $_SERVER['QUERY_STRING']];
ActivityReport::instance()->addLog('blog', 'p404', $logs); ActivityReport::instance()->addLog('blog', 'p404', $logs);
} }
public static function postCreate(Cursor $cur, int $post_id): void public static function postCreate(Cursor $cur, int $post_id): void
{ {
$post_url = dcCore::app()->blog?->getPostURL('', self::str($cur->getField('post_dt')), self::str($cur->getField('post_title')), $post_id); $post_url = App::blog()->getPostURL('', self::str($cur->getField('post_dt')), self::str($cur->getField('post_title')), $post_id);
$logs = [ $logs = [
self::str($cur->getField('post_title')), self::str($cur->getField('post_title')),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase(self::str($cur->getField('post_type'))) . '/' . $post_url, self::str(App::blog()->url()) . App::url()->getBase(self::str($cur->getField('post_type'))) . '/' . $post_url,
]; ];
ActivityReport::instance()->addLog('post', 'create', $logs); ActivityReport::instance()->addLog('post', 'create', $logs);
} }
@ -301,24 +308,24 @@ class ActivityBehaviors
public static function postUpdate(Cursor $cur, int|string $post_id): void public static function postUpdate(Cursor $cur, int|string $post_id): void
{ {
$post_id = is_numeric($post_id) ? (int) $post_id : 0; $post_id = is_numeric($post_id) ? (int) $post_id : 0;
$post_url = dcCore::app()->blog?->getPostURL('', self::str($cur->getField('post_dt')), self::str($cur->getField('post_title')), $post_id); $post_url = App::blog()->getPostURL('', self::str($cur->getField('post_dt')), self::str($cur->getField('post_title')), $post_id);
$logs = [ $logs = [
self::str($cur->getField('post_title')), self::str($cur->getField('post_title')),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase(self::str($cur->getField('post_type'))) . '/' . $post_url, self::str(App::blog()->url()) . App::url()->getBase(self::str($cur->getField('post_type'))) . '/' . $post_url,
]; ];
ActivityReport::instance()->addLog('post', 'update', $logs); ActivityReport::instance()->addLog('post', 'update', $logs);
} }
public static function postDelete(int $post_id): void public static function postDelete(int $post_id): void
{ {
$posts = dcCore::app()->blog?->getPosts(['post_id' => $post_id, 'limit' => 1]); $posts = App::blog()->getPosts(['post_id' => $post_id, 'limit' => 1]);
if (!$posts || $posts->isEmpty()) { if ($posts->isEmpty()) {
return; return;
} }
$logs = [ $logs = [
self::str($posts->f('post_title')), self::str($posts->f('post_title')),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
]; ];
ActivityReport::instance()->addLog('post', 'delete', $logs); ActivityReport::instance()->addLog('post', 'delete', $logs);
} }
@ -335,55 +342,55 @@ class ActivityBehaviors
ActivityReport::instance()->addLog('post', 'protection', $logs); ActivityReport::instance()->addLog('post', 'protection', $logs);
} }
public static function commentCreate(dcBlog $blog, Cursor $cur): void public static function commentCreate(BlogInterface $blog, Cursor $cur): void
{ {
if ($cur->getField('comment_trackback')) { if ($cur->getField('comment_trackback')) {
return; return;
} }
$posts = dcCore::app()->blog?->getPosts( $posts = App::blog()->getPosts(
['post_id' => $cur->getField('post_id'), 'limit' => 1, 'post_type' => ''] ['post_id' => $cur->getField('post_id'), 'limit' => 1, 'post_type' => '']
); );
if (!$posts || $posts->isEmpty()) { if ($posts->isEmpty()) {
return; return;
} }
$logs = [ $logs = [
self::str($cur->getField('comment_author')), self::str($cur->getField('comment_author')),
self::str($posts->f('post_title')), self::str($posts->f('post_title')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase(self::str($posts->f('post_type'))) . self::str(App::blog()->url()) . App::url()->getBase(self::str($posts->f('post_type'))) .
'/' . self::str($posts->f('post_url')) . '#c' . self::str($cur->getField('comment_id')), '/' . self::str($posts->f('post_url')) . '#c' . self::str($cur->getField('comment_id')),
]; ];
ActivityReport::instance()->addLog('comment', 'create', $logs); ActivityReport::instance()->addLog('comment', 'create', $logs);
} }
public static function commentUpdate(dcBlog $blog, Cursor $cur, MetaRecord $old): void public static function commentUpdate(BlogInterface $blog, Cursor $cur, MetaRecord $old): void
{ {
$posts = dcCore::app()->blog?->getPosts( $posts = App::blog()->getPosts(
['post_id' => $old->f('post_id'), 'limit' => 1] ['post_id' => $old->f('post_id'), 'limit' => 1]
); );
if (!$posts || $posts->isEmpty()) { if ($posts->isEmpty()) {
return; return;
} }
$logs = [ $logs = [
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
self::str($posts->f('post_title')), self::str($posts->f('post_title')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase(self::str($posts->f('post_type'))) . self::str(App::blog()->url()) . App::url()->getBase(self::str($posts->f('post_type'))) .
'/' . self::str($posts->f('post_url')) . '#c' . self::str($old->f('comment_id')), '/' . self::str($posts->f('post_url')) . '#c' . self::str($old->f('comment_id')),
]; ];
ActivityReport::instance()->addLog('comment', 'update', $logs); ActivityReport::instance()->addLog('comment', 'update', $logs);
} }
public static function trackbackCreate(dcBlog $blog, Cursor $cur): void public static function trackbackCreate(BlogInterface $blog, Cursor $cur): void
{ {
if (!$cur->getField('comment_trackback')) { if (!$cur->getField('comment_trackback')) {
return; return;
} }
$posts = dcCore::app()->blog?->getPosts( $posts = App::blog()->getPosts(
['post_id' => $cur->getField('post_id'), 'no_content' => true, 'limit' => 1] ['post_id' => $cur->getField('post_id'), 'no_content' => true, 'limit' => 1]
); );
if (!$posts || $posts->isEmpty()) { if ($posts->isEmpty()) {
return; return;
} }
@ -391,7 +398,7 @@ class ActivityBehaviors
self::str($cur->getField('comment_author')), self::str($cur->getField('comment_author')),
self::str($cur->getField('comment_site')), self::str($cur->getField('comment_site')),
self::str($posts->f('post_title')), self::str($posts->f('post_title')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase(self::str($posts->f('post_type'))) . self::str(App::blog()->url()) . App::url()->getBase(self::str($posts->f('post_type'))) .
'/' . self::str($posts->f('post_url')), '/' . self::str($posts->f('post_url')),
]; ];
ActivityReport::instance()->addLog('comment', 'trackback', $logs); ActivityReport::instance()->addLog('comment', 'trackback', $logs);
@ -401,8 +408,8 @@ class ActivityBehaviors
{ {
$logs = [ $logs = [
self::str($cur->getField('cat_title')), self::str($cur->getField('cat_title')),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase('category') . '/' . self::str($cur->getField('cat_url')), self::str(App::blog()->url()) . App::url()->getBase('category') . '/' . self::str($cur->getField('cat_url')),
]; ];
ActivityReport::instance()->addLog('category', 'create', $logs); ActivityReport::instance()->addLog('category', 'create', $logs);
} }
@ -411,15 +418,15 @@ class ActivityBehaviors
{ {
$logs = [ $logs = [
self::str($cur->getField('cat_title')), self::str($cur->getField('cat_title')),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
self::str(dcCore::app()->blog?->url) . dcCore::app()->url->getBase('category') . '/' . self::str($cur->getField('cat_url')), self::str(App::blog()->url()) . App::url()->getBase('category') . '/' . self::str($cur->getField('cat_url')),
]; ];
ActivityReport::instance()->addLog('category', 'update', $logs); ActivityReport::instance()->addLog('category', 'update', $logs);
} }
public static function userCreate(Cursor $cur, string $user_id): void public static function userCreate(Cursor $cur, string $user_id): void
{ {
$user_cn = dcUtils::getUserCN( $user_cn = App::users()->getUserCN(
self::str($cur->getField('user_id')), self::str($cur->getField('user_id')),
self::str($cur->getField('user_name')), self::str($cur->getField('user_name')),
self::str($cur->getField('user_firstname')), self::str($cur->getField('user_firstname')),
@ -427,14 +434,14 @@ class ActivityBehaviors
); );
$logs = [ $logs = [
self::str($user_cn), self::str($user_cn),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
]; ];
ActivityReport::instance()->addLog('user', 'create', $logs); ActivityReport::instance()->addLog('user', 'create', $logs);
} }
public static function userUpdate(Cursor $cur, string $user_id): void public static function userUpdate(Cursor $cur, string $user_id): void
{ {
$user_cn = dcUtils::getUserCN( $user_cn = App::users()->getUserCN(
self::str($cur->getField('user_id')), self::str($cur->getField('user_id')),
self::str($cur->getField('user_name')), self::str($cur->getField('user_name')),
self::str($cur->getField('user_firstname')), self::str($cur->getField('user_firstname')),
@ -442,7 +449,7 @@ class ActivityBehaviors
); );
$logs = [ $logs = [
self::str($user_cn), self::str($user_cn),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
]; ];
ActivityReport::instance()->addLog('user', 'update', $logs); ActivityReport::instance()->addLog('user', 'update', $logs);
} }
@ -454,11 +461,11 @@ class ActivityBehaviors
public static function userOption(string $user_id): void public static function userOption(string $user_id): void
{ {
$user = dcCore::app()->getUser($user_id); $user = App::users()->getUser($user_id);
if ($user->isEmpty()) { if ($user->isEmpty()) {
return; return;
} }
$user_cn = dcUtils::getUserCN( $user_cn = App::users()->getUserCN(
self::str($user->f('user_id')), self::str($user->f('user_id')),
self::str($user->f('user_name')), self::str($user->f('user_name')),
self::str($user->f('user_firstname')), self::str($user->f('user_firstname')),
@ -472,8 +479,8 @@ class ActivityBehaviors
public static function userDelete(string $user_id): void public static function userDelete(string $user_id): void
{ {
$users = dcCore::app()->getUser($user_id); $users = App::users()->getUser($user_id);
$user_cn = dcUtils::getUserCN( $user_cn = App::users()->getUserCN(
self::str($users->f('user_id')), self::str($users->f('user_id')),
self::str($users->f('user_name')), self::str($users->f('user_name')),
self::str($users->f('user_firstname')), self::str($users->f('user_firstname')),
@ -481,7 +488,7 @@ class ActivityBehaviors
); );
$logs = [ $logs = [
self::str($user_cn), self::str($user_cn),
self::str(dcCore::app()->auth->getInfo('user_cn')), self::str(App::auth()->getInfo('user_cn')),
]; ];
ActivityReport::instance()->addLog('user', 'delete', $logs); ActivityReport::instance()->addLog('user', 'delete', $logs);
} }

View File

@ -1,15 +1,5 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
@ -17,7 +7,11 @@ namespace Dotclear\Plugin\activityReport;
use Dotclear\Database\MetaRecord; use Dotclear\Database\MetaRecord;
/** /**
* Activity record row type hinting. * @brief activityReport activity record row descriptor class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class ActivityRow class ActivityRow
{ {

View File

@ -1,22 +1,11 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use dcAuth; use Dotclear\App;
use dcCore;
use Dotclear\Core\Backend\Favorites; use Dotclear\Core\Backend\Favorites;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Helper\Date; use Dotclear\Helper\Date;
@ -29,7 +18,11 @@ use Dotclear\Helper\Html\Form\{
}; };
/** /**
* Backend process * @brief activityReport backend class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Backend extends Process class Backend extends Process
{ {
@ -44,9 +37,12 @@ class Backend extends Process
return false; return false;
} }
// be sure to init report
ActivityReport::init();
My::addBackendMenuItem(); My::addBackendMenuItem();
dcCore::app()->addBehaviors([ App::behavior()->addBehaviors([
// dashboard favorites icon // dashboard favorites icon
'adminDashboardFavoritesV2' => function (Favorites $favs): void { 'adminDashboardFavoritesV2' => function (Favorites $favs): void {
$favs->register(My::id(), [ $favs->register(My::id(), [
@ -54,14 +50,14 @@ class Backend extends Process
'url' => My::manageUrl(), 'url' => My::manageUrl(),
'small-icon' => My::icons(), 'small-icon' => My::icons(),
'large-icon' => My::icons(), 'large-icon' => My::icons(),
'permissions' => dcCore::app()->auth->makePermissions([ 'permissions' => App::auth()->makePermissions([
dcAuth::PERMISSION_ADMIN, App::auth()::PERMISSION_ADMIN,
]), ]),
]); ]);
}, },
// dashboard content display // dashboard content display
'adminDashboardContentsV2' => function (ArrayObject $items): void { 'adminDashboardContentsV2' => function (ArrayObject $items): void {
$db = dcCore::app()->auth->user_prefs?->get(My::id())->get('dashboard_item'); $db = App::auth()->prefs()->get(My::id())->get('dashboard_item');
$limit = abs(is_numeric($db) ? (int) $db : 0); $limit = abs(is_numeric($db) ? (int) $db : 0);
if (!$limit) { if (!$limit) {
return ; return ;
@ -87,9 +83,9 @@ class Backend extends Process
$lines[] = '<dt title="' . __($group->title) . '">' . $lines[] = '<dt title="' . __($group->title) . '">' .
'<strong>' . __($group->get($row->action)->title) . '</strong>' . '<strong>' . __($group->get($row->action)->title) . '</strong>' .
'<br />' . Date::str( '<br />' . Date::str(
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'), App::blog()->settings()->get('system')->get('date_format') . ', ' . App::blog()->settings()->get('system')->get('time_format'),
(int) strtotime($row->dt), (int) strtotime($row->dt),
is_string(dcCore::app()->auth->getInfo('user_tz')) ? dcCore::app()->auth->getInfo('user_tz') : 'UTC' is_string(App::auth()->getInfo('user_tz')) ? App::auth()->getInfo('user_tz') : 'UTC'
) . '<dt>' . ) . '<dt>' .
'<dd><p>' . '<dd><p>' .
'<em>' . ActivityReport::parseMessage(__($group->get($row->action)->message), $row->logs) . '</em></p></dd>'; '<em>' . ActivityReport::parseMessage(__($group->get($row->action)->message), $row->logs) . '</em></p></dd>';
@ -105,10 +101,10 @@ class Backend extends Process
'<p class="modules"><a class="module-details" href="' . '<p class="modules"><a class="module-details" href="' .
My::manageUrl() . '">' . My::manageUrl() . '">' .
__('View all logs') . '</a> - <a class="module-config" href="' . __('View all logs') . '</a> - <a class="module-config" href="' .
dcCore::app()->admin->url->get('admin.plugins', [ App::backend()->url()->get('admin.plugins', [
'module' => My::id(), 'module' => My::id(),
'conf' => 1, 'conf' => 1,
'redir' => dcCore::app()->admin->url->get('admin.home'), 'redir' => App::backend()->url()->get('admin.home'),
]) . '">' . ]) . '">' .
__('Configure plugin') . '</a></p>' . __('Configure plugin') . '</a></p>' .
'</div>', '</div>',
@ -116,7 +112,7 @@ class Backend extends Process
}, },
// dashboard content user preference form // dashboard content user preference form
'adminDashboardOptionsFormV2' => function (): void { 'adminDashboardOptionsFormV2' => function (): void {
$db = dcCore::app()->auth->user_prefs?->get(My::id())->get('dashboard_item'); $db = App::auth()->prefs()->get(My::id())->get('dashboard_item');
echo echo
(new Div())->class('fieldset')->items([ (new Div())->class('fieldset')->items([
(new Text('h4', My::name())), (new Text('h4', My::name())),
@ -137,7 +133,7 @@ class Backend extends Process
// save dashboard content user preference // save dashboard content user preference
'adminAfterDashboardOptionsUpdate' => function (?string $user_id = null): void { 'adminAfterDashboardOptionsUpdate' => function (?string $user_id = null): void {
if (!is_null($user_id)) { if (!is_null($user_id)) {
dcCore::app()->auth->user_prefs?->get(My::id())->put( App::auth()->prefs()->get(My::id())->put(
'dashboard_item', 'dashboard_item',
(int) $_POST[My::id() . '_dashboard_item'], (int) $_POST[My::id() . '_dashboard_item'],
'integer' 'integer'

View File

@ -1,21 +1,15 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
/** /**
* Combo helper. * @brief activityReport combo class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Combo class Combo
{ {

View File

@ -1,20 +1,10 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore; use Dotclear\App;
use Dotclear\Core\Backend\Notices; use Dotclear\Core\Backend\Notices;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Helper\Date; use Dotclear\Helper\Date;
@ -32,7 +22,11 @@ use Dotclear\Helper\Html\Form\{
use Exception; use Exception;
/** /**
* Config process. * @brief activityReport config class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Config extends Process class Config extends Process
{ {
@ -85,12 +79,12 @@ class Config extends Process
); );
} }
dcCore::app()->admin->url->redirect('admin.plugins', [ App::backend()->url()->redirect('admin.plugins', [
'module' => My::id(), 'module' => My::id(),
'conf' => 1, 'conf' => 1,
]); ]);
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->error->add($e->getMessage()); App::error()->add($e->getMessage());
} }
return true; return true;
@ -103,19 +97,19 @@ class Config extends Process
} }
$s = ActivityReport::instance()->settings; $s = ActivityReport::instance()->settings;
$tz = is_string(dcCore::app()->auth->getInfo('user_tz')) ? dcCore::app()->auth->getInfo('user_tz') : 'UTC'; $tz = is_string(App::auth()->getInfo('user_tz')) ? App::auth()->getInfo('user_tz') : 'UTC';
if (!$s->lastreport) { if (!$s->lastreport) {
$last_report = __('never'); $last_report = __('never');
$next_report = __('on new activity'); $next_report = __('on new activity');
} else { } else {
$last_report = Date::str( $last_report = Date::str(
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'), App::blog()->settings()->get('system')->get('date_format') . ', ' . App::blog()->settings()->get('system')->get('time_format'),
$s->lastreport, $s->lastreport,
$tz $tz
); );
$next_report = Date::str( $next_report = Date::str(
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'), App::blog()->settings()->get('system')->get('date_format') . ', ' . App::blog()->settings()->get('system')->get('time_format'),
$s->interval + $s->lastreport, $s->interval + $s->lastreport,
$tz $tz
); );
@ -166,11 +160,11 @@ class Config extends Process
'ul', 'ul',
'<li><img alt="' . __('RSS feed') . '" src="' . My::fileURL('img/feed.png') . '" /> ' . '<li><img alt="' . __('RSS feed') . '" src="' . My::fileURL('img/feed.png') . '" /> ' .
'<a title="' . __('RSS feed') . '" href="' . '<a title="' . __('RSS feed') . '" href="' .
dcCore::app()->blog?->url . dcCore::app()->url->getBase(My::id()) . '/rss2/' . ActivityReport::instance()->getUserCode() . '">' . App::blog()->url() . App::url()->getBase(My::id()) . '/rss2/' . ActivityReport::instance()->getUserCode() . '">' .
__('Rss2 activities feed') . '</a></li>' . __('Rss2 activities feed') . '</a></li>' .
'<li><img alt="' . __('Atom feed') . '" src="' . My::fileURL('img/feed.png') . '" /> ' . '<li><img alt="' . __('Atom feed') . '" src="' . My::fileURL('img/feed.png') . '" /> ' .
'<a title="' . __('Atom feed') . '" href="' . '<a title="' . __('Atom feed') . '" href="' .
dcCore::app()->blog?->url . dcCore::app()->url->getBase(My::id()) . '/atom/' . ActivityReport::instance()->getUserCode() . '">' . App::blog()->url() . App::url()->getBase(My::id()) . '/atom/' . ActivityReport::instance()->getUserCode() . '">' .
__('Atom activities feed') . '</a></li>' __('Atom activities feed') . '</a></li>'
)), )),
]), ]),

View File

@ -1,24 +1,18 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore; use Dotclear\App;
use Dotclear\Database\MetaRecord; use Dotclear\Database\MetaRecord;
/** /**
* Template helper. * @brief activityReport frontend context class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Context class Context
{ {
@ -29,15 +23,14 @@ class Context
*/ */
public static function parseTitle(): string public static function parseTitle(): string
{ {
if (!dcCore::app()->ctx if (!App::frontend()->context()->exists('activityreports')
|| !dcCore::app()->ctx->exists('activityreports') || !(App::frontend()->context()->__get('activityreports') instanceof MetaRecord)
|| !(dcCore::app()->ctx->__get('activityreports') instanceof MetaRecord)
) { ) {
return ''; return '';
} }
$group = dcCore::app()->ctx->__get('activityreports')->f('activity_group'); $group = App::frontend()->context()->__get('activityreports')->f('activity_group');
$action = dcCore::app()->ctx->__get('activityreports')->f('activity_action'); $action = App::frontend()->context()->__get('activityreports')->f('activity_action');
if (!is_string($group) if (!is_string($group)
|| !is_string($action) || !is_string($action)
@ -56,16 +49,15 @@ class Context
*/ */
public static function parseContent(): string public static function parseContent(): string
{ {
if (!dcCore::app()->ctx if (!App::frontend()->context()->exists('activityreports')
|| !dcCore::app()->ctx->exists('activityreports') || !(App::frontend()->context()->__get('activityreports') instanceof MetaRecord)
|| !(dcCore::app()->ctx->__get('activityreports') instanceof MetaRecord)
) { ) {
return ''; return '';
} }
$group = dcCore::app()->ctx->__get('activityreports')->f('activity_group'); $group = App::frontend()->context()->__get('activityreports')->f('activity_group');
$action = dcCore::app()->ctx->__get('activityreports')->f('activity_action'); $action = App::frontend()->context()->__get('activityreports')->f('activity_action');
$logs = dcCore::app()->ctx->__get('activityreports')->f('activity_logs'); $logs = App::frontend()->context()->__get('activityreports')->f('activity_logs');
$logs = json_decode(is_string($logs) ? $logs : '', true); $logs = json_decode(is_string($logs) ? $logs : '', true);
if (!is_string($group) if (!is_string($group)
@ -76,9 +68,9 @@ class Context
return ''; return '';
} }
dcCore::app()->initWikiComment(); App::filter()->initWikiComment();
return dcCore::app()->wikiTransform(vsprintf( return App::filter()->wikiTransform(vsprintf(
__(ActivityReport::instance()->groups->get($group)->get($action)->message), __(ActivityReport::instance()->groups->get($group)->get($action)->message),
$logs $logs
)); ));

View File

@ -1,21 +1,15 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
/** /**
* Report format descriptor. * @brief activityReport format decriptor.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Format class Format
{ {

View File

@ -1,21 +1,15 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
/** /**
* Email report formats stack. * @brief activityReport formats stack.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Formats class Formats
{ {

View File

@ -1,24 +1,18 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore; use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/** /**
* Front end process. * @brief activityReport frontend class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Frontend extends Process class Frontend extends Process
{ {
@ -33,13 +27,16 @@ class Frontend extends Process
return false; return false;
} }
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', 'tpl'])); // be sure to init report
ActivityReport::init();
dcCore::app()->tpl->addBlock('activityReports', [Template::class, 'activityReports']); App::frontend()->template()->setPath(App::frontend()->template()->getPath(), implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', 'tpl']));
dcCore::app()->tpl->addValue('activityReportFeedID', [Template::class, 'activityReportFeedID']);
dcCore::app()->tpl->addValue('activityReportTitle', [Template::class, 'activityReportTitle']); App::frontend()->template()->addBlock('activityReports', Template::activityReports(...));
dcCore::app()->tpl->addValue('activityReportDate', [Template::class, 'activityReportDate']); App::frontend()->template()->addValue('activityReportFeedID', Template::activityReportFeedID(...));
dcCore::app()->tpl->addValue('activityReportContent', [Template::class, 'activityReportContent']); App::frontend()->template()->addValue('activityReportTitle', Template::activityReportTitle(...));
App::frontend()->template()->addValue('activityReportDate', Template::activityReportDate(...));
App::frontend()->template()->addValue('activityReportContent', Template::activityReportContent(...));
return true; return true;
} }

View File

@ -1,21 +1,15 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
/** /**
* Actions stack. * @brief activityReport actions stack class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Group class Group
{ {

View File

@ -1,25 +1,23 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
/** /**
* Actions groups stack. * @brief activityReport actions groups stack class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Groups class Groups
{ {
/** @var array<string, Group> $stack The actions groups stack */ /**
* The actions groups stack.
*
* @var array<string, Group> $stack
*/
private array $stack = []; private array $stack = [];
/** /**
@ -37,6 +35,8 @@ class Groups
/** /**
* Add a group. * Add a group.
* *
* Existing group will be overwritten.
*
* @param Group $group The group object * @param Group $group The group object
* *
* @return Groups The groups instance * @return Groups The groups instance

View File

@ -1,20 +1,10 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore; use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Database\Structure; use Dotclear\Database\Structure;
use Dotclear\Database\Statement\{ use Dotclear\Database\Statement\{
@ -24,7 +14,11 @@ use Dotclear\Database\Statement\{
use Exception; use Exception;
/** /**
* Install process. * @brief activityReport install class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Install extends Process class Install extends Process
{ {
@ -42,7 +36,7 @@ class Install extends Process
try { try {
self::beforeGrowUp(); self::beforeGrowUp();
$s = new Structure(dcCore::app()->con, dcCore::app()->prefix); $s = new Structure(App::con(), App::con()->prefix());
$s->__get(My::ACTIVITY_TABLE_NAME) $s->__get(My::ACTIVITY_TABLE_NAME)
->field('activity_id', 'bigint', 0, false) ->field('activity_id', 'bigint', 0, false)
->field('activity_type', 'varchar', 32, false, "'" . My::id() . "'") ->field('activity_type', 'varchar', 32, false, "'" . My::id() . "'")
@ -59,11 +53,11 @@ class Install extends Process
->index('idx_activity_action', 'btree', 'activity_group', 'activity_action') ->index('idx_activity_action', 'btree', 'activity_group', 'activity_action')
->index('idx_activity_status', 'btree', 'activity_status'); ->index('idx_activity_status', 'btree', 'activity_status');
(new Structure(dcCore::app()->con, dcCore::app()->prefix))->synchronize($s); (new Structure(App::con(), App::con()->prefix()))->synchronize($s);
return true; return true;
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->error->add($e->getMessage()); App::error()->add($e->getMessage());
return false; return false;
} }
@ -75,17 +69,17 @@ class Install extends Process
private static function beforeGrowUp(): void private static function beforeGrowUp(): void
{ {
// sorry not sorry we restart from scratch // sorry not sorry we restart from scratch
if (is_string(dcCore::app()->getVersion('activityReport')) if (is_string(App::version()->getVersion('activityReport'))
&& version_compare(dcCore::app()->getVersion('activityReport'), '3.0', '<') && version_compare(App::version()->getVersion('activityReport'), '3.0', '<')
) { ) {
$struct = new Structure(dcCore::app()->con, dcCore::app()->prefix); $struct = new Structure(App::con(), App::con()->prefix());
if ($struct->tableExists('activity')) { if ($struct->tableExists('activity')) {
(new TruncateStatement())->from(dcCore::app()->prefix . 'activity')->truncate(); (new TruncateStatement())->from(App::con()->prefix() . 'activity')->truncate();
} }
if ($struct->tableExists('activity_settings')) { if ($struct->tableExists('activity_settings')) {
(new TruncateStatement())->from(dcCore::app()->prefix . 'activity_settings')->truncate(); (new TruncateStatement())->from(App::con()->prefix() . 'activity_settings')->truncate();
(new DropStatement())->from(dcCore::app()->prefix . 'activity_settings')->drop(); (new DropStatement())->from(App::con()->prefix() . 'activity_settings')->drop();
} }
} }
} }

View File

@ -1,21 +1,11 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use dcCore; use Dotclear\App;
use Dotclear\Core\Backend\Filter\Filters; use Dotclear\Core\Backend\Filter\Filters;
use Dotclear\Core\Backend\{ use Dotclear\Core\Backend\{
Notices, Notices,
@ -32,7 +22,11 @@ use Dotclear\Helper\Html\Form\{
use Exception; use Exception;
/** /**
* Manage process (admin logs list). * @brief activityReport manage class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Manage extends Process class Manage extends Process
{ {
@ -53,7 +47,7 @@ class Manage extends Process
Notices::addSuccessNotice(__('Logs successfully deleted')); Notices::addSuccessNotice(__('Logs successfully deleted'));
My::redirect(); My::redirect();
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->error->add($e->getMessage()); App::error()->add($e->getMessage());
} }
} }
@ -77,7 +71,7 @@ class Manage extends Process
$list = new ManageList($logs, $counter->f(0)); $list = new ManageList($logs, $counter->f(0));
} }
} catch (Exception $e) { } catch (Exception $e) {
dcCore::app()->error->add($e->getMessage()); App::error()->add($e->getMessage());
} }
Page::openModule( Page::openModule(
@ -87,7 +81,7 @@ class Manage extends Process
My::jsLoad('backend') . My::jsLoad('backend') .
# --BEHAVIOR-- activityReportListHeader -- # --BEHAVIOR-- activityReportListHeader --
dcCore::app()->callBehavior('activityReportListHeader') App::behavior()->callBehavior('activityReportListHeader')
); );
echo echo
@ -104,7 +98,7 @@ class Manage extends Process
if (!is_null($logs) && !$logs->isEmpty()) { if (!is_null($logs) && !$logs->isEmpty()) {
echo echo
(new Form('form-logs'))->method('post')->action(dcCore::app()->admin->getPageURL())->fields([ (new Form('form-logs'))->method('post')->action(App::backend()->getPageURL())->fields([
(new Para())->class('right')->separator(' ')->items([ (new Para())->class('right')->separator(' ')->items([
(new Submit('delete_all_logs'))->class('delete')->value(__('Delete all aticivity logs')), (new Submit('delete_all_logs'))->class('delete')->value(__('Delete all aticivity logs')),
(new Submit('delete_reported_logs'))->class('delete')->value(__('Delete all allready reported logs')), (new Submit('delete_reported_logs'))->class('delete')->value(__('Delete all allready reported logs')),

View File

@ -1,21 +1,11 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use dcCore; use Dotclear\App;
use Dotclear\Core\Backend\Filter\Filters; use Dotclear\Core\Backend\Filter\Filters;
use Dotclear\Core\Backend\Listing\{ use Dotclear\Core\Backend\Listing\{
Listing, Listing,
@ -24,13 +14,17 @@ use Dotclear\Core\Backend\Listing\{
use Dotclear\Helper\Date; use Dotclear\Helper\Date;
/** /**
* Logs admin list helper. * @brief activityReport manage logs list class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class ManageList extends Listing class ManageList extends Listing
{ {
public function logsDisplay(Filters $filter, string $enclose_block = ''): void public function logsDisplay(Filters $filter, string $enclose_block = ''): void
{ {
if (!$this->rs || $this->rs->isEmpty()) { if ($this->rs->isEmpty()) {
if ($filter->show()) { if ($filter->show()) {
echo '<p><strong>' . __('No log matches the filter') . '</strong></p>'; echo '<p><strong>' . __('No log matches the filter') . '</strong></p>';
} else { } else {
@ -83,9 +77,9 @@ class ManageList extends Listing
$action = $group->get($row->action); $action = $group->get($row->action);
$message = ActivityReport::parseMessage(__($action->message), $row->logs); $message = ActivityReport::parseMessage(__($action->message), $row->logs);
$date = Date::str( $date = Date::str(
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'), App::blog()->settings()->get('system')->get('date_format') . ', ' . App::blog()->settings()->get('system')->get('time_format'),
(int) strtotime($row->dt), (int) strtotime($row->dt),
is_string(dcCore::app()->auth->getInfo('user_tz')) ? dcCore::app()->auth->getInfo('user_tz') : 'UTC' is_string(App::auth()->getInfo('user_tz')) ? App::auth()->getInfo('user_tz') : 'UTC'
); );
$status = $row->status == ActivityReport::STATUS_PENDING ? __('pending') : __('reported'); $status = $row->status == ActivityReport::STATUS_PENDING ? __('pending') : __('reported');

View File

@ -1,59 +1,26 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore;
use Dotclear\Module\MyPlugin; use Dotclear\Module\MyPlugin;
/** /**
* This module definitions. * @brief activityReport My helper.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class My extends MyPlugin class My extends MyPlugin
{ {
/** @var string Activity database table name */ /**
* Activity database table name.
*
* @var string ACTIVITY_TABLE_NAME
*/
public const ACTIVITY_TABLE_NAME = 'activity'; public const ACTIVITY_TABLE_NAME = 'activity';
/** @var int Incremental version by breaking changes */ // Use default permissions
public const COMPATIBILITY_VERSION = 3;
public static function checkCustomContext(int $context): ?bool
{
switch($context) {
case My::FRONTEND:
return defined('ACTIVITY_REPORT') && My::isInstalled();
case My::BACKEND:
return defined('DC_CONTEXT_ADMIN') && defined('ACTIVITY_REPORT') && My::isInstalled();
case My::CONFIG:
case My::MANAGE:
return defined('DC_CONTEXT_ADMIN')
&& defined('ACTIVITY_REPORT')
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
dcCore::app()->auth::PERMISSION_ADMIN,
]), dcCore::app()->blog?->id);
default:
return null;
}
}
/**
* Check is module is trully installed.
*
* Required as table structrue has changed
*/
public static function isInstalled(): bool
{
return dcCore::app()->getVersion(self::id()) == (string) dcCore::app()->plugins->getDefine(self::id())->get('version');
}
} }

View File

@ -1,25 +1,18 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore; use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Exception;
/** /**
* Prepend process. * @brief activityReport prepend class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Prepend extends Process class Prepend extends Process
{ {
@ -34,29 +27,13 @@ class Prepend extends Process
return false; return false;
} }
if (defined('ACTIVITY_REPORT')) { // regirster activity feed URL
return true; App::url()->register(
} My::id(),
'reports',
try { '^reports/((atom|rss2)/(.+))$',
// launch once activity report stuff UrlHandler::feed(...)
ActivityReport::instance(); );
// regirster activity feed URL
dcCore::app()->url->register(
My::id(),
'reports',
'^reports/((atom|rss2)/(.+))$',
[UrlHandler::class, 'feed']
);
// declare report open
define('ACTIVITY_REPORT', My::COMPATIBILITY_VERSION);
// register predefined activities scan
ActivityBehaviors::register();
} catch (Exception $e) {
}
return true; return true;
} }

View File

@ -1,21 +1,15 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
/** /**
* Module settings helper. * @brief activityReport settings helper class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Settings class Settings
{ {

View File

@ -1,25 +1,19 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use dcCore; use Dotclear\App;
use Dotclear\Helper\Date; use Dotclear\Helper\Date;
/** /**
* Template blocs and values. * @brief activityReport frontend template class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Template class Template
{ {
@ -43,12 +37,12 @@ class Template
$lastn = abs((int) $attr['lastn']) + 0; $lastn = abs((int) $attr['lastn']) + 0;
} }
$p = '$_page_number = dcCore::app()->public->getPageNumber(); if ($_page_number < 1) { $_page_number = 1; }' . "\n\$params = new ArrayObject();\n"; $p = '$_page_number = App::frontend()->getPageNumber(); if ($_page_number < 1) { $_page_number = 1; }' . "\n\$params = new ArrayObject();\n";
if ($lastn > 0) { if ($lastn > 0) {
$p .= "\$params['limit'] = " . $lastn . ";\n"; $p .= "\$params['limit'] = " . $lastn . ";\n";
} else { } else {
$p .= "\$params['limit'] = dcCore::app()->ctx->nb_entry_per_page;\n"; $p .= "\$params['limit'] = App::frontend()->context()->nb_entry_per_page;\n";
} }
if (!isset($attr['ignore_pagination']) || $attr['ignore_pagination'] == '0') { if (!isset($attr['ignore_pagination']) || $attr['ignore_pagination'] == '0') {
@ -60,10 +54,10 @@ class Template
return return
"<?php \n" . "<?php \n" .
$p . $p .
'dcCore::app()->ctx->activityreport_params = $params; ' . "\n" . 'App::frontend()->context()->activityreport_params = $params; ' . "\n" .
'dcCore::app()->ctx->activityreports = ' . ActivityReport::class . '::instance()->getLogs($params); unset($params); ' . "\n" . 'App::frontend()->context()->activityreports = ' . ActivityReport::class . '::instance()->getLogs($params); unset($params); ' . "\n" .
'while (dcCore::app()->ctx->activityreports->fetch()) : ?>' . $content . '<?php endwhile; ' . 'while (App::frontend()->context()->activityreports->fetch()) : ?>' . $content . '<?php endwhile; ' .
'dcCore::app()->ctx->pop("activityreports"); dcCore::app()->ctx->pop("activityreport_params"); ' . "\n" . 'App::frontend()->context()->pop("activityreports"); App::frontend()->context()->pop("activityreport_params"); ' . "\n" .
'?>'; '?>';
} }
@ -81,8 +75,8 @@ class Template
public static function activityReportFeedID(ArrayObject $attr): string public static function activityReportFeedID(ArrayObject $attr): string
{ {
return return
'urn:md5:<?php echo md5(dcCore::app()->ctx->activityreports->blog_id.' . 'urn:md5:<?php echo md5(App::frontend()->context()->activityreports->blog_id.' .
'dcCore::app()->ctx->activityreports->activity_id.dcCore::app()->ctx->activityreports->activity_dt); ' . 'App::frontend()->context()->activityreports->activity_id.App::frontend()->context()->activityreports->activity_dt); ' .
'?>'; '?>';
} }
@ -99,7 +93,7 @@ class Template
*/ */
public static function activityReportTitle(ArrayObject $attr): string public static function activityReportTitle(ArrayObject $attr): string
{ {
$f = dcCore::app()->tpl->getFilters($attr); $f = App::frontend()->template()->getFilters($attr);
return '<?php echo ' . sprintf($f, Context::class . '::parseTitle()') . '; ?>'; return '<?php echo ' . sprintf($f, Context::class . '::parseTitle()') . '; ?>';
} }
@ -117,7 +111,7 @@ class Template
*/ */
public static function activityReportContent(ArrayObject $attr): string public static function activityReportContent(ArrayObject $attr): string
{ {
$f = dcCore::app()->tpl->getFilters($attr); $f = App::frontend()->template()->getFilters($attr);
return '<?php echo ' . sprintf($f, Context::class . '::parseContent()') . '; ?>'; return '<?php echo ' . sprintf($f, Context::class . '::parseContent()') . '; ?>';
} }
@ -146,16 +140,16 @@ class Template
$iso8601 = !empty($attr['iso8601']); $iso8601 = !empty($attr['iso8601']);
$rfc822 = !empty($attr['rfc822']); $rfc822 = !empty($attr['rfc822']);
$f = dcCore::app()->tpl->getFilters($attr); $f = App::frontend()->template()->getFilters($attr);
if ($rfc822) { if ($rfc822) {
return '<?php echo ' . sprintf($f, Date::class . '::rfc822(strtotime(dcCore::app()->ctx->activityreports->activity_dt),dcCore::app()->blog->settings->system->blog_timezone)') . '; ?>'; return '<?php echo ' . sprintf($f, Date::class . '::rfc822(strtotime(App::frontend()->context()->activityreports->activity_dt),App::blog()->settings()->system->blog_timezone)') . '; ?>';
} elseif ($iso8601) { } elseif ($iso8601) {
return '<?php echo ' . sprintf($f, Date::class . '::iso8601(strtotime(dcCore::app()->ctx->activityreports->activity_dt),dcCore::app()->blog->settings->system->blog_timezone)') . '; ?>'; return '<?php echo ' . sprintf($f, Date::class . '::iso8601(strtotime(App::frontend()->context()->activityreports->activity_dt),App::blog()->settings()->system->blog_timezone)') . '; ?>';
} elseif (!empty($format)) { } elseif (!empty($format)) {
return '<?php echo ' . sprintf($f, Date::class . "::dt2str('" . $format . "',dcCore::app()->ctx->activityreports->activity_dt)") . '; ?>'; return '<?php echo ' . sprintf($f, Date::class . "::dt2str('" . $format . "',App::frontend()->context()->activityreports->activity_dt)") . '; ?>';
} }
return '<?php echo ' . sprintf($f, Date::class . '::dt2str(dcCore::app()->blog->settings->system->date_format,dcCore::app()->ctx->activityreports->activity_dt)') . '; ?>'; return '<?php echo ' . sprintf($f, Date::class . '::dt2str(App::blog()->settings()->system->date_format,App::frontend()->context()->activityreports->activity_dt)') . '; ?>';
} }
} }

View File

@ -1,27 +1,18 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Plugin\Uninstaller\Uninstaller; use Dotclear\Plugin\Uninstaller\Uninstaller;
/** /**
* Uninstall process. * @brief activityReport uninstall class.
* @ingroup activityReport
* *
* Using plugin Uninstaller * @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Uninstall extends Process class Uninstall extends Process
{ {
@ -32,7 +23,7 @@ class Uninstall extends Process
public static function process(): bool public static function process(): bool
{ {
if (!self::status() || !dcCore::app()->plugins->moduleExists('Uninstaller')) { if (!self::status()) {
return false; return false;
} }

View File

@ -1,27 +1,20 @@
<?php <?php
/**
* @brief activityReport, 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\activityReport; namespace Dotclear\Plugin\activityReport;
use context; use Dotclear\App;
use dcCore; use Dotclear\Core\Frontend\Url;
use dcUrlHandlers;
/** /**
* Frontend URL handler. * @brief activityReport frontend URL handler class.
* @ingroup activityReport
*
* @author Jean-Christian Denis (author)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class UrlHandler extends dcUrlHandlers class UrlHandler extends Url
{ {
/** /**
* Get activity logs feed. * Get activity logs feed.
@ -31,9 +24,7 @@ class UrlHandler extends dcUrlHandlers
public static function feed(?string $args): void public static function feed(?string $args): void
{ {
// no context or wrong URL args or module no loaded or report unactive // no context or wrong URL args or module no loaded or report unactive
if (!dcCore::app()->ctx if (!preg_match('/^(atom|rss2)\/(.+)$/', (string) $args, $m)
|| !preg_match('/^(atom|rss2)\/(.+)$/', (string) $args, $m)
|| !defined('ACTIVITY_REPORT')
|| !ActivityReport::instance()->settings->feed_active || !ActivityReport::instance()->settings->feed_active
) { ) {
self::p404(); self::p404();
@ -50,15 +41,15 @@ class UrlHandler extends dcUrlHandlers
} }
// feed limits // feed limits
$nb = dcCore::app()->blog?->settings->get('system')->get('nb_post_per_feed'); $nb = App::blog()->settings()->get('system')->get('nb_post_per_feed');
//$it = dcCore::app()->blog?->settings->get('system')->get('short_feed_items'); //$it = App::blog()->settings()->get('system')->get('short_feed_items');
$rb = dcCore::app()->blog?->settings->get('system')->get('robots_policy'); $rb = App::blog()->settings()->get('system')->get('robots_policy');
dcCore::app()->ctx->__set('nb_entry_per_page', is_numeric($nb) ? (int) $nb : 20); App::frontend()->context()->__set('nb_entry_per_page', is_numeric($nb) ? (int) $nb : 20);
// dcCore::app()->ctx->__set('short_feed_items', is_numerci($it) ? (int) $it : 1); // App::frontend->context()->__set('short_feed_items', is_numerci($it) ? (int) $it : 1);
// serve activity feed template // serve activity feed template
header('X-Robots-Tag: ' . context::robotsPolicy(is_string($rb) ? $rb : '', '')); header('X-Robots-Tag: ' . App::frontend()->context()::robotsPolicy(is_string($rb) ? $rb : '', ''));
self::serveDocument('activityreport-' . $m[1] . '.xml', $mime); self::serveDocument('activityreport-' . $m[1] . '.xml', $mime);
} }
} }