use namespace to autoload plugins activities

master
Jean-Christian Paul Denis 2023-10-18 23:32:44 +02:00
parent 78c34f1b76
commit 49d43afb5a
Signed by: JcDenis
GPG Key ID: 1B5B8C5B90B6C951
13 changed files with 94 additions and 101 deletions

View File

@ -18,10 +18,10 @@ 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(

View File

@ -6,6 +6,7 @@ namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use Dotclear\App; use Dotclear\App;
use Dotclear\Core\Process;
use Dotclear\Database\MetaRecord; use Dotclear\Database\MetaRecord;
use Dotclear\Database\Statement\{ use Dotclear\Database\Statement\{
DeleteStatement, DeleteStatement,
@ -22,6 +23,7 @@ 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;
/** /**
* @brief activityReport main class. * @brief activityReport main class.
@ -32,6 +34,13 @@ use Exception;
*/ */
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;
@ -72,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.
* *
@ -193,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)) {

View File

@ -6,15 +6,14 @@ namespace Dotclear\Plugin\activityReport;
use ArrayObject; use ArrayObject;
use Dotclear\App; use Dotclear\App;
use Dotclear\Interface\Core\BlogInterace; use Dotclear\Core\Process;
use Dotclear\Interface\Core\BlogInterface;
use Dotclear\Database\{ use Dotclear\Database\{
Cursor, Cursor,
MetaRecord MetaRecord
}; };
use Dotclear\Helper\Network\Http; use Dotclear\Helper\Network\Http;
/**
*/
/** /**
* @brief activityReport register class. * @brief activityReport register class.
* @ingroup activityReport * @ingroup activityReport
@ -24,10 +23,19 @@ use Dotclear\Helper\Network\Http;
* @author Jean-Christian Denis (author) * @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
*/ */
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'));
@ -261,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
@ -310,7 +320,7 @@ class ActivityBehaviors
public static function postDelete(int $post_id): void public static function postDelete(int $post_id): void
{ {
$posts = 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 = [
@ -332,7 +342,7 @@ class ActivityBehaviors
ActivityReport::instance()->addLog('post', 'protection', $logs); ActivityReport::instance()->addLog('post', 'protection', $logs);
} }
public static function commentCreate(BlogInterace $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;
@ -340,7 +350,7 @@ class ActivityBehaviors
$posts = 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;
} }
@ -353,12 +363,12 @@ class ActivityBehaviors
ActivityReport::instance()->addLog('comment', 'create', $logs); ActivityReport::instance()->addLog('comment', 'create', $logs);
} }
public static function commentUpdate(BlogInterace $blog, Cursor $cur, MetaRecord $old): void public static function commentUpdate(BlogInterface $blog, Cursor $cur, MetaRecord $old): void
{ {
$posts = 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;
} }
@ -371,7 +381,7 @@ class ActivityBehaviors
ActivityReport::instance()->addLog('comment', 'update', $logs); ActivityReport::instance()->addLog('comment', 'update', $logs);
} }
public static function trackbackCreate(BlogInterace $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;
@ -380,7 +390,7 @@ class ActivityBehaviors
$posts = 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;
} }
@ -416,7 +426,7 @@ class ActivityBehaviors
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')),
@ -431,7 +441,7 @@ class ActivityBehaviors
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')),

View File

@ -37,6 +37,9 @@ class Backend extends Process
return false; return false;
} }
// be sure to init report
ActivityReport::init();
My::addBackendMenuItem(); My::addBackendMenuItem();
App::behavior()->addBehaviors([ App::behavior()->addBehaviors([

View File

@ -79,7 +79,7 @@ class Config extends Process
); );
} }
App::bakend()->url()->redirect('admin.plugins', [ App::backend()->url()->redirect('admin.plugins', [
'module' => My::id(), 'module' => My::id(),
'conf' => 1, 'conf' => 1,
]); ]);

View File

