2015.04.25

This commit is contained in:
brol 2015-04-25 21:25:03 +02:00
parent 1fa82f61f8
commit 627d0b876d
31 changed files with 5630 additions and 2 deletions

View File

@ -1,2 +1,27 @@
# zoneclearFeedServer
Mixer votre blog avec un planet
# README
## WHAT IS ZONECLEARFEEDSERVER ?
"zoneclear Feeds server" is a plugin for the open-source
web publishing software called Dotclear.
It mix your blog with a feeds planet.
## REQUIREMENTS
zoneclearFeedServer requires:
* admin perms for configuration
* admin perms to manager feeds
* Dotclear 2.7
## USAGE
First install zoneclearFeedServer, manualy from a zip package or from
Dotaddict repository. (See Dotclear's documentation to know how do this)
Go to ''plugins manager'', expand zoneclearFeedServer information then
go to ''configure plugin'', fill in form.
Once it's done you can manage your feeds from menu
''Feeds server'' on sidebar or you can add dashboard icon.

259
_admin.php Normal file
View File

@ -0,0 +1,259 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_CONTEXT_ADMIN')) {
return null;
}
# Namespace for settings
$core->blog->settings->addNamespace('zoneclearFeedServer');
# Check if latest version is installed
if ($core->getVersion('zoneclearFeedServer') !=
$core->plugins->moduleInfo('zoneclearFeedServer', 'version')) {
return null;
}
# Widgets
require_once dirname(__FILE__).'/_widgets.php';
# Admin menu
$_menu['Blog']->addItem(
__('Feeds server'),
'plugin.php?p=zoneclearFeedServer',
'index.php?pf=zoneclearFeedServer/icon.png',
preg_match(
'/plugin.php\?p=zoneclearFeedServer(&.*)?$/',
$_SERVER['REQUEST_URI']
),
$core->auth->check('admin', $core->blog->id)
);
# Delete related info about feed post in meta table
$core->addBehavior(
'adminBeforePostDelete',
array('zcfsAdminBehaviors', 'adminBeforePostDelete')
);
if ($core->auth->check('admin', $core->blog->id)) {
# Dashboard icon
$core->addBehavior(
'adminDashboardFavorites',
array('zcfsAdminBehaviors', 'adminDashboardFavorites')
);
# Add info about feed on post page sidebar
$core->addBehavior(
'adminPostHeaders',
array('zcfsAdminBehaviors', 'adminPostHeaders')
);
$core->addBehavior(
'adminPostFormItems',
array('zcfsAdminBehaviors', 'adminPostFormItems')
);
}
# Take care about tweakurls (thanks Mathieu M.)
if (version_compare($core->plugins->moduleInfo('tweakurls', 'version'), '0.8', '>=')) {
$core->addbehavior(
'zcfsAfterPostCreate',
array('zoneclearFeedServer', 'tweakurlsAfterPostCreate')
);
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Mix your blog with a feeds planet - admin methods.
* @since 2.6
*/
class zcfsAdminBehaviors
{
/**
* Favorites.
*
* @param dcCore $core dcCore instance
* @param arrayObject $favs Array of favorites
*/
public static function adminDashboardFavorites(dcCore $core, $favs)
{
$favs->register('zcfs', array(
'title' => __('Feeds server'),
'url' => 'plugin.php?p=zoneclearFeedServer',
'small-icon' => 'index.php?pf=zoneclearFeedServer/icon.png',
'large-icon' => 'index.php?pf=zoneclearFeedServer/icon-big.png',
'permissions' => 'usage,contentadmin',
'active_cb' => array(
'zcfsAdminBehaviors',
'adminDashboardFavoritesActive'
),
'dashboard_cb' => array(
'zcfsAdminBehaviors',
'adminDashboardFavoritesCallback'
)
));
}
/**
* Favorites selection.
*
* @param string $request Requested page
* @param array $params Requested parameters
*/
public static function adminDashboardFavoritesActive($request, $params)
{
return $request == 'plugin.php'
&& isset($params['p'])
&& $params['p'] == 'zoneclearFeedServer';
}
/**
* Favorites hack.
*
* @param dcCore $core dcCore instance
* @param arrayObject $fav Fav attributes
*/
public static function adminDashboardFavoritesCallback(dcCore $core, $fav)
{
$zcfs = new zoneclearFeedServer($core);
$count = $zcfs->getFeeds(array(
'feed_status' => '0'
), true)->f(0);
if (!$count) {
return null;
}
$fav['title'] .= '<br />'.sprintf(
__('%s feed disabled', '%s feeds disabled', $count),
$count
);
$fav['url'] = 'plugin.php?p=zoneclearFeedServer&part=feeds'.
'&sortby=feed_status&order=asc';
$fav['large-icon'] = 'index.php?pf=zoneclearFeedServer'.
'/icon-big-update.png';
}
/**
* Add javascript for toggle to post edition page header.
*
* @return string Page header
*/
public static function adminPostHeaders()
{
return dcPage::jsLoad(
'index.php?pf=zoneclearFeedServer/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;
}
global $core;
$url = $core->meta->getMetadata(array(
'post_id' => $post->post_id,
'meta_type' => 'zoneclearfeed_url',
'limit' => 1
));
$url = $url->isEmpty() ? '' : $url->meta_id;
if (!$url) {
return null;
}
$author = $core->meta->getMetadata(array(
'post_id' => $post->post_id,
'meta_type' => 'zoneclearfeed_author',
'limit' => 1
));
$author = $author->isEmpty() ? '' : $author->meta_id;
$site = $core->meta->getMetadata(array(
'post_id' => $post->post_id,
'meta_type' => 'zoneclearfeed_site',
'limit' => 1
));
$site = $site->isEmpty() ? '' : $site->meta_id;
$sitename = $core->meta->getMetadata(array(
'post_id' => $post->post_id,
'meta_type' => 'zoneclearfeed_sitename',
'limit' => 1
));
$sitename = $sitename->isEmpty() ? '' : $sitename->meta_id;
$edit = '';
if ($core->auth->check('admin', $core->blog->id)) {
$fid = $core->meta->getMetadata(array(
'post_id' => $post->post_id,
'meta_type' => 'zoneclearfeed_id',
'limit' => 1
));
if (!$fid->isEmpty()) {
$edit =
'<p><a href="plugin.php?p=zoneclearFeedServer'.
'&amp;part=feed&amp;feed_id='.$fid->meta_id.
'">'.__('Edit this feed').'</a></p>';
}
}
$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)
{
global $core;
$core->con->execute(
'DELETE FROM '.$core->prefix.'meta '.
'WHERE post_id = '.((integer) $post_id).' '.
'AND meta_type '.$core->con->in(array(
'zoneclearfeed_url',
'zoneclearfeed_author',
'zoneclearfeed_site',
'zoneclearfeed_sitename',
'zoneclearfeed_id'
)).' '
);
}
}

215
_config.php Normal file
View File

@ -0,0 +1,215 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_CONTEXT_MODULE')) {
return null;
}
$redir = empty($_REQUEST['redir']) ?
$list->getURL().'#plugins' : $_REQUEST['redir'];
# -- Get settings --
$core->blog->settings->addNamespace('zoneclearFeedServer');
$s = $core->blog->settings->zoneclearFeedServer;
$active = (boolean) $s->zoneclearFeedServer_active;
$pub_active = (boolean) $s->zoneclearFeedServer_pub_active;
$post_status_new = (boolean) $s->zoneclearFeedServer_post_status_new;
$bhv_pub_upd = (integer) $s->zoneclearFeedServer_bhv_pub_upd;
$update_limit = (integer) $s->zoneclearFeedServer_update_limit;
$keep_empty_feed = (boolean) $s->zoneclearFeedServer_keep_empty_feed;
$tag_case = (integer) $s->zoneclearFeedServer_tag_case;
$post_full_tpl = @unserialize($s->zoneclearFeedServer_post_full_tpl);
$post_title_redir = @unserialize($s->zoneclearFeedServer_post_title_redir);
$feeduser = (string) $s->zoneclearFeedServer_user;
if ($update_limit < 1) {
$update_limit = 10;
}
if (!is_array($post_full_tpl)) {
$post_full_tpl = array();
}
if (!is_array($post_title_redir)) {
$post_title_redir = array();
}
$zc = new zoneclearFeedServer($core);
# -- 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 = (integer) $_POST['bhv_pub_upd'];
$limit = abs((integer) $_POST['update_limit']);
$keep_empty_feed = !empty($_POST['keep_empty_feed']);
$tag_case = (integer) $_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('zoneclearFeedServer_active', $active);
$s->put('zoneclearFeedServer_pub_active', $pub_active);
$s->put('zoneclearFeedServer_post_status_new', $post_status_new);
$s->put('zoneclearFeedServer_bhv_pub_upd', $bhv_pub_upd);
$s->put('zoneclearFeedServer_update_limit', $limit);
$s->put('zoneclearFeedServer_keep_empty_feed', $keep_empty_feed);
$s->put('zoneclearFeedServer_tag_case', $tag_case);
$s->put('zoneclearFeedServer_post_full_tpl', serialize($post_full_tpl));
$s->put('zoneclearFeedServer_post_title_redir', serialize($post_title_redir));
$s->put('zoneclearFeedServer_user', $feeduser);
$core->blog->triggerBlog();
dcPage::addSuccessNotice(
__('Configuration successfully updated.')
);
http::redirect(
$list->getURL('module=zoneclearFeedServer&conf=1&redir='.
$list->getRedir())
);
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
}
# -- Form combos --
$combo_admins = $zc->getAllBlogAdmins();
$combo_pubupd = array(
__('Disable') => 0,
__('Before display') => 1,
__('After display') => 2,
__('Through Ajax') => 3
);
$combo_status = array(
__('Unpublished') => 0,
__('Published') => 1
);
$combo_tagcase = array(
__('Keep source case') => 0,
__('First upper case') => 1,
__('All lower case') => 2,
__('All upper case') => 3
);
$pub_page_url = $core->blog->url.$core->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>';
echo '
<div class="fieldset">';
if ($core->blog->settings->zoneclearFeedServer->zoneclearFeedServer_pub_active) {
echo '<p><a class="onblog_link" href="'.$pub_page_url.'" title="'.$pub_page_url.''.'">'.__('View the public list of feeds').'</a></p>';
}
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><label for="update_limit">'.
__('Number of feeds to update at one time:').'</label>'.
form::field('update_limit', 6, 4, $update_limit).'</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($core) as $k => $v) {
echo
'<li><label for="post_title_redir_'.$v.'">'.
form::checkbox(
array('post_title_redir[]', 'post_title_redir_'.$v),
$v,
in_array($v, $post_title_redir)
).
__($k).'</label></li>';
}
echo '
</ul>
</div><div class="two-boxes">
<p>'.__('Show full content on:').'</p><ul>';
foreach($zc->getPublicUrlTypes($core) as $k => $v) {
echo
'<li><label for="post_full_tpl_'.$v.'">'.
form::checkbox(
array('post_full_tpl[]', 'post_full_tpl_'.$v),
$v,
in_array($v, $post_full_tpl)
).
__($k).'</label></li>';
}
echo '
</ul>
</div>
</div>
';
dcPage::helpBlock('zoneclearFeedServer');

36
_define.php Normal file
View File

@ -0,0 +1,36 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_RC_PATH')) {
return null;
}
$this->registerModule(
/* Name */
"zoneclearFeedServer",
/* Description*/
"Mix your blog with a feeds planet",
/* Author */
"Jean-Christian Denis, BG, Pierre Van Glabeke",
/* Version */
'2015.04.25',
/* Properies */
array(
'permissions' => 'admin',
'type' => 'plugin',
'dc_min' => '2.7',
'support' => 'http://forum.dotclear.org/viewtopic.php?pid=331158',
'details' => 'http://plugins.dotaddict.org/dc2/details/zoneclearFeedServer'
)
);

98
_install.php Normal file
View File

@ -0,0 +1,98 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_CONTEXT_ADMIN')) {
return null;
}
$dc_min = '2.7';
$mod_id = 'zoneclearFeedServer';
try {
# Check module version
if (version_compare(
$core->getVersion($mod_id),
$core->plugins->moduleInfo($mod_id, 'version'),
'>='
)) {
return null;
}
# Check Dotclear version
if (!method_exists('dcUtils', 'versionsCompare')
|| dcUtils::versionsCompare(DC_VERSION, $dc_min, '<', false)) {
throw new Exception(sprintf(
'%s requires Dotclear %s', $mod_id, $dc_min
));
}
# Tables
$t = new dbStruct($core->con, $core->prefix);
$t->zc_feed
->feed_id ('bigint', 0, false)
->feed_creadt ('timestamp', 0, false, 'now()')
->feed_upddt ('timestamp', 0, false, 'now()')
->feed_type ('varchar', 32, false, "'feed'")
->blog_id ('varchar', 32, false)
->cat_id ('bigint', 0, true)
->feed_upd_int ('integer', 0, false, 3600)
->feed_upd_last ('integer', 0, false, 0)
->feed_status ('smallint', 0, false, 0)
->feed_name ('varchar', 255, false)
->feed_desc ('text', 0, true) //!pgsql reserved 'desc'
->feed_url ('varchar', 255, false)
->feed_feed ('varchar', 255, false)
->feed_tags ('varchar', 255, true)
->feed_get_tags ('smallint', 0, false, 1)
->feed_owner ('varchar', 255, false)
->feed_tweeter ('varchar', 64, false) // tweeter ident
->feed_lang ('varchar', 5, true)
->feed_nb_out ('integer', 0, false, 0)
->feed_nb_in ('integer', 0, false, 0)
->primary('pk_zcfs', 'feed_id')
->index('idx_zcfs_type', 'btree', 'feed_type')
->index('idx_zcfs_blog', 'btree', 'blog_id');
$ti = new dbStruct($core->con, $core->prefix);
$changes = $ti->synchronize($t);
# Settings
$core->blog->settings->addNamespace('zoneclearFeedServer');
$s = $core->blog->settings->zoneclearFeedServer;
$s->put('zoneclearFeedServer_active', false, 'boolean', 'Enable zoneclearBlogServer', false, true);
$s->put('zoneclearFeedServer_pub_active', false, 'boolean', 'Enable public page of list of feeds', false, true);
$s->put('zoneclearFeedServer_post_status_new', true, 'boolean', 'Enable auto publish new posts', false, true);
$s->put('zoneclearFeedServer_bhv_pub_upd', 2, 'string', 'Auto update on public side (disable/before/after)', false, true);
$s->put('zoneclearFeedServer_update_limit', 1, 'integer', 'Number of feeds to update at one time', false, true);
$s->put('zoneclearFeedServer_keep_empty_feed', false, 'boolean', 'Keep active empty feeds', false, true);
$s->put('zoneclearFeedServer_tag_case', 0, 'integer', 'How to transform imported tags', false, true);
$s->put('zoneclearFeedServer_user', '', 'string','User id that has right on post', false, true);
$s->put('zoneclearFeedServer_post_full_tpl', serialize(array('post', 'category', 'tag', 'archive')), 'string', 'List of templates types for full feed', false, true);
$s->put('zoneclearFeedServer_post_title_redir', serialize(array('feed')), 'string', 'List of templates types for redirection to original post', false, true);
# Set module version
$core->setVersion(
$mod_id,
$core->plugins->moduleInfo($mod_id, 'version')
);
return true;
}
catch (Exception $e) {
$core->error->add($e->getMessage());
return false;
}

55
_prepend.php Normal file
View File

