You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

425 lines
15 KiB

<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
use function Sabre\Uri\split;
function wikiplugin_convene_info(): array
{
return [
'name' => tra('Convene'),
'documentation' => 'PluginConvene',
'description' => tra('Suggest meeting dates and times and vote to select one'),
'introduced' => 9,
'prefs' => ['wikiplugin_convene','feature_calendar'],
'body' => tra('Convene data generated from user input'),
'iconname' => 'group',
'filter' => 'rawhtml_unsafe',
'tags' => [ 'basic' ],
'format' => 'html',
'params' => [
'title' => [
'required' => false,
'name' => tra('Title'),
'description' => tra('Title for the event'),
'since' => '9.0',
'default' => tra('Convene'),
],
'calendarid' => [
'required' => false,
'name' => tra('Calendar ID'),
'description' => tra('ID number of the site calendar in which to store the date for the events with the most votes'),
'since' => '9.0',
'filter' => 'digits',
'default' => 1,
'profile_reference' => 'calendar',
],
'minvotes' => [
'required' => false,
'name' => tra('Minimum Votes'),
'description' => tra('Minimum number of votes needed to show Add-to-Calendar icon, so that new users do
not see a potentially confusing icon before the convene has enough information on it'),
'since' => '10.3',
'filter' => 'digits',
'default' => 3,
],
'dateformat' => [
'required' => false,
'name' => tra('Date-Time Format'),
'description' => tra('Display date and time in short or long format, according to the site wide setting (or use "other" to specify a custom format below)'),
'since' => '9.0',
'filter' => 'alpha',
'default' => 'short',
'options' => [
['text' => '', 'value' => ''],
['text' => tra('Short'), 'value' => 'short'],
['text' => tra('Long'), 'value' => 'long'],
['text' => tra('Other'), 'value' => 'other'],
]
],
'dateformatother' => [
'required' => false,
'name' => tra('Other Date-Time Format'),
'description' => tra('Use a custom format string for the dates using PHP "strftime" or "date_format" parameters'),
'since' => '23.0',
'filter' => 'text',
'default' => '',
],
'adminperms' => [
'required' => false,
'name' => tra('Observe Admin Permissions'),
'description' => tra("Only admins can edit or delete other users' votes and dates. N.B. This is a guide only as if a user can edit the page they can change this setting, it is intended to make the plugin easier to use for most users."),
'since' => '9.0',
'filter' => 'alpha',
'default' => 'y',
'options' => [
['text' => '', 'value' => ''],
['text' => tra('Yes'), 'value' => 'y'],
['text' => tra('No'), 'value' => 'n']
]
],
'avatars' => [
'required' => false,
'name' => tra('Show user profile pictures'),
'description' => tra("Show user's profile pictures next to their names."),
'since' => '9.0',
'filter' => 'alpha',
'default' => 'y',
'options' => [
['text' => '', 'value' => ''],
['text' => tra('Yes'), 'value' => 'y'],
['text' => tra('No'), 'value' => 'n']
]
],
'autolock' => [
'required' => false,
'name' => tra('Automatic Lock'),
'description' => tra('Lock this plugin at a certain time and date (format YYYY-MM-DD hh:mm'),
'since' => '20.2',
'filter' => 'datetime',
'default' => '',
],
'locked' => [
'required' => false,
'name' => tra('Locked'),
'description' => tra('Prevent further votes or changes from the interface.'),
'since' => '20.2',
'filter' => 'alpha',
'default' => 'n',
'options' => [
['text' => '', 'value' => ''],
['text' => tra('Yes'), 'value' => 'y'],
['text' => tra('No'), 'value' => 'n']
],
],
'id' => [
'required' => false,
'name' => tra('Id of the form'),
'description' => tra('Leave blank automatically generate.'),
'since' => '23.0',
'filter' => 'text',
'default' => '',
],
'voteoptions' => [
'required' => false,
'name' => tra('Vote options'),
'description' => tra('Comma-separated for personalized set of vote options'),
'since' => '24.0',
'filter' => 'text',
'default' => default_voteoptions(),
'separator' => ',',
'accepted' => tr('-1=Not OK,-0.5=No but...,0=Unconfirmed,0.5=OK but...,1=OK'),
],
]
];
}
function wikiplugin_convene($data, $params): string
{
global $page;
/** @var HeaderLib $headerlib */
$headerlib = TikiLib::lib('header');
/** @var TikiLib $tikilib */
$tikilib = TikiLib::lib('tiki');
/** @var Smarty_Tiki $smarty */
$smarty = TikiLib::lib('smarty');
$smarty->loadPlugin('smarty_function_icon');
$smarty->loadPlugin('smarty_modifier_userlink');
$smarty->loadPlugin('smarty_modifier_avatarize');
if (! isset($params['voteoptions'])) {
$params['voteoptions'] = default_voteoptions();
}
if (! is_array($params['voteoptions'])) {
$params['voteoptions'] = explode(',', $params['voteoptions']);
}
//in case there is any feedback from a previous ajax action since this plugin does not refresh the page upon edit
Feedback::sendHeaders();
//Test if vote options are numeric value
foreach ($params['voteoptions'] as $voteoption) {
$optionvalue = explode('=', $voteoption);
if (!is_numeric($optionvalue[0])) {
Feedback::error(tr('Plugin convene: one or more of your option values must be numeric values'));
}
}
static $convenePluginIndex = 0;
++$convenePluginIndex;
//set defaults
$plugininfo = wikiplugin_convene_info();
$defaults = [];
foreach ($plugininfo['params'] as $key => $param) {
$defaults[$key] = $param['default'];
}
$params = array_merge($defaults, $params);
$params['index'] = $convenePluginIndex;
$params['id'] = empty($params['id']) ? 'pluginConvene' . $convenePluginIndex : $params['id'];
$dataArrays = json_decode($data, true);
$dataArray = $dataArrays[0]; // Default data votes
$dataArrayComments = $dataArrays[1]; //Data comments
if (! is_array($dataArray)) {
//start flat static text to prepared array
$dataString = $data . '';
$dataArray = [];
$lines = explode("\n", trim($data));
sort($lines);
foreach ($lines as $line) {
$line = trim($line);
if (! empty($line)) {
$parts = explode(':', $line);
$dataArray[trim($parts[0])] = trim($parts[1]);
}
}
$data = TikiFilter_PrepareInput::delimiter('_')->prepare($dataArray);
//end flat static text to prepared array
$data = $data['dates'];
} else {
$data = $dataArray;
}
$tikiDate = new TikiDate();
$gmformat = str_replace($tikiDate->search, $tikiDate->replace, $tikilib->get_short_datetime_format());
//start votes summed together
$votes = [];
$dateLabels = [];
foreach ($data as $stamp => & $date) {
foreach ($date as $user => $vote) {
if (empty($votes[$stamp])) {
$votes[$stamp] = 0;
}
$votes[$stamp] += $vote;
}
$dateLabels[$stamp] = [];
if ($params['dateformat'] === "long") {
$dateLabels[$stamp]['formatted'] = $tikilib->get_long_datetime($stamp);
} elseif ($params['dateformat'] === 'other') {
$format = $params['dateformatother'];
if (strpos($format, '%') === 0) { // assuming a strftime format starts with %
$dateLabels[$stamp]['formatted'] = TikiLib::date_format($format, $stamp);
} else {
$dateLabels[$stamp]['formatted'] = TikiLib::date_format2($format, $stamp);
}
} else {
$dateLabels[$stamp]['formatted'] = $tikilib->get_short_datetime($stamp);
}
$dateLabels[$stamp]['gmdate'] = tr('UTC date time: %0', gmdate($gmformat, $stamp));
}
//end votes summed together
//start find top vote stamps
$topVoteStamps = [];
$topVotes = max($votes);
foreach ($votes as $stamp => $vote) {
if ($vote === $topVotes) {
$topVoteStamps[] = $stamp;
}
}
//end find top vote stamp
//start reverse array for easy listing as table
$rows = [];
unset($date);
foreach ($data as $stamp => $date) {
foreach ($date as $user => $vote) {
if (isset($rows[$user][$stamp])) {
$rows[$user][$stamp] = [];
}
$rows[$user][$stamp] = $vote;
}
}
//end reverse array for easy listing as table
$autolockMessage = '';
if ($params['autolock']) {
if (! preg_match('/\d{4}-\d{2}-\d{2} \d{2}:\d/', $params['autolock'])) {
$autolock = TikiLib::date_format('%Y-%m-%d %H:%M', strtotime($params['autolock']));
if (! $autolock) {
Feedback::error(tr('Plugin convene: autolock date format not recognised'));
} else {
$params['autolock'] = $autolock;
}
}
$lockDate = new TikiDate();
$lockDate->setDate($params['autolock']);
$smarty->loadPlugin('smarty_modifier_tiki_short_datetime');
if ($lockDate < $tikiDate) {
$params['locked'] = 'y';
$autolockMessage = tr('Voting ended: %0', smarty_modifier_tiki_short_datetime($params['autolock']));
} else {
$autolockMessage = tr('Voting ends: %0', smarty_modifier_tiki_short_datetime($params['autolock']));
}
}
$smarty->assign('autolockMessage', $autolockMessage);
// perms for this object
$currentObject = current_object();
$perms = Perms::get($currentObject);
$canEdit = $perms->edit;
if ($params['adminperms'] !== 'y') {
$canAdmin = $canEdit;
} elseif ($currentObject['type'] === 'wiki page') {
$canAdmin = $perms->admin_wiki;
} elseif ($currentObject['type'] === 'trackeritem') {
$canAdmin = $perms->admin_trackers;
} else {
$canAdmin = $perms->admin; // global for other object types
}
if ($params['calendarid'] > 0) {
$calperms = Perms::get([
'type' => 'calendar',
'object' => $params['calendarid'],
]);
$canAddEvents = $calperms->add_events;
}
$smarty->assign('canEdit', $canEdit);
$smarty->assign('canAdmin', $canAdmin);
$smarty->assign('canAddEvents', $canAddEvents);
$smarty->assign('dates', $data);
$smarty->assign('dateLabels', $dateLabels);
$smarty->assign('rows', $rows);
$smarty->assign('votes', $votes);
$smarty->assign('topVoteStamps', $topVoteStamps);
$smarty->assign('params', $params);
$smarty->assign('comments', $dataArrayComments);
if($params['locked'] === "y"){
$vote_infos=[
"autolock" => $params['autolock'],
"object" => $currentObject['object'],
"users" => array_keys($rows),
"votes" => $votes
];
send_email_result_vote($vote_infos);
}
$conveneData = json_encode($params);
$headerlib->add_jsfile('lib/jquery_tiki/wikiplugin-convene.js')
->add_js("\$('#{$params['id']}').setupConvene($conveneData)");
return $smarty->fetch('wiki-plugins/wikiplugin_convene.tpl');
}
function default_voteoptions()
{
return '-1=Not OK,0=Unconfirmed,1=OK';
}
/**
* This module will help to send message to all member who participate on vote
* when lock time reached.
*
* @param $vote_infos
*
* @throws Exception
*/
function send_email_result_vote($vote_infos){
$date_start = TikiLib::date_format('%Y-%m-%d %H:%M',strtotime("now"));
if ($vote_infos["autolock"] === $date_start) {
$users=$vote_infos["users"];
$votes=$vote_infos["votes"];
include_once('lib/webmail/tikimaillib.php');
$userlib = TikiLib::lib('user');
$smarty = TikiLib::lib('smarty');
$tikilib = TikiLib::lib('tiki');
$mail = new TikiMail();
$machine = parse_url($_SERVER['REQUEST_URI']);
$machine = $tikilib->httpPrefix(true) . dirname($machine['path']);
$smarty->assign_by_ref('machine', $machine);
$machine = preg_replace("!/$!", "", $machine);
$smarty->assign('mail_machine', $machine);
$smarty->assign('mail_site', $_SERVER["SERVER_NAME"]);
$object_event = $vote_infos['object'];
$event_path = str_replace(" ","-",$object_event);
$max_vote = 0;
$vote_result = "";
arsort($votes);
$i = 0;
foreach($votes as $date => $vote) {
if ($i === 0) {
$max_vote = $vote;
}
if ($max_vote === $vote) {
$date_vote = TikiLib::date_format('%Y-%m-%d %H:%M', $date);
if ($i === 0) {
$vote_result = $vote . tra("votes on date of ") . $date_vote." ";
} else {
$vote_result.= tra("and"). " ".$date_vote;
}
}
$i++;
}
foreach ($users as $user) {
$userinfo = $userlib->get_user_email($user);
if ($userinfo) {
$smarty->assign('mail_user', $user);
$smarty->assign('event_link_path', $event_path);
$smarty->assign('vote_result', $vote_result);
$mail->setUser($userinfo);
$subject = sprintf($smarty->fetch('mail/convene_vote_result_subject.tpl'),$object_event,$_SERVER['SERVER_NAME']);
$mail->setSubject($subject);
$txt = $smarty->fetch('mail/convene_vote_result.tpl');
$mail->setText($txt);
$mail->send([$userinfo]);
}
}
}
}