admin/main.php
<?php declare(strict_types=1);
/*
XOOPS - PHP Content Management System
Copyright (c) 2000-2020 XOOPS.org
<https://xoops.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
You may not change or alter any portion of this comment or credits
of supporting developers from this source code or any supporting
source code which is considered copyrighted (c) material of the
original comment or credit authors.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* XOOPS Poll Administration
* Routines to manage administration of CRUD and display of polls
*
* @copyright :: {@link https://xoops.org/ XOOPS Project}
* @license :: {@link https://www.gnu.org/licenses/gpl-2.0.html GNU GPL 2.0 or later}
* @subpackage:: admin
* @author :: Xoops Module Team
* @since :: 1.0
*
* @uses xoops_load() to instantiate needed classes
* @uses XoopsFormloader
* @uses Xoopslists
* @uses CriteriaCompo
* @uses Criteria
* @uses xoops_getModuleHandler() to load this modules class handlers
* @uses ModuleAdmin class to display module administration page navigation
* @uses $GLOBALS['xoopsSecurity']::getTokenHTML() used for security on input of form data
* @uses $GLOBALS['xoops'] class::methods used to get general information about XOOPS
* @uses XoopsPageNav class to display page navigation links for multiple pages of data
* @uses xoops_template_clear_module_cache() function used to clear cache after data has been updated
* @uses redirect_header() function to send user to page after completing task(s)
*/
use Xmf\Module\Admin;
use Xmf\Request;
use XoopsModules\Newbb;
use XoopsModules\Xoopspoll\{
Common\Configurator,
Constants,
FormDateTimePicker,
Helper,
Poll,
Utility
};
require_once __DIR__ . '/admin_header.php';
require_once $GLOBALS['xoops']->path('class/xoopsblock.php');
xoops_load('xoopsformloader');
xoops_load('xoopslists');
$helper = Helper::getInstance();
$configurator = new Configurator();
$icons = $configurator->icons;
$op = Request::getString('op', Request::getCmd('op', 'list', 'POST'), 'GET');
switch ($op) {
case 'list':
default:
$limit = Request::getInt('limit', Constants::DEFAULT_POLL_PAGE_LIMIT);
$start = Request::getInt('start', 0);
/** @var \XoopsPersistableObjectHandler $pollHandler */
$pollHandler = $helper->getHandler('Poll');
$criteria = new \CriteriaCompo();
$criteria->setLimit($limit + 1);
$criteria->setStart($start);
$criteria->setSort('weight ASC, start_time'); // trick criteria to allow 2 sort criteria
$criteria->setOrder('ASC');
$pollObjs = $pollHandler->getAll($criteria);
$pollsCount = count($pollObjs);
xoops_cp_header();
$adminObject = Admin::getInstance();
$xoopsTpl->assign('navigation', $adminObject->displayNavigation(basename(__FILE__)));
$adminObject->addItemButton(_AM_XOOPSPOLL_CREATENEWPOLL, 'main.php' . '?op=add', $icon = 'add');
$xoopsTpl->assign('addPollButton', $adminObject->displayButton('left'));
$renderedNav = '';
if (is_array($pollObjs) && $pollsCount > 0) {
/* if newbb forum module is loaded find poll/topic association */
/** @var \XoopsModuleHandler $moduleHandler */
$moduleHandler = xoops_getHandler('module');
$newbbModule = $moduleHandler->getByDirname('newbb');
if (($newbbModule instanceof \XoopsModule) && $newbbModule->isactive()) {
/** @var Newbb\TopicHandler $topicHandler */
$topicHandler = Newbb\Helper::getInstance()->getHandler('Topic');
$topicFields = ['topic_id', 'topic_title', 'poll_id'];
$criteria = new \CriteriaCompo();
$criteria->add(new \Criteria('topic_haspoll', 0, '>'));
$pollsWithTopics = [];
$topicsWithPolls = $topicHandler->getAll($criteria, $topicFields, false);
foreach ($topicsWithPolls as $pollTopics) {
$pollsWithTopics[$pollTopics['poll_id']] = [
'topic_id' => $pollTopics['topic_id'],
'topic_title' => $pollTopics['topic_title'],
];
}
if (!empty($pollsWithTopics)) {
$adminObject->addInfoBox(_AM_XOOPSPOLL_NEWBB_SUPPORT);
$adminObject->addInfoBoxLine(sprintf("<img src='" . $pathIcon16 . "/forum.png' alt='" . _AM_XOOPSPOLL_NEWBB_SUPPORT . "'> " . _AM_XOOPSPOLL_NEWBB_INTRO, null, null, 'information'), '');
$newbbIntro = $adminObject->renderInfoBox();
} else {
$newbbIntro = '';
}
} else {
$pollsWithTopics = [];
$newbbIntro = '';
}
$xoopsTpl->assign('newbbIntro', $newbbIntro);
// $xoopsTpl->assign('securityToken', $GLOBALS['xoopsSecurity']->getTokenHTML()); //mb
$pollItems = [];
foreach ($pollObjs as $pollObj) {
$pollVars = $pollObj->getValues();
$id = $pollVars['poll_id'];
if (array_key_exists($id, $pollsWithTopics)) {
$topic_id = $pollsWithTopics[$id]['topic_id'];
$topic_title = $pollsWithTopics[$id]['topic_title'];
} else {
$topic_id = 0;
$topic_title = '';
}
$checked = (Constants::DISPLAY_POLL_IN_BLOCK === $pollVars['display']) ? ' checked' : '';
$xuCurrentTimestamp = xoops_getUserTimestamp(time());
$xuCurrentFormatted = ucfirst(date(_MEDIUMDATESTRING, (int)$xuCurrentTimestamp));
$xuStartTimestamp = xoops_getUserTimestamp($pollVars['start_time']);
$xuStartFormattedTime = ucfirst(date(_MEDIUMDATESTRING, (int)$xuStartTimestamp));
$xuEndTimestamp = xoops_getUserTimestamp($pollVars['end_time']);
if ($xuEndTimestamp > $xuCurrentTimestamp) {
$end = ucfirst(date(_MEDIUMDATESTRING, (int)$xuEndTimestamp)); // formatted output for current user
} else {
$end = "<span class='red'>" . _AM_XOOPSPOLL_EXPIRED . '</span><br>' . "<a href='" . $_SERVER['SCRIPT_NAME'] . "?op=restart&poll_id={$id}'>" . _AM_XOOPSPOLL_RESTART . '</a>';
}
$pollItems[$id] = [
'question' => $pollVars['question'],
'id' => $id,
'weight' => $pollVars['weight'],
'topic_id' => $topic_id,
'topic_title' => $topic_title,
'checked' => $checked,
'voters' => $pollVars['voters'],
'votes' => $pollVars['votes'],
'xuStartFormattedTime' => $xuStartFormattedTime,
'end' => $end,
'buttons' => [
'edit' => [
'href' => $_SERVER['SCRIPT_NAME'] . "?op=edit&poll_id={$id}",
'file' => $pathIcon16 . '/edit.png',
'alt' => _AM_XOOPSPOLL_EDITPOLL,
],
'clone' => [
'href' => $_SERVER['SCRIPT_NAME'] . "?op=clone&poll_id={$id}",
'file' => $pathIcon16 . '/editcopy.png',
'alt' => _AM_XOOPSPOLL_CLONE,
],
'delete' => [
'href' => $_SERVER['SCRIPT_NAME'] . "?op=delete&poll_id={$id}",
'file' => $pathIcon16 . '/delete.png',
'alt' => _DELETE,
],
'log' => [
'href' => $_SERVER['SCRIPT_NAME'] . "?op=log&poll_id={$id}",
'file' => $pathIcon16 . '/search.png',
'alt' => _AM_XOOPSPOLL_VIEWLOG,
],
],
];
if ($topic_id > 0) {
$pollItems[$id]['buttons']['forum'] = [
'href' => $GLOBALS['xoops']->url('modules/newbb/viewtopic.php') . "?topic_id={$topic_id}",
'file' => $pathIcon16 . '/forum.png',
'alt' => _AM_XOOPSPOLL_NEWBB_TOPIC . ' ' . htmlspecialchars($topic_title, ENT_QUOTES | ENT_HTML5),
];
}
}
xoops_load('pagenav');
$pageNav = new \XoopsPageNav($pollsCount, $limit, $start);
$renderedNav = $pageNav->renderNav();
}
$xoopsTpl->assign('pollItems', $pollItems);
$xoopsTpl->assign('rendered_nav', $renderedNav);
$xoopsTpl->assign('self', $_SERVER['SCRIPT_NAME']);
$xoopsTpl->display($helper->path('templates/admin/xoopspoll_list.tpl'));
require_once __DIR__ . '/admin_footer.php';
exit();
case 'edit':
case 'add':
$optionHandler = $helper->getHandler('Option');
$pollHandler = $helper->getHandler('Poll');
$pollId = Request::getInt('poll_id', 0);
$pollObj = $pollHandler->get($pollId); // will auto create object if poll_id=0
// display the form
xoops_cp_header();
$adminObject = Admin::getInstance();
$adminObject->displayNavigation(basename(__FILE__));
$pollObj->renderForm($_SERVER['SCRIPT_NAME'], 'post');
require_once __DIR__ . '/admin_footer.php';
exit();
case 'update':
if (!$GLOBALS['xoopsSecurity']->check()) {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_MEDIUM, implode('<br>', $GLOBALS['xoopsSecurity']->getErrors()));
}
$optionHandler = $helper->getHandler('Option');
$logHandler = $helper->getHandler('Log');
$pollHandler = $helper->getHandler('Poll');
$pollId = Request::getInt('poll_id', 0, 'POST');
$pollObj = $pollHandler->get($pollId);
$notify = Request::getInt('notify', Constants::NOTIFICATION_ENABLED, 'POST');
$currentTimestamp = time();
$xuEndTimestamp = strtotime(Request::getString('xu_end_time', null, 'POST'));
$endTimestamp = empty($xuEndTimestamp) ? ($currentTimestamp + Constants::DEFAULT_POLL_DURATION) : userTimeToServerTime($xuEndTimestamp);
$xuStartTimestamp = strtotime(Request::getString('xu_start_time', null, 'POST'));
$startTimestamp = empty($xuStartTimestamp) ? ($endTimestamp - Constants::DEFAULT_POLL_DURATION) : userTimeToServerTime($xuStartTimestamp);
// don't allow changing start time if there are votes in the log
if (($startTimestamp < $pollObj->getVar('start_time')) && ($logHandler->getTotalVotesByPollId($pollId) > 0)) {
$startTimestamp = $pollObj->getVar('start_time'); //don't change start time
}
$pollVars = [
'user_id' => Request::getInt('user_id', $GLOBALS['xoopsUser']->uid(), 'POST'),
'question' => Request::getString('question', null, 'POST'),
'description' => Request::getText('description', null, 'POST'),
'mail_status' => (Constants::NOTIFICATION_ENABLED === $notify) ? Constants::POLL_NOT_MAILED : Constants::POLL_MAILED,
'mail_voter' => Request::getInt('mail_voter', Constants::NOT_MAIL_POLL_TO_VOTER, 'POST'),
'start_time' => $startTimestamp,
'end_time' => $endTimestamp,
'display' => Request::getInt('display', Constants::DO_NOT_DISPLAY_POLL_IN_BLOCK, 'POST'),
'visibility' => Request::getInt('visibility', Constants::HIDE_NEVER, 'POST'),
'weight' => Request::getInt('weight', Constants::DEFAULT_WEIGHT, 'POST'),
'multiple' => Request::getInt('multiple', Constants::NOT_MULTIPLE_SELECT_POLL, 'POST'),
'multilimit' => Request::getInt('multilimit', Constants::MULTIPLE_SELECT_LIMITLESS, 'POST'),
'anonymous' => Request::getInt('anonymous', Constants::ANONYMOUS_VOTING_DISALLOWED, 'POST'),
];
$pollObj->setVars($pollVars);
$pollId = $pollHandler->insert($pollObj);
if (!$pollId) {
$err = $pollObj->getHtmlErrors();
exit($err);
}
// now get the options
$optionIdArray = Request::getArray('option_id', [], 'POST');
$optionIdArray = array_map('\intval', $optionIdArray);
$optionTextArray = Request::getArray('option_text', [], 'POST');
$optionColorArray = Request::getArray('option_color', [], 'POST');
foreach ($optionIdArray as $key => $oId) {
if (!empty($oId) && ($optionObj = $optionHandler->get($oId))) {
// existing option object so need to update it
$optionTextArray[$key] = trim($optionTextArray[$key]);
if ('' === $optionTextArray[$key]) {
// want to delete this option
if (false !== $optionHandler->delete($optionObj)) {
// now remove it from the log
$logHandler->deleteByOptionId($optionObj->getVar('option_id'));
}
} else {
$optionObj->setVar('option_text', $optionTextArray[$key]);
$optionObj->setVar('option_color', $optionColorArray[$key]);
$optionObj->setVar('poll_id', $pollId);
$optionHandler->insert($optionObj);
}
} else {
// new option object
$optionObj = $optionHandler->create();
$optionTextArray[$key] = trim($optionTextArray[$key]);
if ('' !== $optionTextArray[$key]) { // ignore if text is empty
$optionObj->setVar('option_text', $optionTextArray[$key]);
$optionObj->setVar('option_color', $optionColorArray[$key]);
$optionObj->setVar('poll_id', $pollId);
$optionHandler->insert($optionObj);
}
unset($optionObj);
}
}
unset($optionHandler, $logHandler, $pollObj, $pollHandler, $pollId);
// clear the template cache so changes take effect immediately
require_once $GLOBALS['xoops']->path('class/template.php');
xoops_template_clear_module_cache($GLOBALS['xoopsModule']->getVar('mid'));
redirect_header($_SERVER['SCRIPT_NAME'] . '?op=list', Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_DBUPDATED);
break;
case 'delete':
$pollId = Request::getInt('poll_id', 0);
$pollHandler = $helper->getHandler('Poll');
$pollObj = $pollHandler->get($pollId);
if (!($pollObj instanceof Poll)) {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, implode('<br>', $pollHandler->getErrors()));
}
xoops_cp_header();
$adminObject = Admin::getInstance();
$adminObject->displayNavigation(basename(__FILE__));
xoops_confirm(
[
'op' => 'delete_ok',
'poll_id' => $pollId,
],
$_SERVER['SCRIPT_NAME'],
sprintf(_AM_XOOPSPOLL_RUSUREDEL, htmlspecialchars($pollObj->getVar('question'), ENT_QUOTES | ENT_HTML5))
);
require_once __DIR__ . '/admin_footer.php';
// xoops_cp_footer();
exit();
case 'delete_ok':
if (!$GLOBALS['xoopsSecurity']->check()) {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_MEDIUM, implode('<br>', $GLOBALS['xoopsSecurity']->getErrors()));
}
$pollHandler = $helper->getHandler('Poll');
$pollId = Request::getInt('poll_id', 0, 'POST');
if ($pollHandler->deleteAll(new \Criteria('poll_id', $pollId, '='))) {
$optionHandler = $helper->getHandler('Option');
$optionHandler->deleteAll(new \Criteria('poll_id', $pollId));
$logHandler = $helper->getHandler('Log');
$logHandler->deleteByPollId($pollId);
unset($pollHandler, $optionHandler, $logHandler);
// clear the template cache
require_once $GLOBALS['xoops']->path('class/template.php');
xoops_template_clear_module_cache($GLOBALS['xoopsModule']->getVar('mid'));
// delete comments for this poll
xoops_comment_delete($GLOBALS['xoopsModule']->getVar('mid'), $pollId);
//now clear association with newbb topic if one exists
/** @var \XoopsModuleHandler $moduleHandler */
$moduleHandler = xoops_getHandler('module');
$newbbModule = $moduleHandler->getByDirname('newbb');
if (($newbbModule instanceof XoopsModule) && $newbbModule->isactive()) {
/** @var Newbb\TopicHandler $topicHandler */
$topicHandler = \XoopsModules\Newbb\Helper::getInstance()->getHandler('Topic');
$criteria = new CriteriaCompo();
$criteria->add(new Criteria('poll_id', $pollId, '='));
/* {@internal the order of the next 2 statements is important! */
$topicHandler->updateAll('topic_haspoll', 0, $criteria); // clear poll association
$topicHandler->updateAll('poll_id', 0, $criteria); // clear poll_id
xoops_template_clear_module_cache($newbbModule->getVar('mid')); // clear newbb template cache
}
}
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_DBUPDATED);
break;
case 'restart':
$pollId = Request::getInt('poll_id', 0);
$pollHandler = $helper->getHandler('Poll');
$pollObj = $pollHandler->get($pollId);
$pollForm = new \XoopsThemeForm(_AM_XOOPSPOLL_RESTARTPOLL, 'poll_form', $_SERVER['SCRIPT_NAME'], 'post', true);
// setup times for forms
$xuCurrentTimestamp = xoops_getUserTimestamp(time());
$xuCurrentFormatted = ucfirst(date(_MEDIUMDATESTRING, (int)$xuCurrentTimestamp));
$xuStartTimestamp = $xuCurrentTimestamp;
$xuEndTimestamp = $xuStartTimestamp + Constants::DEFAULT_POLL_DURATION;
$timeTray = new \XoopsFormElementTray(_AM_XOOPSPOLL_POLL_TIMES, ' ', 'time_tray');
//add start time to the form
$startTimeText = new FormDateTimePicker("<div class='bold'>" . _AM_XOOPSPOLL_START_TIME . '<br>' . "<span class='x-small'>" . _AM_XOOPSPOLL_FORMAT . '<br>' . sprintf(_AM_XOOPSPOLL_CURRENTTIME, $xuCurrentFormatted) . '</span></div>', 'xu_start_time', 20, $xuStartTimestamp);
$timeTray->addElement($startTimeText, true);
// add ending date to form
$endTimeText = new FormDateTimePicker("<div class='bold middle'>" . _AM_XOOPSPOLL_EXPIRATION . '</div>', 'xu_end_time', 20, $xuEndTimestamp);
$timeTray->addElement($endTimeText, true);
$pollForm->addElement($timeTray);
$pollForm->addElement(new \XoopsFormRadioYN(_AM_XOOPSPOLL_NOTIFY, 'notify', Constants::POLL_MAILED));
$pollForm->addElement(new \XoopsFormRadioYN(_AM_XOOPSPOLL_RESET, 'reset', 0));
$pollForm->addElement(new \XoopsFormHidden('op', 'restart_ok'));
$pollForm->addElement(new \XoopsFormHidden('poll_id', $pollId));
$pollForm->addElement(new \XoopsFormButton('', 'poll_submit', _AM_XOOPSPOLL_RESTART, 'submit'));
xoops_cp_header();
$adminObject = Admin::getInstance();
$adminObject->displayNavigation(basename(__FILE__));
$pollForm->display();
require_once __DIR__ . '/admin_footer.php';
exit();
case 'restart_ok':
if (!$GLOBALS['xoopsSecurity']->check()) {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_MEDIUM, implode('<br>', $GLOBALS['xoopsSecurity']->getErrors()));
}
$pollId = Request::getInt('poll_id', 0, 'POST');
if (empty($pollId)) {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_ERROR_INVALID_POLLID);
}
$pollHandler = $helper->getHandler('Poll');
$pollObj = $pollHandler->get($pollId);
$xuEndTimestamp = strtotime(Request::getString('xu_end_time', null, 'POST'));
$xuStartTimestamp = strtotime(Request::getString('xu_start_time', null, 'POST'));
$endTimestamp = empty($xuEndTimestamp) ? (time() + Constants::DEFAULT_POLL_DURATION) : userTimeToServerTime($xuEndTimestamp);
$startTimestamp = empty($xuStartTimestamp) ? ($xuEndTimestamp - Constants::DEFAULT_POLL_DURATION) : userTimeToServerTime($xuStartTimestamp);
$pollObj->setVar('end_time', $endTimestamp);
$pollObj->setVar('start_time', $startTimestamp);
$notify = Request::getInt('notify', Constants::NOTIFICATION_DISABLED, 'POST');
if (Constants::NOTIFICATION_ENABLED === $notify) {
// if notify, set mail status to "not mailed"
$pollObj->setVar('mail_status', Constants::POLL_NOT_MAILED);
} else {
// if not notify, set mail status to already "mailed"
$pollObj->setVar('mail_status', Constants::POLL_MAILED);
}
// save the poll settings
$pollHandler->insert($pollObj);
$reset = Request::getInt('reset', Constants::DO_NOT_RESET_RESULTS, 'POST');
if (Constants::RESET_RESULTS === $reset) {
// reset all logs
$logHandler = $helper->getHandler('Log');
$logHandler->deleteByPollId($pollId);
unset($logHandler);
$optionHandler = $helper->getHandler('Option');
$criteria = new \Criteria('poll_id', $pollId, '=');
$optionHandler->updateAll('option_count', 0, $criteria);
}
if (!$pollHandler->updateCount($pollObj)) {
echo $pollObj->getHtmlErrors();
exit();
}
require_once $GLOBALS['xoops']->path('class/template.php');
xoops_template_clear_module_cache($GLOBALS['xoopsModule']->getVar('mid'));
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_DBUPDATED);
break;
case 'log':
$pollId = Request::getInt('poll_id', 0);
$limit = Request::getInt('limit', Constants::DEFAULT_POLL_PAGE_LIMIT);
$start = Request::getInt('start', 0);
$orderby = Request::getString('orderby', 'time');
$orderdir = Request::getString('orderdir', 'ASC');
if (empty($pollId)) {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_ERROR_INVALID_POLLID);
}
$pollHandler = $helper->getHandler('Poll');
$pollObj = $pollHandler->get($pollId);
$expiredClass = ($pollObj->getVar('end_time') < time()) ? ' red' : '';
xoops_cp_header();
$adminObject = Admin::getInstance();
$adminObject->displayNavigation(basename(__FILE__));
$xuEndTimestamp = userTimeToServerTime($pollObj->getVar('end_time'));
$xuEndFormattedTime = ucfirst(date(_MEDIUMDATESTRING, (int)$xuEndTimestamp));
/**
* @todo need to move this html to a template and pass variables via xoopsTpl
* {@internal show a brief description of the question we are focusing on}
*/
echo "<h4 class='left'>"
. _AM_XOOPSPOLL_LOGSLIST
. "</h4>\n"
. "<table class='outer bnone width100' style='padding: 0; margin: 0;'>\n"
. " <tr>\n"
. " <td>\n"
. " <table class='width100 bnone marg2 pad3'>\n"
. " <thead>\n"
. " <tr class='bg3'>\n"
. " <th class='center' nowrap>"
. _AM_XOOPSPOLL_POLLQUESTION
. "</th>\n"
. " <th class='center' nowrap>"
. _AM_XOOPSPOLL_POLLDESC
. "</th>\n"
. ' <th nowrap>'
. _AM_XOOPSPOLL_VOTERS
. "</th>\n"
. ' <th nowrap>'
. _AM_XOOPSPOLL_VOTES
. "</th>\n"
. ' <th nowrap>'
. _AM_XOOPSPOLL_EXPIRATION
. "</th>\n"
. " </tr>\n"
. " </thead>\n"
. " <tfoot></tfoot>\n"
. " <tbody>\n"
. " <tr class='bg1'>\n"
. " <td class='center'>"
. $pollObj->getVar('question')
. "</td>\n"
. " <td class='center'>"
. $pollObj->getVar('description')
. "</td>\n"
. " <td class='center'>"
. $pollObj->getVar('voters')
. "</td>\n"
. " <td class='center'>"
. $pollObj->getVar('votes')
. "</td>\n"
. " <td class='center{$expiredClass}'>{$xuEndFormattedTime}</td>\n"
. " </tr>\n"
. " </tbody>\n"
. " </table>\n"
. " </td>\n"
. " </tr>\n"
. "</table>\n";
echo "<br>\n";
if ($pollObj->getVar('votes')) { // there are votes to show
// show summary of results
$optionHandler = $helper->getHandler('Option');
$criteria = new \CriteriaCompo();
$criteria->add(new \Criteria('poll_id', $pollId, '='));
$criteria->setGroupBy('option_id');
$options = $optionHandler->getAll($criteria, null, false);
echo "<div class='center' style='margin-bottom: 2em;'>\n"
. "<h4 class='left'>"
. _AM_XOOPSPOLL_LOGSLIST
. "</h4>\n"
. "<table class='outer bnone width100' style='padding: 0; margin: 0;'>\n"
. "<thead>\n"
. " <tr>\n"
. " <th class='width15'>"
. _AM_XOOPSPOLL_OPTION
. "</th>\n"
. ' <th>'
. _AM_XOOPSPOLL_LABEL
. "</th>\n"
. " <th class='width15'>"
. _AM_XOOPSPOLL_COUNT
. "</th>\n"
. " </tr>\n"
. "</thead>\n"
. "<tfoot></tfoot>\n"
. '<tbody>';
$rowClass = 'even';
$i = 0;
foreach ($options as $thisOption) {
echo " <tr class='{$rowClass}'><td class='center'>" . ++$i . "</td><td class='center'>{$thisOption['option_text']}</td><td class='center'>{$thisOption['option_count']}</td></tr>\n";
$rowClass = ('odd' === $rowClass) ? 'even' : 'odd';
}
echo "</tbody>\n" . "</table>\n" . '</div>';
// show logs
echo "<h4 class='left'>" . _AM_XOOPSPOLL_POLLVOTERS . "</h4>\n";
$logHandler = $helper->getHandler('Log');
$criteria = new \CriteriaCompo();
$criteria->add(new \Criteria('poll_id', $pollId, '='));
$logsCount = $logHandler->getCount($criteria);
$criteria->setSort($orderby);
$criteria->setOrder($orderdir);
$criteria->setStart($start);
$criteria->setLimit($limit);
$logsArray = $logHandler->getAll($criteria);
$arrowUp = $pathIcon16 . '/up.gif';
$arrowDown = $pathIcon16 . '/down.gif';
$sorthref = $_SERVER['SCRIPT_NAME'] . "?op=log&poll_id={$pollId}&orderby=";
$class = 'even';
if (is_array($logsArray) && $logsCount > 0) {
echo "<table class='outer bnone width100' style='padding: 0; margin: 0;'>\n" . " <tr>\n" . " <td class='bg2'>\n" . " <table class='width100 bnone pad3 marg2'>\n" . " <thead>\n" . " <tr class='bg3'>\n";
$ipLabel = (Constants::LOOK_UP_HOST === $GLOBALS['xoopsModuleConfig']['look_up_host']) ? _AM_XOOPSPOLL_HOST_NAME : _AM_XOOPSPOLL_IP;
$fieldArray = [
['order' => 'log_id', 'label' => _AM_XOOPSPOLL_LOGID],
['order' => 'option_id', 'label' => _AM_XOOPSPOLL_OPTIONID],
['order' => 'ip', 'label' => $ipLabel],
['order' => 'user_id', 'label' => _AM_XOOPSPOLL_VOTER],
['order' => 'time', 'label' => _AM_XOOPSPOLL_VOTETIME],
];
foreach ($fieldArray as $field) {
echo " <th nowrap>\n"
. " <a href='{$sorthref}{$field['order']}&orderdir=ASC'><img src='{$arrowUp}' alt=''></a>\n"
. " <a href='{$sorthref}{$field['order']}&orderdir=DESC'><img src='{$arrowDown}' alt=''></a>\n"
. " {$field['label']}\n"
. " </th>\n";
}
echo ' </tr>' . " </thead>\n" . " <tbody>\n";
$optionHandler = $helper->getHandler('Option');
$luhConfig = Constants::LOOK_UP_HOST === $GLOBALS['xoopsModuleConfig']['look_up_host'];
foreach ($logsArray as $thisLog) {
$logVals = $thisLog->getValues();
$option = $optionHandler->get($logVals['option_id']);
$remoteIp = $luhConfig ? Utility::getHostByAddrWithCache($logVals['ip']) : $logVals['ip'];
echo " <tr class='bg1'>\n" . " <td class='{$class} center'>{$logVals['log_id']}</td>\n" . " <td class='{$class}'>" . $option->getVar('option_text') . "</td>\n" . " <td class='{$class} center'>{$remoteIp}</td>\n";
if (0 !== $logVals['user_id']) {
$user = new \XoopsUser($logVals['user_id']);
$uname = $user->getVar('uname');
$from_userid = $GLOBALS['xoopsUser']->getVar('uid');
$to_userid = $user->getVar('uid');
$pmLink = $GLOBALS['xoops']->buildUrl(
$GLOBALS['xoops']->path('pmlite.php', true),
[
'send' => 1,
'from_userid' => $from_userid,
'to_userid' => $to_userid,
]
);
echo " <td class='{$class} center'>\n"
. ' <a href='
. $GLOBALS['xoops']->url('/userinfo.php')
. '?uid='
. $user->getVar('uid')
. ">{$uname}</a> \n"
. " <a href='{$pmLink}' target='_blank'><img src='"
. $pathIcon16
. "/mail_generic.png' alt='"
. _AM_XOOPSPOLL_PM_VOTER
. "' title='"
. _AM_XOOPSPOLL_PM_VOTER
. "'>\n"
. " </td>\n";
} else {
echo " <td class='{$class} center'>{$GLOBALS['xoopsConfig']['anonymous']}</td>\n";
}
$xuLogTimestamp = userTimeToServerTime($logVals['time']);
$xuLogFormattedTime = ucfirst(date(_DATESTRING, (int)$xuLogTimestamp));
echo " <td class='{$class} center'>{$xuLogFormattedTime}</td>\n" . " </tr>\n";
$class = ('odd' === $class) ? 'even' : 'odd';
}
echo " </tbody>\n" . " </table>\n" . " </td>\n" . " </tr>\n" . "</table>\n";
xoops_load('pagenav');
$pageNav = new \XoopsPageNav($logsCount, $limit, $start, 'start', "op=log&poll_id={$pollId}");
echo "<div class='right' style='margin: 2em auto;'>" . $pageNav->renderNav() . '</div>';
}
}
// echo "<div class='center' style='margin-bottom: 1em;'>[ <a href='" . $_SERVER['SCRIPT_NAME'] . "?op=list'>" . _AM_XOOPSPOLL_RETURNLIST . "</a> ]</div>\n";
// echo "<div class='center' style='margin-bottom: 1em;'>[ <a href='" . $_SERVER['SCRIPT_NAME'] . "?op=list'><img src='". $pathIcon16 ."/back.png' alt='" . _AM_XOOPSPOLL_RETURNLIST . "' title='" . _AM_XOOPSPOLL_RETURNLIST . "'>" . _AM_XOOPSPOLL_RETURNLIST . "</a> ]</div>\n";
$adminObject->addItemButton(_AM_XOOPSPOLL_RETURNLIST, 'main.php' . '?op=list', $icon = '../16/back');
$adminObject->displayButton('center');
require_once __DIR__ . '/admin_footer.php';
break;
case 'quickupdate':
$pollId = Request::getArray('poll_id', [], 'POST');
$pollId = array_map('\intval', $pollId);
$count = count($pollId);
if ($count) {
$pollHandler = $helper->getHandler('Poll');
$criteria = new \CriteriaCompo();
$idString = '(' . implode(',', $pollId) . ')';
$criteria->add(new \Criteria('poll_id', $idString, 'IN'));
$pollObjs = $pollHandler->getAll($criteria);
// get display variables from form POST
$display = Request::getArray('display', [], 'POST');
$display = array_map('\intval', $display);
$weight = Request::getArray('weight', [], 'POST');
$weight = array_map('\intval', $weight);
foreach ($pollObjs as $pollObj) {
$thisId = $pollObj->getVar('poll_id');
$display[$thisId] = empty($display[$thisId]) ? Constants::DO_NOT_DISPLAY_POLL_IN_BLOCK : Constants::DISPLAY_POLL_IN_BLOCK;
$weight[$thisId] = empty($weight[$thisId]) ? Constants::DEFAULT_WEIGHT : $weight[$thisId];
if ($display[$thisId] !== $pollObj->getVar('display') || $weight[$thisId] !== $pollObj->getVar('weight')) {
$pollObj->setVars(['display' => $display[$thisId], 'weight' => $weight[$thisId]]);
$pollHandler->insert($pollObj);
}
unset($pollObj);
}
unset($pollObjs);
require_once $GLOBALS['xoops']->path('class/template.php');
xoops_template_clear_module_cache($GLOBALS['xoopsModule']->getVar('mid'));
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_DBUPDATED);
} else {
redirect_header($_SERVER['SCRIPT_NAME'], Constants::REDIRECT_DELAY_SHORT, _AM_XOOPSPOLL_NOTHING_HERE);
}
break;
// added cloning capability in v 1.40
case 'clone':
$pollHandler = $helper->getHandler('Poll');
$optionHandler = $helper->getHandler('Option');
$pollId = Request::getInt('poll_id', 0);
$pollObj = $pollHandler->get($pollId);
$origValues = $pollObj->getValues();
unset($origValues['poll_id']);
$pollDuration = $origValues['end_time'] - $origValues['start_time'];
$pollDuration = ($pollDuration > 0) ? $pollDuration : Constants::DEFAULT_POLL_DURATION;
$newValues = [
'votes' => 0,
'voters' => 0,
'mail_status' => Constants::POLL_NOT_MAILED,
'question' => $origValues['question'] . '(' . _AM_XOOPSPOLL_CLONE . ')',
'start_time' => time(), //set the start time to now
'end_time' => time() + $pollDuration,
];
$cloneValues = array_merge($origValues, $newValues);
$cloneObj = $pollHandler->create();
$cloneObj->setVars($cloneValues);
$cloneId = $pollHandler->insert($cloneObj);
// now set cloned options
$optionObjs = $optionHandler->getAllByPollId($pollId);
foreach ($optionObjs as $optionObj) {
$cloneOptObj = $optionHandler->create();
$cloneValues = $optionObj->getValues();
$cloneValues['option_id'] = 0;
$cloneValues['poll_id'] = $cloneId;
$cloneValues['option_count'] = 0;
$cloneOptObj->setVars($cloneValues);
$optId = $optionHandler->insert($cloneOptObj);
unset($cloneValues, $cloneOptObj);
}
unset($pollObj, $cloneObj, $origValues, $cloneValues, $newValues);
redirect_header($_SERVER['SCRIPT_NAME'] . "?poll_id={$cloneId}&op=edit", Constants::REDIRECT_DELAY_MEDIUM, _AM_XOOPSPOLL_CLONE_SUCCESS);
break;
}