Compare commits

...

3 Commits

Author SHA1 Message Date
e9e118dc82
cosmetic 2023-10-22 10:26:39 +02:00
bbbec07345
code review 2023-10-22 10:25:14 +02:00
bee9b19cfc
release 2023.10.11 2023-10-10 23:37:45 +02:00
13 changed files with 268 additions and 137 deletions

View File

@ -1,3 +1,16 @@
myUrlHandlers 2023.10.22
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Use default permissions and update to admin only
* Code review (phpstan)
myUrlHandlers 2023.10.11
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Code review
myUrlHandlers 2023.10.07 myUrlHandlers 2023.10.07
=========================================================== ===========================================================
* Require Dotclear 2.28 * Require Dotclear 2.28

View File

@ -1,8 +1,8 @@
# README # README
[![Release](https://img.shields.io/badge/release-2023.08.13-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/myUrlHandlers/releases) [![Release](https://img.shields.io/badge/release-2023.10.22-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/myUrlHandlers/releases)
![Date](https://img.shields.io/badge/date-2023.08.13-c44d58.svg) ![Date](https://img.shields.io/badge/date-2023.10.22-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/myUrlHandlers) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/myUrlHandlers)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/myUrlHandlers/src/branch/master/LICENSE) [![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/myUrlHandlers/src/branch/master/LICENSE)
@ -10,13 +10,13 @@
_myUrlHandlers_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org). _myUrlHandlers_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org).
> You can change public URL of each Dotclear parts, like post, category, etc and some plugins having public parts. > Change public URL of each Dotclear parts, like post, category, etc and some plugins having public parts.
## REQUIREMENTS ## REQUIREMENTS
* contentadmin permissions for management
* Dotclear 2.28 * Dotclear 2.28
* PHP 8.1+ * PHP 8.1+
* Dotclear admin permissions for management
## USAGE ## USAGE
@ -36,8 +36,8 @@ or you can add dashboard icon.
## CONTRIBUTORS ## CONTRIBUTORS
* Alex pirine (First author) * Alex pirine (Author)
* te2dy * te2dy
* Jean-Christian Denis * Jean-Christian Denis (latest)
You are welcome to contribute to this code. You are welcome to contribute to this code.

View File

@ -1,27 +1,28 @@
<?php <?php
/** /**
* @brief myUrlHandlers, a plugin for Dotclear 2 * @file
* @brief The plugin myUrlHandlers definition
* @ingroup myUrlHandlers
* *
* @package Dotclear * @defgroup myUrlHandlers Plugin myUrlHandlers.
* @subpackage Plugin *
* Change Dotclear URL handlers.
* *
* @author Alex Pirine and contributors * @author Alex Pirine and contributors
* * @author Jean-Christian Denis
* @copyright Jean-Christian Denis * @copyright Alex Pirine
* @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
*/ */
use Dotclear\App; declare(strict_types=1);
$this->registerModule( $this->registerModule(
'URL handlers', 'URL handlers',
'Change Dotclear URL handlers', 'Change Dotclear URL handlers',
'Alex Pirine and contributors', 'Alex Pirine and contributors',
'2023.08.13', '2023.10.11',
[ [
'requires' => [['core', '2.28']], 'requires' => [['core', '2.28']],
'permissions' => App::auth()->makePermissions([ 'permissions' => 'My',
App::auth()::PERMISSION_CONTENT_ADMIN,
]),
'priority' => 150000, 'priority' => 150000,
'type' => 'plugin', 'type' => 'plugin',
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues', 'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues',

View File

@ -2,11 +2,11 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="myUrlHandlers"> <module id="myUrlHandlers">
<name>URL handlers</name> <name>URL handlers</name>
<version>2023.08.13</version> <version>2023.10.22</version>
<author>Alex Pirine and contributors</author> <author>Alex Pirine and contributors</author>
<desc>Change Dotclear URL handlers</desc> <desc>Change Dotclear URL handlers</desc>
<file>https://github.com/JcDenis/myUrlHandlers/releases/download/v2023.08.13/plugin-myUrlHandlers.zip</file> <file>https://git.dotclear.watch/JcDenis/myUrlHandlers/releases/download/v2023.10.22/plugin-myUrlHandlers.zip</file>
<da:dcmin>2.27</da:dcmin> <da:dcmin>2.28</da:dcmin>
<da:details>https://git.dotclear.watch/JcDenis/myUrlHandlers/src/branch/master/README.md</da:details> <da:details>https://git.dotclear.watch/JcDenis/myUrlHandlers/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/JcDenis/myUrlHandlers/issues</da:support> <da:support>https://git.dotclear.watch/JcDenis/myUrlHandlers/issues</da:support>
</module> </module>

View File

@ -1,15 +1,5 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
@ -18,6 +8,14 @@ use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Core\Backend\Favorites; use Dotclear\Core\Backend\Favorites;
/**
* @brief myUrlHandlers backend class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Backend extends Process class Backend extends Process
{ {
public static function init(): bool public static function init(): bool
@ -40,7 +38,7 @@ 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' => App::auth()->makePermissions([App::auth()::PERMISSION_CONTENT_ADMIN]), 'permissions' => App::auth()->makePermissions([App::auth()::PERMISSION_ADMIN]),
]); ]);
}); });

View File

@ -1,15 +1,5 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
@ -17,6 +7,14 @@ namespace Dotclear\Plugin\myUrlHandlers;
use Dotclear\App; use Dotclear\App;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/**
* @brief myUrlHandlers installation class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Install extends Process class Install extends Process
{ {
public static function init(): bool public static function init(): bool

View File

@ -1,15 +1,5 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
@ -26,7 +16,12 @@ use Dotclear\Helper\Text;
use Exception; use Exception;
/** /**
* Manage contributions list * @brief myUrlHandlers manage class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class Manage extends Process class Manage extends Process
{ {
@ -51,14 +46,14 @@ class Manage extends Process
if (empty($handlers[$name])) { if (empty($handlers[$name])) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Uknown handler "%s".'), __('Uknown handler "%s".'),
Html::escapeHTML($name) Html::escapeHTML((string) $name)
)); ));
} }
if (empty($url)) { if (empty($url)) {
throw new Exception(sprintf( throw new Exception(sprintf(
__('Invalid URL for handler "%s".'), __('Invalid URL for handler "%s".'),
Html::escapeHTML($name) Html::escapeHTML((string) $name)
)); ));
} }

View File

@ -1,23 +1,27 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
use Dotclear\Module\MyPlugin; use Dotclear\Module\MyPlugin;
/**
* @brief myUrlHandlers My helper.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class My extends MyPlugin class My extends MyPlugin
{ {
/** @var string This module settings ID */ /**
* This module settings ID.
*
* @var string NS_SETTING_ID
*/
public const NS_SETTING_ID = 'handlers'; public const NS_SETTING_ID = 'handlers';
// Use default permissions
} }

View File

@ -1,15 +1,5 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
@ -17,52 +7,66 @@ namespace Dotclear\Plugin\myUrlHandlers;
use Dotclear\App; use Dotclear\App;
use Dotclear\Core\PostType; use Dotclear\Core\PostType;
/**
* @brief myUrlHandlers main class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class MyUrlHandlers class MyUrlHandlers
{ {
/** /**
* The default URLs handlers. * The URLs stack.
* *
* @var array<string,array<string,string>> $defaults * @var UrlStack $stack
*/ */
private static array $defaults = []; private static UrlStack $stack;
/** /**
* The posts types URLs. * The posts types URLs.
* *
* @var array<string,string> $url2post * @var array<string, string> $pt_public2type
*/ */
private static array $url2post = []; private static array $pt_public2type = [];
/** /**
* The posts types admin URLs. * The posts types admin URLs.
* *
* @var array<string,string> $post_adm_url * @var array<string, string> $pt_type2admin
*/ */
private static array $post_adm_url = []; private static array $pt_type2admin = [];
/** /**
* Initialize handlers list. * Initialize handlers list.
*/ */
public static function init(): void public static function init(): void
{ {
self::$stack = new UrlStack();
# Set defaults # Set defaults
foreach (App::url()->getTypes() as $k => $v) { foreach (App::url()->getTypes() as $k => $v) {
if (empty($v['url'])) { if (empty($v['url'])) {
continue; continue;
} }
$p = '/' . preg_quote($v['url'], '/') . '/';
$v['representation'] = str_replace('%', '%%', $v['representation']); $v['representation'] = str_replace('%', '%%', $v['representation']);
$v['representation'] = preg_replace($p, '%s', $v['representation'], 1, $c); $v['representation'] = preg_replace('/' . preg_quote($v['url'], '/') . '/', '%s', $v['representation'], 1, $c);
if ($c) { if ($c && is_string($v['representation'])) {
self::$defaults[$k] = $v; self::$stack->set(new UrlDescriptor(
$k,
$v['url'],
$v['representation'],
$v['handler'] ?? null
));
} }
} }
foreach (App::postTypes()->dump() as $pt) { foreach (App::postTypes()->dump() as $pt) {
self::$url2post[$pt->public_url] = $pt->type; self::$pt_public2type[$pt->public_url] = $pt->type;
self::$post_adm_url[$pt->type] = $pt->admin_url; self::$pt_type2admin[$pt->type] = $pt->admin_url;
} }
# Read user settings # Read user settings
@ -79,38 +83,40 @@ class MyUrlHandlers
*/ */
public static function overrideHandler(string $name, string $url): void public static function overrideHandler(string $name, string $url): void
{ {
if (!isset(self::$defaults[$name])) { $desc = self::$stack->get($name);
if (is_null($desc->handler())) {
return; return;
} }
App::url()->register( App::url()->register(
$name, $name,
$url, $url,
sprintf(self::$defaults[$name]['representation'], $url), sprintf($desc->representation, $url),
self::$defaults[$name]['handler'] $desc->handler()
); );
$k = self::$url2post[self::$defaults[$name]['url'] . '/%s'] ?? ''; $type = self::$pt_public2type[$desc->url . '/%s'] ?? '';
if (!$type) {
return;
}
if ($k) {
App::postTypes()->set(new PostType( App::postTypes()->set(new PostType(
$k, $type,
self::$post_adm_url[$k], self::$pt_type2admin[$type],
App::url()->getBase($name) . '/%s' App::url()->getBase($name) . '/%s'
)); ));
} }
}
/** /**
* Get default URLs handlers. * Get default URLs handlers.
* *
* @return array<string,string> The default URLs handlers * @return array<string, string> The default URLs handlers
*/ */
public static function getDefaults(): array public static function getDefaults(): array
{ {
$res = []; $res = [];
foreach (self::$defaults as $k => $v) { foreach (self::$stack->dump() as $v) {
$res[$k] = $v['url']; $res[$v->id] = $v->url;
} }
return $res; return $res;
@ -119,7 +125,7 @@ class MyUrlHandlers
/** /**
* Get custom blog URLs handlers. * Get custom blog URLs handlers.
* *
* @return array<string,string> The blog URLs handlers * @return array<string, string> The blog URLs handlers
*/ */
public static function getBlogHandlers(): array public static function getBlogHandlers(): array
{ {
@ -131,7 +137,7 @@ class MyUrlHandlers
/** /**
* Save custom URLs handlers. * Save custom URLs handlers.
* *
* @param array<string,string> $handlers The custom URLs handlers * @param array<string, string> $handlers The custom URLs handlers
*/ */
public static function saveBlogHandlers(array $handlers): void public static function saveBlogHandlers(array $handlers): void
{ {

View File

@ -1,21 +1,19 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/**
* @brief myUrlHandlers prepend class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Prepend extends Process class Prepend extends Process
{ {
public static function init(): bool public static function init(): bool

View File

@ -1,15 +1,5 @@
<?php <?php
/**
* @brief myUrlHandlers, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Alex Pirine 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\myUrlHandlers; namespace Dotclear\Plugin\myUrlHandlers;
@ -17,6 +7,14 @@ namespace Dotclear\Plugin\myUrlHandlers;
use Dotclear\Core\Process; use Dotclear\Core\Process;
use Dotclear\Plugin\Uninstaller\Uninstaller; use Dotclear\Plugin\Uninstaller\Uninstaller;
/**
* @brief myUrlHandlers uninstall class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Uninstall extends Process class Uninstall extends Process
{ {
public static function init(): bool public static function init(): bool

51
src/UrlDescriptor.php Normal file
View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace Dotclear\Plugin\myUrlHandlers;
/**
* @brief myUrlHandlers URL descriptor class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class UrlDescriptor
{
/**
* URL handler callback.
*
* @var ?callable $handler
*/
private $handler = null;
/**
* Constructor.
*
* @param string $id The ID
* @param string $url The URL
* @param string $representation The representation
* @param ?callable $handler The callback
*/
public function __construct(
public readonly string $id,
public readonly string $url = '',
public readonly string $representation = '',
?callable $handler = null,
) {
// As PHP does not support callable property type.
$this->handler = $handler;
}
/**
* Get handler.
*
* @return ?callable The handler
*/
public function handler(): ?callable
{
return $this->handler;
}
}

69
src/UrlStack.php Normal file
View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace Dotclear\Plugin\myUrlHandlers;
/**
* @brief myUrlHandlers URL descriptor stack class.
* @ingroup myUrlHandlers
*
* @author Alex Pirine (author)
* @author Jean-Christian Denis (latest)
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class UrlStack
{
/**
* The stack of URL descriptors.
*
* @var array<string, UrlDescriptor>
*/
private array $stack = [];
/**
* Check if an handler is set.
*
* @param string $id The handler ID
*
* @return bool True if it exists
*/
public function has(string $id): bool
{
return array_key_exists($id, $this->stack);
}
/**
* Set an URL handler.
*
* @param UrlDescriptor $descriptor The URL descriptor
*/
public function set(UrlDescriptor $descriptor): void
{
$this->stack[$descriptor->id] = $descriptor;
}
/**
* Get an URL handler.
*
* If it does not exist, return an empty handler.
*
* @param string $id The handler ID
*
* @return UrlDescriptor The URL descriptor
*/
public function get(string $id): UrlDescriptor
{
return $this->stack[$id] ?? new UrlDescriptor($id);
}
/**
* Get URLs stack.
*
* @return array<string, UrlDescriptor>
*/
public function dump()
{
return $this->stack;
}
}