@ -4,7 +4,7 @@ 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;
/** /**
@ -23,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)
@ -50,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)
@ -70,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

@ -27,13 +27,16 @@ class Frontend extends Process
return false; return false;
} }
// be sure to init report
ActivityReport::init();
App::frontend()->template()->setPath(App::frontend()->template()->getPath(), implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', 'tpl'])); App::frontend()->template()->setPath(App::frontend()->template()->getPath(), implode(DIRECTORY_SEPARATOR, [My::path(), 'default-templates', 'tpl']));
App::frontend()->template()->addBlock('activityReports', Template::activityReports(...)); App::frontend()->template()->addBlock('activityReports', Template::activityReports(...));
App::frontend()->template()->addValue('activityReportFeedID', Template::activityReportFeedID(...)); App::frontend()->template()->addValue('activityReportFeedID', Template::activityReportFeedID(...));
App::frontend()->template()->addValue('activityReportTitle', Template::activityReportTitle(...)); App::frontend()->template()->addValue('activityReportTitle', Template::activityReportTitle(...));
App::frontend()->template()->addValue('activityReportDate', Template::activityReportDate(...)); App::frontend()->template()->addValue('activityReportDate', Template::activityReportDate(...));
App::frontend()->template()l->addValue('activityReportContent', Template::activityReportContent(...)); App::frontend()->template()->addValue('activityReportContent', Template::activityReportContent(...));
return true; return true;
} }

View File

@ -13,7 +13,11 @@ namespace Dotclear\Plugin\activityReport;
*/ */
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 = [];
/** /**
@ -31,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

@ -24,7 +24,7 @@ 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 {

View File

@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Dotclear\Plugin\activityReport; namespace Dotclear\Plugin\activityReport;
use Dotclear\App;
use Dotclear\Module\MyPlugin; use Dotclear\Module\MyPlugin;
/** /**
@ -23,39 +22,5 @@ class My extends MyPlugin
*/ */
public const ACTIVITY_TABLE_NAME = 'activity'; public const ACTIVITY_TABLE_NAME = 'activity';
/** // Use default permissions
* Incremental version by breaking changes.
*
* @var int COMPATIBILITY_VERSION
*/
public const COMPATIBILITY_VERSION = 3;
public static function checkCustomContext(int $context): ?bool
{
return match ($context) {
My::FRONTEND =>
defined('ACTIVITY_REPORT') && My::isInstalled(),
My::BACKEND =>
App::task()->checkContext('BACKEND') && defined('ACTIVITY_REPORT') && My::isInstalled(),
My::CONFIG, My::MANAGE =>
App::task()->checkContext('BACKEND')
&& defined('ACTIVITY_REPORT')
&& App::auth()->check(App::auth()->makePermissions([
App::auth()::PERMISSION_ADMIN,
]), App::blog()->id()),
default =>
null,
};
}
/**
* Check is module is trully installed.
*
* Required as table structrue has changed
*/
public static function isInstalled(): bool
{
return App::version()->getVersion(self::id()) == (string) App::plugins()->getDefine(self::id())->get('version');
}
} }

View File

@ -6,7 +6,6 @@ namespace Dotclear\Plugin\activityReport;
use Dotclear\App; use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Exception;
/** /**
* @brief activityReport prepend class. * @brief activityReport prepend class.
@ -28,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
App::url()->register(
My::id(),
'reports',
'^reports/((atom|rss2)/(.+))$',
UrlHandler::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

@ -57,7 +57,7 @@ class Template
'App::frontend()->context()->activityreport_params = $params; ' . "\n" . 'App::frontend()->context()->activityreport_params = $params; ' . "\n" .
'App::frontend()->context()->activityreports = ' . ActivityReport::class . '::instance()->getLogs($params); unset($params); ' . "\n" . 'App::frontend()->context()->activityreports = ' . ActivityReport::class . '::instance()->getLogs($params); unset($params); ' . "\n" .
'while (App::frontend()->context()->activityreports->fetch()) : ?>' . $content . '<?php endwhile; ' . 'while (App::frontend()->context()->activityreports->fetch()) : ?>' . $content . '<?php endwhile; ' .
'App::frontend()->context()->pop("activityreports"); App::frontend()->context()x->pop("activityreport_params"); ' . "\n" . 'App::frontend()->context()->pop("activityreports"); App::frontend()->context()->pop("activityreport_params"); ' . "\n" .
'?>'; '?>';
} }
@ -111,7 +111,7 @@ class Template
*/ */
public static function activityReportContent(ArrayObject $attr): string public static function activityReportContent(ArrayObject $attr): string
{ {
$f = App::frontend()->context()->getFilters($attr); $f = App::frontend()->template()->getFilters($attr);
return '<?php echo ' . sprintf($f, Context::class . '::parseContent()') . '; ?>'; return '<?php echo ' . sprintf($f, Context::class . '::parseContent()') . '; ?>';
} }

View File

@ -25,7 +25,6 @@ class UrlHandler extends Url
{ {
// 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 (!preg_match('/^(atom|rss2)\/(.+)$/', (string) $args, $m) if (!preg_match('/^(atom|rss2)\/(.+)$/', (string) $args, $m)
|| !defined('ACTIVITY_REPORT')
|| !ActivityReport::instance()->settings->feed_active || !ActivityReport::instance()->settings->feed_active
) { ) {
self::p404(); self::p404();