@ -0,0 +1,55 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_RC_PATH')) {
return null;
}
if ($core->getVersion('zoneclearFeedServer') !=
$core->plugins->moduleInfo('zoneclearFeedServer', 'version')) {
return null;
}
$d = dirname(__FILE__).'/inc/';
$__autoload['zoneclearFeedServer'] = $d.'class.zoneclear.feed.server.php';
$__autoload['zcfsFeedsList'] = $d.'lib.zcfs.list.php';
$__autoload['zcfsEntriesList'] = $d.'lib.zcfs.list.php';
$__autoload['zcfsFeedsActionsPage'] = $d.'class.zcfs.feedsactions.php';
$__autoload['zcfsDefaultFeedsActions'] = $d.'class.zcfs.feedsactions.php';
# public url for page of description of the flux
$core->url->register(
'zoneclearFeedsPage',
'zcfeeds',
'^zcfeeds(.*?)$',
array('zcfsUrlHandler', 'zcFeedsPage')
);
# Add to plugn soCialMe (writer part)
$__autoload['zcfsSoCialMeWriter'] = $d.'lib.zcfs.socialmewriter.php';
$core->addBehavior(
'soCialMeWriterMarker',
array('zcfsSoCialMeWriter', 'soCialMeWriterMarker')
);
$core->addBehavior(
'zoneclearFeedServerAfterFeedUpdate',
array('zcfsSoCialMeWriter', 'zoneclearFeedServerAfterFeedUpdate')
);
# Add to report on plugin activityReport
if (defined('ACTIVITY_REPORT')) {
require_once $d.'lib.zcfs.activityreport.php';
}

735
_public.php Normal file
View File

@ -0,0 +1,735 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
# contact@jcdenis.fr http://jcd.lv
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_RC_PATH')) {
return null;
}
# Namespace for settings
$core->blog->settings->addNamespace('zoneclearFeedServer');
$s = $core->blog->settings->zoneclearFeedServer;
# Widgets
require_once dirname(__FILE__).'/_widgets.php';
$core->addBehavior(
'coreBlogGetPosts',
array('zcfsPublicBehaviors', 'coreBlogGetPosts')
);
if (!$s->zoneclearFeedServer_active) {
return null;
}
if (1 == $s->zoneclearFeedServer_bhv_pub_upd) {
$core->addBehavior(
'publicBeforeDocument',
array('zcfsPublicBehaviors', 'publicDocument')
);
}
elseif (2 == $s->zoneclearFeedServer_bhv_pub_upd) {
$core->addBehavior(
'publicAfterDocument',
array('zcfsPublicBehaviors', 'publicAfterDocument')
);
}
elseif (3 == $s->zoneclearFeedServer_bhv_pub_upd) {
$core->addBehavior(
'publicHeadContent',
array('zcfsPublicBehaviors', 'publicHeadContent')
);
}
# Take care about tweakurls (thanks Mathieu M.)
if (version_compare($core->plugins->moduleInfo('tweakurls', 'version'), '0.8', '>=')) {
$core->addbehavior(
'zoneclearFeedServerAfterPostCreate',
array('zoneclearFeedServer', 'tweakurlsAfterPostCreate')
);
}
# Register tempalte blocks
$tpl_blocks = array(
'Feeds',
'FeedsFooter',
'FeedsHeader',
'FeedIf'
);
foreach($tpl_blocks as $v) {
$core->tpl->addBlock('zc'.$v, array('zcfsTemplate', $v));
}
# Register tempalte values
$tpl_values = array(
'FeedsCount',
'FeedsEntriesCount',
'FeedEntriesCount',
'FeedCategory',
'FeedCategoryID',
'FeedCategoryURL',
'FeedCategoryShortURL',
'FeedID',
'FeedIfFirst',
'FeedIfOdd',
'FeedLang',
'FeedName',
'FeedOwner',
'FeedDesc',
'FeedSiteURL',
'FeedFeedURL'
);
foreach($tpl_values as $v) {
$core->tpl->addValue('zc'.$v, array('zcfsTemplate', $v));
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Mix your blog with a feeds planet - public methods.
* @since 2.6
*/
class zcfsPublicBehaviors
{
/**
* Remember others post extension.
*
* @param record $rs record instance
*/
public static function coreBlogGetPosts(record $rs)
{
$GLOBALS['beforeZcFeedRsExt'] = $rs->extensions();
$rs->extend('zcfsRsExtPosts');
}
/**
* Update feeds after contents.
*
* @param dcCore $core dcCore instance
* @return string Document
*/
public static function publicAfterDocument(dcCore $core)
{
# Limit feeds update to home page et feed page
# Like publishScheduledEntries
if (!in_array($core->url->type, array('default', 'feed'))) {
return null;
}
self::publicDocument($core);
}
/**
* Generic behavior for before and after public content.
*
* @param dcCore $core dcCore instance
* @return null NULL
*/
public static function publicDocument(dcCore $core)
{
$zc = new zoneclearFeedServer($core);
$zc->checkFeedsUpdate();
return null;
}
/**
* Update feeds by an Ajax request (background).
*
* @param dcCore $core dcCore instance
* @param context $_ctx context instance
* @return string HTML content
*/
public static function publicHeadContent(dcCore $core, context $_ctx)
{
# Limit update to home page
if ($core->url->type != 'default') {
return null;
}
$blog_url = html::escapeJS(
$core->blog->url.
$core->url->getBase('zoneclearFeedsPage').
'/zcfsupd'
);
$blog_id = html::escapeJS($core->blog->id);
echo
"\n<!-- JS for zoneclearFeedServer --> \n".
"<script type=\"text/javascript\" src=\"".
$core->blog->url.
$core->url->getBase('zoneclearFeedsPage').
'/zcfsupd.js">'.
"</script> \n".
"<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";
}
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Mix your blog with a feeds planet - rs methods.
* @since 2.6
*/
class zcfsRsExtPosts extends rsExtPost
{
/**
* Get feed meta.
*
* @param record $rs record instance
* @param string $info Feed info key
* @return string Feed info value
*/
public static function zcFeed($rs, $info)
{
$p = array(
'post_id' => $rs->post_id,
'meta_type' => 'zoneclearfeed_'.$info,
'limit' => 1
);
$meta = $rs->core->meta->getMetadata($p);
return $meta->isEmpty() ? null : $meta->meta_id;
}
/**
* Call other rs extension.
*
* @param string $type Type of extension
* @param array $args Arguments
* @return mixed record extension ressource
*/
public static function zcFeedBrother($type, $args)
{
if (!empty($GLOBALS['beforeZcFeedRsExt'][$type])) {
$func = $GLOBALS['beforeZcFeedRsExt'][$type];
}
elseif (is_callable('rsExtPostPublic', $type)) {
$func = array('rsExtPostPublic', $type);
}
else {
$func = array('rsExtPost', $type);
}
return call_user_func_array($func, $args);
}
/**
* Get author link from post to feed.
*
* @param record $rs record instance
* @return string Author link
*/
public static function getAuthorLink($rs)
{
$author = $rs->zcFeed('author');
$site = $rs->zcFeed('site');
$sitename = $rs->zcFeed('sitename');
return ($author && $sitename) ?
$author.' (<a href="'.$site.'">'.$sitename.'</a>)' :
self::zcFeedBrother('getAuthorLink', array(&$rs));
}
/**
* Get author CN from post to feed.
*
* @param record $rs record instance
* @return string Author CN
*/
public static function getAuthorCN($rs)
{
$author = $rs->zcFeed('author');
return $author ?
$author :
self::zcFeedBrother('getAuthorCN', array(&$rs));
}
/**
* Get post link from post to feed.
*
* @param record $rs record instance
* @return string Post link
*/
public static function getURL($rs)
{
$url = $rs->zcFeed('url');
$types = @unserialize($rs->core->blog->settings->zoneclearFeedServer->zoneclearFeedServer_post_title_redir);
$full = is_array($types) && in_array($rs->core->url->type, $types);
return $url && $full ?
zoneclearFeedServer::absoluteURL($rs->zcFeed('site'), $url) :
self::zcFeedBrother('getURL', array(&$rs));
}
/**
* Get post content from post to feed.
*
* @param record $rs record instance
* @return string Post content
*/
public static function getContent($rs, $absolute_urls=false)
{
$url = $rs->zcFeed('url');
$sitename = $rs->zcFeed('sitename');
$content = self::zcFeedBrother('getContent', array(&$rs,$absolute_urls));
if ($url && $sitename && $rs->post_type == 'post') {
$types = @unserialize($rs->core->blog->settings->zoneclearFeedServer->zoneclearFeedServer_post_full_tpl);
if (is_array($types) && in_array($rs->core->url->type, $types)) {
return $content .
'<p class="zoneclear-original"><em>'.
sprintf(__('Original post on <a href="%s">%s</a>'), $url, $sitename).
'</em></p>';
}
else {
$content = context::remove_html($content);
$content = context::cut_string($content,350);
$content = html::escapeHTML($content);
return
'<p>'.$content.'... '.
'<em><a href="'.self::getURL($rs).'" title="'.
__('Read more details about this feed').
'">'.__('Continue reading').'</a></em></p>';
}
}
else {
return $content;
}
}
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Mix your blog with a feeds planet - url handler methods.
* @since 2.6
*/
class zcfsUrlHandler extends dcUrlHandlers
{
/**
* Feeds source page and update methods.
*
* @param array $args Page arguments
* @return mixed
*/
public static function zcFeedsPage($args)
{
global $core, $_ctx;
$s = $core->blog->settings->zoneclearFeedServer;
# Not active
if (!$s->zoneclearFeedServer_active) {
self::p404();
return null;
}
# Update feeds (from ajax or other post resquest)
if ($args == '/zcfsupd'
&& 3 == $s->zoneclearFeedServer_bhv_pub_upd
) {
$msg = '';
if (!empty($_POST['blogId'])
&& html::escapeJS($core->blog->id) == $_POST['blogId']
) {
try {
$zc = new zoneclearFeedServer($core);
if ($zc->checkFeedsUpdate()) {
$msg = '<status>ok</status><message>'.
'Feeds updated successfully</message>';
}
}
catch (Exception $e) {}
}
if (empty($msg)) {
$msg = '<status>failed</status><message>'.
'Failed to update feeds</message>';
}
header('Content-Type: application/xml; charset=UTF-8');
echo
'<?xml version="1.0" encoding="utf-8"?>'."\n".
'<response><rsp>'."\n".
$msg."\n".
'</rsp></response>';
exit(1);
}
# Server js
elseif ($args == '/zcfsupd.js'
&& 3 == $s->zoneclearFeedServer_bhv_pub_upd
) {
$core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__).'/default-templates');
self::serveDocument(
'zcfsupd.js',
'text/javascript',
false,
false
);
}
# Server feeds description page
elseif (in_array($args, array('', '/'))
&& $s->zoneclearFeedServer_pub_active
) {
$tplset = $core->themes->moduleInfo($core->blog->settings->system->theme,'tplset');
if (!empty($tplset) && is_dir(dirname(__FILE__).'/default-templates/'.$tplset)) {
$core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__).'/default-templates/'.$tplset);
} else {
$core->tpl->setPath($core->tpl->getPath(), dirname(__FILE__).'/default-templates/'.DC_DEFAULT_TPLSET);
}
self::serveDocument('zcfeeds.html');
}
# Unknow
else {
self::p404();
}
return null;
}
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Mix your blog with a feeds planet - template methods.
* @since 2.6
*/
class zcfsTemplate
{
public static function Feeds($a, $c)
{
$lastn = -1;
$p = '';
if (isset($a['lastn'])) {
$lastn = abs((integer) $a['lastn'])+0;
$p .= "\$zcfs_params['limit'] = ".$lastn.";\n";
}
if (isset($a['cat_id'])) {
$p .= "@\$zcfs_params['sql'] .= 'AND Z.cat_id = ".addslashes($a['cat_id'])." ';\n";
}
if (isset($a['no_category'])) {
$p .= "@\$zcfs_params['sql'] .= 'AND Z.cat_id IS NULL ';\n";
}
if (!empty($a['site_url'])) {
$p .= "\$zcfs_params['feed_url'] = '".addslashes($a['site_url'])."';\n";
}
if (isset($a['feed_status'])) {
$p .= "\$zcfs_params['feed_status'] = ".((integer) $a['feed_status']).";\n";
}
else {
$p .= "\$zcfs_params['feed_status'] = 1;\n";
}
if (!empty($a['feed_url'])) {
$p .= "\$zcfs_params['feed_feed'] = '".addslashes($a['feed_url'])."';\n";
}
if (isset($a['feed_owner'])) {
$p .= "@\$zcfs_params['sql'] .= \"AND Z.feed_owner = '".addslashes($a['author'])."' \";\n";
}
$sortby = 'feed_creadt';
$order = 'desc';
if (isset($a['sortby'])) {
switch ($a['sortby']) {
case 'name': $sortby = 'lowername'; break;
case 'owner' : $sortby = 'feed_owner'; break;
case 'date' : $sortby = 'feed_dt'; break;
case 'update' : $sortby = 'feed_upddt'; break;
case 'id' : $sortby = 'feed_id'; break;
}
}
if (isset($a['order'])
&& preg_match('/^(desc|asc)$/i', $a['order'])
) {
$order = $a['order'];
}
$p .= "\$zcfs_params['order'] = '".$sortby." ".$order."';\n";
return
'<?php '.$p.
'$_ctx->feeds_params = $zcfs_params;'."\n".
'$zcfs = new zoneclearFeedServer($core);'."\n".
'$_ctx->feeds = $zcfs->getFeeds($zcfs_params); unset($zcfs_params,$zcfs);'."\n".
"?>\n".
'<?php while ($_ctx->feeds->fetch()) : ?>'.$c.'<?php endwhile; '.
'$_ctx->feeds = null; $_ctx->feeds_params = null; ?>';
}
public static function FeedIf($a,$c)
{
$if = array();
$operator = isset($a['operator']) ? self::getOperator($a['operator']) : '&&';
if (isset($a['type'])) {
$type = trim($a['type']);
$type = !empty($type) ? $type : 'feed';
$if[] = '$_ctx->feeds->feed_type == "'.addslashes($type).'"';
}
if (isset($a['site_url'])) {
$url = trim($a['feed_url']);
if (substr($url, 0, 1) == '!') {
$url = substr($url, 1);
$if[] = '$_ctx->feeds->feed_url != "'.addslashes($url).'"';
}
else {
$if[] = '$_ctx->feeds->feed_url == "'.addslashes($url).'"';
}
}
if (isset($a['feed_url'])) {
$url = trim($a['feed_feed']);
if (substr($url, 0, 1) == '!') {
$url = substr($url, 1);
$if[] = '$_ctx->feeds->feed_feed != "'.addslashes($url).'"';
}
else {
$if[] = '$_ctx->feeds->feed_feed == "'.addslashes($url).'"';
}
}
if (isset($a['category'])) {
$category = addslashes(trim($a['category']));
if (substr($category, 0, 1) == '!') {
$category = substr($category, 1);
$if[] = '($_ctx->feeds->cat_url != "'.$category.'")';
}
else {
$if[] = '($_ctx->feeds->cat_url == "'.$category.'")';
}
}
if (isset($a['first'])) {
$sign = (boolean) $a['first'] ? '=' : '!';
$if[] = '$_ctx->feeds->index() '.$sign.'= 0';
}
if (isset($a['odd'])) {
$sign = (boolean) $a['odd'] ? '=' : '!';
$if[] = '($_ctx->feeds->index()+1)%2 '.$sign.'= 1';
}
if (isset($a['has_category'])) {
$sign = (boolean) $a['has_category'] ? '' : '!';
$if[] = $sign.'$_ctx->feeds->cat_id';
}
if (isset($a['has_description'])) {
$sign = (boolean) $a['has_description'] ? '' : '!';
$if[] = $sign.'$_ctx->feeds->feed_desc';
}
return empty($if) ?
$c :
'<?php if('.implode(' '.$operator.' ',$if).') : ?>'.$c.'<?php endif; ?>';
}
public static function FeedIfFirst($a)
{
$ret = isset($a['return']) ? $a['return'] : 'first';
$ret = html::escapeHTML($ret);
return
'<?php if ($_ctx->feeds->index() == 0) { '.
"echo '".addslashes($ret)."'; } ?>";
}
public static function FeedIfOdd($a)
{
$ret = isset($a['return']) ? $a['return'] : 'odd';
$ret = html::escapeHTML($ret);
return
'<?php if (($_ctx->feeds->index()+1)%2 == 1) { '.
"echo '".addslashes($ret)."'; } ?>";
}
public static function FeedDesc($a)
{
return self::getValue($a, '$_ctx->feeds->feed_desc');
}
public static function FeedOwner($a)
{
return self::getValue($a, '$_ctx->feeds->feed_owner');
}
public static function FeedCategory($a)
{
return self::getValue($a, '$_ctx->feeds->cat_title');
}
public static function FeedCategoryID($a)
{
return self::getValue($a, '$_ctx->feeds->cat_id');
}
public static function FeedCategoryURL($a)
{
return self::getValue($a, '$core->blog->url.$core->url->getBase(\'category\').\'/\'.html::sanitizeURL($_ctx->feeds->cat_url)');
}
public static function FeedCategoryShortURL($a)
{
return self::getValue($a, '$_ctx->feeds->cat_url');
}
public static function FeedID($a)
{
return self::getValue($a, '$_ctx->feeds->feed_id');
}
public static function FeedLang($a)
{
$f = $GLOBALS['core']->tpl->getFilters($a);
return empty($a['full']) ?
'<?php echo '.sprintf($f,'$_ctx->feeds->feed_lang').'; ?>'
:
'<?php $langs = l10n::getISOcodes(); if (isset($langs[$_ctx->feeds->feed_lang])) { echo '.sprintf($f, '$langs[$_ctx->feeds->feed_lang]').'; } else { echo '.sprintf($f, '$_ctx->feeds->feed_lang').'; } unset($langs); ?>';
}
public static function FeedName($a)
{
return self::getValue($a, '$_ctx->feeds->feed_name');
}
public static function FeedSiteURL($a)
{
return self::getValue($a, '$_ctx->feeds->feed_url');
}
public static function FeedFeedURL($a)
{
return self::getValue($a, '$_ctx->feeds->feed_feed');
}
public static function FeedsHeader($a, $c)
{
return "<?php if (\$_ctx->feeds->isStart()) : ?>".$c."<?php endif; ?>";
}
public static function FeedsFooter($a, $c)
{
return "<?php if (\$_ctx->feeds->isEnd()) : ?>".$c."<?php endif; ?>";
}
public static function FeedsCount($a)
{
$none = 'no sources';
$one = 'one source';
$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
"<?php \$fcount = \$_ctx->feeds->count(); \n".
"if (\$fcount == 0) {\n".
" printf(__('".$none."'),\$fcount);\n".
"} elseif (\$fcount == 1) {\n".
" printf(__('".$one."'),\$fcount);\n".
"} else {\n".
" printf(__('".$more."'),\$fcount);\n".
"} unset(\$fcount); ?>";
}
public static function FeedsEntriesCount($a)
{
$none = 'no entries';
$one = 'one entry';
$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
"<?php \$fcount = 0; \$allfeeds = \$_ctx->feeds->zc->getFeeds(); \n".
"if (!\$allfeeds->isEmpty()) { \n".
" while (\$allfeeds->fetch()) { ".
" \$fcount += (integer) \$_ctx->feeds->zc->getPostsByFeed(array('feed_id'=>\$allfeeds->feed_id),true)->f(0); ".
" } \n".
"} \n".
"if (\$fcount == 0) {\n".
" printf(__('".$none."'),\$fcount);\n".
"} elseif (\$fcount == 1) {\n".
" printf(__('".$one."'),\$fcount);\n".
"} else {\n".
" printf(__('".$more."'),\$fcount);\n".
"} unset(\$allfeeds,\$fcount); ?>";
}
public static function FeedEntriesCount($a)
{
$none = 'no entries';
$one = 'one entry';
$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
"<?php \$fcount = \$_ctx->feeds->zc->getPostsByFeed(array('feed_id'=>\$_ctx->feeds->feed_id),true)->f(0); \n".
"if (\$fcount == 0) {\n".
" printf(__('".$none."'),\$fcount);\n".
"} elseif (\$fcount == 1) {\n".
" printf(__('".$one."'),\$fcount);\n".
"} else {\n".
" printf(__('".$more."'),\$fcount);\n".
"} unset(\$fcount); ?>";
}
protected static function getValue($a,$v)
{
return '<?php echo '.sprintf($GLOBALS['core']->tpl->getFilters($a), $v).'; ?>';
}
protected static function getOperator($op)
{
switch (strtolower($op))
{
case 'or':
case '||':
return '||';
case 'and':
case '&&':
default:
return '&&';
}
}
}

