Current oav website
This commit is contained in:
392
dotclear._no/inc/admin/actions/class.dcaction.php
Normal file
392
dotclear._no/inc/admin/actions/class.dcaction.php
Normal file
@ -0,0 +1,392 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
if (!defined('DC_RC_PATH')) {return;}
|
||||
|
||||
/**
|
||||
* dcActionsPage -- handler for action page on selected entries
|
||||
*
|
||||
*/
|
||||
abstract class dcActionsPage
|
||||
{
|
||||
/** @var string form submit uri */
|
||||
protected $uri;
|
||||
/** @var dcCore dotclear core instance */
|
||||
protected $core;
|
||||
/** @var array action combo box */
|
||||
protected $combo;
|
||||
/** @var array list of defined actions (callbacks) */
|
||||
protected $actions;
|
||||
/** @var array selected entries (each key is the entry id, value contains the entry description) */
|
||||
protected $entries;
|
||||
/** @var record record that challenges ids against permissions */
|
||||
protected $rs;
|
||||
/** @var array redirection $_GET arguments, if any (does not contain ids by default, ids may be merged to it) */
|
||||
protected $redir_args;
|
||||
/** @var array list of $_POST fields used to build the redirection */
|
||||
protected $redirect_fields;
|
||||
/** @var string redirection anchor if any */
|
||||
protected $redir_anchor;
|
||||
|
||||
/** @var string current action, if any */
|
||||
protected $action;
|
||||
/** @var array list of url parameters (usually $_POST) */
|
||||
protected $from;
|
||||
/** @var string form field name for "entries" (usually "entries") */
|
||||
protected $field_entries;
|
||||
|
||||
/** @var string title for checkboxes list, if displayed */
|
||||
protected $cb_title;
|
||||
|
||||
/** @var string title for caller page title */
|
||||
protected $caller_title;
|
||||
|
||||
/** @var boolean true if we are acting inside a plugin (different handling of begin/endpage) */
|
||||
protected $in_plugin;
|
||||
|
||||
/** @var boolean true if we enable to keep selection when redirecting */
|
||||
protected $enable_redir_selection;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
* @param mixed $core dotclear core
|
||||
* @param mixed $uri form uri
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function __construct($core, $uri, $redirect_args = [])
|
||||
{
|
||||
$this->core = $core;
|
||||
$this->actions = new ArrayObject();
|
||||
$this->combo = [];
|
||||
$this->uri = $uri;
|
||||
$this->redir_args = $redirect_args;
|
||||
$this->redirect_fields = [];
|
||||
$this->action = '';
|
||||
$this->cb_title = __('Title');
|
||||
$this->entries = [];
|
||||
$this->from = new ArrayObject($_POST);
|
||||
$this->field_entries = 'entries';
|
||||
$this->caller_title = __('Entries');
|
||||
if (isset($this->redir_args['_ANCHOR'])) {
|
||||
$this->redir_anchor = '#' . $this->redir_args['_ANCHOR'];
|
||||
unset($this->redir_args['_ANCHOR']);
|
||||
} else {
|
||||
$this->redir_anchor = '';
|
||||
}
|
||||
$u = explode('?', $_SERVER['REQUEST_URI']);
|
||||
$this->in_plugin = (strpos($u[0], 'plugin.php') !== false);
|
||||
$this->enable_redir_selection = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* setEnableRedirSelection - define whether to keep selection when redirecting
|
||||
* Can be usefull to be disabled to preserve some compatibility.
|
||||
*
|
||||
* @param boolean $enable true to enable, false otherwise
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function setEnableRedirSelection($enable)
|
||||
{
|
||||
$this->enable_redir_selection = $enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* addAction - adds an action
|
||||
*
|
||||
* @param string $actions the actions names as if it was a standalone combo array.
|
||||
* It will be merged with other actions.
|
||||
* Can be bound to multiple values, if the same callback is to be called
|
||||
* @param callback $callback the callback for the action.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return dcActionsPage the actions page itself, enabling to chain addAction().
|
||||
*/
|
||||
public function addAction($actions, $callback)
|
||||
{
|
||||
foreach ($actions as $k => $a) {
|
||||
// Check each case of combo definition
|
||||
// Store form values in $values
|
||||
if (is_array($a)) {
|
||||
$values = array_values($a);
|
||||
if (!isset($this->combo[$k])) {
|
||||
$this->combo[$k] = [];
|
||||
}
|
||||
$this->combo[$k] = array_merge($this->combo[$k], $a);
|
||||
} elseif ($a instanceof formSelectOption) {
|
||||
$values = [$a->value];
|
||||
$this->combo[$k] = $a->value;
|
||||
} else {
|
||||
$values = [$a];
|
||||
$this->combo[$k] = $a;
|
||||
}
|
||||
// Associate each potential value to the callback
|
||||
foreach ($values as $v) {
|
||||
$this->actions[$v] = $callback;
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* getCombo - returns the actions combo, useable through form::combo
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return array the actions combo
|
||||
*/
|
||||
public function getCombo()
|
||||
{
|
||||
return $this->combo;
|
||||
}
|
||||
|
||||
/**
|
||||
* getIDS() - returns the list of selected entries
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return array the list
|
||||
*/
|
||||
public function getIDs()
|
||||
{
|
||||
return array_keys($this->entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* getIDS() - returns the list of selected entries as HTML hidden fields string
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the HTML code for hidden fields
|
||||
*/
|
||||
public function getIDsHidden()
|
||||
{
|
||||
$ret = '';
|
||||
foreach ($this->entries as $id => $v) {
|
||||
$ret .= form::hidden($this->field_entries . '[]', $id);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* getHiddenFields() - returns all redirection parameters as HTML hidden fields
|
||||
*
|
||||
* @param boolean $with_ids if true, also include ids in HTML code
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the HTML code for hidden fields
|
||||
*/
|
||||
public function getHiddenFields($with_ids = false)
|
||||
{
|
||||
$ret = '';
|
||||
foreach ($this->redir_args as $k => $v) {
|
||||
$ret .= form::hidden([$k], $v);
|
||||
}
|
||||
if ($with_ids) {
|
||||
$ret .= $this->getIDsHidden();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* getRS() - get record from DB Query containing requested IDs
|
||||
*
|
||||
* @param boolean $with_ids if true, also include ids in HTML code
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the HTML code for hidden fields
|
||||
*/
|
||||
public function getRS()
|
||||
{
|
||||
return $this->rs;
|
||||
}
|
||||
|
||||
/**
|
||||
* setupRedir - setup redirection arguments
|
||||
* by default, $_POST fields as defined in redirect_fields attributes
|
||||
* are set into redirect_args.
|
||||
*
|
||||
* @param array $from input to parse fields from (usually $_POST)
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
protected function setupRedir($from)
|
||||
{
|
||||
foreach ($this->redirect_fields as $p) {
|
||||
if (isset($from[$p])) {
|
||||
$this->redir_args[$p] = $from[$p];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getRedirection - returns redirection URL
|
||||
*
|
||||
* @param array $params extra parameters to append to redirection
|
||||
* must be an array : each key is the name,
|
||||
* each value is the wanted value
|
||||
* @param boolean $with_selected_entries if true, add selected entries in url
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the redirection url
|
||||
*/
|
||||
public function getRedirection($with_selected_entries = false, $params = [])
|
||||
{
|
||||
$redir_args = array_merge($params, $this->redir_args);
|
||||
if (isset($redir_args['redir'])) {
|
||||
unset($redir_args['redir']);
|
||||
}
|
||||
|
||||
if ($with_selected_entries && $this->enable_redir_selection) {
|
||||
$redir_args[$this->field_entries] = array_keys($this->entries);
|
||||
}
|
||||
return $this->uri . '?' . http_build_query($redir_args) . $this->redir_anchor;
|
||||
}
|
||||
|
||||
/**
|
||||
* redirect - redirects to redirection page
|
||||
*
|
||||
* @see getRedirection for arguments details
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function redirect($with_selected_entries = false, $params = [])
|
||||
{
|
||||
http::redirect($this->getRedirection($with_selected_entries, $params));
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* getURI - returns current form URI, if any
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the form URI
|
||||
*/
|
||||
public function getURI()
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* getCallerTitle - returns current form URI, if any
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the form URI
|
||||
*/
|
||||
public function getCallerTitle()
|
||||
{
|
||||
return $this->caller_title;
|
||||
}
|
||||
|
||||
/**
|
||||
* getAction - returns current action, if any
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the action
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* process - proceeds action handling, if any
|
||||
* this method may issue an exit() if
|
||||
* an action is being processed. If it
|
||||
* returns, no action has been performed
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
|
||||
$this->setupRedir($this->from);
|
||||
$this->fetchEntries($this->from);
|
||||
if (isset($this->from['action'])) {
|
||||
$this->action = $this->from['action'];
|
||||
try {
|
||||
$performed = false;
|
||||
foreach ($this->actions as $k => $v) {
|
||||
if ($this->from['action'] == $k) {
|
||||
$performed = true;
|
||||
call_user_func($v, $this->core, $this, $this->from);
|
||||
}
|
||||
}
|
||||
if ($performed) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->error($e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getcheckboxes -returns html code for selected entries
|
||||
* as a table containing entries checkboxes
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the html code for checkboxes
|
||||
*/
|
||||
public function getCheckboxes()
|
||||
{
|
||||
$ret =
|
||||
'<table class="posts-list"><tr>' .
|
||||
'<th colspan="2">' . $this->cb_title . '</th>' .
|
||||
'</tr>';
|
||||
foreach ($this->entries as $id => $title) {
|
||||
$ret .=
|
||||
'<tr><td class="minimal">' .
|
||||
form::checkbox([$this->field_entries . '[]'], $id, [
|
||||
'checked' => true
|
||||
]) .
|
||||
'</td>' .
|
||||
'<td>' . $title . '</td></tr>';
|
||||
}
|
||||
$ret .= '</table>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* beginPage, endPage - displays the beginning/ending of a page, if action does not redirects dirtectly
|
||||
*
|
||||
* These methods are called from the actions themselves.
|
||||
*
|
||||
* @param string $breadcrumb breadcrumb to display
|
||||
* @param string $head page header to include
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
abstract public function beginPage($breadcrumb = '', $head = '');
|
||||
abstract public function endPage();
|
||||
|
||||
/**
|
||||
* fetchEntries - fills-in information by requesting into db
|
||||
* this method may setup the following attributes
|
||||
* * entries : list of entries (checked against permissions)
|
||||
* entries ids are array keys, values contain entry description (if relevant)
|
||||
* * rs : record given by db request
|
||||
* @access protected
|
||||
*/
|
||||
abstract protected function fetchEntries($from);
|
||||
|
||||
}
|
||||
205
dotclear._no/inc/admin/actions/class.dcactionblogs.php
Normal file
205
dotclear._no/inc/admin/actions/class.dcactionblogs.php
Normal file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
if (!defined('DC_RC_PATH')) {return;}
|
||||
|
||||
class dcBlogsActionsPage extends dcActionsPage
|
||||
{
|
||||
public function __construct($core, $uri, $redirect_args = [])
|
||||
{
|
||||
parent::__construct($core, $uri, $redirect_args);
|
||||
$this->redirect_fields = ['status', 'sortby', 'order', 'page', 'nb'];
|
||||
$this->field_entries = 'blogs';
|
||||
$this->title_cb = __('Blogs');
|
||||
$this->loadDefaults();
|
||||
$core->callBehavior('adminBlogsActionsPage', $core, $this);
|
||||
}
|
||||
|
||||
protected function loadDefaults()
|
||||
{
|
||||
// We could have added a behavior here, but we want default action
|
||||
// to be setup first
|
||||
dcDefaultBlogActions::adminBlogsActionsPage($this->core, $this);
|
||||
}
|
||||
|
||||
public function beginPage($breadcrumb = '', $head = '')
|
||||
{
|
||||
if ($this->in_plugin) {
|
||||
echo '<html><head><title>' . __('Blogs') . '</title>' .
|
||||
dcPage::jsLoad('js/_blogs_actions.js') .
|
||||
$head .
|
||||
'</script></head><body>' .
|
||||
$breadcrumb;
|
||||
} else {
|
||||
dcPage::open(
|
||||
__('Blogs'),
|
||||
dcPage::jsLoad('js/_blogs_actions.js') .
|
||||
$head,
|
||||
$breadcrumb
|
||||
);
|
||||
}
|
||||
echo '<p><a class="back" href="' . $this->getRedirection(true) . '">' . __('Back to blogs list') . '</a></p>';
|
||||
}
|
||||
|
||||
public function endPage()
|
||||
{
|
||||
dcPage::close();
|
||||
}
|
||||
|
||||
public function error(Exception $e)
|
||||
{
|
||||
$this->core->error->add($e->getMessage());
|
||||
$this->beginPage(dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($this->core->blog->name) => '',
|
||||
__('Blogs') => $this->core->adminurl->get('admin.blogs'),
|
||||
__('Blogs actions') => ''
|
||||
])
|
||||
);
|
||||
$this->endPage();
|
||||
}
|
||||
|
||||
public function getCheckboxes()
|
||||
{
|
||||
$ret = '';
|
||||
foreach ($this->entries as $id => $res) {
|
||||
$ret .=
|
||||
'<tr>' .
|
||||
'<td class="minimal">' . form::checkbox([$this->field_entries . '[]'], $id,
|
||||
[
|
||||
'checked' => true
|
||||
]) .
|
||||
'</td>' .
|
||||
'<td>' . $res['blog'] . '</td>' .
|
||||
'<td>' . $res['name'] . '</td>' .
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
return
|
||||
'<table class="blogs-list"><tr>' .
|
||||
'<th colspan="2">' . __('Blog id') . '</th><th>' . __('Blog name') . '</th>' .
|
||||
'</tr>' . $ret . '</table>';
|
||||
}
|
||||
|
||||
protected function fetchEntries($from)
|
||||
{
|
||||
$params = [];
|
||||
if (!empty($from['blogs'])) {
|
||||
$params['blog_id'] = $from['blogs'];
|
||||
}
|
||||
|
||||
$bl = $this->core->getBlogs($params);
|
||||
while ($bl->fetch()) {
|
||||
$this->entries[$bl->blog_id] = [
|
||||
'blog' => $bl->blog_id,
|
||||
'name' => $bl->blog_name
|
||||
];
|
||||
}
|
||||
$this->rs = $bl;
|
||||
}
|
||||
}
|
||||
|
||||
class dcDefaultBlogActions
|
||||
{
|
||||
public static function adminBlogsActionsPage($core, dcBlogsActionsPage $ap)
|
||||
{
|
||||
if (!$core->auth->isSuperAdmin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ap->addAction(
|
||||
[__('Status') => [
|
||||
__('Set online') => 'online',
|
||||
__('Set offline') => 'offline',
|
||||
__('Set as removed') => 'remove'
|
||||
]],
|
||||
['dcDefaultBlogActions', 'doChangeBlogStatus']
|
||||
);
|
||||
$ap->addAction(
|
||||
[__('Delete') => [
|
||||
__('Delete') => 'delete']],
|
||||
['dcDefaultBlogActions', 'doDeleteBlog']
|
||||
);
|
||||
}
|
||||
|
||||
public static function doChangeBlogStatus($core, dcBlogsActionsPage $ap, $post)
|
||||
{
|
||||
if (!$core->auth->isSuperAdmin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = $ap->getAction();
|
||||
$ids = $ap->getIDs();
|
||||
if (empty($ids)) {
|
||||
throw new Exception(__('No blog selected'));
|
||||
}
|
||||
switch ($action) {
|
||||
case 'online':$status = 1;
|
||||
break;
|
||||
case 'offline':$status = 0;
|
||||
break;
|
||||
case 'remove':$status = -1;
|
||||
break;
|
||||
default:$status = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
$cur = $core->con->openCursor($core->prefix . 'blog');
|
||||
$cur->blog_status = $status;
|
||||
//$cur->blog_upddt = date('Y-m-d H:i:s');
|
||||
$cur->update('WHERE blog_id ' . $core->con->in($ids));
|
||||
|
||||
dcPage::addSuccessNotice(__('Selected blogs have been successfully updated.'));
|
||||
$ap->redirect(true);
|
||||
}
|
||||
|
||||
public static function doDeleteBlog($core, dcBlogsActionsPage $ap, $post)
|
||||
{
|
||||
if (!$core->auth->isSuperAdmin()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ap_ids = $ap->getIDs();
|
||||
if (empty($ap_ids)) {
|
||||
throw new Exception(__('No blog selected'));
|
||||
}
|
||||
|
||||
if (!$core->auth->checkPassword($_POST['pwd'])) {
|
||||
throw new Exception(__('Password verification failed'));
|
||||
}
|
||||
|
||||
$ids = [];
|
||||
foreach ($ap_ids as $id) {
|
||||
if ($id == $core->blog->id) {
|
||||
dcPage::addWarningNotice(__('The current blog cannot be deleted.'));
|
||||
} else {
|
||||
$ids[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($ids)) {
|
||||
# --BEHAVIOR-- adminBeforeBlogsDelete
|
||||
$core->callBehavior('adminBeforeBlogsDelete', $ids);
|
||||
|
||||
foreach ($ids as $id) {
|
||||
$core->delBlog($id);
|
||||
}
|
||||
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d blog has been successfully deleted',
|
||||
'%d blogs have been successfully deleted',
|
||||
count($ids)
|
||||
),
|
||||
count($ids))
|
||||
);
|
||||
}
|
||||
$ap->redirect(false);
|
||||
}
|
||||
}
|
||||
235
dotclear._no/inc/admin/actions/class.dcactioncomments.php
Normal file
235
dotclear._no/inc/admin/actions/class.dcactioncomments.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
if (!defined('DC_RC_PATH')) {return;}
|
||||
|
||||
class dcCommentsActionsPage extends dcActionsPage
|
||||
{
|
||||
public function __construct($core, $uri, $redirect_args = [])
|
||||
{
|
||||
parent::__construct($core, $uri, $redirect_args);
|
||||
$this->redirect_fields = ['type', 'author', 'status',
|
||||
'sortby', 'ip', 'order', 'page', 'nb', 'section'];
|
||||
$this->field_entries = 'comments';
|
||||
$this->title_cb = __('Comments');
|
||||
$this->loadDefaults();
|
||||
$core->callBehavior('adminCommentsActionsPage', $core, $this);
|
||||
}
|
||||
|
||||
protected function loadDefaults()
|
||||
{
|
||||
// We could have added a behavior here, but we want default action
|
||||
// to be setup first
|
||||
dcDefaultCommentActions::adminCommentsActionsPage($this->core, $this);
|
||||
}
|
||||
|
||||
public function beginPage($breadcrumb = '', $head = '')
|
||||
{
|
||||
if ($this->in_plugin) {
|
||||
echo '<html><head><title>' . __('Comments') . '</title>' .
|
||||
dcPage::jsLoad('js/_comments_actions.js') .
|
||||
$head .
|
||||
'</script></head><body>' .
|
||||
$breadcrumb;
|
||||
} else {
|
||||
dcPage::open(
|
||||
__('Comments'),
|
||||
dcPage::jsLoad('js/_comments_actions.js') .
|
||||
$head,
|
||||
$breadcrumb
|
||||
);
|
||||
|
||||
}
|
||||
echo '<p><a class="back" href="' . $this->getRedirection(true) . '">' . __('Back to comments list') . '</a></p>';
|
||||
}
|
||||
|
||||
public function endPage()
|
||||
{
|
||||
dcPage::close();
|
||||
}
|
||||
|
||||
public function error(Exception $e)
|
||||
{
|
||||
$this->core->error->add($e->getMessage());
|
||||
$this->beginPage(dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($this->core->blog->name) => '',
|
||||
__('Comments') => $this->core->adminurl->get('admin.comments'),
|
||||
__('Comments actions') => ''
|
||||
])
|
||||
);
|
||||
$this->endPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* getcheckboxes -returns html code for selected entries
|
||||
* as a table containing entries checkboxes
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @return string the html code for checkboxes
|
||||
*/
|
||||
public function getCheckboxes()
|
||||
{
|
||||
$ret =
|
||||
'<table class="posts-list"><tr>' .
|
||||
'<th colspan="2">' . __('Author') . '</th><th>' . __('Title') . '</th>' .
|
||||
'</tr>';
|
||||
foreach ($this->entries as $id => $title) {
|
||||
$ret .=
|
||||
'<tr><td class="minimal">' .
|
||||
form::checkbox([$this->field_entries . '[]'], $id,
|
||||
[
|
||||
'checked' => true
|
||||
]) .
|
||||
'</td>' .
|
||||
'<td>' . $title['author'] . '</td><td>' . $title['title'] . '</td></tr>';
|
||||
}
|
||||
$ret .= '</table>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
protected function fetchEntries($from)
|
||||
{
|
||||
$params = [];
|
||||
if (!empty($from['comments'])) {
|
||||
$comments = $from['comments'];
|
||||
|
||||
foreach ($comments as $k => $v) {
|
||||
$comments[$k] = (integer) $v;
|
||||
}
|
||||
|
||||
$params['sql'] = 'AND C.comment_id IN(' . implode(',', $comments) . ') ';
|
||||
} else {
|
||||
$params['sql'] = 'AND 1=0 ';
|
||||
}
|
||||
|
||||
if (!isset($from['full_content']) || empty($from['full_content'])) {
|
||||
$params['no_content'] = true;
|
||||
}
|
||||
$co = $this->core->blog->getComments($params);
|
||||
while ($co->fetch()) {
|
||||
$this->entries[$co->comment_id] = [
|
||||
'title' => $co->post_title,
|
||||
'author' => $co->comment_author
|
||||
];
|
||||
}
|
||||
$this->rs = $co;
|
||||
}
|
||||
}
|
||||
|
||||
class dcDefaultCommentActions
|
||||
{
|
||||
public static function adminCommentsActionsPage($core, dcCommentsActionsPage $ap)
|
||||
{
|
||||
if ($core->auth->check('publish,contentadmin', $core->blog->id)) {
|
||||
$ap->addAction(
|
||||
[__('Status') => [
|
||||
__('Publish') => 'publish',
|
||||
__('Unpublish') => 'unpublish',
|
||||
__('Mark as pending') => 'pending',
|
||||
__('Mark as junk') => 'junk'
|
||||
]],
|
||||
['dcDefaultCommentActions', 'doChangeCommentStatus']
|
||||
);
|
||||
}
|
||||
|
||||
if ($core->auth->check('delete,contentadmin', $core->blog->id)) {
|
||||
$ap->addAction(
|
||||
[__('Delete') => [
|
||||
__('Delete') => 'delete']],
|
||||
['dcDefaultCommentActions', 'doDeleteComment']
|
||||
);
|
||||
}
|
||||
|
||||
$ip_filter_active = true;
|
||||
if ($core->blog->settings->antispam->antispam_filters !== null) {
|
||||
$filters_opt = $core->blog->settings->antispam->antispam_filters;
|
||||
if (is_array($filters_opt)) {
|
||||
$ip_filter_active = isset($filters_opt['dcFilterIP']) && is_array($filters_opt['dcFilterIP']) && $filters_opt['dcFilterIP'][0] == 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ip_filter_active) {
|
||||
$blacklist_actions = [__('Blacklist IP') => 'blacklist'];
|
||||
if ($core->auth->isSuperAdmin()) {
|
||||
$blacklist_actions[__('Blacklist IP (global)')] = 'blacklist_global';
|
||||
}
|
||||
|
||||
$ap->addAction(
|
||||
[__('IP address') => $blacklist_actions],
|
||||
['dcDefaultCommentActions', 'doBlacklistIP']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function doChangeCommentStatus($core, dcCommentsActionsPage $ap, $post)
|
||||
{
|
||||
$action = $ap->getAction();
|
||||
$co_ids = $ap->getIDs();
|
||||
if (empty($co_ids)) {
|
||||
throw new Exception(__('No comment selected'));
|
||||
}
|
||||
switch ($action) {
|
||||
case 'unpublish':$status = 0;
|
||||
break;
|
||||
case 'pending':$status = -1;
|
||||
break;
|
||||
case 'junk':$status = -2;
|
||||
break;
|
||||
default:$status = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
$core->blog->updCommentsStatus($co_ids, $status);
|
||||
|
||||
dcPage::addSuccessNotice(__('Selected comments have been successfully updated.'));
|
||||
$ap->redirect(true);
|
||||
}
|
||||
|
||||
public static function doDeleteComment($core, dcCommentsActionsPage $ap, $post)
|
||||
{
|
||||
$co_ids = $ap->getIDs();
|
||||
if (empty($co_ids)) {
|
||||
throw new Exception(__('No comment selected'));
|
||||
}
|
||||
// Backward compatibility
|
||||
foreach ($co_ids as $comment_id) {
|
||||
# --BEHAVIOR-- adminBeforeCommentDelete
|
||||
$core->callBehavior('adminBeforeCommentDelete', $comment_id);
|
||||
}
|
||||
|
||||
# --BEHAVIOR-- adminBeforeCommentsDelete
|
||||
$core->callBehavior('adminBeforeCommentsDelete', $co_ids);
|
||||
|
||||
$core->blog->delComments($co_ids);
|
||||
dcPage::addSuccessNotice(__('Selected comments have been successfully deleted.'));
|
||||
$ap->redirect(false);
|
||||
}
|
||||
|
||||
public static function doBlacklistIP($core, dcCommentsActionsPage $ap, $post)
|
||||
{
|
||||
$action = $ap->getAction();
|
||||
$co_ids = $ap->getIDs();
|
||||
if (empty($co_ids)) {
|
||||
throw new Exception(__('No comment selected'));
|
||||
}
|
||||
|
||||
$global = !empty($action) && $action == 'blacklist_global' && $core->auth->isSuperAdmin();
|
||||
|
||||
$ip_filter = new dcFilterIP($core);
|
||||
$rs = $ap->getRS();
|
||||
while ($rs->fetch()) {
|
||||
$ip_filter->addIP('black', $rs->comment_ip, $global);
|
||||
}
|
||||
|
||||
dcPage::addSuccessNotice(__('IP addresses for selected comments have been blacklisted.'));
|
||||
$ap->redirect(true);
|
||||
}
|
||||
}
|
||||
448
dotclear._no/inc/admin/actions/class.dcactionposts.php
Normal file
448
dotclear._no/inc/admin/actions/class.dcactionposts.php
Normal file
@ -0,0 +1,448 @@
|
||||
<?php
|
||||
/**
|
||||
* @package Dotclear
|
||||
* @subpackage Backend
|
||||
*
|
||||
* @copyright Olivier Meunier & Association Dotclear
|
||||
* @copyright GPL-2.0-only
|
||||
*/
|
||||
|
||||
if (!defined('DC_RC_PATH')) {return;}
|
||||
|
||||
class dcPostsActionsPage extends dcActionsPage
|
||||
{
|
||||
public function __construct($core, $uri, $redirect_args = [])
|
||||
{
|
||||
parent::__construct($core, $uri, $redirect_args);
|
||||
$this->redirect_fields = ['user_id', 'cat_id', 'status',
|
||||
'selected', 'attachment', 'month', 'lang', 'sortby', 'order', 'page', 'nb'];
|
||||
$this->loadDefaults();
|
||||
}
|
||||
|
||||
protected function loadDefaults()
|
||||
{
|
||||
// We could have added a behavior here, but we want default action
|
||||
// to be setup first
|
||||
dcDefaultPostActions::adminPostsActionsPage($this->core, $this);
|
||||
$this->core->callBehavior('adminPostsActionsPage', $this->core, $this);
|
||||
|
||||
}
|
||||
|
||||
public function beginPage($breadcrumb = '', $head = '')
|
||||
{
|
||||
if ($this->in_plugin) {
|
||||
echo '<html><head><title>' . __('Posts') . '</title>' .
|
||||
dcPage::jsLoad('js/_posts_actions.js') .
|
||||
$head .
|
||||
'</script></head><body>' .
|
||||
$breadcrumb;
|
||||
} else {
|
||||
dcPage::open(
|
||||
__('Posts'),
|
||||
dcPage::jsLoad('js/_posts_actions.js') .
|
||||
$head,
|
||||
$breadcrumb
|
||||
);
|
||||
}
|
||||
echo '<p><a class="back" href="' . $this->getRedirection(true) . '">' . __('Back to entries list') . '</a></p>';
|
||||
}
|
||||
|
||||
public function endPage()
|
||||
{
|
||||
if ($this->in_plugin) {
|
||||
echo '</body></html>';
|
||||
} else {
|
||||
dcPage::close();
|
||||
}
|
||||
}
|
||||
|
||||
public function error(Exception $e)
|
||||
{
|
||||
$this->core->error->add($e->getMessage());
|
||||
$this->beginPage(dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($this->core->blog->name) => '',
|
||||
$this->getCallerTitle() => $this->getRedirection(true),
|
||||
__('Posts actions') => ''
|
||||
])
|
||||
);
|
||||
$this->endPage();
|
||||
}
|
||||
|
||||
protected function fetchEntries($from)
|
||||
{
|
||||
$params = [];
|
||||
if (!empty($from['entries'])) {
|
||||
$entries = $from['entries'];
|
||||
|
||||
foreach ($entries as $k => $v) {
|
||||
$entries[$k] = (integer) $v;
|
||||
}
|
||||
|
||||
$params['sql'] = 'AND P.post_id IN(' . implode(',', $entries) . ') ';
|
||||
} else {
|
||||
$params['sql'] = 'AND 1=0 ';
|
||||
}
|
||||
|
||||
if (!isset($from['full_content']) || empty($from['full_content'])) {
|
||||
$params['no_content'] = true;
|
||||
}
|
||||
|
||||
if (isset($from['post_type'])) {
|
||||
$params['post_type'] = $from['post_type'];
|
||||
}
|
||||
|
||||
$posts = $this->core->blog->getPosts($params);
|
||||
while ($posts->fetch()) {
|
||||
$this->entries[$posts->post_id] = $posts->post_title;
|
||||
}
|
||||
$this->rs = $posts;
|
||||
}
|
||||
}
|
||||
|
||||
class dcDefaultPostActions
|
||||
{
|
||||
public static function adminPostsActionsPage($core, $ap)
|
||||
{
|
||||
if ($core->auth->check('publish,contentadmin', $core->blog->id)) {
|
||||
$ap->addAction(
|
||||
[__('Status') => [
|
||||
__('Publish') => 'publish',
|
||||
__('Unpublish') => 'unpublish',
|
||||
__('Schedule') => 'schedule',
|
||||
__('Mark as pending') => 'pending'
|
||||
]],
|
||||
['dcDefaultPostActions', 'doChangePostStatus']
|
||||
);
|
||||
}
|
||||
$ap->addAction(
|
||||
[__('Mark') => [
|
||||
__('Mark as selected') => 'selected',
|
||||
__('Mark as unselected') => 'unselected'
|
||||
]],
|
||||
['dcDefaultPostActions', 'doUpdateSelectedPost']
|
||||
);
|
||||
$ap->addAction(
|
||||
[__('Change') => [
|
||||
__('Change category') => 'category'
|
||||
]],
|
||||
['dcDefaultPostActions', 'doChangePostCategory']
|
||||
);
|
||||
$ap->addAction(
|
||||
[__('Change') => [
|
||||
__('Change language') => 'lang'
|
||||
]],
|
||||
['dcDefaultPostActions', 'doChangePostLang']
|
||||
);
|
||||
if ($core->auth->check('admin', $core->blog->id)) {
|
||||
$ap->addAction(
|
||||
[__('Change') => [
|
||||
__('Change author') => 'author']],
|
||||
['dcDefaultPostActions', 'doChangePostAuthor']
|
||||
);
|
||||
}
|
||||
if ($core->auth->check('delete,contentadmin', $core->blog->id)) {
|
||||
$ap->addAction(
|
||||
[__('Delete') => [
|
||||
__('Delete') => 'delete']],
|
||||
['dcDefaultPostActions', 'doDeletePost']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function doChangePostStatus($core, dcPostsActionsPage $ap, $post)
|
||||
{
|
||||
switch ($ap->getAction()) {
|
||||
case 'unpublish':$status = 0;
|
||||
break;
|
||||
case 'schedule':$status = -1;
|
||||
break;
|
||||
case 'pending':$status = -2;
|
||||
break;
|
||||
default:$status = 1;
|
||||
break;
|
||||
}
|
||||
$posts_ids = $ap->getIDs();
|
||||
if (empty($posts_ids)) {
|
||||
throw new Exception(__('No entry selected'));
|
||||
}
|
||||
$core->blog->updPostsStatus($posts_ids, $status);
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully updated to status : "%s"',
|
||||
'%d entries have been successfully updated to status : "%s"',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids),
|
||||
$core->blog->getPostStatus($status))
|
||||
);
|
||||
$ap->redirect(true);
|
||||
}
|
||||
|
||||
public static function doUpdateSelectedPost($core, dcPostsActionsPage $ap, $post)
|
||||
{
|
||||
$posts_ids = $ap->getIDs();
|
||||
if (empty($posts_ids)) {
|
||||
throw new Exception(__('No entry selected'));
|
||||
}
|
||||
$action = $ap->getAction();
|
||||
$core->blog->updPostsSelected($posts_ids, $action == 'selected');
|
||||
if ($action == 'selected') {
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully marked as selected',
|
||||
'%d entries have been successfully marked as selected',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids))
|
||||
);
|
||||
} else {
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully marked as unselected',
|
||||
'%d entries have been successfully marked as unselected',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids))
|
||||
);
|
||||
}
|
||||
$ap->redirect(true);
|
||||
}
|
||||
|
||||
public static function doDeletePost($core, dcPostsActionsPage $ap, $post)
|
||||
{
|
||||
|
||||
$posts_ids = $ap->getIDs();
|
||||
if (empty($posts_ids)) {
|
||||
throw new Exception(__('No entry selected'));
|
||||
}
|
||||
// Backward compatibility
|
||||
foreach ($posts_ids as $post_id) {
|
||||
# --BEHAVIOR-- adminBeforePostDelete
|
||||
$core->callBehavior('adminBeforePostDelete', (integer) $post_id);
|
||||
}
|
||||
|
||||
# --BEHAVIOR-- adminBeforePostsDelete
|
||||
$core->callBehavior('adminBeforePostsDelete', $posts_ids);
|
||||
|
||||
$core->blog->delPosts($posts_ids);
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully deleted',
|
||||
'%d entries have been successfully deleted',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids))
|
||||
);
|
||||
|
||||
$ap->redirect(false);
|
||||
}
|
||||
|
||||
public static function doChangePostCategory($core, dcPostsActionsPage $ap, $post)
|
||||
{
|
||||
if (isset($post['new_cat_id'])) {
|
||||
$posts_ids = $ap->getIDs();
|
||||
if (empty($posts_ids)) {
|
||||
throw new Exception(__('No entry selected'));
|
||||
}
|
||||
$new_cat_id = $post['new_cat_id'];
|
||||
if (!empty($post['new_cat_title']) && $core->auth->check('categories', $core->blog->id)) {
|
||||
$cur_cat = $core->con->openCursor($core->prefix . 'category');
|
||||
$cur_cat->cat_title = $post['new_cat_title'];
|
||||
$cur_cat->cat_url = '';
|
||||
$title = $cur_cat->cat_title;
|
||||
|
||||
$parent_cat = !empty($post['new_cat_parent']) ? $post['new_cat_parent'] : '';
|
||||
|
||||
# --BEHAVIOR-- adminBeforeCategoryCreate
|
||||
$core->callBehavior('adminBeforeCategoryCreate', $cur_cat);
|
||||
|
||||
$new_cat_id = $core->blog->addCategory($cur_cat, (integer) $parent_cat);
|
||||
|
||||
# --BEHAVIOR-- adminAfterCategoryCreate
|
||||
$core->callBehavior('adminAfterCategoryCreate', $cur_cat, $new_cat_id);
|
||||
}
|
||||
|
||||
$core->blog->updPostsCategory($posts_ids, $new_cat_id);
|
||||
$title = $core->blog->getCategory($new_cat_id);
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully moved to category "%s"',
|
||||
'%d entries have been successfully moved to category "%s"',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids),
|
||||
html::escapeHTML($title->cat_title))
|
||||
);
|
||||
|
||||
$ap->redirect(true);
|
||||
} else {
|
||||
|
||||
$ap->beginPage(
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
||||
__('Change category for this selection') => ''
|
||||
]));
|
||||
# categories list
|
||||
# Getting categories
|
||||
$categories_combo = dcAdminCombos::getCategoriesCombo(
|
||||
$core->blog->getCategories()
|
||||
);
|
||||
echo
|
||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
||||
$ap->getCheckboxes() .
|
||||
'<p><label for="new_cat_id" class="classic">' . __('Category:') . '</label> ' .
|
||||
form::combo(['new_cat_id'], $categories_combo);
|
||||
|
||||
if ($core->auth->check('categories', $core->blog->id)) {
|
||||
echo
|
||||
'<div>' .
|
||||
'<p id="new_cat">' . __('Create a new category for the post(s)') . '</p>' .
|
||||
'<p><label for="new_cat_title">' . __('Title:') . '</label> ' .
|
||||
form::field('new_cat_title', 30, 255) . '</p>' .
|
||||
'<p><label for="new_cat_parent">' . __('Parent:') . '</label> ' .
|
||||
form::combo('new_cat_parent', $categories_combo) .
|
||||
'</p>' .
|
||||
'</div>';
|
||||
}
|
||||
|
||||
echo
|
||||
$core->formNonce() .
|
||||
$ap->getHiddenFields() .
|
||||
form::hidden(['action'], 'category') .
|
||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
||||
'</form>';
|
||||
$ap->endPage();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
public static function doChangePostAuthor($core, dcPostsActionsPage $ap, $post)
|
||||
{
|
||||
if (isset($post['new_auth_id']) && $core->auth->check('admin', $core->blog->id)) {
|
||||
$new_user_id = $post['new_auth_id'];
|
||||
$posts_ids = $ap->getIDs();
|
||||
if (empty($posts_ids)) {
|
||||
throw new Exception(__('No entry selected'));
|
||||
}
|
||||
if ($core->getUser($new_user_id)->isEmpty()) {
|
||||
throw new Exception(__('This user does not exist'));
|
||||
}
|
||||
|
||||
$cur = $core->con->openCursor($core->prefix . 'post');
|
||||
$cur->user_id = $new_user_id;
|
||||
$cur->update('WHERE post_id ' . $core->con->in($posts_ids));
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully set to user "%s"',
|
||||
'%d entries have been successfully set to user "%s"',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids),
|
||||
html::escapeHTML($new_user_id))
|
||||
);
|
||||
|
||||
$ap->redirect(true);
|
||||
} else {
|
||||
$usersList = [];
|
||||
if ($core->auth->check('admin', $core->blog->id)) {
|
||||
$params = [
|
||||
'limit' => 100,
|
||||
'order' => 'nb_post DESC'
|
||||
];
|
||||
$rs = $core->getUsers($params);
|
||||
$rsStatic = $rs->toStatic();
|
||||
$rsStatic->extend('rsExtUser');
|
||||
$rsStatic = $rsStatic->toExtStatic();
|
||||
$rsStatic->lexicalSort('user_id');
|
||||
while ($rsStatic->fetch()) {
|
||||
$usersList[] = $rsStatic->user_id;
|
||||
}
|
||||
}
|
||||
$ap->beginPage(
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
||||
__('Change author for this selection') => '']),
|
||||
dcPage::jsLoad('js/jquery/jquery.autocomplete.js') .
|
||||
dcPage::jsJson('users_list', $usersList)
|
||||
);
|
||||
|
||||
echo
|
||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
||||
$ap->getCheckboxes() .
|
||||
'<p><label for="new_auth_id" class="classic">' . __('New author (author ID):') . '</label> ' .
|
||||
form::field('new_auth_id', 20, 255);
|
||||
|
||||
echo
|
||||
$core->formNonce() . $ap->getHiddenFields() .
|
||||
form::hidden(['action'], 'author') .
|
||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
||||
'</form>';
|
||||
$ap->endPage();
|
||||
}
|
||||
}
|
||||
public static function doChangePostLang($core, dcPostsActionsPage $ap, $post)
|
||||
{
|
||||
$posts_ids = $ap->getIDs();
|
||||
if (empty($posts_ids)) {
|
||||
throw new Exception(__('No entry selected'));
|
||||
}
|
||||
if (isset($post['new_lang'])) {
|
||||
$new_lang = $post['new_lang'];
|
||||
$cur = $core->con->openCursor($core->prefix . 'post');
|
||||
$cur->post_lang = $new_lang;
|
||||
$cur->update('WHERE post_id ' . $core->con->in($posts_ids));
|
||||
dcPage::addSuccessNotice(sprintf(
|
||||
__(
|
||||
'%d entry has been successfully set to language "%s"',
|
||||
'%d entries have been successfully set to language "%s"',
|
||||
count($posts_ids)
|
||||
),
|
||||
count($posts_ids),
|
||||
html::escapeHTML(l10n::getLanguageName($new_lang)))
|
||||
);
|
||||
$ap->redirect(true);
|
||||
} else {
|
||||
$ap->beginPage(
|
||||
dcPage::breadcrumb(
|
||||
[
|
||||
html::escapeHTML($core->blog->name) => '',
|
||||
$ap->getCallerTitle() => $ap->getRedirection(true),
|
||||
__('Change language for this selection') => ''
|
||||
]));
|
||||
# lang list
|
||||
# Languages combo
|
||||
$rs = $core->blog->getLangs(['order' => 'asc']);
|
||||
$all_langs = l10n::getISOcodes(0, 1);
|
||||
$lang_combo = ['' => '', __('Most used') => [], __('Available') => l10n::getISOcodes(1, 1)];
|
||||
while ($rs->fetch()) {
|
||||
if (isset($all_langs[$rs->post_lang])) {
|
||||
$lang_combo[__('Most used')][$all_langs[$rs->post_lang]] = $rs->post_lang;
|
||||
unset($lang_combo[__('Available')][$all_langs[$rs->post_lang]]);
|
||||
} else {
|
||||
$lang_combo[__('Most used')][$rs->post_lang] = $rs->post_lang;
|
||||
}
|
||||
}
|
||||
unset($all_langs);
|
||||
unset($rs);
|
||||
|
||||
echo
|
||||
'<form action="' . $ap->getURI() . '" method="post">' .
|
||||
$ap->getCheckboxes() .
|
||||
|
||||
'<p><label for="new_lang" class="classic">' . __('Entry language:') . '</label> ' .
|
||||
form::combo('new_lang', $lang_combo);
|
||||
|
||||
echo
|
||||
$core->formNonce() . $ap->getHiddenFields() .
|
||||
form::hidden(['action'], 'lang') .
|
||||
'<input type="submit" value="' . __('Save') . '" /></p>' .
|
||||
'</form>';
|
||||
$ap->endPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user