Compare commits

..

No commits in common. "master" and "v2023.08.12" have entirely different histories.

11 changed files with 243 additions and 202 deletions

View File

@ -1,16 +1,3 @@
postExpired 2023.11.04
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Fix typo
* Code review (phpstan)
postExpired 2023.10.19
===========================================================
* Require Dotclear 2.28
* Require PHP 8.1
* Upgrade to Dotclear 2.28
postExpired 2023.08.13 postExpired 2023.08.13
=========================================================== ===========================================================
* Require Dotclear 2.27 * Require Dotclear 2.27

View File

@ -1,22 +1,26 @@
# README # README
[![Release](https://img.shields.io/badge/release-2023.11.04-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/postExpired/releases) [![Release](https://img.shields.io/badge/release-2023.08.13-a2cbe9.svg)](https://git.dotclear.watch/JcDenis/postExpired/releases)
![Date](https://img.shields.io/badge/date-2023.11.04-c44d58.svg) [![Date](https://img.shields.io/badge/date-2023.08.13-c44d58.svg)](https://git.dotclear.watch/JcDenis/postExpired/releases)
[![Dotclear](https://img.shields.io/badge/dotclear-v2.28-137bbb.svg)](https://fr.dotclear.org/download) [![Dotclear](https://img.shields.io/badge/dotclear-v2.27-137bbb.svg)](https://fr.dotclear.org/download)
[![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/postExpired) [![Dotaddict](https://img.shields.io/badge/dotaddict-official-9ac123.svg)](https://plugins.dotaddict.org/dc2/details/postExpired)
[![License](https://img.shields.io/badge/license-GPL--2.0-ececec.svg)](https://git.dotclear.watch/JcDenis/postExpired/src/branch/master/LICENSE) [![License](https://img.shields.io/github/license/JcDenis/postExpired)](https://git.dotclear.watch/JcDenis/postExpired/blob/master/LICENSE)
## ABOUT ## WHAT IS POSTEXPIRED ?
_postExpired_ is a plugin for the open-source web publishing software called [Dotclear](https://www.dotclear.org). Post expired is a plugin for the open-source
web publishing software called Dotclear.
> Add options to the sidebar of post edition page to change some options of a post at a given time. It add options to the sidebar of post edition page
to change some options of a post at a given time.
## REQUIREMENTS ## REQUIREMENTS
* Dotclear 2.28 _postExpired_ requires:
* PHP 8.1+
* Dotclear contentadmin permissions * contentadmin permissions
* Dotclear 2.27
* PHP 7.4+
## USAGE ## USAGE
@ -35,14 +39,13 @@ Notes:
## LINKS ## LINKS
* [License](https://git.dotclear.watch/JcDenis/postExpired/src/branch/master/LICENSE) * License : [GNU GPL v2](https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html)
* [Packages & details](https://git.dotclear.watch/JcDenis/postExpired/releases) (or on [Dotaddict](https://plugins.dotaddict.org/dc2/details/postExpired)) * Source & contribution : [Gitea Page](https://git.dotclear.watch/JcDenis/postExpired) or [GitHub Page](https://github.com/JcDenis/postExpired)
* [Sources & contributions](https://git.dotclear.watch/JcDenis/postExpired) (or on [GitHub](https://github.com/JcDenis/postExpired)) * Packages & details: [Gitea Page](https://git.dotclear.watch/JcDenis/postExpired/releases) or [Dotaddict Page](https://plugins.dotaddict.org/dc2/details/postExpired)
* [Issues & security](https://git.dotclear.watch/JcDenis/postExpired/issues) (or on [GitHub](https://github.com/JcDenis/postExpired/issues)) * Discuss & help : [Dotclear Forum](https://forum.dotclear.org/viewtopic.php?id=42305)
* [Discuss & help](https://forum.dotclear.org/viewtopic.php?id=42305)
## CONTRIBUTORS ## CONTRIBUTORS
* Jean-Christian Denis (author) * Jean-Christian Denis
You are welcome to contribute to this code. You are welcome to contribute to this code.

View File

@ -1,30 +1,33 @@
<?php <?php
/** /**
* @file * @brief postExpired, a plugin for Dotclear 2
* @brief The plugin postExpired definition
* @ingroup postExpired
* *
* @defgroup postExpired Plugin postExpired. * @package Dotclear
* @subpackage Plugin
* *
* Change entries options at a given date. * @author Jean-Christian Denis and Contributors
* *
* @author Tomtom (author) * @copyright Jean-Christian Denis
* @author Jean-Christian Denis (latest) * @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
*/ */
declare(strict_types=1); if (!defined('DC_RC_PATH')) {
return null;
}
$this->registerModule( $this->registerModule(
'Expired entries', 'Expired entries',
'Change entries options at a given date', 'Change entries options at a given date',
'Jean-Christian Denis and Contributors', 'Jean-Christian Denis and Contributors',
'2023.11.04', '2023.08.13',
[ [
'requires' => [['core', '2.28']], 'requires' => [['core', '2.27']],
'permissions' => 'My', 'permissions' => dcCore::app()->auth->makePermissions([
'type' => 'plugin', dcCore::app()->auth::PERMISSION_USAGE,
'support' => 'https://git.dotclear.watch/JcDenis/' . basename(__DIR__) . '/issues', dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
'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', '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

@ -2,11 +2,11 @@
<modules xmlns:da="http://dotaddict.org/da/"> <modules xmlns:da="http://dotaddict.org/da/">
<module id="postExpired"> <module id="postExpired">
<name>Expired entries</name> <name>Expired entries</name>
<version>2023.11.04</version> <version>2023.08.13</version>
<author>Jean-Christian Denis and Contributors</author> <author>Jean-Christian Denis and Contributors</author>
<desc>Change entries options at a given date</desc> <desc>Change entries options at a given date</desc>
<file>https://git.dotclear.watch/JcDenis/postExpired/releases/download/v2023.11.04/plugin-postExpired.zip</file> <file>https://git.dotclear.watch/JcDenis/postExpired/releases/download/v2023.08.13/plugin-postExpired.zip</file>
<da:dcmin>2.28</da:dcmin> <da:dcmin>2.27</da:dcmin>
<da:details>https://git.dotclear.watch/JcDenis/postExpired/src/branch/master/README.md</da:details> <da:details>https://git.dotclear.watch/JcDenis/postExpired/src/branch/master/README.md</da:details>
<da:support>https://git.dotclear.watch/JcDenis/postExpired/issues</da:support> <da:support>https://git.dotclear.watch/JcDenis/postExpired/issues</da:support>
</module> </module>

View File

@ -1,19 +1,22 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use Dotclear\App; use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/**
* @brief postExpired backend class.
* @ingroup postExpired
*
* @author Jean-Christian Denis
* @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
@ -27,19 +30,19 @@ class Backend extends Process
return false; return false;
} }
App::behavior()->addBehaviors([ dcCore::app()->addBehaviors([
'adminPostsActions' => BackendBehaviors::adminPostsActions(...), 'adminPostsActions' => [BackendBehaviors::class, 'adminPostsActions'],
'adminPagesActions' => BackendBehaviors::adminPostsActions(...), 'adminPagesActions' => [BackendBehaviors::class, 'adminPostsActions'],
'adminPostHeaders' => BackendBehaviors::adminPostHeaders(...), 'adminPostHeaders' => [BackendBehaviors::class, 'adminPostHeaders'],
'adminPageHeaders' => BackendBehaviors::adminPostHeaders(...), 'adminPageHeaders' => [BackendBehaviors::class, 'adminPostHeaders'],
'adminPostFormItems' => BackendBehaviors::adminPostFormItems(...), 'adminPostFormItems' => [BackendBehaviors::class, 'adminPostFormItems'],
'adminPageFormItems' => BackendBehaviors::adminPostFormItems(...), 'adminPageFormItems' => [BackendBehaviors::class, 'adminPostFormItems'],
'adminBeforePostDelete' => BackendBehaviors::adminBeforePostDelete(...), 'adminBeforePostDelete' => [BackendBehaviors::class, 'adminBeforePostDelete'],
'adminBeforePageDelete' => BackendBehaviors::adminBeforePostDelete(...), 'adminBeforePageDelete' => [BackendBehaviors::class, 'adminBeforePostDelete'],
'adminAfterPostUpdate' => BackendBehaviors::adminAfterPostSave(...), 'adminAfterPostUpdate' => [BackendBehaviors::class, 'adminAfterPostSave'],
'adminAfterPageUpdate' => BackendBehaviors::adminAfterPostSave(...), 'adminAfterPageUpdate' => [BackendBehaviors::class, 'adminAfterPostSave'],
'adminAfterPostCreate' => BackendBehaviors::adminAfterPostSave(...), 'adminAfterPostCreate' => [BackendBehaviors::class, 'adminAfterPostSave'],
'adminAfterPageCreate' => BackendBehaviors::adminAfterPostSave(...), 'adminAfterPageCreate' => [BackendBehaviors::class, 'adminAfterPostSave'],
]); ]);
return true; return true;

View File

@ -1,12 +1,22 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use ArrayObject; use ArrayObject;
use DateTimeZone; use DateTimeZone;
use Dotclear\App; use dcCore;
use Dotclear\Core\Backend\Action\ActionsPosts; use Dotclear\Core\Backend\Action\ActionsPosts;
use Dotclear\Core\Backend\{ use Dotclear\Core\Backend\{
Notices, Notices,
@ -34,11 +44,9 @@ use Dotclear\Helper\Html\Html;
use Exception; use Exception;
/** /**
* @brief postExpired backend behaviors class. * @ingroup DC_PLUGIN_POSTEXPIRED
* @ingroup postExpired * @brief Scheduled post change - admin methods.
* * @since 2.6
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class BackendBehaviors class BackendBehaviors
{ {
@ -55,7 +63,7 @@ class BackendBehaviors
__('Add expired date') => 'post_expired_add', __('Add expired date') => 'post_expired_add',
], ],
], ],
self::callbackAdd(...) [self::class, 'callbackAdd']
); );
$pa->addAction( $pa->addAction(
@ -64,7 +72,7 @@ class BackendBehaviors
__('Remove expired date') => 'post_expired_remove', __('Remove expired date') => 'post_expired_remove',
], ],
], ],
self::callbackRemove(...) [self::class, 'callbackRemove']
); );
} }
@ -81,9 +89,9 @@ class BackendBehaviors
/** /**
* Add form to post sidebar. * Add form to post sidebar.
* *
* @param ArrayObject<string, mixed> $main_items Main items * @param ArrayObject $main_items Main items
* @param ArrayObject<string, mixed> $sidebar_items Sidebar items * @param ArrayObject $sidebar_items Sidebar items
* @param ?MetaRecord $post Post record or null * @param ?MetaRecord $post Post record or null
*/ */
public static function adminPostFormItems(ArrayObject $main_items, ArrayObject $sidebar_items, ?MetaRecord $post): void public static function adminPostFormItems(ArrayObject $main_items, ArrayObject $sidebar_items, ?MetaRecord $post): void
{ {
@ -138,8 +146,8 @@ class BackendBehaviors
/** /**
* Posts actions callback to add expired date. * Posts actions callback to add expired date.
* *
* @param ActionsPosts $pa ActionsPosts instance * @param ActionsPosts $pa ActionsPosts instance
* @param ArrayObject<string, mixed> $post _POST actions * @param ArrayObject $post _POST actions
*/ */
public static function callbackAdd(ActionsPosts $pa, ArrayObject $post): void public static function callbackAdd(ActionsPosts $pa, ArrayObject $post): void
{ {
@ -161,8 +169,8 @@ class BackendBehaviors
) )
) { ) {
foreach ($posts_ids as $post_id) { foreach ($posts_ids as $post_id) {
self::delPostExpired((int) $post_id); self::delPostExpired($post_id);
self::setPostExpired((int) $post_id, $post); self::setPostExpired($post_id, $post);
} }
Notices::addSuccessNotice(__('Expired date added.')); Notices::addSuccessNotice(__('Expired date added.'));
@ -175,9 +183,9 @@ class BackendBehaviors
$pa->beginPage( $pa->beginPage(
Page::breadcrumb([ Page::breadcrumb([
Html::escapeHTML(App::blog()->name()) => '', Html::escapeHTML(dcCore::app()->blog->name) => '',
$pa->getCallerTitle() => $pa->getRedirection(true), $pa->getCallerTitle() => $pa->getRedirection(true),
__('Add expired date to this selection') => '', __('Add expired date to this selection') => '',
]), ]),
//Page::jsDatePicker() . //Page::jsDatePicker() .
self::adminPostHeaders() self::adminPostHeaders()
@ -189,7 +197,7 @@ class BackendBehaviors
(new Para())->items([ (new Para())->items([
... self::fieldsPostExpired($posts->f('post_type'), null, false), ... self::fieldsPostExpired($posts->f('post_type'), null, false),
... $pa->hiddenFields(), ... $pa->hiddenFields(),
App::nonce()->formNonce(), dcCore::app()->formNonce(false),
(new Hidden(['action'], 'post_expired_add')), (new Hidden(['action'], 'post_expired_add')),
(new Submit(['do']))->value(__('Save')), (new Submit(['do']))->value(__('Save')),
]), ]),
@ -202,8 +210,8 @@ class BackendBehaviors
/** /**
* Posts actions callback to add expired date. * Posts actions callback to add expired date.
* *
* @param ActionsPosts $pa ActionsPosts instance * @param ActionsPosts $pa ActionsPosts instance
* @param ArrayObject<string, mixed> $post _POST actions * @param ArrayObject $post _POST actions
*/ */
public static function callbackRemove(ActionsPosts $pa, ArrayObject $post): void public static function callbackRemove(ActionsPosts $pa, ArrayObject $post): void
{ {
@ -215,7 +223,7 @@ class BackendBehaviors
// Delete expired date // Delete expired date
foreach ($posts_ids as $post_id) { foreach ($posts_ids as $post_id) {
self::delPostExpired((int) $post_id); self::delPostExpired($post_id);
} }
Notices::addSuccessNotice(__('Expired date deleted.')); Notices::addSuccessNotice(__('Expired date deleted.'));
@ -229,14 +237,14 @@ class BackendBehaviors
*/ */
private static function delPostExpired(int $post_id): void private static function delPostExpired(int $post_id): void
{ {
App::meta()->delPostMeta($post_id, My::META_TYPE); dcCore::app()->meta->delPostMeta($post_id, My::META_TYPE);
} }
/** /**
* Save expired date. * Save expired date.
* *
* @param int $post_id Post id * @param int $post_id Post id
* @param ArrayObject<string, mixed> $post _POST fields * @param ArrayObject $post _POST fields
*/ */
private static function setPostExpired(int $post_id, ArrayObject $post): void private static function setPostExpired(int $post_id, ArrayObject $post): void
{ {
@ -273,7 +281,7 @@ class BackendBehaviors
$post_expired['newpassword'] = (string) $post['post_expired_newpassword']; $post_expired['newpassword'] = (string) $post['post_expired_newpassword'];
} }
App::meta()->setPostMeta( dcCore::app()->meta->setPostMeta(
$post_id, $post_id,
My::META_TYPE, My::META_TYPE,
My::encode($post_expired) My::encode($post_expired)
@ -286,15 +294,14 @@ class BackendBehaviors
* @param string $post_type Posts type * @param string $post_type Posts type
* @param null|int $post_id Post ID * @param null|int $post_id Post ID
* @param bool $render Render fileds to HTML * @param bool $render Render fileds to HTML
* * @return array Array of object form fields
* @return array<string, string|Para> Array of object form fields
*/ */
private static function fieldsPostExpired(string $post_type, ?int $post_id = null, bool $render = true): array private static function fieldsPostExpired(string $post_type, ?int $post_id = null, bool $render = true): array
{ {
$fields = $post_expired = []; $fields = $post_expired = [];
if ($post_id) { if ($post_id) {
$rs = App::meta()->getMetadata([ $rs = dcCore::app()->meta->getMetadata([
'meta_type' => My::META_TYPE, 'meta_type' => My::META_TYPE,
'post_id' => $post_id, 'post_id' => $post_id,
'limit' => 1, 'limit' => 1,
@ -321,7 +328,7 @@ class BackendBehaviors
$fields['post_expired_category'] = (new Para())->items([ $fields['post_expired_category'] = (new Para())->items([
(new Label(__('Category:'), Label::OUTSIDE_LABEL_BEFORE))->for('post_expired_category'), (new Label(__('Category:'), Label::OUTSIDE_LABEL_BEFORE))->for('post_expired_category'),
(new Select('post_expired_category'))->default(empty($post_expired['category']) ? '' : $post_expired['category'])->items(self::categoriesCombo( (new Select('post_expired_category'))->default(empty($post_expired['category']) ? '' : $post_expired['category'])->items(self::categoriesCombo(
App::blog()->getCategories( dcCore::app()->blog->getCategories(
['post_type' => 'post'] ['post_type' => 'post']
) )
)), )),
@ -347,15 +354,13 @@ class BackendBehaviors
(new Checkbox('post_expired_password', !empty($post_expired['password'])))->value(1), (new Checkbox('post_expired_password', !empty($post_expired['password'])))->value(1),
(new Label(__('Change password'), Label::OUTSIDE_LABEL_AFTER))->for('post_expired_password')->class('classic'), (new Label(__('Change password'), Label::OUTSIDE_LABEL_AFTER))->for('post_expired_password')->class('classic'),
(new Label(__('New password:'), Label::OUTSIDE_LABEL_BEFORE))->for('post_expired_newpassword'), (new Label(__('New password:'), Label::OUTSIDE_LABEL_BEFORE))->for('post_expired_newpassword'),
(new Input('post_expired_newpassword'))->size(65)->maxlength(255)->class('maximal')->value(empty($post_expired['newpassword']) ? '' : $post_expired['newpassword']), (new Input('post_expired_newpassword'))->size(65)->maxlenght(255)->class('maximal')->value(empty($post_expired['newpassword']) ? '' : $post_expired['newpassword']),
(new Note())->text(__('Leave empty to remove it'))->class('form-note'), (new Note())->text(__('Leave empty to remove it'))->class('form-note'),
]); ]);
if ($render) { if ($render) {
foreach ($fields as $k => $v) { foreach ($fields as $k => $v) {
if (!is_string($v)) { $fields[$k] = $v->render();
$fields[$k] = $v->render();
}
} }
} }
@ -367,7 +372,7 @@ class BackendBehaviors
* *
* @param MetaRecord $categories Categories recordset * @param MetaRecord $categories Categories recordset
* *
* @return array<int|string, string|Option> Categorires combo * @return array Categorires combo
*/ */
private static function categoriesCombo(MetaRecord $categories): array private static function categoriesCombo(MetaRecord $categories): array
{ {
@ -378,7 +383,7 @@ class BackendBehaviors
]; ];
try { try {
$categories = App::blog()->getCategories( $categories = dcCore::app()->blog->getCategories(
['post_type' => 'post'] ['post_type' => 'post']
); );
while ($categories->fetch()) { while ($categories->fetch()) {
@ -397,7 +402,7 @@ class BackendBehaviors
/** /**
* Custom status combo. * Custom status combo.
* *
* @return array<string, string> Status combo * @return array Status combo
*/ */
private static function statusCombo(): array private static function statusCombo(): array
{ {
@ -412,7 +417,7 @@ class BackendBehaviors
/** /**
* Custom selection combo. * Custom selection combo.
* *
* @return array<string, string> Selection combo * @return array Selection combo
*/ */
private static function selectedCombo(): array private static function selectedCombo(): array
{ {
@ -426,7 +431,7 @@ class BackendBehaviors
/** /**
* Custom comment status combo. * Custom comment status combo.
* *
* @return array<string, string> Comment status combo * @return array Comment status combo
*/ */
private static function commentCombo(): array private static function commentCombo(): array
{ {
@ -440,7 +445,7 @@ class BackendBehaviors
/** /**
* Custom trackback status combo. * Custom trackback status combo.
* *
* @return array<string, string> Trackback status combo * @return array Trackback status combo
*/ */
private static function trackbackCombo(): array private static function trackbackCombo(): array
{ {
@ -460,7 +465,7 @@ class BackendBehaviors
*/ */
private static function dateFromUser(string $date): string private static function dateFromUser(string $date): string
{ {
$u = App::auth()->getInfo('user_tz') ?? 'UTC'; $u = !isset(dcCore::app()->auth) ? 'UTC' : dcCore::app()->auth->getInfo('user_tz');
$d = date_create($date, new DateTimeZone($u)); $d = date_create($date, new DateTimeZone($u));
return $d ? date_format($d->setTimezone(new DateTimeZone('UTC')), 'Y-m-d H:i:00') : ''; return $d ? date_format($d->setTimezone(new DateTimeZone('UTC')), 'Y-m-d H:i:00') : '';
@ -475,7 +480,7 @@ class BackendBehaviors
*/ */
private static function dateToUser(string $date): string private static function dateToUser(string $date): string
{ {
$u = App::auth()->getInfo('user_tz') ?? 'UTC'; $u = !isset(dcCore::app()->auth) ? 'UTC' : dcCore::app()->auth->getInfo('user_tz');
$d = date_create($date, new DateTimeZone('UTC')); $d = date_create($date, new DateTimeZone('UTC'));
return $d ? date_format($d->setTimezone(new DateTimeZone($u)), 'Y-m-d\TH:i') : ''; return $d ? date_format($d->setTimezone(new DateTimeZone($u)), 'Y-m-d\TH:i') : '';

View File

@ -1,19 +1,22 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use Dotclear\App; use dcCore;
use Dotclear\Core\Process; use Dotclear\Core\Process;
/**
* @brief postExpired frontend class.
* @ingroup postExpired
*
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
class Frontend extends Process class Frontend extends Process
{ {
public static function init(): bool public static function init(): bool
@ -32,27 +35,27 @@ class Frontend extends Process
__('This entry has no expiration date'); __('This entry has no expiration date');
# launch update only on public home page and feed # launch update only on public home page and feed
if (in_array(App::url()->type, ['default', 'feed'])) { if (in_array(dcCore::app()->url->type, ['default', 'feed'])) {
App::behavior()->addBehavior( dcCore::app()->addBehavior(
'publicBeforeDocumentV2', 'publicBeforeDocumentV2',
FrontendBehaviors::publicBeforeDocumentV2(...) [FrontendBehaviors::class, 'publicBeforeDocumentV2']
); );
} }
App::behavior()->addBehavior( dcCore::app()->addBehavior(
'coreBlogGetPosts', 'coreBlogGetPosts',
FrontendBehaviors::coreBlogGetPosts(...) [FrontendBehaviors::class, 'coreBlogGetPosts']
); );
App::frontend()->template()->addBlock( dcCore::app()->tpl->addBlock(
'EntryExpiredIf', 'EntryExpiredIf',
FrontendTemplate::EntryExpiredIf(...) [FrontendTemplate::class, 'EntryExpiredIf']
); );
App::frontend()->template()->addValue( dcCore::app()->tpl->addValue(
'EntryExpiredDate', 'EntryExpiredDate',
FrontendTemplate::EntryExpiredDate(...) [FrontendTemplate::class, 'EntryExpiredDate']
); );
App::frontend()->template()->addValue( dcCore::app()->tpl->addValue(
'EntryExpiredTime', 'EntryExpiredTime',
FrontendTemplate::EntryExpiredTime(...) [FrontendTemplate::class, 'EntryExpiredTime']
); );
return true; return true;

View File

@ -1,11 +1,23 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use DateTimeZone; use DateTimeZone;
use Dotclear\App; use dcBlog;
use dcCore;
use dcMeta;
use Dotclear\Database\MetaRecord; use Dotclear\Database\MetaRecord;
use Dotclear\Database\Statement\{ use Dotclear\Database\Statement\{
JoinStatement, JoinStatement,
@ -13,11 +25,9 @@ use Dotclear\Database\Statement\{
}; };
/** /**
* @brief postExpired frontend behaviors class. * @ingroup DC_PLUGIN_POSTEXPIRED
* @ingroup postExpired * @brief Scheduled post change - public methods.
* * @since 2.6
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class FrontendBehaviors class FrontendBehaviors
{ {
@ -28,7 +38,7 @@ class FrontendBehaviors
{ {
// Get expired dates and post_id // Get expired dates and post_id
$sql = new SelectStatement(); $sql = new SelectStatement();
$posts = $sql->from($sql->as(App::con()->prefix() . App::blog()::POST_TABLE_NAME, 'P')) $posts = $sql->from($sql->as(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME, 'P'))
->columns([ ->columns([
'P.post_id', 'P.post_id',
'P.post_tz', 'P.post_tz',
@ -37,11 +47,11 @@ class FrontendBehaviors
->join( ->join(
(new JoinStatement()) (new JoinStatement())
->inner() ->inner()
->from($sql->as(App::con()->prefix() . App::meta()::META_TABLE_NAME, 'META')) ->from($sql->as(dcCore::app()->prefix . dcMeta::META_TABLE_NAME, 'META'))
->on('META.post_id = P.post_id') ->on('META.post_id = P.post_id')
->statement() ->statement()
) )
->where('blog_id = ' . $sql->quote(App::blog()->id())) ->where('blog_id = ' . $sql->quote((string) dcCore::app()->blog->id))
->and('META.meta_type = ' . $sql->quote(My::META_TYPE)) ->and('META.meta_type = ' . $sql->quote(My::META_TYPE))
->select(); ->select();
@ -55,7 +65,7 @@ class FrontendBehaviors
$now_tz = (int) date_format(date_create('now', $utc), 'U'); $now_tz = (int) date_format(date_create('now', $utc), 'U');
// Prepared post Cursor // Prepared post Cursor
$post_cur = App::blog()->openPostCursor(); $post_cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME);
// Loop through marked posts // Loop through marked posts
$updated = false; $updated = false;
@ -69,8 +79,8 @@ class FrontendBehaviors
if ($now_tz > $meta_tz) { if ($now_tz > $meta_tz) {
// Delete meta for expired date // Delete meta for expired date
App::auth()->sudo( dcCore::app()->auth->sudo(
App::meta()->delPostMeta(...), [dcCore::app()->meta, 'delPostMeta'],
$posts->f('post_id'), $posts->f('post_id'),
My::META_TYPE My::META_TYPE
); );
@ -125,7 +135,7 @@ class FrontendBehaviors
// Update post // Update post
$post_cur->update( $post_cur->update(
'WHERE post_id = ' . $posts->f('post_id') . ' ' . 'WHERE post_id = ' . $posts->f('post_id') . ' ' .
"AND blog_id = '" . App::con()->escapeStr(App::blog()->id()) . "' " "AND blog_id = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog->id) . "' "
); );
$updated = true; $updated = true;
@ -134,7 +144,7 @@ class FrontendBehaviors
// Say blog is updated // Say blog is updated
if ($updated) { if ($updated) {
App::blog()->triggerBlog(); dcCore::app()->blog->triggerBlog();
} }
} }
@ -145,6 +155,6 @@ class FrontendBehaviors
*/ */
public static function coreBlogGetPosts(MetaRecord $rs): void public static function coreBlogGetPosts(MetaRecord $rs): void
{ {
$rs->extend(rsExtPostExpired::class); $rs->extend('rsExtPostExpired');
} }
} }

View File

@ -1,27 +1,36 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use ArrayObject; use ArrayObject;
use Dotclear\App; use dcCore;
use dcTemplate;
use Dotclear\Helper\Date; use Dotclear\Helper\Date;
/** /**
* @brief postExpired frontend template class. * @ingroup DC_PLUGIN_POSTEXPIRED
* @ingroup postExpired * @brief Scheduled post change - template methods.
* * @since 2.6
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class FrontendTemplate class FrontendTemplate
{ {
/** /**
* Template condition to check if there is an expired date. * Template condition to check if there is an expired date.
* *
* @param ArrayObject<string, mixed> $attr Block attributes * @param ArrayObject $attr Block attributes
* @param string $content Block content * @param string $content Block content
* *
* @return string * @return string
*/ */
@ -29,13 +38,13 @@ class FrontendTemplate
{ {
$if = []; $if = [];
$operator = isset($attr['operator']) ? $operator = isset($attr['operator']) ?
App::frontend()->template()->getOperator($attr['operator']) : '&&'; dcTemplate::getOperator($attr['operator']) : '&&';
if (isset($attr['has_date'])) { if (isset($attr['has_date'])) {
$sign = (bool) $attr['has_date'] ? '!' : '='; $sign = (bool) $attr['has_date'] ? '!' : '=';
$if[] = '(null ' . $sign . '== App::frontend()->context()->posts->postExpiredDate())'; $if[] = '(null ' . $sign . '== dcCore::app()->ctx->posts->postExpiredDate())';
} else { } else {
$if[] = '(null !== App::frontend()->context()->posts->postExpiredDate())'; $if[] = '(null !== dcCore::app()->ctx->posts->postExpiredDate())';
} }
return return
@ -47,7 +56,7 @@ class FrontendTemplate
/** /**
* Template for expired date. * Template for expired date.
* *
* @param ArrayObject<string, mixed> $attr Value attributes * @param ArrayObject $attr Value attributes
* *
* @return string * @return string
*/ */
@ -55,38 +64,38 @@ class FrontendTemplate
{ {
$format = !empty($attr['format']) ? $format = !empty($attr['format']) ?
addslashes($attr['format']) : ''; addslashes($attr['format']) : '';
$f = App::frontend()->template()->getFilters($attr); $f = dcCore::app()->tpl->getFilters($attr);
if (!empty($attr['rfc822'])) { if (!empty($attr['rfc822'])) {
$res = sprintf($f, Date::class . '::rfc822(strtotime(App::frontend()->context()->posts->postExpiredDate()),App::frontend()->context()->posts->post_tz)'); $res = sprintf($f, Date::class . '::rfc822(strtotime(dcCore::app()->ctx->posts->postExpiredDate()),dcCore::app()->ctx->posts->post_tz)');
} elseif (!empty($attr['iso8601'])) { } elseif (!empty($attr['iso8601'])) {
$res = sprintf($f, Date::class . '::iso8601(strtotime(App::frontend()->context()->posts->postExpiredDate(),App::frontend()->context()->posts->post_tz)'); $res = sprintf($f, Date::class . '::iso8601(strtotime(dcCore::app()->ctx->posts->postExpiredDate(),dcCore::app()->ctx->posts->post_tz)');
} elseif ($format) { } elseif ($format) {
$res = sprintf($f, Date::class . "::dt2str('" . $format . "',App::frontend()->context()->posts->postExpiredDate())"); $res = sprintf($f, Date::class . "::dt2str('" . $format . "',dcCore::app()->ctx->posts->postExpiredDate())");
} else { } else {
$res = sprintf($f, Date::class . '::dt2str(App::blog()->settings()->system->date_format,App::frontend()->context()->posts->postExpiredDate())'); $res = sprintf($f, Date::class . '::dt2str(dcCore::app()->blog->settings->system->date_format,dcCore::app()->ctx->posts->postExpiredDate())');
} }
return '<?php if (null !== App::frontend()->context()->posts->postExpiredDate()) { echo ' . $res . '; } ?>'; return '<?php if (null !== dcCore::app()->ctx->posts->postExpiredDate()) { echo ' . $res . '; } ?>';
} }
/** /**
* Template for expired time. * Template for expired time.
* *
* @param ArrayObject<string, mixed> $attr Value attributes * @param ArrayObject $attr Value attributes
* *
* @return string * @return string
*/ */
public static function EntryExpiredTime(ArrayObject $attr): string public static function EntryExpiredTime(ArrayObject $attr): string
{ {
return return
'<?php if (null !== App::frontend()->context()->posts->postExpiredDate()) { echo ' . sprintf( '<?php if (null !== dcCore::app()->ctx->posts->postExpiredDate()) { echo ' . sprintf(
App::frontend()->template()->getFilters($attr), dcCore::app()->tpl->getFilters($attr),
Date::class . '::dt2str(' . Date::class . '::dt2str(' .
( (
!empty($attr['format']) ? !empty($attr['format']) ?
"'" . addslashes($attr['format']) . "'" : 'App::blog()->settings()->system->time_format' "'" . addslashes($attr['format']) . "'" : 'dcCore::app()->blog->settings->system->time_format'
) . ',App::frontend()->context()->posts->postExpiredDate())' ) . ',dcCore::app()->ctx->posts->postExpiredDate())'
) . '; } ?>'; ) . '; } ?>';
} }
} }

View File

@ -1,30 +1,46 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use dcCore;
use Dotclear\Module\MyPlugin; use Dotclear\Module\MyPlugin;
/** /**
* @brief postExpired My helper. * This module definiton.
* @ingroup postExpired
*
* @author Jean-Christian Denis
* @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 meta type */ /** @var string This module meta type */
public const META_TYPE = 'post_expired'; public const META_TYPE = 'post_expired';
public static function checkCustomContext(int $context): ?bool
{
return $context !== My::BACKEND ? null :
defined('DC_CONTEXT_ADMIN')
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
]), dcCore::app()->blog->id);
}
/** /**
* Encode Expired Date settings. * Encode Expired Date settings.
* *
* This is saved into post_meta as meta_id value, * This is saved into post_meta as meta_id value,
* so this must be less than 255 caracters. * so this must be less than 255 caracters.
* *
* @param array<string, string> $in Array of options * @param array $in Array of options
* *
* @return string "Serialized" options * @return string "Serialized" options
*/ */
@ -43,18 +59,16 @@ class My extends MyPlugin
* *
* @param string $in "Serialized" options * @param string $in "Serialized" options
* *
* @return array<string, string> Array of options * @return array Array of options
*/ */
public static function decode(string $in): array public static function decode(string $in): array
{ {
$out = []; $out = [];
foreach (explode(';', $in) as $v) { foreach (explode(';', $in) as $v) {
$v = explode('|', $v); $v = explode('|', $v);
$out[(string) $v[0]] = (string) $v[1]; $out[$v[0]] = $v[1];
} }
return $out; return $out;
} }
// Use default permissions
} }

View File

@ -1,27 +1,31 @@
<?php <?php
/**
* @brief postExpired, 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\postExpired; namespace Dotclear\Plugin\postExpired;
use Dotclear\App; use dcCore;
use Dotclear\Database\MetaRecord; use Dotclear\Database\MetaRecord;
use Dotclear\Schema\Extension\Post; use rsExtPost;
/** /**
* @brief postExpired record extension class. * @ingroup DC_PLUGIN_POSTEXPIRED
* @ingroup postExpired * @brief Scheduled post change - extends recordset.
* * @since 2.6
* @author Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/ */
class rsExtPostExpired extends Post class rsExtPostExpired extends rsExtPost
{ {
/** /** @var array $memory Memory to prevent redondant call */
* Memory to prevent redondant call.
*
* @var array<string, string> $memory
*/
protected static array $memory = []; protected static array $memory = [];
/** /**
@ -34,7 +38,7 @@ class rsExtPostExpired extends Post
public static function postExpiredDate(MetaRecord $rs): string public static function postExpiredDate(MetaRecord $rs): string
{ {
if (!static::$memory[$rs->f('post_id')]) { if (!static::$memory[$rs->f('post_id')]) {
$rs_date = App::meta()->getMetadata([ $rs_date = dcCore::app()->meta->getMetadata([
'meta_type' => My::META_TYPE, 'meta_type' => My::META_TYPE,
'post_id' => $rs->f('post_id'), 'post_id' => $rs->f('post_id'),
'limit' => 1, 'limit' => 1,
@ -44,8 +48,8 @@ class rsExtPostExpired extends Post
return ''; return '';
} }
$v = My::decode($rs_date->f('meta_id')); $v = My::decode($rs_date->f('meta_id'));
static::$memory[(string) $rs->f('post_id')] = (string) $v['date']; static::$memory[$rs->f('post_id')] = $v['date'];
} }
return static::$memory[$rs->f('post_id')]; return static::$memory[$rs->f('post_id')];