83
_uninstall.php Normal file
View File

@ -0,0 +1,83 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_CONTEXT_ADMIN')) {
return null;
}
$mod_id = 'zoneclearFeedServer';
$this->addUserAction(
/* type */ 'settings',
/* action */ 'delete_all',
/* ns */ $mod_id,
/* desc */ __('delete all settings')
);
$this->addUserAction(
/* type */ 'tables',
/* action */ 'delete',
/* ns */ 'zc_feed',
/* desc */ __('delete table')
);
$this->addUserAction(
/* type */ 'plugins',
/* action */ 'delete',
/* ns */ $mod_id,
/* desc */ __('delete plugin files')
);
$this->addUserAction(
/* type */ 'versions',
/* action */ 'delete',
/* ns */ $mod_id,
/* desc */ __('delete the version number')
);
$this->addDirectAction(
/* type */ 'settings',
/* action */ 'delete_all',
/* ns */ $mod_id,
/* desc */ sprintf(__('delete all %s settings'), $mod_id)
);
$this->addDirectAction(
/* type */ 'tables',
/* action */ 'delete',
/* ns */ 'zc_feed',
/* desc */ sprintf(__('delete %s table'), $mod_id)
);
$this->addDirectAction(
/* type */ 'plugins',
/* action */ 'delete',
/* ns */ $mod_id,
/* desc */ sprintf(__('delete %s plugin files'), $mod_id)
);
$this->addDirectAction(
/* type */ 'versions',
/* action */ 'delete',
/* ns */ $mod_id,
/* desc */ sprintf(__('delete %s version number'), $mod_id)
);
$this->addDirectCallback(
/* function */ 'zoneclearfeedServerUninstall',
/* desc */ 'delete feeds relations'
);
function zoneclearfeedServerUninstall($core, $id)
{
if ($id != 'zoneclearFeedServer') {
return null;
}
//...
}

326
_widgets.php Normal file
View File

@ -0,0 +1,326 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_RC_PATH')) {
return null;
}
$core->addBehavior(
'initWidgets',
array('zoneclearFeedServerWidget', 'adminSource')
);
$core->addBehavior(
'initWidgets',
array('zoneclearFeedServerWidget', 'adminNumber')
);
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Mix your blog with a feeds planet - widgets methods.
* @since 2.6
*/
class zoneclearFeedServerWidget
{
/**
* Widget configuration for sources list.
*
* @param dcWidget $w dcWidget instance
*/
public static function adminSource($w)
{
$w->create(
'zcfssource',
__('Feeds server: sources'),
array('zoneclearFeedServerWidget', 'publicSource'),
null,
__('List sources of feeds')
);
$w->zcfssource->setting(
'title',
__('Title:'),
__('Feeds sources'),
'text'
);
$w->zcfssource->setting(
'sortby',
__('Order by:'),
'feed_upd_last',
'combo',
array(
__('Last update') => 'feed_upd_last',
__('Name') => 'lowername',
__('Create date') => 'feed_creadt'
)
);
$w->zcfssource->setting(
'sort',
__('Sort:'),
'desc',
'combo',
array(
__('Ascending') => 'asc',
__('Descending') => 'desc'
)
);
$w->zcfssource->setting(
'limit',
__('Limit:'),
10,
'text'
);
$w->zcfssource->setting(
'pagelink',
__('Add link to feeds page'),
1,
'check'
);
$w->zcfssource->setting(
'homeonly',
__('Display on:'),
0,
'combo',
array(
__('All pages') => 0,
__('Home page only') => 1,
__('Except on home page') => 2
)
);
$w->zcfssource->setting(
'content_only',
__('Content only'),
0,
'check'
);
$w->zcfssource->setting(
'class',
__('CSS class:'),
''
);
$w->zcfssource->setting('offline',__('Offline'),0,'check');
}
/**
* Widget configuration for feeds info.
*
* @param dcWidget $w dcWidget instance
*/
public static function adminNumber($w)
{
$w->create(
'zcfsnumber',
__('Feeds server: numbers'),
array('zoneclearFeedServerWidget', 'publicNumber'),
null,
__('Show some numbers about feeds')
);
$w->zcfsnumber->setting(
'title',
__('Title:')
,__('Feeds numbers'),
'text'
);
# Feed
$w->zcfsnumber->setting(
'feed_show',
__('Show feeds count'),
1,
'check'
);
$w->zcfsnumber->setting(
'feed_title',
__('Title for feeds count:'),
__('Feeds:'),
'text'
);
# Entry
$w->zcfsnumber->setting(
'entry_show',
__('Show entries count'),
1,
'check'
);
$w->zcfsnumber->setting(
'entry_title',
__('Title for entries count:'),
__('Entries:'),
'text'
);
$w->zcfsnumber->setting(
'homeonly',
__('Display on:'),
0,
'combo',
array(
__('All pages') => 0,
__('Home page only') => 1,
__('Except on home page') => 2
)
);
$w->zcfsnumber->setting(
'content_only',
__('Content only'),
0,
'check'
);
$w->zcfsnumber->setting(
'class',
__('CSS class:'),
''
);
$w->zcfsnumber->setting('offline',__('Offline'),0,'check');
}
/**
* Widget for sources list.
*
* @param dcWidget $w dcWidget instance
*/
public static function publicSource($w)
{
global $core;
if ($w->offline)
return;
if (!$core->blog->settings->zoneclearFeedServer->zoneclearFeedServer_active
|| $w->homeonly == 1 && $core->url->type != 'default'
|| $w->homeonly == 2 && $core->url->type == 'default'
) {
return null;
}
$p = array();
$p['order'] = ($w->sortby && in_array($w->sortby, array('feed_upd_last', 'lowername', 'feed_creadt'))) ?
$w->sortby.' ' : 'feed_upd_last ';
$p['order'] .= $w->sort == 'desc' ? 'DESC' : 'ASC';
$p['limit'] = abs((integer) $w->limit);
$p['feed_status'] = 1;
$zc = new zoneclearFeedServer($core);
$rs = $zc->getFeeds($p);
if ($rs->isEmpty()) {
return null;
}
$res = '';
$i = 1;
while($rs->fetch()) {
$res .=
'<li>'.
'<a href="'.$rs->feed_url.'" title="'.$rs->feed_owner.'">'.$rs->feed_name.'</a>'.
'</li>';
$i++;
}
if ($w->pagelink) {
$res .= '<li><a href="'.$core->blog->url.$core->url->getBase('zoneclearFeedsPage').'">'.__('All sources').'</a></li>';
}
$res =
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '').
'<ul>'.$res.'</ul>';
return $w->renderDiv($w->content_only,'zoneclear-sources '.$w->class,'',$res);
}
/**
* Widget for feeds info.
*
* @param dcWidget $w dcWidget instance
*/
public static function publicNumber($w)
{
global $core;
if ($w->offline)
return;
if (!$core->blog->settings->zoneclearFeedServer->zoneclearFeedServer_active
|| $w->homeonly == 1 && $core->url->type != 'default'
|| $w->homeonly == 2 && $core->url->type == 'default'
) {
return null;
}
$zc = new zoneclearFeedServer($core);
$content = '';
# Feed
if ($w->feed_show) {
$title = ($w->feed_title ?
'<strong>'.html::escapeHTML($w->feed_title).'</strong> ' : '');
$count = $zc->getFeeds(array(),true)->f(0);
if ($count == 0) {
$text = sprintf(__('no sources'),$count);
}
elseif ($count == 1) {
$text = sprintf(__('one source'),$count);
}
else {
$text = sprintf(__('%d sources'),$count);
}
if ($core->blog->settings->zoneclearFeedServer->zoneclearFeedServer_pub_active) {
$text = '<a href="'.$core->blog->url.$core->url->getBase('zoneclearFeedsPage').'">'.$text.'</a>';
}
$content .= sprintf('<li>%s%s</li>',$title,$text);
}
# Entry
if ($w->entry_show) {
$count = 0;
$feeds = $zc->getFeeds();
if (!$feeds->isEmpty()) {
while ($feeds->fetch()) {
$count += (integer) $zc->getPostsByFeed(array('feed_id' => $feeds->feed_id), true)->f(0);
}
}
$title = ($w->entry_title ?
'<strong>'.html::escapeHTML($w->entry_title).'</strong> ' : '');
if ($count == 0) {
$text = sprintf(__('no entries'),$count);
}
elseif ($count == 1) {
$text = sprintf(__('one entry'),$count);
}
else {
$text = sprintf(__('%d entries'),$count);
}
$content .= sprintf('<li>%s%s</li>',$title,$text);
}
# Nothing to display
if (!$content) {
return null;
}
# Display
$res =
($w->title ? $w->renderTitle(html::escapeHTML($w->title)) : '').
'<ul>'.$content.'</ul>';
return $w->renderDiv($w->content_only,'zoneclear-number '.$w->class,'',$res);
}
}

124
changelog Normal file
View File

