use namespace
This commit is contained in:
parent
b7affac99d
commit
ef04d66d44
35 changed files with 4781 additions and 3535 deletions
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
$opts = getopt('d:c:b:u:h');
|
$opts = getopt('d:c:b:u:h');
|
||||||
|
|
||||||
function zchelp($status = 0)
|
function zchelp(string|int $status = 0): void
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
"Options: \n" .
|
"Options: \n" .
|
||||||
|
@ -33,7 +33,7 @@ if (isset($opts['d'])) {
|
||||||
$dc_root = $_SERVER['DC_ROOT'];
|
$dc_root = $_SERVER['DC_ROOT'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($opts['c'])) {
|
if (isset($opts['c']) && is_string($opts['c'])) {
|
||||||
$dc_conf = realpath($opts['c']);
|
$dc_conf = realpath($opts['c']);
|
||||||
} elseif (isset($_SERVER['DC_RC_PATH'])) {
|
} elseif (isset($_SERVER['DC_RC_PATH'])) {
|
||||||
$dc_conf = realpath($_SERVER['DC_RC_PATH']);
|
$dc_conf = realpath($_SERVER['DC_RC_PATH']);
|
||||||
|
@ -55,7 +55,7 @@ if (!$dc_conf || !is_readable($dc_conf)) {
|
||||||
zchelp(1);
|
zchelp(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$blog_id) {
|
if (!$blog_id || !is_string($blog_id)) {
|
||||||
fwrite(STDERR, "Blog ID is not defined\n\n");
|
fwrite(STDERR, "Blog ID is not defined\n\n");
|
||||||
zchelp(1);
|
zchelp(1);
|
||||||
}
|
}
|
||||||
|
@ -69,23 +69,21 @@ unset($blog_id);
|
||||||
require $dc_root . '/inc/prepend.php';
|
require $dc_root . '/inc/prepend.php';
|
||||||
unset($dc_root);
|
unset($dc_root);
|
||||||
|
|
||||||
dcCore::app()->setBlog(DC_BLOG_ID);
|
dcCore::app()->setBlog(is_string(DC_BLOG_ID) ? DC_BLOG_ID : '');
|
||||||
if (dcCore::app()->blog->id == null) {
|
if (is_null(dcCore::app()->blog) || dcCore::app()->blog->id == null) {
|
||||||
fwrite(STDERR, "Blog is not defined\n");
|
fwrite(STDERR, "Blog is not defined\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($opts['u']) || !dcCore::app()->auth->checkUser($opts['u'])) {
|
if (!isset($opts['u']) || is_null(dcCore::app()->auth) || !dcCore::app()->auth->checkUser(is_string($opts['u']) ? $opts['u'] : '')) {
|
||||||
fwrite(STDERR, "Unable to set user\n");
|
fwrite(STDERR, "Unable to set user\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcCore::app()->plugins->loadModules(DC_PLUGINS_ROOT);
|
dcCore::app()->plugins->loadModules(DC_PLUGINS_ROOT);
|
||||||
|
|
||||||
dcCore::app()->blog->settings->addNamespace(basename(__DIR__));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$zc = new zoneclearFeedServer();
|
$zc = Dotclear\Plugin\zoneclearFeedServer\ZoneclearFeedServer::instance();
|
||||||
$zc->checkFeedsUpdate();
|
$zc->checkFeedsUpdate();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
fwrite(STDERR, $e->getMessage() . "\n");
|
fwrite(STDERR, $e->getMessage() . "\n");
|
||||||
|
|
|
@ -1,243 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
|
||||||
* @brief Mix your blog with a feeds planet - admin methods.
|
|
||||||
* @since 2.6
|
|
||||||
*/
|
|
||||||
class zcfsAdminBehaviors
|
|
||||||
{
|
|
||||||
public static function basename()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function feedsSortbyCombo()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
__('Date') => 'feed_upddt',
|
|
||||||
__('Name') => 'lowername',
|
|
||||||
__('Frequency') => 'feed_upd_int',
|
|
||||||
__('Update date') => 'feed_upd_last',
|
|
||||||
__('Status') => 'feed_status',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function entriesSortbyCombo()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
__('Date') => 'post_dt',
|
|
||||||
__('Title') => 'post_title',
|
|
||||||
__('Category') => 'cat_title',
|
|
||||||
__('Author') => 'user_id',
|
|
||||||
__('Status') => 'post_status',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Favorites.
|
|
||||||
*
|
|
||||||
* @param dcFavorites $favs Array of favorites
|
|
||||||
*/
|
|
||||||
public static function adminDashboardFavoritesV2(dcFavorites $favs)
|
|
||||||
{
|
|
||||||
$favs->register('zcfs', [
|
|
||||||
'title' => __('Feeds server'),
|
|
||||||
'url' => dcCore::app()->adminurl->get('admin.plugin.' . basename(dirname('../' . __DIR__))),
|
|
||||||
'small-icon' => dcPage::getPF(basename(dirname('../' . __DIR__)) . '/icon.svg'),
|
|
||||||
'large-icon' => dcPage::getPF(basename(dirname('../' . __DIR__)) . '/icon.svg'),
|
|
||||||
'permissions' => dcCore::app()->auth->makePermissions([
|
|
||||||
dcAuth::PERMISSION_USAGE,
|
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
|
||||||
]),
|
|
||||||
'dashboard_cb' => ['zcfsAdminBehaviors', 'adminDashboardFavoritesCallback'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Favorites hack.
|
|
||||||
*
|
|
||||||
* @param arrayObject $fav Fav attributes
|
|
||||||
*/
|
|
||||||
public static function adminDashboardFavoritesCallback($fav)
|
|
||||||
{
|
|
||||||
$zcfs = new zoneclearFeedServer();
|
|
||||||
|
|
||||||
$count = $zcfs->getFeeds(['feed_status' => '0'], true)->f(0);
|
|
||||||
if (!$count) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fav['title'] .= '<br />' . sprintf(__('%s feed disabled', '%s feeds disabled', $count), $count);
|
|
||||||
$fav['large-icon'] = dcPage::getPF(basename(dirname('../' . __DIR__)) . '/icon-update.svg');
|
|
||||||
$fav['url'] = dcCore::app()->adminurl->get(
|
|
||||||
'admin.plugin.' . basename(dirname('../' . __DIR__)),
|
|
||||||
['part' => 'feeds', 'sortby' => 'feed_status', 'order' => 'asc']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User pref columns lists.
|
|
||||||
*
|
|
||||||
* @param arrayObject $cols Columns
|
|
||||||
*/
|
|
||||||
public static function adminColumnsListsV2($cols)
|
|
||||||
{
|
|
||||||
$cols['zcfs_feeds'] = [
|
|
||||||
__('Feeds server: Feeds'),
|
|
||||||
[
|
|
||||||
'desc' => [true, __('Feed')],
|
|
||||||
'period' => [true, __('Frequency')],
|
|
||||||
'update' => [true, __('Last update')],
|
|
||||||
'entries' => [true, __('Entries')],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
$cols['zcfs_entries'] = [
|
|
||||||
__('Feeds server: Entries'),
|
|
||||||
[
|
|
||||||
'date' => [true, __('Date')],
|
|
||||||
'category' => [true, __('Category')],
|
|
||||||
'author' => [true, __('Author')],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User pref filters options.
|
|
||||||
*
|
|
||||||
* @param arrayObject $sorts Sort options
|
|
||||||
*/
|
|
||||||
public static function adminFiltersListsV2($sorts)
|
|
||||||
{
|
|
||||||
$sorts['zcfs_feeds'] = [
|
|
||||||
__('Feeds server: Feeds'),
|
|
||||||
self::feedsSortbyCombo(),
|
|
||||||
'lowername',
|
|
||||||
'asc',
|
|
||||||
[__('feeds per page'), 30],
|
|
||||||
];
|
|
||||||
$sorts['zcfs_entries'] = [
|
|
||||||
__('Feeds server: Entries'),
|
|
||||||
self::entriesSortbyCombo(),
|
|
||||||
'post_dt',
|
|
||||||
'desc',
|
|
||||||
[__('entries per page'), 30],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add javascript for toggle to post edition page header.
|
|
||||||
*
|
|
||||||
* @return string Page header
|
|
||||||
*/
|
|
||||||
public static function adminPostHeaders()
|
|
||||||
{
|
|
||||||
return dcPage::jsLoad(dcPage::getPF(basename(dirname('../' . __DIR__)) . '/js/post.js'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add form to post sidebar.
|
|
||||||
*
|
|
||||||
* @param ArrayObject $main_items Main items
|
|
||||||
* @param ArrayObject $sidebar_items Sidebar items
|
|
||||||
* @param record $post Post record or null
|
|
||||||
*/
|
|
||||||
public static function adminPostFormItems(ArrayObject $main_items, ArrayObject $sidebar_items, $post)
|
|
||||||
{
|
|
||||||
if ($post === null || $post->post_type != 'post') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$url = dcCore::app()->meta->getMetadata([
|
|
||||||
'post_id' => $post->post_id,
|
|
||||||
'meta_type' => 'zoneclearfeed_url',
|
|
||||||
'limit' => 1,
|
|
||||||
]);
|
|
||||||
$url = $url->isEmpty() ? '' : $url->meta_id;
|
|
||||||
if (!$url) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$author = dcCore::app()->meta->getMetadata([
|
|
||||||
'post_id' => $post->post_id,
|
|
||||||
'meta_type' => 'zoneclearfeed_author',
|
|
||||||
'limit' => 1,
|
|
||||||
]);
|
|
||||||
$author = $author->isEmpty() ? '' : $author->meta_id;
|
|
||||||
|
|
||||||
$site = dcCore::app()->meta->getMetadata([
|
|
||||||
'post_id' => $post->post_id,
|
|
||||||
'meta_type' => 'zoneclearfeed_site',
|
|
||||||
'limit' => 1,
|
|
||||||
]);
|
|
||||||
$site = $site->isEmpty() ? '' : $site->meta_id;
|
|
||||||
|
|
||||||
$sitename = dcCore::app()->meta->getMetadata([
|
|
||||||
'post_id' => $post->post_id,
|
|
||||||
'meta_type' => 'zoneclearfeed_sitename',
|
|
||||||
'limit' => 1,
|
|
||||||
]);
|
|
||||||
$sitename = $sitename->isEmpty() ? '' : $sitename->meta_id;
|
|
||||||
|
|
||||||
$edit = '';
|
|
||||||
if (dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_CONTENT_ADMIN]), dcCore::app()->blog->id)) {
|
|
||||||
$fid = dcCore::app()->meta->getMetadata([
|
|
||||||
'post_id' => $post->post_id,
|
|
||||||
'meta_type' => 'zoneclearfeed_id',
|
|
||||||
'limit' => 1,
|
|
||||||
]);
|
|
||||||
if (!$fid->isEmpty()) {
|
|
||||||
$edit = sprintf(
|
|
||||||
'<p><a href="%s">%s</a></p>',
|
|
||||||
dcCore::app()->adminurl->get(
|
|
||||||
'admin.plugin.' . basename(dirname('../' . __DIR__)),
|
|
||||||
['part' => 'feed', 'feed_id' => $fid->meta_id]
|
|
||||||
),
|
|
||||||
__('Edit this feed')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$sidebar_items['options-box']['items']['zcfs'] = '<div id="zcfs">' .
|
|
||||||
'<h5>' . __('Feed source') . '</h5>' .
|
|
||||||
'<p>' .
|
|
||||||
'<a href="' . $url . '" title="' . $author . ' - ' . $url . '">' . __('feed URL') . '</a> - ' .
|
|
||||||
'<a href="' . $site . '" title="' . $sitename . ' - ' . $site . '">' . __('site URL') . '</a>' .
|
|
||||||
'</p>' .
|
|
||||||
$edit .
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete related info about feed post in meta table.
|
|
||||||
*
|
|
||||||
* @param integer $post_id Post id
|
|
||||||
*/
|
|
||||||
public static function adminBeforePostDelete($post_id)
|
|
||||||
{
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' ' .
|
|
||||||
'WHERE post_id = ' . ((int) $post_id) . ' ' .
|
|
||||||
'AND meta_type ' . dcCore::app()->con->in([
|
|
||||||
'zoneclearfeed_url',
|
|
||||||
'zoneclearfeed_author',
|
|
||||||
'zoneclearfeed_site',
|
|
||||||
'zoneclearfeed_sitename',
|
|
||||||
'zoneclearfeed_id',
|
|
||||||
]) . ' '
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_RC_PATH')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
|
||||||
* @brief Mix your blog with a feeds planet - public methods.
|
|
||||||
* @since 2.6
|
|
||||||
*/
|
|
||||||
class zcfsPublicBehaviors
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Remember others post extension.
|
|
||||||
*
|
|
||||||
* @param dcRecord $rs record instance
|
|
||||||
*/
|
|
||||||
public static function coreBlogGetPosts(dcRecord $rs)
|
|
||||||
{
|
|
||||||
dcCore::app()->__set('beforeZcFeedRsExt', $rs->extensions());
|
|
||||||
$rs->extend('zcfsRsExtPosts');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update feeds after contents.
|
|
||||||
*/
|
|
||||||
public static function publicAfterDocumentV2()
|
|
||||||
{
|
|
||||||
# Limit feeds update to home page et feed page
|
|
||||||
# Like publishScheduledEntries
|
|
||||||
if (!in_array(dcCore::app()->url->type, ['default', 'feed'])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
self::publicDocumentV2();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic behavior for before and after public content.
|
|
||||||
*/
|
|
||||||
public static function publicDocumentV2()
|
|
||||||
{
|
|
||||||
$zc = new zoneclearFeedServer();
|
|
||||||
$zc->checkFeedsUpdate();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update feeds by an Ajax request (background).
|
|
||||||
*/
|
|
||||||
public static function publicHeadContent()
|
|
||||||
{
|
|
||||||
# Limit update to home page
|
|
||||||
if (dcCore::app()->url->type != 'default') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$blog_url = html::escapeJS(
|
|
||||||
dcCore::app()->blog->url .
|
|
||||||
dcCore::app()->url->getBase('zoneclearFeedsPage') .
|
|
||||||
'/zcfsupd'
|
|
||||||
);
|
|
||||||
$blog_id = html::escapeJS(dcCore::app()->blog->id);
|
|
||||||
|
|
||||||
echo
|
|
||||||
"\n<!-- JS for zoneclearFeedServer --> \n" .
|
|
||||||
dcUtils::jsLoad(dcCore::app()->blog->url . dcCore::app()->url->getBase('zoneclearFeedsPage') . '/zcfsupd.js') .
|
|
||||||
"<script type=\"text/javascript\"> \n//<![CDATA[\n" .
|
|
||||||
' $(function(){if(!document.getElementById){return;} ' .
|
|
||||||
" $('body').zoneclearFeedServer({blog_url:'" .
|
|
||||||
$blog_url . "',blog_id:'" . $blog_id . "'}); " .
|
|
||||||
" })\n" .
|
|
||||||
"//]]>\n</script>\n";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,8 @@
|
||||||
$(function(){
|
/*global $, dotclear */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(() => {
|
||||||
$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});
|
$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});
|
||||||
|
dotclear.condSubmit('#form-feeds td input[type=checkbox]', '#form-feeds #feeds-action');
|
||||||
|
dotclear.condSubmit('#form-entries td input[type=checkbox]', '#form-entries #feed-action');
|
||||||
});
|
});
|
|
@ -1,7 +1,10 @@
|
||||||
$(function(){
|
/*global $, dotclear */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$(() => {
|
||||||
/* toogle admin form sidebar */
|
/* toogle admin form sidebar */
|
||||||
$('#zcfs h5').toggleWithLegend(
|
$('#zcfs h5').toggleWithLegend(
|
||||||
$('#zcfs').children().not('h5'),
|
$('#zcfs').children().not('h5'),
|
||||||
{cookie:'dcx_zcfs_admin_form_sidebar',legend_click:true}
|
{user_pref:'dcx_zcfs_admin_form_sidebar',legend_click:true}
|
||||||
);
|
);
|
||||||
});
|
});
|
160
locales/fr/main.lang.php
Normal file
160
locales/fr/main.lang.php
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package Dotclear
|
||||||
|
*
|
||||||
|
* @copyright Olivier Meunier & Association Dotclear
|
||||||
|
* @copyright GPL-2.0-only
|
||||||
|
*/
|
||||||
|
#
|
||||||
|
# DOT NOT MODIFY THIS FILE !
|
||||||
|
#
|
||||||
|
|
||||||
|
use Dotclear\Helper\L10n;
|
||||||
|
|
||||||
|
L10n::$locales['List of feeds'] = 'Liste des sources';
|
||||||
|
L10n::$locales['Feed properties update'] = 'Mise à jour de flux';
|
||||||
|
L10n::$locales['Feed named "%s" point to "%s" has been updated by "%s"'] = 'Le flux nommé "%s" pointant vers "%s" a été mis à jour par "%s"';
|
||||||
|
L10n::$locales['Feed creation'] = 'Création de flux';
|
||||||
|
L10n::$locales['A new feed named "%s" point to "%s" was added by "%s"'] = 'Un nouveau flux nommé "%s" pointant vers "%s" a été ajouté par "%s"';
|
||||||
|
L10n::$locales['Feed status'] = 'Satut de flux';
|
||||||
|
L10n::$locales['Feed named "%s" point to "%s" has been set to "%s"'] = 'Le flux nommé "%s" pointant vers "%s" a été marqué comme "%s"';
|
||||||
|
L10n::$locales['Feed deletion'] = 'Suppression de flux';
|
||||||
|
L10n::$locales['Feed named "%s" point to "%s" has been deleted by "%s"'] = 'Le flux nommé "%s" pointant vers "%s" a été supprimé par "%s"';
|
||||||
|
L10n::$locales['Check feed update'] = 'Vérification de flux';
|
||||||
|
L10n::$locales['Feed named "%s" has been updated automatically'] = 'Le flux nommé "%s" pointant vers "%s" a été vérifié automatiquement';
|
||||||
|
L10n::$locales['%s feed disabled'] = [
|
||||||
|
'%s flux désactivé',
|
||||||
|
'%s flux désactivés',
|
||||||
|
];
|
||||||
|
L10n::$locales['Feeds server: Feeds'] = 'Serveur de flux : Flux';
|
||||||
|
L10n::$locales['Feed'] = 'Flux';
|
||||||
|
L10n::$locales['Feeds server: Entries'] = 'Serveur de flux : Billets';
|
||||||
|
L10n::$locales['Feed server'] = 'Serveur de flux';
|
||||||
|
L10n::$locales['feeds per page'] = 'flux par page';
|
||||||
|
L10n::$locales['edit feed'] = 'Modifier le flux';
|
||||||
|
L10n::$locales['Edit this feed'] = 'Modifier ce flux';
|
||||||
|
L10n::$locales['Feed source'] = 'Source du flux';
|
||||||
|
L10n::$locales['feed URL'] = 'URL du fil';
|
||||||
|
L10n::$locales['site URL'] = 'URL du site';
|
||||||
|
L10n::$locales['Update date'] = 'Date de mise à jour';
|
||||||
|
L10n::$locales['Disabled'] = 'Désactivé';
|
||||||
|
L10n::$locales['Enabled'] = 'Activé';
|
||||||
|
L10n::$locales['Every hour'] = 'Toutes les heures';
|
||||||
|
L10n::$locales['Every two hours'] = 'Toutes les deux heures';
|
||||||
|
L10n::$locales['Two times per day'] = 'Deux fois par jour';
|
||||||
|
L10n::$locales['Every day'] = 'Chaque jour';
|
||||||
|
L10n::$locales['Every two days'] = 'Tous les deux jours';
|
||||||
|
L10n::$locales['Keep source case'] = 'Garder la casse de la source';
|
||||||
|
L10n::$locales['First upper case'] = 'Premier caractère en majuscule';
|
||||||
|
L10n::$locales['All lower case'] = 'Tout en minuscule';
|
||||||
|
L10n::$locales['All upper case'] = 'Tout en majuscule';
|
||||||
|
L10n::$locales['Disable'] = 'Désactiver';
|
||||||
|
L10n::$locales['Before display'] = 'Avant l\'affichage';
|
||||||
|
L10n::$locales['After display'] = 'Après l\'affichage';
|
||||||
|
L10n::$locales['Through Ajax'] = 'À travers Ajax';
|
||||||
|
L10n::$locales['Configuration has been successfully updated.'] = 'La configuration a été mise à jour avec succés.';
|
||||||
|
L10n::$locales['Dotclear cache is not writable or not well configured!'] = 'Le cache de Dotclear n\'est pas accessible en écriture ou n\'est pas configuré !';
|
||||||
|
L10n::$locales['View the public list of feeds'] = 'Voir la page publique de la liste des flux';
|
||||||
|
L10n::$locales['Enable plugin'] = 'Activer le plugin';
|
||||||
|
L10n::$locales['Status of new posts:'] = 'Status des nouveaux billets :';
|
||||||
|
L10n::$locales['Owner of entries created by the feed server:'] = 'Propriétaire des billets créés par le serveur de flux :';
|
||||||
|
L10n::$locales['How to transform imported tags:'] = 'Comment tranformer la casse des mots-clés importés :';
|
||||||
|
L10n::$locales['Update feeds on public side:'] = 'Mettre à jour les flux depuis la partie publique :';
|
||||||
|
L10n::$locales['Number of feeds to update at one time:'] = 'Nombre de flux mis à jour à la fois :';
|
||||||
|
L10n::$locales['Keep active empty feeds'] = 'Garder actif les flux vides';
|
||||||
|
L10n::$locales['Enable public page'] = 'Activer la page publique';
|
||||||
|
L10n::$locales['Redirect to original post on:'] = 'Rediriger vers le billet original sur :';
|
||||||
|
L10n::$locales['Show full content on:'] = 'Afficher le contenu complet sur :';
|
||||||
|
L10n::$locales['Feeds'] = 'Flux de syndication';
|
||||||
|
L10n::$locales['Feeds server'] = 'Serveur de flux';
|
||||||
|
L10n::$locales['Back to feeds list'] = 'Retour à la liste des flux';
|
||||||
|
L10n::$locales['Feeds actions'] = 'Actions sur les flux';
|
||||||
|
L10n::$locales['Change update interval'] = 'Changer l\'interval de mise à jour';
|
||||||
|
L10n::$locales['Disable feed update'] = 'Désactiver la mise à jour du flux';
|
||||||
|
L10n::$locales['Enable feed update'] = 'Activer la mise à jour du flux';
|
||||||
|
L10n::$locales['Reset last update'] = 'Remettre à zéro le chronomètre de mise à jour';
|
||||||
|
L10n::$locales['Update (check) feed'] = 'Mettre à jour (vérifier) le flux';
|
||||||
|
L10n::$locales['Delete related posts'] = 'Effacer les billets liés';
|
||||||
|
L10n::$locales['Delete feed (without related posts)'] = 'Effacer le flux (sans effacer les billets liés)';
|
||||||
|
L10n::$locales['No feeds selected'] = 'Aucun flux selectionné';
|
||||||
|
L10n::$locales['Entries have been successfully deleted.'] = 'Les billets ont été effacé avec succès.';
|
||||||
|
L10n::$locales['%d feed has been successfully updated.'] = [
|
||||||
|
'%s flux a été mis à jour.',
|
||||||
|
'%s flux ont été mis à jour.',
|
||||||
|
];
|
||||||
|
L10n::$locales['Last update of %s feed successfully reseted.'] = [
|
||||||
|
'La date de dernière mise à jour de %s flux a été remis à zéro.',
|
||||||
|
'Les date de dernière mise à jour de %s flux ont été remis à zéro.',
|
||||||
|
];
|
||||||
|
L10n::$locales['Category of %s feed successfully changed.'] = [
|
||||||
|
'La catégorie de %s flux a été changé.',
|
||||||
|
'Les catégories de %s flux ont été changé.',
|
||||||
|
];
|
||||||
|
L10n::$locales['Update frequency of %s feed successfully changed.'] = [
|
||||||
|
'La fréquence de mise à jour de %s flux a été changé.',
|
||||||
|
'Les fréquences de mise à jour de %s flux ont été changé.',
|
||||||
|
];
|
||||||
|
L10n::$locales['Change update frequency for this selection'] = 'Changer la fréquence de mise à jour pour la selection';
|
||||||
|
L10n::$locales['Frequency:'] = 'Fréquence :';
|
||||||
|
L10n::$locales['No feeds matches the filter'] = 'Aucun flux correspondant au filtre.';
|
||||||
|
L10n::$locales['No feeds'] = 'Aucun flux';
|
||||||
|
L10n::$locales['List of %s feeds matching the filter.'] = 'Liste des %s flux correspondant au filtre.';
|
||||||
|
L10n::$locales['List of feeds. (%s)'] = 'Liste des flux. (%s)';
|
||||||
|
L10n::$locales['enabled'] = 'activé';
|
||||||
|
L10n::$locales['disabled'] = 'désactivé';
|
||||||
|
L10n::$locales['never'] = 'jamais';
|
||||||
|
L10n::$locales['View entries'] = 'Voir les billets';
|
||||||
|
L10n::$locales['Module is not wel configured'] = 'Le module n\'est pas configuré correctement';
|
||||||
|
L10n::$locales['Feeds list'] = 'Liste de flux';
|
||||||
|
L10n::$locales['New feed'] = 'Nouveau flux';
|
||||||
|
L10n::$locales['Selected feeds action:'] = 'Action sur les flux sélectionnés :';
|
||||||
|
L10n::$locales['Record with same feed URL already exists.'] = 'Un enregistrement avec la même URL de flux existe déjà.';
|
||||||
|
L10n::$locales['You must provide a name.'] = 'Vous devez indiquer un nom.';
|
||||||
|
L10n::$locales['You must provide an owner.'] = 'Vous devez indiquer un propriétaire.';
|
||||||
|
L10n::$locales['You must provide valid site URL.'] = 'Vous devez donner une URL de site valide.';
|
||||||
|
L10n::$locales['You must provide valid feed URL.'] = 'Vous devez donner une URL de flux valide.';
|
||||||
|
L10n::$locales['You must provide valid category.'] = 'Vous devez donner une catégorie valide.';
|
||||||
|
L10n::$locales['Failed to save feed.'] = 'Impossible de sauvegarder le flux.';
|
||||||
|
L10n::$locales['Feed successfully created.'] = 'Flux créé avec succcès.';
|
||||||
|
L10n::$locales['Edit feed'] = 'Edition de flux';
|
||||||
|
L10n::$locales['Edit feed "%s"'] = 'Modifier le flux "%s"';
|
||||||
|
L10n::$locales['Feed information'] = 'Information sur le flux';
|
||||||
|
L10n::$locales['Owner:'] = 'Propriétaire :';
|
||||||
|
L10n::$locales['Site URL:'] = 'URL du site :';
|
||||||
|
L10n::$locales['Tweeter or Identica ident:'] = 'Identifiant Twiiter ou Identi.ca :';
|
||||||
|
L10n::$locales['Local settings'] = 'Paramètres locaux';
|
||||||
|
L10n::$locales['Update:'] = 'Mise à jour :';
|
||||||
|
L10n::$locales['Import tags from feed'] = 'Importer les tags depuis le flux';
|
||||||
|
L10n::$locales['This feed does not exist.'] = 'Ce flux n\'existe pas.';
|
||||||
|
L10n::$locales['next feed'] = 'flux suivant';
|
||||||
|
L10n::$locales['previous feed'] = 'flux précédent';
|
||||||
|
L10n::$locales['No entries matches the filter'] = 'Aucun billet correspondant au filtre.';
|
||||||
|
L10n::$locales['No entries'] = 'Aucun billet';
|
||||||
|
L10n::$locales['List of entries. (%s)'] = 'Liste des billets. (%s)';
|
||||||
|
L10n::$locales['Original post on <a href="%s">%s</a>'] = 'Billet original sur <a href="%s">%s</a>';
|
||||||
|
L10n::$locales['Read more details about this feed'] = 'Lire plus de détails à propos de ce flux';
|
||||||
|
L10n::$locales['Feeds server: sources'] = 'Serveur de flux : les sources';
|
||||||
|
L10n::$locales['List sources of feeds'] = 'Liste des sources du flux';
|
||||||
|
L10n::$locales['Feeds sources'] = 'Sources des flux';
|
||||||
|
L10n::$locales['Create date'] = 'Date de création';
|
||||||
|
L10n::$locales['Limit:'] = 'Limite :';
|
||||||
|
L10n::$locales['Link to the list of sources:'] = 'Lien vers la liste des sources :';
|
||||||
|
L10n::$locales['All sources'] = 'Toutes les sources';
|
||||||
|
L10n::$locales['Feeds server: numbers'] = 'Serveur de flux : les chiffres';
|
||||||
|
L10n::$locales['Show some numbers about feeds'] = 'Afficher quelques chiffres à propose du flux';
|
||||||
|
L10n::$locales['Feeds numbers'] = 'Le flux en chiffres';
|
||||||
|
L10n::$locales['Show feeds count'] = 'Afficher le nombre de flux';
|
||||||
|
L10n::$locales['Title for feeds count:'] = 'Titre pour le nombre de flux :';
|
||||||
|
L10n::$locales['Feeds:'] = 'Flux :';
|
||||||
|
L10n::$locales['Show entries count'] = 'Afficher le nombre de billets';
|
||||||
|
L10n::$locales['Title for entries count:'] = 'Titre pour le nombre de billets :';
|
||||||
|
L10n::$locales['Entries:'] = 'Billets :';
|
||||||
|
L10n::$locales['one source'] = 'une source';
|
||||||
|
L10n::$locales['no sources'] = 'aucune source';
|
||||||
|
L10n::$locales['one entry'] = 'une publication';
|
||||||
|
L10n::$locales['no entries'] = 'aucune publication';
|
||||||
|
L10n::$locales['Entries pages'] = 'Pages des billets';
|
||||||
|
L10n::$locales['Tags pages'] = 'Pages des mots-clés';
|
||||||
|
L10n::$locales['Archives pages'] = 'Pages des archives';
|
||||||
|
L10n::$locales['Category pages'] = 'Pages de catégories';
|
||||||
|
L10n::$locales['Mix your blog with a feeds planet'] = 'Mixer votre blog avec un planet';
|
|
@ -1,399 +1,560 @@
|
||||||
|
# Language: Français
|
||||||
|
# Module: zoneclearFeedServer - 2022.12.11.00001
|
||||||
|
# Date: 2023-05-07 22:36:31
|
||||||
|
# Author: Jean-Christian Denis
|
||||||
|
# Translated with translater 2023.04.23
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Project-Id-Version: zoneclearFeedServer 2022.11.26\n"
|
"Project-Id-Version: zoneclearFeedServer 2022.12.11.00001\n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: 2022-12-10T22:19:59+00:00\n"
|
"PO-Revision-Date: 2023-05-07T22:36:31+00:00\n"
|
||||||
"Last-Translator: Jean-Christian Denis\n"
|
"Last-Translator: Jean-Christian Denis\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
msgid "Feeds server"
|
#: default-templates/currywurst/zcfeeds.html:4
|
||||||
msgstr "Serveur de flux"
|
#: default-templates/mustek/zcfeeds.html:4
|
||||||
|
#: src/Frontend.php:52
|
||||||
msgid "Disable"
|
|
||||||
msgstr "Désactiver"
|
|
||||||
|
|
||||||
msgid "Before display"
|
|
||||||
msgstr "Avant l'affichage"
|
|
||||||
|
|
||||||
msgid "After display"
|
|
||||||
msgstr "Après l'affichage"
|
|
||||||
|
|
||||||
msgid "Through Ajax"
|
|
||||||
msgstr "À travers Ajax"
|
|
||||||
|
|
||||||
msgid "Keep source case"
|
|
||||||
msgstr "Garder la casse de la source"
|
|
||||||
|
|
||||||
msgid "First upper case"
|
|
||||||
msgstr "Premier caractère en majuscule"
|
|
||||||
|
|
||||||
msgid "All lower case"
|
|
||||||
msgstr "Tout en minuscule"
|
|
||||||
|
|
||||||
msgid "All upper case"
|
|
||||||
msgstr "Tout en majuscule"
|
|
||||||
|
|
||||||
msgid "Dotclear cache is not writable or not well configured!"
|
|
||||||
msgstr "Le cache de Dotclear n'est pas accessible en écriture ou n'est pas configuré !"
|
|
||||||
|
|
||||||
msgid "Enable plugin"
|
|
||||||
msgstr "Activer le plugin"
|
|
||||||
|
|
||||||
msgid "View the public list of feeds"
|
|
||||||
msgstr "Voir la page publique de la liste des flux"
|
|
||||||
|
|
||||||
msgid "Rules"
|
|
||||||
msgstr "Règles"
|
|
||||||
|
|
||||||
msgid "Status of new posts:"
|
|
||||||
msgstr "Status des nouveaux billets :"
|
|
||||||
|
|
||||||
msgid "Owner of entries created by zoneclearFeedServer:"
|
|
||||||
msgstr "Propriétaire des billets créés par zoneclearFeedServer :"
|
|
||||||
|
|
||||||
msgid "How to transform imported tags:"
|
|
||||||
msgstr "Comment tranformer la casse des mots-clés importés :"
|
|
||||||
|
|
||||||
msgid "Update feeds on public side:"
|
|
||||||
msgstr "Mettre à jour les flux depuis la partie publique :"
|
|
||||||
|
|
||||||
msgid "Update %s feed(s) at a time."
|
|
||||||
msgstr "Mettre à jour %s flux à la fois."
|
|
||||||
|
|
||||||
msgid "Keep active empty feeds"
|
|
||||||
msgstr "Garder actif les flux vides"
|
|
||||||
|
|
||||||
msgid "Enable public page"
|
|
||||||
msgstr "Activer la page publique"
|
|
||||||
|
|
||||||
msgid "Redirect to original post on:"
|
|
||||||
msgstr "Rediriger vers le billet original sur :"
|
|
||||||
|
|
||||||
msgid "Show full content on:"
|
|
||||||
msgstr "Afficher le contenu complet sur :"
|
|
||||||
|
|
||||||
msgid "List of feeds"
|
msgid "List of feeds"
|
||||||
msgstr "Liste des sources"
|
msgstr "Liste des sources"
|
||||||
|
|
||||||
msgid "Feeds server: sources"
|
#: src/ActivityReportActions.php:36
|
||||||
msgstr "Serveur de flux : les sources"
|
msgid "Feed properties update"
|
||||||
|
msgstr "Mise à jour de flux"
|
||||||
msgid "List sources of feeds"
|
|
||||||
msgstr "Liste des sources du flux"
|
|
||||||
|
|
||||||
msgid "Feeds sources"
|
|
||||||
msgstr "Sources des flux"
|
|
||||||
|
|
||||||
msgid "Create date"
|
|
||||||
msgstr "Date de création"
|
|
||||||
|
|
||||||
msgid "Limit:"
|
|
||||||
msgstr "Limite :"
|
|
||||||
|
|
||||||
msgid "Link to the list of sources:"
|
|
||||||
msgstr "Lien vers la liste des sources :"
|
|
||||||
|
|
||||||
msgid "All sources"
|
|
||||||
msgstr "Toutes les sources"
|
|
||||||
|
|
||||||
msgid "Feeds server: numbers"
|
|
||||||
msgstr "Serveur de flux : les chiffres"
|
|
||||||
|
|
||||||
msgid "Show some numbers about feeds"
|
|
||||||
msgstr "Afficher quelques chiffres à propose du flux"
|
|
||||||
|
|
||||||
msgid "Feeds numbers"
|
|
||||||
msgstr "Le flux en chiffres"
|
|
||||||
|
|
||||||
msgid "Show feeds count"
|
|
||||||
msgstr "Afficher le nombre de flux"
|
|
||||||
|
|
||||||
msgid "Title for feeds count:"
|
|
||||||
msgstr "Titre pour le nombre de flux :"
|
|
||||||
|
|
||||||
msgid "Feeds:"
|
|
||||||
msgstr "Flux :"
|
|
||||||
|
|
||||||
msgid "Show entries count"
|
|
||||||
msgstr "Afficher le nombre de billets"
|
|
||||||
|
|
||||||
msgid "Title for entries count:"
|
|
||||||
msgstr "Titre pour le nombre de billets :"
|
|
||||||
|
|
||||||
msgid "Entries:"
|
|
||||||
msgstr "Billets :"
|
|
||||||
|
|
||||||
msgid "one source"
|
|
||||||
msgstr "une source"
|
|
||||||
|
|
||||||
msgid "no sources"
|
|
||||||
msgstr "aucune source"
|
|
||||||
|
|
||||||
msgid "one entry"
|
|
||||||
msgstr "une publication"
|
|
||||||
|
|
||||||
msgid "no entries"
|
|
||||||
msgstr "aucune publication"
|
|
||||||
|
|
||||||
msgid "feed creation"
|
|
||||||
msgstr "création d'un flux"
|
|
||||||
|
|
||||||
msgid "A new feed named \"%s\" point to \"%s\" was added by \"%s\""
|
|
||||||
msgstr "Un nouveau flux nommé \"%s\" pointant vers \"%s\" a été ajouté par \"%s\""
|
|
||||||
|
|
||||||
msgid "updating feed info"
|
|
||||||
msgstr "mise à jour des informations du flux (administration)"
|
|
||||||
|
|
||||||
|
#: src/ActivityReportActions.php:37
|
||||||
msgid "Feed named \"%s\" point to \"%s\" has been updated by \"%s\""
|
msgid "Feed named \"%s\" point to \"%s\" has been updated by \"%s\""
|
||||||
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été mis à jour par \"%s\""
|
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été mis à jour par \"%s\""
|
||||||
|
|
||||||
msgid "updating feed records"
|
#: src/ActivityReportActions.php:63
|
||||||
msgstr "mise à jour des enregistrements du flux (automatique)"
|
msgid "Feed creation"
|
||||||
|
msgstr "Création de flux"
|
||||||
|
|
||||||
msgid "Records of the feed named \"%s\" have been updated automatically"
|
#: src/ActivityReportActions.php:64
|
||||||
msgstr "Les enregistrements du flux nommé \"%s\" ont été automatiquement mis à jour"
|
msgid "A new feed named \"%s\" point to \"%s\" was added by \"%s\""
|
||||||
|
msgstr "Un nouveau flux nommé \"%s\" pointant vers \"%s\" a été ajouté par \"%s\""
|
||||||
|
|
||||||
msgid "feed deletion"
|
#: src/ActivityReportActions.php:83
|
||||||
msgstr "suppression d'un flux"
|
msgid "Feed status"
|
||||||
|
msgstr "Satut de flux"
|
||||||
msgid "Feed named \"%s\" point to \"%s\" has been deleted by \"%s\""
|
|
||||||
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été supprimé par \"%s\""
|
|
||||||
|
|
||||||
msgid "feed status"
|
|
||||||
msgstr "status d'un flux"
|
|
||||||
|
|
||||||
|
#: src/ActivityReportActions.php:84
|
||||||
msgid "Feed named \"%s\" point to \"%s\" has been set to \"%s\""
|
msgid "Feed named \"%s\" point to \"%s\" has been set to \"%s\""
|
||||||
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été marqué comme \"%s\""
|
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été marqué comme \"%s\""
|
||||||
|
|
||||||
msgid "Update date"
|
#: src/ActivityReportActions.php:105
|
||||||
msgstr "Date de mise à jour"
|
msgid "Feed deletion"
|
||||||
|
msgstr "Suppression de flux"
|
||||||
|
|
||||||
|
#: src/ActivityReportActions.php:106
|
||||||
|
msgid "Feed named \"%s\" point to \"%s\" has been deleted by \"%s\""
|
||||||
|
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été supprimé par \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityReportActions.php:132
|
||||||
|
msgid "Check feed update"
|
||||||
|
msgstr "Vérification de flux"
|
||||||
|
|
||||||
|
#: src/ActivityReportActions.php:133
|
||||||
|
msgid "Feed named \"%s\" has been updated automatically"
|
||||||
|
msgstr "Le flux nommé \"%s\" pointant vers \"%s\" a été vérifié automatiquement"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:68
|
||||||
msgid "%s feed disabled"
|
msgid "%s feed disabled"
|
||||||
msgid_plural "%s feeds disabled"
|
msgid_plural "%s feeds disabled"
|
||||||
msgstr[0] "%s flux désactivé"
|
msgstr[0] "%s flux désactivé"
|
||||||
msgstr[1] "%s flux désactivés"
|
msgstr[1] "%s flux désactivés"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:85
|
||||||
msgid "Feeds server: Feeds"
|
msgid "Feeds server: Feeds"
|
||||||
msgstr "Serveur de flux : Flux"
|
msgstr "Serveur de flux : Flux"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:87
|
||||||
|
#: src/FeedsList.php:62
|
||||||
|
#: src/ManageFeed.php:236
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr "Flux"
|
msgstr "Flux"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:95
|
||||||
msgid "Feeds server: Entries"
|
msgid "Feeds server: Entries"
|
||||||
msgstr "Serveur de flux : Billets"
|
msgstr "Serveur de flux : Billets"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:103
|
||||||
|
msgid "Feed server"
|
||||||
|
msgstr "Serveur de flux"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:117
|
||||||
msgid "feeds per page"
|
msgid "feeds per page"
|
||||||
msgstr "flux par page"
|
msgstr "flux par page"
|
||||||
|
|
||||||
msgid "entries per page"
|
#: src/BackendBehaviors.php:149
|
||||||
msgstr "billets par page"
|
msgid "edit feed"
|
||||||
|
msgstr "Modifier le flux"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:225
|
||||||
msgid "Edit this feed"
|
msgid "Edit this feed"
|
||||||
msgstr "Modifier ce flux"
|
msgstr "Modifier ce flux"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:231
|
||||||
msgid "Feed source"
|
msgid "Feed source"
|
||||||
msgstr "Source du flux"
|
msgstr "Source du flux"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:238
|
||||||
msgid "feed URL"
|
msgid "feed URL"
|
||||||
msgstr "URL du fil"
|
msgstr "URL du fil"
|
||||||
|
|
||||||
|
#: src/BackendBehaviors.php:242
|
||||||
msgid "site URL"
|
msgid "site URL"
|
||||||
msgstr "URL du site"
|
msgstr "URL du site"
|
||||||
|
|
||||||
|
#: src/Combo.php:35
|
||||||
|
msgid "Update date"
|
||||||
|
msgstr "Date de mise à jour"
|
||||||
|
|
||||||
|
#: src/Combo.php:60
|
||||||
|
msgid "Disabled"
|
||||||
|
msgstr "Désactivé"
|
||||||
|
|
||||||
|
#: src/Combo.php:61
|
||||||
|
msgid "Enabled"
|
||||||
|
msgstr "Activé"
|
||||||
|
|
||||||
|
#: src/Combo.php:82
|
||||||
|
msgid "Every hour"
|
||||||
|
msgstr "Toutes les heures"
|
||||||
|
|
||||||
|
#: src/Combo.php:83
|
||||||
|
msgid "Every two hours"
|
||||||
|
msgstr "Toutes les deux heures"
|
||||||
|
|
||||||
|
#: src/Combo.php:84
|
||||||
|
msgid "Two times per day"
|
||||||
|
msgstr "Deux fois par jour"
|
||||||
|
|
||||||
|
#: src/Combo.php:85
|
||||||
|
msgid "Every day"
|
||||||
|
msgstr "Chaque jour"
|
||||||
|
|
||||||
|
#: src/Combo.php:86
|
||||||
|
msgid "Every two days"
|
||||||
|
msgstr "Tous les deux jours"
|
||||||
|
|
||||||
|
#: src/Combo.php:97
|
||||||
|
msgid "Keep source case"
|
||||||
|
msgstr "Garder la casse de la source"
|
||||||
|
|
||||||
|
#: src/Combo.php:98
|
||||||
|
msgid "First upper case"
|
||||||
|
msgstr "Premier caractère en majuscule"
|
||||||
|
|
||||||
|
#: src/Combo.php:99
|
||||||
|
msgid "All lower case"
|
||||||
|
msgstr "Tout en minuscule"
|
||||||
|
|
||||||
|
#: src/Combo.php:100
|
||||||
|
msgid "All upper case"
|
||||||
|
msgstr "Tout en majuscule"
|
||||||
|
|
||||||
|
#: src/Combo.php:110
|
||||||
|
msgid "Disable"
|
||||||
|
msgstr "Désactiver"
|
||||||
|
|
||||||
|
#: src/Combo.php:111
|
||||||
|
msgid "Before display"
|
||||||
|
msgstr "Avant l'affichage"
|
||||||
|
|
||||||
|
#: src/Combo.php:112
|
||||||
|
msgid "After display"
|
||||||
|
msgstr "Après l'affichage"
|
||||||
|
|
||||||
|
#: src/Combo.php:113
|
||||||
|
msgid "Through Ajax"
|
||||||
|
msgstr "À travers Ajax"
|
||||||
|
|
||||||
|
#: src/Config.php:69
|
||||||
|
msgid "Configuration has been successfully updated."
|
||||||
|
msgstr "La configuration a été mise à jour avec succés."
|
||||||
|
|
||||||
|
#: src/Config.php:101
|
||||||
|
msgid "Dotclear cache is not writable or not well configured!"
|
||||||
|
msgstr "Le cache de Dotclear n'est pas accessible en écriture ou n'est pas configuré !"
|
||||||
|
|
||||||
|
#: src/Config.php:108
|
||||||
|
msgid "View the public list of feeds"
|
||||||
|
msgstr "Voir la page publique de la liste des flux"
|
||||||
|
|
||||||
|
#: src/Config.php:146
|
||||||
|
msgid "Enable plugin"
|
||||||
|
msgstr "Activer le plugin"
|
||||||
|
|
||||||
|
#: src/Config.php:158
|
||||||
|
msgid "Status of new posts:"
|
||||||
|
msgstr "Status des nouveaux billets :"
|
||||||
|
|
||||||
|
#: src/Config.php:166
|
||||||
|
msgid "Owner of entries created by the feed server:"
|
||||||
|
msgstr "Propriétaire des billets créés par le serveur de flux :"
|
||||||
|
|
||||||
|
#: src/Config.php:174
|
||||||
|
msgid "How to transform imported tags:"
|
||||||
|
msgstr "Comment tranformer la casse des mots-clés importés :"
|
||||||
|
|
||||||
|
#: src/Config.php:186
|
||||||
|
msgid "Update feeds on public side:"
|
||||||
|
msgstr "Mettre à jour les flux depuis la partie publique :"
|
||||||
|
|
||||||
|
#: src/Config.php:194
|
||||||
|
msgid "Number of feeds to update at one time:"
|
||||||
|
msgstr "Nombre de flux mis à jour à la fois :"
|
||||||
|
|
||||||
|
#: src/Config.php:205
|
||||||
|
msgid "Keep active empty feeds"
|
||||||
|
msgstr "Garder actif les flux vides"
|
||||||
|
|
||||||
|
#: src/Config.php:213
|
||||||
|
msgid "Enable public page"
|
||||||
|
msgstr "Activer la page publique"
|
||||||
|
|
||||||
|
#: src/Config.php:225
|
||||||
|
msgid "Redirect to original post on:"
|
||||||
|
msgstr "Rediriger vers le billet original sur :"
|
||||||
|
|
||||||
|
#: src/Config.php:232
|
||||||
|
msgid "Show full content on:"
|
||||||
|
msgstr "Afficher le contenu complet sur :"
|
||||||
|
|
||||||
|
#: src/FeedsActions.php:46
|
||||||
|
msgid "Feeds"
|
||||||
|
msgstr "Flux de syndication"
|
||||||
|
|
||||||
|
#: src/FeedsActions.php:61
|
||||||
|
#: src/FeedsDefaultActions.php:271
|
||||||
|
msgid "Feeds server"
|
||||||
|
msgstr "Serveur de flux"
|
||||||
|
|
||||||
|
#: src/FeedsActions.php:67
|
||||||
|
msgid "Back to feeds list"
|
||||||
|
msgstr "Retour à la liste des flux"
|
||||||
|
|
||||||
|
#: src/FeedsActions.php:82
|
||||||
|
msgid "Feeds actions"
|
||||||
|
msgstr "Actions sur les flux"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:49
|
||||||
msgid "Change update interval"
|
msgid "Change update interval"
|
||||||
msgstr "Changer l'interval de mise à jour"
|
msgstr "Changer l'interval de mise à jour"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:53
|
||||||
msgid "Disable feed update"
|
msgid "Disable feed update"
|
||||||
msgstr "Désactiver la mise à jour du flux"
|
msgstr "Désactiver la mise à jour du flux"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:57
|
||||||
msgid "Enable feed update"
|
msgid "Enable feed update"
|
||||||
msgstr "Activer la mise à jour du flux"
|
msgstr "Activer la mise à jour du flux"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:61
|
||||||
msgid "Reset last update"
|
msgid "Reset last update"
|
||||||
msgstr "Remettre à zéro le chronomètre de mise à jour"
|
msgstr "Remettre à zéro le chronomètre de mise à jour"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:65
|
||||||
msgid "Update (check) feed"
|
msgid "Update (check) feed"
|
||||||
msgstr "Mettre à jour (vérifier) le flux"
|
msgstr "Mettre à jour (vérifier) le flux"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:69
|
||||||
msgid "Delete related posts"
|
msgid "Delete related posts"
|
||||||
msgstr "Effacer les billets liés"
|
msgstr "Effacer les billets liés"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:73
|
||||||
msgid "Delete feed (without related posts)"
|
msgid "Delete feed (without related posts)"
|
||||||
msgstr "Effacer le flux (sans effacer les billets liés)"
|
msgstr "Effacer le flux (sans effacer les billets liés)"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:87
|
||||||
msgid "No feeds selected"
|
msgid "No feeds selected"
|
||||||
msgstr "Aucun flux selectionné"
|
msgstr "Aucun flux selectionné"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:154
|
||||||
msgid "Entries have been successfully deleted."
|
msgid "Entries have been successfully deleted."
|
||||||
msgstr "Les billets ont été effacé avec succès."
|
msgstr "Les billets ont été effacé avec succès."
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:205
|
||||||
msgid "%d feed has been successfully updated."
|
msgid "%d feed has been successfully updated."
|
||||||
msgid_plural "%d feeds have been successfully updated."
|
msgid_plural "%d feeds have been successfully updated."
|
||||||
msgstr[0] "%s flux a été mis à jour."
|
msgstr[0] "%s flux a été mis à jour."
|
||||||
msgstr[1] "%s flux ont été mis à jour."
|
msgstr[1] "%s flux ont été mis à jour."
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:233
|
||||||
msgid "Last update of %s feed successfully reseted."
|
msgid "Last update of %s feed successfully reseted."
|
||||||
msgid_plural "Last update of %s feeds successfully reseted."
|
msgid_plural "Last update of %s feeds successfully reseted."
|
||||||
msgstr[0] "La date de dernière mise à jour de %s flux a été remis à zéro."
|
msgstr[0] "La date de dernière mise à jour de %s flux a été remis à zéro."
|
||||||
msgstr[1] "Les date de dernière mise à jour de %s flux ont été remis à zéro."
|
msgstr[1] "Les date de dernière mise à jour de %s flux ont été remis à zéro."
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:263
|
||||||
msgid "Category of %s feed successfully changed."
|
msgid "Category of %s feed successfully changed."
|
||||||
msgid_plural "Category of %s feeds successfully changed."
|
msgid_plural "Category of %s feeds successfully changed."
|
||||||
msgstr[0] "La catégorie de %s flux a été changé."
|
msgstr[0] "La catégorie de %s flux a été changé."
|
||||||
msgstr[1] "Les catégories de %s flux ont été changé."
|
msgstr[1] "Les catégories de %s flux ont été changé."
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:329
|
||||||
msgid "Update frequency of %s feed successfully changed."
|
msgid "Update frequency of %s feed successfully changed."
|
||||||
msgid_plural "Update frequency of %s feeds successfully changed."
|
msgid_plural "Update frequency of %s feeds successfully changed."
|
||||||
msgstr[0] "La fréquence de mise à jour de %s flux a été changé."
|
msgstr[0] "La fréquence de mise à jour de %s flux a été changé."
|
||||||
msgstr[1] "Les fréquences de mise à jour de %s flux ont été changé."
|
msgstr[1] "Les fréquences de mise à jour de %s flux ont été changé."
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:340
|
||||||
msgid "Change update frequency for this selection"
|
msgid "Change update frequency for this selection"
|
||||||
msgstr "Changer la fréquence de mise à jour pour la selection"
|
msgstr "Changer la fréquence de mise à jour pour la selection"
|
||||||
|
|
||||||
|
#: src/FeedsDefaultActions.php:355
|
||||||
msgid "Frequency:"
|
msgid "Frequency:"
|
||||||
msgstr "Fréquence :"
|
msgstr "Fréquence :"
|
||||||
|
|
||||||
msgid "No entries matches the filter"
|
#: src/FeedsList.php:44
|
||||||
msgstr "Aucun billet correspondant au filtre."
|
|
||||||
|
|
||||||
msgid "No entries"
|
|
||||||
msgstr "Aucun billet"
|
|
||||||
|
|
||||||
msgid "Feeds"
|
|
||||||
msgstr "Flux de syndication"
|
|
||||||
|
|
||||||
msgid "Back to feeds list"
|
|
||||||
msgstr "Retour à la liste des flux"
|
|
||||||
|
|
||||||
msgid "Feeds actions"
|
|
||||||
msgstr "Actions sur les flux"
|
|
||||||
|
|
||||||
msgid "No feeds matches the filter"
|
msgid "No feeds matches the filter"
|
||||||
msgstr "Aucun flux correspondant au filtre."
|
msgstr "Aucun flux correspondant au filtre."
|
||||||
|
|
||||||
|
#: src/FeedsList.php:45
|
||||||
msgid "No feeds"
|
msgid "No feeds"
|
||||||
msgstr "Aucun flux"
|
msgstr "Aucun flux"
|
||||||
|
|
||||||
|
#: src/FeedsList.php:93
|
||||||
msgid "List of %s feeds matching the filter."
|
msgid "List of %s feeds matching the filter."
|
||||||
msgstr "Liste des %s flux correspondant au filtre."
|
msgstr "Liste des %s flux correspondant au filtre."
|
||||||
|
|
||||||
msgid "List of feeds (%s)"
|
#: src/FeedsList.php:94
|
||||||
msgstr "Liste des flux (%s)"
|
msgid "List of feeds. (%s)"
|
||||||
|
msgstr "Liste des flux. (%s)"
|
||||||
|
|
||||||
|
#: src/FeedsList.php:110
|
||||||
|
msgid "enabled"
|
||||||
|
msgstr "activé"
|
||||||
|
|
||||||
|
#: src/FeedsList.php:110
|
||||||
|
msgid "disabled"
|
||||||
|
msgstr "désactivé"
|
||||||
|
|
||||||
|
#: src/FeedsList.php:161
|
||||||
msgid "never"
|
msgid "never"
|
||||||
msgstr "jamais"
|
msgstr "jamais"
|
||||||
|
|
||||||
|
#: src/FeedsList.php:169
|
||||||
msgid "View entries"
|
msgid "View entries"
|
||||||
msgstr "Voir les billets"
|
msgstr "Voir les billets"
|
||||||
|
|
||||||
msgid "Original post on <a href=\"%s\">%s</a>"
|
#: src/Manage.php:68
|
||||||
msgstr "Billet original sur <a href=\"%s\">%s</a>"
|
msgid "Module is not wel configured"
|
||||||
|
msgstr "Le module n'est pas configuré correctement"
|
||||||
|
|
||||||
msgid "Read more details about this feed"
|
#: src/Manage.php:157
|
||||||
msgstr "Lire plus de détails à propos de ce flux"
|
msgid "Feeds list"
|
||||||
|
msgstr "Liste de flux"
|
||||||
msgid "Disabled"
|
|
||||||
msgstr "Désactivé"
|
|
||||||
|
|
||||||
msgid "Enabled"
|
|
||||||
msgstr "Activé"
|
|
||||||
|
|
||||||
msgid "Every hour"
|
|
||||||
msgstr "Toutes les heures"
|
|
||||||
|
|
||||||
msgid "Every two hours"
|
|
||||||
msgstr "Toutes les deux heures"
|
|
||||||
|
|
||||||
msgid "Two times per day"
|
|
||||||
msgstr "Deux fois par jour"
|
|
||||||
|
|
||||||
msgid "Every day"
|
|
||||||
msgstr "Chaque jour"
|
|
||||||
|
|
||||||
msgid "Every two days"
|
|
||||||
msgstr "Tous les deux jours"
|
|
||||||
|
|
||||||
msgid "Entries pages"
|
|
||||||
msgstr "Pages des billets"
|
|
||||||
|
|
||||||
msgid "Tags pages"
|
|
||||||
msgstr "Pages des mots-clés"
|
|
||||||
|
|
||||||
msgid "Archives pages"
|
|
||||||
msgstr "Pages des archives"
|
|
||||||
|
|
||||||
msgid "Category pages"
|
|
||||||
msgstr "Pages de catégories"
|
|
||||||
|
|
||||||
msgid "This feed does not exist."
|
|
||||||
msgstr "Ce flux n'existe pas."
|
|
||||||
|
|
||||||
msgid "next feed"
|
|
||||||
msgstr "flux suivant"
|
|
||||||
|
|
||||||
msgid "previous feed"
|
|
||||||
msgstr "flux précédent"
|
|
||||||
|
|
||||||
msgid "Record with same feed URL already exists."
|
|
||||||
msgstr "Un enregistrement avec la même URL de flux existe déjà."
|
|
||||||
|
|
||||||
msgid "You must provide a name."
|
|
||||||
msgstr "Vous devez indiquer un nom."
|
|
||||||
|
|
||||||
msgid "You must provide an owner."
|
|
||||||
msgstr "Vous devez indiquer un propriétaire."
|
|
||||||
|
|
||||||
msgid "You must provide valid site URL."
|
|
||||||
msgstr "Vous devez donner une URL de site valide."
|
|
||||||
|
|
||||||
msgid "You must provide valid feed URL."
|
|
||||||
msgstr "Vous devez donner une URL de flux valide."
|
|
||||||
|
|
||||||
msgid "You must provide valid category."
|
|
||||||
msgstr "Vous devez donner une catégorie valide."
|
|
||||||
|
|
||||||
msgid "Feed successfully updated."
|
|
||||||
msgstr "Flux mis à jour avec succès."
|
|
||||||
|
|
||||||
msgid "Feed successfully created."
|
|
||||||
msgstr "Flux créé avec succcès."
|
|
||||||
|
|
||||||
msgid "Edit feed"
|
|
||||||
msgstr "Edition de flux"
|
|
||||||
|
|
||||||
|
#: src/Manage.php:167
|
||||||
|
#: src/ManageFeed.php:212
|
||||||
msgid "New feed"
|
msgid "New feed"
|
||||||
msgstr "Nouveau flux"
|
msgstr "Nouveau flux"
|
||||||
|
|
||||||
|
#: src/Manage.php:195
|
||||||
|
msgid "Selected feeds action:"
|
||||||
|
msgstr "Action sur les flux sélectionnés :"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:78
|
||||||
|
msgid "Record with same feed URL already exists."
|
||||||
|
msgstr "Un enregistrement avec la même URL de flux existe déjà."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:81
|
||||||
|
msgid "You must provide a name."
|
||||||
|
msgstr "Vous devez indiquer un nom."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:84
|
||||||
|
msgid "You must provide an owner."
|
||||||
|
msgstr "Vous devez indiquer un propriétaire."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:87
|
||||||
|
msgid "You must provide valid site URL."
|
||||||
|
msgstr "Vous devez donner une URL de site valide."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:90
|
||||||
|
msgid "You must provide valid feed URL."
|
||||||
|
msgstr "Vous devez donner une URL de flux valide."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:93
|
||||||
|
msgid "You must provide valid category."
|
||||||
|
msgstr "Vous devez donner une catégorie valide."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:105
|
||||||
|
msgid "Failed to save feed."
|
||||||
|
msgstr "Impossible de sauvegarder le flux."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:109
|
||||||
|
msgid "Feed successfully created."
|
||||||
|
msgstr "Flux créé avec succcès."
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:212
|
||||||
|
msgid "Edit feed"
|
||||||
|
msgstr "Edition de flux"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:215
|
||||||
msgid "Edit feed \"%s\""
|
msgid "Edit feed \"%s\""
|
||||||
msgstr "Modifier le flux \"%s\""
|
msgstr "Modifier le flux \"%s\""
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:248
|
||||||
msgid "Feed information"
|
msgid "Feed information"
|
||||||
msgstr "Information sur le flux"
|
msgstr "Information sur le flux"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:264
|
||||||
msgid "Owner:"
|
msgid "Owner:"
|
||||||
msgstr "Propriétaire :"
|
msgstr "Propriétaire :"
|
||||||
|
|
||||||
msgid "Tweeter or Identica ident:"
|
#: src/ManageFeed.php:276
|
||||||
msgstr "Identifiant Twiiter ou Identi.ca :"
|
|
||||||
|
|
||||||
msgid "Site URL:"
|
msgid "Site URL:"
|
||||||
msgstr "URL du site :"
|
msgstr "URL du site :"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:322
|
||||||
|
msgid "Tweeter or Identica ident:"
|
||||||
|
msgstr "Identifiant Twiiter ou Identi.ca :"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:334
|
||||||
msgid "Local settings"
|
msgid "Local settings"
|
||||||
msgstr "Paramètres locaux"
|
msgstr "Paramètres locaux"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:358
|
||||||
msgid "Update:"
|
msgid "Update:"
|
||||||
msgstr "Mise à jour :"
|
msgstr "Mise à jour :"
|
||||||
|
|
||||||
|
#: src/ManageFeed.php:379
|
||||||
msgid "Import tags from feed"
|
msgid "Import tags from feed"
|
||||||
msgstr "Importer les tags depuis le flux"
|
msgstr "Importer les tags depuis le flux"
|
||||||
|
|
||||||
msgid "Selected feeds action:"
|
#: src/ManageFeedVars.php:85
|
||||||
msgstr "Action sur les flux sélectionnés :"
|
msgid "This feed does not exist."
|
||||||
|
msgstr "Ce flux n'existe pas."
|
||||||
|
|
||||||
|
#: src/ManageFeedVars.php:115
|
||||||
|
msgid "next feed"
|
||||||
|
msgstr "flux suivant"
|
||||||
|
|
||||||
|
#: src/ManageFeedVars.php:137
|
||||||
|
msgid "previous feed"
|
||||||
|
msgstr "flux précédent"
|
||||||
|
|
||||||
|
#: src/PostsList.php:43
|
||||||
|
msgid "No entries matches the filter"
|
||||||
|
msgstr "Aucun billet correspondant au filtre."
|
||||||
|
|
||||||
|
#: src/PostsList.php:44
|
||||||
|
msgid "No entries"
|
||||||
|
msgstr "Aucun billet"
|
||||||
|
|
||||||
|
#: src/PostsList.php:92
|
||||||
|
msgid "List of entries. (%s)"
|
||||||
|
msgstr "Liste des billets. (%s)"
|
||||||
|
|
||||||
|
#: src/RsExtPosts.php:146
|
||||||
|
msgid "Original post on <a href=\"%s\">%s</a>"
|
||||||
|
msgstr "Billet original sur <a href=\"%s\">%s</a>"
|
||||||
|
|
||||||
|
#: src/RsExtPosts.php:157
|
||||||
|
msgid "Read more details about this feed"
|
||||||
|
msgstr "Lire plus de détails à propos de ce flux"
|
||||||
|
|
||||||
|
#: src/Widgets.php:38
|
||||||
|
msgid "Feeds server: sources"
|
||||||
|
msgstr "Serveur de flux : les sources"
|
||||||
|
|
||||||
|
#: src/Widgets.php:41
|
||||||
|
msgid "List sources of feeds"
|
||||||
|
msgstr "Liste des sources du flux"
|
||||||
|
|
||||||
|
#: src/Widgets.php:44
|
||||||
|
msgid "Feeds sources"
|
||||||
|
msgstr "Sources des flux"
|
||||||
|
|
||||||
|
#: src/Widgets.php:54
|
||||||
|
msgid "Create date"
|
||||||
|
msgstr "Date de création"
|
||||||
|
|
||||||
|
#: src/Widgets.php:69
|
||||||
|
msgid "Limit:"
|
||||||
|
msgstr "Limite :"
|
||||||
|
|
||||||
|
#: src/Widgets.php:75
|
||||||
|
msgid "Link to the list of sources:"
|
||||||
|
msgstr "Lien vers la liste des sources :"
|
||||||
|
|
||||||
|
#: src/Widgets.php:76
|
||||||
|
msgid "All sources"
|
||||||
|
msgstr "Toutes les sources"
|
||||||
|
|
||||||
|
#: src/Widgets.php:87
|
||||||
|
msgid "Feeds server: numbers"
|
||||||
|
msgstr "Serveur de flux : les chiffres"
|
||||||
|
|
||||||
|
#: src/Widgets.php:90
|
||||||
|
msgid "Show some numbers about feeds"
|
||||||
|
msgstr "Afficher quelques chiffres à propose du flux"
|
||||||
|
|
||||||
|
#: src/Widgets.php:93
|
||||||
|
msgid "Feeds numbers"
|
||||||
|
msgstr "Le flux en chiffres"
|
||||||
|
|
||||||
|
#: src/Widgets.php:103
|
||||||
|
msgid "Show feeds count"
|
||||||
|
msgstr "Afficher le nombre de flux"
|
||||||
|
|
||||||
|
#: src/Widgets.php:109
|
||||||
|
msgid "Title for feeds count:"
|
||||||
|
msgstr "Titre pour le nombre de flux :"
|
||||||
|
|
||||||
|
#: src/Widgets.php:110
|
||||||
|
msgid "Feeds:"
|
||||||
|
msgstr "Flux :"
|
||||||
|
|
||||||
|
#: src/Widgets.php:115
|
||||||
|
msgid "Show entries count"
|
||||||
|
msgstr "Afficher le nombre de billets"
|
||||||
|
|
||||||
|
#: src/Widgets.php:121
|
||||||
|
msgid "Title for entries count:"
|
||||||
|
msgstr "Titre pour le nombre de billets :"
|
||||||
|
|
||||||
|
#: src/Widgets.php:122
|
||||||
|
msgid "Entries:"
|
||||||
|
msgstr "Billets :"
|
||||||
|
|
||||||
|
#: src/Widgets.php:219
|
||||||
|
msgid "one source"
|
||||||
|
msgstr "une source"
|
||||||
|
|
||||||
|
#: src/Widgets.php:219
|
||||||
|
msgid "no sources"
|
||||||
|
msgstr "aucune source"
|
||||||
|
|
||||||
|
#: src/Widgets.php:250
|
||||||
|
msgid "one entry"
|
||||||
|
msgstr "une publication"
|
||||||
|
|
||||||
|
#: src/Widgets.php:250
|
||||||
|
msgid "no entries"
|
||||||
|
msgstr "aucune publication"
|
||||||
|
|
||||||
|
#: src/ZoneclearFeedServer.php:964
|
||||||
|
msgid "Entries pages"
|
||||||
|
msgstr "Pages des billets"
|
||||||
|
|
||||||
|
#: src/ZoneclearFeedServer.php:965
|
||||||
|
msgid "Tags pages"
|
||||||
|
msgstr "Pages des mots-clés"
|
||||||
|
|
||||||
|
#: src/ZoneclearFeedServer.php:966
|
||||||
|
msgid "Archives pages"
|
||||||
|
msgstr "Pages des archives"
|
||||||
|
|
||||||
|
#: src/ZoneclearFeedServer.php:967
|
||||||
|
msgid "Category pages"
|
||||||
|
msgstr "Pages de catégories"
|
||||||
|
|
||||||
msgid "Mix your blog with a feeds planet"
|
msgid "Mix your blog with a feeds planet"
|
||||||
msgstr "Mixer votre blog avec un planet"
|
msgstr "Mixer votre blog avec un planet"
|
||||||
|
|
|
@ -10,138 +10,137 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
class zcfsActivityReportBehaviors
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Database\Cursor;
|
||||||
|
use Dotclear\Plugin\activityReport\{
|
||||||
|
Action,
|
||||||
|
ActivityReport,
|
||||||
|
Group
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feeds actions to the plugin activity report.
|
||||||
|
*/
|
||||||
|
class ActivityReportActions
|
||||||
{
|
{
|
||||||
public static function init()
|
public static function init(): void
|
||||||
{
|
{
|
||||||
# This file is used with plugin activityReport
|
$group = new Group(My::id(), My::name());
|
||||||
dcCore::app()->activityReport->addGroup(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
__('Plugin zoneclearFeedServer')
|
|
||||||
);
|
|
||||||
|
|
||||||
# from BEHAVIOR zoneclearFeedServerAfterAddFeed in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
|
$group->add(new Action(
|
||||||
dcCore::app()->activityReport->addAction(
|
'updateFeed',
|
||||||
'zoneclearFeedServer',
|
__('Feed properties update'),
|
||||||
'create',
|
__('Feed named "%s" point to "%s" has been updated by "%s"'),
|
||||||
__('feed creation'),
|
'zoneclearFeedServerAfterUpdateFeed',
|
||||||
|
function (Cursor $cur, int $id): void {
|
||||||
|
$user = dcCore::app()->auth?->getInfo('user_cn');
|
||||||
|
if (!is_string($user)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rs = ZoneclearFeedServer::instance()->getFeeds(['feed_id' => $id]);
|
||||||
|
if ($rs->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$row = new FeedRow($rs);
|
||||||
|
|
||||||
|
$logs = [
|
||||||
|
$row->name,
|
||||||
|
$row->feed,
|
||||||
|
$user,
|
||||||
|
];
|
||||||
|
|
||||||
|
ActivityReport::instance()->addLog(My::id(), 'updateFeed', $logs);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
$group->add(new Action(
|
||||||
|
'addFeed',
|
||||||
|
__('Feed creation'),
|
||||||
__('A new feed named "%s" point to "%s" was added by "%s"'),
|
__('A new feed named "%s" point to "%s" was added by "%s"'),
|
||||||
'zoneclearFeedServerAfterAddFeed',
|
'zoneclearFeedServerAfterAddFeed',
|
||||||
function ($cur) {
|
function (Cursor $cur, int $id): void {
|
||||||
|
$user = dcCore::app()->auth?->getInfo('user_cn');
|
||||||
|
if (!is_string($user)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$logs = [
|
$logs = [
|
||||||
$cur->feed_name,
|
$cur->getField('feed_name'),
|
||||||
$cur->feed_feed,
|
$cur->getField('feed_feed'),
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
$user,
|
||||||
];
|
];
|
||||||
|
|
||||||
dcCore::app()->activityReport->addLog(
|
ActivityReport::instance()->addLog(My::id(), 'addFeed', $logs);
|
||||||
'zoneclearFeedServer',
|
|
||||||
'create',
|
|
||||||
$logs
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
# from BEHAVIOR zoneclearFeedServerAfterUpdFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
|
|
||||||
dcCore::app()->activityReport->addAction(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'updatefeedinfo',
|
|
||||||
__('updating feed info'),
|
|
||||||
__('Feed named "%s" point to "%s" has been updated by "%s"'),
|
|
||||||
'zoneclearFeedServerAfterUpdFeed',
|
|
||||||
function ($cur, $id) {
|
|
||||||
if (defined('DC_CONTEXT_ADMIN')) {
|
|
||||||
$zc = new zoneclearFeedServer();
|
|
||||||
$rs = $zc->getFeeds(['feed_id' => $id]);
|
|
||||||
|
|
||||||
$logs = [
|
$group->add(new Action(
|
||||||
$rs->feed_name,
|
'enableFeed',
|
||||||
$rs->feed_feed,
|
__('Feed status'),
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
|
||||||
];
|
|
||||||
|
|
||||||
dcCore::app()->activityReport->addLog(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'updatefeedinfo',
|
|
||||||
$logs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
# from BEHAVIOR zoneclearFeedServerAfterUpdFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
|
|
||||||
dcCore::app()->activityReport->addAction(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'updatefeedrecords',
|
|
||||||
__('updating feed records'),
|
|
||||||
__('Records of the feed named "%s" have been updated automatically'),
|
|
||||||
'zoneclearFeedServerAfterUpdFeed',
|
|
||||||
function ($cur, $id) {
|
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
|
||||||
$zc = new zoneclearFeedServer();
|
|
||||||
$rs = $zc->getFeeds(['feed_id' => $id]);
|
|
||||||
|
|
||||||
$logs = [
|
|
||||||
$rs->feed_name,
|
|
||||||
];
|
|
||||||
|
|
||||||
dcCore::app()->activityReport->addLog(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'updatefeedrecords',
|
|
||||||
$logs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
# from BEHAVIOR zoneclearFeedServerAfterDelFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
|
|
||||||
dcCore::app()->activityReport->addAction(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'delete',
|
|
||||||
__('feed deletion'),
|
|
||||||
__('Feed named "%s" point to "%s" has been deleted by "%s"'),
|
|
||||||
'zoneclearFeedServerAfterDelFeed',
|
|
||||||
function ($id) {
|
|
||||||
$zc = new zoneclearFeedServer();
|
|
||||||
$rs = $zc->getFeeds(['feed_id' => $id]);
|
|
||||||
|
|
||||||
$logs = [
|
|
||||||
$rs->feed_name,
|
|
||||||
$rs->feed_feed,
|
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
|
||||||
];
|
|
||||||
|
|
||||||
dcCore::app()->activityReport->addLog(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'delete',
|
|
||||||
$logs
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
# from BEHAVIOR zoneclearFeedServerAfterEnableFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
|
|
||||||
dcCore::app()->activityReport->addAction(
|
|
||||||
'zoneclearFeedServer',
|
|
||||||
'status',
|
|
||||||
__('feed status'),
|
|
||||||
__('Feed named "%s" point to "%s" has been set to "%s"'),
|
__('Feed named "%s" point to "%s" has been set to "%s"'),
|
||||||
'zoneclearFeedServerAfterEnableFeed',
|
'zoneclearFeedServerAfterEnableFeed',
|
||||||
function ($id, $enable, $time) {
|
function (int $id, bool $enable, int $time): void {
|
||||||
$zc = new zoneclearFeedServer();
|
$rs = ZoneclearFeedServer::instance()->getFeeds(['feed_id' => $id]);
|
||||||
$rs = $zc->getFeeds(['feed_id' => $id]);
|
if ($rs->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$row = new FeedRow($rs);
|
||||||
|
|
||||||
$logs = [
|
$logs = [
|
||||||
$rs->feed_name,
|
$row->name,
|
||||||
$rs->feed_feed,
|
$row->feed,
|
||||||
$enable ? 'enable' : 'disable',
|
$enable ? 'enabled' : 'disabled',
|
||||||
];
|
];
|
||||||
|
|
||||||
dcCore::app()->activityReport->addLog(
|
ActivityReport::instance()->addLog(My::id(), 'enableFeed', $logs);
|
||||||
'zoneclearFeedServer',
|
|
||||||
'status',
|
|
||||||
$logs
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
|
|
||||||
|
$group->add(new Action(
|
||||||
|
'deleteFeed',
|
||||||
|
__('Feed deletion'),
|
||||||
|
__('Feed named "%s" point to "%s" has been deleted by "%s"'),
|
||||||
|
'zoneclearFeedServerBeforeDeleteFeed',
|
||||||
|
function (int $id): void {
|
||||||
|
$rs = ZoneclearFeedServer::instance()->getFeeds(['feed_id' => $id]);
|
||||||
|
if ($rs->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$row = new FeedRow($rs);
|
||||||
|
|
||||||
|
$user = dcCore::app()->auth?->getInfo('user_cn');
|
||||||
|
if (!is_string($user)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$logs = [
|
||||||
|
$row->name,
|
||||||
|
$row->feed,
|
||||||
|
$user,
|
||||||
|
];
|
||||||
|
|
||||||
|
ActivityReport::instance()->addLog(My::id(), 'deleteFeed', $logs);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
$group->add(new Action(
|
||||||
|
'checkFeedUpdate',
|
||||||
|
__('Check feed update'),
|
||||||
|
__('Feed named "%s" has been updated automatically'),
|
||||||
|
'zoneclearFeedServerAfterCheckFeedUpdate',
|
||||||
|
function (FeedRow $row): void {
|
||||||
|
$logs = [
|
||||||
|
$row->name,
|
||||||
|
];
|
||||||
|
|
||||||
|
ActivityReport::instance()->addLog(My::id(), 'checkFeedUpdate', $logs);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
ActivityReport::instance()->groups->add($group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
123
src/Backend.php
123
src/Backend.php
|
@ -10,46 +10,97 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->blog->settings->addNamespace(basename(__DIR__));
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
require_once __DIR__ . '/_widgets.php';
|
use dcAdmin;
|
||||||
|
use dcCore;
|
||||||
|
use dcPage;
|
||||||
|
use dcMenu;
|
||||||
|
use dcNsProcess;
|
||||||
|
|
||||||
$perm = dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
/**
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
* Backend prepend.
|
||||||
]), dcCore::app()->blog->id);
|
*/
|
||||||
|
class Backend extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant();
|
||||||
|
|
||||||
if (dcCore::app()->blog->settings->__get(basename(__DIR__))->active
|
return static::$init;
|
||||||
&& '' != dcCore::app()->blog->settings->__get(basename(__DIR__))->user
|
|
||||||
) {
|
|
||||||
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
|
||||||
__('Feeds server'),
|
|
||||||
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
|
|
||||||
dcPage::getPF(basename(__DIR__) . '/icon.svg'),
|
|
||||||
preg_match(
|
|
||||||
'/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/',
|
|
||||||
$_SERVER['REQUEST_URI']
|
|
||||||
),
|
|
||||||
$perm
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($perm) {
|
|
||||||
# Dashboard icon
|
|
||||||
dcCore::app()->addBehavior('adminDashboardFavoritesV2', ['zcfsAdminBehaviors', 'adminDashboardFavoritesV2']);
|
|
||||||
# User pref
|
|
||||||
dcCore::app()->addBehavior('adminColumnsListsV2', ['zcfsAdminBehaviors', 'adminColumnsListsV2']);
|
|
||||||
dcCore::app()->addBehavior('adminFiltersListsV2', ['zcfsAdminBehaviors', 'adminFiltersListsV2']);
|
|
||||||
# Add info about feed on post page sidebar
|
|
||||||
dcCore::app()->addBehavior('adminPostHeaders', ['zcfsAdminBehaviors', 'adminPostHeaders']);
|
|
||||||
dcCore::app()->addBehavior('adminPostFormItems', ['zcfsAdminBehaviors', 'adminPostFormItems']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Take care about tweakurls (thanks Mathieu M.)
|
public static function process(): bool
|
||||||
dcCore::app()->addbehavior('zcfsAfterPostCreate', ['zoneclearFeedServer', 'tweakurlsAfterPostCreate']);
|
{
|
||||||
}
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
# Delete related info about feed post in meta table
|
// behaviors that will be always loaded
|
||||||
dcCore::app()->addBehavior('adminBeforePostDelete', ['zcfsAdminBehaviors', 'adminBeforePostDelete']);
|
dcCore::app()->addBehaviors([
|
||||||
|
// Allways take care to delete related info about feed post in meta table
|
||||||
|
'adminBeforePostDelete' => function (int $post_id): void {
|
||||||
|
ZoneclearFeedServer::instance()::deletePostsMeta($post_id);
|
||||||
|
},
|
||||||
|
// widgets registration
|
||||||
|
'initWidgets' => [Widgets::class, 'init'],
|
||||||
|
// add Uninstaller cleaner for special direct action
|
||||||
|
'UninstallerCleanersConstruct' => [UninstallCleaner::class, 'init'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->auth)
|
||||||
|
|| is_null(dcCore::app()->blog)
|
||||||
|
|| is_null(dcCore::app()->adminurl)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not active
|
||||||
|
if (!dcCore::app()->blog->settings->get(My::id())->get('active')
|
||||||
|
|| '' == dcCore::app()->blog->settings->get(My::id())->get('user')
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get user perm
|
||||||
|
$has_perm = dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
]), dcCore::app()->blog->id);
|
||||||
|
|
||||||
|
// add sidebar menu icon
|
||||||
|
if ((dcCore::app()->menu[dcAdmin::MENU_PLUGINS] instanceof dcMenu)) {
|
||||||
|
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
||||||
|
My::name(),
|
||||||
|
dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||||
|
dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
|
preg_match(
|
||||||
|
'/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/',
|
||||||
|
$_SERVER['REQUEST_URI']
|
||||||
|
),
|
||||||
|
$has_perm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no perm
|
||||||
|
if (!$has_perm) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// behaviors that require user perm
|
||||||
|
dcCore::app()->addBehaviors([
|
||||||
|
'adminDashboardFavoritesV2' => [BackendBehaviors::class, 'adminDashboardFavoritesV2'],
|
||||||
|
'adminColumnsListsV2' => [BackendBehaviors::class, 'adminColumnsListsV2'],
|
||||||
|
'adminFiltersListsV2' => [BackendBehaviors::class, 'adminFiltersListsV2'],
|
||||||
|
'adminPostListHeaderV2' => [BackendBehaviors::class, 'adminPostListHeaderV2'],
|
||||||
|
'adminPostListValueV2' => [BackendBehaviors::class, 'adminPostListValueV2'],
|
||||||
|
'adminPostHeaders' => [BackendBehaviors::class, 'adminPostHeaders'],
|
||||||
|
'adminPostFormItems' => [BackendBehaviors::class, 'adminPostFormItems'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
248
src/BackendBehaviors.php
Normal file
248
src/BackendBehaviors.php
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcCore;
|
||||||
|
use dcPage;
|
||||||
|
use dcFavorites;
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Link,
|
||||||
|
Para,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend behaviors.
|
||||||
|
*/
|
||||||
|
class BackendBehaviors
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* User dashboard favorites icon.
|
||||||
|
*/
|
||||||
|
public static function adminDashboardFavoritesV2(dcFavorites $favs): void
|
||||||
|
{
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->adminurl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$favs->register(My::id(), [
|
||||||
|
'title' => My::name(),
|
||||||
|
'url' => dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||||
|
'small-icon' => dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
|
'large-icon' => dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
|
'permissions' => dcCore::app()->auth->makePermissions([
|
||||||
|
dcCore::app()->auth::PERMISSION_USAGE,
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
]),
|
||||||
|
// update user dashboard favorites icon with nb of updated feeds
|
||||||
|
'dashboard_cb' => function (ArrayObject $fav): void {
|
||||||
|
if (is_null(dcCore::app()->adminurl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = ZoneclearFeedServer::instance()->getFeeds(['feed_status' => '0'], true)->f(0);
|
||||||
|
if (!$count || !is_numeric($count)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fav['title'] .= '<br />' . sprintf(__('%s feed disabled', '%s feeds disabled', (int) $count), (int) $count);
|
||||||
|
$fav['large-icon'] = dcPage::getPF(My::id() . '/icon-update.svg');
|
||||||
|
$fav['url'] = dcCore::app()->adminurl->get(
|
||||||
|
'admin.plugin.' . My::id(),
|
||||||
|
['part' => 'feeds', 'sortby' => 'feed_status', 'order' => 'asc']
|
||||||
|
);
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists columns user preference.
|
||||||
|
*/
|
||||||
|
public static function adminColumnsListsV2(ArrayObject $cols): void
|
||||||
|
{
|
||||||
|
// feeds
|
||||||
|
$cols[My::id() . 'feeds'] = [
|
||||||
|
__('Feeds server: Feeds'),
|
||||||
|
[
|
||||||
|
'desc' => [true, __('Feed')],
|
||||||
|
'period' => [true, __('Frequency')],
|
||||||
|
'update' => [true, __('Last update')],
|
||||||
|
'entries' => [true, __('Entries')],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
// feed posts
|
||||||
|
$cols[My::id() . 'posts'] = [
|
||||||
|
__('Feeds server: Entries'),
|
||||||
|
[
|
||||||
|
'date' => [true, __('Date')],
|
||||||
|
'category' => [true, __('Category')],
|
||||||
|
'author' => [true, __('Author')],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
// posts feed
|
||||||
|
$cols['posts'][1]['feed'] = [true, __('Feed server')];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists filter.
|
||||||
|
*/
|
||||||
|
public static function adminFiltersListsV2(ArrayObject $sorts): void
|
||||||
|
{
|
||||||
|
// feeds
|
||||||
|
$sorts[My::id() . 'feeds'] = [
|
||||||
|
__('Feeds server: Feeds'),
|
||||||
|
Combo::feedsSortby(),
|
||||||
|
'lowername',
|
||||||
|
'asc',
|
||||||
|
[__('feeds per page'), 30],
|
||||||
|
];
|
||||||
|
// feed posts
|
||||||
|
$sorts[My::id() . 'posts'] = [
|
||||||
|
__('Feeds server: Entries'),
|
||||||
|
Combo::postsSortby(),
|
||||||
|
'post_dt',
|
||||||
|
'desc',
|
||||||
|
[__('entries per page'), 30],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add head column to posts list.
|
||||||
|
*/
|
||||||
|
public static function adminPostListHeaderV2(MetaRecord $rs, ArrayObject $cols): void
|
||||||
|
{
|
||||||
|
$cols['feed'] = '<th scope="col">' . __('Feed') . '</th>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add body column to posts list.
|
||||||
|
*/
|
||||||
|
public static function adminPostListValueV2(MetaRecord $rs, ArrayObject $cols): void
|
||||||
|
{
|
||||||
|
$rs_meta = dcCore::app()->meta->getMetadata(['post_id' => $rs->f('post_id'), 'meta_type' => My::META_PREFIX . 'id']);
|
||||||
|
if ($rs_meta->isEmpty()) {
|
||||||
|
$item = (new Text('', '-'));
|
||||||
|
} else {
|
||||||
|
$row = new FeedRow(ZoneclearFeedServer::instance()->getFeeds(['feed_id' => $rs_meta->f('meta_id')]));
|
||||||
|
$item = (new Link())
|
||||||
|
->href(dcCore::app()->adminurl?->get('admin.plugin.' . My::id(), ['part' => 'feed', 'feed_id' => $row->id]) . '#feed')
|
||||||
|
->title(__('edit feed'))
|
||||||
|
->text(Html::escapeHTML($row->name));
|
||||||
|
}
|
||||||
|
$cols['feed'] = (new Para(null, 'td'))->class('nowrap')->items([$item])->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add info about feed on post page sidebar.
|
||||||
|
*/
|
||||||
|
public static function adminPostHeaders(): string
|
||||||
|
{
|
||||||
|
return dcPage::jsModuleLoad(My::id() . '/js/post.js');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add info about feed on post page sidebar.
|
||||||
|
*/
|
||||||
|
public static function adminPostFormItems(ArrayObject $main_items, ArrayObject $sidebar_items, ?MetaRecord $post): void
|
||||||
|
{
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not feed on new post
|
||||||
|
if ($post === null || $post->f('post_type') != 'post') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = dcCore::app()->meta->getMetadata([
|
||||||
|
'post_id' => $post->f('post_id'),
|
||||||
|
'meta_type' => My::META_PREFIX . 'url',
|
||||||
|
'limit' => 1,
|
||||||
|
]);
|
||||||
|
$url = $url->isEmpty() ? '' : $url->f('meta_id');
|
||||||
|
if (!$url) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$author = dcCore::app()->meta->getMetadata([
|
||||||
|
'post_id' => $post->f('post_id'),
|
||||||
|
'meta_type' => My::META_PREFIX . 'author',
|
||||||
|
'limit' => 1,
|
||||||
|
]);
|
||||||
|
$author = $author->isEmpty() ? '' : $author->f('meta_id');
|
||||||
|
|
||||||
|
$site = dcCore::app()->meta->getMetadata([
|
||||||
|
'post_id' => $post->f('post_id'),
|
||||||
|
'meta_type' => My::META_PREFIX . 'site',
|
||||||
|
'limit' => 1,
|
||||||
|
]);
|
||||||
|
$site = $site->isEmpty() ? '' : $site->f('meta_id');
|
||||||
|
|
||||||
|
$sitename = dcCore::app()->meta->getMetadata([
|
||||||
|
'post_id' => $post->f('post_id'),
|
||||||
|
'meta_type' => My::META_PREFIX . 'sitename',
|
||||||
|
'limit' => 1,
|
||||||
|
]);
|
||||||
|
$sitename = $sitename->isEmpty() ? '' : $sitename->f('meta_id');
|
||||||
|
|
||||||
|
$edit = (new Text('', ''));
|
||||||
|
if (dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
]), dcCore::app()->blog->id)
|
||||||
|
) {
|
||||||
|
$fid = dcCore::app()->meta->getMetadata([
|
||||||
|
'post_id' => $post->f('post_id'),
|
||||||
|
'meta_type' => My::META_PREFIX . 'id',
|
||||||
|
'limit' => 1,
|
||||||
|
]);
|
||||||
|
if (!$fid->isEmpty()) {
|
||||||
|
$edit = (new Link())
|
||||||
|
->href(dcCore::app()->adminurl->get(
|
||||||
|
'admin.plugin.' . My::id(),
|
||||||
|
['part' => 'feed', 'feed_id' => $fid->f('meta_id')]
|
||||||
|
))
|
||||||
|
->text(__('Edit this feed'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sidebar_items['options-box']['items'][My::id()] = (new Div('zcfs'))
|
||||||
|
->items([
|
||||||
|
(new Text('h5', __('Feed source'))),
|
||||||
|
(new Para())
|
||||||
|
->separator('<br />')
|
||||||
|
->items([
|
||||||
|
(new Link())
|
||||||
|
->href($url)
|
||||||
|
->title($author . ' - ' . $url)
|
||||||
|
->text(__('feed URL')),
|
||||||
|
(new Link())
|
||||||
|
->href($site)
|
||||||
|
->title($sitename . ' - ' . $site)
|
||||||
|
->text(__('site URL')),
|
||||||
|
$edit,
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render();
|
||||||
|
}
|
||||||
|
}
|
143
src/Combo.php
Normal file
143
src/Combo.php
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various combo list.
|
||||||
|
*/
|
||||||
|
class Combo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public static function feedsSortby(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Date') => 'feed_upddt',
|
||||||
|
__('Name') => 'lowername',
|
||||||
|
__('Frequency') => 'feed_upd_int',
|
||||||
|
__('Update date') => 'feed_upd_last',
|
||||||
|
__('Status') => 'feed_status',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public static function postsSortby(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Date') => 'post_dt',
|
||||||
|
__('Title') => 'post_title',
|
||||||
|
__('Category') => 'cat_title',
|
||||||
|
__('Author') => 'user_id',
|
||||||
|
__('Status') => 'post_status',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public static function feedsStatus(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Disabled') => '0',
|
||||||
|
__('Enabled') => '1',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,int>
|
||||||
|
*/
|
||||||
|
public static function postsStatus(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Unpublished') => 0,
|
||||||
|
__('Published') => 1,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,int>
|
||||||
|
*/
|
||||||
|
public static function updateInterval(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Every hour') => 3600,
|
||||||
|
__('Every two hours') => 7200,
|
||||||
|
__('Two times per day') => 43200,
|
||||||
|
__('Every day') => 86400,
|
||||||
|
__('Every two days') => 172800,
|
||||||
|
__('Every week') => 604800,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,int>
|
||||||
|
*/
|
||||||
|
public static function tagCase(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Keep source case') => 0,
|
||||||
|
__('First upper case') => 1,
|
||||||
|
__('All lower case') => 2,
|
||||||
|
__('All upper case') => 3,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,int>
|
||||||
|
*/
|
||||||
|
public static function pubUpdate(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('Disable') => 0,
|
||||||
|
__('Before display') => 1,
|
||||||
|
__('After display') => 2,
|
||||||
|
__('Through Ajax') => 3,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string,string>
|
||||||
|
*/
|
||||||
|
public static function postCategories(): array
|
||||||
|
{
|
||||||
|
$combo = ['-' => ''];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$categories = dcCore::app()->blog?->getCategories(['post_type' => 'post']);
|
||||||
|
if (!is_null($categories)) {
|
||||||
|
while ($categories->fetch()) {
|
||||||
|
$level = is_numeric($categories->f('level')) ? (int) $categories->f('level') : 1;
|
||||||
|
$cat_title = is_string($categories->f('cat_title')) ? $categories->f('cat_title') : '';
|
||||||
|
$cat_id = is_numeric($categories->f('cat_id')) ? (string) $categories->f('cat_id') : '';
|
||||||
|
|
||||||
|
$combo[
|
||||||
|
str_repeat(' ', $level - 1) .
|
||||||
|
'• ' . Html::escapeHTML($cat_title)
|
||||||
|
] = $cat_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return $combo;
|
||||||
|
}
|
||||||
|
}
|
389
src/Config.php
389
src/Config.php
|
@ -10,188 +10,233 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_MODULE')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$redir = empty($_REQUEST['redir']) ? dcCore::app()->admin->list->getURL() . '#plugins' : $_REQUEST['redir'];
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
# -- Get settings --
|
use adminModulesList;
|
||||||
dcCore::app()->blog->settings->addNamespace(basename(__DIR__));
|
use dcCore;
|
||||||
$s = dcCore::app()->blog->settings->__get(basename(__DIR__));
|
use dcPage;
|
||||||
|
use dcNsProcess;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Link,
|
||||||
|
Number,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
$active = (bool) $s->active;
|
/**
|
||||||
$pub_active = (bool) $s->pub_active;
|
* Backend module configuration.
|
||||||
$post_status_new = (bool) $s->post_status_new;
|
*/
|
||||||
$bhv_pub_upd = (int) $s->bhv_pub_upd;
|
class Config extends dcNsProcess
|
||||||
$update_limit = (int) $s->update_limit;
|
{
|
||||||
$keep_empty_feed = (bool) $s->keep_empty_feed;
|
public static function init(): bool
|
||||||
$tag_case = (int) $s->tag_case;
|
{
|
||||||
$post_full_tpl = json_decode($s->post_full_tpl);
|
static::$init == defined('DC_CONTEXT_ADMIN')
|
||||||
$post_title_redir = json_decode($s->post_title_redir);
|
&& dcCore::app()->auth?->isSuperAdmin()
|
||||||
$feeduser = (string) $s->user;
|
&& My::phpCompliant();
|
||||||
|
|
||||||
if ($update_limit < 1) {
|
return static::$init;
|
||||||
$update_limit = 10;
|
|
||||||
}
|
|
||||||
if (!is_array($post_full_tpl)) {
|
|
||||||
$post_full_tpl = [];
|
|
||||||
}
|
|
||||||
if (!is_array($post_title_redir)) {
|
|
||||||
$post_title_redir = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$zc = new zoneclearFeedServer();
|
|
||||||
|
|
||||||
# -- Set settings --
|
|
||||||
if (!empty($_POST['save'])) {
|
|
||||||
try {
|
|
||||||
$active = !empty($_POST['active']);
|
|
||||||
$pub_active = !empty($_POST['pub_active']);
|
|
||||||
$post_status_new = !empty($_POST['post_status_new']);
|
|
||||||
$bhv_pub_upd = (int) $_POST['bhv_pub_upd'];
|
|
||||||
$limit = abs((int) $_POST['update_limit']);
|
|
||||||
$keep_empty_feed = !empty($_POST['keep_empty_feed']);
|
|
||||||
$tag_case = (int) $_POST['tag_case'];
|
|
||||||
$post_full_tpl = $_POST['post_full_tpl'];
|
|
||||||
$post_title_redir = $_POST['post_title_redir'];
|
|
||||||
$feeduser = (string) $_POST['feeduser'];
|
|
||||||
|
|
||||||
if ($limit < 1) {
|
|
||||||
$limit = 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$s->put('active', $active);
|
public static function process(): bool
|
||||||
$s->put('pub_active', $pub_active);
|
{
|
||||||
$s->put('post_status_new', $post_status_new);
|
if (!static::$init) {
|
||||||
$s->put('bhv_pub_upd', $bhv_pub_upd);
|
return false;
|
||||||
$s->put('update_limit', $limit);
|
}
|
||||||
$s->put('keep_empty_feed', $keep_empty_feed);
|
|
||||||
$s->put('tag_case', $tag_case);
|
|
||||||
$s->put('post_full_tpl', json_encode($post_full_tpl));
|
|
||||||
$s->put('post_title_redir', json_encode($post_title_redir));
|
|
||||||
$s->put('user', $feeduser);
|
|
||||||
|
|
||||||
dcCore::app()->blog->triggerBlog();
|
// no action
|
||||||
|
if (empty($_POST['save'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
// read settings
|
||||||
__('Configuration successfully updated.')
|
$s = ZoneclearFeedServer::instance()->settings;
|
||||||
);
|
|
||||||
dcCore::app()->adminurl->redirect(
|
// write settings
|
||||||
'admin.plugins',
|
try {
|
||||||
['module' => basename(__DIR__), 'conf' => 1, 'redir' => dcCore::app()->admin->list->getRedir()]
|
foreach ($s->dump() as $key => $value) {
|
||||||
|
$s->set($key, $_POST[$key] ?? $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::addSuccessNotice(
|
||||||
|
__('Configuration has been successfully updated.')
|
||||||
);
|
);
|
||||||
|
dcCore::app()->adminurl?->redirect('admin.plugins', [
|
||||||
|
'module' => My::id(),
|
||||||
|
'conf' => '1',
|
||||||
|
'redir' => !(dcCore::app()->admin->__get('list') instanceof adminModulesList) ? '' : dcCore::app()->admin->__get('list')->getRedir(),
|
||||||
|
]);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->blog)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$s = $z->settings;
|
||||||
|
|
||||||
|
$msg = [];
|
||||||
|
if (!is_writable(DC_TPL_CACHE)) {
|
||||||
|
$msg[] = (new Para())
|
||||||
|
->class('error')
|
||||||
|
->text(__('Dotclear cache is not writable or not well configured!'));
|
||||||
|
}
|
||||||
|
if ($s->pub_active) {
|
||||||
|
$msg[] = (new Para())
|
||||||
|
->items([
|
||||||
|
(new Link())
|
||||||
|
->class('onblog_link outgoing')
|
||||||
|
->text(__('View the public list of feeds') . ' <img alt="" src="images/outgoing-link.svg">')
|
||||||
|
->href(dcCore::app()->blog->url . dcCore::app()->url->getBase('zoneclearFeedsPage')),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$titles = [];
|
||||||
|
foreach ($z->getPublicUrlTypes() as $k => $v) {
|
||||||
|
$titles[] = (new Para(null, 'li'))
|
||||||
|
->items([
|
||||||
|
(new Checkbox(['post_title_redir[]', 'post_title_redir_' . $v], in_array($v, $s->post_title_redir)))
|
||||||
|
->value($v),
|
||||||
|
(new Label(__($k), Label::OUTSIDE_LABEL_AFTER))
|
||||||
|
->class('classic')
|
||||||
|
->for('post_title_redir_' . $v),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = [];
|
||||||
|
foreach ($z->getPublicUrlTypes() as $k => $v) {
|
||||||
|
$contents[] = (new Para(null, 'li'))
|
||||||
|
->items([
|
||||||
|
(new Checkbox(['post_full_tpl_[]', 'post_full_tpl_' . $v], in_array($v, $s->post_full_tpl)))
|
||||||
|
->value($v),
|
||||||
|
(new Label(__($k), Label::OUTSIDE_LABEL_AFTER))
|
||||||
|
->class('classic')
|
||||||
|
->for('post_full_tpl_' . $v),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
(new Div())
|
||||||
|
->items([
|
||||||
|
(new Div())
|
||||||
|
->items($msg),
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Checkbox('active', $s->active))
|
||||||
|
->value(1),
|
||||||
|
(new Label(__('Enable plugin'), Label::OUTSIDE_LABEL_AFTER))
|
||||||
|
->class('classic')
|
||||||
|
->for('active'),
|
||||||
|
]),
|
||||||
|
(new Div())
|
||||||
|
->class('clear two-cols')
|
||||||
|
->items([
|
||||||
|
(new Div())
|
||||||
|
->class('fieldset col')
|
||||||
|
->items([
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Status of new posts:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('post_status_new'),
|
||||||
|
(new Select('post_status_new'))
|
||||||
|
->items(Combo::postsStatus())
|
||||||
|
->default((string) $s->post_status_new),
|
||||||
|
]),
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Owner of entries created by the feed server:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('user'),
|
||||||
|
(new Select('user'))
|
||||||
|
->items($z->getAllBlogAdmins())
|
||||||
|
->default($s->user),
|
||||||
|
]),
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('How to transform imported tags:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('tag_case'),
|
||||||
|
(new Select('tag_case'))
|
||||||
|
->items(Combo::tagCase())
|
||||||
|
->default((string) $s->tag_case),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
(new Div())
|
||||||
|
->class('fieldset col')
|
||||||
|
->items([
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Update feeds on public side:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('bhv_pub_upd'),
|
||||||
|
(new Select('bhv_pub_upd'))
|
||||||
|
->items(Combo::pubUpdate())
|
||||||
|
->default((string) $s->bhv_pub_upd),
|
||||||
|
]),
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Number of feeds to update at one time:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('update_limit'),
|
||||||
|
(new Number('update_limit'))
|
||||||
|
->min(0)
|
||||||
|
->max(20)
|
||||||
|
->value($s->update_limit),
|
||||||
|
]),
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Checkbox('keep_empty_feed', $s->keep_empty_feed))
|
||||||
|
->value(1),
|
||||||
|
(new Label(__('Keep active empty feeds'), Label::OUTSIDE_LABEL_AFTER))
|
||||||
|
->class('classic')
|
||||||
|
->for('keep_empty_feed'),
|
||||||
|
]),
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Checkbox('pub_active', $s->pub_active))
|
||||||
|
->value(1),
|
||||||
|
(new Label(__('Enable public page'), Label::OUTSIDE_LABEL_AFTER))
|
||||||
|
->class('classic')
|
||||||
|
->for('pub_active'),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
(new Div())
|
||||||
|
->class('two-cols')
|
||||||
|
->items([
|
||||||
|
(new Div())
|
||||||
|
->class('fieldset col')
|
||||||
|
->items([
|
||||||
|
(new Text('p', __('Redirect to original post on:'))),
|
||||||
|
(new Para(null, 'ul'))
|
||||||
|
->items($titles),
|
||||||
|
]),
|
||||||
|
(new Div())
|
||||||
|
->class('fieldset col')
|
||||||
|
->items([
|
||||||
|
(new Text('p', __('Show full content on:'))),
|
||||||
|
(new Para(null, 'ul'))
|
||||||
|
->items($contents),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render();
|
||||||
|
|
||||||
|
dcPage::helpBlock('zoneclearFeedServer');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# -- Form combos --
|
|
||||||
$combo_admins = $zc->getAllBlogAdmins();
|
|
||||||
$combo_pubupd = [
|
|
||||||
__('Disable') => 0,
|
|
||||||
__('Before display') => 1,
|
|
||||||
__('After display') => 2,
|
|
||||||
__('Through Ajax') => 3,
|
|
||||||
];
|
|
||||||
$combo_status = [
|
|
||||||
__('Unpublished') => 0,
|
|
||||||
__('Published') => 1,
|
|
||||||
];
|
|
||||||
$combo_tagcase = [
|
|
||||||
__('Keep source case') => 0,
|
|
||||||
__('First upper case') => 1,
|
|
||||||
__('All lower case') => 2,
|
|
||||||
__('All upper case') => 3,
|
|
||||||
];
|
|
||||||
|
|
||||||
$pub_page_url = dcCore::app()->blog->url . dcCore::app()->url->getBase('zoneclearFeedsPage');
|
|
||||||
|
|
||||||
# -- Display form --
|
|
||||||
|
|
||||||
if (!is_writable(DC_TPL_CACHE)) {
|
|
||||||
echo '<p class="error">' . __('Dotclear cache is not writable or not well configured!') . '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '
|
|
||||||
<div class="fieldset">
|
|
||||||
<h4>' . __('Activation') . '</h4>
|
|
||||||
|
|
||||||
<p><label for="active">' .
|
|
||||||
form::checkbox('active', 1, $active) .
|
|
||||||
__('Enable plugin') . '</label></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fieldset">';
|
|
||||||
|
|
||||||
if ($s->pub_active) {
|
|
||||||
echo sprintf(
|
|
||||||
'<p><a class="onblog_link outgoing" href="%s" title="%s">%s <img alt="" src="images/outgoing-link.svg"></a></p>',
|
|
||||||
$pub_page_url,
|
|
||||||
$pub_page_url,
|
|
||||||
__('View the public list of feeds')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '
|
|
||||||
<h4>' . __('Rules') . '</h4>
|
|
||||||
|
|
||||||
<div class="two-boxes">
|
|
||||||
|
|
||||||
<p><label for="post_status_new">' . __('Status of new posts:') . '</label>' .
|
|
||||||
form::combo('post_status_new', $combo_status, $post_status_new) . '</p>
|
|
||||||
|
|
||||||
<p><label for="feeduser">' .
|
|
||||||
__('Owner of entries created by zoneclearFeedServer:') . '</label>' .
|
|
||||||
form::combo('feeduser', $combo_admins, $feeduser) . '</p>
|
|
||||||
|
|
||||||
<p><label for="tag_case">' . __('How to transform imported tags:') . '</label>' .
|
|
||||||
form::combo('tag_case', $combo_tagcase, $tag_case) . '</p>
|
|
||||||
|
|
||||||
</div><div class="two-boxes">
|
|
||||||
|
|
||||||
<p><label for="bhv_pub_upd">' . __('Update feeds on public side:') . '</label>' .
|
|
||||||
form::combo('bhv_pub_upd', $combo_pubupd, $bhv_pub_upd) . '</p>
|
|
||||||
|
|
||||||
<p class="classic"><label for="update_limit" class="ib">' . sprintf(
|
|
||||||
__('Update %s feed(s) at a time.'),
|
|
||||||
form::number('update_limit', ['min' => 0, 'max' => 20, 'default' => $update_limit])
|
|
||||||
) . '</label></p>
|
|
||||||
|
|
||||||
<p><label for="keep_empty_feed">' .
|
|
||||||
form::checkbox('keep_empty_feed', 1, $keep_empty_feed) . __('Keep active empty feeds') . '</label></p>
|
|
||||||
|
|
||||||
<p><label for="pub_active">' .
|
|
||||||
form::checkbox('pub_active', 1, $pub_active) . __('Enable public page') . '</label></p>
|
|
||||||
|
|
||||||
</div><div class="two-boxes">
|
|
||||||
|
|
||||||
<p>' . __('Redirect to original post on:') . '</p><ul>';
|
|
||||||
|
|
||||||
foreach ($zc->getPublicUrlTypes() as $k => $v) {
|
|
||||||
echo sprintf(
|
|
||||||
'<li><label for="post_title_redir_%s">%s%s</label></li>',
|
|
||||||
$v,
|
|
||||||
form::checkbox(['post_title_redir[]', 'post_title_redir_' . $v], $v, in_array($v, $post_title_redir)),
|
|
||||||
__($k)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
echo '
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div><div class="two-boxes">
|
|
||||||
|
|
||||||
<p>' . __('Show full content on:') . '</p><ul>';
|
|
||||||
|
|
||||||
foreach ($zc->getPublicUrlTypes() as $k => $v) {
|
|
||||||
echo sprintf(
|
|
||||||
'<li><label for="post_full_tpl_%s">%s%s</label></li>',
|
|
||||||
$v,
|
|
||||||
form::checkbox(['post_full_tpl[]', 'post_full_tpl_' . $v], $v, in_array($v, $post_full_tpl)),
|
|
||||||
__($k)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '</ul></div></div>';
|
|
||||||
|
|
||||||
dcPage::helpBlock('zoneclearFeedServer');
|
|
||||||
|
|
72
src/FeedRow.php
Normal file
72
src/FeedRow.php
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Feed meta record row type hinting.
|
||||||
|
*/
|
||||||
|
class FeedRow
|
||||||
|
{
|
||||||
|
public readonly int $id;
|
||||||
|
public readonly int $creadt;
|
||||||
|
public readonly int $upddt;
|
||||||
|
public readonly string $type;
|
||||||
|
public readonly ?string $blog_id;
|
||||||
|
public readonly ?int $cat_id;
|
||||||
|
public readonly int $upd_int;
|
||||||
|
public readonly int $upd_last;
|
||||||
|
public readonly int $status;
|
||||||
|
public readonly string $name;
|
||||||
|
public readonly string $desc;
|
||||||
|
public readonly string $url;
|
||||||
|
public readonly string $feed;
|
||||||
|
public readonly string $tags;
|
||||||
|
public readonly bool $get_tags;
|
||||||
|
public readonly string $owner;
|
||||||
|
public readonly string $tweeter;
|
||||||
|
public readonly string $lang;
|
||||||
|
public readonly int $nb_out;
|
||||||
|
public readonly int $nb_in;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor sets properties.
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public readonly MetaRecord $rs
|
||||||
|
) {
|
||||||
|
$this->id = is_numeric($this->rs->f('feed_id')) ? (int) $this->rs->f('feed_id') : 0;
|
||||||
|
$this->creadt = is_numeric($this->rs->f('feed_creadt')) ? (int) $this->rs->f('feed_creadt') : 0;
|
||||||
|
$this->upddt = is_numeric($this->rs->f('feed_upddt')) ? (int) $this->rs->f('feed_upddt') : 0;
|
||||||
|
$this->type = is_string($this->rs->f('feed_type')) ? $this->rs->f('feed_type') : '';
|
||||||
|
$this->blog_id = is_string($this->rs->f('blog_id')) ? $this->rs->f('blog_id') : null;
|
||||||
|
$this->cat_id = is_numeric($this->rs->f('cat_id')) ? (int) $this->rs->f('cat_id') : null;
|
||||||
|
$this->upd_int = is_numeric($this->rs->f('feed_upd_int')) ? (int) $this->rs->f('feed_upd_int') : 0;
|
||||||
|
$this->upd_last = is_numeric($this->rs->f('feed_upd_last')) ? (int) $this->rs->f('feed_upd_last') : 0;
|
||||||
|
$this->status = is_numeric($this->rs->f('feed_status')) ? (int) $this->rs->f('feed_status') : 0;
|
||||||
|
$this->name = is_string($this->rs->f('feed_name')) ? $this->rs->f('feed_name') : '';
|
||||||
|
$this->desc = is_string($this->rs->f('feed_desc')) ? $this->rs->f('feed_desc') : '';
|
||||||
|
$this->url = is_string($this->rs->f('feed_url')) ? $this->rs->f('feed_url') : '';
|
||||||
|
$this->feed = is_string($this->rs->f('feed_feed')) ? $this->rs->f('feed_feed') : '';
|
||||||
|
$this->tags = is_string($this->rs->f('feed_tags')) ? $this->rs->f('feed_tags') : '';
|
||||||
|
$this->get_tags = !empty($this->rs->f('feed_get_tags'));
|
||||||
|
$this->owner = is_string($this->rs->f('feed_owner')) ? $this->rs->f('feed_owner') : '';
|
||||||
|
$this->tweeter = is_string($this->rs->f('feed_tweeter')) ? $this->rs->f('feed_tweeter') : '';
|
||||||
|
$this->lang = is_string($this->rs->f('feed_lang')) ? $this->rs->f('feed_lang') : '';
|
||||||
|
$this->nb_out = is_numeric($this->rs->f('feed_nb_out')) ? (int) $this->rs->f('feed_nb_out') : 0;
|
||||||
|
$this->nb_in = is_numeric($this->rs->f('feed_nb_in')) ? (int) $this->rs->f('feed_nb_in') : 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,19 +10,35 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class zcfsFeedsActions extends dcActions
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcActions;
|
||||||
|
use dcCore;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend feeds list actions handler.
|
||||||
|
*/
|
||||||
|
class FeedsActions extends dcActions
|
||||||
{
|
{
|
||||||
public $zcfs;
|
public ZoneclearFeedServer $zcfs;
|
||||||
|
|
||||||
public function __construct($uri, $redirect_args = [])
|
/**
|
||||||
|
* @param string $uri
|
||||||
|
* @param array<string,mixed> $redirect_args
|
||||||
|
*/
|
||||||
|
public function __construct(string $uri, array $redirect_args = [])
|
||||||
{
|
{
|
||||||
$this->zcfs = new zoneclearFeedServer();
|
$this->zcfs = ZoneclearFeedServer::instance();
|
||||||
|
|
||||||
parent::__construct($uri, $redirect_args);
|
parent::__construct($uri, $redirect_args);
|
||||||
|
|
||||||
$this->redirect_fields = [
|
$this->redirect_fields = [
|
||||||
'sortby', 'order', 'page', 'nb',
|
'sortby', 'order', 'page', 'nb',
|
||||||
];
|
];
|
||||||
|
@ -31,13 +47,15 @@ class zcfsFeedsActions extends dcActions
|
||||||
$this->loadDefaults();
|
$this->loadDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadDefaults()
|
protected function loadDefaults(): void
|
||||||
{
|
{
|
||||||
zcfsDefaultFeedsActions::zcfsFeedsActions($this);
|
FeedsDefaultActions::addDefaultFeedsActions($this);
|
||||||
dcCore::app()->callBehavior('zcfsFeedsActions', $this);
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerAddFeedsActions - FeedsActions
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerAddFeedsActions', $this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function beginPage($breadcrumb = '', $head = '')
|
public function beginPage(string $breadcrumb = '', string $head = ''): void
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Feeds server') . '</title>' .
|
'<html><head><title>' . __('Feeds server') . '</title>' .
|
||||||
|
@ -49,17 +67,17 @@ class zcfsFeedsActions extends dcActions
|
||||||
__('Back to feeds list') . '</a></p>';
|
__('Back to feeds list') . '</a></p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function endPage()
|
public function endPage(): void
|
||||||
{
|
{
|
||||||
echo '</body></html>';
|
echo '</body></html>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function error(Exception $e)
|
public function error(Exception $e): void
|
||||||
{
|
{
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
$this->beginPage(
|
$this->beginPage(
|
||||||
dcPage::breadcrumb([
|
dcPage::breadcrumb([
|
||||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
Html::escapeHTML((string) dcCore::app()->blog?->name) => '',
|
||||||
$this->getCallerTitle() => $this->getRedirection(true),
|
$this->getCallerTitle() => $this->getRedirection(true),
|
||||||
__('Feeds actions') => '',
|
__('Feeds actions') => '',
|
||||||
])
|
])
|
||||||
|
@ -67,313 +85,21 @@ class zcfsFeedsActions extends dcActions
|
||||||
$this->endPage();
|
$this->endPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function fetchEntries($from)
|
protected function fetchEntries(ArrayObject $from): void
|
||||||
{
|
{
|
||||||
if (!empty($from['feeds'])) {
|
if (!empty($from['feeds']) && is_array($from['feeds'])) {
|
||||||
$params['feed_id'] = $from['feeds'];
|
$params = [
|
||||||
|
'feed_id' => $from['feeds'],
|
||||||
|
];
|
||||||
|
|
||||||
$feeds = $this->zcfs->getFeeds($params);
|
$feeds = ZoneclearFeedServer::instance()->getFeeds($params);
|
||||||
while ($feeds->fetch()) {
|
while ($feeds->fetch()) {
|
||||||
$this->entries[$feeds->feed_id] = $feeds->feed_name;
|
$row = new FeedRow($feeds);
|
||||||
|
$this->entries[$row->id] = $row->name;
|
||||||
}
|
}
|
||||||
$this->rs = $feeds;
|
$this->rs = $feeds;
|
||||||
} else {
|
} else {
|
||||||
$this->rs = dcCore::app()->con->select(
|
$this->rs = MetaRecord::newFromArray([]);
|
||||||
'SELECT blog_id FROM ' . dcCore::app()->prefix . dcBlog::BLOG_TABLE_NAME . ' WHERE false'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
|
||||||
* @brief Feeds server - Default actions methods
|
|
||||||
* @since 2.6
|
|
||||||
* @see dcDefaultPostsActionsPage for mor info
|
|
||||||
*/
|
|
||||||
class zcfsDefaultFeedsActions
|
|
||||||
{
|
|
||||||
public static function zcfsFeedsActions(zcfsFeedsActions $ap)
|
|
||||||
{
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Change category') => 'changecat'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doChangeCategory']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Change update interval') => 'changeint'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doChangeInterval']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Disable feed update') => 'disablefeed'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doEnableFeed']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Enable feed update') => 'enablefeed'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doEnableFeed']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Reset last update') => 'resetupdlast'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doResetUpdate']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Update (check) feed') => 'updatefeed'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doUpdateFeed']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Delete related posts') => 'deletepost'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doDeletePost']
|
|
||||||
);
|
|
||||||
$ap->addAction(
|
|
||||||
[__('Delete feed (without related posts)') => 'deletefeed'],
|
|
||||||
['zcfsDefaultFeedsActions', 'doDeleteFeed']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doEnableFeed(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
$enable = $ap->getAction() == 'enablefeed';
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$ap->zcfs->enableFeed($id, $enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
|
||||||
$enable ?
|
|
||||||
__(
|
|
||||||
'%d feed has been successfully enabled.',
|
|
||||||
'%d feeds have been successfully enabled.',
|
|
||||||
count($ids)
|
|
||||||
)
|
|
||||||
:
|
|
||||||
__(
|
|
||||||
'%d feed has been successfully disabled.',
|
|
||||||
'%d feeds have been successfully disabled.',
|
|
||||||
count($ids)
|
|
||||||
),
|
|
||||||
count($ids)
|
|
||||||
));
|
|
||||||
$ap->redirect(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doDeletePost(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
$types = [
|
|
||||||
'zoneclearfeed_url',
|
|
||||||
'zoneclearfeed_author',
|
|
||||||
'zoneclearfeed_site',
|
|
||||||
'zoneclearfeed_sitename',
|
|
||||||
'zoneclearfeed_id',
|
|
||||||
];
|
|
||||||
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$posts = $ap->zcfs->getPostsByFeed([
|
|
||||||
'feed_id' => $id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
while ($posts->fetch()) {
|
|
||||||
dcCore::app()->blog->delPost($posts->post_id);
|
|
||||||
dcCore::app()->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' ' .
|
|
||||||
'WHERE post_id = ' . $posts->post_id . ' ' .
|
|
||||||
'AND meta_type ' . dcCore::app()->con->in($types) . ' '
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
|
||||||
__('Entries have been successfully deleted.')
|
|
||||||
);
|
|
||||||
$ap->redirect(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doDeleteFeed(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$ap->zcfs->delFeed($id);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
|
||||||
__(
|
|
||||||
'%d feed has been successfully deleted.',
|
|
||||||
'%d feeds have been successfully deleted.',
|
|
||||||
count($ids)
|
|
||||||
),
|
|
||||||
count($ids)
|
|
||||||
));
|
|
||||||
$ap->redirect(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doUpdateFeed(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$ap->zcfs->checkFeedsUpdate($id, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
|
||||||
__(
|
|
||||||
'%d feed has been successfully updated.',
|
|
||||||
'%d feeds have been successfully updated.',
|
|
||||||
count($ids)
|
|
||||||
),
|
|
||||||
count($ids)
|
|
||||||
));
|
|
||||||
$ap->redirect(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doResetUpdate(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$cur = $ap->zcfs->openCursor();
|
|
||||||
$cur->feed_upd_last = 0;
|
|
||||||
$ap->zcfs->updFeed($id, $cur);
|
|
||||||
$ap->zcfs->checkFeedsUpdate($id, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
|
||||||
__(
|
|
||||||
'Last update of %s feed successfully reseted.',
|
|
||||||
'Last update of %s feeds successfully reseted.',
|
|
||||||
count($ids)
|
|
||||||
),
|
|
||||||
count($ids)
|
|
||||||
));
|
|
||||||
$ap->redirect(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doChangeCategory(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
if (isset($post['upd_cat_id'])) {
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$cat_id = abs((int) $post['upd_cat_id']);
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$cur = $ap->zcfs->openCursor();
|
|
||||||
$cur->cat_id = $cat_id == 0 ? null : $cat_id;
|
|
||||||
$ap->zcfs->updFeed($id, $cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
|
||||||
__(
|
|
||||||
'Category of %s feed successfully changed.',
|
|
||||||
'Category of %s feeds successfully changed.',
|
|
||||||
count($ids)
|
|
||||||
),
|
|
||||||
count($ids)
|
|
||||||
));
|
|
||||||
$ap->redirect(true);
|
|
||||||
} else {
|
|
||||||
$categories_combo = dcAdminCombos::getCategoriesCombo(
|
|
||||||
dcCore::app()->blog->getCategories()
|
|
||||||
);
|
|
||||||
|
|
||||||
$ap->beginPage(
|
|
||||||
dcPage::breadcrumb([
|
|
||||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
|
||||||
__('Feeds server') => '',
|
|
||||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
|
||||||
__('Change category for this selection') => '',
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
|
||||||
$ap->getCheckboxes() .
|
|
||||||
'<p><label for="upd_cat_id" class="classic">' . __('Category:') . '</label> ' .
|
|
||||||
form::combo(['upd_cat_id'], $categories_combo, '') .
|
|
||||||
dcCore::app()->formNonce() .
|
|
||||||
$ap->getHiddenFields() .
|
|
||||||
form::hidden(['action'], 'changecat') .
|
|
||||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
$ap->endPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function doChangeInterval(zcfsFeedsActions $ap, $post)
|
|
||||||
{
|
|
||||||
if (isset($post['upd_upd_int'])) {
|
|
||||||
$ids = $ap->getIDs();
|
|
||||||
|
|
||||||
if (empty($ids)) {
|
|
||||||
throw new Exception(__('No feeds selected'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$upd_int = abs((int) $post['upd_upd_int']);
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$cur = $ap->zcfs->openCursor();
|
|
||||||
$cur->feed_upd_int = $upd_int;
|
|
||||||
$ap->zcfs->updFeed($id, $cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
|
||||||
__(
|
|
||||||
'Update frequency of %s feed successfully changed.',
|
|
||||||
'Update frequency of %s feeds successfully changed.',
|
|
||||||
count($ids)
|
|
||||||
),
|
|
||||||
count($ids)
|
|
||||||
));
|
|
||||||
$ap->redirect(true);
|
|
||||||
} else {
|
|
||||||
$ap->beginPage(
|
|
||||||
dcPage::breadcrumb(
|
|
||||||
[
|
|
||||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
|
||||||
__('Feeds server') => '',
|
|
||||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
|
||||||
__('Change update frequency for this selection') => '',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
echo
|
|
||||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
|
||||||
$ap->getCheckboxes() .
|
|
||||||
'<p><label for="upd_upd_int" class="classic">' . __('Frequency:') . '</label> ' .
|
|
||||||
form::combo(['upd_upd_int'], $ap->zcfs->getAllUpdateInterval(), '') .
|
|
||||||
dcCore::app()->formNonce() .
|
|
||||||
$ap->getHiddenFields() .
|
|
||||||
form::hidden(['action'], 'changeint') .
|
|
||||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
|
||||||
'</form>';
|
|
||||||
|
|
||||||
$ap->endPage();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,68 +10,90 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcCore;
|
||||||
|
use dcMeta;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Database\Statement\DeleteStatement;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Form,
|
||||||
|
Hidden,
|
||||||
|
Label,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Submit,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Backend feeds list default actions.
|
||||||
* @brief Feeds server - Default actions methods
|
|
||||||
* @since 2.6
|
|
||||||
* @see dcDefaultPostsActionsPage for mor info
|
|
||||||
*/
|
*/
|
||||||
class zcfsDefaultFeedsActions
|
class FeedsDefaultActions
|
||||||
{
|
{
|
||||||
public static function zcfsFeedsActions(zcfsFeedsActions $ap)
|
/**
|
||||||
|
* Add feeds list actions.
|
||||||
|
*/
|
||||||
|
public static function addDefaultFeedsActions(FeedsActions $ap): void
|
||||||
{
|
{
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Change category') => 'changecat'],
|
[__('Change category') => 'changecat'],
|
||||||
['zcfsDefaultFeedsActions', 'doChangeCategory']
|
[self::class, 'doChangeCategory']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Change update interval') => 'changeint'],
|
[__('Change update interval') => 'changeint'],
|
||||||
['zcfsDefaultFeedsActions', 'doChangeInterval']
|
[self::class, 'doChangeInterval']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Disable feed update') => 'disablefeed'],
|
[__('Disable feed update') => 'disablefeed'],
|
||||||
['zcfsDefaultFeedsActions', 'doEnableFeed']
|
[self::class, 'doEnableFeed']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Enable feed update') => 'enablefeed'],
|
[__('Enable feed update') => 'enablefeed'],
|
||||||
['zcfsDefaultFeedsActions', 'doEnableFeed']
|
[self::class, 'doEnableFeed']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Reset last update') => 'resetupdlast'],
|
[__('Reset last update') => 'resetupdlast'],
|
||||||
['zcfsDefaultFeedsActions', 'doResetUpdate']
|
[self::class, 'doResetUpdate']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Update (check) feed') => 'updatefeed'],
|
[__('Update (check) feed') => 'updatefeed'],
|
||||||
['zcfsDefaultFeedsActions', 'doUpdateFeed']
|
[self::class, 'doUpdateFeed']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Delete related posts') => 'deletepost'],
|
[__('Delete related posts') => 'deletepost'],
|
||||||
['zcfsDefaultFeedsActions', 'doDeletePost']
|
[self::class, 'doDeletePost']
|
||||||
);
|
);
|
||||||
$ap->addAction(
|
$ap->addAction(
|
||||||
[__('Delete feed (without related posts)') => 'deletefeed'],
|
[__('Delete feed (without related posts)') => 'deletefeed'],
|
||||||
['zcfsDefaultFeedsActions', 'doDeleteFeed']
|
[self::class, 'doDeleteFeed']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doEnableFeed(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Enable / disable feeds.
|
||||||
|
*/
|
||||||
|
public static function doEnableFeed(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
$enable = $ap->getAction() == 'enablefeed';
|
$enable = $ap->getAction() == 'enablefeed';
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$ap->zcfs->enableFeed($id, $enable);
|
$ap->zcfs->enableFeed($id, $enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
dcPage::addSuccessNotice(sprintf(
|
||||||
$enable ?
|
$enable ?
|
||||||
__(
|
__(
|
||||||
'%d feed has been successfully enabled.',
|
'%d feed has been successfully enabled.',
|
||||||
|
@ -89,20 +111,25 @@ class zcfsDefaultFeedsActions
|
||||||
$ap->redirect(true);
|
$ap->redirect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doDeletePost(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Delete feeds posts.
|
||||||
|
*/
|
||||||
|
public static function doDeletePost(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
$types = [
|
$types = [
|
||||||
'zoneclearfeed_url',
|
My::META_PREFIX . 'url',
|
||||||
'zoneclearfeed_author',
|
My::META_PREFIX . 'author',
|
||||||
'zoneclearfeed_site',
|
My::META_PREFIX . 'site',
|
||||||
'zoneclearfeed_sitename',
|
My::META_PREFIX . 'sitename',
|
||||||
'zoneclearfeed_id',
|
My::META_PREFIX . 'id',
|
||||||
];
|
];
|
||||||
|
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
|
@ -111,34 +138,42 @@ class zcfsDefaultFeedsActions
|
||||||
]);
|
]);
|
||||||
|
|
||||||
while ($posts->fetch()) {
|
while ($posts->fetch()) {
|
||||||
dcCore::app()->blog->delPost($posts->post_id);
|
if (is_numeric($posts->f('post_id'))) {
|
||||||
dcCore::app()->con->execute(
|
dcCore::app()->blog?->delPost((int) $posts->f('post_id'));
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' ' .
|
$sql = new DeleteStatement();
|
||||||
'WHERE post_id = ' . $posts->post_id . ' ' .
|
$sql
|
||||||
'AND meta_type ' . dcCore::app()->con->in($types) . ' '
|
->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME)
|
||||||
);
|
->where('post_id = ' . $posts->f('post_id'))
|
||||||
|
->and('meta_type ' . $sql->in($types))
|
||||||
|
->delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
dcPage::addSuccessNotice(
|
||||||
__('Entries have been successfully deleted.')
|
__('Entries have been successfully deleted.')
|
||||||
);
|
);
|
||||||
$ap->redirect(true);
|
$ap->redirect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doDeleteFeed(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Delete feeds.
|
||||||
|
*/
|
||||||
|
public static function doDeleteFeed(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$ap->zcfs->delFeed($id);
|
$ap->zcfs->deleteFeed($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
dcPage::addSuccessNotice(sprintf(
|
||||||
__(
|
__(
|
||||||
'%d feed has been successfully deleted.',
|
'%d feed has been successfully deleted.',
|
||||||
'%d feeds have been successfully deleted.',
|
'%d feeds have been successfully deleted.',
|
||||||
|
@ -149,77 +184,90 @@ class zcfsDefaultFeedsActions
|
||||||
$ap->redirect(true);
|
$ap->redirect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doUpdateFeed(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Update feeds properties.
|
||||||
|
*/
|
||||||
|
public static function doUpdateFeed(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$ap->zcfs->checkFeedsUpdate($id, true);
|
$ap->zcfs->checkFeedsUpdate($id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
dcPage::addSuccessNotice(sprintf(
|
||||||
__('%d feed has been successfully updated.', '%d feeds have been successfully updated.', count($ids)),
|
__('%d feed has been successfully updated.', '%d feeds have been successfully updated.', count($ids)),
|
||||||
count($ids)
|
count($ids)
|
||||||
));
|
));
|
||||||
$ap->redirect(true);
|
$ap->redirect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doResetUpdate(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Reset feeds update timer.
|
||||||
|
*/
|
||||||
|
public static function doResetUpdate(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$cur = $ap->zcfs->openCursor();
|
$cur = $ap->zcfs->openCursor();
|
||||||
$cur->feed_upd_last = 0;
|
foreach ($ids as $id) {
|
||||||
$ap->zcfs->updFeed($id, $cur);
|
$cur->clean();
|
||||||
|
$cur->setField('feed_upd_last', 0);
|
||||||
|
$ap->zcfs->updateFeed($id, $cur);
|
||||||
$ap->zcfs->checkFeedsUpdate($id, true);
|
$ap->zcfs->checkFeedsUpdate($id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
dcPage::addSuccessNotice(sprintf(
|
||||||
__('Last update of %s feed successfully reseted.', 'Last update of %s feeds successfully reseted.', count($ids)),
|
__('Last update of %s feed successfully reseted.', 'Last update of %s feeds successfully reseted.', count($ids)),
|
||||||
count($ids)
|
count($ids)
|
||||||
));
|
));
|
||||||
$ap->redirect(true);
|
$ap->redirect(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doChangeCategory(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Change feeds categories.
|
||||||
|
*/
|
||||||
|
public static function doChangeCategory(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
if (isset($post['upd_cat_id'])) {
|
if (isset($post['upd_cat_id'])) {
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cat_id = abs((int) $post['upd_cat_id']);
|
$cat_id = is_numeric($post['upd_cat_id']) ? abs((int) $post['upd_cat_id']) : null;
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$cur = $ap->zcfs->openCursor();
|
$cur = $ap->zcfs->openCursor();
|
||||||
$cur->cat_id = $cat_id == 0 ? null : $cat_id;
|
foreach ($ids as $id) {
|
||||||
$ap->zcfs->updFeed($id, $cur);
|
$cur->clean();
|
||||||
|
$cur->setField('cat_id', $cat_id == 0 ? null : $cat_id);
|
||||||
|
$ap->zcfs->updateFeed($id, $cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
dcPage::addSuccessNotice(sprintf(
|
||||||
__('Category of %s feed successfully changed.', 'Category of %s feeds successfully changed.', count($ids)),
|
__('Category of %s feed successfully changed.', 'Category of %s feeds successfully changed.', count($ids)),
|
||||||
count($ids)
|
count($ids)
|
||||||
));
|
));
|
||||||
$ap->redirect(true);
|
$ap->redirect(true);
|
||||||
} else {
|
} else {
|
||||||
$categories_combo = dcAdminCombos::getCategoriesCombo(
|
|
||||||
dcCore::app()->blog->getCategories()
|
|
||||||
);
|
|
||||||
|
|
||||||
$ap->beginPage(
|
$ap->beginPage(
|
||||||
dcPage::breadcrumb([
|
dcPage::breadcrumb([
|
||||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
Html::escapeHTML((string) dcCore::app()->blog?->name) => '',
|
||||||
__('Feeds server') => '',
|
__('Feeds server') => '',
|
||||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
$ap->getCallerTitle() => $ap->getRedirection(true),
|
||||||
__('Change category for this selection') => '',
|
__('Change category for this selection') => '',
|
||||||
|
@ -227,38 +275,57 @@ class zcfsDefaultFeedsActions
|
||||||
);
|
);
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
(new Form('form-action'))
|
||||||
$ap->getCheckboxes() .
|
->method('post')
|
||||||
'<p><label for="upd_cat_id" class="classic">' . __('Category:') . '</label> ' .
|
->action($ap->getURI())
|
||||||
form::combo(['upd_cat_id'], $categories_combo, '') .
|
->fields([
|
||||||
dcCore::app()->formNonce() .
|
(new Text('', $ap->getCheckboxes())),
|
||||||
$ap->getHiddenFields() .
|
(new Para())
|
||||||
form::hidden(['action'], 'changecat') .
|
->items(array_merge(
|
||||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
$ap->hiddenFields(),
|
||||||
'</form>';
|
[
|
||||||
|
(new Label(__('Category:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('upd_cat_id'),
|
||||||
|
(new Select('upd_cat_id'))
|
||||||
|
->items(Combo::postCategories()),
|
||||||
|
(new Submit('do-action'))
|
||||||
|
->value(__('Save')),
|
||||||
|
(new Hidden(['action'], 'changecat')),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
|
||||||
|
])
|
||||||
|
->render();
|
||||||
|
|
||||||
$ap->endPage();
|
$ap->endPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function doChangeInterval(zcfsFeedsActions $ap, $post)
|
/**
|
||||||
|
* Change feeds update interval.
|
||||||
|
*/
|
||||||
|
public static function doChangeInterval(FeedsActions $ap, ArrayObject $post): void
|
||||||
{
|
{
|
||||||
if (isset($post['upd_upd_int'])) {
|
if (isset($post['upd_upd_int'])) {
|
||||||
$ids = $ap->getIDs();
|
$ids = $ap->getIDs();
|
||||||
|
|
||||||
if (empty($ids)) {
|
if (empty($ids)) {
|
||||||
throw new Exception(__('No feeds selected'));
|
$ap->error(new Exception(__('No feeds selected')));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$upd_int = abs((int) $post['upd_upd_int']);
|
$upd_int = is_numeric($post['upd_upd_int']) ? abs((int) $post['upd_upd_int']) : 0;
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$cur = $ap->zcfs->openCursor();
|
$cur = $ap->zcfs->openCursor();
|
||||||
$cur->feed_upd_int = $upd_int;
|
foreach ($ids as $id) {
|
||||||
$ap->zcfs->updFeed($id, $cur);
|
$cur->clean();
|
||||||
|
$cur->setField('feed_upd_int', $upd_int);
|
||||||
|
$ap->zcfs->updateFeed($id, $cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(sprintf(
|
dcPage::addSuccessNotice(sprintf(
|
||||||
__('Update frequency of %s feed successfully changed.', 'Update frequency of %s feeds successfully changed.', count($ids)),
|
__('Update frequency of %s feed successfully changed.', 'Update frequency of %s feeds successfully changed.', count($ids)),
|
||||||
count($ids)
|
count($ids)
|
||||||
));
|
));
|
||||||
|
@ -267,7 +334,7 @@ class zcfsDefaultFeedsActions
|
||||||
$ap->beginPage(
|
$ap->beginPage(
|
||||||
dcPage::breadcrumb(
|
dcPage::breadcrumb(
|
||||||
[
|
[
|
||||||
html::escapeHTML(dcCore::app()->blog->name) => '',
|
Html::escapeHTML((string) dcCore::app()->blog?->name) => '',
|
||||||
__('Feeds server') => '',
|
__('Feeds server') => '',
|
||||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
$ap->getCallerTitle() => $ap->getRedirection(true),
|
||||||
__('Change update frequency for this selection') => '',
|
__('Change update frequency for this selection') => '',
|
||||||
|
@ -276,15 +343,28 @@ class zcfsDefaultFeedsActions
|
||||||
);
|
);
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
(new Form('form-action'))
|
||||||
$ap->getCheckboxes() .
|
->method('post')
|
||||||
'<p><label for="upd_upd_int" class="classic">' . __('Frequency:') . '</label> ' .
|
->action($ap->getURI())
|
||||||
form::combo(['upd_upd_int'], $ap->zcfs->getAllUpdateInterval(), '') .
|
->fields([
|
||||||
dcCore::app()->formNonce() .
|
(new Text('', $ap->getCheckboxes())),
|
||||||
$ap->getHiddenFields() .
|
(new Para())
|
||||||
form::hidden(['action'], 'changeint') .
|
->items(array_merge(
|
||||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
$ap->hiddenFields(),
|
||||||
'</form>';
|
[
|
||||||
|
(new Label(__('Frequency:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('upd_upd_int'),
|
||||||
|
(new Select('upd_upd_int'))
|
||||||
|
->items(Combo::updateInterval()),
|
||||||
|
(new Submit('do-action'))
|
||||||
|
->value(__('Save')),
|
||||||
|
(new Hidden(['action'], 'changeint')),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
|
||||||
|
])
|
||||||
|
->render();
|
||||||
|
|
||||||
$ap->endPage();
|
$ap->endPage();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,132 +10,179 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use adminGenericFilterV2;
|
||||||
|
use adminGenericListV2;
|
||||||
|
use dcCore;
|
||||||
|
use dcPager;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Link,
|
||||||
|
Para,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Backend feeds list.
|
||||||
* @brief Feeds server - feeds list methods
|
|
||||||
* @since 2.6
|
|
||||||
* @see adminGenericList for more info
|
|
||||||
*/
|
*/
|
||||||
class zcfsFeedsList extends adminGenericList
|
class FeedsList extends adminGenericListV2
|
||||||
{
|
{
|
||||||
private $zc = null;
|
public function display(adminGenericFilterV2 $filter, string $enclose_block = ''): void
|
||||||
|
|
||||||
public function feedsDisplay($page, $nb_per_page, $enclose_block = '', $filter = false)
|
|
||||||
{
|
{
|
||||||
if ($this->rs->isEmpty()) {
|
if ($this->rs->isEmpty()) {
|
||||||
if ($filter) {
|
echo
|
||||||
echo '<p><strong>' . __('No feeds matches the filter') . '</strong></p>';
|
(new Text(
|
||||||
} else {
|
'p',
|
||||||
echo '<p><strong>' . __('No feeds') . '</strong></p>';
|
$filter->show() ?
|
||||||
}
|
__('No feeds matches the filter') :
|
||||||
} else {
|
__('No feeds')
|
||||||
$this->zc = new zoneclearFeedServer();
|
))
|
||||||
$pager = new dcPager($page, $this->rs_count, $nb_per_page, 10);
|
->class('info')
|
||||||
$entries = [];
|
->render();
|
||||||
if (isset($_REQUEST['feeds'])) {
|
|
||||||
foreach ($_REQUEST['feeds'] as $v) {
|
|
||||||
$entries[(int) $v] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$html_block = '<div class="table-outer">' .
|
|
||||||
'<table>' .
|
|
||||||
'<caption>' . (
|
|
||||||
$filter ?
|
|
||||||
sprintf(__('List of %s feeds matching the filter.'), $this->rs_count) :
|
|
||||||
sprintf(__('List of feeds (%s)'), $this->rs_count)
|
|
||||||
) . '</caption>';
|
|
||||||
|
|
||||||
$cols = [
|
return;
|
||||||
'title' => '<th colspan="2" class="first nowrap">' . __('Name') . '</th>',
|
|
||||||
'desc' => '<th class="nowrap" scope="col">' . __('Feed') . '</th>',
|
|
||||||
'period' => '<th class="nowrap" scope="col">' . __('Frequency') . '</th>',
|
|
||||||
'update' => '<th class="nowrap" scope="col">' . __('Last update') . '</th>',
|
|
||||||
'entries' => '<th class="nowrap" scope="col">' . __('Entries') . '</th>',
|
|
||||||
'status' => '<th class="nowrap" scope="col">' . __('Status') . '</th>',
|
|
||||||
];
|
|
||||||
$cols = new ArrayObject($cols);
|
|
||||||
|
|
||||||
dcCore::app()->callBehavior('adminZcfsFeedsListHeader', $this->rs, $cols);
|
|
||||||
|
|
||||||
$this->userColumns('zcfs_feeds', $cols);
|
|
||||||
|
|
||||||
$html_block .= '<tr>' . implode(iterator_to_array($cols)) . '</tr>%s</table>%s</div>';
|
|
||||||
if ($enclose_block) {
|
|
||||||
$html_block = sprintf($enclose_block, $html_block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $pager->getLinks();
|
$page = is_numeric($filter->value('page')) ? (int) $filter->value('page') : 1;
|
||||||
|
$nbpp = is_numeric($filter->value('nb')) ? (int) $filter->value('nb') : 10;
|
||||||
|
$count = (int) $this->rs_count;
|
||||||
|
$pager = new dcPager($page, $count, $nbpp, 10);
|
||||||
|
|
||||||
$blocks = explode('%s', $html_block);
|
$cols = new ArrayObject([
|
||||||
|
'title' => (new Text('th', __('Name')))
|
||||||
|
->class('first')
|
||||||
|
->extra('colspan="2"'),
|
||||||
|
'desc' => (new Text('th', __('Feed')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
'period' => (new Text('th', __('Frequency')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
'update' => (new Text('th', __('Last update')))
|
||||||
|
->extra('scope="col"')->class('nowrap'),
|
||||||
|
'entries' => (new Text('th', __('Entries')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
'status' => (new Text('th', __('Status')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
]);
|
||||||
|
|
||||||
echo $blocks[0];
|
$this->userColumns(My::id() . 'feeds', $cols);
|
||||||
|
|
||||||
|
$lines = [];
|
||||||
while ($this->rs->fetch()) {
|
while ($this->rs->fetch()) {
|
||||||
echo $this->feedsLine(isset($entries[$this->rs->feed_id]));
|
$lines[] = $this->line(isset($_POST['feeds']) && in_array($this->rs->post_id, $_POST['feeds']));
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $blocks[1];
|
echo
|
||||||
echo $blocks[2];
|
$pager->getLinks() .
|
||||||
echo $pager->getLinks();
|
sprintf(
|
||||||
}
|
$enclose_block,
|
||||||
|
(new Div())
|
||||||
|
->class('table-outer')
|
||||||
|
->items([
|
||||||
|
(new Para(null, 'table'))
|
||||||
|
->items([
|
||||||
|
(new Text(
|
||||||
|
'caption',
|
||||||
|
$filter->show() ?
|
||||||
|
sprintf(__('List of %s feeds matching the filter.'), $this->rs_count) :
|
||||||
|
sprintf(__('List of feeds. (%s)'), $this->rs_count)
|
||||||
|
)),
|
||||||
|
(new Para(null, 'tr'))
|
||||||
|
->items(iterator_to_array($cols)),
|
||||||
|
(new Para(null, 'tbody'))
|
||||||
|
->items($lines),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render()
|
||||||
|
) .
|
||||||
|
$pager->getLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function feedsLine($checked)
|
private function line(bool $checked): Para
|
||||||
{
|
{
|
||||||
$combo_status = zoneclearFeedServer::getAllStatus();
|
$row = new FeedRow($this->rs);
|
||||||
$combo_upd_int = zoneclearFeedServer::getAllUpdateInterval();
|
$img_title = $row->status ? __('enabled') : __('disabled');
|
||||||
$status = $this->rs->feed_status ?
|
$img_src = $row->status ? 'check-on.png' : 'check-off.png';
|
||||||
'<img src="images/check-on.png" alt="enable" />' :
|
|
||||||
'<img src="images/check-off.png" alt="disable" />';
|
|
||||||
|
|
||||||
$entries_count = $this->zc->getPostsByFeed(['feed_id' => $this->rs->feed_id], true)->f(0);
|
$entries_count = ZoneclearFeedServer::instance()->getPostsByFeed(['feed_id' => $row->id], true)->f(0);
|
||||||
$shunk_feed = $this->rs->feed_feed;
|
if (!is_numeric($entries_count)) {
|
||||||
|
$entries_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$shunk_feed = $row->feed;
|
||||||
if (strlen($shunk_feed) > 83) {
|
if (strlen($shunk_feed) > 83) {
|
||||||
$shunk_feed = substr($shunk_feed, 0, 50) . '...' . substr($shunk_feed, -20);
|
$shunk_feed = substr($shunk_feed, 0, 50) . '...' . substr($shunk_feed, -20);
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = dcCore::app()->adminurl->get('admin.plugin.' . basename(dirname('../' . __DIR__)), ['part' => 'feed', 'feed_id' => $this->rs->feed_id]);
|
$url = dcCore::app()->adminurl?->get('admin.plugin.' . My::id(), ['part' => 'feed', 'feed_id' => $row->id]);
|
||||||
|
if (!is_string($url)) {
|
||||||
|
$url = '';
|
||||||
|
}
|
||||||
|
$tz = dcCore::app()->auth?->getInfo('user_tz');
|
||||||
|
if (!is_string($tz)) {
|
||||||
|
$tz = 'UTC';
|
||||||
|
}
|
||||||
|
|
||||||
$cols = [
|
$cols = new ArrayObject([
|
||||||
'check' => '<td class="nowrap minimal">' .
|
'check' => (new Para(null, 'td'))
|
||||||
form::checkbox(['feeds[]'], $this->rs->feed_id, ['checked' => $checked]) .
|
->class('nowrap minimal')
|
||||||
'</td>',
|
->items([
|
||||||
'title' => '<td class="nowrap" scope="row">' .
|
(new Checkbox(['feeds[]'], $checked))
|
||||||
'<a href="' . $url . '#feed" title="' . __('Edit') . '">' . html::escapeHTML($this->rs->feed_name) . '</a>' .
|
->value($row->id),
|
||||||
'</td>',
|
]),
|
||||||
'desc' => '<td class="nowrap maximal">' .
|
'title' => (new Para(null, 'td'))
|
||||||
'<a href="' . $this->rs->feed_feed . '" title="' . html::escapeHTML($this->rs->feed_desc) . '">' . html::escapeHTML($shunk_feed) . '</a>' .
|
->class('nowrap')
|
||||||
'</td>',
|
->items([
|
||||||
'period' => '<td class="nowrap minimal count">' .
|
(new Link())
|
||||||
array_search($this->rs->feed_upd_int, $combo_upd_int) .
|
->title(__('Edit'))
|
||||||
'</td>',
|
->text(Html::escapeHTML($row->name))
|
||||||
'update' => '<td class="nowrap minimal count">' .
|
->href($url . '#feed'),
|
||||||
(
|
]),
|
||||||
$this->rs->feed_upd_last < 1 ?
|
'desc' => (new Para(null, 'td'))
|
||||||
|
->class('nowrap maximal')
|
||||||
|
->items([
|
||||||
|
(new Link())
|
||||||
|
->title(Html::escapeHTML($row->desc))
|
||||||
|
->text(Html::escapeHTML($shunk_feed))
|
||||||
|
->href($row->feed),
|
||||||
|
])
|
||||||
|
->class('nowrap minimal'),
|
||||||
|
'period' => (new Text('td', (string) array_search($row->upd_int, Combo::updateInterval())))
|
||||||
|
->class('nowrap minimal'),
|
||||||
|
'update' => (new Text(
|
||||||
|
'td',
|
||||||
|
$row->upd_last < 1 ?
|
||||||
__('never') :
|
__('never') :
|
||||||
dt::str(__('%Y-%m-%d %H:%M'), (int) $this->rs->feed_upd_last, dcCore::app()->auth->getInfo('user_tz'))
|
Date::str(__('%Y-%m-%d %H:%M'), $row->upd_last, $tz)
|
||||||
) . '</td>',
|
))
|
||||||
'entries' => '<td class="nowrap minimal count">' .
|
->class('nowrap minimal'),
|
||||||
(
|
'entries' => (new Para(null, 'td'))
|
||||||
$entries_count ?
|
->class('nowrap minimal count')
|
||||||
'<a href="' . $url . '#entries" title="' . __('View entries') . '">' . $entries_count . '</a>' :
|
->items([
|
||||||
$entries_count
|
(new Link())
|
||||||
) . '</td>',
|
->title(Html::escapeHTML(__('View entries')))
|
||||||
'status' => '<td class="nowrap minimal status">' . $status . '</td>',
|
->text(Html::escapeHTML((string) $entries_count))
|
||||||
];
|
->href($url . '#entries'),
|
||||||
|
]),
|
||||||
|
'status' => (new Para(null, 'td'))
|
||||||
|
->class('nowrap minimal status')
|
||||||
|
->items([
|
||||||
|
(new Text('img', ''))
|
||||||
|
->title($img_title)
|
||||||
|
->extra('src="images/' . $img_src . '"'),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
$cols = new ArrayObject($cols);
|
$this->userColumns(My::id() . 'feeds', $cols);
|
||||||
dcCore::app()->callBehavior('adminZcfsFeedsListValue', $this->rs, $cols);
|
|
||||||
|
|
||||||
$this->userColumns('zcfs_feeds', $cols);
|
return (new Para('p' . $row->id, 'tr'))
|
||||||
|
->class('line' . ($row->status != 1 ? ' offline ' : ''))
|
||||||
return
|
->items(iterator_to_array($cols));
|
||||||
'<tr class="line ' . ($this->rs->feed_status ? '' : 'offline ') . '" id="p' . $this->rs->feed_id . '">' .
|
|
||||||
implode(iterator_to_array($cols)) .
|
|
||||||
'</tr>';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
164
src/Frontend.php
164
src/Frontend.php
|
@ -10,71 +10,109 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Namespace for settings
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
dcCore::app()->blog->settings->addNamespace(basename(__DIR__));
|
|
||||||
$s = dcCore::app()->blog->settings->__get(basename(__DIR__));
|
|
||||||
|
|
||||||
# Widgets
|
use dcCore;
|
||||||
require_once __DIR__ . '/_widgets.php';
|
use dcNsProcess;
|
||||||
|
use dcUtils;
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
dcCore::app()->addBehavior('coreBlogGetPosts', ['zcfsPublicBehaviors', 'coreBlogGetPosts']);
|
/**
|
||||||
|
* Frontend prepend.
|
||||||
|
*/
|
||||||
|
class Frontend extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = My::phpCompliant();
|
||||||
|
|
||||||
if (!$s->active) {
|
return static::$init;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (1 == $s->bhv_pub_upd) {
|
|
||||||
dcCore::app()->addBehavior('publicBeforeDocumentV2', ['zcfsPublicBehaviors', 'publicDocumentV2']);
|
|
||||||
} elseif (2 == $s->bhv_pub_upd) {
|
|
||||||
dcCore::app()->addBehavior('publicAfterDocumentV2', ['zcfsPublicBehaviors', 'publicAfterDocumentV2']);
|
|
||||||
} elseif (3 == $s->bhv_pub_upd) {
|
|
||||||
dcCore::app()->addBehavior('publicHeadContent', ['zcfsPublicBehaviors', 'publicHeadContent']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Take care about tweakurls (thanks Mathieu M.)
|
|
||||||
if (version_compare(dcCore::app()->plugins->moduleInfo('tweakurls', 'version'), '0.8', '>=')) {
|
|
||||||
dcCore::app()->addbehavior('zoneclearFeedServerAfterPostCreate', ['zoneclearFeedServer', 'tweakurlsAfterPostCreate']);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Register tempalte blocks
|
|
||||||
$tpl_blocks = [
|
|
||||||
'Feeds',
|
|
||||||
'FeedsFooter',
|
|
||||||
'FeedsHeader',
|
|
||||||
'FeedIf',
|
|
||||||
];
|
|
||||||
foreach ($tpl_blocks as $v) {
|
|
||||||
dcCore::app()->tpl->addBlock('zc' . $v, ['zcfsTemplate', $v]);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Register tempalte values
|
|
||||||
$tpl_values = [
|
|
||||||
'FeedsCount',
|
|
||||||
'FeedsEntriesCount',
|
|
||||||
'FeedEntriesCount',
|
|
||||||
'FeedCategory',
|
|
||||||
'FeedCategoryID',
|
|
||||||
'FeedCategoryURL',
|
|
||||||
'FeedCategoryShortURL',
|
|
||||||
'FeedID',
|
|
||||||
'FeedIfFirst',
|
|
||||||
'FeedIfOdd',
|
|
||||||
'FeedLang',
|
|
||||||
'FeedName',
|
|
||||||
'FeedOwner',
|
|
||||||
'FeedDesc',
|
|
||||||
'FeedSiteURL',
|
|
||||||
'FeedFeedURL',
|
|
||||||
];
|
|
||||||
foreach ($tpl_values as $v) {
|
|
||||||
dcCore::app()->tpl->addValue('zc' . $v, ['zcfsTemplate', $v]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->addBehavior('publicBreadcrumb', function ($context, $separator) {
|
|
||||||
if ($context == 'zoneclearFeedsPage') {
|
|
||||||
return __('List of feeds');
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$s = ZoneclearFeedServer::instance()->settings;
|
||||||
|
|
||||||
|
dcCore::app()->addBehaviors([
|
||||||
|
// posts record
|
||||||
|
'coreBlogGetPosts' => function (MetaRecord $rs): void {
|
||||||
|
RsExtPosts::$brother_extensions = $rs->extensions();
|
||||||
|
$rs->extend(RsExtPosts::class);
|
||||||
|
},
|
||||||
|
// breadcrumb
|
||||||
|
'publicBreadcrumb' => function (string $context, string $separator): string {
|
||||||
|
return $context == 'zoneclearFeedsPage' ? __('List of feeds') : '';
|
||||||
|
},
|
||||||
|
// widgets registration
|
||||||
|
'initWidgets' => [Widgets::class, 'init'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Register template blocks
|
||||||
|
foreach (My::TPL_BLOCKS as $block) {
|
||||||
|
dcCore::app()->tpl->addBlock('zc' . $block, [Template::class, $block]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register template values
|
||||||
|
foreach (My::TPL_VALUES as $value) {
|
||||||
|
dcCore::app()->tpl->addValue('zc' . $value, [Template::class, $value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// module not active
|
||||||
|
if (!$s->active) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// feeds update methods
|
||||||
|
if (1 == $s->bhv_pub_upd) {
|
||||||
|
dcCore::app()->addBehavior('publicBeforeDocumentV2', function (): void {
|
||||||
|
if (in_array(dcCore::app()->url->type, ['default', 'feed'])) {
|
||||||
|
try {
|
||||||
|
ZoneclearFeedServer::instance()->checkFeedsUpdate();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} elseif (2 == $s->bhv_pub_upd) {
|
||||||
|
dcCore::app()->addBehavior('publicAfterDocumentV2', function (): void {
|
||||||
|
try {
|
||||||
|
ZoneclearFeedServer::instance()->checkFeedsUpdate();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
pdump($e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} elseif (3 == $s->bhv_pub_upd) {
|
||||||
|
dcCore::app()->addBehavior('publicHeadContent', function (): void {
|
||||||
|
if (is_null(dcCore::app()->blog) || dcCore::app()->url->type != 'default') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$blog_url = Html::escapeJS(
|
||||||
|
dcCore::app()->blog->url .
|
||||||
|
dcCore::app()->url->getBase('zoneclearFeedsPage') .
|
||||||
|
'/zcfsupd'
|
||||||
|
);
|
||||||
|
$blog_id = Html::escapeJS(dcCore::app()->blog->id);
|
||||||
|
|
||||||
|
echo
|
||||||
|
"\n<!-- JS for zoneclearFeedServer --> \n" .
|
||||||
|
dcUtils::jsLoad(dcCore::app()->blog->url . dcCore::app()->url->getBase('zoneclearFeedsPage') . '/zcfsupd.js') .
|
||||||
|
"<script type=\"text/javascript\"> \n//<![CDATA[\n" .
|
||||||
|
' $(function(){if(!document.getElementById){return;} ' .
|
||||||
|
" $('body').zoneclearFeedServer({blog_url:'" .
|
||||||
|
$blog_url . "',blog_id:'" . $blog_id . "'}); " .
|
||||||
|
" })\n" .
|
||||||
|
"//]]>\n</script>\n";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
101
src/Install.php
101
src/Install.php
|
@ -10,56 +10,75 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
// Check module version
|
|
||||||
if (!dcCore::app()->newVersion(
|
use dcCore;
|
||||||
basename(__DIR__),
|
use dcNsProcess;
|
||||||
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
|
use Dotclear\Database\Structure;
|
||||||
)) {
|
use Exception;
|
||||||
return null;
|
|
||||||
|
/**
|
||||||
|
* Module installation.
|
||||||
|
*/
|
||||||
|
class Install extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
if (defined('DC_CONTEXT_ADMIN') && My::phpCompliant()) {
|
||||||
|
$version = dcCore::app()->plugins->moduleInfo(My::id(), 'version');
|
||||||
|
static::$init = is_string($version) ? dcCore::app()->newVersion(My::id(), $version) : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
// Upgrade existing install
|
// Upgrade existing install
|
||||||
zcfsUpgrade::preUpgrade();
|
Upgrade::preUpgrade();
|
||||||
|
|
||||||
// Tables
|
// Tables
|
||||||
$t = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
|
$s = new Structure(dcCore::app()->con, dcCore::app()->prefix);
|
||||||
$t->{initZoneclearFeedServer::TABLE_NAME}
|
$s->__get(My::TABLE_NAME)
|
||||||
->feed_id('bigint', 0, false)
|
->field('feed_id', 'bigint', 0, false)
|
||||||
->feed_creadt('timestamp', 0, false, 'now()')
|
->field('feed_creadt', 'timestamp', 0, false, 'now()')
|
||||||
->feed_upddt('timestamp', 0, false, 'now()')
|
->field('feed_upddt', 'timestamp', 0, false, 'now()')
|
||||||
->feed_type('varchar', 32, false, "'feed'")
|
->field('feed_type', 'varchar', 32, false, "'feed'")
|
||||||
->blog_id('varchar', 32, false)
|
->field('blog_id', 'varchar', 32, false)
|
||||||
->cat_id('bigint', 0, true)
|
->field('cat_id', 'bigint', 0, true)
|
||||||
->feed_upd_int('integer', 0, false, 3600)
|
->field('feed_upd_int', 'integer', 0, false, 3600)
|
||||||
->feed_upd_last('integer', 0, false, 0)
|
->field('feed_upd_last', 'integer', 0, false, 0)
|
||||||
->feed_status('smallint', 0, false, 0)
|
->field('feed_status', 'smallint', 0, false, 0)
|
||||||
->feed_name('varchar', 255, false)
|
->field('feed_name', 'varchar', 255, false)
|
||||||
->feed_desc('text', null, true) //!pgsql reserved 'desc'
|
->field('feed_desc', 'text', null, true) //!pgsql reserved 'desc'
|
||||||
->feed_url('varchar', 255, false)
|
->field('feed_url', 'varchar', 255, false)
|
||||||
->feed_feed('varchar', 255, false)
|
->field('feed_feed', 'varchar', 255, false)
|
||||||
->feed_tags('varchar', 255, true)
|
->field('feed_tags', 'varchar', 255, true)
|
||||||
->feed_get_tags('smallint', 0, false, 1)
|
->field('feed_get_tags', 'smallint', 0, false, 1)
|
||||||
->feed_owner('varchar', 255, false)
|
->field('feed_owner', 'varchar', 255, false)
|
||||||
->feed_tweeter('varchar', 64, false) // tweeter ident
|
->field('feed_tweeter', 'varchar', 64, false) // tweeter ident
|
||||||
->feed_lang('varchar', 5, true)
|
->field('feed_lang', 'varchar', 5, true)
|
||||||
->feed_nb_out('integer', 0, false, 0)
|
->field('feed_nb_out', 'integer', 0, false, 0)
|
||||||
->feed_nb_in('integer', 0, false, 0)
|
->field('feed_nb_in', 'integer', 0, false, 0)
|
||||||
|
|
||||||
->primary('pk_zcfs', 'feed_id')
|
->primary('pk_zcfs', 'feed_id')
|
||||||
->index('idx_zcfs_type', 'btree', 'feed_type')
|
->index('idx_zcfs_type', 'btree', 'feed_type')
|
||||||
->index('idx_zcfs_blog', 'btree', 'blog_id');
|
->index('idx_zcfs_blog', 'btree', 'blog_id');
|
||||||
|
|
||||||
$ti = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
|
(new Structure(dcCore::app()->con, dcCore::app()->prefix))->synchronize($s);
|
||||||
$changes = $ti->synchronize($t);
|
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
dcCore::app()->blog->settings->addNamespace(basename(__DIR__));
|
$s = dcCore::app()->blog?->settings->get(My::id());
|
||||||
$s = dcCore::app()->blog->settings->__get(basename(__DIR__));
|
if (is_null($s)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$s->put('active', false, 'boolean', 'Enable zoneclearBlogServer', false, true);
|
$s->put('active', false, 'boolean', 'Enable zoneclearBlogServer', false, true);
|
||||||
$s->put('pub_active', false, 'boolean', 'Enable public page of list of feeds', false, true);
|
$s->put('pub_active', false, 'boolean', 'Enable public page of list of feeds', false, true);
|
||||||
$s->put('post_status_new', true, 'boolean', 'Enable auto publish new posts', false, true);
|
$s->put('post_status_new', true, 'boolean', 'Enable auto publish new posts', false, true);
|
||||||
|
@ -68,12 +87,14 @@ try {
|
||||||
$s->put('keep_empty_feed', false, 'boolean', 'Keep active empty feeds', false, true);
|
$s->put('keep_empty_feed', false, 'boolean', 'Keep active empty feeds', false, true);
|
||||||
$s->put('tag_case', 0, 'integer', 'How to transform imported tags', false, true);
|
$s->put('tag_case', 0, 'integer', 'How to transform imported tags', false, true);
|
||||||
$s->put('user', '', 'string', 'User id that has right on post', false, true);
|
$s->put('user', '', 'string', 'User id that has right on post', false, true);
|
||||||
$s->put('post_full_tpl', json_encode(['post', 'category', 'tag', 'archive']), 'string', 'List of templates types for full feed', false, true);
|
$s->put('post_full_tpl', ['post', 'category', 'tag', 'archive'], 'array', 'List of templates types for full feed', false, true);
|
||||||
$s->put('post_title_redir', json_encode(['feed']), 'string', 'List of templates types for redirection to original post', false, true);
|
$s->put('post_title_redir', ['feed'], 'array', 'List of templates types for redirection to original post', false, true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
665
src/Manage.php
665
src/Manage.php
|
@ -10,557 +10,204 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 !== dcCore::app()->testVersion(
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
basename(__DIR__),
|
|
||||||
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
|
|
||||||
)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::check(dcCore::app()->auth->makePermissions([
|
use adminGenericFilterV2;
|
||||||
dcAuth::PERMISSION_CONTENT_ADMIN,
|
use dcAdminFilters;
|
||||||
]));
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Div,
|
||||||
|
Form,
|
||||||
|
Label,
|
||||||
|
Link,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Submit,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
$zcfs = new zoneclearFeedServer();
|
/**
|
||||||
|
* Backend feeds list manage page.
|
||||||
|
*/
|
||||||
|
class Manage extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init == defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& !is_null(dcCore::app()->auth)
|
||||||
|
&& !is_null(dcCore::app()->blog)
|
||||||
|
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
]), dcCore::app()->blog->id);
|
||||||
|
|
||||||
|
// call period manage page
|
||||||
|
if (($_REQUEST['part'] ?? 'feeds') === 'feed') {
|
||||||
|
static::$init = ManageFeed::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$s = $z->settings;
|
||||||
|
|
||||||
|
// not configured
|
||||||
|
if (!$s->active || !$s->user) {
|
||||||
|
dcCore::app()->error->add(__('Module is not wel configured'));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call period manage page
|
||||||
|
if (($_REQUEST['part'] ?? 'feeds') === 'feed') {
|
||||||
|
return ManageFeed::process();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null(dcCore::app()->adminurl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$s = $z->settings;
|
||||||
|
|
||||||
|
// not configured
|
||||||
|
if (!$s->active || !$s->user) {
|
||||||
|
dcPage::openModule(My::id());
|
||||||
|
|
||||||
# Not configured
|
|
||||||
if (!dcCore::app()->blog->settings->__get(basename(__DIR__))->active
|
|
||||||
|| !dcCore::app()->blog->settings->__get(basename(__DIR__))->user
|
|
||||||
) {
|
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Feeds server') . '</title></head><body>' .
|
|
||||||
dcPage::breadcrumb([
|
dcPage::breadcrumb([
|
||||||
__('Plugins') => '',
|
__('Plugins') => '',
|
||||||
__('Feeds server') => '',
|
My::name() => '',
|
||||||
]) .
|
]) .
|
||||||
dcPage::notices();
|
dcPage::notices();
|
||||||
|
|
||||||
############################################################
|
dcPage::closeModule();
|
||||||
#
|
|
||||||
# One feed
|
|
||||||
#
|
|
||||||
############################################################
|
|
||||||
} elseif (isset($_REQUEST['part']) && $_REQUEST['part'] == 'feed') {
|
|
||||||
$feed_id = '';
|
|
||||||
$feed_name = '';
|
|
||||||
$feed_desc = '';
|
|
||||||
$feed_owner = '';
|
|
||||||
$feed_tweeter = '';
|
|
||||||
$feed_url = '';
|
|
||||||
$feed_feed = '';
|
|
||||||
$feed_lang = dcCore::app()->auth->getInfo('user_lang');
|
|
||||||
$feed_tags = '';
|
|
||||||
$feed_get_tags = '0';
|
|
||||||
$feed_cat_id = '';
|
|
||||||
$feed_status = '0';
|
|
||||||
$feed_upd_int = 3600;
|
|
||||||
|
|
||||||
$can_view_page = true;
|
return;
|
||||||
|
|
||||||
$feed_headlink = '<link rel="%s" title="%s" href="' . dcCore::app()->admin->getPageURL() . '&part=feed&feed_id=%s" />';
|
|
||||||
$feed_link = '<a href="' . dcCore::app()->admin->getPageURL() . '&part=feed&feed_id=%s" title="%s">%s</a>';
|
|
||||||
|
|
||||||
$next_link = $prev_link = $next_headlink = $prev_headlink = null;
|
|
||||||
|
|
||||||
# Combos
|
|
||||||
$combo_langs = l10n::getISOcodes(true);
|
|
||||||
$combo_status = $zcfs->getAllStatus();
|
|
||||||
$combo_upd_int = $zcfs->getAllUpdateInterval();
|
|
||||||
$combo_categories = ['-' => ''];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$categories = dcCore::app()->blog->getCategories(['post_type' => 'post']);
|
|
||||||
while ($categories->fetch()) {
|
|
||||||
$combo_categories[
|
|
||||||
str_repeat(' ', $categories->level - 1) .
|
|
||||||
'• ' . html::escapeHTML($categories->cat_title)
|
|
||||||
] = $categories->cat_id;
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get entry informations
|
// call feed manage page
|
||||||
if (!empty($_REQUEST['feed_id'])) {
|
if (($_REQUEST['part'] ?? 'feeds') === 'feed') {
|
||||||
$feed = $zcfs->getFeeds(['feed_id' => $_REQUEST['feed_id']]);
|
ManageFeed::render();
|
||||||
|
|
||||||
if ($feed->isEmpty()) {
|
return;
|
||||||
dcCore::app()->error->add(__('This feed does not exist.'));
|
|
||||||
$can_view_page = false;
|
|
||||||
} else {
|
|
||||||
$feed_id = $feed->feed_id;
|
|
||||||
$feed_name = $feed->feed_name;
|
|
||||||
$feed_desc = $feed->feed_desc;
|
|
||||||
$feed_owner = $feed->feed_owner;
|
|
||||||
$feed_tweeter = $feed->feed_tweeter;
|
|
||||||
$feed_url = $feed->feed_url;
|
|
||||||
$feed_feed = $feed->feed_feed;
|
|
||||||
$feed_lang = $feed->feed_lang;
|
|
||||||
$feed_tags = $feed->feed_tags;
|
|
||||||
$feed_get_tags = $feed->feed_get_tags;
|
|
||||||
$feed_cat_id = $feed->cat_id;
|
|
||||||
$feed_status = $feed->feed_status;
|
|
||||||
$feed_upd_int = $feed->feed_upd_int;
|
|
||||||
|
|
||||||
$next_params = [
|
|
||||||
'sql' => 'AND feed_id < ' . $feed_id . ' ',
|
|
||||||
'limit' => 1,
|
|
||||||
];
|
|
||||||
$next_rs = $zcfs->getFeeds($next_params);
|
|
||||||
$prev_params = [
|
|
||||||
'sql' => 'AND feed_id > ' . $feed_id . ' ',
|
|
||||||
'limit' => 1,
|
|
||||||
];
|
|
||||||
$prev_rs = $zcfs->getFeeds($prev_params);
|
|
||||||
|
|
||||||
if (!$next_rs->isEmpty()) {
|
|
||||||
$next_link = sprintf(
|
|
||||||
$feed_link,
|
|
||||||
$next_rs->feed_id,
|
|
||||||
html::escapeHTML($next_rs->feed_name),
|
|
||||||
__('next feed') . ' »'
|
|
||||||
);
|
|
||||||
$next_headlink = sprintf(
|
|
||||||
$feed_headlink,
|
|
||||||
'next',
|
|
||||||
html::escapeHTML($next_rs->feed_name),
|
|
||||||
$next_rs->feed_id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$prev_rs->isEmpty()) {
|
// feeds actions
|
||||||
$prev_link = sprintf(
|
$feeds_actions_page = new FeedsActions(
|
||||||
$feed_link,
|
|
||||||
$prev_rs->feed_id,
|
|
||||||
html::escapeHTML($prev_rs->feed_name),
|
|
||||||
'« ' . __('previous feed')
|
|
||||||
);
|
|
||||||
$prev_headlink = sprintf(
|
|
||||||
$feed_headlink,
|
|
||||||
'previous',
|
|
||||||
html::escapeHTML($prev_rs->feed_name),
|
|
||||||
$prev_rs->feed_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_POST['action']) && $_POST['action'] == 'savefeed') {
|
|
||||||
try {
|
|
||||||
$feed_name = $_POST['feed_name'];
|
|
||||||
$feed_desc = $_POST['feed_desc'];
|
|
||||||
$feed_owner = $_POST['feed_owner'];
|
|
||||||
$feed_tweeter = $_POST['feed_tweeter'];
|
|
||||||
$feed_url = $_POST['feed_url'];
|
|
||||||
$feed_feed = $_POST['feed_feed'];
|
|
||||||
$feed_lang = $_POST['feed_lang'];
|
|
||||||
$feed_tags = $_POST['feed_tags'];
|
|
||||||
$feed_get_tags = empty($_POST['feed_get_tags']) ? 0 : 1;
|
|
||||||
$feed_cat_id = $_POST['feed_cat_id'] !== '' ? $_POST['feed_cat_id'] : null;
|
|
||||||
$feed_upd_int = $_POST['feed_upd_int'];
|
|
||||||
if (isset($_POST['feed_status'])) {
|
|
||||||
$feed_status = (int) $_POST['feed_status'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$testfeed_params['feed_feed'] = $feed_feed;
|
|
||||||
if ($feed_id) {
|
|
||||||
$testfeed_params['sql'] = 'AND feed_id <> ' . $feed_id . ' ';
|
|
||||||
}
|
|
||||||
if ($zcfs->getFeeds($testfeed_params, true)->f(0)) {
|
|
||||||
throw new Exception(__('Record with same feed URL already exists.'));
|
|
||||||
}
|
|
||||||
if (empty($feed_name)) {
|
|
||||||
throw new Exception(__('You must provide a name.'));
|
|
||||||
}
|
|
||||||
if (empty($feed_owner)) {
|
|
||||||
throw new Exception(__('You must provide an owner.'));
|
|
||||||
}
|
|
||||||
if (!zoneclearFeedServer::validateURL($feed_url)) {
|
|
||||||
throw new Exception(__('You must provide valid site URL.'));
|
|
||||||
}
|
|
||||||
if (!zoneclearFeedServer::validateURL($feed_feed)) {
|
|
||||||
throw new Exception(__('You must provide valid feed URL.'));
|
|
||||||
}
|
|
||||||
if (null === $feed_cat_id && !dcCore::app()->blog->getCategory((int) $feed_cat_id)) {
|
|
||||||
throw new Exception(__('You must provide valid category.'));
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($_POST['action']) && $_POST['action'] == 'savefeed' && !dcCore::app()->error->flag()) {
|
|
||||||
$cur = $zcfs->openCursor();
|
|
||||||
$cur->feed_name = $feed_name;
|
|
||||||
$cur->feed_desc = $feed_desc;
|
|
||||||
$cur->feed_owner = $feed_owner;
|
|
||||||
$cur->feed_tweeter = $feed_tweeter;
|
|
||||||
$cur->feed_url = $feed_url;
|
|
||||||
$cur->feed_feed = $feed_feed;
|
|
||||||
$cur->feed_lang = $feed_lang;
|
|
||||||
$cur->feed_tags = $feed_tags;
|
|
||||||
$cur->feed_get_tags = (int) $feed_get_tags;
|
|
||||||
$cur->cat_id = null === $feed_cat_id ? null : (int) $feed_cat_id;
|
|
||||||
$cur->feed_status = (int) $feed_status;
|
|
||||||
$cur->feed_upd_int = (int) $feed_upd_int;
|
|
||||||
|
|
||||||
# Update feed
|
|
||||||
if ($feed_id) {
|
|
||||||
try {
|
|
||||||
# --BEHAVIOR-- adminBeforeZoneclearFeedServerFeedUpdate
|
|
||||||
dcCore::app()->callBehavior('adminBeforeZoneclearFeedServerFeedUpdate', $cur, $feed_id);
|
|
||||||
|
|
||||||
$zcfs->updFeed($feed_id, $cur);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterZoneclearFeedServerFeedUpdate
|
|
||||||
dcCore::app()->callBehavior('adminAfterZoneclearFeedServerFeedUpdate', $cur, $feed_id);
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
|
||||||
__('Feed successfully updated.')
|
|
||||||
);
|
|
||||||
dcCore::app()->adminurl->redirect(
|
|
||||||
'admin.plugin.' . basename(__DIR__),
|
|
||||||
['part' => 'feed', 'feed_id' => $feed_id]
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
# --BEHAVIOR-- adminBeforeZoneclearFeedServerFeedCreate
|
|
||||||
dcCore::app()->callBehavior('adminBeforeZoneclearFeedServerFeedCreate', $cur);
|
|
||||||
|
|
||||||
$return_id = $zcfs->addFeed($cur);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminAfterZoneclearFeedServerFeedCreate
|
|
||||||
dcCore::app()->callBehavior('adminAfterZoneclearFeedServerFeedCreate', $cur, $return_id);
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
|
||||||
__('Feed successfully created.')
|
|
||||||
);
|
|
||||||
dcCore::app()->adminurl->redirect(
|
|
||||||
'admin.plugin.' . basename(__DIR__),
|
|
||||||
['part' => 'feed', 'feed_id' => $return_id]
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Prepared entries list
|
|
||||||
if ($feed_id && $can_view_page) {
|
|
||||||
# action
|
|
||||||
$posts_actions_page = new dcPostsActions(
|
|
||||||
'plugin.php',
|
'plugin.php',
|
||||||
[
|
['p' => My::id(), 'part' => 'feeds']
|
||||||
'p' => basename(__DIR__),
|
|
||||||
'part' => 'feed',
|
|
||||||
'feed_id' => $feed_id,
|
|
||||||
'_ANCHOR' => 'entries',
|
|
||||||
]
|
|
||||||
);
|
|
||||||
if ($posts_actions_page->process()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
# filters
|
|
||||||
$post_filter = new zcfsPostFilter();
|
|
||||||
$post_filter->add('part', 'feed');
|
|
||||||
$post_filter->add('feed_id', $feed_id);
|
|
||||||
$params = $post_filter->params();
|
|
||||||
|
|
||||||
# lexical sort
|
|
||||||
$sortby_lex = [
|
|
||||||
// key in sorty_combo (see above) => field in SQL request
|
|
||||||
'post_title' => 'post_title',
|
|
||||||
'cat_title' => 'cat_title',
|
|
||||||
'user_id' => 'P.user_id', ];
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminPostsSortbyLexCombo
|
|
||||||
dcCore::app()->callBehavior('adminPostsSortbyLexCombo', [& $sortby_lex]);
|
|
||||||
|
|
||||||
$params['no_content'] = true;
|
|
||||||
$params['feed_id'] = $feed_id;
|
|
||||||
$params['order'] = (array_key_exists($post_filter->sortby, $sortby_lex) ?
|
|
||||||
dcCore::app()->con->lexFields($sortby_lex[$post_filter->sortby]) :
|
|
||||||
$post_filter->sortby) . ' ' . $post_filter->order;
|
|
||||||
|
|
||||||
# posts
|
|
||||||
try {
|
|
||||||
$posts = $zcfs->getPostsByFeed($params);
|
|
||||||
$counter = $zcfs->getPostsByFeed($params, true);
|
|
||||||
$post_list = new zcfsEntriesList(
|
|
||||||
dcCore::app(),
|
|
||||||
$posts,
|
|
||||||
$counter->f(0)
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# display
|
|
||||||
echo
|
|
||||||
'<html><head><title>' . __('Feeds server') . '</title>' .
|
|
||||||
($feed_id && isset($post_filter) && !dcCore::app()->error->flag() ?
|
|
||||||
$post_filter->js(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['part' => 'feed', 'feed_id' => $feed_id], '&') . '#entries') .
|
|
||||||
dcPage::jsLoad(dcPage::getPF(basename(__DIR__) . '/js/list.js'))
|
|
||||||
: '') .
|
|
||||||
dcPage::jsPageTabs() .
|
|
||||||
$next_headlink . "\n" . $prev_headlink .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminZoneclearFeedServerHeader
|
|
||||||
dcCore::app()->callBehavior('adminZoneclearFeedServerHeader') .
|
|
||||||
|
|
||||||
'</head><body>' .
|
|
||||||
|
|
||||||
dcPage::breadcrumb([
|
|
||||||
__('Plugins') => '',
|
|
||||||
__('Feeds server') => dcCore::app()->admin->getPageURL(),
|
|
||||||
($feed_id ? __('Edit feed') : __('New feed')) => '',
|
|
||||||
]) .
|
|
||||||
dcPage::notices() .
|
|
||||||
($feed_id ? '<h3>' . sprintf(__('Edit feed "%s"'), $feed_name) . '</h3>' : '');
|
|
||||||
|
|
||||||
# Feed
|
|
||||||
if ($can_view_page) {
|
|
||||||
# nav link
|
|
||||||
if ($feed_id && ($next_link || $prev_link)) {
|
|
||||||
echo '<p class="nav_prevnext">';
|
|
||||||
if ($prev_link) {
|
|
||||||
echo $prev_link;
|
|
||||||
}
|
|
||||||
if ($next_link && $prev_link) {
|
|
||||||
echo ' | ';
|
|
||||||
}
|
|
||||||
if ($next_link) {
|
|
||||||
echo $next_link;
|
|
||||||
}
|
|
||||||
echo '</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '
|
|
||||||
<div' . ($feed_id ? ' class="multi-part" title="' . __('Feed') . '"' : '') . ' id="edit-entry">
|
|
||||||
<form method="post" action="plugin.php">
|
|
||||||
|
|
||||||
<div class="two-cols">' .
|
|
||||||
|
|
||||||
'<div class="col70">' .
|
|
||||||
'<h4>' . __('Feed information') . '</h4>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_name" class="required">
|
|
||||||
<abbr title="' . __('Required field') . '">*</abbr>' .
|
|
||||||
__('Name:') . '</label>' .
|
|
||||||
form::field('feed_name', 60, 255, $feed_name, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_owner" class="required">
|
|
||||||
<abbr title="' . __('Required field') . '">*</abbr>' .
|
|
||||||
__('Owner:') . '</label>' .
|
|
||||||
form::field('feed_owner', 60, 255, $feed_owner, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
// move this away
|
|
||||||
'<p><label for="feed_tweeter">' .
|
|
||||||
__('Tweeter or Identica ident:') . '</label>' .
|
|
||||||
form::field('feed_tweeter', 60, 64, $feed_tweeter, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_url" class="required">
|
|
||||||
<abbr title="' . __('Required field') . '">*</abbr>' .
|
|
||||||
__('Site URL:') . '</label>' .
|
|
||||||
form::field('feed_url', 60, 255, $feed_url, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_feed" class="required">
|
|
||||||
<abbr title="' . __('Required field') . '">*</abbr>' .
|
|
||||||
__('Feed URL:') . '</label>' .
|
|
||||||
form::field('feed_feed', 60, 255, $feed_feed, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_desc">' . __('Description:') . '</label>' .
|
|
||||||
form::field('feed_desc', 60, 255, $feed_desc, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_tags">' . __('Tags:') . '</label>' .
|
|
||||||
form::field('feed_tags', 60, 255, $feed_tags, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminZoneclearFeedServerFeedForm
|
|
||||||
dcCore::app()->callBehavior('adminZoneclearFeedServerFeedForm', $feed_id) .
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<div class="col30">' .
|
|
||||||
'<h4>' . __('Local settings') . '</h4>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_cat_id">' . __('Category:') . '</label>' .
|
|
||||||
form::combo('feed_cat_id', $combo_categories, $feed_cat_id, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_status">' . __('Status:') . '</label>' .
|
|
||||||
form::combo('feed_status', $combo_status, $feed_status, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_upd_int">' . __('Update:') . '</label>' .
|
|
||||||
form::combo('feed_upd_int', $combo_upd_int, $feed_upd_int, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_lang">' . __('Lang:') . '</label>' .
|
|
||||||
form::combo('feed_lang', $combo_langs, $feed_lang, 'maximal') .
|
|
||||||
'</p>' .
|
|
||||||
|
|
||||||
'<p><label for="feed_get_tags" class="classic">' .
|
|
||||||
form::checkbox('feed_get_tags', 1, $feed_get_tags) .
|
|
||||||
__('Import tags from feed') . '</label></p>' .
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'</div>' .
|
|
||||||
|
|
||||||
'<p class="clear">
|
|
||||||
<input type="submit" name="save" value="' . __('Save') . ' (s)" accesskey="s"/>' .
|
|
||||||
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . basename(__DIR__), [
|
|
||||||
'part' => 'feed',
|
|
||||||
'feed_id' => $feed_id,
|
|
||||||
'action' => 'savefeed',
|
|
||||||
]) .
|
|
||||||
dcCore::app()->formNonce() .
|
|
||||||
'</p>
|
|
||||||
</form>
|
|
||||||
</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
# entries
|
|
||||||
if ($feed_id && $can_view_page && isset($post_filter) && isset($post_list) && isset($posts_actions_page) && !dcCore::app()->error->flag()) {
|
|
||||||
echo '<div class="multi-part" title="' . __('Entries') . '" id="entries">';
|
|
||||||
|
|
||||||
# show filters
|
|
||||||
$post_filter->display(
|
|
||||||
['admin.plugin.' . basename(__DIR__),'#entries'],
|
|
||||||
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . basename(__DIR__), [
|
|
||||||
'part' => 'feed',
|
|
||||||
'feed_id' => $feed_id,
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
# fix pager url
|
|
||||||
$args = $post_filter->values();
|
|
||||||
unset($args['page']);
|
|
||||||
$args['page'] = '%s';
|
|
||||||
|
|
||||||
# show posts
|
|
||||||
$post_list->display(
|
|
||||||
$post_filter->page,
|
|
||||||
$post_filter->nb,
|
|
||||||
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), $args, '&') . '#entries',
|
|
||||||
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['part' => 'feed']) . '#entries" method="post" id="form-entries">' .
|
|
||||||
'%s' .
|
|
||||||
|
|
||||||
'<div class="two-cols">' .
|
|
||||||
'<p class="col checkboxes-helpers"></p>' .
|
|
||||||
|
|
||||||
'<p class="col right">' . __('Selected entries action:') . ' ' .
|
|
||||||
form::combo('action', $posts_actions_page->getCombo()) .
|
|
||||||
'<input type="submit" name="save" value="' . __('ok') . '" /></p>' .
|
|
||||||
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . basename(__DIR__), $post_filter->values()) .
|
|
||||||
form::hidden('redir', dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), $post_filter->values())) .
|
|
||||||
dcCore::app()->formNonce() .
|
|
||||||
'</div>' .
|
|
||||||
'</form>',
|
|
||||||
$post_filter->show()
|
|
||||||
);
|
|
||||||
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
############################################################
|
|
||||||
#
|
|
||||||
# All feeds
|
|
||||||
#
|
|
||||||
############################################################
|
|
||||||
} else {
|
|
||||||
# actions
|
|
||||||
$feeds_actions_page = new zcfsFeedsActions(
|
|
||||||
'plugin.php',
|
|
||||||
['p' => basename(__DIR__), 'part' => 'feeds']
|
|
||||||
);
|
);
|
||||||
if ($feeds_actions_page->process()) {
|
if ($feeds_actions_page->process()) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# filters
|
// feeds filters
|
||||||
$feeds_filter = new adminGenericFilter(dcCore::app(), 'zcfs_feeds');
|
$feeds_filter = new adminGenericFilterV2(My::id() . 'feeds');
|
||||||
$feeds_filter->add('part', 'feeds');
|
$feeds_filter->add('part', 'feeds');
|
||||||
$feeds_filter->add(dcAdminFilters::getPageFilter());
|
$feeds_filter->add(dcAdminFilters::getPageFilter());
|
||||||
$feeds_filter->add(dcAdminFilters::getSearchFilter());
|
$feeds_filter->add(dcAdminFilters::getSearchFilter());
|
||||||
$params = $feeds_filter->params();
|
$params = $feeds_filter->params();
|
||||||
|
|
||||||
# feeds
|
// feeds list
|
||||||
try {
|
try {
|
||||||
$feeds = $zcfs->getFeeds($params);
|
$feeds = $z->getFeeds($params);
|
||||||
$feeds_counter = $zcfs->getFeeds($params, true)->f(0);
|
$feeds_counter = $z->getFeeds($params, true)->f(0);
|
||||||
$feeds_list = new zcfsFeedsList(
|
$feeds_list = new FeedsList($feeds, $feeds_counter);
|
||||||
dcCore::app(),
|
|
||||||
$feeds,
|
|
||||||
$feeds_counter
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
dcCore::app()->error->add($e->getMessage());
|
dcCore::app()->error->add($e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
# display
|
dcPage::openModule(
|
||||||
|
My::id(),
|
||||||
|
(
|
||||||
|
isset($feeds_list) && !dcCore::app()->error->flag() ?
|
||||||
|
$feeds_filter->js(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'feeds'], '&')) .
|
||||||
|
dcPage::jsModuleLoad(My::id() . '/js/list.js')
|
||||||
|
: ''
|
||||||
|
) .
|
||||||
|
dcPage::jsPageTabs()
|
||||||
|
);
|
||||||
|
|
||||||
echo
|
echo
|
||||||
'<html><head><title>' . __('Feeds server') . '</title>' .
|
|
||||||
$feeds_filter->js(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['part' => 'feeds'], '&')) .
|
|
||||||
dcPage::jsLoad(dcPage::getPF(basename(__DIR__) . '/js/list.js')) .
|
|
||||||
dcPage::jsPageTabs() .
|
|
||||||
|
|
||||||
# --BEHAVIOR-- adminZoneclearFeedServerHeader
|
|
||||||
dcCore::app()->callBehavior('adminZoneclearFeedServerHeader') .
|
|
||||||
|
|
||||||
'</head><body>' .
|
|
||||||
|
|
||||||
dcPage::breadcrumb([
|
dcPage::breadcrumb([
|
||||||
__('Plugins') => '',
|
__('Plugins') => '',
|
||||||
__('Feeds server') => '',
|
My::name() => dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||||
|
__('Feeds list') => '',
|
||||||
]) .
|
]) .
|
||||||
dcPage::notices();
|
dcPage::notices();
|
||||||
|
|
||||||
if (isset($feeds_list)) {
|
|
||||||
echo
|
echo
|
||||||
'<p class="top-add">' .
|
(new Para())
|
||||||
'<a class="button add" href="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['part' => 'feed']) . '">' .
|
->class('top-add')
|
||||||
__('New feed') . '</a></p>';
|
->items([
|
||||||
|
(new Link())
|
||||||
|
->class('button add')
|
||||||
|
->text(__('New feed'))
|
||||||
|
->href((string) dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'feed'])),
|
||||||
|
])
|
||||||
|
->render();
|
||||||
|
|
||||||
|
if (isset($feeds_list)) {
|
||||||
$feeds_filter->display(
|
$feeds_filter->display(
|
||||||
'admin.plugin.' . basename(__DIR__),
|
'admin.plugin.' . My::id(),
|
||||||
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . basename(__DIR__), ['part' => 'feeds'])
|
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . My::id(), ['part' => 'feeds'])
|
||||||
);
|
);
|
||||||
|
|
||||||
$feeds_list->feedsDisplay(
|
$feeds_list->display(
|
||||||
$feeds_filter->page,
|
$feeds_filter,
|
||||||
$feeds_filter->nb,
|
(new Form('form-feeds'))
|
||||||
'<form action="' . dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['part' => 'feeds']) . '" method="post" id="form-actions">' .
|
->method('post')
|
||||||
'%s' .
|
->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'feeds']))
|
||||||
'<div class="two-cols">' .
|
->fields([
|
||||||
'<p class="col checkboxes-helpers"></p>' .
|
(new Text('', '%s')),
|
||||||
'<p class="col right">' . __('Selected feeds action:') . ' ' .
|
(new Div())
|
||||||
form::combo(['action'], $feeds_actions_page->getCombo()) .
|
->class('two-cols')
|
||||||
'<input type="submit" value="' . __('ok') . '" />' .
|
->items([
|
||||||
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . basename(__DIR__), $feeds_filter->values(true)) .
|
(new Para())
|
||||||
dcCore::app()->formNonce() .
|
->class('col checkboxes-helpers'),
|
||||||
'</p>' .
|
(new Para())
|
||||||
'</div>' .
|
->class('col right')
|
||||||
'</form>',
|
->items(array_merge(
|
||||||
$feeds_filter->show()
|
dcCore::app()->adminurl->hiddenFormFields('admin.plugin.' . My::id(), $feeds_filter->values(true)),
|
||||||
|
[
|
||||||
|
(new Label(__('Selected feeds action:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('action'),
|
||||||
|
(new Select('action'))
|
||||||
|
->items($feeds_actions_page->getCombo()),
|
||||||
|
(new Submit('feeds-action'))
|
||||||
|
->value(__('ok')),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
echo '</body></html>';
|
dcPage::closeModule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
463
src/ManageFeed.php
Normal file
463
src/ManageFeed.php
Normal file
|
@ -0,0 +1,463 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use dcPage;
|
||||||
|
use dcPostsActions;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Form,
|
||||||
|
Hidden,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Submit,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Dotclear\Helper\L10n;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend feed and feed posts manage page.
|
||||||
|
*/
|
||||||
|
class ManageFeed extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init == defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& !is_null(dcCore::app()->auth) && !is_null(dcCore::app()->blog)
|
||||||
|
&& dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcCore::app()->auth::PERMISSION_CONTENT_ADMIN,
|
||||||
|
]), dcCore::app()->blog->id)
|
||||||
|
&& ($_REQUEST['part'] ?? 'feeds') === 'feed';
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no action
|
||||||
|
if (empty($_POST['action'])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$s = $z->settings;
|
||||||
|
$v = ManageFeedVars::instance();
|
||||||
|
|
||||||
|
// save feed
|
||||||
|
if ($_POST['action'] == 'savefeed') {
|
||||||
|
// check values
|
||||||
|
$testfeed_params['feed_feed'] = $v->feed;
|
||||||
|
if ($v->id) {
|
||||||
|
$testfeed_params['sql'] = 'AND feed_id <> ' . $v->id . ' ';
|
||||||
|
}
|
||||||
|
if ($z->getFeeds($testfeed_params, true)->f(0)) {
|
||||||
|
dcCore::app()->error->add(__('Record with same feed URL already exists.'));
|
||||||
|
}
|
||||||
|
if (empty($v->name)) {
|
||||||
|
dcCore::app()->error->add(__('You must provide a name.'));
|
||||||
|
}
|
||||||
|
if (empty($v->owner)) {
|
||||||
|
dcCore::app()->error->add(__('You must provide an owner.'));
|
||||||
|
}
|
||||||
|
if (!$z::validateURL($v->url)) {
|
||||||
|
dcCore::app()->error->add(__('You must provide valid site URL.'));
|
||||||
|
}
|
||||||
|
if (!$z::validateURL($v->feed)) {
|
||||||
|
dcCore::app()->error->add(__('You must provide valid feed URL.'));
|
||||||
|
}
|
||||||
|
if (null !== $v->cat_id && !dcCore::app()->blog?->getCategory($v->cat_id)) {
|
||||||
|
dcCore::app()->error->add(__('You must provide valid category.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// check failed
|
||||||
|
if (dcCore::app()->error->flag()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save feed
|
||||||
|
try {
|
||||||
|
$id = $v->save();
|
||||||
|
if (!$id) {
|
||||||
|
throw new Exception(__('Failed to save feed.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::addSuccessNotice(
|
||||||
|
__('Feed successfully created.')
|
||||||
|
);
|
||||||
|
dcCore::app()->adminurl?->redirect(
|
||||||
|
'admin.plugin.' . My::id(),
|
||||||
|
['part' => 'feed', 'feed_id' => $id]
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null(dcCore::app()->adminurl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$s = $z->settings;
|
||||||
|
$v = ManageFeedVars::instance();
|
||||||
|
|
||||||
|
// Prepared entries list
|
||||||
|
if ($v->id && $v->can_view_page) {
|
||||||
|
// posts actions
|
||||||
|
$posts_actions_page = new dcPostsActions(
|
||||||
|
'plugin.php',
|
||||||
|
[
|
||||||
|
'p' => My::id(),
|
||||||
|
'part' => 'feed',
|
||||||
|
'feed_id' => $v->id,
|
||||||
|
'_ANCHOR' => 'entries',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
if ($posts_actions_page->process()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// posts filters
|
||||||
|
$post_filter = new PostsFilter();
|
||||||
|
$post_filter->add('part', 'feed');
|
||||||
|
$post_filter->add('feed_id', $v->id);
|
||||||
|
$params = $post_filter->params();
|
||||||
|
|
||||||
|
// typehint
|
||||||
|
$sortby = is_string($post_filter->value('sortby')) ? $post_filter->value('sortby') : 'post_creadt';
|
||||||
|
$order = is_string($post_filter->value('order')) ? $post_filter->value('order') : 'DESC';
|
||||||
|
|
||||||
|
# lexical sort
|
||||||
|
$sortby_lex = [
|
||||||
|
// key in sorty_combo (see above) => field in SQL request
|
||||||
|
'post_title' => 'post_title',
|
||||||
|
'cat_title' => 'cat_title',
|
||||||
|
'user_id' => 'P.user_id', ];
|
||||||
|
|
||||||
|
# --BEHAVIOR-- adminPostsSortbyLexCombo
|
||||||
|
dcCore::app()->callBehavior('adminPostsSortbyLexCombo', [& $sortby_lex]);
|
||||||
|
|
||||||
|
$params['no_content'] = true;
|
||||||
|
$params['feed_id'] = $v->id;
|
||||||
|
$params['order'] = (
|
||||||
|
array_key_exists($sortby, $sortby_lex) ?
|
||||||
|
dcCore::app()->con->lexFields($sortby_lex[$sortby]) :
|
||||||
|
$sortby
|
||||||
|
) . ' ' . $order;
|
||||||
|
|
||||||
|
# posts
|
||||||
|
try {
|
||||||
|
$posts = $z->getPostsByFeed($params);
|
||||||
|
$counter = $z->getPostsByFeed($params, true);
|
||||||
|
$post_list = new PostsList($posts, $counter->f(0));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// display
|
||||||
|
dcPage::openModule(
|
||||||
|
My::id(),
|
||||||
|
(
|
||||||
|
$v->id && isset($post_filter) && !dcCore::app()->error->flag() ?
|
||||||
|
$post_filter->js(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'feed', 'feed_id' => $v->id], '&') . '#entries') .
|
||||||
|
dcPage::jsModuleLoad(My::id() . '/js/list.js')
|
||||||
|
: ''
|
||||||
|
) .
|
||||||
|
dcPage::jsPageTabs() .
|
||||||
|
$v->next_headlink . "\n" . $v->prev_headlink
|
||||||
|
);
|
||||||
|
|
||||||
|
echo
|
||||||
|
dcPage::breadcrumb([
|
||||||
|
__('Plugins') => '',
|
||||||
|
My::name() => dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||||
|
($v->id ? __('Edit feed') : __('New feed')) => '',
|
||||||
|
]) .
|
||||||
|
dcPage::notices() .
|
||||||
|
(new Text('h3', ($v->id ? sprintf(__('Edit feed "%s"'), Html::escapeHTML($v->name)) : __('New feed'))))->render();
|
||||||
|
|
||||||
|
if ($v->can_view_page) {
|
||||||
|
# nav link
|
||||||
|
if ($v->id && ($v->next_link || $v->prev_link)) {
|
||||||
|
$text = '';
|
||||||
|
if ($v->prev_link) {
|
||||||
|
$text .= $v->prev_link;
|
||||||
|
}
|
||||||
|
if ($v->next_link && $v->prev_link) {
|
||||||
|
$text .= ' | ';
|
||||||
|
}
|
||||||
|
if ($v->next_link) {
|
||||||
|
$text .= $v->next_link;
|
||||||
|
}
|
||||||
|
echo (new Text('p', $text))->class('nav_prevnext')->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo
|
||||||
|
(new Div('edit-entry'))
|
||||||
|
->class($v->id ? 'multi-part' : '')
|
||||||
|
->title($v->id ? __('Feed') : '')
|
||||||
|
->items([
|
||||||
|
(new Form('edit-entry-form'))
|
||||||
|
->method('post')
|
||||||
|
->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))
|
||||||
|
->fields([
|
||||||
|
(new Div())
|
||||||
|
->class('two-cols')
|
||||||
|
->items([
|
||||||
|
(new Div())
|
||||||
|
->class('col70')
|
||||||
|
->items([
|
||||||
|
(new Text('h4', __('Feed information'))),
|
||||||
|
// feed_name
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Name:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->class('required')
|
||||||
|
->for('feed_name'),
|
||||||
|
(new Input('feed_name'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->name),
|
||||||
|
]),
|
||||||
|
// feed_owner
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Owner:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->class('required')
|
||||||
|
->for('feed_owner'),
|
||||||
|
(new Input('feed_owner'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->owner),
|
||||||
|
]),
|
||||||
|
// feed_url
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Site URL:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->class('required')
|
||||||
|
->for('feed_url'),
|
||||||
|
(new Input('feed_url'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->url),
|
||||||
|
]),
|
||||||
|
// feed_feed
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Feed URL:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->class('required')
|
||||||
|
->for('feed_feed'),
|
||||||
|
(new Input('feed_feed'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->feed),
|
||||||
|
]),
|
||||||
|
// feed_desc
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Description:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_desc'),
|
||||||
|
(new Input('feed_desc'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->desc),
|
||||||
|
]),
|
||||||
|
// feed_tags
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Tags:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_tags'),
|
||||||
|
(new Input('feed_tags'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->tags),
|
||||||
|
]),
|
||||||
|
// feed_tweeter
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Tweeter or Identica ident:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_tweeter'),
|
||||||
|
(new Input('feed_tweeter'))
|
||||||
|
->class('maximal')
|
||||||
|
->size(60)
|
||||||
|
->maxlenght(255)
|
||||||
|
->value($v->tweeter),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
(new Div())
|
||||||
|
->class('col30')
|
||||||
|
->items([
|
||||||
|
(new Text('h4', __('Local settings'))),
|
||||||
|
// feed_cat_id
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Category:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_cat_id'),
|
||||||
|
(new Select('feed_cat_id'))
|
||||||
|
->class('maximal')
|
||||||
|
->items(Combo::postCategories())
|
||||||
|
->default((string) $v->cat_id),
|
||||||
|
]),
|
||||||
|
// feed_status
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Status:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_status'),
|
||||||
|
(new Select('feed_status'))
|
||||||
|
->class('maximal')
|
||||||
|
->items(Combo::feedsStatus())
|
||||||
|
->default((string) $v->status),
|
||||||
|
]),
|
||||||
|
// feed_upd_int
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Update:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_upd_int'),
|
||||||
|
(new Select('feed_upd_int'))
|
||||||
|
->class('maximal')
|
||||||
|
->items(Combo::updateInterval())
|
||||||
|
->default((string) $v->upd_int),
|
||||||
|
]),
|
||||||
|
// feed_lang
|
||||||
|
(new Para())
|
||||||
|
->items([
|
||||||
|
(new Label(__('Lang:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('feed_lang'),
|
||||||
|
(new Select('feed_lang'))
|
||||||
|
->class('maximal')
|
||||||
|
->items(L10n::getISOcodes(true))
|
||||||
|
->default((string) $v->lang),
|
||||||
|
]),
|
||||||
|
// feed_get_tags
|
||||||
|
(new Para())->items([
|
||||||
|
(new Checkbox('feed_get_tags', $v->get_tags))
|
||||||
|
->value(1),
|
||||||
|
(new Label(__('Import tags from feed'), Label::OUTSIDE_LABEL_AFTER))
|
||||||
|
->class('classic')
|
||||||
|
->for('feed_get_tags'),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
(new Para())
|
||||||
|
->class('clear')
|
||||||
|
->items(array_merge(
|
||||||
|
dcCore::app()->adminurl->hiddenFormFields('admin.plugin.' . My::id(), [
|
||||||
|
'part' => 'feed',
|
||||||
|
'feed_id' => $v->id,
|
||||||
|
'action' => 'savefeed',
|
||||||
|
]),
|
||||||
|
[
|
||||||
|
(new Submit(['save']))
|
||||||
|
->value(__('Save') . ' (s)')
|
||||||
|
->accesskey('s'),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($v->id && $v->can_view_page && isset($post_filter) && isset($post_list) && isset($posts_actions_page) && !dcCore::app()->error->flag()) {
|
||||||
|
echo '<div class="multi-part" title="' . __('Entries') . '" id="entries">';
|
||||||
|
|
||||||
|
# show posts filters
|
||||||
|
$post_filter->display(
|
||||||
|
['admin.plugin.' . My::id(),'#entries'],
|
||||||
|
dcCore::app()->adminurl->getHiddenFormFields('admin.plugin.' . My::id(), [
|
||||||
|
'part' => 'feed',
|
||||||
|
'feed_id' => $v->id,
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
# fix pager url
|
||||||
|
$args = $post_filter->values();
|
||||||
|
unset($args['page']);
|
||||||
|
$args['page'] = '%s';
|
||||||
|
|
||||||
|
# show posts
|
||||||
|
$post_list->display(
|
||||||
|
$post_filter,
|
||||||
|
dcCore::app()->adminurl->get('admin.plugin.' . My::id(), $args, '&') . '#entries',
|
||||||
|
(new Form('form-entries'))
|
||||||
|
->method('post')
|
||||||
|
->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'feed']) . '#entries')
|
||||||
|
->fields([
|
||||||
|
(new Text('', '%s')),
|
||||||
|
(new Div())
|
||||||
|
->class('two-cols')
|
||||||
|
->items([
|
||||||
|
(new Para())
|
||||||
|
->class('col checkboxes-helpers'),
|
||||||
|
(new Para())
|
||||||
|
->class('col right')
|
||||||
|
->items(array_merge(
|
||||||
|
dcCore::app()->adminurl->hiddenFormFields('admin.plugin.' . My::id(), $post_filter->values()),
|
||||||
|
[
|
||||||
|
(new Hidden('redir', dcCore::app()->adminurl->get('admin.plugin.' . My::id(), $post_filter->values()))),
|
||||||
|
(new Label(__('Selected entries action:'), Label::OUTSIDE_LABEL_BEFORE))
|
||||||
|
->for('action'),
|
||||||
|
(new Select('action'))
|
||||||
|
->items($posts_actions_page->getCombo()),
|
||||||
|
(new Submit('feed-action'))
|
||||||
|
->value(__('ok')),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
|
||||||
|
]
|
||||||
|
)),
|
||||||
|
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render()
|
||||||
|
);
|
||||||
|
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::closeModule();
|
||||||
|
}
|
||||||
|
}
|
242
src/ManageFeedVars.php
Normal file
242
src/ManageFeedVars.php
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backend feed manage page vars (type hinting).
|
||||||
|
*/
|
||||||
|
class ManageFeedVars
|
||||||
|
{
|
||||||
|
/** @var ManageFeedVars $container Self instance */
|
||||||
|
private static $container;
|
||||||
|
|
||||||
|
public readonly int $id;
|
||||||
|
public readonly string $name;
|
||||||
|
public readonly string $desc;
|
||||||
|
public readonly string $owner;
|
||||||
|
public readonly string $tweeter;
|
||||||
|
public readonly string $url;
|
||||||
|
public readonly string $feed;
|
||||||
|
public readonly string $lang;
|
||||||
|
public readonly string $tags;
|
||||||
|
public readonly bool $get_tags;
|
||||||
|
public readonly ?int $cat_id;
|
||||||
|
public readonly int $status;
|
||||||
|
public readonly int $upd_int;
|
||||||
|
|
||||||
|
public readonly bool $can_view_page;
|
||||||
|
public readonly string $next_link;
|
||||||
|
public readonly string $prev_link;
|
||||||
|
public readonly string $next_headlink;
|
||||||
|
public readonly string $prev_headlink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor sets properties.
|
||||||
|
*/
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
|
||||||
|
$feed_headlink = '<link rel="%s" title="%s" href="' . dcCore::app()->admin->getPageURL() . '&part=feed&feed_id=%s" />';
|
||||||
|
$feed_link = '<a href="' . dcCore::app()->admin->getPageURL() . '&part=feed&feed_id=%s" title="%s">%s</a>';
|
||||||
|
$lang = dcCore::app()->auth?->getInfo('user_lang');
|
||||||
|
|
||||||
|
// default values
|
||||||
|
$feed_id = 0;
|
||||||
|
$feed_name = '';
|
||||||
|
$feed_desc = '';
|
||||||
|
$feed_owner = '';
|
||||||
|
$feed_tweeter = '';
|
||||||
|
$feed_url = '';
|
||||||
|
$feed_feed = '';
|
||||||
|
$feed_lang = is_string($lang) ? $lang : 'en';
|
||||||
|
$feed_tags = '';
|
||||||
|
$feed_get_tags = false;
|
||||||
|
$feed_cat_id = null;
|
||||||
|
$feed_status = 0;
|
||||||
|
$feed_upd_int = 86400;
|
||||||
|
|
||||||
|
$can_view_page = true;
|
||||||
|
$next_link = '';
|
||||||
|
$prev_link = '';
|
||||||
|
$next_headlink = '';
|
||||||
|
$prev_headlink = '';
|
||||||
|
|
||||||
|
// database values
|
||||||
|
if (!empty($_REQUEST['feed_id'])) {
|
||||||
|
$feed = $z->getFeeds(['feed_id' => $_REQUEST['feed_id']]);
|
||||||
|
|
||||||
|
if ($feed->isEmpty()) {
|
||||||
|
dcCore::app()->error->add(__('This feed does not exist.'));
|
||||||
|
$can_view_page = false;
|
||||||
|
} else {
|
||||||
|
$row = new FeedRow($feed);
|
||||||
|
$feed_id = $row->id;
|
||||||
|
$feed_name = $row->name;
|
||||||
|
$feed_desc = $row->desc;
|
||||||
|
$feed_owner = $row->owner;
|
||||||
|
$feed_tweeter = $row->tweeter;
|
||||||
|
$feed_url = $row->url;
|
||||||
|
$feed_feed = $row->feed;
|
||||||
|
$feed_lang = $row->lang;
|
||||||
|
$feed_tags = $row->tags;
|
||||||
|
$feed_get_tags = $row->get_tags;
|
||||||
|
$feed_cat_id = $row->cat_id;
|
||||||
|
$feed_status = $row->status;
|
||||||
|
$feed_upd_int = $row->upd_int;
|
||||||
|
|
||||||
|
$next_params = [
|
||||||
|
'sql' => 'AND feed_id < ' . $feed_id . ' ',
|
||||||
|
'limit' => 1,
|
||||||
|
];
|
||||||
|
$next_rs = $z->getFeeds($next_params);
|
||||||
|
|
||||||
|
if (!$next_rs->isEmpty()) {
|
||||||
|
$next_row = new FeedRow($next_rs);
|
||||||
|
$next_link = sprintf(
|
||||||
|
$feed_link,
|
||||||
|
$next_row->id,
|
||||||
|
Html::escapeHTML($next_row->name),
|
||||||
|
__('next feed') . ' »'
|
||||||
|
);
|
||||||
|
$next_headlink = sprintf(
|
||||||
|
$feed_headlink,
|
||||||
|
'next',
|
||||||
|
Html::escapeHTML($next_row->name),
|
||||||
|
$next_row->id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$prev_params = [
|
||||||
|
'sql' => 'AND feed_id > ' . $feed_id . ' ',
|
||||||
|
'limit' => 1,
|
||||||
|
];
|
||||||
|
$prev_rs = $z->getFeeds($prev_params);
|
||||||
|
|
||||||
|
if (!$prev_rs->isEmpty()) {
|
||||||
|
$prev_row = new FeedRow($prev_rs);
|
||||||
|
$prev_link = sprintf(
|
||||||
|
$feed_link,
|
||||||
|
$prev_row->id,
|
||||||
|
Html::escapeHTML($prev_row->name),
|
||||||
|
'« ' . __('previous feed')
|
||||||
|
);
|
||||||
|
$prev_headlink = sprintf(
|
||||||
|
$feed_headlink,
|
||||||
|
'previous',
|
||||||
|
Html::escapeHTML($prev_row->name),
|
||||||
|
$prev_row->id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// form values
|
||||||
|
if (!empty($_POST)) {
|
||||||
|
$feed_name = !empty($_POST['feed_name']) && is_string($_POST['feed_name']) ? $_POST['feed_name'] : $feed_name;
|
||||||
|
$feed_desc = !empty($_POST['feed_desc']) && is_string($_POST['feed_desc']) ? $_POST['feed_desc'] : $feed_desc;
|
||||||
|
$feed_owner = !empty($_POST['feed_owner']) && is_string($_POST['feed_owner']) ? $_POST['feed_owner'] : $feed_owner;
|
||||||
|
$feed_tweeter = !empty($_POST['feed_tweeter']) && is_string($_POST['feed_tweeter']) ? $_POST['feed_tweeter'] : $feed_tweeter;
|
||||||
|
$feed_url = !empty($_POST['feed_url']) && is_string($_POST['feed_url']) ? $_POST['feed_url'] : $feed_url;
|
||||||
|
$feed_feed = !empty($_POST['feed_feed']) && is_string($_POST['feed_feed']) ? $_POST['feed_feed'] : $feed_feed;
|
||||||
|
$feed_lang = !empty($_POST['feed_lang']) && is_string($_POST['feed_lang']) ? $_POST['feed_lang'] : $feed_lang;
|
||||||
|
$feed_tags = !empty($_POST['feed_tags']) && is_string($_POST['feed_tags']) ? $_POST['feed_tags'] : $feed_tags;
|
||||||
|
$feed_get_tags = empty($_POST['feed_get_tags']) ? $feed_get_tags : true;
|
||||||
|
$feed_cat_id = empty($_POST['feed_cat_id']) ? $feed_cat_id : $_POST['feed_cat_id'];
|
||||||
|
$feed_upd_int = !empty($_POST['feed_upd_int']) && is_numeric($_POST['feed_upd_int']) ? (int) $_POST['feed_upd_int'] : $feed_upd_int;
|
||||||
|
$feed_status = empty($_POST['feed_status']) ? $feed_status : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// class values
|
||||||
|
$this->id = $feed_id;
|
||||||
|
$this->name = $feed_name;
|
||||||
|
$this->desc = $feed_desc;
|
||||||
|
$this->owner = $feed_owner;
|
||||||
|
$this->tweeter = $feed_tweeter;
|
||||||
|
$this->url = $feed_url;
|
||||||
|
$this->feed = $feed_feed;
|
||||||
|
$this->lang = $feed_lang;
|
||||||
|
$this->tags = $feed_tags;
|
||||||
|
$this->get_tags = $feed_get_tags;
|
||||||
|
$this->cat_id = $feed_cat_id;
|
||||||
|
$this->status = $feed_status;
|
||||||
|
$this->upd_int = $feed_upd_int;
|
||||||
|
|
||||||
|
$this->can_view_page = $can_view_page;
|
||||||
|
$this->next_link = $next_link;
|
||||||
|
$this->prev_link = $prev_link;
|
||||||
|
$this->next_headlink = $next_headlink;
|
||||||
|
$this->prev_headlink = $prev_headlink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get self instance.
|
||||||
|
*
|
||||||
|
* @return ManageFeedVars Self instance
|
||||||
|
*/
|
||||||
|
public static function instance(): ManageFeedVars
|
||||||
|
{
|
||||||
|
if (!(self::$container instanceof self)) {
|
||||||
|
self::$container = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or update feed.
|
||||||
|
*
|
||||||
|
* @return int The feed ID
|
||||||
|
*/
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$id = $this->id;
|
||||||
|
|
||||||
|
// prepare cursor
|
||||||
|
$cur = $z->openCursor();
|
||||||
|
$cur->setField('feed_name', $this->name);
|
||||||
|
$cur->setField('feed_desc', $this->desc);
|
||||||
|
$cur->setField('feed_owner', $this->owner);
|
||||||
|
$cur->setField('feed_tweeter', $this->tweeter);
|
||||||
|
$cur->setField('feed_url', $this->url);
|
||||||
|
$cur->setField('feed_feed', $this->feed);
|
||||||
|
$cur->setField('feed_lang', $this->lang);
|
||||||
|
$cur->setField('feed_tags', $this->tags);
|
||||||
|
$cur->setField('feed_get_tags', $this->get_tags);
|
||||||
|
$cur->setField('cat_id', $this->cat_id);
|
||||||
|
$cur->setField('feed_status', $this->status);
|
||||||
|
$cur->setField('feed_upd_int', $this->upd_int);
|
||||||
|
|
||||||
|
# --BEHAVIOR-- adminBeforeZoneclearFeedServerFeedSave - Cursor, int
|
||||||
|
dcCore::app()->callBehavior('adminBeforeZoneclearFeedServerFeedSave', $cur, $id);
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
// create feed
|
||||||
|
$id = $z->addFeed($cur);
|
||||||
|
} else {
|
||||||
|
// update feed
|
||||||
|
$z->updateFeed($id, $cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
# --BEHAVIOR-- adminAfterZoneclearFeedServerFeedSave - Cursor - int
|
||||||
|
dcCore::app()->callBehavior('adminAfterZoneclearFeedServerFeedSave', $cur, $id);
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
}
|
94
src/My.php
Normal file
94
src/My.php
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module definitions.
|
||||||
|
*/
|
||||||
|
class My
|
||||||
|
{
|
||||||
|
/** @var string This module required php version */
|
||||||
|
public const PHP_MIN = '8.1';
|
||||||
|
|
||||||
|
/** @var string This module database table name */
|
||||||
|
public const TABLE_NAME = 'zc_feed';
|
||||||
|
|
||||||
|
/** @var string This module meta prefix */
|
||||||
|
public const META_PREFIX = 'zoneclearfeed_';
|
||||||
|
|
||||||
|
/** @var array<int,string> This module template blocks */
|
||||||
|
public const TPL_BLOCKS = [
|
||||||
|
'Feeds',
|
||||||
|
'FeedsFooter',
|
||||||
|
'FeedsHeader',
|
||||||
|
'FeedIf',
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var array<int,string> This module template values */
|
||||||
|
public const TPL_VALUES = [
|
||||||
|
'FeedsCount',
|
||||||
|
'FeedsEntriesCount',
|
||||||
|
'FeedEntriesCount',
|
||||||
|
'FeedCategory',
|
||||||
|
'FeedCategoryID',
|
||||||
|
'FeedCategoryURL',
|
||||||
|
'FeedCategoryShortURL',
|
||||||
|
'FeedID',
|
||||||
|
'FeedIfFirst',
|
||||||
|
'FeedIfOdd',
|
||||||
|
'FeedLang',
|
||||||
|
'FeedName',
|
||||||
|
'FeedOwner',
|
||||||
|
'FeedDesc',
|
||||||
|
'FeedSiteURL',
|
||||||
|
'FeedFeedURL',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string This module id
|
||||||
|
*/
|
||||||
|
public static function id(): string
|
||||||
|
{
|
||||||
|
return basename(dirname(__DIR__));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string This module name
|
||||||
|
*/
|
||||||
|
public static function name(): string
|
||||||
|
{
|
||||||
|
$name = dcCore::app()->plugins->moduleInfo(self::id(), 'name');
|
||||||
|
|
||||||
|
return __(is_string($name) ? $name : self::id());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string This module path
|
||||||
|
*/
|
||||||
|
public static function path(): string
|
||||||
|
{
|
||||||
|
return dirname(__DIR__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool True on this module php version complied
|
||||||
|
*/
|
||||||
|
public static function phpCompliant(): bool
|
||||||
|
{
|
||||||
|
return version_compare(phpversion(), self::PHP_MIN, '>=');
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,23 +10,31 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use adminGenericFilterV2;
|
||||||
|
use dcAdminCombos;
|
||||||
|
use dcAdminFilter;
|
||||||
|
use dcAdminFilters;
|
||||||
|
use dcCore;
|
||||||
|
use dcUtils;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Backend feed posts list filters.
|
||||||
* @brief Feeds server - Posts list filters methods
|
|
||||||
* @since 2.20
|
|
||||||
* @see adminGenericFilter for more info
|
|
||||||
*/
|
*/
|
||||||
class zcfsPostFilter extends adminGenericFilter
|
class PostsFilter extends adminGenericFilterV2
|
||||||
{
|
{
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct(dcCore::app(), 'zcfs_entries');
|
// use user posts pref
|
||||||
|
parent::__construct('posts');
|
||||||
|
|
||||||
$filters = new arrayObject([
|
$filters = new ArrayObject([
|
||||||
dcAdminFilters::getPageFilter(),
|
dcAdminFilters::getPageFilter(),
|
||||||
$this->getPostUserFilter(),
|
$this->getPostUserFilter(),
|
||||||
$this->getPostCategoriesFilter(),
|
$this->getPostCategoriesFilter(),
|
||||||
|
@ -50,8 +58,8 @@ class zcfsPostFilter extends adminGenericFilter
|
||||||
$users = null;
|
$users = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$users = dcCore::app()->blog->getPostsUsers();
|
$users = dcCore::app()->blog?->getPostsUsers();
|
||||||
if ($users->isEmpty()) {
|
if (is_null($users) || $users->isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
@ -81,8 +89,8 @@ class zcfsPostFilter extends adminGenericFilter
|
||||||
$categories = null;
|
$categories = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$categories = dcCore::app()->blog->getCategories();
|
$categories = dcCore::app()->blog?->getCategories();
|
||||||
if ($categories->isEmpty()) {
|
if (is_null($categories) || $categories->isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
@ -96,10 +104,12 @@ class zcfsPostFilter extends adminGenericFilter
|
||||||
__('(No cat)') => 'NULL',
|
__('(No cat)') => 'NULL',
|
||||||
];
|
];
|
||||||
while ($categories->fetch()) {
|
while ($categories->fetch()) {
|
||||||
|
if (is_numeric($categories->f('level')) && is_string($categories->f('cat_title'))) {
|
||||||
$combo[
|
$combo[
|
||||||
str_repeat(' ', ($categories->level - 1) * 4) .
|
str_repeat(' ', ((int) $categories->f('level') - 1) * 4) .
|
||||||
html::escapeHTML($categories->cat_title) . ' (' . $categories->nb_post . ')'
|
Html::escapeHTML($categories->f('cat_title')) . ' (' . $categories->f('nb_post') . ')'
|
||||||
] = $categories->cat_id;
|
] = $categories->f('cat_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (new dcAdminFilter('cat_id'))
|
return (new dcAdminFilter('cat_id'))
|
||||||
|
@ -131,8 +141,8 @@ class zcfsPostFilter extends adminGenericFilter
|
||||||
$dates = null;
|
$dates = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$dates = dcCore::app()->blog->getDates(['type' => 'month']);
|
$dates = dcCore::app()->blog?->getDates(['type' => 'month']);
|
||||||
if ($dates->isEmpty()) {
|
if (is_null($dates) || $dates->isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
|
@ -10,139 +10,173 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use adminGenericListV2;
|
||||||
|
use dcCore;
|
||||||
|
use dcPager;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Link,
|
||||||
|
Para,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Backend feed posts lists.
|
||||||
* @brief Feeds server - Posts list methods
|
|
||||||
* @since 2.6
|
|
||||||
* @see adminGenericList for more info
|
|
||||||
*/
|
*/
|
||||||
class zcfsEntriesList extends adminGenericList
|
class PostsList extends adminGenericListV2
|
||||||
{
|
{
|
||||||
public function display($page, $nb_per_page, $base_url, $enclose_block = '', $filter = false)
|
public function display(PostsFilter $filter, string $base_url, string $enclose_block = ''): void
|
||||||
{
|
{
|
||||||
if ($this->rs->isEmpty()) {
|
if ($this->rs->isEmpty()) {
|
||||||
echo '<p><strong>' . (
|
echo
|
||||||
$filter ?
|
(new Text(
|
||||||
|
'p',
|
||||||
|
$filter->show() ?
|
||||||
__('No entries matches the filter') :
|
__('No entries matches the filter') :
|
||||||
__('No entries')
|
__('No entries')
|
||||||
) . '</strong></p>';
|
))
|
||||||
} else {
|
->class('info')
|
||||||
$pager = new dcPager($page, $this->rs_count, $nb_per_page, 10);
|
->render();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$page = is_numeric($filter->value('page')) ? (int) $filter->value('page') : 1;
|
||||||
|
$nbpp = is_numeric($filter->value('nb')) ? (int) $filter->value('nb') : 10;
|
||||||
|
$count = (int) $this->rs_count;
|
||||||
|
$pager = new dcPager($page, $count, $nbpp, 10);
|
||||||
$pager->base_url = $base_url;
|
$pager->base_url = $base_url;
|
||||||
|
|
||||||
$entries = [];
|
$cols = new ArrayObject([
|
||||||
if (isset($_REQUEST['feeds'])) {
|
'title' => (new Text('th', __('Title')))
|
||||||
foreach ($_REQUEST['feeds'] as $v) {
|
->class('first')
|
||||||
$entries[(int) $v] = true;
|
->extra('colspan="2"'),
|
||||||
}
|
'date' => (new Text('th', __('Date')))
|
||||||
}
|
->extra('scope="col"'),
|
||||||
|
'author' => (new Text('th', __('Author')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
'category' => (new Text('th', __('Category')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
'status' => (new Text('th', __('Status')))
|
||||||
|
->extra('scope="col"'),
|
||||||
|
]);
|
||||||
|
|
||||||
$html_block = '<div class="table-outer clear">' .
|
$this->userColumns(My::id() . 'posts', $cols);
|
||||||
'<table>' .
|
|
||||||
'<caption>' . (
|
|
||||||
$filter ?
|
|
||||||
sprintf(__('List of %s entries matching the filter.'), $this->rs_count) :
|
|
||||||
sprintf(__('List of entries (%s)'), $this->rs_count)
|
|
||||||
) . '</caption>';
|
|
||||||
|
|
||||||
$cols = [
|
|
||||||
'title' => '<th scope="col" colspan="2" class="first">' . __('Title') . '</th>',
|
|
||||||
'date' => '<th scope="col">' . __('Date') . '</th>',
|
|
||||||
'author' => '<th scope="col">' . __('Author') . '</th>',
|
|
||||||
'category' => '<th scope="col">' . __('Category') . '</th>',
|
|
||||||
'status' => '<th scope="col">' . __('Status') . '</th>',
|
|
||||||
];
|
|
||||||
|
|
||||||
$cols = new ArrayObject($cols);
|
|
||||||
dcCore::app()->callBehavior('adminZcfsPostListHeader', $this->rs, $cols);
|
|
||||||
|
|
||||||
$this->userColumns('zcfs_entries', $cols);
|
|
||||||
|
|
||||||
$html_block .= '<tr>' . implode(iterator_to_array($cols)) . '</tr>%s</table></div>';
|
|
||||||
if ($enclose_block) {
|
|
||||||
$html_block = sprintf($enclose_block, $html_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
echo $pager->getLinks();
|
|
||||||
|
|
||||||
$blocks = explode('%s', $html_block);
|
|
||||||
|
|
||||||
echo $blocks[0];
|
|
||||||
|
|
||||||
|
$lines = [];
|
||||||
while ($this->rs->fetch()) {
|
while ($this->rs->fetch()) {
|
||||||
echo $this->postLine();
|
$lines[] = $this->line(isset($_POST['entries']) && in_array($this->rs->post_id, $_POST['entries']));
|
||||||
}
|
}
|
||||||
|
|
||||||
echo $blocks[1];
|
echo
|
||||||
|
$pager->getLinks() .
|
||||||
echo $pager->getLinks();
|
sprintf(
|
||||||
}
|
$enclose_block,
|
||||||
|
(new Div())
|
||||||
|
->class('table-outer')
|
||||||
|
->items([
|
||||||
|
(new Para(null, 'table'))
|
||||||
|
->items([
|
||||||
|
(new Text(
|
||||||
|
'caption',
|
||||||
|
$filter->show() ?
|
||||||
|
sprintf(__('List of %s entries matching the filter.'), $this->rs_count) :
|
||||||
|
sprintf(__('List of entries. (%s)'), $this->rs_count)
|
||||||
|
)),
|
||||||
|
(new Para(null, 'tr'))
|
||||||
|
->items(iterator_to_array($cols)),
|
||||||
|
(new Para(null, 'tbody'))
|
||||||
|
->items($lines),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
->render()
|
||||||
|
) .
|
||||||
|
$pager->getLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function postLine()
|
private function line(bool $checked): Para
|
||||||
{
|
{
|
||||||
$cat_link = dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([dcAuth::PERMISSION_CATEGORIES]), dcCore::app()->blog->id) ?
|
$cat_title = (new Text('', __('None')));
|
||||||
'<a href="category.php?id=%s" title="' . __('Edit category') . '">%s</a>'
|
if ($this->rs->cat_title
|
||||||
: '%2$s';
|
&& dcCore::app()->auth?->check(dcCore::app()->auth->makePermissions([dcCore::app()->auth::PERMISSION_CATEGORIES]), dcCore::app()->blog?->id)
|
||||||
|
) {
|
||||||
|
$cat_title = (new Link())
|
||||||
|
->href('category.php?id=' . $this->rs->cat_id)
|
||||||
|
->title(Html::escapeHTML(__('Edit category')))
|
||||||
|
->text(Html::escapeHTML($this->rs->cat_title));
|
||||||
|
}
|
||||||
|
|
||||||
$cat_title = $this->rs->cat_title ?
|
|
||||||
sprintf($cat_link, $this->rs->cat_id, html::escapeHTML($this->rs->cat_title))
|
|
||||||
: __('None');
|
|
||||||
|
|
||||||
$img = '<img alt="%1$s" title="%1$s" src="images/%2$s" />';
|
|
||||||
$img_status = '';
|
|
||||||
$sts_class = '';
|
|
||||||
switch ($this->rs->post_status) {
|
switch ($this->rs->post_status) {
|
||||||
case 1:
|
case 1:
|
||||||
$img_status = sprintf($img, __('Published'), 'check-on.png');
|
$img_title = __('Published');
|
||||||
$sts_class = 'sts-online';
|
$img_src = 'check-on.png';
|
||||||
|
$sts_class = ' sts-online';
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
$img_status = sprintf($img, __('Unpublished'), 'check-off.png');
|
|
||||||
$sts_class = 'sts-offline';
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
$img_status = sprintf($img, __('Scheduled'), 'scheduled.png');
|
$img_title = __('Scheduled');
|
||||||
$sts_class = 'sts-scheduled';
|
$img_src = 'scheduled.png';
|
||||||
|
$sts_class = ' sts-scheduled';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case -2:
|
case -2:
|
||||||
$img_status = sprintf($img, __('Pending'), 'check-wrn.png');
|
$img_title = __('Pending');
|
||||||
$sts_class = 'sts-pending';
|
$img_src = 'check-wrn.png';
|
||||||
|
$sts_class = ' sts-pending';
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$img_title = __('Unpublished');
|
||||||
|
$img_src = 'check-off.png';
|
||||||
|
$sts_class = ' sts-offline';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
$res = '<tr class="line ' . ($this->rs->post_status != 1 ? 'offline ' : '') . $sts_class . '"' .
|
$cols = new ArrayObject([
|
||||||
' id="p' . $this->rs->post_id . '">';
|
'check' => (new Para(null, 'td'))
|
||||||
|
->class('nowrap minimal')
|
||||||
|
->items([
|
||||||
|
(new Checkbox(['entries[]'], $checked))
|
||||||
|
->value($this->rs->post_id)
|
||||||
|
->disabled(!$this->rs->isEditable()),
|
||||||
|
]),
|
||||||
|
'title' => (new Para(null, 'td'))
|
||||||
|
->class('maximal')
|
||||||
|
->items([
|
||||||
|
(new Link())
|
||||||
|
->href(dcCore::app()->getPostAdminURL($this->rs->post_type, $this->rs->post_id))
|
||||||
|
->title(Html::escapeHTML($this->rs->getURL()))
|
||||||
|
->text(Html::escapeHTML(trim(Html::clean($this->rs->post_title)))),
|
||||||
|
]),
|
||||||
|
'date' => (new Text('td', Date::dt2str(__('%Y-%m-%d %H:%M'), $this->rs->post_dt)))
|
||||||
|
->class('nowrap count'),
|
||||||
|
'author' => (new Text('td', Html::escapeHTML($this->rs->user_id)))
|
||||||
|
->class('nowrap'),
|
||||||
|
'category' => (new Para(null, 'td'))
|
||||||
|
->class('nowrap')
|
||||||
|
->items([$cat_title]),
|
||||||
|
'status' => (new Para(null, 'td'))
|
||||||
|
->class('nowrap status')
|
||||||
|
->items([
|
||||||
|
(new Text('img', ''))
|
||||||
|
->title($img_title)
|
||||||
|
->extra('src="images/' . $img_src . '"'),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
$cols = [
|
$this->userColumns(My::id() . 'posts', $cols);
|
||||||
'check' => '<td class="nowrap minimal">' .
|
|
||||||
form::checkbox(['entries[]'], $this->rs->post_id, '', '', '', !$this->rs->isEditable()) . '</td>',
|
|
||||||
'title' => '<td scope="row" class="maximal"><a href="' .
|
|
||||||
dcCore::app()->getPostAdminURL($this->rs->post_type, $this->rs->post_id) . '" ' .
|
|
||||||
'title="' . html::escapeHTML($this->rs->getURL()) . '">' .
|
|
||||||
html::escapeHTML(trim(html::clean($this->rs->post_title))) . '</a></td>',
|
|
||||||
'date' => '<td class="nowrap count">' . dt::dt2str(__('%Y-%m-%d %H:%M'), $this->rs->post_dt) . '</td>',
|
|
||||||
'author' => '<td class="nowrap">' . html::escapeHTML($this->rs->user_id) . '</td>',
|
|
||||||
'category' => '<td class="nowrap">' . $cat_title . '</td>',
|
|
||||||
'status' => '<td class="nowrap status">' . $img_status . '</td>',
|
|
||||||
];
|
|
||||||
|
|
||||||
$cols = new ArrayObject($cols);
|
return (new Para('p' . $this->rs->post_id, 'tr'))
|
||||||
dcCore::app()->callBehavior('adminZcfsPostListValue', $this->rs, $cols);
|
->class('line' . ($this->rs->post_status != 1 ? ' offline ' : '') . $sts_class)
|
||||||
|
->items(iterator_to_array($cols));
|
||||||
$this->userColumns('zcfs_entries', $cols);
|
|
||||||
|
|
||||||
$res .= implode(iterator_to_array($cols));
|
|
||||||
$res .= '</tr>';
|
|
||||||
|
|
||||||
return $res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,35 +10,44 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clearbricks::lib()->autoload([
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
'zoneclearFeedServer' => __DIR__ . '/inc/class.zoneclearfeedserver.php',
|
|
||||||
'zcfsAdminBehaviors' => __DIR__ . '/inc/class.zcfsadminbehaviors.php',
|
|
||||||
'zcfsPostFilter' => __DIR__ . '/inc/class.zcfspostfilter.php',
|
|
||||||
'zcfsEntriesList' => __DIR__ . '/inc/class.zcfsentrieslist.php',
|
|
||||||
'zcfsFeedsList' => __DIR__ . '/inc/class.zcfsfeedslist.php',
|
|
||||||
'zcfsFeedsActions' => __DIR__ . '/inc/class.zcfsfeedsactions.php',
|
|
||||||
'zcfsDefaultFeedsActions' => __DIR__ . '/inc/class.zcfsdefaultfeedsactions.php',
|
|
||||||
'zcfsTemplate' => __DIR__ . '/inc/class.zcfstemplate.php',
|
|
||||||
'zcfsPublicBehaviors' => __DIR__ . '/inc/class.zcfspublicbehaviors.php',
|
|
||||||
'zcfsRsExtPosts' => __DIR__ . '/inc/class.zcfsrsextposts.php',
|
|
||||||
'zcfsUrlHandler' => __DIR__ . '/inc/class.zcfsurlhandler.php',
|
|
||||||
'zcfsActivityReportBehaviors' => __DIR__ . '/inc/class.zcfsactivityreportbehaviors.php',
|
|
||||||
'zcfsUpgrade' => __DIR__ . '/inc/class.zcfsupgrade.php',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// public url for page of description of the flux
|
use dcCore;
|
||||||
dcCore::app()->url->register(
|
use dcNsProcess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module prepend.
|
||||||
|
*/
|
||||||
|
class Prepend extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = My::phpCompliant();
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public url for page of description of the flux
|
||||||
|
dcCore::app()->url->register(
|
||||||
'zoneclearFeedsPage',
|
'zoneclearFeedsPage',
|
||||||
'zcfeeds',
|
'zcfeeds',
|
||||||
'^zcfeeds(.*?)$',
|
'^zcfeeds(.*?)$',
|
||||||
['zcfsUrlHandler', 'zcFeedsPage']
|
[UrlHandler::class, 'zoneclearFeedsPage']
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add to report on plugin activityReport
|
// report zoneclearFeedServer activities
|
||||||
if (defined('ACTIVITY_REPORT_V2')) {
|
if (defined('ACTIVITY_REPORT') && ACTIVITY_REPORT == 3) {
|
||||||
zcfsActivityReportBehaviors::init();
|
ActivityReportActions::init();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,74 +10,83 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use context;
|
||||||
|
use dcCore;
|
||||||
|
use rsExtPost;
|
||||||
|
use rsExtPostPublic;
|
||||||
|
use Dotclear\Database\MetaRecord;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Posts record extension to integrate feed info.
|
||||||
* @brief Mix your blog with a feeds planet - rs methods.
|
|
||||||
* @since 2.6
|
|
||||||
*/
|
*/
|
||||||
class zcfsRsExtPosts extends rsExtPost
|
class RsExtPosts extends rsExtPost
|
||||||
{
|
{
|
||||||
public static function zc()
|
/** @var array<string,mixed> $brother_extensions Stack posts record extensions */
|
||||||
{
|
public static array $brother_extensions = [];
|
||||||
return new zoneclearFeedServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get feed meta.
|
* Get feed meta.
|
||||||
*
|
*
|
||||||
* @param dcRecord $rs record instance
|
* @param MetaRecord $rs The record instance
|
||||||
* @param string $info Feed info key
|
* @param string $info The feed info key
|
||||||
* @return string Feed info value
|
*
|
||||||
|
* @return null|string Feed info value
|
||||||
*/
|
*/
|
||||||
public static function zcFeed($rs, $info)
|
public static function zcFeed(MetaRecord $rs, string $info): ?string
|
||||||
{
|
{
|
||||||
$meta = dcCore::app()->meta->getMetadata([
|
$meta = dcCore::app()->meta->getMetadata([
|
||||||
'post_id' => $rs->post_id,
|
'post_id' => $rs->f('post_id'),
|
||||||
'meta_type' => 'zoneclearfeed_' . $info,
|
'meta_type' => My::META_PREFIX . $info,
|
||||||
'limit' => 1,
|
'limit' => 1,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $meta->isEmpty() ? null : $meta->meta_id;
|
return $meta->isEmpty() || !is_string($meta->f('meta_id')) ? null : $meta->f('meta_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call other rs extension.
|
* Call other rs extension.
|
||||||
*
|
*
|
||||||
* @param string $type Type of extension
|
* @param string $type The type of extension
|
||||||
* @param array $args Arguments
|
* @param array<string|int,mixed> $args The arguments
|
||||||
* @return mixed record extension ressource
|
*
|
||||||
|
* @return string The record extension ressource result
|
||||||
*/
|
*/
|
||||||
public static function zcFeedBrother($type, $args)
|
public static function zcFeedBrother(string $type, array $args): string
|
||||||
{
|
{
|
||||||
$ext = dcCore::app()->__get('beforeZcFeedRsExt');
|
$ext = static::$brother_extensions;
|
||||||
if (null !== $ext && !empty($ext[$type])) {
|
if (isset($ext[$type]) && is_callable($ext[$type])) {
|
||||||
$func = $ext[$type];
|
$func = $ext[$type];
|
||||||
} elseif (is_callable(['rsExtPostPublic', $type])) {
|
} elseif (is_callable([rsExtPostPublic::class, $type])) {
|
||||||
$func = ['rsExtPostPublic', $type];
|
$func = [rsExtPostPublic::class, $type];
|
||||||
|
} elseif (is_callable([rsExtPost::class, $type])) {
|
||||||
|
$func = [rsExtPost::class, $type];
|
||||||
} else {
|
} else {
|
||||||
$func = ['rsExtPost', $type];
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return call_user_func_array($func, $args);
|
$cb = call_user_func_array($func, $args);
|
||||||
|
|
||||||
|
return is_string($cb) ? $cb : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get author link from post to feed.
|
* Get author link from post to feed.
|
||||||
*
|
*
|
||||||
* @param dcRecord $rs record instance
|
* @param MetaRecord $rs The record instance
|
||||||
* @return string Author link
|
* @return string The author link
|
||||||
*/
|
*/
|
||||||
public static function getAuthorLink(dcRecord $rs): string
|
public static function getAuthorLink(MetaRecord $rs): string
|
||||||
{
|
{
|
||||||
$author = $rs->zcFeed('author');
|
$author = $rs->__call('zcFeed', ['author']);
|
||||||
$site = $rs->zcFeed('site');
|
$site = $rs->__call('zcFeed', ['site']);
|
||||||
$sitename = $rs->zcFeed('sitename');
|
$sitename = $rs->__call('zcFeed', ['sitename']);
|
||||||
|
|
||||||
return $author && $sitename ?
|
return is_string($author) && is_string($site) && is_string($sitename) ?
|
||||||
sprintf('%s (<a href="%s">%s</a>)', $author, $site, $sitename) :
|
sprintf('%s (<a href="%s">%s</a>)', $author, $site, $sitename) :
|
||||||
self::zcFeedBrother('getAuthorLink', [&$rs]);
|
self::zcFeedBrother('getAuthorLink', [&$rs]);
|
||||||
}
|
}
|
||||||
|
@ -85,14 +94,15 @@ class zcfsRsExtPosts extends rsExtPost
|
||||||
/**
|
/**
|
||||||
* Get author CN from post to feed.
|
* Get author CN from post to feed.
|
||||||
*
|
*
|
||||||
* @param dcRecord $rs record instance
|
* @param MetaRecord $rs The record instance
|
||||||
* @return string Author CN
|
*
|
||||||
|
* @return string The author CN
|
||||||
*/
|
*/
|
||||||
public static function getAuthorCN(dcRecord $rs): string
|
public static function getAuthorCN(MetaRecord $rs): string
|
||||||
{
|
{
|
||||||
$author = $rs->zcFeed('author');
|
$author = $rs->__call('zcFeed', ['author']);
|
||||||
|
|
||||||
return $author ?
|
return is_string($author) ?
|
||||||
$author :
|
$author :
|
||||||
self::zcFeedBrother('getAuthorCN', [&$rs]);
|
self::zcFeedBrother('getAuthorCN', [&$rs]);
|
||||||
}
|
}
|
||||||
|
@ -100,36 +110,37 @@ class zcfsRsExtPosts extends rsExtPost
|
||||||
/**
|
/**
|
||||||
* Get post link from post to feed.
|
* Get post link from post to feed.
|
||||||
*
|
*
|
||||||
* @param dcRecord $rs record instance
|
* @param MetaRecord $rs The record instance
|
||||||
* @return string Post link
|
*
|
||||||
|
* @return string The post link
|
||||||
*/
|
*/
|
||||||
public static function getURL(dcRecord $rs): string
|
public static function getURL(MetaRecord $rs): string
|
||||||
{
|
{
|
||||||
$url = $rs->zcFeed('url');
|
$url = $rs->__call('zcFeed', ['url']);
|
||||||
$types = json_decode(dcCore::app()->blog->settings->__get(basename(dirname('../' . __DIR__)))->post_title_redir);
|
$site = $rs->__call('zcFeed', ['site']);
|
||||||
$full = is_array($types) && in_array(dcCore::app()->url->type, $types);
|
$full = in_array(dcCore::app()->url->type, ZoneclearFeedServer::instance()->settings->post_title_redir);
|
||||||
|
|
||||||
return $url && $full ?
|
return is_string($site) && is_string($url) && $full ?
|
||||||
zoneclearFeedServer::absoluteURL($rs->zcFeed('site'), $url) :
|
ZoneclearFeedServer::instance()::absoluteURL($site, $url) :
|
||||||
self::zcFeedBrother('getURL', [&$rs]);
|
self::zcFeedBrother('getURL', [&$rs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get post content from post to feed.
|
* Get post content from post to feed.
|
||||||
*
|
*
|
||||||
* @param dcRecord $rs record instance
|
* @param MetaRecord $rs The record instance
|
||||||
* @return string Post content
|
* @param mixed $absolute_urls Serve absolute URL (type "mixed" from rsExtPost)
|
||||||
|
*
|
||||||
|
* @return string The post content
|
||||||
*/
|
*/
|
||||||
public static function getContent(dcRecord $rs, bool $absolute_urls = false): string
|
public static function getContent(MetaRecord $rs, mixed $absolute_urls = false): string
|
||||||
{
|
{
|
||||||
$url = $rs->zcFeed('url');
|
$url = $rs->__call('zcFeed', ['url']);
|
||||||
$sitename = $rs->zcFeed('sitename');
|
$sitename = $rs->__call('zcFeed', ['sitename']);
|
||||||
$content = self::zcFeedBrother('getContent', [&$rs, $absolute_urls]);
|
$content = self::zcFeedBrother('getContent', [&$rs, $absolute_urls]);
|
||||||
|
|
||||||
if ($url && $sitename && $rs->post_type == 'post') {
|
if (is_string($url) && is_string($sitename) && $rs->f('post_type') == 'post') {
|
||||||
$types = json_decode(dcCore::app()->blog->settings->__get(basename(dirname('../' . __DIR__)))->post_full_tpl);
|
if (in_array(dcCore::app()->url->type, ZoneclearFeedServer::instance()->settings->post_full_tpl)) {
|
||||||
|
|
||||||
if (is_array($types) && in_array(dcCore::app()->url->type, $types)) {
|
|
||||||
return $content . sprintf(
|
return $content . sprintf(
|
||||||
'<p class="zoneclear-original"><em>%s</em></p>',
|
'<p class="zoneclear-original"><em>%s</em></p>',
|
||||||
sprintf(__('Original post on <a href="%s">%s</a>'), $url, $sitename)
|
sprintf(__('Original post on <a href="%s">%s</a>'), $url, $sitename)
|
||||||
|
@ -137,7 +148,7 @@ class zcfsRsExtPosts extends rsExtPost
|
||||||
}
|
}
|
||||||
$content = context::remove_html($content);
|
$content = context::remove_html($content);
|
||||||
$content = context::cut_string($content, 350);
|
$content = context::cut_string($content, 350);
|
||||||
$content = html::escapeHTML($content);
|
$content = Html::escapeHTML($content);
|
||||||
|
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<p>%s... <em><a href="%s" title="%s">%s</a></em></p>',
|
'<p>%s... <em><a href="%s" title="%s">%s</a></em></p>',
|
||||||
|
|
125
src/Settings.php
Normal file
125
src/Settings.php
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module settings (type hinting).
|
||||||
|
*/
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
/** @var Settings Self instance */
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
public readonly bool $active;
|
||||||
|
|
||||||
|
public readonly bool $pub_active;
|
||||||
|
|
||||||
|
public readonly bool $post_status_new;
|
||||||
|
|
||||||
|
public readonly int $bhv_pub_upd;
|
||||||
|
|
||||||
|
public readonly int $update_limit;
|
||||||
|
|
||||||
|
public readonly bool $keep_empty_feed;
|
||||||
|
|
||||||
|
public readonly int $tag_case;
|
||||||
|
|
||||||
|
/** @var array<int,string> */
|
||||||
|
public readonly array $post_full_tpl;
|
||||||
|
|
||||||
|
/** @var array<int,string> */
|
||||||
|
public readonly array $post_title_redir;
|
||||||
|
|
||||||
|
public readonly string $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor set up plugin settings.
|
||||||
|
*/
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
if (is_null(dcCore::app()->blog)) {
|
||||||
|
throw new Exception(__('Blog is not defined'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$s = dcCore::app()->blog->settings->get(My::id());
|
||||||
|
|
||||||
|
$update_limit = is_numeric($s->get('update_limit')) ? (int) $s->get('update_limit') : 1;
|
||||||
|
|
||||||
|
$this->active = !empty($s->get('active'));
|
||||||
|
$this->pub_active = !empty($s->get('pub_active'));
|
||||||
|
$this->post_status_new = !empty($s->get('post_status_new'));
|
||||||
|
$this->bhv_pub_upd = is_numeric($s->get('bhv_pub_upd')) ? (int) $s->get('bhv_pub_upd') : 1;
|
||||||
|
$this->update_limit = $update_limit < 1 ? 10 : $update_limit;
|
||||||
|
$this->keep_empty_feed = !empty($s->get('keep_empty_feed'));
|
||||||
|
$this->tag_case = is_numeric($s->get('tag_case')) ? (int) $s->get('tag_case') : 0;
|
||||||
|
$this->post_full_tpl = is_array($s->get('post_full_tpl')) ? $s->get('post_full_tpl') : [];
|
||||||
|
$this->post_title_redir = is_array($s->get('post_title_redir')) ? $s->get('post_title_redir') : [];
|
||||||
|
$this->user = is_string($s->get('user')) ? $s->get('user') : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function instance(): Settings
|
||||||
|
{
|
||||||
|
if (!(self::$instance instanceof Settings)) {
|
||||||
|
self::$instance = new Settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isset(string $key): bool
|
||||||
|
{
|
||||||
|
return property_exists($this, $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(string $key): mixed
|
||||||
|
{
|
||||||
|
return $this->{$key} ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite a plugin settings (in db).
|
||||||
|
*
|
||||||
|
* @param string $key The setting ID
|
||||||
|
* @param mixed $value The setting value
|
||||||
|
*
|
||||||
|
* @return bool True on success
|
||||||
|
*/
|
||||||
|
public function set(string $key, mixed $value): bool
|
||||||
|
{
|
||||||
|
$s = dcCore::app()->blog?->settings->get(My::id());
|
||||||
|
|
||||||
|
if (!is_null($s) && property_exists($this, $key) && settype($value, gettype($this->{$key})) === true) {
|
||||||
|
$s->drop($key);
|
||||||
|
$s->put($key, $value, gettype($this->{$key}), '', true, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List defined settings keys.
|
||||||
|
*
|
||||||
|
* @return array<string,mixed> The settings keys
|
||||||
|
*/
|
||||||
|
public function dump(): array
|
||||||
|
{
|
||||||
|
return get_object_vars($this);
|
||||||
|
}
|
||||||
|
}
|
176
src/Template.php
176
src/Template.php
|
@ -10,44 +10,47 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcCore;
|
||||||
|
use dcTemplate;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Frontend template blocks and values.
|
||||||
* @brief Mix your blog with a feeds planet - template methods.
|
|
||||||
* @since 2.6
|
|
||||||
*/
|
*/
|
||||||
class zcfsTemplate
|
class Template
|
||||||
{
|
{
|
||||||
public static function Feeds($a, $c)
|
public static function Feeds(ArrayObject $a, string $c): string
|
||||||
{
|
{
|
||||||
$lastn = -1;
|
$lastn = -1;
|
||||||
$p = '';
|
$p = '';
|
||||||
if (isset($a['lastn'])) {
|
if (isset($a['lastn']) && is_numeric($a['lastn'])) {
|
||||||
$lastn = abs((int) $a['lastn']) + 0;
|
$lastn = abs((int) $a['lastn']) + 0;
|
||||||
$p .= "\$zcfs_params['limit'] = " . $lastn . ";\n";
|
$p .= "\$zcfs_params['limit'] = " . $lastn . ";\n";
|
||||||
}
|
}
|
||||||
if (isset($a['cat_id'])) {
|
if (isset($a['cat_id']) && is_string($a['cat_id'])) {
|
||||||
$p .= "@\$zcfs_params['sql'] .= 'AND Z.cat_id = " . addslashes($a['cat_id']) . " ';\n";
|
$p .= "@\$zcfs_params['sql'] .= 'AND Z.cat_id = " . addslashes($a['cat_id']) . " ';\n";
|
||||||
}
|
}
|
||||||
if (isset($a['no_category'])) {
|
if (isset($a['no_category'])) {
|
||||||
$p .= "@\$zcfs_params['sql'] .= 'AND Z.cat_id IS NULL ';\n";
|
$p .= "@\$zcfs_params['sql'] .= 'AND Z.cat_id IS NULL ';\n";
|
||||||
}
|
}
|
||||||
if (!empty($a['site_url'])) {
|
if (!empty($a['site_url']) && is_string($a['site_url'])) {
|
||||||
$p .= "\$zcfs_params['feed_url'] = '" . addslashes($a['site_url']) . "';\n";
|
$p .= "\$zcfs_params['feed_url'] = '" . addslashes($a['site_url']) . "';\n";
|
||||||
}
|
}
|
||||||
if (isset($a['feed_status'])) {
|
if (isset($a['feed_status']) && is_numeric($a['feed_status'])) {
|
||||||
$p .= "\$zcfs_params['feed_status'] = " . ((int) $a['feed_status']) . ";\n";
|
$p .= "\$zcfs_params['feed_status'] = " . ((int) $a['feed_status']) . ";\n";
|
||||||
} else {
|
} else {
|
||||||
$p .= "\$zcfs_params['feed_status'] = 1;\n";
|
$p .= "\$zcfs_params['feed_status'] = 1;\n";
|
||||||
}
|
}
|
||||||
if (!empty($a['feed_url'])) {
|
if (!empty($a['feed_url']) && is_string($a['feed_url'])) {
|
||||||
$p .= "\$zcfs_params['feed_feed'] = '" . addslashes($a['feed_url']) . "';\n";
|
$p .= "\$zcfs_params['feed_feed'] = '" . addslashes($a['feed_url']) . "';\n";
|
||||||
}
|
}
|
||||||
if (isset($a['feed_owner'])) {
|
if (isset($a['feed_owner']) && is_string($a['feed_owner'])) {
|
||||||
$p .= "@\$zcfs_params['sql'] .= \"AND Z.feed_owner = '" . addslashes($a['author']) . "' \";\n";
|
$p .= "@\$zcfs_params['sql'] .= \"AND Z.feed_owner = '" . addslashes($a['feed_owner']) . "' \";\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
$sortby = 'feed_creadt';
|
$sortby = 'feed_creadt';
|
||||||
|
@ -71,7 +74,7 @@ class zcfsTemplate
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($a['order']) && preg_match('/^(desc|asc)$/i', $a['order'])) {
|
if (isset($a['order']) && is_string($a['order']) && preg_match('/^(desc|asc)$/i', $a['order'])) {
|
||||||
$order = $a['order'];
|
$order = $a['order'];
|
||||||
}
|
}
|
||||||
$p .= "\$zcfs_params['order'] = '" . $sortby . ' ' . $order . "';\n";
|
$p .= "\$zcfs_params['order'] = '" . $sortby . ' ' . $order . "';\n";
|
||||||
|
@ -79,26 +82,26 @@ class zcfsTemplate
|
||||||
return
|
return
|
||||||
'<?php ' . $p .
|
'<?php ' . $p .
|
||||||
'dcCore::app()->ctx->feeds_params = $zcfs_params;' . "\n" .
|
'dcCore::app()->ctx->feeds_params = $zcfs_params;' . "\n" .
|
||||||
'$zcfs = new zoneclearFeedServer();' . "\n" .
|
'$zcfs = ' . ZoneclearFeedServer::class . '::instance();' . "\n" .
|
||||||
'dcCore::app()->ctx->feeds = $zcfs->getFeeds($zcfs_params); unset($zcfs_params,$zcfs);' . "\n" .
|
'dcCore::app()->ctx->feeds = $zcfs->getFeeds($zcfs_params); unset($zcfs_params,$zcfs);' . "\n" .
|
||||||
"?>\n" .
|
"?>\n" .
|
||||||
'<?php while (dcCore::app()->ctx->feeds->fetch()) : ?>' . $c . '<?php endwhile; ' .
|
'<?php while (dcCore::app()->ctx->feeds->fetch()) : ?>' . $c . '<?php endwhile; ' .
|
||||||
'dcCore::app()->ctx->feeds = null; dcCore::app()->ctx->feeds_params = null; ?>';
|
'dcCore::app()->ctx->feeds = null; dcCore::app()->ctx->feeds_params = null; ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedIf($a, $c)
|
public static function FeedIf(ArrayObject $a, string $c): string
|
||||||
{
|
{
|
||||||
$if = [];
|
$if = [];
|
||||||
|
|
||||||
$operator = isset($a['operator']) ? self::getOperator($a['operator']) : '&&';
|
$operator = isset($a['operator']) && is_string($a['operator']) ? dcTemplate::getOperator($a['operator']) : '&&';
|
||||||
|
|
||||||
if (isset($a['type'])) {
|
if (isset($a['type']) && is_string($a['type'])) {
|
||||||
$type = trim($a['type']);
|
$type = trim($a['type']);
|
||||||
$type = !empty($type) ? $type : 'feed';
|
$type = !empty($type) ? $type : 'feed';
|
||||||
$if[] = 'dcCore::app()->ctx->feeds->feed_type == "' . addslashes($type) . '"';
|
$if[] = 'dcCore::app()->ctx->feeds->feed_type == "' . addslashes($type) . '"';
|
||||||
}
|
}
|
||||||
if (isset($a['site_url'])) {
|
if (isset($a['site_url']) && is_string($a['site_url'])) {
|
||||||
$url = trim($a['feed_url']);
|
$url = trim($a['site_url']);
|
||||||
if (substr($url, 0, 1) == '!') {
|
if (substr($url, 0, 1) == '!') {
|
||||||
$url = substr($url, 1);
|
$url = substr($url, 1);
|
||||||
$if[] = 'dcCore::app()->ctx->feeds->feed_url != "' . addslashes($url) . '"';
|
$if[] = 'dcCore::app()->ctx->feeds->feed_url != "' . addslashes($url) . '"';
|
||||||
|
@ -106,8 +109,8 @@ class zcfsTemplate
|
||||||
$if[] = 'dcCore::app()->ctx->feeds->feed_url == "' . addslashes($url) . '"';
|
$if[] = 'dcCore::app()->ctx->feeds->feed_url == "' . addslashes($url) . '"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($a['feed_url'])) {
|
if (isset($a['feed_url']) && is_string($a['feed_url'])) {
|
||||||
$url = trim($a['feed_feed']);
|
$url = trim($a['feed_url']);
|
||||||
if (substr($url, 0, 1) == '!') {
|
if (substr($url, 0, 1) == '!') {
|
||||||
$url = substr($url, 1);
|
$url = substr($url, 1);
|
||||||
$if[] = 'dcCore::app()->ctx->feeds->feed_feed != "' . addslashes($url) . '"';
|
$if[] = 'dcCore::app()->ctx->feeds->feed_feed != "' . addslashes($url) . '"';
|
||||||
|
@ -115,7 +118,7 @@ class zcfsTemplate
|
||||||
$if[] = 'dcCore::app()->ctx->feeds->feed_feed == "' . addslashes($url) . '"';
|
$if[] = 'dcCore::app()->ctx->feeds->feed_feed == "' . addslashes($url) . '"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isset($a['category'])) {
|
if (isset($a['category']) && is_string($a['category'])) {
|
||||||
$category = addslashes(trim($a['category']));
|
$category = addslashes(trim($a['category']));
|
||||||
if (substr($category, 0, 1) == '!') {
|
if (substr($category, 0, 1) == '!') {
|
||||||
$category = substr($category, 1);
|
$category = substr($category, 1);
|
||||||
|
@ -146,112 +149,100 @@ class zcfsTemplate
|
||||||
'<?php if(' . implode(' ' . $operator . ' ', $if) . ') : ?>' . $c . '<?php endif; ?>';
|
'<?php if(' . implode(' ' . $operator . ' ', $if) . ') : ?>' . $c . '<?php endif; ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedIfFirst($a)
|
public static function FeedIfFirst(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
$ret = $a['return'] ?? 'first';
|
$ret = Html::escapeHTML(isset($a['return']) && is_string($a['return']) ? $a['return'] : 'first');
|
||||||
$ret = html::escapeHTML($ret);
|
|
||||||
|
|
||||||
return
|
return
|
||||||
'<?php if (dcCore::app()->ctx->feeds->index() == 0) { ' .
|
'<?php if (dcCore::app()->ctx->feeds->index() == 0) { ' .
|
||||||
"echo '" . addslashes($ret) . "'; } ?>";
|
"echo '" . addslashes($ret) . "'; } ?>";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedIfOdd($a)
|
public static function FeedIfOdd(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
$ret = $a['return'] ?? 'odd';
|
$ret = Html::escapeHTML(isset($a['return']) && is_string($a['return']) ? $a['return'] : 'odd');
|
||||||
$ret = html::escapeHTML($ret);
|
|
||||||
|
|
||||||
return
|
return
|
||||||
'<?php if ((dcCore::app()->ctx->feeds->index()+1)%2 == 1) { ' .
|
'<?php if ((dcCore::app()->ctx->feeds->index()+1)%2 == 1) { ' .
|
||||||
"echo '" . addslashes($ret) . "'; } ?>";
|
"echo '" . addslashes($ret) . "'; } ?>";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedDesc($a)
|
public static function FeedDesc(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_desc');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedOwner($a)
|
public static function FeedOwner(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_owner');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_owner');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedCategory($a)
|
public static function FeedCategory(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->cat_title');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->cat_title');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedCategoryID($a)
|
public static function FeedCategoryID(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->cat_id');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->cat_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedCategoryURL($a)
|
public static function FeedCategoryURL(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->blog->url.dcCore::app()->url->getBase(\'category\').\'/\'.html::sanitizeURL(dcCore::app()->ctx->feeds->cat_url)');
|
return self::getValue($a, 'dcCore::app()->blog->url.dcCore::app()->url->getBase(\'category\').\'/\'.Html::sanitizeURL(dcCore::app()->ctx->feeds->cat_url)');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedCategoryShortURL($a)
|
public static function FeedCategoryShortURL(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->cat_url');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->cat_url');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedID($a)
|
public static function FeedID(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_id');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedLang($a)
|
public static function FeedLang(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
$f = dcCore::app()->tpl->getFilters($a);
|
|
||||||
|
|
||||||
return empty($a['full']) ?
|
return empty($a['full']) ?
|
||||||
'<?php echo ' . sprintf($f, 'dcCore::app()->ctx->feeds->feed_lang') . '; ?>' :
|
self::getValue($a, 'dcCore::app()->ctx->feeds->feed_lang') :
|
||||||
'<?php $langs = l10n::getISOcodes(); if (isset($langs[dcCore::app()->ctx->feeds->feed_lang])) { echo ' .
|
'<?php $langs = l10n::getISOcodes(); if (isset($langs[dcCore::app()->ctx->feeds->feed_lang])) { ?>' .
|
||||||
sprintf($f, '$langs[dcCore::app()->ctx->feeds->feed_lang]') . '; } else { echo ' .
|
self::getValue($a, '$langs[dcCore::app()->ctx->feeds->feed_lang]') .
|
||||||
sprintf($f, 'dcCore::app()->ctx->feeds->feed_lang') . '; } unset($langs); ?>';
|
'<?php } else { ?>' .
|
||||||
|
self::getValue($a, 'dcCore::app()->ctx->feeds->feed_lang') .
|
||||||
|
'<?php ; } unset($langs); ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedName($a)
|
public static function FeedName(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_name');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_name');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedSiteURL($a)
|
public static function FeedSiteURL(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_url');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_url');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedFeedURL($a)
|
public static function FeedFeedURL(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_feed');
|
return self::getValue($a, 'dcCore::app()->ctx->feeds->feed_feed');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedsHeader($a, $c)
|
public static function FeedsHeader(ArrayObject $a, string $c): string
|
||||||
{
|
{
|
||||||
return '<?php if (dcCore::app()->ctx->feeds->isStart()) : ?>' . $c . '<?php endif; ?>';
|
return '<?php if (dcCore::app()->ctx->feeds->isStart()) : ?>' . $c . '<?php endif; ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedsFooter($a, $c)
|
public static function FeedsFooter(ArrayObject $a, string $c): string
|
||||||
{
|
{
|
||||||
return '<?php if (dcCore::app()->ctx->feeds->isEnd()) : ?>' . $c . '<?php endif; ?>';
|
return '<?php if (dcCore::app()->ctx->feeds->isEnd()) : ?>' . $c . '<?php endif; ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedsCount($a)
|
public static function FeedsCount(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
$none = 'no sources';
|
$none = isset($a['none']) && is_string($a['none']) ? addslashes($a['none']) : 'no sources';
|
||||||
$one = 'one source';
|
$one = isset($a['one']) && is_string($a['one']) ? addslashes($a['one']) : 'one source';
|
||||||
$more = '%d sources';
|
$more = isset($a['more']) && is_string($a['more']) ? addslashes($a['more']) : '%d sources';
|
||||||
|
|
||||||
if (isset($a['none'])) {
|
|
||||||
$none = addslashes($a['none']);
|
|
||||||
}
|
|
||||||
if (isset($a['one'])) {
|
|
||||||
$one = addslashes($a['one']);
|
|
||||||
}
|
|
||||||
if (isset($a['more'])) {
|
|
||||||
$more = addslashes($a['more']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
"<?php \$fcount = dcCore::app()->ctx->feeds->count(); \n" .
|
"<?php \$fcount = dcCore::app()->ctx->feeds->count(); \n" .
|
||||||
|
@ -264,25 +255,15 @@ class zcfsTemplate
|
||||||
'} unset($fcount); ?>';
|
'} unset($fcount); ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedsEntriesCount($a)
|
public static function FeedsEntriesCount(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
$none = __('no entries');
|
$none = isset($a['none']) && is_string($a['none']) ? addslashes($a['none']) : 'no entries';
|
||||||
$one = __('one entry');
|
$one = isset($a['one']) && is_string($a['one']) ? addslashes($a['one']) : 'one entry';
|
||||||
$more = __('%d entries');
|
$more = isset($a['more']) && is_string($a['more']) ? addslashes($a['more']) : '%d entries';
|
||||||
|
|
||||||
if (isset($a['none'])) {
|
|
||||||
$none = addslashes($a['none']);
|
|
||||||
}
|
|
||||||
if (isset($a['one'])) {
|
|
||||||
$one = addslashes($a['one']);
|
|
||||||
}
|
|
||||||
if (isset($a['more'])) {
|
|
||||||
$more = addslashes($a['more']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
"<?php \$fcount = 0; \n" .
|
"<?php \$fcount = 0; \n" .
|
||||||
'$zc = new zoneclearFeedServer();' . "\n" .
|
'$zc = ' . ZoneclearFeedServer::class . '::instance();' . "\n" .
|
||||||
"\$allfeeds = \$zc->getFeeds(); \n" .
|
"\$allfeeds = \$zc->getFeeds(); \n" .
|
||||||
"if (!\$allfeeds->isEmpty()) { \n" .
|
"if (!\$allfeeds->isEmpty()) { \n" .
|
||||||
' while ($allfeeds->fetch()) { ' .
|
' while ($allfeeds->fetch()) { ' .
|
||||||
|
@ -298,24 +279,14 @@ class zcfsTemplate
|
||||||
'} unset($allfeeds,$fcount); ?>';
|
'} unset($allfeeds,$fcount); ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function FeedEntriesCount($a)
|
public static function FeedEntriesCount(ArrayObject $a): string
|
||||||
{
|
{
|
||||||
$none = 'no entries';
|
$none = isset($a['none']) && is_string($a['none']) ? addslashes($a['none']) : 'no entries';
|
||||||
$one = 'one entry';
|
$one = isset($a['one']) && is_string($a['one']) ? addslashes($a['one']) : 'one entry';
|
||||||
$more = '%d entries';
|
$more = isset($a['more']) && is_string($a['more']) ? addslashes($a['more']) : '%d entries';
|
||||||
|
|
||||||
if (isset($a['none'])) {
|
|
||||||
$none = addslashes($a['none']);
|
|
||||||
}
|
|
||||||
if (isset($a['one'])) {
|
|
||||||
$one = addslashes($a['one']);
|
|
||||||
}
|
|
||||||
if (isset($a['more'])) {
|
|
||||||
$more = addslashes($a['more']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
"<?php \$zcfs = new zoneclearFeedServer(); \n" .
|
'<?php $zcfs = ' . ZoneclearFeedServer::class . "::instance(); \n" .
|
||||||
"\$fcount = \$zc->getPostsByFeed(array('feed_id'=>dcCore::app()->ctx->feeds->feed_id),true)->f(0); \n" .
|
"\$fcount = \$zc->getPostsByFeed(array('feed_id'=>dcCore::app()->ctx->feeds->feed_id),true)->f(0); \n" .
|
||||||
"if (\$fcount == 0) {\n" .
|
"if (\$fcount == 0) {\n" .
|
||||||
" printf(__('" . $none . "'),\$fcount);\n" .
|
" printf(__('" . $none . "'),\$fcount);\n" .
|
||||||
|
@ -326,21 +297,8 @@ class zcfsTemplate
|
||||||
'} unset($fcount); ?>';
|
'} unset($fcount); ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function getValue($a, $v)
|
protected static function getValue(ArrayObject $a, string $v): string
|
||||||
{
|
{
|
||||||
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($a), $v) . '; ?>';
|
return '<?php echo ' . sprintf(dcCore::app()->tpl->getFilters($a), $v) . '; ?>';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function getOperator($op)
|
|
||||||
{
|
|
||||||
switch (strtolower($op)) {
|
|
||||||
case 'or':
|
|
||||||
case '||':
|
|
||||||
return '||';
|
|
||||||
case 'and':
|
|
||||||
case '&&':
|
|
||||||
default:
|
|
||||||
return '&&';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,102 +10,89 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addUserAction(
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
/* type */
|
|
||||||
'settings',
|
|
||||||
/* action */
|
|
||||||
'delete_all',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* desc */
|
|
||||||
__('delete all settings')
|
|
||||||
);
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'tables',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
initZoneclearFeedServer::TABLE_NAME,
|
|
||||||
/* desc */
|
|
||||||
__('delete table')
|
|
||||||
);
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'plugins',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* desc */
|
|
||||||
__('delete plugin files')
|
|
||||||
);
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'versions',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* desc */
|
|
||||||
__('delete the version number')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addDirectAction(
|
use dcCore;
|
||||||
/* type */
|
use dcNsProcess;
|
||||||
'settings',
|
use Dotclear\Plugin\Uninstaller\Uninstaller;
|
||||||
/* action */
|
|
||||||
'delete_all',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* desc */
|
|
||||||
sprintf(__('delete all %s settings'), basename(__DIR__))
|
|
||||||
);
|
|
||||||
$this->addDirectAction(
|
|
||||||
/* type */
|
|
||||||
'tables',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
initZoneclearFeedServer::TABLE_NAME,
|
|
||||||
/* desc */
|
|
||||||
sprintf(__('delete %s table'), basename(__DIR__))
|
|
||||||
);
|
|
||||||
$this->addDirectAction(
|
|
||||||
/* type */
|
|
||||||
'plugins',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* desc */
|
|
||||||
sprintf(__('delete %s plugin files'), basename(__DIR__))
|
|
||||||
);
|
|
||||||
$this->addDirectAction(
|
|
||||||
/* type */
|
|
||||||
'versions',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* desc */
|
|
||||||
sprintf(__('delete %s version number'), basename(__DIR__))
|
|
||||||
);
|
|
||||||
$this->addDirectCallback(
|
|
||||||
/* function */
|
|
||||||
'zoneclearfeedServerUninstall',
|
|
||||||
/* desc */
|
|
||||||
'delete feeds relations'
|
|
||||||
);
|
|
||||||
|
|
||||||
function zoneclearfeedServerUninstall($id)
|
/**
|
||||||
|
* Plugin Uninstaller actions.
|
||||||
|
*/
|
||||||
|
class Uninstall extends dcNsProcess
|
||||||
{
|
{
|
||||||
if ($id != basename(__DIR__)) {
|
public static function init(): bool
|
||||||
return null;
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN');
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($_POST[My::id() . 'DeletePostsMeta'])) {
|
||||||
|
ZoneclearFeedServer::instance()::deletePostsMeta(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uninstaller::instance()
|
||||||
|
->addUserAction(
|
||||||
|
'settings',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
My::id() . 'DeletePostsMeta',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'tables',
|
||||||
|
'delete',
|
||||||
|
My::TABLE_NAME
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'plugins',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'versions',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'settings',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
My::id() . 'DeletePostsMeta',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'tables',
|
||||||
|
'delete',
|
||||||
|
My::TABLE_NAME
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'plugins',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'versions',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
//...
|
|
||||||
}
|
}
|
||||||
|
|
104
src/UninstallCleaner.php
Normal file
104
src/UninstallCleaner.php
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcMeta;
|
||||||
|
use Dotclear\Database\Statement\{
|
||||||
|
DeleteStatement,
|
||||||
|
SelectStatement
|
||||||
|
};
|
||||||
|
use Dotclear\Plugin\Uninstaller\{
|
||||||
|
ActionDescriptor,
|
||||||
|
CleanerDescriptor,
|
||||||
|
CleanerParent,
|
||||||
|
CleanersStack,
|
||||||
|
ValueDescriptor
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin Uninstaller Cleaner object.
|
||||||
|
*
|
||||||
|
* This add special action for feed posts metadata.
|
||||||
|
*/
|
||||||
|
class UninstallCleaner extends CleanerParent
|
||||||
|
{
|
||||||
|
public static function init(CleanersStack $cleaners): void
|
||||||
|
{
|
||||||
|
$cleaners->set(new UninstallCleaner());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(new CleanerDescriptor(
|
||||||
|
id: My::id() . 'DeletePostsMeta',
|
||||||
|
name: __('Feed Server'),
|
||||||
|
desc: __('Feed server posts feed metadata'),
|
||||||
|
actions: [
|
||||||
|
new ActionDescriptor(
|
||||||
|
id: 'delete_all',
|
||||||
|
select: __('delete selected posts feed metadata'),
|
||||||
|
query: __('delete "%s" posts feed metadata'),
|
||||||
|
success: __('"%s" posts feed metadata deleted'),
|
||||||
|
error: __('Failed to delete "%s" posts feed metadata')
|
||||||
|
),
|
||||||
|
]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function distributed(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function values(): array
|
||||||
|
{
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$sql->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME)
|
||||||
|
->columns([
|
||||||
|
$sql->as($sql->count('*'), 'counter'),
|
||||||
|
])
|
||||||
|
->where($sql->like('meta_type', My::META_PREFIX . '%'));
|
||||||
|
|
||||||
|
$rs = $sql->select();
|
||||||
|
if (is_null($rs) || $rs->isEmpty() || !is_numeric($rs->f('counter'))) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = [];
|
||||||
|
while ($rs->fetch()) {
|
||||||
|
$res[] = new ValueDescriptor(
|
||||||
|
ns: My::id(),
|
||||||
|
count: (int) $rs->f('counter')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute(string $action, string $ns): bool
|
||||||
|
{
|
||||||
|
if ($action == 'delete_all') {
|
||||||
|
$sql = new DeleteStatement();
|
||||||
|
$sql->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME)
|
||||||
|
->where($sql->like('meta_type', My::META_PREFIX . '%'))
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,27 +10,46 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class zcfsUpgrade
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcNamespace;
|
||||||
|
use Dotclear\Database\Statement\{
|
||||||
|
SelectStatement,
|
||||||
|
UpdateStatement
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module versions upgrades.
|
||||||
|
*/
|
||||||
|
class Upgrade
|
||||||
{
|
{
|
||||||
public static function preUpgrade()
|
public static function preUpgrade(): void
|
||||||
{
|
{
|
||||||
$current = dcCore::app()->getVersion(basename(dirname('../' . __DIR__)));
|
$current = dcCore::app()->getVersion(My::id());
|
||||||
if ($current && version_compare($current, '2022.12.10', '<')) {
|
if (!is_string($current) || empty($current)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version_compare($current, '2022.12.10', '<')) {
|
||||||
self::preUpgrade20221210();
|
self::preUpgrade20221210();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version_compare($current, '2023.05.05', '<')) {
|
||||||
|
self::preUpgrade20230505();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static function preUpgrade20221210()
|
protected static function preUpgrade20221210(): void
|
||||||
{
|
{
|
||||||
// Rename settings
|
// Rename settings
|
||||||
$setting_ids = [
|
$setting_ids = [
|
||||||
'zoneclearFeedServer_active' => 'active',
|
'zoneclearFeedServer_active' => 'active',
|
||||||
'zoneclearFeedServer_pub_active' => 'pub_active',
|
'zoneclearFeedServer_pub_active' => 'pub_active',
|
||||||
'zoneclearFeedServer_post_status_new' => 'psot_new_status',
|
'zoneclearFeedServer_post_status_new' => 'post_new_status',
|
||||||
'zoneclearFeedServer_bhv_pub_upd' => 'bhv_pub_upd',
|
'zoneclearFeedServer_bhv_pub_upd' => 'bhv_pub_upd',
|
||||||
'zoneclearFeedServer_update_limit' => 'update_limit',
|
'zoneclearFeedServer_update_limit' => 'update_limit',
|
||||||
'zoneclearFeedServer_keep_empty_feed' => 'keep_empty_feed',
|
'zoneclearFeedServer_keep_empty_feed' => 'keep_empty_feed',
|
||||||
|
@ -40,23 +59,36 @@ class zcfsUpgrade
|
||||||
'zoneclearFeedServer_post_title_redir' => 'post_title_redir',
|
'zoneclearFeedServer_post_title_redir' => 'post_title_redir',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($setting_ids as $old => $new) {
|
|
||||||
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
|
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
|
||||||
$cur->setting_id = $new;
|
foreach ($setting_ids as $old => $new) {
|
||||||
$cur->update("WHERE setting_id = '" . $old . "' and setting_ns = 'zoneclearFeedServer' ");
|
$cur->clean();
|
||||||
|
$cur->setField('setting_id', $new);
|
||||||
|
$cur->setField('setting_ns', My::id());
|
||||||
|
|
||||||
|
$sql = new UpdateStatement();
|
||||||
|
$sql
|
||||||
|
->where('setting_id = ' . $sql->quote($old))
|
||||||
|
->and('setting_ns = ' . $sql->quote('zoneclearFeedServer'))
|
||||||
|
->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
// use json rather than serialise for settings array
|
// use json rather than serialise for settings array
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$record = $sql
|
||||||
|
->from(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME)
|
||||||
|
->where('setting_ns = ' . $sql->quote(My::id()))
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if (is_null($record)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$setting_values = [
|
$setting_values = [
|
||||||
'post_full_tpl' => ['post', 'category', 'tag', 'archive'],
|
'post_full_tpl' => ['post', 'category', 'tag', 'archive'],
|
||||||
'post_title_redir' => ['feed'],
|
'post_title_redir' => ['feed'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$record = dcCore::app()->con->select(
|
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
|
||||||
'SELECT * FROM ' . dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME . ' ' .
|
|
||||||
"WHERE setting_ns = '" . dcCore::app()->con->escape(basename(dirname('../' . __DIR__))) . "' "
|
|
||||||
);
|
|
||||||
|
|
||||||
while ($record->fetch()) {
|
while ($record->fetch()) {
|
||||||
foreach ($setting_values as $key => $default) {
|
foreach ($setting_values as $key => $default) {
|
||||||
try {
|
try {
|
||||||
|
@ -65,13 +97,31 @@ class zcfsUpgrade
|
||||||
$value = $default;
|
$value = $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cur = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME);
|
$cur->clean();
|
||||||
$cur->setting_value = json_encode(!is_array($value) ? $default : $value);
|
$cur->setField('setting_value', json_encode(!is_array($value) ? $default : $value));
|
||||||
$cur->update(
|
|
||||||
"WHERE setting_id = '" . $key . "' and setting_ns = '" . dcCore::app()->con->escape($record->setting_ns) . "' " .
|
$sql = new UpdateStatement();
|
||||||
'AND blog_id ' . (null === $record->blog_id ? 'IS NULL ' : ("= '" . dcCore::app()->con->escape($record->blog_id) . "' "))
|
$sql
|
||||||
);
|
->where('setting_id = ' . $sql->quote($key))
|
||||||
|
->and('setting_ns = ' . $sql->quote($record->f('setting_ns')))
|
||||||
|
->and('blog_id ' . (null === $record->f('blog_id') ? 'IS NULL ' : ('= ' . $sql->quote($record->f('blog_id')))))
|
||||||
|
->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function preUpgrade20230505(): void
|
||||||
|
{
|
||||||
|
// change settings type of json string to array
|
||||||
|
$sql = new UpdateStatement();
|
||||||
|
$sql
|
||||||
|
->ref(dcCore::app()->prefix . dcNamespace::NS_TABLE_NAME)
|
||||||
|
->column('setting_type')
|
||||||
|
->value('array')
|
||||||
|
->where('setting_id ' . $sql->in([
|
||||||
|
'post_full_tpl',
|
||||||
|
'post_title_redir',
|
||||||
|
]))
|
||||||
|
->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,41 +10,44 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcUrlHandlers;
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Frontend URL handler.
|
||||||
* @brief Mix your blog with a feeds planet - url handler methods.
|
*
|
||||||
* @since 2.6
|
* This adds public page that list feeds.
|
||||||
|
* And serve an endpoint to update feeds through js.
|
||||||
*/
|
*/
|
||||||
class zcfsUrlHandler extends dcUrlHandlers
|
class UrlHandler extends dcUrlHandlers
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Feeds source page and update methods.
|
* Feeds source page and update methods.
|
||||||
*
|
*
|
||||||
* @param array $args Page arguments
|
* @param string $args The page arguments
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public static function zcFeedsPage($args)
|
public static function zoneclearFeedsPage(string $args): void
|
||||||
{
|
{
|
||||||
$s = dcCore::app()->blog->settings->__get(basename(dirname('../' . __DIR__)));
|
$z = ZoneclearFeedServer::instance();
|
||||||
|
$s = $z->settings;
|
||||||
|
|
||||||
# Not active
|
# Not active
|
||||||
if (!$s->active) {
|
if (is_null(dcCore::app()->blog) || !$s->active) {
|
||||||
self::p404();
|
self::p404();
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Update feeds (from ajax or other post resquest)
|
# Update feeds (from ajax or other post resquest)
|
||||||
if ($args == '/zcfsupd' && 3 == $s->bhv_pub_upd) {
|
if ($args == '/zcfsupd' && 3 == $s->bhv_pub_upd) {
|
||||||
$msg = '';
|
$msg = '';
|
||||||
if (!empty($_POST['blogId']) && html::escapeJS(dcCore::app()->blog->id) == $_POST['blogId']) {
|
if (!empty($_POST['blogId']) && Html::escapeJS(dcCore::app()->blog->id) == $_POST['blogId']) {
|
||||||
try {
|
try {
|
||||||
$zc = new zoneclearFeedServer();
|
if ($z->checkFeedsUpdate()) {
|
||||||
if ($zc->checkFeedsUpdate()) {
|
|
||||||
$msg = sprintf(
|
$msg = sprintf(
|
||||||
'<status>%s</status><message>%s</message>',
|
'<status>%s</status><message>%s</message>',
|
||||||
'ok',
|
'ok',
|
||||||
|
@ -73,7 +76,7 @@ class zcfsUrlHandler extends dcUrlHandlers
|
||||||
|
|
||||||
# Server js
|
# Server js
|
||||||
} elseif ($args == '/zcfsupd.js' && 3 == $s->bhv_pub_upd) {
|
} elseif ($args == '/zcfsupd.js' && 3 == $s->bhv_pub_upd) {
|
||||||
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), __DIR__ . '/default-templates');
|
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), My::path() . '/default-templates');
|
||||||
self::serveDocument(
|
self::serveDocument(
|
||||||
'zcfsupd.js',
|
'zcfsupd.js',
|
||||||
'text/javascript',
|
'text/javascript',
|
||||||
|
@ -83,8 +86,12 @@ class zcfsUrlHandler extends dcUrlHandlers
|
||||||
|
|
||||||
# Server feeds description page
|
# Server feeds description page
|
||||||
} elseif (in_array($args, ['', '/']) && $s->pub_active) {
|
} elseif (in_array($args, ['', '/']) && $s->pub_active) {
|
||||||
$tplset = dcCore::app()->themes->moduleInfo(dcCore::app()->blog->settings->system->theme, 'tplset');
|
$theme = dcCore::app()->blog->settings->get('system')->get('theme');
|
||||||
$path = __DIR__ . '/default-templates/';
|
if (!is_string($theme)) {
|
||||||
|
self::p404();
|
||||||
|
}
|
||||||
|
$tplset = dcCore::app()->themes->moduleInfo($theme, 'tplset');
|
||||||
|
$path = My::path() . '/default-templates/';
|
||||||
if (!empty($tplset) && is_dir($path . $tplset)) {
|
if (!empty($tplset) && is_dir($path . $tplset)) {
|
||||||
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), $path . $tplset);
|
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), $path . $tplset);
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,7 +103,5 @@ class zcfsUrlHandler extends dcUrlHandlers
|
||||||
else {
|
else {
|
||||||
self::p404();
|
self::p404();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
141
src/Widgets.php
141
src/Widgets.php
|
@ -10,38 +10,33 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->addBehavior(
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
'initWidgets',
|
|
||||||
['zoneclearFeedServerWidget', 'adminSource']
|
use dcCore;
|
||||||
);
|
use Dotclear\Helper\Html\Html;
|
||||||
dcCore::app()->addBehavior(
|
use Dotclear\Plugin\widgets\WidgetsStack;
|
||||||
'initWidgets',
|
use Dotclear\Plugin\widgets\WidgetsElement;
|
||||||
['zoneclearFeedServerWidget', 'adminNumber']
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
* Widgets.
|
||||||
* @brief Mix your blog with a feeds planet - widgets methods.
|
*
|
||||||
* @since 2.6
|
* A widget to list feeds source.
|
||||||
|
* A widget to list feeds statistics.
|
||||||
*/
|
*/
|
||||||
class zoneclearFeedServerWidget
|
class Widgets
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Widget configuration for sources list.
|
* @param WidgetsStack $w WidgetsStack instance
|
||||||
*
|
|
||||||
* @param dcWidgets $w dcWidgets instance
|
|
||||||
*/
|
*/
|
||||||
public static function adminSource($w)
|
public static function init(WidgetsStack $w): void
|
||||||
{
|
{
|
||||||
$w
|
$w
|
||||||
->create(
|
->create(
|
||||||
'zcfssource',
|
'zcfssource',
|
||||||
__('Feeds server: sources'),
|
__('Feeds server: sources'),
|
||||||
['zoneclearFeedServerWidget', 'publicSource'],
|
[self::class, 'publicSource'],
|
||||||
null,
|
null,
|
||||||
__('List sources of feeds')
|
__('List sources of feeds')
|
||||||
)
|
)
|
||||||
|
@ -85,20 +80,12 @@ class zoneclearFeedServerWidget
|
||||||
->addContentOnly()
|
->addContentOnly()
|
||||||
->addClass()
|
->addClass()
|
||||||
->addOffline();
|
->addOffline();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Widget configuration for feeds info.
|
|
||||||
*
|
|
||||||
* @param dcWidgets $w dcWidgets instance
|
|
||||||
*/
|
|
||||||
public static function adminNumber($w)
|
|
||||||
{
|
|
||||||
$w
|
$w
|
||||||
->create(
|
->create(
|
||||||
'zcfsnumber',
|
'zcfsnumber',
|
||||||
__('Feeds server: numbers'),
|
__('Feeds server: numbers'),
|
||||||
['zoneclearFeedServerWidget', 'publicNumber'],
|
[self::class, 'publicNumber'],
|
||||||
null,
|
null,
|
||||||
__('Show some numbers about feeds')
|
__('Show some numbers about feeds')
|
||||||
)
|
)
|
||||||
|
@ -144,59 +131,58 @@ class zoneclearFeedServerWidget
|
||||||
/**
|
/**
|
||||||
* Widget for sources list.
|
* Widget for sources list.
|
||||||
*
|
*
|
||||||
* @param dcWidget $w dcWidget instance
|
* @param WidgetsElement $w Widgets Element instance
|
||||||
*/
|
*/
|
||||||
public static function publicSource($w)
|
public static function publicSource(WidgetsElement $w): string
|
||||||
{
|
{
|
||||||
if ($w->offline) {
|
$z = ZoneclearFeedServer::instance();
|
||||||
return null;
|
$s = $z->settings;
|
||||||
}
|
|
||||||
|
|
||||||
if (!dcCore::app()->blog->settings->__get(basename(__DIR__))->active
|
if ($w->__get('offline')
|
||||||
|
|| !$s->active
|
||||||
|| !$w->checkHomeOnly(dcCore::app()->url->type)
|
|| !$w->checkHomeOnly(dcCore::app()->url->type)
|
||||||
) {
|
) {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$p = [];
|
$p = [];
|
||||||
$p['order'] = ($w->sortby && in_array($w->sortby, ['feed_upd_last', 'lowername', 'feed_creadt'])) ?
|
$p['order'] = ($w->__get('sortby') && in_array($w->__get('sortby'), ['feed_upd_last', 'lowername', 'feed_creadt'])) ?
|
||||||
$w->sortby . ' ' : 'feed_upd_last ';
|
$w->__get('sortby') . ' ' : 'feed_upd_last ';
|
||||||
$p['order'] .= $w->sort == 'desc' ? 'DESC' : 'ASC';
|
$p['order'] .= $w->__get('sort') == 'desc' ? 'DESC' : 'ASC';
|
||||||
$p['limit'] = abs((int) $w->limit);
|
$p['limit'] = is_numeric($w->__get('limit')) ? abs((int) $w->__get('limit')) : 10;
|
||||||
$p['feed_status'] = 1;
|
$p['feed_status'] = 1;
|
||||||
|
|
||||||
$zc = new zoneclearFeedServer();
|
$rs = $z->getFeeds($p);
|
||||||
$rs = $zc->getFeeds($p);
|
|
||||||
|
|
||||||
if ($rs->isEmpty()) {
|
if ($rs->isEmpty()) {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$lines = [];
|
$lines = [];
|
||||||
$i = 1;
|
$i = 1;
|
||||||
while ($rs->fetch()) {
|
while ($rs->fetch()) {
|
||||||
|
$row = new FeedRow($rs);
|
||||||
$lines[] = sprintf(
|
$lines[] = sprintf(
|
||||||
'<li><a href="%s" title="%s">%s</a></li>',
|
'<li><a href="%s" title="%s">%s</a></li>',
|
||||||
$rs->feed_url,
|
$row->url,
|
||||||
$rs->feed_owner,
|
$row->owner,
|
||||||
$rs->feed_name
|
$row->name
|
||||||
);
|
);
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
$pub = '';
|
$pub = '';
|
||||||
if ($w->pagelink && dcCore::app()->blog->settings->__get(basename(__DIR__))->pub_active) {
|
if ($w->__get('pagelink') && $s->pub_active) {
|
||||||
$pub = sprintf(
|
$pub = sprintf(
|
||||||
'<p><strong><a href="%s">%s</a></strong></p>',
|
'<p><strong><a href="%s">%s</a></strong></p>',
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase('zoneclearFeedsPage'),
|
dcCore::app()->blog?->url . dcCore::app()->url->getBase('zoneclearFeedsPage'),
|
||||||
html::escapeHTML($w->pagelink)
|
Html::escapeHTML(is_string($w->__get('pagelink')) ? $w->__get('pagelink') : '')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $w->renderDiv(
|
return $w->renderDiv(
|
||||||
$w->content_only,
|
(bool) $w->__get('content_only'),
|
||||||
'zoneclear-sources ' . $w->class,
|
'zoneclear-sources ' . $w->__get('class'),
|
||||||
'',
|
'',
|
||||||
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') .
|
($w->__get('title') ? $w->renderTitle(Html::escapeHTML(is_string($w->__get('title')) ? $w->__get('title') : '')) : '') .
|
||||||
sprintf('<ul>%s</ul>', implode('', $lines)) . $pub
|
sprintf('<ul>%s</ul>', implode('', $lines)) . $pub
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -204,38 +190,38 @@ class zoneclearFeedServerWidget
|
||||||
/**
|
/**
|
||||||
* Widget for feeds info.
|
* Widget for feeds info.
|
||||||
*
|
*
|
||||||
* @param dcWidget $w dcWidget instance
|
* @param WidgetsElement $w Widgets Element instance
|
||||||
*/
|
*/
|
||||||
public static function publicNumber($w)
|
public static function publicNumber(WidgetsElement $w): string
|
||||||
{
|
{
|
||||||
if ($w->offline) {
|
$z = ZoneclearFeedServer::instance();
|
||||||
return;
|
$s = $z->settings;
|
||||||
}
|
|
||||||
|
|
||||||
if (!dcCore::app()->blog->settings->__get(basename(__DIR__))->active
|
if ($w->__get('offline')
|
||||||
|
|| !$s->active
|
||||||
|| !$w->checkHomeOnly(dcCore::app()->url->type)
|
|| !$w->checkHomeOnly(dcCore::app()->url->type)
|
||||||
) {
|
) {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$zc = new zoneclearFeedServer();
|
|
||||||
$content = '';
|
$content = '';
|
||||||
|
|
||||||
# Feed
|
# Feed
|
||||||
if ($w->feed_show) {
|
if ($w->__get('feed_show')) {
|
||||||
$title = ($w->feed_title ? sprintf(
|
$title = ($w->__get('feed_title') ? sprintf(
|
||||||
'<strong>%s</strong> ',
|
'<strong>%s</strong> ',
|
||||||
html::escapeHTML($w->feed_title)
|
Html::escapeHTML(is_string($w->__get('feed_title')) ? $w->__get('feed_title') : '')
|
||||||
) : '');
|
) : '');
|
||||||
|
|
||||||
$count = $zc->getFeeds([], true)->f(0);
|
$count = $z->getFeeds([], true)->f(0);
|
||||||
|
$count = is_numeric($count) ? (int) $count : 0;
|
||||||
|
|
||||||
$text = $count ? sprintf(__('one source', '%d sources', $count), $count) : __('no sources');
|
$text = $count ? sprintf(__('one source', '%d sources', $count), $count) : __('no sources');
|
||||||
|
|
||||||
if (dcCore::app()->blog->settings->__get(basename(__DIR__))->pub_active) {
|
if ($s->pub_active) {
|
||||||
$text = sprintf(
|
$text = sprintf(
|
||||||
'<a href="%s">%s</a>',
|
'<a href="%s">%s</a>',
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase('zoneclearFeedsPage'),
|
dcCore::app()->blog?->url . dcCore::app()->url->getBase('zoneclearFeedsPage'),
|
||||||
$text
|
$text
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -244,18 +230,21 @@ class zoneclearFeedServerWidget
|
||||||
}
|
}
|
||||||
|
|
||||||
# Entry
|
# Entry
|
||||||
if ($w->entry_show) {
|
if ($w->__get('entry_show')) {
|
||||||
$count = 0;
|
$count = 0;
|
||||||
$feeds = $zc->getFeeds();
|
$feeds = $z->getFeeds();
|
||||||
|
|
||||||
if (!$feeds->isEmpty()) {
|
if (!$feeds->isEmpty()) {
|
||||||
while ($feeds->fetch()) {
|
while ($feeds->fetch()) {
|
||||||
$count += (int) $zc->getPostsByFeed(['feed_id' => $feeds->feed_id], true)->f(0);
|
$fid = is_numeric($feeds->f('feed_id')) ? (int) $feeds->f('feed_id') : 0;
|
||||||
|
$c = $z->getPostsByFeed(['feed_id' => $fid], true)->f(0);
|
||||||
|
$c = is_numeric($c) ? (int) $c : 0;
|
||||||
|
$count += $c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$title = ($w->entry_title ? sprintf(
|
$title = ($w->__get('entry_title') ? sprintf(
|
||||||
'<strong>%s</strong> ',
|
'<strong>%s</strong> ',
|
||||||
html::escapeHTML($w->entry_title)
|
Html::escapeHTML(is_string($w->__get('entry_title')) ? $w->__get('entry_title') : '')
|
||||||
) : '');
|
) : '');
|
||||||
|
|
||||||
$text = $count ? sprintf(__('one entry', '%d entries', $count), $count) : __('no entries');
|
$text = $count ? sprintf(__('one entry', '%d entries', $count), $count) : __('no entries');
|
||||||
|
@ -264,15 +253,15 @@ class zoneclearFeedServerWidget
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$content) {
|
if (!$content) {
|
||||||
return null;
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
# Display
|
# Display
|
||||||
return $w->renderDiv(
|
return $w->renderDiv(
|
||||||
$w->content_only,
|
(bool) $w->__get('content_only'),
|
||||||
'zoneclear-number ' . $w->class,
|
'zoneclear-number ' . $w->__get('class'),
|
||||||
'',
|
'',
|
||||||
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '') .
|
($w->__get('title') ? $w->renderTitle(Html::escapeHTML(is_string($w->__get('title')) ? $w->__get('title') : '')) : '') .
|
||||||
sprintf('<ul>%s</ul>', $content)
|
sprintf('<ul>%s</ul>', $content)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
976
src/ZoneclearFeedServer.php
Normal file
976
src/ZoneclearFeedServer.php
Normal file
|
@ -0,0 +1,976 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\zoneclearFeedServer;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcAuth;
|
||||||
|
use dcBlog;
|
||||||
|
use dcCategories;
|
||||||
|
use dcCore;
|
||||||
|
use dcMeta;
|
||||||
|
use dcUtils;
|
||||||
|
use Dotclear\Database\{
|
||||||
|
Cursor,
|
||||||
|
MetaRecord
|
||||||
|
};
|
||||||
|
use Dotclear\Database\Statement\{
|
||||||
|
DeleteStatement,
|
||||||
|
JoinStatement,
|
||||||
|
SelectStatement
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
use Dotclear\Helper\File\{
|
||||||
|
Files,
|
||||||
|
Path
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Html\Html;
|
||||||
|
use Dotclear\Helper\Network\Feed\{
|
||||||
|
Parser,
|
||||||
|
Reader
|
||||||
|
};
|
||||||
|
use Dotclear\Helper\Text;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main module class.
|
||||||
|
*/
|
||||||
|
class ZoneclearFeedServer
|
||||||
|
{
|
||||||
|
/** @var int Net HTTP feed reader timeout */
|
||||||
|
public const NET_HTTP_TIMEOUT = 5;
|
||||||
|
|
||||||
|
/** @var string Net HTTP feed reader agent */
|
||||||
|
public const NET_HTTP_AGENT = 'zoneclearFeedServer - http://zoneclear.org';
|
||||||
|
|
||||||
|
/** @var int Net HTTP feed reader max redirect */
|
||||||
|
public const NET_HTTP_MAX_REDIRECT = 2;
|
||||||
|
|
||||||
|
/** @var ZoneclearFeedServer Self instance */
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
/** @var Settings The settings instance */
|
||||||
|
public readonly Settings $settings;
|
||||||
|
|
||||||
|
/** @var null|resource $lock File lock for update */
|
||||||
|
private static $lock = null;
|
||||||
|
|
||||||
|
/** @var null|string $user Affiliate user ID */
|
||||||
|
private $user = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor load settings.
|
||||||
|
*/
|
||||||
|
protected function __construct()
|
||||||
|
{
|
||||||
|
$this->settings = Settings::instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get class instance.
|
||||||
|
*
|
||||||
|
* @return ZoneclearFeedServer Self instacne
|
||||||
|
*/
|
||||||
|
public static function instance(): ZoneclearFeedServer
|
||||||
|
{
|
||||||
|
if (!(self::$instance instanceof ZoneclearFeedServer)) {
|
||||||
|
self::$instance = new ZoneclearFeedServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open database table cursor.
|
||||||
|
*
|
||||||
|
* @return Cursor The cursor
|
||||||
|
*/
|
||||||
|
public function openCursor(): Cursor
|
||||||
|
{
|
||||||
|
return dcCore::app()->con->openCursor(dcCore::app()->prefix . My::TABLE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update feed record.
|
||||||
|
*
|
||||||
|
* @param int $id The feed ID
|
||||||
|
* @param Cursor $cur The cursor instance
|
||||||
|
*/
|
||||||
|
public function updateFeed(int $id, Cursor $cur): void
|
||||||
|
{
|
||||||
|
dcCore::app()->con->writeLock(dcCore::app()->prefix . My::TABLE_NAME);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($id < 1) {
|
||||||
|
throw new Exception(__('No such ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$cur->setField('feed_upddt', date('Y-m-d H:i:s'));
|
||||||
|
|
||||||
|
$cur->update(sprintf(
|
||||||
|
"WHERE feed_id = %s AND blog_id = '%s' ",
|
||||||
|
$id,
|
||||||
|
dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id)
|
||||||
|
));
|
||||||
|
dcCore::app()->con->unlock();
|
||||||
|
$this->trigger();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->con->unlock();
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerAfterUpdateFeed -- Cursor, int
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerAfterUpdateFeed', $cur, $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add feed record.
|
||||||
|
*
|
||||||
|
* @param Cursor $cur The cursor
|
||||||
|
*
|
||||||
|
* @return int The new feed ID
|
||||||
|
*/
|
||||||
|
public function addFeed(Cursor $cur): int
|
||||||
|
{
|
||||||
|
dcCore::app()->con->writeLock(dcCore::app()->prefix . My::TABLE_NAME);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$cur->setField('feed_id', $this->getNextId());
|
||||||
|
$cur->setField('blog_id', dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id));
|
||||||
|
$cur->setField('feed_creadt', date('Y-m-d H:i:s'));
|
||||||
|
$cur->setField('feed_upddt', date('Y-m-d H:i:s'));
|
||||||
|
|
||||||
|
//add getFeedCursor here
|
||||||
|
|
||||||
|
$cur->insert();
|
||||||
|
dcCore::app()->con->unlock();
|
||||||
|
$this->trigger();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->con->unlock();
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = is_numeric($cur->getField('feed_id')) ? (int) $cur->getField('feed_id') : 0;
|
||||||
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerAfterAddFeed -- Cursor, int
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerAfterAddFeed', $cur, $id);
|
||||||
|
|
||||||
|
return $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick enable / disable feed.
|
||||||
|
*
|
||||||
|
* @param int $id The feed ID
|
||||||
|
* @param bool $enable Enable feed
|
||||||
|
* @param int $time Force update time
|
||||||
|
*/
|
||||||
|
public function enableFeed(int $id, bool $enable = true, int $time = 0): void
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($id < 1) {
|
||||||
|
throw new Exception(__('No such ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$cur = $this->openCursor();
|
||||||
|
dcCore::app()->con->writeLock(dcCore::app()->prefix . My::TABLE_NAME);
|
||||||
|
|
||||||
|
$cur->setField('feed_upddt', date('Y-m-d H:i:s'));
|
||||||
|
$cur->setField('feed_status', (int) $enable);
|
||||||
|
if (0 < $time) {
|
||||||
|
$cur->setField('feed_upd_last', $time);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cur->update(sprintf(
|
||||||
|
"WHERE feed_id = %s AND blog_id = '%s' ",
|
||||||
|
$id,
|
||||||
|
dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id)
|
||||||
|
));
|
||||||
|
dcCore::app()->con->unlock();
|
||||||
|
$this->trigger();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->con->unlock();
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerAfterEnableFeed -- int, bool, int
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerAfterEnableFeed', $id, $enable, $time);
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
/**
|
||||||
|
* Delete record (this not deletes post).
|
||||||
|
*
|
||||||
|
* @param int $id The feed ID
|
||||||
|
*/
|
||||||
|
public function deleteFeed(int $id): void
|
||||||
|
{
|
||||||
|
if ($id < 1) {
|
||||||
|
throw new Exception(__('No such ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerBeforeDeleteFeed -- int
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerBeforeDeleteFeed', $id);
|
||||||
|
|
||||||
|
$sql = new DeleteStatement();
|
||||||
|
$sql->from(dcCore::app()->prefix . My::TABLE_NAME)
|
||||||
|
->where('feed_id ' . $sql->in($id))
|
||||||
|
->and('blog_id = ' . $sql->quote((string) dcCore::app()->blog?->id))
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
$this->trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all post(s) meta.
|
||||||
|
*
|
||||||
|
* This deletes all post(s) related meta,
|
||||||
|
* the post from the planet become an ordinary post.
|
||||||
|
*
|
||||||
|
* @param null|int $id The post ID (or null for all!)
|
||||||
|
*/
|
||||||
|
public static function deletePostsMeta(?int $id): void
|
||||||
|
{
|
||||||
|
$sql = new DeleteStatement();
|
||||||
|
$sql->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME)
|
||||||
|
->where('meta_type ' . $sql->in([
|
||||||
|
My::META_PREFIX . 'url',
|
||||||
|
My::META_PREFIX . 'author',
|
||||||
|
My::META_PREFIX . 'site',
|
||||||
|
My::META_PREFIX . 'sitename',
|
||||||
|
My::META_PREFIX . 'id',
|
||||||
|
]));
|
||||||
|
|
||||||
|
if (!is_null($post_id)) {
|
||||||
|
$sql->and('post_id = ' . $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get related posts.
|
||||||
|
*
|
||||||
|
* @param array<string,int|string|array> $params The query params
|
||||||
|
* @param bool $count_only Return only result count
|
||||||
|
*
|
||||||
|
* @return MetaRecord The record instance
|
||||||
|
*/
|
||||||
|
public function getPostsByFeed(array $params = [], bool $count_only = false): MetaRecord
|
||||||
|
{
|
||||||
|
if (!isset($params['feed_id']) || !is_numeric($params['feed_id'])) {
|
||||||
|
return MetaRecord::newFromArray([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$sql->join(
|
||||||
|
(new JoinStatement())
|
||||||
|
->left()
|
||||||
|
->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' F')
|
||||||
|
->on('P.post_id = F.post_id')
|
||||||
|
->statement()
|
||||||
|
);
|
||||||
|
|
||||||
|
$params['sql'] = "AND P.blog_id = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id) . "' " .
|
||||||
|
"AND F.meta_type = '" . My::META_PREFIX . "id' " .
|
||||||
|
"AND F.meta_id = '" . dcCore::app()->con->escapeStr((string) $params['feed_id']) . "' ";
|
||||||
|
|
||||||
|
unset($params['feed_id']);
|
||||||
|
|
||||||
|
$rs = dcCore::app()->blog?->getPosts($params, $count_only, $sql);
|
||||||
|
|
||||||
|
return is_null($rs) ? MetaRecord::newFromArray([]) : $rs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get feed record.
|
||||||
|
*
|
||||||
|
* @param array<string,int|string|array> $params The query params
|
||||||
|
* @param bool $count_only Return only result count
|
||||||
|
*
|
||||||
|
* @return MetaRecord The record instance
|
||||||
|
*/
|
||||||
|
public function getFeeds(array $params = [], bool $count_only = false): MetaRecord
|
||||||
|
{
|
||||||
|
if ($count_only) {
|
||||||
|
$strReq = 'SELECT count(Z.feed_id) ';
|
||||||
|
} else {
|
||||||
|
$content_req = '';
|
||||||
|
if (!empty($params['columns']) && is_array($params['columns'])) {
|
||||||
|
$content_req .= implode(', ', $params['columns']) . ', ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$strReq = 'SELECT Z.feed_id, Z.feed_creadt, Z.feed_upddt, Z.feed_type, ' .
|
||||||
|
'Z.blog_id, Z.cat_id, ' .
|
||||||
|
'Z.feed_upd_int, Z.feed_upd_last, Z.feed_status, ' .
|
||||||
|
$content_req .
|
||||||
|
'LOWER(Z.feed_name) as lowername, Z.feed_name, Z.feed_desc, ' .
|
||||||
|
'Z.feed_url, Z.feed_feed, Z.feed_get_tags, ' .
|
||||||
|
'Z.feed_tags, Z.feed_owner, Z.feed_tweeter, Z.feed_lang, ' .
|
||||||
|
'Z.feed_nb_out, Z.feed_nb_in, ' .
|
||||||
|
'C.cat_title, C.cat_url, C.cat_desc ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$strReq .= 'FROM ' . dcCore::app()->prefix . My::TABLE_NAME . ' Z ' .
|
||||||
|
'LEFT OUTER JOIN ' . dcCore::app()->prefix . dcCategories::CATEGORY_TABLE_NAME . ' C ON Z.cat_id = C.cat_id ';
|
||||||
|
|
||||||
|
if (!empty($params['from']) && is_string($params['from'])) {
|
||||||
|
$strReq .= $params['from'] . ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$strReq .= "WHERE Z.blog_id = '" . dcCore::app()->con->escapeStr((string) dcCore::app()->blog?->id) . "' ";
|
||||||
|
|
||||||
|
if (isset($params['feed_type']) && is_string($params['feed_type'])) {
|
||||||
|
$strReq .= "AND Z.feed_type = '" . dcCore::app()->con->escapeStr((string) $params['feed_type']) . "' ";
|
||||||
|
} else {
|
||||||
|
$strReq .= "AND Z.feed_type = 'feed' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($params['feed_id'])) {
|
||||||
|
if (is_array($params['feed_id'])) {
|
||||||
|
array_walk($params['feed_id'], function (&$v, $k) { if ($v !== null) { $v = (int) $v; }});
|
||||||
|
} elseif (is_numeric($params['feed_id'])) {
|
||||||
|
$params['feed_id'] = [(int) $params['feed_id']];
|
||||||
|
}
|
||||||
|
$strReq .= 'AND Z.feed_id ' . dcCore::app()->con->in($params['feed_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($params['feed_feed']) && is_string($params['feed_feed'])) {
|
||||||
|
$strReq .= "AND Z.feed_feed = '" . dcCore::app()->con->escapeStr((string) $params['feed_feed']) . "' ";
|
||||||
|
}
|
||||||
|
if (isset($params['feed_url']) && is_string($params['feed_url'])) {
|
||||||
|
$strReq .= "AND Z.feed_url = '" . dcCore::app()->con->escapeStr((string) $params['feed_url']) . "' ";
|
||||||
|
}
|
||||||
|
if (isset($params['feed_status'])) {
|
||||||
|
$strReq .= 'AND Z.feed_status = ' . ((int) $params['feed_status']) . ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($params['q']) && is_string($params['q'])) {
|
||||||
|
$q = dcCore::app()->con->escapeStr((string) str_replace('*', '%', strtolower($params['q'])));
|
||||||
|
$strReq .= "AND LOWER(Z.feed_name) LIKE '" . $q . "' ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($params['sql']) && is_string($params['sql'])) {
|
||||||
|
$strReq .= $params['sql'] . ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$count_only) {
|
||||||
|
if (!empty($params['order']) && is_string($params['order'])) {
|
||||||
|
$strReq .= 'ORDER BY ' . dcCore::app()->con->escapeStr((string) $params['order']) . ' ';
|
||||||
|
} else {
|
||||||
|
$strReq .= 'ORDER BY Z.feed_upddt DESC ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$count_only && isset($params['limit'])) {
|
||||||
|
if (is_numeric($params['limit'])) {
|
||||||
|
$params['limit'] = (int) $params['limit'];
|
||||||
|
}
|
||||||
|
if (is_int($params['limit']) || is_array($params['limit'])) {
|
||||||
|
$strReq .= dcCore::app()->con->limit($params['limit']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MetaRecord(dcCore::app()->con->select($strReq));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get next table id.
|
||||||
|
*
|
||||||
|
* @return int THe next ID
|
||||||
|
*/
|
||||||
|
private function getNextId(): int
|
||||||
|
{
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$rs = $sql
|
||||||
|
->column($sql->max('feed_id'))
|
||||||
|
->from(dcCore::app()->prefix . My::TABLE_NAME)
|
||||||
|
->select();
|
||||||
|
|
||||||
|
return (int) $rs?->f(0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock a file to see if an update is ongoing.
|
||||||
|
*
|
||||||
|
* @return bool True if file is locked
|
||||||
|
*/
|
||||||
|
public function lockUpdate()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
# Need flock function
|
||||||
|
if (!function_exists('flock')) {
|
||||||
|
throw new Exception("Can't call php function named flock");
|
||||||
|
}
|
||||||
|
# Cache writable ?
|
||||||
|
if (!is_writable(DC_TPL_CACHE)) {
|
||||||
|
throw new Exception("Can't write in cache fodler");
|
||||||
|
}
|
||||||
|
# Set file path
|
||||||
|
$f_md5 = md5((string) dcCore::app()->blog?->id);
|
||||||
|
$cached_file = sprintf(
|
||||||
|
'%s/%s/%s/%s/%s.txt',
|
||||||
|
DC_TPL_CACHE,
|
||||||
|
'periodical',
|
||||||
|
substr($f_md5, 0, 2),
|
||||||
|
substr($f_md5, 2, 2),
|
||||||
|
$f_md5
|
||||||
|
);
|
||||||
|
# Real path
|
||||||
|
$cached_file = Path::real($cached_file, false);
|
||||||
|
if (false === $cached_file) {
|
||||||
|
throw new Exception("Can't get cache file path");
|
||||||
|
}
|
||||||
|
# Make dir
|
||||||
|
if (!is_dir(dirname($cached_file))) {
|
||||||
|
Files::makeDir(dirname($cached_file), true);
|
||||||
|
}
|
||||||
|
# Make file
|
||||||
|
if (!file_exists($cached_file)) {
|
||||||
|
!$fp = @fopen($cached_file, 'w');
|
||||||
|
if ($fp === false) {
|
||||||
|
throw new Exception("Can't create file");
|
||||||
|
}
|
||||||
|
fwrite($fp, '1', strlen('1'));
|
||||||
|
fclose($fp);
|
||||||
|
}
|
||||||
|
# Open file
|
||||||
|
if (!($fp = @fopen($cached_file, 'r+'))) {
|
||||||
|
throw new Exception("Can't open file");
|
||||||
|
}
|
||||||
|
# Lock file
|
||||||
|
if (!flock($fp, LOCK_EX)) {
|
||||||
|
throw new Exception("Can't lock file");
|
||||||
|
}
|
||||||
|
self::$lock = $fp;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlock file of update process.
|
||||||
|
*/
|
||||||
|
public function unlockUpdate(): void
|
||||||
|
{
|
||||||
|
if (!is_null(self::$lock)) {
|
||||||
|
@fclose(self::$lock);
|
||||||
|
self::$lock = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check and add/update post related to record if needed.
|
||||||
|
*
|
||||||
|
* @param int $id The feed ID
|
||||||
|
* @param bool $throw Throw exception or end silently
|
||||||
|
*
|
||||||
|
* @return bool True on success
|
||||||
|
*/
|
||||||
|
public function checkFeedsUpdate(int $id = 0, bool $throw = false): bool
|
||||||
|
{
|
||||||
|
$s = $this->settings;
|
||||||
|
|
||||||
|
# Not configured
|
||||||
|
if (is_null(dcCore::app()->auth) || !$s->active || !$s->user) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Limit to one update at a time
|
||||||
|
try {
|
||||||
|
$this->lockUpdate();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
if ($throw) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tz = dcCore::app()->blog?->settings->get('system')->get('blog_timezone');
|
||||||
|
Date::setTZ(is_string($tz) ? $tz : 'UTC');
|
||||||
|
$time = time();
|
||||||
|
|
||||||
|
# All feeds or only one (from admin)
|
||||||
|
$f = !$id ?
|
||||||
|
$this->getFeeds(['feed_status' => 1, 'order' => 'feed_upd_last ASC']) :
|
||||||
|
$this->getFeeds(['feed_id' => $id]);
|
||||||
|
|
||||||
|
# No feed
|
||||||
|
if ($f->isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$enabled = false;
|
||||||
|
$updates = false;
|
||||||
|
$loop_mem = [];
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
$cur_post = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME);
|
||||||
|
$cur_meta = dcCore::app()->con->openCursor(dcCore::app()->prefix . dcMeta::META_TABLE_NAME);
|
||||||
|
|
||||||
|
while ($f->fetch()) {
|
||||||
|
$row = new FeedRow($f);
|
||||||
|
# Check if feed need update
|
||||||
|
if ($id
|
||||||
|
|| $i < $s->update_limit && $row->status == 1 && ($time > $row->upd_last + $row->upd_int)
|
||||||
|
) {
|
||||||
|
if (!$enabled) {
|
||||||
|
# Set feeds user
|
||||||
|
$this->enableUser(true);
|
||||||
|
$enabled = true;
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
$feed = self::readFeed($row->feed);
|
||||||
|
|
||||||
|
# Nothing to parse
|
||||||
|
if (!$feed) {
|
||||||
|
# Keep active empty feed or disable it ?
|
||||||
|
if (!$s->keep_empty_feed) {
|
||||||
|
$this->enableFeed($row->id, false);
|
||||||
|
} else {
|
||||||
|
# Set update time of this feed
|
||||||
|
$this->enableFeed($row->id, true, $time);
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
|
|
||||||
|
# Not updated since last visit
|
||||||
|
} elseif (!$id
|
||||||
|
&& '' != $feed->pubdate
|
||||||
|
&& strtotime($feed->pubdate) < $row->upd_last
|
||||||
|
) {
|
||||||
|
# Set update time of this feed
|
||||||
|
$this->enableFeed($row->id, true, $time);
|
||||||
|
$i++;
|
||||||
|
} else {
|
||||||
|
# Set update time of this feed
|
||||||
|
$this->enableFeed($row->id, (bool) $row->status, $time);
|
||||||
|
|
||||||
|
dcCore::app()->con->begin();
|
||||||
|
|
||||||
|
foreach ($feed->items as $item) {
|
||||||
|
$item_TS = $item->TS ? $item->TS : $time;
|
||||||
|
|
||||||
|
// I found that mercurial atom feed did not repect standard
|
||||||
|
$item_link = @$item->link;
|
||||||
|
if (!$item_link) {
|
||||||
|
$item_link = @$item->guid;
|
||||||
|
}
|
||||||
|
# Unknow feed item link
|
||||||
|
if (!$item_link) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$item_link = dcCore::app()->con->escapeStr((string) $item_link);
|
||||||
|
$is_new_published_entry = false;
|
||||||
|
|
||||||
|
# Not updated since last visit
|
||||||
|
if (!$id && $item_TS < $row->upd_last) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fix loop twin
|
||||||
|
if (in_array($item_link, $loop_mem)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$loop_mem[] = $item_link;
|
||||||
|
|
||||||
|
# Check if entry exists
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$old_post = $sql
|
||||||
|
->columns([
|
||||||
|
'P.post_id',
|
||||||
|
'P.post_status',
|
||||||
|
])
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME, 'P'))
|
||||||
|
->join(
|
||||||
|
(new JoinStatement())
|
||||||
|
->inner()
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcMeta::META_TABLE_NAME, 'M'))
|
||||||
|
->on('P.post_id = M.post_id')
|
||||||
|
->statement()
|
||||||
|
)
|
||||||
|
->where('blog_id = ' . $sql->quote((string) dcCore::app()->blog?->id))
|
||||||
|
->and("meta_type = '" . My::META_PREFIX . "url'")
|
||||||
|
->and('meta_id = ' . $sql->quote($item_link))
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if (is_null($old_post)) {
|
||||||
|
$old_post = MetaRecord::newFromArray([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prepare entry Cursor
|
||||||
|
$cur_post->clean();
|
||||||
|
$cur_post->setField('post_dt', date('Y-m-d H:i:s', $item_TS));
|
||||||
|
if ($row->cat_id) {
|
||||||
|
$cur_post->setField('cat_id', $row->cat_id);
|
||||||
|
}
|
||||||
|
$post_content = $item->content ? $item->content : $item->description;
|
||||||
|
$cur_post->setField('post_format', 'xhtml');
|
||||||
|
$cur_post->setField('post_content', Html::absoluteURLs($post_content, $feed->link));
|
||||||
|
$cur_post->setField('post_title', $item->title ? $item->title : Text::cutString(Html::clean(is_string($cur_post->getField('post_content')) ? $cur_post->getField('post_content') : ''), 60));
|
||||||
|
$creator = $item->creator ? $item->creator : $row->owner;
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Create entry
|
||||||
|
if ($old_post->isEmpty()) {
|
||||||
|
# Post
|
||||||
|
$cur_post->setField('user_id', dcCore::app()->auth->userID());
|
||||||
|
$cur_post->setField('post_format', 'xhtml');
|
||||||
|
$cur_post->setField('post_status', $s->post_status_new);
|
||||||
|
$cur_post->setField('post_open_comment', 0);
|
||||||
|
$cur_post->setField('post_open_tb', 0);
|
||||||
|
|
||||||
|
$post_id = dcCore::app()->auth->sudo(
|
||||||
|
[dcCore::app()->blog, 'addPost'],
|
||||||
|
$cur_post
|
||||||
|
);
|
||||||
|
|
||||||
|
# Auto tweet new post
|
||||||
|
if (!empty($cur_post->getField('post_status'))) {
|
||||||
|
$is_new_published_entry = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update entry
|
||||||
|
} else {
|
||||||
|
$post_id = is_numeric($old_post->f('post_id')) ? (int) $old_post->f('post_id') : 0;
|
||||||
|
|
||||||
|
dcCore::app()->auth->sudo(
|
||||||
|
[dcCore::app()->blog, 'updPost'],
|
||||||
|
$post_id,
|
||||||
|
$cur_post
|
||||||
|
);
|
||||||
|
|
||||||
|
# Quick delete old meta
|
||||||
|
$sql = new DeleteStatement();
|
||||||
|
$sql->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME)
|
||||||
|
->where('post_id = ' . $post_id)
|
||||||
|
->and($sql->like('meta_type', My::META_PREFIX . '%'))
|
||||||
|
->delete();
|
||||||
|
|
||||||
|
# Delete old tags
|
||||||
|
dcCore::app()->auth->sudo(
|
||||||
|
[dcCore::app()->meta, 'delPostMeta'],
|
||||||
|
$post_id,
|
||||||
|
'tag'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Quick add new meta
|
||||||
|
|
||||||
|
$cur_meta->clean();
|
||||||
|
$cur_meta->setField('post_id', $post_id);
|
||||||
|
$cur_meta->setField('meta_type', My::META_PREFIX . 'url');
|
||||||
|
$cur_meta->setField('meta_id', $item_link);
|
||||||
|
$cur_meta->insert();
|
||||||
|
|
||||||
|
$cur_meta->clean();
|
||||||
|
$cur_meta->setField('post_id', $post_id);
|
||||||
|
$cur_meta->setField('meta_type', My::META_PREFIX . 'author');
|
||||||
|
$cur_meta->setField('meta_id', $creator);
|
||||||
|
$cur_meta->insert();
|
||||||
|
|
||||||
|
$cur_meta->clean();
|
||||||
|
$cur_meta->setField('post_id', $post_id);
|
||||||
|
$cur_meta->setField('meta_type', My::META_PREFIX . 'site');
|
||||||
|
$cur_meta->setField('meta_id', $row->url);
|
||||||
|
$cur_meta->insert();
|
||||||
|
|
||||||
|
$cur_meta->clean();
|
||||||
|
$cur_meta->setField('post_id', $post_id);
|
||||||
|
$cur_meta->setField('meta_type', My::META_PREFIX . 'sitename');
|
||||||
|
$cur_meta->setField('meta_id', $row->name);
|
||||||
|
$cur_meta->insert();
|
||||||
|
|
||||||
|
$cur_meta->clean();
|
||||||
|
$cur_meta->setField('post_id', $post_id);
|
||||||
|
$cur_meta->setField('meta_type', My::META_PREFIX . 'id');
|
||||||
|
$cur_meta->setField('meta_id', $row->id);
|
||||||
|
$cur_meta->insert();
|
||||||
|
|
||||||
|
# Add new tags
|
||||||
|
$tags = dcCore::app()->meta->splitMetaValues($row->tags);
|
||||||
|
if ($row->get_tags) {
|
||||||
|
# Some feed subjects contains more than one tag
|
||||||
|
foreach ($item->subject as $subjects) {
|
||||||
|
$tmp = dcCore::app()->meta->splitMetaValues($subjects);
|
||||||
|
$tags = array_merge($tags, $tmp);
|
||||||
|
}
|
||||||
|
$tags = array_unique($tags);
|
||||||
|
}
|
||||||
|
$formated_tags = [];
|
||||||
|
foreach ($tags as $tag) {
|
||||||
|
# Change tags case
|
||||||
|
switch ((int) $s->tag_case) {
|
||||||
|
case 3: $tag = strtoupper($tag);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 2: $tag = strtolower($tag);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1: $tag = ucfirst(strtolower($tag));
|
||||||
|
|
||||||
|
break;
|
||||||
|
default: /* do nothing */ break;
|
||||||
|
}
|
||||||
|
if (!in_array($tag, $formated_tags)) {
|
||||||
|
$formated_tags[] = $tag;
|
||||||
|
dcCore::app()->auth->sudo(
|
||||||
|
[dcCore::app()->meta, 'delPostMeta'],
|
||||||
|
$post_id,
|
||||||
|
'tag',
|
||||||
|
dcMeta::sanitizeMetaID($tag)
|
||||||
|
);
|
||||||
|
dcCore::app()->auth->sudo(
|
||||||
|
[dcCore::app()->meta, 'setPostMeta'],
|
||||||
|
$post_id,
|
||||||
|
'tag',
|
||||||
|
dcMeta::sanitizeMetaID($tag)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->con->rollback();
|
||||||
|
$this->enableUser(false);
|
||||||
|
$this->unlockUpdate();
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerAfterCheckFeedUpdate -- FeedRow
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerAfterCheckFeedUpdate', $row);
|
||||||
|
}
|
||||||
|
dcCore::app()->con->commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($enabled) {
|
||||||
|
$this->enableUser(false);
|
||||||
|
}
|
||||||
|
$this->unlockUpdate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set permission to update post table.
|
||||||
|
*
|
||||||
|
* @param boolean $enable Enable or disable perm
|
||||||
|
*/
|
||||||
|
public function enableUser(bool $enable = false): void
|
||||||
|
{
|
||||||
|
if (is_null(dcCore::app()->auth)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enable
|
||||||
|
if ($enable) {
|
||||||
|
// backup current user
|
||||||
|
if (!is_null(dcCore::app()->auth->userID()) && !is_string(dcCore::app()->auth->userID())) {
|
||||||
|
throw new Exception('Unable to backup user');
|
||||||
|
}
|
||||||
|
$this->user = dcCore::app()->auth->userID();
|
||||||
|
// set zcfs posts user
|
||||||
|
if (!dcCore::app()->auth->checkUser($this->settings->user)) {
|
||||||
|
throw new Exception('Unable to set user');
|
||||||
|
}
|
||||||
|
# Disable
|
||||||
|
} else {
|
||||||
|
dcCore::app()->auth = null;
|
||||||
|
dcCore::app()->auth = new dcAuth();
|
||||||
|
// restore current user
|
||||||
|
dcCore::app()->auth->checkUser($this->user ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read and parse external feeds.
|
||||||
|
*
|
||||||
|
* @param string $url The feed URL
|
||||||
|
*
|
||||||
|
* @return Parser|false The parsed feed
|
||||||
|
*/
|
||||||
|
public static function readFeed(string $url): false|Parser
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$feed_reader = new Reader();
|
||||||
|
$feed_reader->setCacheDir(DC_TPL_CACHE);
|
||||||
|
$feed_reader->setTimeout(self::NET_HTTP_TIMEOUT);
|
||||||
|
$feed_reader->setMaxRedirects(self::NET_HTTP_MAX_REDIRECT);
|
||||||
|
$feed_reader->setUserAgent(self::NET_HTTP_AGENT);
|
||||||
|
|
||||||
|
return $feed_reader->parse($url);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger blog.
|
||||||
|
*/
|
||||||
|
private function trigger(): void
|
||||||
|
{
|
||||||
|
dcCore::app()->blog?->triggerBlog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an URL is well formed.
|
||||||
|
*
|
||||||
|
* @param string $url The URL
|
||||||
|
*
|
||||||
|
* @return bool True if URL is allowed
|
||||||
|
*/
|
||||||
|
public static function validateURL(string $url): bool
|
||||||
|
{
|
||||||
|
return false !== strpos($url, 'http://')
|
||||||
|
|| false !== strpos($url, 'https://');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get full URL.
|
||||||
|
*
|
||||||
|
* Know bugs: anchor is not well parsed.
|
||||||
|
*
|
||||||
|
* @param string $root The root URL
|
||||||
|
* @param string $url A URL
|
||||||
|
*
|
||||||
|
* @return string The parse URL
|
||||||
|
*/
|
||||||
|
public static function absoluteURL(string $root, string $url): string
|
||||||
|
{
|
||||||
|
$host = preg_replace(
|
||||||
|
'|^([a-z]{3,}://)(.*?)/(.*)$|',
|
||||||
|
'$1$2',
|
||||||
|
$root
|
||||||
|
);
|
||||||
|
|
||||||
|
$parse = parse_url($url);
|
||||||
|
|
||||||
|
if (empty($parse['scheme'])) {
|
||||||
|
if (strpos($url, '/') === 0) {
|
||||||
|
$url = $host . $url;
|
||||||
|
} elseif (strpos($url, '#') === 0) {
|
||||||
|
$url = $root . $url;
|
||||||
|
} elseif (preg_match('|/$|', $root)) {
|
||||||
|
$url = $root . $url;
|
||||||
|
} else {
|
||||||
|
$url = dirname($root) . '/' . $url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of (super)admins of current blog.
|
||||||
|
*
|
||||||
|
* @return array<string,string> List of UserCNs/UserIds
|
||||||
|
*/
|
||||||
|
public function getAllBlogAdmins(): array
|
||||||
|
{
|
||||||
|
$admins = [];
|
||||||
|
|
||||||
|
# Get super admins
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$rs = $sql
|
||||||
|
->from(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME)
|
||||||
|
->columns([
|
||||||
|
'user_id',
|
||||||
|
'user_super',
|
||||||
|
'user_name',
|
||||||
|
'user_firstname',
|
||||||
|
'user_displayname',
|
||||||
|
])
|
||||||
|
->where('user_super = 1')
|
||||||
|
->and('user_status = 1')
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if (!is_null($rs) && !$rs->isEmpty()) {
|
||||||
|
while ($rs->fetch()) {
|
||||||
|
$user_cn = dcUtils::getUserCN(
|
||||||
|
$rs->f('user_id'),
|
||||||
|
$rs->f('user_name'),
|
||||||
|
$rs->f('user_firstname'),
|
||||||
|
$rs->f('user_displayname')
|
||||||
|
);
|
||||||
|
$admins[$user_cn . ' (super admin)'] = $rs->f('user_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get admins
|
||||||
|
$sql = new SelectStatement();
|
||||||
|
$rs = $sql
|
||||||
|
->columns([
|
||||||
|
'U.user_id',
|
||||||
|
'U.user_super',
|
||||||
|
'U.user_name',
|
||||||
|
'U.user_firstname',
|
||||||
|
'U.user_displayname',
|
||||||
|
])
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME, 'U'))
|
||||||
|
->join(
|
||||||
|
(new JoinStatement())
|
||||||
|
->left()
|
||||||
|
->from($sql->as(dcCore::app()->prefix . dcAuth::PERMISSIONS_TABLE_NAME, 'P'))
|
||||||
|
->on('U.user_id = P.user_id')
|
||||||
|
->statement()
|
||||||
|
)
|
||||||
|
->where('U.user_status = 1')
|
||||||
|
->and('P.blog_id = ' . $sql->quote((string) dcCore::app()->blog?->id))
|
||||||
|
->and($sql->like('P.permissions', '%|admin|%'))
|
||||||
|
->select();
|
||||||
|
|
||||||
|
if (!is_null($rs) && !$rs->isEmpty()) {
|
||||||
|
while ($rs->fetch()) {
|
||||||
|
$user_cn = dcUtils::getUserCN(
|
||||||
|
$rs->f('user_id'),
|
||||||
|
$rs->f('user_name'),
|
||||||
|
$rs->f('user_firstname'),
|
||||||
|
$rs->f('user_displayname')
|
||||||
|
);
|
||||||
|
$admins[$user_cn . ' (admin)'] = $rs->f('user_id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $admins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of urls where entries could be hacked.
|
||||||
|
*
|
||||||
|
* @return array<string,string> List of names/types of URLs
|
||||||
|
*/
|
||||||
|
public static function getPublicUrlTypes(): array
|
||||||
|
{
|
||||||
|
$types = new ArrayObject([
|
||||||
|
__('Home page') => 'default',
|
||||||
|
__('Entries pages') => 'post',
|
||||||
|
__('Tags pages') => 'tag',
|
||||||
|
__('Archives pages') => 'archive',
|
||||||
|
__('Category pages') => 'category',
|
||||||
|
__('Entries feed') => 'feed',
|
||||||
|
]);
|
||||||
|
|
||||||
|
# --BEHAVIOR-- zoneclearFeedServerPublicUrlTypes -- ArrayObject
|
||||||
|
dcCore::app()->callBehavior('zoneclearFeedServerPublicUrlTypes', $types);
|
||||||
|
|
||||||
|
return $types->getArrayCopy();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,925 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* @brief zoneclearFeedServer, a plugin for Dotclear 2
|
|
||||||
*
|
|
||||||
* @package Dotclear
|
|
||||||
* @subpackage Plugin
|
|
||||||
*
|
|
||||||
* @author Jean-Christian Denis, BG, Pierre Van Glabeke
|
|
||||||
*
|
|
||||||
* @copyright Jean-Christian Denis
|
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
|
||||||
*/
|
|
||||||
if (!defined('DC_RC_PATH')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
|
|
||||||
* @brief Feeds server - main methods
|
|
||||||
* @since 2.6
|
|
||||||
*/
|
|
||||||
class zoneclearFeedServer
|
|
||||||
{
|
|
||||||
public static $nethttp_timeout = 5;
|
|
||||||
public static $nethttp_agent = 'zoneclearFeedServer - http://zoneclear.org';
|
|
||||||
public static $nethttp_maxredirect = 2;
|
|
||||||
|
|
||||||
public $con;
|
|
||||||
private $blog;
|
|
||||||
private $table;
|
|
||||||
private $lock = null;
|
|
||||||
private $user = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->con = dcCore::app()->con;
|
|
||||||
$this->blog = dcCore::app()->con->escape(dcCore::app()->blog->id);
|
|
||||||
$this->table = dcCore::app()->prefix . initZoneclearFeedServer::TABLE_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Short openCursor.
|
|
||||||
*
|
|
||||||
* @return cursor cursor instance
|
|
||||||
*/
|
|
||||||
public function openCursor()
|
|
||||||
{
|
|
||||||
return $this->con->openCursor($this->table);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update feed record.
|
|
||||||
*
|
|
||||||
* @param integer $id Feed id
|
|
||||||
* @param cursor $cur cursor instance
|
|
||||||
*/
|
|
||||||
public function updFeed($id, cursor $cur)
|
|
||||||
{
|
|
||||||
$this->con->writeLock($this->table);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$id = (int) $id;
|
|
||||||
|
|
||||||
if ($id < 1) {
|
|
||||||
throw new Exception(__('No such ID'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$cur->feed_upddt = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
$cur->update(sprintf(
|
|
||||||
"WHERE feed_id = %s AND blog_id = '%s' ",
|
|
||||||
$id,
|
|
||||||
$this->blog
|
|
||||||
));
|
|
||||||
$this->con->unlock();
|
|
||||||
$this->trigger();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->con->unlock();
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerAfterUpdFeed
|
|
||||||
dcCore::app()->callBehavior('zoneclearFeedServerAfterUpdFeed', $cur, $id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add feed record.
|
|
||||||
*
|
|
||||||
* @param cursor $cur cursor instance
|
|
||||||
*/
|
|
||||||
public function addFeed(cursor $cur)
|
|
||||||
{
|
|
||||||
$this->con->writeLock($this->table);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$cur->feed_id = $this->getNextId();
|
|
||||||
$cur->blog_id = $this->blog;
|
|
||||||
$cur->feed_creadt = date('Y-m-d H:i:s');
|
|
||||||
$cur->feed_upddt = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
//add getFeedCursor here
|
|
||||||
|
|
||||||
$cur->insert();
|
|
||||||
$this->con->unlock();
|
|
||||||
$this->trigger();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->con->unlock();
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerAfterAddFeed
|
|
||||||
dcCore::app()->callBehavior('zoneclearFeedServerAfterAddFeed', $cur);
|
|
||||||
|
|
||||||
return $cur->feed_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quick enable / disable feed.
|
|
||||||
*
|
|
||||||
* @param integer $id Feed Id
|
|
||||||
* @param boolean $enable Enable or disable feed
|
|
||||||
* @param integer $time Force update time
|
|
||||||
*/
|
|
||||||
public function enableFeed($id, $enable = true, $time = null)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$id = (int) $id;
|
|
||||||
|
|
||||||
if ($id < 1) {
|
|
||||||
throw new Exception(__('No such ID'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$cur = $this->openCursor();
|
|
||||||
$this->con->writeLock($this->table);
|
|
||||||
|
|
||||||
$cur->feed_upddt = date('Y-m-d H:i:s');
|
|
||||||
$cur->feed_status = (int) $enable;
|
|
||||||
if (null !== $time) {
|
|
||||||
$cur->feed_upd_last = (int) $time;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cur->update(sprintf(
|
|
||||||
"WHERE feed_id = %s AND blog_id = '%s' ",
|
|
||||||
$id,
|
|
||||||
$this->blog
|
|
||||||
));
|
|
||||||
$this->con->unlock();
|
|
||||||
$this->trigger();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->con->unlock();
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerAfterEnableFeed
|
|
||||||
dcCore::app()->callBehavior('zoneclearFeedServerAfterEnableFeed', $id, $enable, $time);
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
/**
|
|
||||||
* Delete record (this not deletes post).
|
|
||||||
*
|
|
||||||
* @param integer $id Feed Id
|
|
||||||
*/
|
|
||||||
public function delFeed($id)
|
|
||||||
{
|
|
||||||
$id = (int) $id;
|
|
||||||
|
|
||||||
if ($id < 1) {
|
|
||||||
throw new Exception(__('No such ID'));
|
|
||||||
}
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerBeforeDelFeed
|
|
||||||
dcCore::app()->callBehavior('zoneclearFeedServerBeforeDelFeed', $id);
|
|
||||||
|
|
||||||
$this->con->execute(sprintf(
|
|
||||||
"DELETE FROM %s WHERE feed_id = %s AND blog_id = '%s' ",
|
|
||||||
$this->table,
|
|
||||||
$id,
|
|
||||||
$this->blog
|
|
||||||
));
|
|
||||||
$this->trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get related posts.
|
|
||||||
*
|
|
||||||
* @param array $params Query params
|
|
||||||
* @param boolean $count_only Return only result count
|
|
||||||
* @return null|dcRecord record instance
|
|
||||||
*/
|
|
||||||
public function getPostsByFeed($params = [], $count_only = false)
|
|
||||||
{
|
|
||||||
if (!isset($params['feed_id'])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql = new dcSelectStatement();
|
|
||||||
$sql->join(
|
|
||||||
(new dcJoinStatement())
|
|
||||||
->type('LEFT')
|
|
||||||
->from(dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' F')
|
|
||||||
->on('P.post_id = F.post_id')
|
|
||||||
->statement()
|
|
||||||
);
|
|
||||||
|
|
||||||
$params['sql'] = "AND P.blog_id = '" . $this->blog . "' " .
|
|
||||||
"AND F.meta_type = 'zoneclearfeed_id' " .
|
|
||||||
"AND F.meta_id = '" . $this->con->escape($params['feed_id']) . "' ";
|
|
||||||
|
|
||||||
unset($params['feed_id']);
|
|
||||||
|
|
||||||
return dcCore::app()->blog->getPosts($params, $count_only, $sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get feed record.
|
|
||||||
*
|
|
||||||
* @param array $params Query params
|
|
||||||
* @param boolean $count_only Return only result count
|
|
||||||
* @return dcRecord record instance
|
|
||||||
*/
|
|
||||||
public function getFeeds($params = [], $count_only = false)
|
|
||||||
{
|
|
||||||
if ($count_only) {
|
|
||||||
$strReq = 'SELECT count(Z.feed_id) ';
|
|
||||||
} else {
|
|
||||||
$content_req = '';
|
|
||||||
if (!empty($params['columns']) && is_array($params['columns'])) {
|
|
||||||
$content_req .= implode(', ', $params['columns']) . ', ';
|
|
||||||
}
|
|
||||||
|
|
||||||
$strReq = 'SELECT Z.feed_id, Z.feed_creadt, Z.feed_upddt, Z.feed_type, ' .
|
|
||||||
'Z.blog_id, Z.cat_id, ' .
|
|
||||||
'Z.feed_upd_int, Z.feed_upd_last, Z.feed_status, ' .
|
|
||||||
$content_req .
|
|
||||||
'LOWER(Z.feed_name) as lowername, Z.feed_name, Z.feed_desc, ' .
|
|
||||||
'Z.feed_url, Z.feed_feed, Z.feed_get_tags, ' .
|
|
||||||
'Z.feed_tags, Z.feed_owner, Z.feed_tweeter, Z.feed_lang, ' .
|
|
||||||
'Z.feed_nb_out, Z.feed_nb_in, ' .
|
|
||||||
'C.cat_title, C.cat_url, C.cat_desc ';
|
|
||||||
}
|
|
||||||
|
|
||||||
$strReq .= 'FROM ' . $this->table . ' Z ' .
|
|
||||||
'LEFT OUTER JOIN ' . dcCore::app()->prefix . dcCategories::CATEGORY_TABLE_NAME . ' C ON Z.cat_id = C.cat_id ';
|
|
||||||
|
|
||||||
if (!empty($params['from'])) {
|
|
||||||
$strReq .= $params['from'] . ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
$strReq .= "WHERE Z.blog_id = '" . $this->blog . "' ";
|
|
||||||
|
|
||||||
if (isset($params['feed_type'])) {
|
|
||||||
$strReq .= "AND Z.feed_type = '" . $this->con->escape($params['type']) . "' ";
|
|
||||||
} else {
|
|
||||||
$strReq .= "AND Z.feed_type = 'feed' ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($params['feed_id'])) {
|
|
||||||
if (is_array($params['feed_id'])) {
|
|
||||||
array_walk($params['feed_id'], function (&$v, $k) { if ($v !== null) { $v = (int) $v; }});
|
|
||||||
} else {
|
|
||||||
$params['feed_id'] = [(int) $params['feed_id']];
|
|
||||||
}
|
|
||||||
$strReq .= 'AND Z.feed_id ' . $this->con->in($params['feed_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($params['feed_feed'])) {
|
|
||||||
$strReq .= "AND Z.feed_feed = '" . $this->con->escape($params['feed_feed']) . "' ";
|
|
||||||
}
|
|
||||||
if (isset($params['feed_url'])) {
|
|
||||||
$strReq .= "AND Z.feed_url = '" . $this->con->escape($params['feed_url']) . "' ";
|
|
||||||
}
|
|
||||||
if (isset($params['feed_status'])) {
|
|
||||||
$strReq .= 'AND Z.feed_status = ' . ((int) $params['feed_status']) . ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($params['q'])) {
|
|
||||||
$q = $this->con->escape(str_replace('*', '%', strtolower($params['q'])));
|
|
||||||
$strReq .= "AND LOWER(Z.feed_name) LIKE '" . $q . "' ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($params['sql'])) {
|
|
||||||
$strReq .= $params['sql'] . ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$count_only) {
|
|
||||||
if (!empty($params['order'])) {
|
|
||||||
$strReq .= 'ORDER BY ' . $this->con->escape($params['order']) . ' ';
|
|
||||||
} else {
|
|
||||||
$strReq .= 'ORDER BY Z.feed_upddt DESC ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$count_only && !empty($params['limit'])) {
|
|
||||||
$strReq .= $this->con->limit($params['limit']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$rs = $this->con->select($strReq);
|
|
||||||
|
|
||||||
return $rs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get next table id.
|
|
||||||
*
|
|
||||||
* @return integer Next id
|
|
||||||
*/
|
|
||||||
private function getNextId()
|
|
||||||
{
|
|
||||||
return $this->con->select(
|
|
||||||
'SELECT MAX(feed_id) FROM ' . $this->table
|
|
||||||
)->f(0) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lock a file to see if an update is ongoing.
|
|
||||||
*
|
|
||||||
* @return boolean True if file is locked
|
|
||||||
*/
|
|
||||||
public function lockUpdate()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
# Need flock function
|
|
||||||
if (!function_exists('flock')) {
|
|
||||||
throw new Exception("Can't call php function named flock");
|
|
||||||
}
|
|
||||||
# Cache writable ?
|
|
||||||
if (!is_writable(DC_TPL_CACHE)) {
|
|
||||||
throw new Exception("Can't write in cache fodler");
|
|
||||||
}
|
|
||||||
# Set file path
|
|
||||||
$f_md5 = md5($this->blog);
|
|
||||||
$cached_file = sprintf(
|
|
||||||
'%s/%s/%s/%s/%s.txt',
|
|
||||||
DC_TPL_CACHE,
|
|
||||||
'periodical',
|
|
||||||
substr($f_md5, 0, 2),
|
|
||||||
substr($f_md5, 2, 2),
|
|
||||||
$f_md5
|
|
||||||
);
|
|
||||||
# Real path
|
|
||||||
$cached_file = path::real($cached_file, false);
|
|
||||||
# Make dir
|
|
||||||
if (!is_dir(dirname($cached_file))) {
|
|
||||||
files::makeDir(dirname($cached_file), true);
|
|
||||||
}
|
|
||||||
# Make file
|
|
||||||
if (!file_exists($cached_file)) {
|
|
||||||
!$fp = @fopen($cached_file, 'w');
|
|
||||||
if ($fp === false) {
|
|
||||||
throw new Exception("Can't create file");
|
|
||||||
}
|
|
||||||
fwrite($fp, '1', strlen('1'));
|
|
||||||
fclose($fp);
|
|
||||||
}
|
|
||||||
# Open file
|
|
||||||
if (!($fp = @fopen($cached_file, 'r+'))) {
|
|
||||||
throw new Exception("Can't open file");
|
|
||||||
}
|
|
||||||
# Lock file
|
|
||||||
if (!flock($fp, LOCK_EX)) {
|
|
||||||
throw new Exception("Can't lock file");
|
|
||||||
}
|
|
||||||
$this->lock = $fp;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unlock file of update process.
|
|
||||||
*/
|
|
||||||
public function unlockUpdate()
|
|
||||||
{
|
|
||||||
@fclose($this->lock);
|
|
||||||
$this->lock = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check and add/update post related to record if needed.
|
|
||||||
*
|
|
||||||
* @param integer $id Feed Id
|
|
||||||
* @param boolean $throw Throw exception or end silently
|
|
||||||
* @return boolean True if process succeed
|
|
||||||
*/
|
|
||||||
public function checkFeedsUpdate($id = null, $throw = false)
|
|
||||||
{
|
|
||||||
$s = dcCore::app()->blog->settings->__get(basename(dirname('../' . __DIR__)));
|
|
||||||
|
|
||||||
# Not configured
|
|
||||||
if (!$s->active || !$s->user) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Limit to one update at a time
|
|
||||||
try {
|
|
||||||
$this->lockUpdate();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
if ($throw) {
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt::setTZ(dcCore::app()->blog->settings->system->blog_timezone);
|
|
||||||
$time = time();
|
|
||||||
|
|
||||||
# All feeds or only one (from admin)
|
|
||||||
$f = !$id ?
|
|
||||||
$this->getFeeds(['feed_status' => 1, 'order' => 'feed_upd_last ASC']) :
|
|
||||||
$this->getFeeds(['feed_id' => $id]);
|
|
||||||
|
|
||||||
# No feed
|
|
||||||
if ($f->isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$enabled = false;
|
|
||||||
$updates = false;
|
|
||||||
$loop_mem = [];
|
|
||||||
|
|
||||||
$limit = abs((int) $s->update_limit);
|
|
||||||
if ($limit < 1) {
|
|
||||||
$limit = 10;
|
|
||||||
}
|
|
||||||
$i = 0;
|
|
||||||
|
|
||||||
$cur_post = $this->con->openCursor(dcCore::app()->prefix . dcBlog::POST_TABLE_NAME);
|
|
||||||
$cur_meta = $this->con->openCursor(dcCore::app()->prefix . dcMeta::META_TABLE_NAME);
|
|
||||||
|
|
||||||
while ($f->fetch()) {
|
|
||||||
# Check if feed need update
|
|
||||||
if ($id
|
|
||||||
|| $i < $limit && $f->feed_status == 1 && ($time > $f->feed_upd_last + $f->feed_upd_int)
|
|
||||||
) {
|
|
||||||
if (!$enabled) {
|
|
||||||
# Set feeds user
|
|
||||||
$this->enableUser(true);
|
|
||||||
$enabled = true;
|
|
||||||
}
|
|
||||||
$i++;
|
|
||||||
$feed = self::readFeed($f->feed_feed);
|
|
||||||
|
|
||||||
# Nothing to parse
|
|
||||||
if (!$feed) {
|
|
||||||
# Keep active empty feed or disable it ?
|
|
||||||
if (!$s->keep_empty_feed) {
|
|
||||||
$this->enableFeed($f->feed_id, false);
|
|
||||||
} else {
|
|
||||||
# Set update time of this feed
|
|
||||||
$this->enableFeed($f->feed_id, true, $time);
|
|
||||||
}
|
|
||||||
$i++;
|
|
||||||
|
|
||||||
# Not updated since last visit
|
|
||||||
} elseif (!$id
|
|
||||||
&& '' != $feed->pubdate
|
|
||||||
&& strtotime($feed->pubdate) < $f->feed_upd_last
|
|
||||||
) {
|
|
||||||
# Set update time of this feed
|
|
||||||
$this->enableFeed($f->feed_id, true, $time);
|
|
||||||
$i++;
|
|
||||||
} else {
|
|
||||||
# Set update time of this feed
|
|
||||||
$this->enableFeed($f->feed_id, $f->feed_status, $time);
|
|
||||||
|
|
||||||
$this->con->begin();
|
|
||||||
|
|
||||||
foreach ($feed->items as $item) {
|
|
||||||
$item_TS = $item->TS ? $item->TS : $time;
|
|
||||||
|
|
||||||
// I found that mercurial atom feed did not repect standard
|
|
||||||
$item_link = @$item->link;
|
|
||||||
if (!$item_link) {
|
|
||||||
$item_link = @$item->guid;
|
|
||||||
}
|
|
||||||
# Unknow feed item link
|
|
||||||
if (!$item_link) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$item_link = $this->con->escape($item_link);
|
|
||||||
$is_new_published_entry = false;
|
|
||||||
|
|
||||||
# Not updated since last visit
|
|
||||||
if (!$id && $item_TS < $f->feed_upd_last) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fix loop twin
|
|
||||||
if (in_array($item_link, $loop_mem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$loop_mem[] = $item_link;
|
|
||||||
|
|
||||||
# Check if entry exists
|
|
||||||
$old_post = $this->con->select(
|
|
||||||
'SELECT P.post_id, P.post_status ' .
|
|
||||||
'FROM ' . dcCore::app()->prefix . dcBlog::POST_TABLE_NAME . ' P ' .
|
|
||||||
'INNER JOIN ' . dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' M ' .
|
|
||||||
'ON P.post_id = M.post_id ' .
|
|
||||||
"WHERE blog_id='" . $this->blog . "' " .
|
|
||||||
"AND meta_type = 'zoneclearfeed_url' " .
|
|
||||||
"AND meta_id = '" . $item_link . "' "
|
|
||||||
);
|
|
||||||
|
|
||||||
# Prepare entry cursor
|
|
||||||
$cur_post->clean();
|
|
||||||
$cur_post->post_dt = date('Y-m-d H:i:s', $item_TS);
|
|
||||||
if ($f->cat_id) {
|
|
||||||
$cur_post->cat_id = $f->cat_id;
|
|
||||||
}
|
|
||||||
$post_content = $item->content ? $item->content : $item->description;
|
|
||||||
$cur_post->post_format = 'xhtml';
|
|
||||||
$cur_post->post_content = html::absoluteURLs($post_content, $feed->link);
|
|
||||||
$cur_post->post_title = $item->title ? $item->title : text::cutString(html::clean($cur_post->post_content), 60);
|
|
||||||
$creator = $item->creator ? $item->creator : $f->feed_owner;
|
|
||||||
|
|
||||||
try {
|
|
||||||
# Create entry
|
|
||||||
if ($old_post->isEmpty()) {
|
|
||||||
# Post
|
|
||||||
$cur_post->user_id = dcCore::app()->auth->userID();
|
|
||||||
$cur_post->post_format = 'xhtml';
|
|
||||||
$cur_post->post_status = (int) $s->post_status_new;
|
|
||||||
$cur_post->post_open_comment = 0;
|
|
||||||
$cur_post->post_open_tb = 0;
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerBeforePostCreate
|
|
||||||
dcCore::app()->callBehavior(
|
|
||||||
'zoneclearFeedServerBeforePostCreate',
|
|
||||||
$cur_post
|
|
||||||
);
|
|
||||||
|
|
||||||
$post_id = dcCore::app()->auth->sudo(
|
|
||||||
[dcCore::app()->blog, 'addPost'],
|
|
||||||
$cur_post
|
|
||||||
);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerAfterPostCreate
|
|
||||||
dcCore::app()->callBehavior(
|
|
||||||
'zoneclearFeedServerAfterPostCreate',
|
|
||||||
$cur_post,
|
|
||||||
$post_id
|
|
||||||
);
|
|
||||||
|
|
||||||
# Auto tweet new post
|
|
||||||
if ($cur_post->post_status == 1) {
|
|
||||||
$is_new_published_entry = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update entry
|
|
||||||
} else {
|
|
||||||
$post_id = $old_post->post_id;
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerBeforePostUpdate
|
|
||||||
dcCore::app()->callBehavior(
|
|
||||||
'zoneclearFeedServerBeforePostUpdate',
|
|
||||||
$cur_post,
|
|
||||||
$post_id
|
|
||||||
);
|
|
||||||
|
|
||||||
dcCore::app()->auth->sudo(
|
|
||||||
[dcCore::app()->blog, 'updPost'],
|
|
||||||
$post_id,
|
|
||||||
$cur_post
|
|
||||||
);
|
|
||||||
|
|
||||||
# Quick delete old meta
|
|
||||||
$this->con->execute(
|
|
||||||
'DELETE FROM ' . dcCore::app()->prefix . dcMeta::META_TABLE_NAME . ' ' .
|
|
||||||
'WHERE post_id = ' . $post_id . ' ' .
|
|
||||||
"AND meta_type LIKE 'zoneclearfeed_%' "
|
|
||||||
);
|
|
||||||
|
|
||||||
# Delete old tags
|
|
||||||
dcCore::app()->auth->sudo(
|
|
||||||
[dcCore::app()->meta, 'delPostMeta'],
|
|
||||||
$post_id,
|
|
||||||
'tag'
|
|
||||||
);
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerAfterPostUpdate
|
|
||||||
dcCore::app()->callBehavior(
|
|
||||||
'zoneclearFeedServerAfterPostUpdate',
|
|
||||||
$cur_post,
|
|
||||||
$post_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Quick add new meta
|
|
||||||
$meta = new ArrayObject();
|
|
||||||
$meta->tweeter = $f->feed_tweeter;
|
|
||||||
|
|
||||||
$cur_meta->clean();
|
|
||||||
$cur_meta->post_id = $post_id;
|
|
||||||
$cur_meta->meta_type = 'zoneclearfeed_url';
|
|
||||||
$cur_meta->meta_id = $meta->url = $item_link;
|
|
||||||
$cur_meta->insert();
|
|
||||||
|
|
||||||
$cur_meta->clean();
|
|
||||||
$cur_meta->post_id = $post_id;
|
|
||||||
$cur_meta->meta_type = 'zoneclearfeed_author';
|
|
||||||
$cur_meta->meta_id = $meta->author = $creator;
|
|
||||||
$cur_meta->insert();
|
|
||||||
|
|
||||||
$cur_meta->clean();
|
|
||||||
$cur_meta->post_id = $post_id;
|
|
||||||
$cur_meta->meta_type = 'zoneclearfeed_site';
|
|
||||||
$cur_meta->meta_id = $meta->site = $f->feed_url;
|
|
||||||
$cur_meta->insert();
|
|
||||||
|
|
||||||
$cur_meta->clean();
|
|
||||||
$cur_meta->post_id = $post_id;
|
|
||||||
$cur_meta->meta_type = 'zoneclearfeed_sitename';
|
|
||||||
$cur_meta->meta_id = $meta->sitename = $f->feed_name;
|
|
||||||
$cur_meta->insert();
|
|
||||||
|
|
||||||
$cur_meta->clean();
|
|
||||||
$cur_meta->post_id = $post_id;
|
|
||||||
$cur_meta->meta_type = 'zoneclearfeed_id';
|
|
||||||
$cur_meta->meta_id = $meta->id = $f->feed_id;
|
|
||||||
$cur_meta->insert();
|
|
||||||
|
|
||||||
# Add new tags
|
|
||||||
$tags = dcCore::app()->meta->splitMetaValues($f->feed_tags);
|
|
||||||
if ($f->feed_get_tags) {
|
|
||||||
# Some feed subjects contains more than one tag
|
|
||||||
foreach ($item->subject as $subjects) {
|
|
||||||
$tmp = dcCore::app()->meta->splitMetaValues($subjects);
|
|
||||||
$tags = array_merge($tags, $tmp);
|
|
||||||
}
|
|
||||||
$tags = array_unique($tags);
|
|
||||||
}
|
|
||||||
$formated_tags = [];
|
|
||||||
foreach ($tags as $tag) {
|
|
||||||
# Change tags case
|
|
||||||
switch ((int) $s->tag_case) {
|
|
||||||
case 3: $tag = strtoupper($tag);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 2: $tag = strtolower($tag);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 1: $tag = ucfirst(strtolower($tag));
|
|
||||||
|
|
||||||
break;
|
|
||||||
default: /* do nothing */ break;
|
|
||||||
}
|
|
||||||
if (!in_array($tag, $formated_tags)) {
|
|
||||||
$formated_tags[] = $tag;
|
|
||||||
dcCore::app()->auth->sudo(
|
|
||||||
[dcCore::app()->meta, 'delPostMeta'],
|
|
||||||
$post_id,
|
|
||||||
'tag',
|
|
||||||
dcMeta::sanitizeMetaID($tag)
|
|
||||||
);
|
|
||||||
dcCore::app()->auth->sudo(
|
|
||||||
[dcCore::app()->meta, 'setPostMeta'],
|
|
||||||
$post_id,
|
|
||||||
'tag',
|
|
||||||
dcMeta::sanitizeMetaID($tag)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$meta->tags = $formated_tags;
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerAfterFeedUpdate
|
|
||||||
dcCore::app()->callBehavior(
|
|
||||||
'zoneclearFeedServerAfterFeedUpdate',
|
|
||||||
$is_new_published_entry,
|
|
||||||
$cur_post,
|
|
||||||
$meta
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$this->con->rollback();
|
|
||||||
$this->enableUser(false);
|
|
||||||
$this->unlockUpdate();
|
|
||||||
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
$updates = true;
|
|
||||||
}
|
|
||||||
$this->con->commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($enabled) {
|
|
||||||
$this->enableUser(false);
|
|
||||||
}
|
|
||||||
$this->unlockUpdate();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set permission to update post table.
|
|
||||||
*
|
|
||||||
* @param boolean $enable Enable or disable perm
|
|
||||||
*/
|
|
||||||
public function enableUser($enable = false)
|
|
||||||
{
|
|
||||||
# Enable
|
|
||||||
if ($enable) {
|
|
||||||
// backup current user
|
|
||||||
$this->user = dcCore::app()->auth->userID();
|
|
||||||
// set zcfs posts user
|
|
||||||
if (!dcCore::app()->auth->checkUser((string) dcCore::app()->blog->settings->__get(basename(dirname('../' . __DIR__)))->user)) {
|
|
||||||
throw new Exception('Unable to set user');
|
|
||||||
}
|
|
||||||
# Disable
|
|
||||||
} else {
|
|
||||||
dcCore::app()->auth = null;
|
|
||||||
dcCore::app()->auth = new dcAuth();
|
|
||||||
// restore current user
|
|
||||||
dcCore::app()->auth->checkUser($this->user ?? '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read and parse external feeds.
|
|
||||||
*
|
|
||||||
* @param string $f Feed URL
|
|
||||||
* @return feedParser|false Parsed feed
|
|
||||||
*/
|
|
||||||
public static function readFeed($f)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$feed_reader = new feedReader();
|
|
||||||
$feed_reader->setCacheDir(DC_TPL_CACHE);
|
|
||||||
$feed_reader->setTimeout(self::$nethttp_timeout);
|
|
||||||
$feed_reader->setMaxRedirects(self::$nethttp_maxredirect);
|
|
||||||
$feed_reader->setUserAgent(self::$nethttp_agent);
|
|
||||||
|
|
||||||
return $feed_reader->parse($f);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trigger.
|
|
||||||
*/
|
|
||||||
private function trigger()
|
|
||||||
{
|
|
||||||
dcCore::app()->blog->triggerBlog();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an URL is well formed
|
|
||||||
*
|
|
||||||
* @param string $url URL
|
|
||||||
* @return Boolean True if URL is allowed
|
|
||||||
*/
|
|
||||||
public static function validateURL($url)
|
|
||||||
{
|
|
||||||
return false !== strpos($url, 'http://')
|
|
||||||
|| false !== strpos($url, 'https://');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get full URL.
|
|
||||||
*
|
|
||||||
* Know bugs: anchor is not well parsed.
|
|
||||||
*
|
|
||||||
* @param string $root Root URL
|
|
||||||
* @param string $url An URL
|
|
||||||
* @return string Parse URL
|
|
||||||
*/
|
|
||||||
public static function absoluteURL($root, $url)
|
|
||||||
{
|
|
||||||
$host = preg_replace(
|
|
||||||
'|^([a-z]{3,}://)(.*?)/(.*)$|',
|
|
||||||
'$1$2',
|
|
||||||
$root
|
|
||||||
);
|
|
||||||
|
|
||||||
$parse = parse_url($url);
|
|
||||||
|
|
||||||
if (empty($parse['scheme'])) {
|
|
||||||
if (strpos($url, '/') === 0) {
|
|
||||||
$url = $host . $url;
|
|
||||||
} elseif (strpos($url, '#') === 0) {
|
|
||||||
$url = $root . $url;
|
|
||||||
} elseif (preg_match('|/$|', $root)) {
|
|
||||||
$url = $root . $url;
|
|
||||||
} else {
|
|
||||||
$url = dirname($root) . '/' . $url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get list of feeds status.
|
|
||||||
*
|
|
||||||
* @return array List of names/values of feeds status
|
|
||||||
*/
|
|
||||||
public static function getAllStatus()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
__('Disabled') => '0',
|
|
||||||
__('Enabled') => '1',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get list of predefined interval.
|
|
||||||
*
|
|
||||||
* @return array List of Name/time of intervals
|
|
||||||
*/
|
|
||||||
public static function getAllUpdateInterval()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
__('Every hour') => 3600,
|
|
||||||
__('Every two hours') => 7200,
|
|
||||||
__('Two times per day') => 43200,
|
|
||||||
__('Every day') => 86400,
|
|
||||||
__('Every two days') => 172800,
|
|
||||||
__('Every week') => 604800,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get list of (super)admins of current blog.
|
|
||||||
*
|
|
||||||
* @return array List of UserCNs/UserIds
|
|
||||||
*/
|
|
||||||
public function getAllBlogAdmins()
|
|
||||||
{
|
|
||||||
$admins = [];
|
|
||||||
|
|
||||||
# Get super admins
|
|
||||||
$rs = $this->con->select(
|
|
||||||
'SELECT user_id, user_super, user_name, user_firstname, user_displayname ' .
|
|
||||||
'FROM ' . $this->con->escapeSystem(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME) . ' ' .
|
|
||||||
'WHERE user_super = 1 AND user_status = 1 '
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$rs->isEmpty()) {
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
$user_cn = dcUtils::getUserCN(
|
|
||||||
$rs->user_id,
|
|
||||||
$rs->user_name,
|
|
||||||
$rs->user_firstname,
|
|
||||||
$rs->user_displayname
|
|
||||||
);
|
|
||||||
$admins[$user_cn . ' (super admin)'] = $rs->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get admins
|
|
||||||
$rs = $this->con->select(
|
|
||||||
'SELECT U.user_id, U.user_super, U.user_name, U.user_firstname, U.user_displayname ' .
|
|
||||||
'FROM ' . $this->con->escapeSystem(dcCore::app()->prefix . dcAuth::USER_TABLE_NAME) . ' U ' .
|
|
||||||
'LEFT JOIN ' . $this->con->escapeSystem(dcCore::app()->prefix . dcAuth::PERMISSIONS_TABLE_NAME) . ' P ' .
|
|
||||||
'ON U.user_id=P.user_id ' .
|
|
||||||
'WHERE U.user_status = 1 ' .
|
|
||||||
"AND P.blog_id = '" . $this->blog . "' " .
|
|
||||||
"AND P.permissions LIKE '%|admin|%' "
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$rs->isEmpty()) {
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
$user_cn = dcUtils::getUserCN(
|
|
||||||
$rs->user_id,
|
|
||||||
$rs->user_name,
|
|
||||||
$rs->user_firstname,
|
|
||||||
$rs->user_displayname
|
|
||||||
);
|
|
||||||
$admins[$user_cn . ' (admin)'] = $rs->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $admins;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get list of urls where entries could be hacked.
|
|
||||||
*
|
|
||||||
* @return array List of names/types of URLs
|
|
||||||
*/
|
|
||||||
public static function getPublicUrlTypes()
|
|
||||||
{
|
|
||||||
$types = [];
|
|
||||||
|
|
||||||
# --BEHAVIOR-- zoneclearFeedServerPublicUrlTypes
|
|
||||||
dcCore::app()->callBehavior('zoneclearFeedServerPublicUrlTypes', $types);
|
|
||||||
|
|
||||||
$types[__('Home page')] = 'default';
|
|
||||||
$types[__('Entries pages')] = 'post';
|
|
||||||
$types[__('Tags pages')] = 'tag';
|
|
||||||
$types[__('Archives pages')] = 'archive';
|
|
||||||
$types[__('Category pages')] = 'category';
|
|
||||||
$types[__('Entries feed')] = 'feed';
|
|
||||||
|
|
||||||
return $types;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Take care about plugin tweakurls (thanks Mathieu M.).
|
|
||||||
*
|
|
||||||
* @param cursor $cur cursor instance
|
|
||||||
* @param integer $id Post Id
|
|
||||||
*/
|
|
||||||
public static function tweakurlsAfterPostCreate(cursor $cur, $id)
|
|
||||||
{
|
|
||||||
if (version_compare(dcCore::app()->plugins->moduleInfo('tweakurls', 'version'), '0.8', '>=')) {
|
|
||||||
$cur->post_url = tweakUrls::tweakBlogURL($cur->post_url);
|
|
||||||
dcCore::app()->auth->sudo([dcCore::app()->blog, 'updPost'], $id, $cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue