code review

This commit is contained in:
Jean-Christian Denis 2023-10-22 19:04:35 +02:00
parent 3f32615115
commit 8b352b5a81
Signed by: JcDenis
GPG key ID: 1B5B8C5B90B6C951
10 changed files with 172 additions and 43 deletions

View file

@ -1,3 +1,12 @@
DotclearWatch 0.9.3 - 2023.10.22
===========================================================
* Require dotclear 2.28
* Require php 8.1
* Add PHP minor version (using PHP constants)
* Add uninstall feature (plugin Uninstaller)
* Fix colored synthax
* Use Helper Form everywhere
DotclearWatch 0.9.2 - 2023.10.14
===========================================================
* Require dotclear 2.28

View file

@ -1,7 +1,7 @@
# README
[![Release](https://img.shields.io/badge/release-0.9.2-a2cbe9.svg)](https://git.dotclear.watch/dw/DotclearWatch/releases)
![Date](https://img.shields.io/badge/date-2023.10.14-c44d58.svg)
[![Release](https://img.shields.io/badge/release-0.9.3-a2cbe9.svg)](https://git.dotclear.watch/dw/DotclearWatch/releases)
![Date](https://img.shields.io/badge/date-2023.10.22-c44d58.svg)
[![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/DotclearWatch)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/dw/DotclearWatch/src/branch/master/LICENSE)
@ -31,7 +31,7 @@ in aboutConfig global parameters called DotclearWatch->hidden_modules
* Dotclear 2.28
* PHP 8.1+
* super admin permission to intall it
* Dotclear super admin permission to intall it
## USAGE

View file

@ -18,7 +18,7 @@ $this->registerModule(
'Dotclear Watch',
'Send report about your Dotclear',
'Jean-Christian Denis and contributors',
'0.9.2',
'0.9.3',
[
'requires' => [['core', '2.28']],
'permissions' => 'My',

View file

@ -2,10 +2,10 @@
<modules xmlns:da="http://dotaddict.org/da/">
<module id="DotclearWatch">
<name>Dotclear Watch</name>
<version>0.9.2</version>
<version>0.9.3</version>
<author>Jean-Christian Denis and contributors</author>
<desc>Send report about your Dotclear</desc>
<file>https://git.dotclear.watch/dw/DotclearWatch/releases/download/v0.9.2/plugin-DotclearWatch.zip</file>
<file>https://git.dotclear.watch/dw/DotclearWatch/releases/download/v0.9.3/plugin-DotclearWatch.zip</file>
<da:dcmin>2.28</da:dcmin>
<da:details>https://git.dotclear.watch/dw/DotclearWatch/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/dw/DotclearWatch/issues</da:support>

View file

@ -6,13 +6,18 @@ namespace Dotclear\Plugin\DotclearWatch;
use Dotclear\App;
use Dotclear\Core\Process;
use Dotclear\Helper\Html\Form\{
Img,
Li,
Link,
Ul
};
/**
* @brief DotclearWatch backend class.
* @ingroup DotclearWatch
*
* @author Jean-Christian Denis
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Backend extends Process
@ -29,23 +34,31 @@ class Backend extends Process
}
App::behavior()->addBehaviors([
// Add JS for asynchronous report sending
'adminDashboardHeaders' => function (): string {
return My::jsLoad('service', App::version()->getVersion(My::id()));
},
// Add icon on bottom of dashboard sidebar menu
'adminPageFooterV2' => function (): void {
if (My::settings()->getGlobal('distant_api_url')) {
echo sprintf(
'<ul><li><a href="%s" title="%s" class="outgoing">%s<img src="%s" /></a></ul></li>',
'https://stat.dotclear.watch',
__('Uses DotclearWatch plugin statistics'),
__('Shared statistics'),
My::fileURL('icon.svg')
);
echo (new Ul())->items([
(new li())->items([
(new Link())
->class('outgoing')
->href('https://stat.dotclear.watch')
->title(__('Uses DotclearWatch plugin statistics'))
->text(__('Shared statistics'))
->items([
(new Img(My::fileURL('icon.svg'))),
]),
]),
])->render();
}
},
]);
App::rest()->addFunction(
// Add REST service for asynchronous report sending
'adminDotclearWatchSendReport',
function (): array {
Utils::sendReport();

View file

@ -23,16 +23,26 @@ use Dotclear\Helper\Html\Form\{
use Dotclear\Helper\Html\Html;
/**
* @brief DotclearWatch configuration class.
* @ingroup DotclearWatch
* @brief DotclearWatch configuration class.
* @ingroup DotclearWatch
*
* @author Jean-Christian Denis
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Config extends Process
{
private static string $hidden_modules = '';
/**
* List of hidden modules.
*
* @var string $hidden_modules
*/
private static string $hidden_modules = '';
/**
* Distant API URL.
*
* @var string $distant_api_url
*/
private static string $distant_api_url = '';
public static function init(): bool
@ -46,7 +56,7 @@ class Config extends Process
return false;
}
if (self::useColorSynthax()) {
if (App::auth()->prefs()->get('interface')->get('colorsyntax')) {
App::behavior()->addBehavior('pluginsToolsHeadersV2', fn (bool $plugin): string => Page::jsLoadCodeMirror(App::auth()->prefs()->get('interface')->get('colorsyntax_theme')));
}
@ -62,7 +72,8 @@ class Config extends Process
Notices::AddSuccessNotice(__('Cache directory sucessfully cleared.'));
}
self::$hidden_modules = '';
self::$distant_api_url = !empty($_POST['distant_api_url']) && is_string($_POST['distant_api_url']) ? $_POST['distant_api_url'] : Utils::DISTANT_API_URL;
self::$hidden_modules = '';
foreach (explode(',', $_POST['hidden_modules']) as $hidden) {
$hidden = trim($hidden);
if (!empty($hidden)) {
@ -70,8 +81,6 @@ class Config extends Process
}
}
self::$distant_api_url = !empty($_POST['distant_api_url']) && is_string($_POST['distant_api_url']) ? $_POST['distant_api_url'] : Utils::DISTANT_API_URL;
My::settings()->put('hidden_modules', self::$hidden_modules, 'string', 'Hidden modules from report', true, true);
My::settings()->put('distant_api_url', self::$distant_api_url, 'string', 'Distant API report URL', true, true);
Notices::AddSuccessNotice(__('Settings successfully updated.'));
@ -106,12 +115,12 @@ class Config extends Process
]),
(new Para())->items([
(new Label(__('Hidden modules:')))->for('hidden_modules'),
(new Input('hidden_modules'))->class('maximal')->size(65)->maxlenght(255)->value(self::$hidden_modules),
(new Input('hidden_modules'))->class('maximal')->size(65)->maxlength(255)->value(self::$hidden_modules),
]),
(new Note())->class('form-note')->text(__('This is the comma separated list of plugins IDs and themes IDs to ignore in report.')),
(new Para())->items([
(new Label(__('Distant API URL:')))->for('distant_api_url'),
(new Input('distant_api_url'))->class('maximal')->size(65)->maxlenght(255)->value(self::$distant_api_url),
(new Input('distant_api_url'))->class('maximal')->size(65)->maxlength(255)->value(self::$distant_api_url),
]),
(new Note())->class('form-note')->text(__('This is the URL of the API to send report. Leave empty to reset value.')),
(new Para())->items([
@ -138,14 +147,9 @@ class Config extends Process
->class('maximal'),
])->render() .
(
self::useColorSynthax() ?
App::auth()->prefs()->get('interface')->get('colorsyntax') ?
Page::jsRunCodeMirror(My::id() . 'editor', 'report_contents', 'json', App::auth()->prefs()->get('interface')->get('colorsyntax_theme')) : ''
);
}
}
private static function useColorSynthax(): bool
{
return App::auth()->prefs()->get('interface')->get('colorsyntax') && '' != App::auth()->prefs()->get('interface')->get('colorsyntax_theme');
}
}

View file

@ -7,11 +7,10 @@ namespace Dotclear\Plugin\DotclearWatch;
use Dotclear\Core\Process;
/**
* @brief DotclearWatch install class.
* @ingroup DotclearWatch
* @brief DotclearWatch install class.
* @ingroup DotclearWatch
*
* @author Jean-Christian Denis
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Install extends Process
@ -23,8 +22,8 @@ class Install extends Process
public static function process(): bool
{
if (self::status() && ($s = My::settings()) !== null) {
$s->put(
if (self::status()) {
My::settings()->put(
'hidden_modules',
'DotclearWatch',
'string',
@ -32,7 +31,7 @@ class Install extends Process
false,
true
);
$s->put(
My::settings()->put(
'distant_api_url',
'https://dotclear.watch/api',
'string',

View file

@ -7,11 +7,10 @@ namespace Dotclear\Plugin\DotclearWatch;
use Dotclear\Module\MyPlugin;
/**
* @brief DotclearWatch My helper.
* @ingroup DotclearWatch
* @brief DotclearWatch My helper.
* @ingroup DotclearWatch
*
* @author Jean-Christian Denis
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class My extends MyPlugin

66
src/Uninstall.php Normal file
View file

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Dotclear\Plugin\DotclearWatch;
use Dotclear\Core\Process;
use Dotclear\Plugin\Uninstaller\Uninstaller;
/**
* @brief DotclearWatch uninstall class.
* @ingroup DotclearWatch
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Uninstall extends Process
{
public static function init(): bool
{
return self::status(My::checkContext(My::UNINSTALL));
}
public static function process(): bool
{
if (!self::status()) {
return false;
}
Uninstaller::instance()
->addUserAction(
'settings',
'delete_all',
My::id()
)
->addUserAction(
'plugins',
'delete',
My::id()
)
->addUserAction(
'versions',
'delete',
My::id()
)
->addDirectAction(
'settings',
'delete_all',
My::id()
)
->addDirectAction(
'plugins',
'delete',
My::id()
)
->addDirectAction(
'versions',
'delete',
My::id()
)
;
// no custom action
return false;
}
}

View file

@ -11,11 +11,10 @@ use Dotclear\Module\ModuleDefine;
use Exception;
/**
* @brief DotclearWatch utils class.
* @ingroup DotclearWatch
* @brief DotclearWatch utils class.
* @ingroup DotclearWatch
*
* @author Jean-Christian Denis
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Utils
@ -256,11 +255,21 @@ class Utils
}
}
/**
* Check if report can be done.
*
* @return bool True if it can
*/
private static function check(): bool
{
return true; // not yet
}
/**
* Get report key.
*
* @return string The report key
*/
private static function key(): string
{
return Crypt::hmac(self::uid() . My::id(), App::config()->cryptAlgo());
@ -279,11 +288,21 @@ class Utils
return self::$uid;
}
/**
* Get blog report uid.
*
* @return string The blog report uid
*/
private static function buid(): string
{
return md5(self::uid() . App::blog()->uid());
}
/**
* Get query URL.
*
* @return string The URL
*/
private static function url(): string
{
$api_url = My::settings()->getGlobal('distant_api_url');
@ -291,6 +310,9 @@ class Utils
return (is_string($api_url) ? $api_url : self::DISTANT_API_URL) . '/' . self::DISTANT_API_VERSION . '/%s/' . self::uid();
}
/**
* Clear report logs.
*/
private static function clear(): void
{
$rs = App::log()->getLogs([
@ -311,6 +333,9 @@ class Utils
App::log()->delLogs($logs);
}
/**
* Log error.
*/
private static function error(string $message): void
{
self::clear();
@ -322,6 +347,9 @@ class Utils
App::log()->addLog($cur);
}
/**
* Write report.
*/
private static function write(string $contents): void
{
self::clear();
@ -333,6 +361,11 @@ class Utils
App::log()->addLog($cur);
}
/**
* Check if report is expired.
*
* @return bool True if expired
*/
private static function expired(): bool
{
$rs = App::log()->getLogs([
@ -342,6 +375,11 @@ class Utils
return $rs->isEmpty() || !is_string($rs->f('log_dt')) || (int) strtotime($rs->f('log_dt')) + self::EXPIRED_DELAY < time();
}
/**
* Get report content.
*
* @return string Teh report content
*/
private static function contents(): string
{
// Build json response
@ -363,7 +401,8 @@ class Utils
'server' => self::getServer(),
'php' => [
'sapi' => php_sapi_name() ?: 'php',
'version' => phpversion(),
'version' => PHP_VERSION,
'minor' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION,
],
'system' => [
'name' => php_uname('s'),