@ -0,0 +1,124 @@
zoneclearFeedServer xxxx.xx.xx
* Not fixed disallow self blog feeds
* Added plugin muppet support (request Mathieu M.)
* Added log for errors
zoneclearFeedServer 2015.04.25 - Pierre Van Glabeke
* modif nom dans liste des plugins
* modif html5 pour validation
zoneclearFeedServer 2015.01.13 - Pierre Van Glabeke
* Dotclear 2.7 requis
* Fin de ligne unix
* Ajout case hors ligne pour les widgets
* Jeux de templates modifiés (mustek/currywurst)
* Modifications locales
zoneclearFeedServer 2013.11.18
* Require Dotclear 2.6
* New icons 'traviata' thx @franckpaul
* Use new Actions systems for feeds and posts
zoneclearFeedServer 2013.07.12
* Added sort option on widget
* Fixed Dashboard counts
* Fixed Feed tags spliting
* Fixed typo
zoneclearFeedServer 2013.07.02
* Required Dotclear 2.5
* Fixed admin pages titles and messages and typo
* Added Favorites icon
* Added new 'homeonly' option on widgets
* Fixed https protocol
* Added option to keep active empty feeds
* Added option to transform imported tags
zoneclearFeedServer 1.3 - 2011-01-30
* Fixed install on nightly build
* Fixed bug on null blog (and settings)
* Added verbose on admin side
* Added behaviors to open to others plugins (ie messenger)
* Added support of plugin soCialMe (writer part)
* Removed messenger functions (as it's to another plugin to do this)
zoneclearFeedServer 1.2 - 2010-09-11
* Added plugin tweakurls support (Thanks Mathieu M.)
zoneclearFeedServer 1.1 - 2010-09-08
* Removed old Twitter functions
* Added StatusNet small functions (Identica)
* Required plugin Tac for Twitter ability
zoneclearFeedServer 1.0 - 2010-06-27
* Switched to DC 2.2 (settings, tags)
* Fixed PHP 5.3 compatibility
* Added toogle menu and link to feed edition in admin post page
* Fixed redirection to original post
* Fixed typo
zoneclearFeedServer 0.8 -2010-06-08
* Added auto tweet new post
* Added option to import tags from feed (or not)
* Fixed filters on admin list (closes #466)
* Enhanced lockUpdate() function
zoneclearFeedServer 0.7.2 - 2010-05-25
* Fixed minor bugs
* Fixed DC 2.1.7
zoneclearFeedServer 0.7.1 - 2010-05-01
* Fixed update order
zoneclearFeedServer 0.7 - 2010-04-22
* Added icon on dashboard if some feeds are disabled
* Added public page of feed description (first step)
* Added update of existing entries
* Added settings to add "aftercontent" and ajax options
* Added uninstall features
* Fixed duplicate entry (I hope so) using php flock
* Fixed feeds actions on admin
* Fixed typo (closes #441)
* Fixed user settings (closes #442)
zoneclearFeedServer 0.6 - 2010-04-11
* Added DC 2.2 compatibility (new setting)
* Added cron script to update feeds
* Fixed multiple bugs
* Changed admin interface
zoneclearFeedServer 0.5.2 - 2010-04-05
* Added option to redirect url to local/original post
* Changed db fields names (fixed pgSQL compatibility)
zoneclearFeedServer 0.5.1 - 2010-02-16
* Fixed php warning on admin post page
zoneclearFeedServer 0.5 - 2010-02-08
* Added option to change update interval by group of feeds
* Fixed order by lower name
* Fixed HTML escape on content
* Fixed typo
zoneclearFeedServer 0.4.3 - 2010-01-02
* Added option to update feeds from admin side
* Added behavior for more urls types for full content
zoneclearFeedServer 0.4 - 2010-02-02
* Added option to change posts owner
* Added option to truncate content on some templates
zoneclearFeedServer 0.3.1 - 2010-01-28
* Fixed bug with getURL on classic post
zoneclearFeedServer 0.3 - 2010-01-27
* First lab release
* Fixed absolute URL
* Fixed unauthentication
zoneclearFeedServer 0.2 - 2010-01-26
* First release
zoneclearFeedServer 0.1 - 2010-01-25
* First test

105
cron-script.php Normal file
View File

@ -0,0 +1,105 @@
#!/usr/bin/env php
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
# This file is highly based cron-script.php
# From Dotclear extension called planet
# By Olivier Meunier and contributors
# Licensed under the GPL version 2.0 license
$opts = getopt('d:c:b:u:h');
function help($status=0)
{
echo
"Options: \n".
" -h shows this help\n".
" -d DotClear root path\n".
" -c DotClear conf path\n".
" -b Blog ID\n".
" -u User ID\n\n";
exit($status);
}
if (isset($opts['h'])) {
help();
}
$dc_root = null;
$dc_conf = null;
$blog_id = null;
if (isset($opts['d'])) {
$dc_root = $opts['d'];
} elseif (isset($_SERVER['DC_ROOT'])) {
$dc_root = $_SERVER['DC_ROOT'];
}
if (isset($opts['c'])) {
$dc_conf = realpath($opts['c']);
} elseif (isset($_SERVER['DC_RC_PATH'])) {
$dc_conf = realpath($_SERVER['DC_RC_PATH']);
}
if (isset($opts['b'])) {
$blog_id = $opts['b'];
} elseif (isset($_SERVER['DC_BLOG_ID'])) {
$blog_id = $opts['DC_BLOG_ID'];
}
if (!$dc_root || !is_dir($dc_root)) {
fwrite(STDERR,"DotClear root path is not defined\n\n");
help(1);
}
if (!$dc_conf || !is_readable($dc_conf)) {
fwrite(STDERR,"DotClear configuration not found\n\n");
help(1);
}
if (!$blog_id) {
fwrite(STDERR,"Blog ID is not defined\n\n");
help(1);
}
$_SERVER['DC_RC_PATH'] = $dc_conf;
unset($dc_conf);
define('DC_BLOG_ID',$blog_id);
unset($blog_id);
require $dc_root.'/inc/prepend.php';
unset($dc_root);
$core->setBlog(DC_BLOG_ID);
if ($core->blog->id == null) {
fwrite(STDERR,"Blog is not defined\n");
exit(1);
}
if (!isset($opts['u']) || !$core->auth->checkUser($opts['u'])) {
fwrite(STDERR,"Unable to set user\n");
exit(1);
}
$core->plugins->loadModules(DC_PLUGINS_ROOT);
$core->blog->settings->addNamespace('zoneclearFeedServer');
try {
$zc = new zoneclearFeedServer($core);
$zc->checkFeedsUpdate();
} catch (Exception $e) {
fwrite(STDERR,$e->getMessage()."\n");
exit(1);
}

View File

@ -0,0 +1,68 @@
{{tpl:extends parent="__layout.html"}}
<tpl:Block name="head-title">
<title>{{tpl:lang List of feeds}} - {{tpl:BlogName encode_html="1"}}</title>
</tpl:Block>
<tpl:Block name="meta-robots">
<meta name="ROBOTS" content="{{tpl:BlogMetaRobots}}" />
</tpl:Block>
<tpl:Block name="meta-entry">
<meta name="description" lang="{{tpl:BlogLanguage}}" content="{{tpl:BlogDescription encode_html="1" cut_string="180"}}" />
<meta name="author" content="{{tpl:BlogEditor encode_html="1"}}" />
<meta name="date" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
</tpl:Block>
<tpl:Block name="dc-entry">
<meta property="dc.title" lang="{{tpl:BlogLanguage}}" content="{{tpl:lang List of feeds}} - {{tpl:BlogName encode_html="1"}}" />
<meta property="dc.description" lang="{{tpl:BlogLanguage}}" content="{{tpl:BlogDescription remove_html="1"}}" />
<meta property="dc.language" content="{{tpl:BlogLanguage}}" />
<meta property="dc.date" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
</tpl:Block>
<tpl:Block name="head-linkrel">
<link rel="contents" href="{{tpl:BlogArchiveURL}}" title="{{tpl:lang Archives}}" />
<tpl:Categories>
<link rel="section" href="{{tpl:CategoryURL}}" title="{{tpl:CategoryTitle encode_html="1"}}" />
</tpl:Categories>
<link rel="alternate" type="application/atom+xml" title="Atom 1.0" href="{{tpl:BlogFeedURL type="atom"}}" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="{{tpl:BlogRSDURL}}" />
<link rel="meta" type="application/xbel+xml" title="Blogroll" href="{{tpl:BlogrollXbelLink}}" />
</tpl:Block>
<tpl:Block name="body-tag"><body class="dc-zcfeeds"></tpl:Block>
<tpl:Block name="main-content">
<div id="main" role="main">
<tpl:zcFeeds sortby="name" order="asc">
<tpl:zcFeedsHeader>
<div id="content-info">
<h2>{{tpl:lang List of feeds}}</h2>
<p>{{tpl:zcFeedsCount}} - {{tpl:zcFeedsEntriesCount}}</p>
</div>
</tpl:zcFeedsHeader>
<div id="p{{tpl:zcFeedID}}" class="post {{tpl:zcFeedIfOdd}} {{tpl:zcFeedIfFirst}}" lang="{{tpl:zcFeedLang}}" xml:lang="{{tpl:zcFeedLang}}">
<h2 class="post-title">{{tpl:zcFeedName encode_html="1"}}</h2>
<p class="post-info">{{tpl:lang By}} <a href="{{tpl:zcFeedSiteURL}}">{{tpl:zcFeedOwner}}</a>
- <a href="{{tpl:zcFeedFeedURL}}">{{tpl:lang source}}</a>
- {{tpl:zcFeedLang full="1"}}
- {{tpl:zcFeedEntriesCount}}
<tpl:zcFeedIf has_category="1">
- <a href="{{tpl:zcFeedCategoryURL}}">{{tpl:zcFeedCategory encode_html="1"}}</a>
</tpl:zcFeedIf>
</p>
<tpl:zcFeedIf has_description="1"><div class="post-content">{{tpl:zcFeedDesc}}</div></tpl:zcFeedIf>
</div>
</tpl:zcFeeds>
</tpl:Block>

View File

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="{{tpl:BlogLanguage}}">
<head>
<meta charset="UTF-8" />
<meta name="ROBOTS" content="{{tpl:BlogMetaRobots}}" />
<title>{{tpl:lang List of feeds}} - {{tpl:BlogName encode_html="1"}}</title>
<meta name="description" lang="{{tpl:BlogLanguage}}" content="{{tpl:BlogDescription cut_string="180" encode_html="1"}}" />
<meta name="copyright" content="{{tpl:BlogCopyrightNotice encode_html="1"}}" />
<meta name="author" content="{{tpl:BlogEditor encode_html="1"}}" />
<meta name="date" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
<meta property="dc.title" lang="{{tpl:BlogLanguage}}" content="{{tpl:lang List of feeds}} - {{tpl:BlogName encode_html="1"}}" />
<meta property="dc.description" lang="{{tpl:BlogLanguage}}" content="{{tpl:BlogDescription encode_html="1"}}" />
<meta property="dc.language" content="{{tpl:BlogLanguage}}" />
<meta property="dc.publisher" content="{{tpl:BlogEditor encode_html="1"}}" />
<meta property="dc.rights" content="{{tpl:BlogCopyrightNotice encode_html="1"}}" />
<meta property="dc.date" content="{{tpl:BlogUpdateDate iso8601="1"}}" />
<meta property="dc.type" content="text" />
<meta property="dc.format" content="text/html" />
<link rel="contents" href="{{tpl:BlogArchiveURL}}" title="{{tpl:lang Archives}}" />
<tpl:Categories>
<link rel="section" href="{{tpl:CategoryURL}}" title="{{tpl:CategoryTitle encode_html="1"}}" />
</tpl:Categories>
<link rel="alternate" type="application/atom+xml" title="Atom 1.0" href="{{tpl:BlogFeedURL type="atom"}}" />
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="{{tpl:BlogRSDURL}}" />
<link rel="meta" type="application/xbel+xml" title="Blogroll" href="{{tpl:BlogrollXbelLink}}" />
{{tpl:include src="_head.html"}}
</head>
<body class="dc-zcfeeds">
<div id="page">
{{tpl:include src="_top.html"}}
<div id="wrapper">
<div id="main" role="main">
<div id="content">
<tpl:zcFeeds sortby="name" order="asc">
<tpl:zcFeedsHeader>
<div id="content-info">
<h2>{{tpl:lang List of feeds}}</h2>
<p>{{tpl:zcFeedsCount}} - {{tpl:zcFeedsEntriesCount}}</p>
</div>
</tpl:zcFeedsHeader>
<div id="p{{tpl:zcFeedID}}" class="post {{tpl:zcFeedIfOdd}} {{tpl:zcFeedIfFirst}}" lang="{{tpl:zcFeedLang}}" xml:lang="{{tpl:zcFeedLang}}">
<h2 class="post-title">{{tpl:zcFeedName encode_html="1"}}</h2>
<p class="post-info">{{tpl:lang By}} <a href="{{tpl:zcFeedSiteURL}}">{{tpl:zcFeedOwner}}</a>
- <a href="{{tpl:zcFeedFeedURL}}">{{tpl:lang source}}</a>
- {{tpl:zcFeedLang full="1"}}
- {{tpl:zcFeedEntriesCount}}
<tpl:zcFeedIf has_category="1">
- <a href="{{tpl:zcFeedCategoryURL}}">{{tpl:zcFeedCategory encode_html="1"}}</a>
</tpl:zcFeedIf>
</p>
<tpl:zcFeedIf has_description="1"><div class="post-content">{{tpl:zcFeedDesc}}</div></tpl:zcFeedIf>
</div>
</tpl:zcFeeds>
</div>
</div> <!-- End #main -->
<div id="sidebar" role="complementary">
<div id="blognav">
{{tpl:Widgets type="nav"}}
</div> <!-- End #blognav -->
<div id="blogextra">
{{tpl:Widgets type="extra"}}
</div> <!-- End #blogextra -->
</div>
</div> <!-- End #wrapper -->
{{tpl:include src="_footer.html"}}
</div> <!-- End #page -->
</body>
</html>

View File

@ -0,0 +1,32 @@
/* -- BEGIN LICENSE BLOCK ----------------------------------
*
* This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
*
* Copyright (c) 2009-2015 Jean-Christian Denis, BG and contributors
*
* Licensed under the GPL version 2.0 license.
* A copy of this license is available in LICENSE file or at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* -- END LICENSE BLOCK ------------------------------------*/
;if(window.jQuery) (function($) {
$.fn.zoneclearFeedServer = function(options) {
var opts = $.extend({}, $.fn.zoneclearFeedServer.defaults, options);
return this.each(function() {
$.ajax({
timeout:5000,
url:opts.blog_url,
type:'POST',
data:{blogId:opts.blog_id}/*,
error:function(){alert('Feeds update failed');},
succes:function(data){data=$(data);alert($(data).find('message').text());}*/
});
});
};
$.fn.zoneclearFeedServer.defaults = {
blog_url: '',
blog_id: ''
};
})(jQuery);

BIN
icon-big-update.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
icon-big.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

View File

@ -0,0 +1,389 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Feeds server - actions methods
* @since 2.6
* @see dcPostsActionsPage for more info
*/
class zcfsFeedsActionsPage extends dcActionsPage
{
public $zcfs;
public function __construct(dcCore $core, $uri, $redirect_args=array())
{
$this->zcfs = new zoneclearFeedServer($core);
parent::__construct($core, $uri, $redirect_args);
$this->redirect_fields = array(
'sortby', 'order', 'page', 'nb'
);
$this->field_entries = 'feeds';
$this->caller_title = __('Feeds');
$this->loadDefaults();
}
protected function loadDefaults()
{
zcfsDefaultFeedsActions::zcfsFeedsActionsPage($this->core, $this);
$this->core->callBehavior('zcfsFeedsActionsPage', $this->core, $this);
}
public function beginPage($breadcrumb='', $head='')
{
echo
'<html><head><title>'.__('Feeds server').'</title>'.
dcPage::jsLoad('js/_posts_actions.js').
$head.
'</script></head><body>'.
$breadcrumb.
'<p><a class="back" href="'.$this->getRedirection(true).'">'.
__('Back to feeds list').'</a></p>';
}
public function endPage()
{
echo
'</body></html>';
}
public function error(Exception $e)
{
$this->core->error->add($e->getMessage());
$this->beginPage(dcPage::breadcrumb(array(
html::escapeHTML($this->core->blog->name) => '',
$this->getCallerTitle() => $this->getRedirection(true),
__('Feeds actions') => ''
)));
$this->endPage();
}
protected function fetchEntries($from)
{
if (!empty($from['feeds'])) {
$params['feed_id'] = $from['feeds'];
$feeds = $this->zcfs->getFeeds($params);
while ($feeds->fetch()) {
$this->entries[$feeds->feed_id] = $feeds->feed_name;
}
$this->rs = $feeds;
}
else {
$this->rs = $this->core->con->select(
"SELECT blog_id FROM ".
$this->core->prefix."blog 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 zcfsFeedsActionsPage(dcCore $core, zcfsFeedsActionsPage $ap)
{
$ap->addAction(
array(__('Change category') => 'changecat'),
array('zcfsDefaultFeedsActions', 'doChangeCategory')
);
$ap->addAction(
array(__('Change update interval') => 'changeint'),
array('zcfsDefaultFeedsActions', 'doChangeInterval')
);
$ap->addAction(
array(__('Disable feed update') => 'disablefeed'),
array('zcfsDefaultFeedsActions', 'doEnableFeed')
);
$ap->addAction(
array(__('Enable feed update') => 'enablefeed'),
array('zcfsDefaultFeedsActions', 'doEnableFeed')
);
$ap->addAction(
array(__('Reset last update') => 'resetupdlast'),
array('zcfsDefaultFeedsActions', 'doResetUpdate')
);
$ap->addAction(
array(__('Update (check) feed') => 'updatefeed'),
array('zcfsDefaultFeedsActions', 'doUpdateFeed')
);
$ap->addAction(
array(__('Delete related posts') => 'deletepost'),
array('zcfsDefaultFeedsActions', 'doDeletePost')
);
$ap->addAction(
array(__('Delete feed (without related posts)') => 'deletefeed'),
array('zcfsDefaultFeedsActions', 'doDeleteFeed')
);
}
public static function doEnableFeed(dcCore $core, zcfsFeedsActionsPage $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);
}
dcPage::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(dcCore $core, zcfsFeedsActionsPage $ap, $post)
{
$types = array(
'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(array(
'feed_id' => $id
));
while($posts->fetch()) {
$core->blog->delPost($posts->post_id);
$core->con->execute(
'DELETE FROM '.$core->prefix.'meta '.
'WHERE post_id = '.$posts->post_id.' '.
'AND meta_type '.$core->con->in($types).' '
);
}
}
dcPage::addSuccessNotice(
__('Entries have been successfully deleted.')
);
$ap->redirect(true);
}
public static function doDeleteFeed(dcCore $core, zcfsFeedsActionsPage $ap, $post)
{
$ids = $ap->getIDs();
if (empty($ids)) {
throw new Exception(__('No feeds selected'));
}
foreach($ids as $id) {
$ap->zcfs->delFeed($id);
}
dcPage::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(dcCore $core, zcfsFeedsActionsPage $ap, $post)
{
$ids = $ap->getIDs();
if (empty($ids)) {
throw new Exception(__('No feeds selected'));
}
foreach($ids as $id) {
$ap->zcfs->checkFeedsUpdate($id, true);
}
dcPage::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(dcCore $core, zcfsFeedsActionsPage $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);
}
dcPage::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(dcCore $core, zcfsFeedsActionsPage $ap, $post)
{
if (isset($post['upd_cat_id'])) {
$ids = $ap->getIDs();
if (empty($ids)) {
throw new Exception(__('No feeds selected'));
}
$cat_id = abs((integer) $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);
}
dcPage::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(
$core->blog->getCategories()
);
$ap->beginPage(
dcPage::breadcrumb(
array(
html::escapeHTML($core->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(array('upd_cat_id'), $categories_combo, '').
$core->formNonce().
$ap->getHiddenFields().
form::hidden(array('action'), 'changecat').
'<input type="submit" value="'.__('Save').'" /></p>'.
'</form>';
$ap->endPage();
}
}
public static function doChangeInterval(dcCore $core, zcfsFeedsActionsPage $ap, $post)
{
if (isset($post['upd_upd_int'])) {
$ids = $ap->getIDs();
if (empty($ids)) {
throw new Exception(__('No feeds selected'));
}
$upd_int = abs((integer) $post['upd_upd_int']);
foreach($ids as $id) {
$cur = $ap->zcfs->openCursor();
$cur->feed_upd_int = $upd_int;
$ap->zcfs->updFeed($id, $cur);
}
dcPage::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(
array(
html::escapeHTML($core->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(array('upd_upd_int'), $ap->zcfs->getAllUpdateInterval(), '').
$core->formNonce().
$ap->getHiddenFields().
form::hidden(array('action'), 'changeint').
'<input type="submit" value="'.__('Save').'" /></p>'.
'</form>';
$ap->endPage();
}
}
}

View File

@ -0,0 +1,933 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
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 $core;
public $con;
private $blog;
private $table;
private $lock = null;
/**
* Constructor.
*
* @param dcCore $core dcCore instance
*/
public function __construct(dcCore $core)
{
$this->core = $core;
$this->con = $core->con;
$this->blog = $core->con->escape($core->blog->id);
$this->table = $core->prefix.'zc_feed';
}
/**
* 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 = (integer) $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
$this->core->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
$this->core->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 = (integer) $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 = (integer) $enable;
if (null !== $time) {
$cur->feed_upd_last = (integer) $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
$this->core->callBehavior(
'zoneclearFeedServerAfterEnableFeed',
$id,
$enable,
$time
);
}
#
/**
* Delete record (this not deletes post).
*
* @param integer $id Feed Id
*/
public function delFeed($id)
{
$id = (integer) $id;
if ($id < 1) {
throw new Exception(__('No such ID'));
}
# --BEHAVIOR-- zoneclearFeedServerBeforeDelFeed
$this->core->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 record record instance
*/
public function getPostsByFeed($params=array(), $count_only=false)
{
if (!isset($params['feed_id'])) {
return null;
}
$params['from'] =
'LEFT JOIN '.$this->core->prefix.'meta F '.
'ON P.post_id = F.post_id ';
$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 $this->core->blog->getPosts($params, $count_only);
}
/**
* Get feed record.
*
* @param array $params Query params
* @param boolean $count_only Return only result count
* @return record record instance
*/
public function getFeeds($params=array(), $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 '.$this->core->prefix.'category 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'],create_function('&$v,$k','if($v!==null){$v=(integer)$v;}'));
}
else {
$params['feed_id'] = array((integer) $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 = ".((integer) $params['feed_status'])." ";
}
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);
$rs->zc = $this;
return $rs;
}
/**
* Get next table id.
*
* @return record record instance
*/
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)
{
# Limit to one update at a time
try {
$this->lockUpdate();
}
catch (Exception $e) {
if ($throw) {
throw $e;
}
return false;
}
dt::setTZ($this->core->blog->settings->system->blog_timezone);
$time = time();
$s = $this->core->blog->settings->zoneclearFeedServer;
# All feeds or only one (from admin)
$f = !$id ?
$this->getFeeds(array(
'feed_status'=>1,
'order'=>'feed_upd_last ASC'
)) :
$this->getFeeds(array(
'feed_id'=>$id
));
# No feed
if ($f->isEmpty()) {
return false;
}
# Set feeds user
$this->enableUser($s->zoneclearFeedServer_user);
$updates = false;
$loop_mem = array();
$limit = abs((integer) $s->zoneclearFeedServer_update_limit);
if ($limit < 1) {
$limit = 10;
}
$i = 0;
$cur_post = $this->con->openCursor($this->core->prefix.'post');
$cur_meta = $this->con->openCursor($this->core->prefix.'meta');
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
) {
$i++;
$feed = self::readFeed($f->feed_feed);
# Nothing to parse
if (!$feed) {
# Keep active empty feed or disable it ?
if (!$s->zoneclearFeedServer_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 '.$this->core->prefix.'post P '.
'INNER JOIN '.$this->core->prefix.'meta 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_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 = $this->core->auth->userID();
$cur_post->post_format = 'xhtml';
$cur_post->post_status = (integer) $s->zoneclearFeedServer_post_status_new;
$cur_post->post_open_comment = 0;
$cur_post->post_open_tb = 0;
# --BEHAVIOR-- zoneclearFeedServerBeforePostCreate
$this->core->callBehavior(
'zoneclearFeedServerBeforePostCreate',
$cur_post
);
$post_id = $this->core->auth->sudo(
array($this->core->blog, 'addPost'),
$cur_post
);
# --BEHAVIOR-- zoneclearFeedServerAfterPostCreate
$this->core->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
$this->core->callBehavior(
'zoneclearFeedServerBeforePostUpdate',
$cur_post,
$post_id
);
$this->core->auth->sudo(
array($this->core->blog, 'updPost'),
$post_id,
$cur_post
);
# Quick delete old meta
$this->con->execute(
'DELETE FROM '.$this->core->prefix.'meta '.
'WHERE post_id = '.$post_id.' '.
"AND meta_type LIKE 'zoneclearfeed_%' "
);
# Delete old tags
$this->core->auth->sudo(
array($this->core->meta, 'delPostMeta'),
$post_id,
'tag'
);
# --BEHAVIOR-- zoneclearFeedServerAfterPostUpdate
$this->core->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 = $this->core->meta->splitMetaValues($f->feed_tags);
if ($f->feed_get_tags) {
# Some feed subjects contains more than one tag
foreach($item->subject as $subjects) {
$tmp = $this->core->meta->splitMetaValues($subjects);
$tags = array_merge($tags, $tmp);
}
$tags = array_unique($tags);
}
$formated_tags = array();
foreach ($tags as $tag) {
# Change tags case
switch((integer) $s->zoneclearFeedServer_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;
$this->core->auth->sudo(
array($this->core->meta, 'setPostMeta'),
$post_id,
'tag',
dcMeta::sanitizeMetaID($tag)
);
}
}
$meta->tags = $formated_tags;
# --BEHAVIOR-- zoneclearFeedServerAfterFeedUpdate
$this->core->callBehavior(
'zoneclearFeedServerAfterFeedUpdate',
$this->core,
$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();
}
}
}
$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) {
if (!$this->core->auth->checkUser($enable)) {
throw new Exception('Unable to set user');
}
}
# Disable
else {
$this->core->auth = null;
$this->core->auth = new dcAuth($this->core);
}
}
/**
* Read and parse external feeds.
*
* @param string $f Feed URL
* @return arrayObject 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 null;
}
}
/**
* Trigger.
*/
private function trigger()
{
$this->core->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 array(
__('Disabled') => '0',
__('Enabled') => '1'
);
}
/**
* Get list of predefined interval.
*
* @return array List of Name/time of intervals
*/
public static function getAllUpdateInterval()
{
return array(
__('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 = array();
# Get super admins
$rs = $this->con->select(
'SELECT user_id, user_super, user_name, user_firstname, user_displayname '.
'FROM '.$this->con->escapeSystem($this->core->prefix.'user').' '.
'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($this->core->prefix.'user').' U '.
'LEFT JOIN '.$this->con->escapeSystem($this->core->prefix.'permissions').' 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.
*
* @param dcCore $core dcCore instance
* @return array List of names/types of URLs
*/
public static function getPublicUrlTypes(dcCore $core)
{
$types = array();
# --BEHAVIOR-- zoneclearFeedServerPublicUrlTypes
$core->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)
{
global $core;
$cur->post_url = tweakUrls::tweakBlogURL($cur->post_url);
$core->auth->sudo(array($core->blog, 'updPost'), $id, $cur);
}
}

204
inc/lib.zcfs.list.php Normal file
View File

@ -0,0 +1,204 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_CONTEXT_ADMIN')) {
return null;
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Feeds server - feeds list methods
* @since 2.6
* @see adminGenericList for more info
*/
class zcfsFeedsList extends adminGenericList
{
public function feedsDisplay($page, $nb_per_page, $url, $enclose='')
{
if ($this->rs->isEmpty()) {
return '<p><strong>'.__('There is no feed').'</strong></p>';
}
$pager = new dcPager($page, $this->rs_count ,$nb_per_page, 10);
$pager->base_url = $url;
$html_block =
'<div class="table-outer">'.
'<table class="clear">'.
'<thead>'.
'<tr>'.
'<th class="nowrap first" colspan="2">'.__('Name').'</th>'.
'<th class="nowrap">'.__('Feed').'</th>'.
'<th class="nowrap">'.__('Frequency').'</th>'.
'<th class="nowrap">'.__('Last update').'</th>'.
'<th class="nowrap">'.__('Entries').'</th>'.
'<th class="nowrap">'.__('Status').'</th>'.
'</tr>'.
'</thead>'.
'<tbody>%s</tbody>'.
'</table>'.
'</div>';
$res = '';
while ($this->rs->fetch()) {
$res .= $this->feedsLine();
}
return
$pager->getLinks().
sprintf($enclose, sprintf($html_block, $res)).
$pager->getLinks();
}
private function feedsLine()
{
$combo_status = zoneclearFeedServer::getAllStatus();
$combo_upd_int = zoneclearFeedServer::getAllUpdateInterval();
$status = $this->rs->feed_status ?
'<img src="images/check-on.png" alt="enable" />' :
'<img src="images/check-off.png" alt="disable" />';
$category = $this->rs->cat_id ?
$this->rs->cat_title : __('no categories');
$entries_count = $this->rs->zc->getPostsByFeed(array('feed_id' => $this->rs->feed_id), true)->f(0);
$shunk_feed = $this->rs->feed_feed;
if (strlen($shunk_feed) > 83) {
$shunk_feed = substr($shunk_feed,0,50).'...'.substr($shunk_feed,-20);
}
$url = 'plugin.php?p=zoneclearFeedServer&amp;part=feed&amp;feed_id='.$this->rs->feed_id;
return
'<tr class="line">'."\n".
'<td class="nowrap">'.
form::checkbox(array('feeds[]'), $this->rs->feed_id, 0).
'</td>'.
'<td class="nowrap">'.
'<a href="'.$url.'#feed" title="'.__('Edit').'">'.
html::escapeHTML($this->rs->feed_name).'</a>'.
"</td>\n".
'<td class="maximal nowrap">'.
'<a href="'.$this->rs->feed_feed.'" title="'.html::escapeHTML($this->rs->feed_desc).'">'.html::escapeHTML($shunk_feed).'</a>'.
"</td>\n".
'<td class="nowrap">'.
array_search($this->rs->feed_upd_int,$combo_upd_int).
"</td>\n".
'<td class="nowrap">'.
($this->rs->feed_upd_last < 1 ?
__('never') :
dt::str(__('%Y-%m-%d %H:%M'), $this->rs->feed_upd_last,$this->rs->zc->core->auth->getInfo('user_tz'))
).
"</td>\n".
'<td class="nowrap">'.
($entries_count ?
'<a href="'.$url.'#entries" title="'.__('View entries').'">'.$entries_count.'</a>' :
$entries_count
).
"</td>\n".
'<td>'.
$status.
"</td>\n".
'</tr>'."\n";
}
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Feeds server - Posts list methods
* @since 2.6
* @see adminGenericList for more info
*/
class zcfsEntriesList extends adminGenericList
{
public function display($page, $nb_per_page, $url, $enclose='')
{
if ($this->rs->isEmpty()) {
return '<p><strong>'.__('No entry').'</strong></p>';
}
$pager = new dcPager($page, $this->rs_count, $nb_per_page, 10);
$pager->base_url = $url;
$pager->html_prev = $this->html_prev;
$pager->html_next = $this->html_next;
$pager->var_page = 'page';
$html_block =
'<div class="table-outer">'.
'<table class="clear"><tr>'.
'<th colspan="2">'.__('Title').'</th>'.
'<th>'.__('Date').'</th>'.
'<th>'.__('Category').'</th>'.
'<th>'.__('Author').'</th>'.
'<th>'.__('Comments').'</th>'.
'<th>'.__('Trackbacks').'</th>'.
'<th>'.__('Status').'</th>'.
'</tr>%s</table></div>';
$res = '';
while ($this->rs->fetch()) {
$res .= $this->postLine();
}
return
$pager->getLinks().
sprintf($enclose, sprintf($html_block, $res)).
$pager->getLinks();
}
private function postLine()
{
$cat_link = $this->core->auth->check('categories', $this->core->blog->id) ?
'<a href="category.php?id=%s" title="'.__('Edit category').'">%s</a>'
: '%2$s';
$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" />';
switch ($this->rs->post_status) {
case 1:
$img_status = sprintf($img, __('published'), 'check-on.png');
break;
case 0:
$img_status = sprintf($img, __('unpublished'), 'check-off.png');
break;
case -1:
$img_status = sprintf($img, __('scheduled'), 'scheduled.png');
break;
case -2:
$img_status = sprintf($img, __('pending'), 'check-wrn.png');
break;
}
return
'<tr class="line'.($this->rs->post_status != 1 ? ' offline' : '').'"'.
' id="p'.$this->rs->post_id.'">'.
'<td class="nowrap">'.
form::checkbox(array('entries[]'), $this->rs->post_id, '', '', '', !$this->rs->isEditable()).'</td>'.
'<td class="maximal"><a href="'.$this->core->getPostAdminURL($this->rs->post_type, $this->rs->post_id).
'" title="'.__('Edit entry').'">'.
html::escapeHTML($this->rs->post_title).'</a></td>'.
'<td class="nowrap">'.dt::dt2str(__('%Y-%m-%d %H:%M'), $this->rs->post_dt).'</td>'.
'<td class="nowrap">'.$cat_title.'</td>'.
'<td class="nowrap">'.$this->rs->user_id.'</td>'.
'<td class="nowrap">'.$this->rs->nb_comment.'</td>'.
'<td class="nowrap">'.$this->rs->nb_trackback.'</td>'.
'<td class="nowrap status">'.$img_status.'</td>'.
'</tr>';
}
}

View File

@ -0,0 +1,148 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_RC_PATH')) {
return null;
}
/**
* @ingroup DC_PLUGIN_ZONECLEARFEEDSERVER
* @brief Feeds server - soCialMe methods
* @since 2.6
*
* Add ability to send social messages when a feed is update
*/
class zcfsSoCialMeWriter
{
public static function soCialMeWriterMarker($rs)
{
$rs['zcfscreate'] = array(
'name' => __('New Zoneclear post'),
'description' => __('When a feed has new entry'),
'action' => array('Message','Link'),
'format' => array('Message'),
'wildcards' => array('Message' => array(
'%posttitle%',
'%postlink%',
'%postauthor%',
'%posttweeter%',
'%sitetitle%',
'%sitelink%',
'%tags'
))
);
}
public static function zoneclearFeedServerAfterFeedUpdate($core, $is_new_published_entry, $post, $meta)
{
// for now only new post
if(!$is_new_published_entry) {
return null;
}
$key = 'zcfscreate';
# Is install
if (!$core->plugins->moduleExists('soCialMe')) {
return null;
}
# Is active
if (!$core->blog->settings->soCialMeWriter->active) {
return null;
}
# Load services
$soCialMeWriter = new soCialMeWriter($core);
# List of service per action
$actions = $soCialMeWriter->getMarker('action');
# List of format per type
$formats = $soCialMeWriter->getMarker('format');
# prepare data
$shortposturl = soCialMeUtils::reduceURL($meta->url);
$shortposturl = $shortposturl ? $shortposturl : $meta->url;
$shortsiteurl = soCialMeUtils::reduceURL($meta->site);
$shortsiteurl = $shortsiteurl ? $shortsiteurl : $meta->site;
// need this?
foreach($meta->tags as $k => $tag) {
$tags[$k] = '#'.$tag;
}
# sendMessage
if (!empty($formats[$key]['Message'])
&& !empty($actions[$key]['Message'])
) {
// parse message
$message_txt = str_replace(
array(
'%posttitle%',
'%postlink%',
'%postauthor%',
'%posttweeter%',
'%sitetitle%',
'%sitelink%',
'%tags'
),
array(
$post->post_title,
$shortposturl,
$meta->author,
$meta->tweeter,
$meta->sitename,
$shortsiteurl,
implode(',', $meta->tags)
),
$formats[$key]['Message']
);
// send message
if (!empty($message_txt)) {
foreach($actions[$key]['Message'] as $service_id) {
$soCialMeWriter->play(
$service_id,
'Message',
'Content',
$message_txt
);
}
}
}
# sendLink
if (!empty($actions[$key]['Link'])) {
foreach($actions[$key]['Link'] as $service_id) {
$soCialMeWriter->play(
$service_id,
'Link',
'Content',
$cur->post_title,$shortposturl
);
}
}
# sendData
// not yet implemented
#sendArticle
// not yet implemented
}
}

View File

@ -0,0 +1,169 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_RC_PATH')) {
return null;
}
# This file is used with plugin activityReport
$core->activityReport->addGroup(
'zoneclearFeedServer',
__('Plugin zoneclearFeedServer')
);
# from BEHAVIOR zoneclearFeedServerAfterAddFeed in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
$core->activityReport->addAction(
'zoneclearFeedServer',
'create',
__('feed creation'),
__('A new feed named "%s" point to "%s" was added by "%s"'),
'zoneclearFeedServerAfterAddFeed',
array('zoneclearFeedServerActivityReportBehaviors', 'addFeed')
);
# from BEHAVIOR zoneclearFeedServerAfterUpdFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
$core->activityReport->addAction(
'zoneclearFeedServer',
'updatefeedinfo',
__('updating feed info'),
__('Feed named "%s" point to "%s" has been updated by "%s"'),
'zoneclearFeedServerAfterUpdFeed',
array('zoneclearFeedServerActivityReportBehaviors', 'updFeedInfo')
);
# from BEHAVIOR zoneclearFeedServerAfterUpdFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
$core->activityReport->addAction(
'zoneclearFeedServer',
'updatefeedrecords',
__('updating feed records'),
__('Records of the feed named "%s" have been updated automatically'),
'zoneclearFeedServerAfterUpdFeed',
array('zoneclearFeedServerActivityReportBehaviors', 'updFeedRecord')
);
# from BEHAVIOR zoneclearFeedServerAfterDelFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
$core->activityReport->addAction(
'zoneclearFeedServer',
'delete',
__('feed deletion'),
__('Feed named "%s" point to "%s" has been deleted by "%s"'),
'zoneclearFeedServerAfterDelFeed',
array('zoneclearFeedServerActivityReportBehaviors', 'delFeed')
);
# from BEHAVIOR zoneclearFeedServerAfterEnableFeed in in zoneclearFeedServer/inc/class.zoneclear.feed.server.php
$core->activityReport->addAction(
'zoneclearFeedServer',
'status',
__('feed status'),
__('Feed named "%s" point to "%s" has been set to "%s"'),
'zoneclearFeedServerAfterEnableFeed',
array('zoneclearFeedServerActivityReportBehaviors', 'enableFeed')
);
class zoneclearFeedServerActivityReportBehaviors
{
public static function addFeed($cur)
{
global $core;
$logs = array(
$cur->feed_name,
$cur->feed_feed,
$core->auth->getInfo('user_cn')
);
$core->activityReport->addLog(
'zoneclearFeedServer',
'create',
$logs
);
}
public static function updFeedInfo($cur, $id)
{
if (defined('DC_CONTEXT_ADMIN')) {
global $core;
$zc = new zoneclearFeedServer($core);
$rs = $zc->getFeeds(array('feed_id' => $id));
$logs = array(
$rs->feed_name,
$rs->feed_feed,
$core->auth->getInfo('user_cn')
);
$core->activityReport->addLog(
'zoneclearFeedServer',
'updatefeedinfo',
$logs
);
}
}
public static function updFeedRecord($cur,$id)
{
if (!defined('DC_CONTEXT_ADMIN')) {
global $core;
$zc = new zoneclearFeedServer($core);
$rs = $zc->getFeeds(array('feed_id' => $id));
$logs = array(
$rs->feed_name
);
$core->activityReport->addLog(
'zoneclearFeedServer',
'updatefeedrecords',
$logs
);
}
}
public static function delFeed($id)
{
global $core;
$zc = new zoneclearFeedServer($core);
$rs = $zc->getFeeds(array('feed_id' => $id));
$logs = array(
$rs->feed_name,
$rs->feed_feed,
$core->auth->getInfo('user_cn')
);
$core->activityReport->addLog(
'zoneclearFeedServer',
'delete',
$logs
);
}
public static function enableFeed($id, $enable, $time)
{
global $core;
$zc = new zoneclearFeedServer($core);
$rs = $zc->getFeeds(array('feed_id' => $id));
$logs = array(
$rs->feed_name,
$rs->feed_feed,
$enable ? 'enable' : 'disable'
);
$core->activityReport->addLog(
'zoneclearFeedServer',
'status',
$logs
);
}
}

856
index.php Normal file
View File

@ -0,0 +1,856 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!defined('DC_CONTEXT_ADMIN')) {
return null;
}
if ($core->getVersion('zoneclearFeedServer') !=
$core->plugins->moduleInfo('zoneclearFeedServer', 'version')) {
return null;
}
dcPage::check('admin');
$zcfs = new zoneclearFeedServer($core);
############################################################
#
# One feed
#
############################################################
if (isset($_REQUEST['part']) && $_REQUEST['part'] == 'feed') {
$feed_id = '';
$feed_name = '';
$feed_desc = '';
$feed_owner = '';
$feed_tweeter = '';
$feed_url = '';
$feed_feed = '';
$feed_lang = $core->auth->getInfo('user_lang');
$feed_tags = '';
$feed_get_tags = '0';
$feed_cat_id = '';
$feed_status = '0';
$feed_upd_int = 3600;
$can_view_page = true;
$feed_headlink = '<link rel="%s" title="%s" href="'.$p_url.'&amp;part=feed&amp;feed_id=%s" />';
$feed_link = '<a href="'.$p_url.'&amp;part=feed&amp;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 = array('-' => '');
try {
$categories = $core->blog->getCategories(array(
'post_type' => 'post'
));
while ($categories->fetch()) {
$combo_categories[
str_repeat('&nbsp;&nbsp;', $categories->level-1).
'&bull; '.html::escapeHTML($categories->cat_title)
] = $categories->cat_id;
}
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
# Get entry informations
if (!empty($_REQUEST['feed_id'])) {
$feed = $zcfs->getFeeds(array('feed_id' => $_REQUEST['feed_id']));
if ($feed->isEmpty()) {
$core->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 = array(
'sql' => 'AND feed_id < '.$feed_id.' ',
'limit' => 1
);
$next_rs = $zcfs->getFeeds($next_params);
$prev_params = array(
'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').'&nbsp;&#187;');
$next_headlink = sprintf($feed_headlink, 'next',
html::escapeHTML($next_rs->feed_name), $next_rs->feed_id);
}
if (!$prev_rs->isEmpty()) {
$prev_link = sprintf($feed_link,$prev_rs->feed_id,
html::escapeHTML($prev_rs->feed_name), '&#171;&nbsp;'.__('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'];
if (isset($_POST['feed_status'])) {
$feed_status = (integer) $_POST['feed_status'];
}
$feed_upd_int = $_POST['feed_upd_int'];
$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.'));
}
$get_feed_cat_id = $core->blog->getCategory($feed_cat_id);
if ($feed_cat_id != '' && !$get_feed_cat_id) {
throw new Exception(__('You must provide valid category.'));
}
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
}
if (!empty($_POST['action']) && $_POST['action'] == 'savefeed'
&& !$core->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 = (integer) $feed_get_tags;
$cur->cat_id = $feed_cat_id != '' ? (integer) $feed_cat_id : null;
$cur->feed_status = (integer) $feed_status;
$cur->feed_upd_int = (integer) $feed_upd_int;
# Update feed
if ($feed_id) {
try {
# --BEHAVIOR-- adminBeforeZoneclearFeedServerFeedUpdate
$core->callBehavior(
'adminBeforeZoneclearFeedServerFeedUpdate',
$cur,
$feed_id
);
$zcfs->updFeed($feed_id, $cur);
# --BEHAVIOR-- adminAfterZoneclearFeedServerFeedUpdate
$core->callBehavior(
'adminAfterZoneclearFeedServerFeedUpdate',
$cur,
$feed_id
);
dcPage::addSuccessNotice(
__('Feed successfully updated.')
);
http::redirect(
$p_url.'&part=feed&feed_id='.$feed_id
);
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
}
else {
try {
# --BEHAVIOR-- adminBeforeZoneclearFeedServerFeedCreate
$core->callBehavior(
'adminBeforeZoneclearFeedServerFeedCreate',
$cur
);
$return_id = $zcfs->addFeed($cur);
# --BEHAVIOR-- adminAfterZoneclearFeedServerFeedCreate
$core->callBehavior(
'adminAfterZoneclearFeedServerFeedCreate',
$cur,
$return_id
);
dcPage::addSuccessNotice(
__('Feed successfully created.')
);
http::redirect(
$p_url.'&part=feed&feed_id='.$return_id
);
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
}
}
# Prepared entries list
if ($feed_id && $can_view_page) {
try {
# Getting categories
$categories = $core->blog->getCategories(array(
'post_type' => 'post'
));
# Getting authors
$users = $core->blog->getPostsUsers();
# Getting dates
$dates = $core->blog->getDates(array(
'type' => 'month'
));
# Getting langs
$langs = $core->blog->getLangs();
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
# Creating filter combo boxes
if (!$core->error->flag()) {
$users_combo = array_merge(
array('-' => ''),
dcAdminCombos::getUsersCombo($users)
);
$categories_combo = array_merge(
array(
new formSelectOption('-', ''),
new formSelectOption(__('(No cat)'), 'NULL')
),
dcAdminCombos::getCategoriesCombo($categories, false)
);
$categories_values = array();
foreach ($categories_combo as $cat) {
if (isset($cat->value)) {
$categories_values[$cat->value] = true;
}
}
$status_combo = array_merge(
array('-' => ''),
dcAdminCombos::getPostStatusesCombo()
);
$selected_combo = array(
'-' => '',
__('Selected') => '1',
__('Not selected') => '0'
);
$dt_m_combo = array_merge(
array('-' => ''),
dcAdminCombos::getDatesCombo($dates)
);
$lang_combo = array_merge(
array('-' => ''),
dcAdminCombos::getLangsCombo($langs,false)
);
$sortby_combo = array(
__('Date') => 'post_dt',
__('Title') => 'post_title',
__('Category') => 'cat_title',
__('Author') => 'user_id',
__('Status') => 'post_status',
__('Selected') => 'post_selected'
);
$order_combo = array(
__('Descending') => 'desc',
__('Ascending') => 'asc'
);
}
# Posts action
$posts_actions_page = new dcPostsActionsPage(
$core,
'plugin.php',
array(
'p' => 'zoneclearFeedServer',
'part' => 'feed',
'feed_id' => $feed_id,
'_ANCHOR' => 'entries'
)
);
if ($posts_actions_page->process()) {
return null;
}
/* Get posts
-------------------------------------------------------- */
$user_id = !empty($_GET['user_id']) ? $_GET['user_id'] : '';
$cat_id = !empty($_GET['cat_id']) ? $_GET['cat_id'] : '';
$status = isset($_GET['status']) ? $_GET['status'] : '';
$selected = isset($_GET['selected']) ? $_GET['selected'] : '';
$month = !empty($_GET['month']) ? $_GET['month'] : '';
$lang = !empty($_GET['lang']) ? $_GET['lang'] : '';
$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'post_dt';
$order = !empty($_GET['order']) ? $_GET['order'] : 'desc';
$show_filters = false;
$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1;
$nb_per_page = 30;
if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) {
if ($nb_per_page != $_GET['nb']) {
$show_filters = true;
}
$nb_per_page = (integer) $_GET['nb'];
}
$params['limit'] = array((($page-1)*$nb_per_page), $nb_per_page);
$params['no_content'] = true;
# - User filter
if ($user_id !== '' && in_array($user_id, $users_combo)) {
$params['user_id'] = $user_id;
$show_filters = true;
}
# - Categories filter
if ($cat_id !== '' && in_array($cat_id, $categories_combo)) {
$params['cat_id'] = $cat_id;
$show_filters = true;
}
# - Status filter
if ($status !== '' && in_array($status, $status_combo)) {
$params['post_status'] = $status;
$show_filters = true;
}
# - Selected filter
if ($selected !== '' && in_array($selected, $selected_combo)) {
$params['post_selected'] = $selected;
$show_filters = true;
}
# - Month filter
if ($month !== '' && in_array($month, $dt_m_combo)) {
$params['post_month'] = substr($month, 4, 2);
$params['post_year'] = substr($month, 0, 4);
$show_filters = true;
}
# - Lang filter
if ($lang !== '' && in_array($lang, $lang_combo)) {
$params['post_lang'] = $lang;
$show_filters = true;
}
# - Sortby and order filter
if ($sortby !== '' && in_array($sortby, $sortby_combo)) {
if ($order !== '' && in_array($order, $order_combo)){
$params['order'] = $sortby.' '.$order;
}
if ($sortby != 'post_dt' || $order != 'desc') {
$show_filters = true;
}
}
# Get posts
try {
$params['feed_id'] = $feed_id;
$posts = $zcfs->getPostsByFeed($params);
$counter = $zcfs->getPostsByFeed($params,true);
$post_list = new zcfsEntriesList(
$core,
$posts,
$counter->f(0)
);
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
}
# Display
echo
'<html><head><title>'.__('Feeds server').'</title>'.
($feed_id && !$core->error->flag() ?
dcPage::jsLoad(
'index.php?pf=periodical/js/postsfilter.js'
).
'<script type="text/javascript">'."\n".
"//<![CDATA["."\n".
dcPage::jsVar(
'dotclear.msg.show_filters',
$show_filters ? 'true':'false'
)."\n".
dcPage::jsVar(
'dotclear.msg.filter_posts_list',
__('Show filters and display options')
)."\n".
dcPage::jsVar(
'dotclear.msg.cancel_the_filter',
__('Cancel filters and display options')
)."\n".
"//]]>\n".
"</script>\n"
: '').
dcPage::jsPageTabs().
$next_headlink."\n".$prev_headlink.
# --BEHAVIOR-- packmanAdminHeader
$core->callBehavior('zcfsAdminHeader', $core).
'</head><body>'.
dcPage::breadcrumb(
array(
html::escapeHTML($core->blog->name) => '',
__('Feeds server') => '',
__('Feeds') => $p_url,
($feed_id ? __('Edit feed') : __('New feed')) => ''
)
).
dcPage::notices();
# Feed
if ($can_view_page) {
# nav link
if ($feed_id && ($next_link || $prev_link)) {
echo '<p>';
if ($prev_link) {
echo $prev_link;
}
if ($next_link && $prev_link) {
echo ' - ';
}
if ($next_link) {
echo $next_link;
}
echo '</p>';
}
echo '
<div 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-- zoneclearFeedServerFeedForm
$core->callBehavior('zoneclearFeedServerFeedForm', $core, $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">'.
form::hidden(array('action'), 'savefeed').
form::hidden(array('feed_id'), $feed_id).
form::hidden(array('p'), 'zoneclearFeedServer').
form::hidden(array('part'), 'feed').
$core->formNonce().
'<input type="submit" name="save" value="'.__('Save').'" /></p>
</form>
</div>';
}
# Entries
if ($feed_id && $can_view_page && !$core->error->flag()) {
echo
'<div class="multi-part" title="'.__('Entries').'" id="entries">'.
'<form action="'.$p_url.'&amp;part=feed#entries" method="get" id="filters-form">'.
'<h3 class="out-of-screen-if-js">'.
__('Cancel filters and display options').
'</h3>'.
'<div class="table">'.
'<div class="cell">'.
'<h4>'.__('Filters').'</h4>'.
'<p><label for="user_id" class="ib">'.__('Author:').'</label> '.
form::combo('user_id',$users_combo,$user_id).'</p>'.
'<p><label for="cat_id" class="ib">'.__('Category:').'</label> '.
form::combo('cat_id',$categories_combo,$cat_id).'</p>'.
'<p><label for="status" class="ib">'.__('Status:').'</label> ' .
form::combo('status',$status_combo,$status).'</p> '.
'</div>'.
'<div class="cell filters-sibling-cell">'.
'<p><label for="selected" class="ib">'.__('Selected:').'</label> '.
form::combo('selected',$selected_combo,$selected).'</p>'.
'<p><label for="month" class="ib">'.__('Month:').'</label> '.
form::combo('month',$dt_m_combo,$month).'</p>'.
'<p><label for="lang" class="ib">'.__('Lang:').'</label> '.
form::combo('lang',$lang_combo,$lang).'</p> '.
'</div>'.
'<div class="cell filters-options">'.
'<h4>'.__('Display options').'</h4>'.
'<p><label for="sortby" class="ib">'.__('Order by:').'</label> '.
form::combo('sortby',$sortby_combo,$sortby).'</p>'.
'<p><label for="order" class="ib">'.__('Sort:').'</label> '.
form::combo('order',$order_combo,$order).'</p>'.
'<p><span class="label ib">'.__('Show').'</span> <label for="nb" class="classic">'.
form::field('nb', 3, 3, $nb_per_page).' '.
__('entries per page').'</label></p>'.
'</div>'.
'</div>'.
'<p><input type="submit" value="'.__('Apply filters and display options').'" />'.
form::hidden(array('p'), 'zoneclearFeedServer').
form::hidden(array('part'), 'feed').
form::hidden(array('feed_id') ,$feed_id).
'<br class="clear" />'. //Opera sucks
'</p>'.
'</form>'.
# Show posts
$post_list->display($page, $nb_per_page,
$p_url.
'&amp;part=feed'.
'&amp;tab=entries'.
'&amp;feed_id='.$feed_id.
'&amp;user_id='.$user_id.
'&amp;cat_id='.$cat_id.
'&amp;status='.$status.
'&amp;selected='.$selected.
'&amp;month='.$month.
'&amp;lang='.$lang.
'&amp;sortby='.$sortby.
'&amp;order='.$order.
'&amp;nb='.$nb_per_page.
'&amp;page=%s',
'<form action="'.$p_url.'&amp;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>'.
form::hidden(array('part'), 'feed').
form::hidden(array('feed_id'), $feed_id).
form::hidden(array('user_id'), $user_id).
form::hidden(array('cat_id'), $cat_id).
form::hidden(array('status'), $status).
form::hidden(array('selected'), $selected).
form::hidden(array('month'), $month).
form::hidden(array('lang'), $lang).
form::hidden(array('sortby'), $sortby).
form::hidden(array('order'), $order).
form::hidden(array('page'), $page).
form::hidden(array('nb'), $nb_per_page).
$core->formNonce().
'</div>'.
'</form>'
);
echo
'</div>';
}
}
############################################################
#
# All feeds
#
############################################################
else {
# Actions page
$feeds_actions_page = new zcfsFeedsActionsPage(
$core,
'plugin.php',
array('p' => 'zoneclearFeedServer', 'part' => 'feeds')
);
if ($feeds_actions_page->process()) {
return null;
}
# Combos
$combo_sortby = array(
__('Date') => 'feed_upddt',
__('Name') => 'lowername',
__('Frequency') => 'feed_upd_int',
__('Date of update') => 'feed_upd_last',
__('Status') => 'feed_status'
);
$combo_order = array(
__('Descending') => 'desc',
__('Ascending') => 'asc'
);
# Prepared lists
$show_filters = false;
$sortby = !empty($_GET['sortby']) ? $_GET['sortby'] : 'feed_upddt';
$order = !empty($_GET['order']) ? $_GET['order'] : 'desc';
$page = !empty($_GET['page']) ? (integer) $_GET['page'] : 1;
$nb_per_page = 30;
if (!empty($_GET['nb']) && (integer) $_GET['nb'] > 0) {
if ($nb_per_page != $_GET['nb']) $show_filters = true;
$nb_per_page = (integer) $_GET['nb'];
}
$params = array();
$params['limit'] = array((($page-1)*$nb_per_page), $nb_per_page);
if ($sortby != '' && in_array($sortby, $combo_sortby)) {
if ($order != '' && in_array($order, $combo_order)) {
$params['order'] = $sortby.' '.$order;
}
if ($sortby != 'feed_upddt' || $order != 'desc') {
$show_filters = true;
}
}
$pager_base_url = $p_url.
'&amp;part=feeds'.
'&amp;sortby='.$sortby.
'&amp;order='.$order.
'&amp;nb='.$nb_per_page.
'&amp;page=%s';
try {
$feeds = $zcfs->getFeeds($params);
$feeds_counter = $zcfs->getFeeds($params, true)->f(0);
$feeds_list = new zcfsFeedsList(
$core,
$feeds,
$feeds_counter,
$pager_base_url
);
}
catch (Exception $e) {
$core->error->add($e->getMessage());
}
# Display
echo
'<html><head><title>'.__('Feeds server').'</title>'.
dcPage::jsLoad(
'index.php?pf=zoneclearFeedServer/js/feedsfilter.js'
).
'<script type="text/javascript">'."\n".
"//<![CDATA["."\n".
dcPage::jsVar(
'dotclear.msg.show_filters',
$show_filters ? 'true':'false'
)."\n".
dcPage::jsVar(
'dotclear.msg.filter_posts_list',
__('Show filters and display options')
)."\n".
dcPage::jsVar(
'dotclear.msg.cancel_the_filter',
__('Cancel filters and display options')
)."\n".
"//]]>\n".
"</script>\n".
dcPage::jsPageTabs().
# --BEHAVIOR-- packmanAdminHeader
$core->callBehavior('zcfsAdminHeader', $core).
'</head><body>'.
dcPage::breadcrumb(
array(
html::escapeHTML($core->blog->name) => '',
__('Feeds server') => '',
__('Feeds') => ''
)
).
dcPage::notices().
'<p class="top-add">'.
'<a class="button add" href="'.$p_url.'&amp;part=feed">'.
__('New feed').'</a></p>'.
'<form action="'.$p_url.'&amp;part=feeds" method="get" id="filters-form">'.
'<h3 class="out-of-screen-if-js">'.__('Show filters and display options').'</h3>'.
'<div class="table">'.
'<div class="cell">'.
'<p><label for="sortby" class="ib">'.__('Order by:').'</label> '.
form::combo('sortby',$combo_sortby, $sortby).'</p>'.
'</div>'.
'<div class="cell">'.
'<p><label for="order" class="ib">'.__('Sort:').'</label> '.
form::combo('order',$combo_order, $order).'</p>'.
'</div>'.
'<div class="cell">'.
'<p><span class="label ib">'.__('Show').'</span> <label for="nb" class="classic">'.
form::field('nb',3,3,$nb_per_page).' '.
__('entries per page').'</label></p>'.
'</div>'.
'</div>'.
'<p><input type="submit" value="'.__('Apply filters and display options').'" />'.
form::hidden(array('p'), 'zoneclearFeedServer').
form::hidden(array('part'), 'feeds').
'<br class="clear" /></p>'. //Opera sucks
'</form>'.
$feeds_list->feedsDisplay($page, $nb_per_page, $pager_base_url,
'<form action="'.$p_url.'&amp;part=feeds" method="post" id="form-actions">'.
'%s'.
'<div class="two-cols">'.
'<p class="col checkboxes-helpers"></p>'.
'<p class="col right">'.__('Selected feeds action:').' '.
form::combo(array('action'), $feeds_actions_page->getCombo()).
'<input type="submit" value="'.__('ok').'" />'.
form::hidden(array('sortby'), $sortby).
form::hidden(array('order'), $order).
form::hidden(array('page'), $page).
form::hidden(array('nb'), $nb_per_page).
form::hidden(array('p'), 'zoneclearFeedServer').
form::hidden(array('part'), 'feeds').
$core->formNonce().
'</p>'.
'</div>'.
'</form>'
);
}
echo
'<hr class="clear"/><p class="right modules">
<a class="module-config" '.
'href="plugins.php?module=zoneclearFeedServer&amp;conf=1&amp;redir='.
urlencode('plugin.php?p=zoneclearFeedServer').'">'.__('Configuration').'</a> -
zoneclearFeedServer - '.$core->plugins->moduleInfo('zoneclearFeedServer', 'version').'&nbsp;
<img alt="'.__('zoneclearFeedServer').'" src="index.php?pf=zoneclearFeedServer/icon.png" />
</p>
</body></html>';

31
js/feedsfilter.js Normal file
View File

@ -0,0 +1,31 @@
$(function(){
$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});
$filtersform = $('#filters-form');
$filtersform.before('<p><a id="filter-control" class="form-control" href="plugin.php?p=zoneclearFeedServer&amp;part=feeds" style="display:inline">'+dotclear.msg.filter_posts_list+'</a></p>')
if( dotclear.msg.show_filters == 'false' ) {
$filtersform.hide();
} else {
$('#filter-control')
.addClass('open')
.text(dotclear.msg.cancel_the_filter);
}
$('#filter-control').click(function() {
if( $(this).hasClass('open') ) {
if( dotclear.msg.show_filters == 'true' ) {
return true;
} else {
$filtersform.hide();
$(this).removeClass('open')
.text(dotclear.msg.filter_posts_list);
}
} else {
$filtersform.show();
$(this).addClass('open')
.text(dotclear.msg.cancel_the_filter);
}
return false;
});
});

7
js/post.js Normal file
View File

@ -0,0 +1,7 @@
$(function(){
/* toogle admin form sidebar */
$('#zcfs h5').toggleWithLegend(
$('#zcfs').children().not('h5'),
{cookie:'dcx_zcfs_admin_form_sidebar',legend_click:true}
);
});

31
js/postsfilter.js Normal file
View File

@ -0,0 +1,31 @@
$(function(){
$('.checkboxes-helpers').each(function(){dotclear.checkboxesHelpers(this);});
$filtersform = $('#filters-form');
$filtersform.before('<p><a id="filter-control" class="form-control" href="plugin.php?p=zoneclearFeedServer&amp;part=feed#entries" style="display:inline">'+dotclear.msg.filter_posts_list+'</a></p>')
if( dotclear.msg.show_filters == 'false' ) {
$filtersform.hide();
} else {
$('#filter-control')
.addClass('open')
.text(dotclear.msg.cancel_the_filter);
}
$('#filter-control').click(function() {
if( $(this).hasClass('open') ) {
if( dotclear.msg.show_filters == 'true' ) {
return true;
} else {
$filtersform.hide();
$(this).removeClass('open')
.text(dotclear.msg.filter_posts_list);
}
} else {
$filtersform.show();
$(this).addClass('open')
.text(dotclear.msg.cancel_the_filter);
}
return false;
});
});

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>Configure ZoneclearFeedServer</title>
</head>
<body>
<h3>Informations</h3>
<ul>
<li>A writable cache folder is required to use this plugin.</li>
<li>If you set a large number of feeds to update at one time, this may cause a timeout error. We recommand to keep it to one.</li>
<li>If you use cron script, you can disable public update.</li>
<li>In order to do update through Ajax, your theme must have behavior publicHeadContent.</li>
</ul>
</body>
</html>

17
locales/en/resources.php Normal file
View File

@ -0,0 +1,17 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!isset($__resources['help']['zoneclearFeedServer']))
{
$__resources['help']['zoneclearFeedServer'] = dirname(__FILE__).'/help/zoneclearFeedServer.html';
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>Configuration de ZoneclearFeedServer</title>
</head>
<body>
<h3>Informations</h3>
<ul>
<li>Un dossier de cache accessible en écriture est nécessaire pour utiliser ce plugin.</li>
<li>Si vous paramétrez un grand nombre de flux à mettre à jour, ceci peut causer une erreur de timeout. Il est recommandé de laisser cette valeur à 1.</li>
<li>Si vous utilisez un script cron, vous pouvez désactiver la mise à jour publique.</li>
<li>Pour utiliser la mise à jour depuis Ajax, votre thème doit avoir le behavior publicheadContent.</li>
</ul>
</body>
</html>

548
locales/fr/main.po Normal file
View File

@ -0,0 +1,548 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: zoneclearFeedServer 2013.07.12\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2013-11-19T08:03:53+00:00\n"
"Last-Translator: Jean-Christian Denis\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Mix your blog with a feeds planet"
msgstr "Mixer votre blog avec un planet"
#: _admin.php:35
#: _admin.php:95
#: inc/class.zcfs.feedsactions.php:34
#: inc/class.zcfs.feedsactions.php:304
#: inc/class.zcfs.feedsactions.php:357
#: index.php:435
#: index.php:468
#: index.php:763
#: index.php:793
msgid "Feeds server"
msgstr "Serveur de flux"
#: _admin.php:143
msgid "%s feed disabled"
msgid_plural "%s feeds disabled"
msgstr[0] "%s flux désactivé"
msgstr[1] "%s flux désactivés"
#: _admin.php:224
msgid "Edit this feed"
msgstr "Modifier ce flux"
#: _admin.php:230
msgid "Feed source"
msgstr "Source du flux"
#: _admin.php:232
msgid "feed URL"
msgstr "URL du fil"
#: _admin.php:233
msgid "site URL"
msgstr "URL du site"
#: _config.php:98
msgid "Disable"
msgstr "Désactiver"
#: _config.php:99
msgid "Before display"
msgstr "Avant l'affichage"
#: _config.php:100
msgid "After display"
msgstr "Après l'affichage"
#: _config.php:101
msgid "Through Ajax"
msgstr "À travers Ajax"
#: _config.php:108
msgid "Keep source case"
msgstr "Garder la casse de la source"
#: _config.php:109
msgid "First upper case"
msgstr "Premier caractère en majuscule"
#: _config.php:110
msgid "All lower case"
msgstr "Tout en minuscule"
#: _config.php:111
msgid "All upper case"
msgstr "Tout en majuscule"
#: _config.php:121
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é !"
#: _config.php:132
msgid "Enable plugin"
msgstr "Activer le plugin"
#: _config.php:136
msgid "View the public list of feeds"
msgstr "Voir la page publique de la liste des flux"
#: _config.php:141
msgid "Rules"
msgstr "Règles"
#: _config.php:146
msgid "Status of new posts:"
msgstr "Status des nouveaux billets :"
#: _config.php:150
msgid "Owner of entries created by zoneclearFeedServer:"
msgstr "Propriétaire des billets créés par zoneclearFeedServer :"
#: _config.php:154
msgid "How to transform imported tags:"
msgstr "Comment tranformer la casse des mots-clés importés :"
#: _config.php:160
msgid "Update feeds on public side:"
msgstr "Mettre à jour les flux depuis la partie publique :"
#: _config.php:164
msgid "Number of feeds to update at one time:"
msgstr "Nombre de flux à mettre à jour à la fois :"
#: _config.php:169
msgid "Keep active empty feeds"
msgstr "Garder actif les flux vides"
#: _config.php:173
msgid "Enable public page"
msgstr "Activer la page publique"
#: _config.php:177
msgid "Redirect to original post on:"
msgstr "Rediriger vers le billet original sur :"
#: _config.php:194
msgid "Show full content on:"
msgstr "Afficher le contenu complet sur :"
#: _public.php:234
msgid "Original post on <a href=\"%s\">%s</a>"
msgstr "Billet original sur <a href=\"%s\">%s</a>"
#: _public.php:245
msgid "Read more details about this feed"
msgstr "Lire plus de détails à propos de ce flux"
#: _widgets.php:35
msgid "Feeds server: sources"
msgstr "Serveur de flux : les sources"
#: _widgets.php:38
msgid "List sources of feeds"
msgstr "Liste des sources du flux"
#: _widgets.php:43
msgid "Feeds sources"
msgstr "Sources des flux"
#: _widgets.php:54
msgid "Create date"
msgstr "Date de création"
#: _widgets.php:69
msgid "Limit:"
msgstr "Limite :"
#: _widgets.php:75
msgid "Add link to feeds page"
msgstr "Ajouter un lien vers la page des flux"
#: _widgets.php:107
msgid "Feeds server: numbers"
msgstr "Serveur de flux : les chiffres"
#: _widgets.php:110
msgid "Show some numbers about feeds"
msgstr "Affciher quelques chiffres à propose du flux"
#: _widgets.php:115
msgid "Feeds numbers"
msgstr "Le flux en chiffres"
#: _widgets.php:122
msgid "Show feeds count"
msgstr "Afficher le nombre de flux"
#: _widgets.php:128
msgid "Title for feeds count:"
msgstr "Titre pour le nombre de flux :"
#: _widgets.php:129
msgid "Feeds:"
msgstr "Flux :"
#: _widgets.php:136
msgid "Show entries count"
msgstr "Afficher le nombre de billets"
#: _widgets.php:142
msgid "Title for entries count:"
msgstr "Titre pour le nombre de billets :"
#: _widgets.php:143
msgid "Entries:"
msgstr "Billets :"
#: _widgets.php:208
msgid "All sources"
msgstr "Toutes les sources"
#: _widgets.php:241
msgid "no sources"
msgstr "aucune source"
#: _widgets.php:244
msgid "one source"
msgstr "une source"
#: _widgets.php:247
msgid "%d sources"
msgstr "%d sources"
#: _widgets.php:270
msgid "no entries"
msgstr "aucun billet"
#: _widgets.php:273
msgid "one entry"
msgstr "un billet"
#: _widgets.php:308
msgid "%d entries"
msgstr "%d billets"
#: default-templates/zcfeeds.html:50
msgid "List of feeds"
msgstr "Liste des sources"
#: inc/class.zcfs.feedsactions.php:21
#: index.php:469
#: index.php:794
msgid "Feeds"
msgstr "Flux de syndication"
#: inc/class.zcfs.feedsactions.php:40
msgid "Back to feeds list"
msgstr "Retour à la liste des flux"
#: inc/class.zcfs.feedsactions.php:55
msgid "Feeds actions"
msgstr "Actions sur les flux"
#: inc/class.zcfs.feedsactions.php:95
msgid "Change update interval"
msgstr "Changer l'interval de mise à jour"
#: inc/class.zcfs.feedsactions.php:99
msgid "Disable feed update"
msgstr "Désactiver la mise à jour du flux"
#: inc/class.zcfs.feedsactions.php:103
msgid "Enable feed update"
msgstr "Activer la mise à jour du flux"
#: inc/class.zcfs.feedsactions.php:107
msgid "Reset last update"
msgstr "Remettre à zéro le chronomètre de mise à jour"
#: inc/class.zcfs.feedsactions.php:111
msgid "Update (check) feed"
msgstr "Mettre à jour (vérifier) le flux"
#: inc/class.zcfs.feedsactions.php:115
msgid "Delete related posts"
msgstr "Effacer les billets liés"
#: inc/class.zcfs.feedsactions.php:119
msgid "Delete feed (without related posts)"
msgstr "Effacer le flux (sans effacer les billets liés)"
#: inc/class.zcfs.feedsactions.php:130
#: inc/class.zcfs.feedsactions.php:169
#: inc/class.zcfs.feedsactions.php:200
#: inc/class.zcfs.feedsactions.php:223
#: inc/class.zcfs.feedsactions.php:246
#: inc/class.zcfs.feedsactions.php:273
#: inc/class.zcfs.feedsactions.php:330
msgid "No feeds selected"
msgstr "Aucun flux selectionné"
#: inc/class.zcfs.feedsactions.php:140
msgid "%d feed has been successfully enabled."
msgid_plural "%d feeds have been successfully enabled."
msgstr[0] "%s flux activé avec succès."
msgstr[1] "%s flux activés avec succès."
#: inc/class.zcfs.feedsactions.php:146
msgid "%d feed has been successfully disabled."
msgid_plural "%d feeds have been successfully disabled."
msgstr[0] "%s flux désactivé avec succès."
msgstr[1] "%s flux désactivés avec succès."
#: inc/class.zcfs.feedsactions.php:190
msgid "Entries have been successfully deleted."
msgstr "Les billets ont été effacé avec succès."
#: inc/class.zcfs.feedsactions.php:209
msgid "%d feed has been successfully deleted."
msgid_plural "%d feeds have been successfully deleted."
msgstr[0] "%s flux effacé avec succès."
msgstr[1] "%s flux effacés avec succès."
#: inc/class.zcfs.feedsactions.php:232
msgid "%d feed has been successfully updated."
msgid_plural "%d feeds have been successfully updated."
msgstr[0] "%s flux mis à jour avec succès."
msgstr[1] "%s flux mis à jour avec succès."
#: inc/class.zcfs.feedsactions.php:209
msgid "Last update of %s feed successfully reseted."
msgid_plural "Last update of %s feeds successfully reseted."
msgstr[0] "Date de dernière mise à jour de %s flux remise à zéro avec succès."
msgstr[1] "Dates de dernières mises à jour de %s flux remises à zéro avec succès."
#: inc/class.zcfs.feedsactions.php:286
msgid "Category of %s feed successfully changed."
msgid_plural "Category of %s feeds successfully changed."
msgstr[0] "Catégorie de %s flux mise à jour avec succès."
msgstr[1] "Catégorie de %s flux mise à jour avec succès."
#: inc/class.zcfs.feedsactions.php:343
msgid "Update frequency of %s feed successfully changed."
msgid_plural "Update frequency of %s feeds successfully changed."
msgstr[0] "Fréquence de mise à jour de %s flux modifiée avec succès."
msgstr[1] "Fréquence de mise à jour de %s flux modifiée avec succès."
#: inc/class.zcfs.feedsactions.php:359
msgid "Change update frequency for this selection"
msgstr "Changer la fréquence de mise à jour pour la selection"
#: inc/class.zcfs.feedsactions.php:365
msgid "Frequency:"
msgstr "Fréquence :"
#: inc/class.zoneclear.feed.server.php:822
msgid "Disabled"
msgstr "Désactivé"
#: inc/class.zoneclear.feed.server.php:823
msgid "Enabled"
msgstr "Activé"
#: inc/class.zoneclear.feed.server.php:835
msgid "Every hour"
msgstr "Toutes les heures"
#: inc/class.zoneclear.feed.server.php:836
msgid "Every two hours"
msgstr "Toutes les deux heures"
#: inc/class.zoneclear.feed.server.php:837
msgid "Two times per day"
msgstr "Deux fois par jour"
#: inc/class.zoneclear.feed.server.php:838
msgid "Every day"
msgstr "Chaque jour"
#: inc/class.zoneclear.feed.server.php:839
msgid "Every two days"
msgstr "Tous les deux jours"
#: inc/class.zoneclear.feed.server.php:911
msgid "Home page"
msgstr "Page d'accueil"
#: inc/class.zoneclear.feed.server.php:912
msgid "Entries pages"
msgstr "Pages des billets"
#: inc/class.zoneclear.feed.server.php:913
msgid "Tags pages"
msgstr "Pages des mots-clés"
#: inc/class.zoneclear.feed.server.php:914
msgid "Archives pages"
msgstr "Pages des archives"
#: inc/class.zoneclear.feed.server.php:915
msgid "Category pages"
msgstr "Pages de catégories"
#: inc/lib.zcfs.list.php:31
msgid "There is no feed"
msgstr "Il n'y a pas de flux"
#: inc/lib.zcfs.list.php:44
#: index.php:494
msgid "Feed"
msgstr "Flux"
#: inc/lib.zcfs.list.php:74
msgid "no categories"
msgstr "aucune catégorie"
#: inc/lib.zcfs.list.php:101
msgid "never"
msgstr "jamais"
#: inc/lib.zcfs.list.php:107
msgid "View entries"
msgstr "Voir les billets"
#: inc/lib.zcfs.socialmewriter.php:32
msgid "New Zoneclear post"
msgstr "Nouveu billet Zoneclear"
#: inc/lib.zcfs.socialmewriter.php:33
msgid "When a feed has new entry"
msgstr "Lorsqu'un flux a un nouveau billet"
#: inc/lib.zcfsr.activityreport.php:23
msgid "Plugin zoneclearFeedServer"
msgstr "Extension zoneclearFeedServer"
#: inc/lib.zcfsr.activityreport.php:30
msgid "feed creation"
msgstr "création d'un flux"
#: inc/lib.zcfsr.activityreport.php:31
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\""
#: inc/lib.zcfsr.activityreport.php:39
msgid "updating feed info"
msgstr "mise à jour des informations du flux (administration)"
#: inc/lib.zcfsr.activityreport.php:40
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\""
#: inc/lib.zcfsr.activityreport.php:48
msgid "updating feed records"
msgstr "mise à jour des enregistrements du flux (automatique)"
#: inc/lib.zcfsr.activityreport.php:49
msgid "Records of the feed named \"%s\" have been updated automatically"
msgstr "Les enregistrements du flux nommé \"%s\" ont été automatiquement mis à jour"
#: inc/lib.zcfsr.activityreport.php:57
msgid "feed deletion"
msgstr "suppression d'un flux"
#: inc/lib.zcfsr.activityreport.php:58
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\""
#: inc/lib.zcfsr.activityreport.php:66
msgid "feed status"
msgstr "status d'un flux"
#: inc/lib.zcfsr.activityreport.php:67
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\""
#: index.php:84
msgid "This feed does not exist."
msgstr "Ce flux n'existe pas."
#: index.php:115
msgid "next feed"
msgstr "flux suivant"
#: index.php:122
msgid "previous feed"
msgstr "flux précédent"
#: index.php:151
msgid "Record with same feed URL already exists."
msgstr "Un enregistrement avec la même URL de flux existe déjà."
#: index.php:154
msgid "You must provide a name."
msgstr "Vous devez indiquer un nom."
#: index.php:157
msgid "You must provide an owner."
msgstr "Vous devez indiquer un propriétaire."
#: index.php:160
msgid "You must provide valid site URL."
msgstr "Vous devez donner une URL de site valide."
#: index.php:163
msgid "You must provide valid feed URL."
msgstr "Vous devez donner une URL de flux valide."
#: index.php:167
msgid "You must provide valid category."
msgstr "Vous devez donner une catégorie valide."
#: index.php:213
msgid "Feed successfully updated."
msgstr "Flux mis à jour avec succès."
#: index.php:241
msgid "Feed successfully created."
msgstr "Flux créé avec succcès."
#: index.php:470
msgid "Edit feed"
msgstr "Edition de flux"
#: index.php:470
#: index.php:801
msgid "New feed"
msgstr "Nouveau flux"
#: index.php:500
msgid "Feed information"
msgstr "Information sur le flux"
#: index.php:510
msgid "Owner:"
msgstr "Propriétaire :"
#: index.php:516
msgid "Tweeter or Identica ident:"
msgstr "Identifiant Twiiter ou Identi.ca :"
#: index.php:522
msgid "Site URL:"
msgstr "URL du site :"
#: index.php:546
msgid "Local settings"
msgstr "Paramètres locaux"
#: index.php:556
msgid "Update:"
msgstr "Mise à jour :"
#: index.php:566
msgid "Import tags from feed"
msgstr "Importer les tags depuis le flux"
#: index.php:708
msgid "Date of update"
msgstr "Date de mise à jour"
#: index.php:833
msgid "Selected feeds action:"
msgstr "Action sur les flux sélectionnés :"

17
locales/fr/resources.php Normal file
View File

@ -0,0 +1,17 @@
<?php
# -- BEGIN LICENSE BLOCK ----------------------------------
#
# This file is part of zoneclearFeedServer, a plugin for Dotclear 2.
#
# Copyright (c) 2009-2015 Jean-Christian Denis and contributors
#
# Licensed under the GPL version 2.0 license.
# A copy of this license is available in LICENSE file or at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
#
# -- END LICENSE BLOCK ------------------------------------
if (!isset($__resources['help']['zoneclearFeedServer']))
{
$__resources['help']['zoneclearFeedServer'] = dirname(__FILE__).'/help/zoneclearFeedServer.html';
}