This commit is contained in:
François 2023-10-13 06:43:02 +02:00
parent 53cdad5218
commit 94d8c8f707
44 changed files with 7453 additions and 0 deletions

View File

@ -1,2 +1,5 @@
# schedule
DokuWiki Extensions : https://www.dokuwiki.org/plugin:schedule
Event management for multi-organization.

29
action.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
if (!defined ('DOKU_INC'))
die ();
if (!defined ('DOKU_PLUGIN'))
define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
require_once (DOKU_PLUGIN.'action.php');
class action_plugin_schedule extends DokuWiki_Action_Plugin {
// ============================================================
function register (Doku_Event_Handler $controller) {
$controller->register_hook ('DOKUWIKI_STARTED', 'AFTER', $this, '_defconf');
}
function _defconf (&$event, $param) {
global $JSINFO;
$JSINFO ['schedule']['useMap'] = $this->getConf ('useMap');
$JSINFO ['schedule']['defaultCenter'] = json_decode ($this->getConf ('defaultCenter'), true);
$JSINFO ['schedule']['defaultZoom'] = json_decode ($this->getConf ('defaultZoom'), true);
}
// ============================================================
}

57
ajax.php Normal file
View File

@ -0,0 +1,57 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
$df_ : 31/12/2000
$ds_ : 20001231
$dn_ : 978217200
$dt_ : array ("Y" => 2000, "m" => 12, "d" => "31)
*/
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (dirname (__FILE__).'/../../../').'/');
global $conf;
require_once (DOKU_INC.'inc/init.php');
if (!$conf['lang'])
$conf['lang'] = 'fr';
require_once (DOKU_INC.'inc/common.php');
require_once (DOKU_INC.'inc/auth.php');
// ============================================================
if (isset ($_SERVER['REMOTE_USER']))
$INFO['userinfo'] = $auth->getUserData ($auth->cleanUser ($_SERVER['REMOTE_USER']));
$schdplug =& plugin_load ('syntax', 'schedule_block');
$scheduleRoot = new scheduleRoot ($schdplug);
ob_start ();
switch ($_REQUEST ['schd']['action']) {
// schedule Table
case 'changeDate':
global $conf;
$dn_showDay = mktime (0, 0, 0, date ("n"), date ("j"), date("Y"));
$ds_showDay = trim ($scheduleRoot->df2ds ($_REQUEST['schd']['date']));
if (preg_match ("#(?<Y>[0-9][0-9][0-9][0-9])(?<m>[0-9][0-9])(?<d>[0-9][0-9])#", $ds_showDay, $dt_showDay))
$dn_showDay = mktime (0, 0, 0, $dt_showDay["m"], $dt_showDay["d"], $dt_showDay["Y"]);
$schedules = new schedules ($scheduleRoot, $_REQUEST['schd']['ns']);
$schedules->load ();
$schedules->printScheduleCalendar ($_REQUEST['schd']['mapId'], $dn_showDay);
break;
// schedule Root Admin
case 'moveSchedules':
$scheduleRoot->manageAction ($_REQUEST['schd']);
$scheduleRoot->printForm ();
break;
default :
ptnl ('No Ajax Function !');
}
$text = ob_get_contents ();
ob_end_clean ();
foreach ($scheduleRoot->message as $type => $msg)
$text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
ptln ($text);
// ============================================================

32
ajaxClearCache.php Normal file
View File

@ -0,0 +1,32 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (dirname (__FILE__).'/../../../').'/');
require_once (DOKU_INC.'inc/init.php');
require_once (DOKU_INC.'inc/common.php');
require_once (DOKU_INC.'inc/auth.php');
// ============================================================
if (isset ($_SERVER['REMOTE_USER']))
$INFO['userinfo'] = $auth->getUserData ($auth->cleanUser ($_SERVER['REMOTE_USER']));
$schdplug =& plugin_load ('syntax', 'schedule_block');
$scheduleRoot = new scheduleRoot ($schdplug);
switch ($_REQUEST ['schedule']['action']) {
case 'clear':
$schedules = new schedules ($scheduleRoot, $_REQUEST ['schedule']['ns']);
$schedules->clearCache ();
break;
case 'clearAll':
$scheduleRoot->clearCache ();
break;
}
// ============================================================

45
ajaxPOI.php Normal file
View File

@ -0,0 +1,45 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
// faire un XML
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (dirname (__FILE__).'/../../../').'/');
require_once (DOKU_INC.'inc/init.php');
require_once (DOKU_INC.'inc/common.php');
require_once (DOKU_INC.'inc/auth.php');
require_once (realpath (dirname (__FILE__)).'/poiDB.class.php');
// ============================================================
if (isset ($_SERVER['REMOTE_USER']))
$INFO['userinfo'] = $auth->getUserData ($auth->cleanUser ($_SERVER['REMOTE_USER']));
$schdplug =& plugin_load ('syntax', 'schedule_block');
$isAdmin =
isset ($INFO ['userinfo']) &&
isset ($INFO ['userinfo']['grps']) &&
in_array (trim ($schdplug->getConf ('adminGroup')), $INFO ['userinfo']['grps']);
$poiDB = new poiDB ($schdplug);
if ('list' == $_REQUEST ['action'])
echo json_encode ($poiDB->getInsee ($_REQUEST['insee']));
elseif ($isAdmin) {
switch ($_REQUEST ['action']) {
case 'add':
$poiDB->addLine ($_REQUEST ['line']);
break;
case 'remove':
$poiDB->removeLine ($_REQUEST ['line']);
break;
default:
die ('No Ajax Function !');
}
} else
die ("No Ajax Function !");
// ============================================================

27
conf/default.php Normal file
View File

@ -0,0 +1,27 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Options for the Schedule Plugin
*/
$conf['scheduleGroup'] = 'schedule';
$conf['adminGroup'] = 'admin';
$conf['dataDir'] = 'schedule';
$conf['groupsDir'] = 'membres';
$conf['noSchedule'] = '2010';
$conf['scheduleDir'] = 'agenda';
$conf['sharedDir'] = 'commun';
$conf['scheduleWhat'] = 'A:Manifestation, Vote, Pétition, Action|B:Echange, Forum, Débat, Conférence, Projection, Exposition, Spectacle, Radio, TV, Pique-Nique|C:Assemblée Générale, Réunion, Mensuelle, Hebdomadaire';
$conf['scheduleAudience'] = 'Ouvert à tous, Membres, Commission, Bureau';
$conf['iconName'] = 'logo.png';
$conf['iconWidth'] = 30;
$conf['repeatPosition'] = 'isolated';
$conf['bubblePosition'] = 'right';
$conf['useMap'] = 1;
$conf['defaultCenter'] = "[47.95583, -2.54833]";
$conf['defaultZoom'] = 14;
$conf['migrate'] = 0;
$conf['showOldValues'] = 0;
?>

28
conf/metadata.php Normal file
View File

@ -0,0 +1,28 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Metadata for configuration manager plugin
* Additions for the schedule plugin
*/
$meta['scheduleGroup'] = array('string'); // who can use form
$meta['adminGroup'] = array('string'); // who can admin data
$meta['dataDir'] = array('string'); // root dir for XML files
$meta['groupsDir'] = array('string'); // dir group in wiki pages to find group names
$meta['noSchedule'] = array('string'); // forbiden name for group (ex skip annual archive dir)
$meta['scheduleDir'] = array('string'); // dir in wiki pages for events (contains subdir for group name or the shared dir)
$meta['sharedDir'] = array('string'); // dir for shared event in wiki pages
$meta['scheduleWhat'] = array('string'); // type event list
$meta['scheduleAudience'] = array('string'); // type audience list
$meta['iconName'] = array('string'); // file name containing logo in group dir
$meta['iconWidth'] = array('numeric'); // default logo width size
$meta['repeatPosition'] = array('multichoice', '_choices' => array('grouped', 'isolated')); // does the repeated events are group on top of form
$meta['bubblePosition'] = array('multichoice', '_choices' => array('left', 'right')); // tooltips position
$meta['useMap'] = array('onoff');
$meta['defaultCenter'] = array('string');
$meta['defaultZoom'] = array('numeric');
$meta['migrate'] = array('onoff'); // XXX to remove ?
$meta['showOldValues'] = array('onoff'); // XXX to remove ?
?>

BIN
images/bul_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

BIN
images/bul_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/bul_c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/calendar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

BIN
images/cat_a.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

BIN
images/cat_ab.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

BIN
images/cat_abc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

BIN
images/cat_ac.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

BIN
images/cat_b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

BIN
images/cat_bc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

BIN
images/cat_c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

BIN
images/edit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

BIN
images/empty.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

BIN
images/orange.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/poi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
images/poiRed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
images/red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

BIN
images/repeat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

BIN
images/warning.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

BIN
images/wizard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

121
lang/en/lang.php Normal file
View File

@ -0,0 +1,121 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* English language file
*/
// javascript
$lang['js'] =
array ('pleaseWait' => 'Connection to the server in progress ...');
// commands
$lang['Valid'] = 'Valid';
$lang['add'] = 'Add';
$lang['clear'] = 'Clear cache';
$lang['clearAll'] = 'Clear all cache';
$lang['clearCache'] = 'Clear cache'; // XXX
$lang['created'] = 'Created';
$lang['modify'] = 'Modify';
$lang['modifyAll'] = 'Modify All';
$lang['prop'] = 'Suggest';
$lang['remove'] = 'Remove';
$lang['selected'] = 'Selected';
$lang['show'] = 'Show';
$lang['test'] = 'Test';
$lang['repeatType'] = array ('day' => 'days', 'week' => 'weeks', 'dayMonth' => 'months', 'dateMonth' => 'months', 'year' => 'years');
// placeholder
$lang['titlePH'] = 'event title';
$lang['leadPH'] = 'Lead paragraph / organisation team / context / ... (optional)';
$lang['posterPH'] = 'http://... (optional)';
$lang['paperPH'] = 'http://... (optional)';
$lang['remarkPH'] = 'explanation / comments / remarks / ... (optional)';
$lang['ratePH'] = 'x € / y € (optional)';
$lang['cityPH'] = 'city (or INSEE code) +!!enter!!';
$lang['addrPH'] = '1, rue de la Tannerie ~br~ 56 000 +!!enter!!';
$lang['datePH'] = 'mm/dd/aa';
$lang['hourPH'] = '--h-- (ex: 09h30-15h)';
$lang['rootMoveDatePH'] = 'mm/dd/aa (move until this date)';
// messages
$lang['days'] = array ('sunday' => 'S', 'monday' => 'M', 'tuesday' => 'T', 'wednesday' => 'W', 'friday' => 'F', 'thursday' => 'T', 'saturday' => 'S');
$lang['enterTip'] = 'Press \'enter\' to update this field!';
$lang['who'] = 'Who';
$lang['audience'] = 'Audience';
$lang['shared'] = array ('', 'Shared');
$lang['proposedBy'] = 'Proposed by';
$lang['what'] = 'What';
$lang['title'] = 'Title';
$lang['lead'] = 'Lead paragraph';
$lang['posterURL'] = 'Poster';
$lang['paperURL'] = 'Paper';
$lang['remark'] = 'Topic';
$lang['rate'] = 'Rate';
$lang['where'] = 'Where';
$lang['city'] = 'Commune';
$lang['addresse'] = 'Addresse';
$lang['when'] = 'When';
$lang['allDates'] = 'All dates';
$lang['inverted'] = 'Inverted';
$lang['noEvent'] = 'No event';
$lang['validation'] = 'Validation';
$lang['proposition'] = 'Proposition';
$lang['reactiveMap'] = 'Interactive map!';
$lang['toComplet'] = 'To complete';
$lang['audienceChoice'] = 'For whom ?';
$lang['memberChoice'] = 'Proposed by ?';
$lang['eventTypeChoice'] = 'What kind of event ?';
$lang['from'] = 'from';
$lang['to'] = 'to';
$lang['fromHour'] = 'from';
$lang['toHour'] = 'to';
$lang['at'] = 'at';
$lang['all'] = 'all';
$lang['each'] = 'each';
$lang['startError'] = "Validation couldn't be performed because:";
$lang['noAudienceError'] = 'audience miss';
$lang['noMemberError'] = 'member miss';
$lang['noTypeError'] = 'event type miss';
$lang['noWhereError'] = 'place miss';
$lang['noTitleError'] = 'title miss';
$lang['mktimeError'] = 'unsupported date (OVH server limitation is : 13 decembre 1901 < YYYY-mm-dd < 20 janvier 2038)';
$lang['pastError'] = 'date out of bounds';
$lang['pastToError'] = 'end date before start :-D';
$lang['badDateError'] = 'inappropriate date';
$lang['notMemberError'] = 'not member';
$lang['addEvent'] = 'Add an event';
$lang['proposedEvent'] = 'Suggest an event';
$lang['propSuccess'] = "Votre proposition est enregistrée. Nous allons vérifier qu'elle est conforme à l'esprit du FSL avant de la mettre en ligne. Merci de votre contributon.";
$lang['notifySubject'] = '[Schedule] New proposal !';
$lang['notifyContent'] = "A new proposal is done.\n\n";
// toolTip
$lang['tipPrevM'] = 'Previous mounth';
$lang['tipNextM'] = 'Next mounth';
// format
$lang['dateFormat'] = 'mdY';
// $lang['orderedFormat'] = function ($num) { // XXX pb OVH
// if ($num < 1)
// return $num;
// switch ($num) {
// case 1:
// return '1st';
// default:
// return "{$num}th";
// }
// };
$lang['orderedFormat'] = array (1 => '1st', 2 => '2th', 3 => '3th', 4 => '4th', 5 => '5th', 6 => '6th', 7 => '7th', 8 => '8th', 9 => '9th', 10 => '10th', 11 => '11th', 12 => '12th', 13 => '13th', 14 => '14th', 15 => '15th', 16 => '16th', 17 => '17th', 18 => '18th', 19 => '19th', 20 => '20th', 21 => '21th', 22 => '22th', 23 => '23th', 24 => '24th', 25 => '25th', 26 => '26th', 27 => '27th', 28 => '28th', 29 => '29th', 30 => '30th', 31 => '31th');
?>

29
lang/en/settings.php Normal file
View File

@ -0,0 +1,29 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* English language file
*/
// for the configuration manager
$lang['scheduleGroup'] = 'in this group one can add event';
$lang['adminGroup'] = 'admin group with all rights on events';
$lang['dataDir'] = 'directory contains XML file per group';
$lang['groupsDir'] = 'directory where group names could be find';
$lang['noSchedule'] = 'forbiden group names';
$lang['scheduleDir'] = 'wiki page for schedule (contains one dir per group)';
$lang['sharedDir'] = 'directory for shared events';
$lang['scheduleWhat'] = 'type of events per categrory (c1:w1,w2|c2:w3,w4|c3:w5,w6,w7)';
$lang['scheduleAudience'] = 'type of public';
$lang['iconName'] = 'logo name of the group which define an event (a1,a2,a3)';
$lang['iconWidth'] = 'logo width of the group which define an event';
$lang['repeatPosition'] = 'Repeat event position (grouped on top or isolated)';
$lang['bubblePosition'] = 'tooltips position of calendar';
$lang['useMap'] = 'Display map';
$lang['defaultCenter'] = "Empty map default localization (lat, lon)";
$lang['defaultZoom'] = "Default zoom";
$lang['migrate'] = 'Performe data migration';
$lang['showOldValues'] = 'Highlight non migrate data';
?>

121
lang/fr/lang.php Normal file
View File

@ -0,0 +1,121 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* French language file
*/
// javascript
$lang['js'] =
array ('pleaseWait' => 'Connexion avec le serveur en cours ...');
// commands
$lang['add'] = 'Ajouter';
$lang['clear'] = 'Effacer le cache';
$lang['clearAll'] = 'Effacer tout les caches';
$lang['clearCache'] = 'Effacer le cache'; // XXX
$lang['created'] = 'Créer';
$lang['modify'] = 'Modifier';
$lang['modifyAll'] = 'Modifier Tout';
$lang['prop'] = 'Proposer';
$lang['remove'] = 'Supprimer';
$lang['selected'] = 'Selectionner';
$lang['show'] = 'Montrer';
$lang['test'] = 'Tester';
$lang['valid'] = 'Valider';
$lang['repeatType'] = array ('day' => 'jour', 'week' => 'semaine', 'dayMonth' => 'mois', 'dateMonth' => 'mois', 'year' => 'ans');
// placeholder
$lang['titlePH'] = "titre de l'évènement";
$lang['leadPH'] = 'Chapeau éditorial / organisateur / contexte / ... (facultatif)';
$lang['posterPH'] = 'http://... (facultatif)';
$lang['paperPH'] = 'http://... (facultatif)';
$lang['remarkPH'] = 'texte explicatif / commentaires / remarques / ... (facultatif)';
$lang['ratePH'] = 'x € / y € (facultatif)';
$lang['cityPH'] = 'commune (ou code INSEE) +!!entrée!!';
$lang['addrPH'] = '1, rue de la Tannerie ~br~ 56 000 +!!entrée!!';
$lang['datePH'] = 'jj/mm/aa';
$lang['hourPH'] = '--h-- (ex: 09h30-15h)';
$lang['rootMoveDatePH'] = "jj/mm/aa (déplace jusqu'à cette date)";
// messages
$lang['days'] = array ('dimanche' => 'D', 'lundi' => 'L', 'mardi' => 'M', 'mercredi' => 'M', 'jeudi' => 'J', 'vendredi' => 'V', 'samedi' => 'S');
$lang['enterTip'] = 'Appuyez sur \'entrée\' pour mettre à jour ce champ !';
$lang['who'] = 'Qui';
$lang['audience'] = 'Auditoire';
$lang['shared'] = array ('', 'Partagé');
$lang['proposedBy'] = 'Proposé par';
$lang['what'] = 'Quoi';
$lang['title'] = 'Titre ';
$lang['lead'] = 'Chapeau éditorial ';
$lang['posterURL'] = 'Affiche ';
$lang['paperURL'] = 'Article ';
$lang['remark'] = 'Sujet ';
$lang['rate'] = 'Tarif ';
$lang['where'] = 'Où ';
$lang['city'] = 'Commune ';
$lang['addresse'] = 'Adresse ';
$lang['when'] = 'Quand ';
$lang['allDates'] = 'Toutes dates';
$lang['inverted'] = 'Inverser';
$lang['noEvent'] = "Pas d'évènement";
$lang['validation'] = 'Validation';
$lang['proposition'] = 'Proposition';
$lang['reactiveMap'] = 'Carte interactive !';
$lang['toComplet'] = 'À compléter';
$lang['audienceChoice'] = 'Quelle audience ?';
$lang['memberChoice'] = 'Proposé par ?';
$lang['eventTypeChoice'] = "Quelle nature d'évènement ?";
$lang['from'] = 'du';
$lang['to'] = 'au';
$lang['fromHour'] = 'de';
$lang['toHour'] = 'à';
$lang['at'] = 'à';
$lang['all'] = 'chaque';
$lang['each'] = 'chaque';
$lang['startError'] = 'Certaines informations ne permettent pas la validation :';
$lang['noAudienceError'] = "manque d'auditoire";
$lang['noMemberError'] = 'manque de membre';
$lang['noTypeError'] = "manque de nature d'évènement";
$lang['noWhereError'] = 'manque de lieu';
$lang['noTitleError'] = 'manque de titre';
$lang['mktimeError'] = 'date non gérée (pour OVH : 13 decembre 1901 < YYYY-mm-dd < 20 janvier 2038)';
$lang['pastError'] = 'début en dehors des limites indiquées';
$lang['pastToError'] = 'date de fin avant le début :-D';
$lang['badDateError'] = 'date incorrecte';
$lang['notMemberError'] = 'non membre';
$lang['addEvent'] = 'Ajouter un évènement';
$lang['proposedEvent'] = 'Proposer un évènement';
$lang['propSuccess'] = "Votre proposition est enregistrée. Nous allons vérifier qu'elle est conforme à l'esprit du FSL avant de la mettre en ligne. Merci de votre contributon.";
$lang['notifySubject'] = '[Agenda] Nouvelle proposition !';
$lang['notifyContent'] = "Une nouvelle proposition a été faite.\n\n";
// toolTip
$lang['tipPrevM'] = 'Mois précédent';
$lang['tipNextM'] = 'Mois suivant';
// format
$lang['dateFormat'] = 'dmY';
// $lang['orderedFormat'] = function ($num) { // XXX pb OVH
// if ($num < 1)
// return $num;
// switch ($num) {
// case 1:
// return '1er';
// default:
// return "{$num}e";
// }
// };
$lang['orderedFormat'] = array (1 => '1er', 2 => '2e', 3 => '3e', 4 => '4e', 5 => '5e', 6 => '6e', 7 => '7e', 8 => '8e', 9 => '9e', 10 => '10e', 11 => '11e', 12 => '12e', 13 => '13e', 14 => '14e', 15 => '15e', 16 => '16e', 17 => '17e', 18 => '18e', 19 => '19e', 20 => '20e', 21 => '21e', 22 => '22e', 23 => '23e', 24 => '24e', 25 => '25e', 26 => '26e', 27 => '27e', 28 => '28e', 29 => '29e', 30 => '30e', 31 => '31e');
?>

33
lang/fr/settings.php Normal file
View File

@ -0,0 +1,33 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* French language file
*/
// for the configuration manager
$lang['scheduleGroup'] = 'en appartenant à ce groupe, on a accès au formulaire pour ajouter des évènements';
$lang['adminGroup'] = 'le groupe qui à tous les droits sur les évènements';
$lang['dataDir'] = 'répertoire où sont placés les fichiers XML des évènements par entité';
$lang['groupsDir'] = 'répertoire où se trouve les entités dans le wiki';
$lang['noSchedule'] = 'liste des entité (séparé par ",") ne devant pas créer des évènements';
$lang['scheduleDir'] = 'page wiki de gestion de l\'agenda (contient un répertoire par entité)';
$lang['sharedDir'] = 'répertoire regroupant les évènements partagés par tous les groupes';
$lang['scheduleWhat'] = 'liste des types d\'évènement par catégorie (c1:t1,t2|c2:t3,t4|c3:t5,t6,t7)';
$lang['scheduleAudience'] = 'les différents auditoires attendus pour les évènement (a1,a2,a3)';
$lang['iconName'] = 'nom du logo du groupe qui à créé l\'évènement';
$lang['iconWidth'] = 'largeur logo du groupe qui à créé l\'évènement';
$lang['repeatPosition'] = 'Position des évènements répétés (groupé en haut ou séparé)';
$lang['repeatPosition_o_grouped'] = 'groupé';
$lang['repeatPosition_o_isolated'] = 'séparé';
$lang['bubblePosition'] = 'Position des info-bulles du calendrier';
$lang['bubblePosition_o_left'] = 'gauche';
$lang['bubblePosition_o_right'] = 'droite';
$lang['useMap'] = 'Affiche une carte de localisation';
$lang['defaultCenter'] = "Position par défaut d'une carte vide (lat, lon)";
$lang['defaultZoom'] = "Zoom par défaut";
$lang['migrate'] = 'Effectue une migration des données';
$lang['showOldValues'] = 'Souligne les données non migrées';
?>

600
lib/scheduleCitiesMap.js Normal file
View File

@ -0,0 +1,600 @@
/*
All scheduleMap behaviors managed by schedule plugin
scheduleMapList: Map of
mapId => scheduleMap
scheduleMap
mapId: div map ID
map: map
poi: Point Of Interest
poiSize: # of number
clusterLayer: clusterLayer
*/
var scheduleMapList = {};
var scheduleUseMap = JSINFO['schedule']['useMap'];
var scheduleZoom = JSINFO['schedule']['defaultZoom'];
var scheduleCenter = JSINFO['schedule']['defaultCenter'];
var schedulePoiUri = DOKU_BASE+'lib/plugins/schedule/images/poi.png';
var scheduleSelectedPoiUri = DOKU_BASE+'lib/plugins/schedule/images/poiRed.png';
var scheduleEmptyUri = DOKU_BASE+'lib/plugins/schedule/images/empty.png';
var scheduleIconCalendarUri = DOKU_BASE+'lib/plugins/schedule/images/calendar.png';
var scheduleAjaxPoiUri = DOKU_BASE+"lib/plugins/schedule/ajaxPOI.php";
var schedulePrecision = 5;
var locationFormatRE = new RegExp ("^\\s*\\(\\s*([\\-0-9.]+)\\s*\\|\\s*([\\-0-9.]+)\\s*\\)\\s*(.*)$");
var iconStyle;
var iconSelectedStyle;
/* selected LI on city UL */
var scheduleSelectedCity = null;
// ========================================
/* format location */
function scheduleGetLocation (lat, lon) {
return "("+
parseFloat (parseFloat (lat).toFixed (schedulePrecision))+"|"+
parseFloat (parseFloat (lon).toFixed (schedulePrecision))+")";
}
// ========================================
/* convert and reverse location */
function scheduleGetCoordFromLocation (latLonArray) {
return ol.proj.transform ([latLonArray [1], latLonArray [0]], 'EPSG:4326', 'EPSG:3857');
}
// ========================================
/* convert and reverse location */
function scheduleGetLocationFromCoord (coord) {
var lonLat = ol.proj.transform (coord, 'EPSG:3857', 'EPSG:4326');
return [parseFloat (lonLat[1]).toFixed (schedulePrecision), parseFloat (lonLat [0]).toFixed (schedulePrecision)];
}
// ========================================
/* center scheduleMap according POI markers */
function scheduleCenterMap (scheduleMap) {
if (!scheduleUseMap)
return;
if (scheduleMap.poiSize) {
scheduleMap.map.getView ().fit (scheduleMap.poi.getExtent (), scheduleMap.map.getSize ());
scheduleMap.map.getView ().setZoom (Math.min (scheduleMap.map.getView ().getZoom ()*.9,
scheduleZoom));
return;
}
scheduleMap.map.getView ().setCenter (scheduleGetCoordFromLocation (scheduleCenter));
scheduleMap.map.getView ().setZoom (6); //scheduleZoom);
}
// ========================================
/* remove all POI markers */
function scheduleClearMarkers (scheduleMap) {
if (!scheduleUseMap)
return;
scheduleMap.poiSize = 0;
if (scheduleMap.poi !== undefined)
scheduleMap.poi.clear ();
}
// ========================================
/* add a wellknown city marker */
function scheduleAddCityMarker (scheduleMap, cityCode) {
if (! cityCode)
return;
var inseeLocation = inseeCityNameLatLon[cityCode];
if (!style) {
// XXX not found
return;
}
scheduleAddLatLonCityMarker (scheduleMap, cityCode,
inseeCityNameLatLon[cityCode][1],
inseeCityNameLatLon[cityCode][2]);
}
// ========================================
/* add a positioned city marker */
function scheduleAddLatLonCityMarker (scheduleMap, cityCode, lat, lon) {
if (!scheduleUseMap)
return;
scheduleMap.poiSize++;
if (scheduleMap.poi === undefined)
return;
scheduleMap.poi.addFeature (new ol.Feature({
geometry: new ol.geom.Point (scheduleGetCoordFromLocation ([lat, lon])),
cityCode: cityCode,
location: scheduleGetLocation (lat, lon),
lat: lat,
lon: lon,
selected: false
}));
}
// ========================================
/* highlight all cities on the list of adress */
function scheduleHighlightAddress (locations) {
if (!locations) {
jQuery ('div.scheduleAddresse').removeClass("poiAdrLight");
return;
}
jQuery ('div.scheduleAddresse').each (function () {
var adrBlock = jQuery (this);
var location = adrBlock.attr ('location');
if (location && (','+locations).indexOf (location) >= 0)
adrBlock.addClass("poiAdrLight");
else
adrBlock.removeClass("poiAdrLight");
});
}
function scheduleHighlightLocation (location) {
scheduleHighlightAddress (location);
scheduleHighlightPOI (location);
}
// ========================================
/* display cities from a UL */
function scheduleAddAllCityFromUl (scheduleMap, ul) {
scheduleClearMarkers (scheduleMap);
ul.find ('li').each (function (index) {
var li = jQuery (this);
scheduleAddLatLonCityMarker (scheduleMap, li.attr ('insee'),
li.attr ('lat'), li.attr ('lon'));
});
if (!scheduleUseMap)
return;
if (scheduleMap.poi !== undefined){
scheduleMap.poi.changed ();
scheduleMap.map.render ();
}
}
// ========================================
function scheduleAddCityToUl (ul, cityName) {
var cityCode = /[0-9AB]{5,}/.exec (cityName);
var lat = "";
var lon = "";
if (cityCode != null)
cityCode = cityCode[0];
if (!cityCode)
cityCode = inseeCityNameInsee [cityName.toLowerCase ()];
if (!cityCode)
cityName = cityCode = cityName.replace(/[^A-ZÀÂÆÇÉÈÊËÎÏÑÔŒÙÛÜÿ a-zàâæçéèêëîïñôœùûüÿ'\-]/gi,'');
else {
cityName = inseeCityNameLatLon[cityCode][0];
lat = inseeCityNameLatLon[cityCode][1];
lon = inseeCityNameLatLon[cityCode][2];
}
var recorded = false;
ul.find ('li[insee="'+cityCode+'"][lat="'+lat+'"][lon="'+lon+'"]').each (function (index) {
recorded = true;
scheduleSetSelectCity (jQuery (this));
});
if (recorded)
return;
var lonLat =
(lat && lon) ?
' lat="'+lat+'" lon="'+lon+'"' :
' class="unknown"';
ul.append ('<li insee="'+cityCode+'"'+lonLat+' onclick="scheduleSelectCity (this)">'+
'<img class="checked" src="'+scheduleEmptyUri+'" width="10" height="16" onclick="scheduleRemoveCity (this)"/>'+
' <span class="addresse"></span> '+
'<span class="city">'+cityName+'</span></li>');
scheduleSetSelectCity (ul.find ("li").last ());
}
// ========================================
/* Sort UL by city name (XXX what about addresse ?) */
function scheduleSortUlCities (ul) {
ul.children ('li').sort (function (a, b) {
var upa = jQuery (a).find ('span.city').text ().toUpperCase ();
var upb = jQuery (b).find ('span.city').text ().toUpperCase ();
return (upa < upb) ? -1 : (upa > upb) ? 1 : 0;
}).appendTo (ul[0]);
}
function scheduleAjaxPOILine (action) {
if (!scheduleSelectedCity)
// XXX dire quelque chose
return;
var insee = scheduleSelectedCity.attr ('insee');
var lat = scheduleSelectedCity.attr ('lat');
var lon = scheduleSelectedCity.attr ('lon');
var addr = scheduleSelectedCity.find ('span.addresse').html ().replace (/<br>/gi, '~br~');
line = new Array ();
line.push (insee);
line.push (lat);
line.push (lon);
line.push (addr);
jQuery.ajax ({
type: "POST",
url: scheduleAjaxPoiUri,
cache: true,
async: true,
data: { action: action, line: line.join ('|') },
success: function (response) { alert (response); }
});
}
function scheduleAddInsee () {
scheduleAjaxPOILine ("add");
}
function scheduleRemoveInsee () {
scheduleAjaxPOILine ("remove");
}
function scheduleTestInsee () {
}
function scheduleSetSelectCity (li) {
scheduleSelectedCity = li;
// change autocomplete
var cityCode = scheduleSelectedCity.attr ('insee');
var form = scheduleSelectedCity.closest ('.scheduleCitiesForm');
var input = form.find ('input[name="addr"]');
input. val (scheduleSelectedCity.find ('span.addresse').html ().replace (/<br>/gi, '~br~'));
jQuery.ajax ({
type: "POST",
url: scheduleAjaxPoiUri,
cache: true,
async: true,
data: { action: "list", insee: cityCode },
success: function (response) {
var db = jQuery.parseJSON (response);
source = new Array ();
for (var i = 0; i < db.length; i++) {
var vals = db[i].split ("|");
source.push ("("+vals[0]+"|"+vals[1]+") "+vals[2]);
}
input.autocomplete ({ source: source });
}
});
}
function scheduleFocusCity () {
if (!scheduleUseMap)
return;
var form = scheduleSelectedCity.closest ('.scheduleCitiesForm');
// focus on map
form.find ('.scheduleMap').each (function () {
var scheduleMap = scheduleMapList [jQuery (this).attr ('id')];
scheduleMap.map.getView ().setCenter (scheduleGetCoordFromLocation ([scheduleSelectedCity.attr ('lat'), scheduleSelectedCity.attr ('lon')]));
scheduleMap.map.getView ().setZoom (Math.min (scheduleMap.map.getView ().getZoom (), scheduleZoom));
});
}
// ========================================
/* User LI selection and focus on map */
function scheduleSelectCity (item) {
scheduleSetSelectCity (jQuery (item).closest ('li'));
scheduleFocusCity ();
}
// ========================================
/* User remove LI */
function scheduleRemoveCity (item) {
var li = jQuery (item).closest ('li');
var ul = li.closest ('ul');
li.remove ();
scheduleUpdateUlCity (ul);
}
function scheduleUpdateUlCity (ul) {
ul.closest ('.scheduleCitiesForm'). find ('.scheduleMap').each (function () {
var scheduleMap = scheduleMapList [jQuery (this).attr ('id')];
scheduleAddAllCityFromUl (scheduleMap, ul);
scheduleCenterMap (scheduleMap);
});
scheduleCheckInputs ();
}
// ========================================
/* Find all initial values */
function scheduleInitPOI () {
jQuery ('.schedulePOI').each (function () {
var poiDiv = jQuery (this);
var scheduleMap = scheduleMapList [poiDiv.find ('.scheduleMap').attr ('id')];
scheduleClearMarkers (scheduleMap);
poiDiv.find ('span.poiLocations').each (function () {
var poiLocations = jQuery (this).text ().split (',');
for (var i = 0; i < poiLocations.length; i++) {
var latLon = poiLocations[i];
var match = latLon.match (locationFormatRE);
if (match) {
var lat = parseFloat (match [1]).toFixed (schedulePrecision);
var lon = parseFloat (match [2]).toFixed (schedulePrecision);
scheduleAddLatLonCityMarker (scheduleMap, "", lat, lon);
} else
// cityCode = latLon
scheduleAddCityMarker (scheduleMap, latLon);
}
scheduleCenterMap (scheduleMap);
});
poiDiv.find ('ul.poiLatLon').each (function () {
jQuery (this).find ('li').each (function (index) {
var li = jQuery (this);
scheduleAddLatLonCityMarker (scheduleMap, li.text (),
li.attr ('lat'), li.attr ('lon'));
});
scheduleCenterMap (scheduleMap);
});
});
jQuery ('.scheduleCitiesForm').each (function () {
var scheduleCitiesForm = jQuery (this);
var scheduleMapDiv = scheduleCitiesForm.find ('.scheduleMap');
if (scheduleMapDiv[0] === undefined)
return;
var scheduleMap = scheduleMapList [scheduleMapDiv.attr ('id')];
scheduleAddAllCityFromUl (scheduleMap, jQuery (this).find ('.cities'));
scheduleCenterMap (scheduleMap);
});
}
// ========================================
/* Find all maps */
function scheduleInitMaps () {
if (!scheduleUseMap)
return;
jQuery ('.scheduleMap').each (function () {
var mapDiv = jQuery (this).find ('div');
if (mapDiv !== undefined && mapDiv && mapDiv.length)
return;
var mapId = jQuery (this).attr ('id');
var osm = new ol.layer.Tile ({
source: new ol.source.OSM ()
});
var poi = new ol.source.Vector ({
features: []
});
iconStyle = new ol.style.Style ({
image: new ol.style.Icon (/** @type {olx.style.IconOptions} */ ({
anchor: [.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
opacity: 0.75,
src: schedulePoiUri
}))
});
iconSelectedStyle = new ol.style.Style ({
image: new ol.style.Icon (/** @type {olx.style.IconOptions} */ ({
anchor: [.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
opacity: 0.75,
src: scheduleSelectedPoiUri
}))
});
var clusters = new ol.source.Cluster({
distance: 10,
source: poi,
});
var styleCache = {false: {}, true: {}};
var clusterLayer = new ol.layer.Vector({
source: clusters,
style: function (feature) {
var features = feature.get ('features');
var size = features.length;
if (size < 2)
return features [0].get ('selected') ? iconSelectedStyle : iconStyle;
var selected = false;
features.forEach (function (item) {
if (item.get ('selected'))
selected = true;
});
var style = styleCache[selected][size];
if (!style) {
style = [new ol.style.Style({
image: new ol.style.Icon (/** @type {olx.style.IconOptions} */ ({
anchor: [.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
opacity: 0.75,
src: selected ? scheduleSelectedPoiUri : schedulePoiUri
})),
text: new ol.style.Text({
text: size.toString (),
offsetY: -24 // XXX textpos conf ?
})
})];
styleCache[selected][size] = style;
}
return style;
}
});
var map = new ol.Map ({
target: mapId,
layers: [osm, clusterLayer],
//logo: false,
controls: ol.control.defaults ({
zoom: true,
attribution: false,
rotate: false
}),
view: new ol.View ({
center: ol.proj.fromLonLat (scheduleCenter),
zoom: scheduleZoom
})
});
if (jQuery (this).hasClass ("scheduleMapDisplay"))
map.set ("mapType", "display");
if (jQuery (this).hasClass ("scheduleMapForm"))
map.set ("mapType", "form");
if (jQuery (this).hasClass ("scheduleMapCalendar"))
map.set ("mapType", "calendar");
map.on ("singleclick", function (evt) {
var f;
map.forEachFeatureAtPixel (evt.pixel, function (feature) {
f = feature;
return true;
});
switch (map.get ("mapType")) {
case "display":
if (f) {
if (f.get ('features').length)
f = f.get ('features')[0];
window.open ("https://www.openstreetmap.org/?mlat="+f.get ('lat')+"&mlon="+f.get ('lon')+"&zoom="+scheduleZoom, "_self");
}
break;
case "form":
var location = scheduleGetLocationFromCoord (evt.coordinate);
scheduleSelectedCity.attr ('lat', location[0]);
scheduleSelectedCity.attr ('lon', location[1]);
scheduleAddAllCityFromUl (scheduleMap, scheduleSelectedCity.closest ('ul'));
break;
}
});
map.on ("pointermove", function (evt) {
var locations = new Set ();
map.forEachFeatureAtPixel (evt.pixel, function (feature) {
feature.get ('features').forEach (function (item) {
locations.add (item.get ('location'));
});
});
locations = Array.from (locations);
scheduleHighlightDays (locations);
scheduleHighlightLocation (locations.join (','));
});
var scheduleMap = {
mapId: mapId,
map: map,
poiSize: 0,
poi: poi,
clusterLayer: clusterLayer
};
scheduleMapList[mapId] = scheduleMap;
scheduleCenterMap (scheduleMap);
});
}
// ========================================
/* Initialisation and attach function */
jQuery (function () {
jQuery (function () {
// create tabs before OpenLayers stuff (important !)
jQuery (".scheduleTabForm").tabs ({
active: 0
});
jQuery ("#scheduleHelp").accordion ({
collapsible: true,
animated: false,
active: false
});
jQuery.datepicker.setDefaults ({
showOn: "both",
buttonImageOnly: true,
buttonImage: scheduleIconCalendarUri,
buttonText: "",
firstDay: 0
});
jQuery.datepicker.formatDate ("yy-mm-dd");
jQuery (".scheduleTabForm .date").datepicker ();
divError = jQuery ("div.schedule").prev ("div.error");
if (divError !== undefined && divError && divError.length)
// XXX a tester (avant divError.size ())
scheduleForceCheckInputs ();
});
// check and format form request
jQuery ('.scheduleFinalForm').submit (function () {
var scheduleFinalForm = jQuery (this);
if (!scheduleForceCheckInputs ())
return false;
var scheduleForm = scheduleFinalForm.closest ('.scheduleTabForm');
var scheduleCitiesForm = scheduleForm.find ('.scheduleCitiesForm');
var cities = new Array ();
var lats = new Array ();
var lons = new Array ();
var addrs = new Array ();
scheduleCitiesForm.find ('li').each (function (index) {
var li = jQuery (this);
cities.push (li.attr ('insee'));
lats.push (li.attr ('lat'));
lons.push (li.attr ('lon'));
addrs.push (li.find ('span.addresse').html ());
});
scheduleFinalForm.append ('<input type="hidden" name="schd[where]" value="'+cities.join (",")+'"/>');
scheduleFinalForm.append ('<input type="hidden" name="schd[lat]" value="'+lats.join (",")+'"/>');
scheduleFinalForm.append ('<input type="hidden" name="schd[lon]" value="'+lons.join (",")+'"/>');
scheduleFinalForm.append ('<input type="hidden" name="schd[addr]" value="'+addrs.join ("|").replace (/<br>/gi, '~br~')+'"/>');
var scheduleMiscForm = scheduleForm.find ('.scheduleMiscForm');
scheduleMiscForm.find ('input[type="text"]').each (function (index) {
if (this.value)
scheduleFinalForm.append ('<input type="hidden" name="'+this.name+'" value="'+this.value.replace(/"/gi, "''")+'"/>');
});
scheduleMiscForm.find ('select:not([class="members"])').each (function (index) {
scheduleFinalForm.append ('<input type="hidden" name="'+this.name+'" value="'+this.value+'"/>');
});
var members = new Array ();
scheduleMiscForm.find ('select[class="members"]').each (function (index) {
jQuery (this).find ('option:selected').each (function (index) {
members.push (jQuery (this).val ());
});
});
if (members.length > 0)
scheduleFinalForm.append ('<input type="hidden" name="schd[member]" value="'+members.join (",")+'"/>');
scheduleMiscForm.find ('textarea').each (function (index) {
var val = jQuery (this).val ().replace(/"/gi, "''");
var name = jQuery (this).attr ('name');
scheduleFinalForm.append ('<input type="hidden" name="'+name+'" value="'+val+'"/>');
});
return true;
});
// city validation
jQuery ('.scheduleCitiesForm input[name="city"]').keypress (function (e) {
if (e.which != 13)
return;
var input = jQuery (this);
var form = input.closest ('.scheduleCitiesForm');
var cityName = input.val ();
if (!cityName)
return false;
input.val ("");
form.find ('input[name="addr"]').val ("");
var ul = form.find ('ul');
scheduleAddCityToUl (ul, cityName);
scheduleSortUlCities (ul);
scheduleUpdateUlCity (ul);
return false;
});
// full adress validation
jQuery ('.scheduleCitiesForm input[name="addr"]').keypress (function (e) {
if (e.which != 13)
return;
if (!scheduleSelectedCity)
return;
var input = jQuery (this);
var form = input.closest ('.scheduleCitiesForm');
var addr = input.val ();
var match = addr.match (locationFormatRE);
if (match) {
addr = match [3];
scheduleSelectedCity.attr ('lat', parseFloat (match [1]).toFixed (schedulePrecision));
scheduleSelectedCity.attr ('lon', parseFloat (match [2]).toFixed (schedulePrecision));
var scheduleMap = scheduleMapList [form.find ('.scheduleMap').attr ('id')];
scheduleAddAllCityFromUl (scheduleMap, scheduleSelectedCity.closest ('ul'));
scheduleFocusCity ();
}
input.val (addr);
scheduleSelectedCity.find ('span.addresse').html (addr.replace (/~br~/gi, '<br/>'));
});
// default form validation for each text field
jQuery ('.scheduleMiscForm input').keypress (function (e) {
if (e.which != 13)
return;
jQuery (this).closest ('.scheduleTabForm').find ('input[type="submit"]').first ().trigger ('click');
});
// init maps
scheduleInitMaps ();
scheduleInitPOI ();
});
// ========================================

145
lib/scheduleForm.js Normal file
View File

@ -0,0 +1,145 @@
// ========================================
var scheduleDoCkeck = false;
function scheduleForceCheckInputs () {
scheduleDoCkeck = true;
return scheduleCheckInputs ();
}
function scheduleCheckSelect (select) {
var warning = select.find ('option:selected').val () == "";
select.prev (".warningPlace").toggleClass ("warning", warning);
return warning;
}
function scheduleCheckInput (input) {
var warning = input.val () == "";
input.toggleClass ("warning", warning);
return warning;
}
function scheduleCheckUL (ul) {
var warning = ul.children ().length == 0;
ul.toggleClass ("warning", warning);
return warning;
}
/*
* highlight missing input fields
*/
function scheduleCheckInputs () {
if (!scheduleDoCkeck)
return false;
var tab = jQuery (".scheduleTabForm");
var tabs = tab.find ("li a.warningPlace");
var checked = true;
var warning = false;
warning = scheduleCheckSelect (tab.find ('select[name="schd[audience]"]'));
warning = scheduleCheckSelect (tab.find ('select.members')) || warning;
tabs.slice (0,1).toggleClass ("warning", warning);
if (warning)
checked = false;
warning = scheduleCheckSelect (tab.find ('select[name="schd[what]"]'));
warning = scheduleCheckInput (tab.find ('input[name="schd[title]"]')) || warning;
tabs.slice (1,2).toggleClass ("warning", warning);
if (warning)
checked = false;
warning = scheduleCheckUL (tab.find ('ul.cities'));
tabs.slice (2,3).toggleClass ("warning", warning);
if (warning)
checked = false;
warning = scheduleCheckInput (tab.find ('input[name="schd[from]"]'));
tabs.slice (3,4).toggleClass ("warning", warning);
if (warning)
checked = false;
warning = scheduleCheckInput (tab.find ('input.edit'));
tabs.slice (4,5).toggleClass ("warning", warning);
if (warning)
checked = false;
return checked;
}
/**
* switch all selected events for delete.
*/
function scheduleSwitchSelection (form) {
for (var i = 0; i < form.elements.length; i++)
form.elements[i].checked = !form.elements[i].checked;
}
/*
* change member selection mode according share status
*/
function scheduleSharedEvent (form) {
var form = jQuery (form);
var shared = null;
form.find ('select[name="schd[shared]"]').each (function () {
if (this.options [this.selectedIndex].text != "")
shared = "true";
});
form.find ('select[name="schd[member]"]').each (function () {
this.multiple = shared;
this.size = shared ? 9 : 1;
});
}
/*
* display repeat input according selection
*/
function scheduleUpdateRepeatType (repeatSelection) {
var selectedValue = repeatSelection.options [repeatSelection.selectedIndex].value;
var inputs = repeatSelection.form.elements;
var disabledWeek = (selectedValue != "week");
var disabledDay = (selectedValue != "dayMonth");
var disabledDate = (selectedValue != "dateMonth");
var checkedDay = 0;
// XXX jquery ?
for (var i = 0; i < inputs.length; i++) {
var name = inputs[i].name;
if (name == "schd[weekDays][]") {
inputs[i].disabled = disabledWeek;
if (inputs[i].checked)
checkedDay++;
} else if (name == "schd[weekRank]")
inputs[i].disabled = disabledDay;
else if (name == "schd[dayInWeek]")
inputs[i].disabled = disabledDay;
else if (name == "schd[dayRank]")
inputs[i].disabled = disabledDate;
}
if (!disabledWeek && checkedDay == 0)
scheduleForceDay (inputs);
// XXX forcer le Ie jour du mois
}
/*
* display repeat input according selection
*/
function scheduleUpdateWeekDays (DaySelection) {
var inputs = DaySelection.form.elements;
var checkedDay = 0;
// XXX jquery
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].name == "schd[weekDays][]")
if (inputs[i].checked)
checkedDay++;
}
if (checkedDay == 0)
scheduleForceDay (inputs);
}
function scheduleForceDay (inputs) {
var date = document.getElementById ("scheduleFrom").value;
if (!date)
date = new Date ();
else {
date = date.split ('/'); // XXX bug format FR seulement
date [1] = parseInt (date [1]) - 1;
if (date[2] < 100)
date [2] = parseInt (date [2]) + 2000;
date = new Date (date[2], date [1], date [0]);
}
var rankDay = date.getDay();
for (var i = 0; i < inputs.length; i++)
if (inputs[i].name == "schd[weekDays][]" && inputs[i].value == rankDay)
inputs[i].checked = true;
}

93
lib/scheduleTable.js Normal file
View File

@ -0,0 +1,93 @@
// ========================================
/* highlight day and cities in table according the event under the mouse */
function scheduleHighlightEvent (day, locations) {
jQuery ('div.cityBubble div.bubble').each (function () {
jQuery (this).hide ();
});
scheduleHighlightPOI (locations);
jQuery ('div.schedule table.short div.mapSelect').each (function () {
var showDay = jQuery (this);
var today = showDay.attr ('day');
if (day && today == day)
showDay.show ();
else
showDay.hide ();
});
}
// ========================================
/* highlight all days in table according the city under the mouse */
function scheduleHighlightDays (targetLocations) {
jQuery ('div.cityBubble div.bubble').each (function () {
jQuery (this).hide ();
});
if (!targetLocations || !targetLocations.length) {
jQuery ('div.schedule table.short div.mapSelect').hide ();
return;
}
targetLocations.forEach (function (location) {
jQuery ('div.cityBubble[location="'+location+'"] div.bubble').each (function () {
jQuery (this).show ();
});
});
jQuery ('div.schedule table.short div.mapSelect').each (function () {
var showDay = jQuery (this);
var eventLocations = showDay.attr ('locations');
if (!eventLocations) {
showDay.hide ();
return;
}
var doShow = false;
targetLocations.forEach (function (location) {
if ((','+eventLocations+',').indexOf (location) >= 0) {
doShow = true;
return;
}
});
if (doShow)
showDay.show ();
else
showDay.hide ();
});
}
var scheduleMapList;
// ========================================
/* highlight all cities on the map according the day under the mouse */
function scheduleHighlightPOI (locations) {
if (!locations) {
jQuery ('div.schedule table.short div.mapSelect').hide ();
jQuery.each (scheduleMapList, function (mapId, scheduleMap) {
scheduleMap.poi.forEachFeature (function (item) {
item.set ('selected', false);
});
scheduleMap.poi.changed ();
scheduleMap.map.render ();
});
return;
}
jQuery.each (scheduleMapList, function (mapId, scheduleMap) {
var changed = false;
scheduleMap.poi.forEachFeature (function (item) {
var location = item.get ('location');
item.set ('selected', (location && (','+locations).indexOf (location) >= 0));
});
scheduleMap.poi.changed ();
scheduleMap.map.render ();
});
}
// ========================================
function scheduleChangeDate (obj, ns, mapId, date) {
var table = jQuery (obj).closest ("table")[0];
scheduleSend (table,
DOKU_BASE+"lib/plugins/schedule/ajax.php",
"schd[ns]="+ns+"&schd[mapId]="+mapId+"&schd[action]=changeDate&schd[date]="+date);
}
// ========================================
function scheduleSelectDate (date) {
jQuery ("#scheduleFrom").val (date);
}
// ========================================

7
plugin.info.txt Normal file
View File

@ -0,0 +1,7 @@
base schedule
author Francois Merciol
email dokuplugin@merciol.fr
date 2021-03-31
name Schedule Plugin
desc Includes and manage shcedule into a page (V4)
url http://www.dokuwiki.org/plugin:schedule

113
poiDB.class.php Normal file
View File

@ -0,0 +1,113 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
// ============================================================
class poiDB {
var $modify = false;
var $dbFileName;
var $dbByInsee;
var $allLines;
// ============================================================
function __construct ($plugin) {
global $conf;
$this->dbFileName =
((!$conf['savedir'] || strpos ($conf['savedir'], '.') === 0) ? DOKU_INC : "").
$conf['savedir'].'/'.trim ($plugin->getConf ('dataDir').'/poiDB.txt');
$this->read ();
}
// ============================================================
function getInsee ($insee) {
if (!isset ($this->dbByInsee [$insee]))
return array ();
return $this->dbByInsee [$insee];
}
// ============================================================
function addLine ($line) {
$this->cleanDB ();
$line = $this->cleanLine ($line);
if (!$this->allLines || !in_array ($line, $this->allLines)) {
$this->allLines [] = $line;
sort ($this->allLines);
$this->modify = true;
}
$this->write ();
echo "record".NL;
}
// ============================================================
function removeLine ($line) {
$this->cleanDB ();
$line = $this->cleanLine ($line);
if (($key = array_search ($line, $this->allLines)) !== false) {
unset ($this->allLines [$key]);
$this->modify = true;
}
$this->write ();
}
// ============================================================
function cleanLine ($line) {
// XXX vérifier nombre
$data = explode ("|", $line);
foreach ($data as $key => $val)
$data[$key] = trim ($val);
$data [1] = number_format ((float)$data[1], 4);
$data [2] = number_format ((float)$data[2], 4);
return implode ("|", $data);
}
// ============================================================
function cleanDB () {
if ($this->allLines)
foreach ($this->allLines as $key => $line) {
$lineCleaned = $this->cleanLine ($line);
if ($lineCleaned != $line)
$this->modify = true;
$this->allLines [$key] = $lineCleaned;
}
}
// ============================================================
function read () {
$this->dbByInsee = array ();
$handle = @fopen ($this->dbFileName, "r");
if ($handle) {
while (($line = fgets ($handle)) !== false) {
$line = trim (preg_replace ("/#.*$/", "", str_replace ('\\\\', '~br~', $line)));
if (!$line)
continue;
$this->allLines [] = $line;
list ($insee, $end) = explode ('|', $line, 2);
$this->dbByInsee [$insee][] = $end;
}
fclose ($handle);
}
}
// ============================================================
function write () {
if (!$this->modify) {
echo "POI DB unchanged !".NL;
return;
}
$handle = @fopen ($this->dbFileName, "w");
if ($handle == false)
die("unable to create file: ".$this->dbFileName); // XXX
foreach ($this->allLines as $line)
fputs ($handle, $line.NL);
fclose ($handle);
echo "POI DB updated !".NL;
}
// ============================================================
}

64
schedule.class.php Normal file
View File

@ -0,0 +1,64 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (dirname (__FILE__).'/../../../').'/');
if (!defined ('DOKU_PLUGIN'))
define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
// ============================================================
// event class
class schedule {
var $id; // event id
var $member; // event owner
var $from; // event begining date
var $to; // event ending date
var $at; // event begining hour
var $what; // event type
var $where; // event place insee code or city name
var $lon; // event place latitude
var $lat; // event place longitude
var $addr; // event place addresse
var $audience; // event expected audience
var $shared; // shared event
var $title; // event page title
var $lead; // event lead
var $posterURL; // event poster URL
var $paperURL; // event paper URL
var $remark; // event remark
var $rate; // event rate
var $repeatFlag; // event repeat or not
var $repeat; // event step of repeat
var $repeatType; // event type of repeat
var $repeatGrouped; // repeat event grouped on top
var $weekDays; // event array days concern by the repeating week
var $weekRank; // event week concern by the repeating month
var $dayInWeek; // event day in the week concern by the repeating month
var $dayRank; // event day in the month concern by the repeating month
var $requestMembers; // all members proposed during the request
}
// ============================================================
// sort event by event date, then creation date
function cmpSchedule ($a, $b) {
if ($a->from == $b->from) {
if ($a->at == $b->at)
return ($a->id < $b->id) ? -1 : 1;
return ($a->at < $b->at) ? -1 : 1;
}
return ($a->from < $b->from) ? -1 : 1;
}
// sort info bubbles by date
function cmpScheduleInDay ($a, $b) {
if ($a['at'] == $b['at'])
return ($a['id'] < $b['id']) ? -1 : 1;
return ($a['at'] < $b['at']) ? -1 : 1;
}
// ============================================================

2830
scheduleInseeCities.php Normal file

File diff suppressed because it is too large Load Diff

465
scheduleRoot.class.php Normal file
View File

@ -0,0 +1,465 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*
* $df_ : 31/12/2000
* $ds_ : 20001231
* $dn_ : 978217200
* $dt_ : array ("Y" => 2000, "m" => 12, "d" => "31)
*/
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (dirname (__FILE__).'/../../../').'/');
if (!defined ('DOKU_PLUGIN'))
define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
function cmpScheduleConfig ($a, $b) {
return ($a['nameSpace'] < $b['nameSpace']) ? -1 : 1;
}
// ============================================================
// admin class
class scheduleRoot {
// ============================================================
// Config attributs
// ============================================================
var $cacheRootDir; // root cache directory
var $dataRootDir; // root data directory
var $scheduleGroup; // group who can display and fill form
var $groupsDir; // pages groups directories
var $scheduleDir; // schedule pages groups directories
var $sharedDir; // schedule directory for shared events
var $scheduleWhat = array (); // set of legal "what"
var $scheduleAudience = array (); // set of legal "audience"
var $iconName; // group icon name
var $iconWidth; // group icon width
// lang
var $scheduleShared = array (); // notshared/shared
var $currentDateFormat;
// ============================================================
// Constant attributs $this->scheduleRoot->
// ============================================================
//var $imagesUrlDir = '/lib/plugins/schedule/images/'; // DOKU_REL
var $wizardIconUrl = '/lib/plugins/schedule/images/wizard.png'; // $this->imagesUrlDir
var $editIconUrl = '/lib/plugins/schedule/images/edit.png';
var $repeatIconUrl = '/lib/plugins/schedule/images/repeat.png';
var $emptyIconUrl = '/lib/plugins/schedule/images/empty.png';
var $oldConfigFile = "config.xml"; // old file config name
var $configFile = "cfg.xml"; // file config name
var $mbrPrefix = "mbr-"; // member prefix file name
var $propFile = "prop.xml"; // member prefix file name
var $configAttributsName = array ("nameSpace", "lastNotification", "lastNotificationReset");
// scheduleDir == NS ?
var $dateFormat = array ("dmY" => array ("shortScan" => "(?<d>[0-9]{1,2})[ /-](?<m>[0-9]{1,2})[ /-](?<Y>[0-9]{1,2})",
"longScan" => "(?<d>[0-9]{1,2})[ /-](?<m>[0-9]{1,2})[ /-](?<Y>[0-9]{4})",
"fieldName" => array ("d", "m", "Y"),
"prettyPrint" => "d/m/Y",
"dayMonth" => "d/m"),
"mdY" => array ("shortScan" => "(?<m>[0-9]{1,2})[ /-](?<d>[0-9]{1,2})[ /-](?<Y>[0-9]{1,2})",
"longScan" => "(?<m>[0-9]{1,2})[ /-](?<d>[0-9]{1,2})[ /-](?<Y>[0-9]{4})",
"fieldName" => array ("m", "d", "Y"),
"prettyPrint" => "m/d/Y",
"dayMonth" => "m/d"));
var $oddEvenValues = array ("odd", "even");
var $scheduleRequestAttributsName = array ("id", "audience", "shared",
"what", "title", "lead", "posterURL", "paperURL", "remark", "rate",
"where", "lon", "lat", "addr",
"from", "to", "at",
"repeat", "repeatType", "weekRank", "dayInWeek", "dayRank",
"user");
var $scheduleSaveAttributsName;
var $filterNames = array ("noMember" => "member",
"noWhat" => "what",
"NoAudience" => "audience");
// ============================================================
// Transcient attributs
// ============================================================
var $message = array (); // messages to display : "notify" =>, "info" =>, "success" =>, "error" =>
var $plugin; // link to wiki plugin inforation (conf, lang, ...)
var $isAdmin; // if user member of schedule adminGroup
var $oddEven = 0; // background color for table lines
// ============================================================
// Util
// ============================================================
/* messages container to be display before plugin */
function message ($type, $text) {
if (isset ($this->message[$type]))
$this->message[$type] .= '<br/>'.NL;
$this->message[$type] .= $text;
}
function startMessage ($type, $text) {
if (isset ($this->message[$type]))
$this->message[$type] = '<br/>'.NL.$this->message[$type];
$this->message[$type] = $text.$this->message[$type];
}
/* debug messages for admin only */
function debug ($text) {
global $INFO;
// XXX
if (isset ($INFO['userinfo'] ['grps']) && in_array ('admin', $INFO ['userinfo'] ['grps']))
$this->message ('notify', '<pre>'.$text.'</pre>');
}
/* Change date format from array to number */
function dt2dn ($dt_date) {
$dn_date = mktime (0, 0, 0, $dt_date["m"], $dt_date["d"], $dt_date["Y"]);
if (!$dn_date)
$this->message ('error', $dt_date["Y"]."-".$dt_date["d"]."-".$dt_date["m"]." : ".$this->plugin->getLang ('mktimeError').'<br/>'.NL);
return $dn_date;
}
/* Check date format 31/12/2000 */
function checkDS ($ds_date) {
return
preg_match ("#([0-9]{8})#", $ds_date, $dumy);
}
/* Change date format from MM/DD/AAAA to number */
function df2ds ($df_date) {
$df_date = trim ($df_date);
if (!$df_date)
return;
if ("!" == $df_date)
$ds_date = date ("Ymd");
elseif (preg_match ("#\+(?<delta>[0-9]+)#", $df_date, $matches))
$ds_date = sprintf ("%08d", date ("Ymd", mktime (0, 0, 0, date ("n"), date ("j")+$matches["delta"], date ("Y"))));
elseif (preg_match ("#\-(?<delta>[0-9]+)#", $df_date, $matches))
$ds_date = sprintf ("%08d", date ("Ymd", mktime (0, 0, 0, date ("n"), date ("j")-$matches["delta"], date ("Y"))));
elseif (preg_match ("#".$this->currentDateFormat ["longScan"]."#", $df_date, $dt_date))
$ds_date = sprintf ("%04d%02d%02d", $dt_date["Y"], $dt_date["m"], $dt_date["d"]);
elseif (preg_match ("#".$this->currentDateFormat ["shortScan"]."#", $df_date, $dt_date))
$ds_date = sprintf ("20%02d%02d%02d", $dt_date["Y"], $dt_date["m"], $dt_date["d"]);
else
$ds_date = "{$df_date}";
return $ds_date;
}
/* Change date format from number to MM/DD/AAAA */
function ds2df ($ds_date) {
$ds_date = trim ($ds_date);
if (preg_match ("#(?<Y>[0-9][0-9][0-9][0-9])(?<m>[0-9][0-9])(?<d>[0-9][0-9])#", $ds_date, $dt_date))
return sprintf ("%02d/%02d/%04d",
$dt_date[$this->currentDateFormat["fieldName"][0]],
$dt_date[$this->currentDateFormat["fieldName"][1]],
$dt_date[$this->currentDateFormat["fieldName"][2]]);
else
return "{$ds_date}";
}
function ds2ln ($ds_date, $bold = false) {
$ds_date = trim ($ds_date);
if (preg_match ("#(?<Y>[0-9][0-9][0-9][0-9])(?<m>[0-9][0-9])(?<d>[0-9][0-9])#", $ds_date, $dt_date)) {
// XXX prévoir le format anglais
setlocale (LC_TIME, 'fr_FR.utf8','fra');
return strftime (($bold ? "**%A %e %B** %Y" : "%A %e %B %Y"),
mktime (0, 0, 0,
$dt_date[$this->currentDateFormat["fieldName"][1]],
$dt_date[$this->currentDateFormat["fieldName"][0]],
$dt_date[$this->currentDateFormat["fieldName"][2]]));
} else
return "{$ds_date}";
}
/* Convert array on string (words seperated bay '|') */
static function array2string ($array) {
if (!$array)
return "";
$array = array_unique ($array);
if (in_array ("", $array))
$array = array_diff ("", $array);
if (count ($array) < 1)
return "";
return implode ("|", $array);
}
/* Convert array on string (words seperated bay '|') */
function assocImplode ($array, $vSep = '|', $kSep = ':') {
$result = "";
foreach ($array as $k => $v) {
$result .= $vSepNeeded.$k.$kSep.$v;
$vSepNeeded = $vSep;
}
return $result;
}
/* Convert array on string (words seperated bay '|') */
function assocExplode ($string, $vSep = '|', $kSep = ':') {
$result = array ();
foreach (explode ($vSep, $string) as $kv) {
$data = explode ($kSep, $kv);
$result [$data[0]] = $data[1];
}
return $result;
}
/* Convert array on string (words seperated bay '|') */
// $ find data/[mp]*/membres/*/agenda/*/* data/[mp]*/commun/agenda/*/* -type f -print > dumy
// $ emacs dumy
// C-x ( mv ' ' C-k C-y ' ' C-y C-f C-x )
// M-1000 C-x e
// C-M-%
// ^\([^ ]* [^ ]* [^ ]*agenda/[^/ ]*_\)/ => \1
// C-M-%
// ^\([^ ]* [^ ]* [^ ]*agenda/[^/ ]*_\)/ => \1
// C-M-%
// ^\([^ ]* [^ ]* [^ ]*agenda/[^/ ]*\)/ => \1_
// $ find data/[mp]*/membres/*/agenda/* -type d -exec rmdir {} \; -print
function removeSep ($titleId) {
return strtr ($titleId, ':/;', ' ');
}
function getPageId ($schedule) {
return ":".
$this->scheduleDir.":".
($schedule->shared ? $this->sharedDir : $schedule->member).":".
$this->removeSep ($schedule->title);
}
function resetOddEven () {
$this->oddEven = 0;
}
function switchOddEven () {
$this->oddEven = 1 - $this->oddEven;
}
function getOddEven () {
return $this->oddEvenValues [$this->oddEven];
}
static function createDirIsNeeded ($dir) {
if (is_dir ($dir))
return;
@mkdir ($dir);
@chmod ($dir, 0775);
}
// ============================================================
function __construct ($plugin) {
$this->plugin = $plugin;
$this->scheduleSaveAttributsName = array_merge ($this->scheduleRequestAttributsName, array ("weekDays"));
global $conf;
$savedir = ((!$conf['savedir'] || strpos ($conf['savedir'], '.') === 0) ? DOKU_INC : "").$conf['savedir']."/";
$this->cacheRootDir = $savedir."cache/schedule/";
$this->dataRootDir = $savedir.trim ($this->plugin->getConf ('dataDir').'/');
scheduleRoot::createDirIsNeeded ($this->cacheRootDir);
scheduleRoot::createDirIsNeeded ($this->dataRootDir);
$this->scheduleGroup = trim ($this->plugin->getConf ('scheduleGroup'));
$this->groupsDir = trim ($this->plugin->getConf ('groupsDir'));
$this->scheduleDir = trim ($this->plugin->getConf ('scheduleDir'));
$this->sharedDir = trim ($this->plugin->getConf ('sharedDir'));
foreach (explode ('|', $this->plugin->getConf ('scheduleWhat')) as $tmpCatDef) {
$tmpCatExp = explode (':', trim ($tmpCatDef));
$tmpCat = trim ($tmpCatExp[0]);
foreach (explode (',', $tmpCatExp[1]) as $tmpWhat) {
$tmpWhat = trim ($tmpWhat);
$this->scheduleWhat[$tmpWhat] = $tmpCat;
}
}
$this->scheduleAudience [""] = $this->plugin->getLang ('audienceChoice');
foreach (explode (',', $this->plugin->getConf ('scheduleAudience')) as $tmpAudience)
$this->scheduleAudience[trim ($tmpAudience)] = trim ($tmpAudience);
$this->iconName = $this->plugin->getConf ('iconName');
$this->iconWidth = $this->plugin->getConf ('iconWidth');
foreach (array (false, true) as $sharedVal) {
$tmp = $this->plugin->getLang ('shared');
$this->scheduleShared[] = trim ($tmp[$sharedVal]);
}
$this->currentDateFormat = $this->dateFormat [$this->plugin->getLang ('dateFormat')];
global $INFO;
$this->isAdmin =
isset ($INFO ['userinfo']) &&
isset ($INFO ['userinfo']['grps']) &&
in_array (trim ($this->plugin->getConf ('adminGroup')), $INFO ['userinfo']['grps']);
}
// ============================================================
// Manage XML file
// ============================================================
/* read lodging config */
function readConfig ($dir) {
$oldFileName = $dir.$this->oldConfigFile;
$fileName = $dir.$this->configFile;
// rename old fashion membre file name
if (file_exists ($oldFileName)) {
// XXX migration
rename ($oldFileName, $fileName);
$exclude = ".|..|".$this->scheduleRoot->configFile;
$exclude_array = explode("|", $exclude);
$pathDir = rtrim ($dir, "/") . "/";
if (is_dir($pathDir)) {
$pathDirObj = opendir ($pathDir);
while (false !== ($file = readdir ($pathDirObj))) {
if (in_array (strtolower ($file), $exclude_array))
continue;
$pathFile = $pathDir.$file;
if (is_file ($pathFile) && preg_match ('#.*\.xml$#i', $file, $b))
rename ($pathFile, $pathDir.$this->mbrPrefix.$file);
}
}
}
if (!file_exists ($fileName))
return false;
$result = array ();
// if (! class_exists ('DOMDocument'))
// return $result;
$xml = new DOMDocument ("1.0", "utf8");
$xml->load ($fileName);
$root = $xml->documentElement;
foreach ($this->configAttributsName as $field) {
$element = $root->getElementsByTagName ($field);
if ($element)
$result [$field] = $element->item (0)->nodeValue;
}
return $result;
}
/* write lodging config */
function writeConfig ($schedules) {
$fileName = $schedules->dataDir.$this->configFile;
scheduleRoot::createDirIsNeeded ($schedules->dataDir);
// if (! class_exists ('DOMDocument'))
// return;
$xml = new DOMDocument ("1.0", "utf8");
$root = $xml->createElement ("schedule");
$xml->appendChild ($root);
foreach ($this->configAttributsName as $field)
$root->appendChild ($xml->createElement ($field, htmlspecialchars ($schedules->$field)));
$xml->formatOutput = true;
$xml->save ($fileName);
chmod ($fileName, 0664);
}
// ============================================================
function manageAction ($request) {
if (!$this->isAdmin)
return;
$md5 = $request['md5'];
if (!$md5)
return;
$schedules = new schedules ($this, $request[$md5]['ns']);
switch ($request["action"]) {
case 'moveSchedules':
$md5 = $request['md5'];
$date = $this->df2ds ($request[$md5]['date']);
$md5bis = $request[$md5]['toNs'];
if (!$date)
return;
$src = new schedules ($this, $request[$md5]['ns']);
$src->load ();
$dst = new schedules ($this, $request[$md5bis]['ns']);
$dst->load ();
$filter = array ();
foreach ($src->allSchedules as $id => $schedule)
if (($schedule->to ? $schedule->to : $schedule->from) < $date)
$filter [$id] = $schedule;
foreach ($filter as $id => $schedule) {
$dst->addSchedule ($schedule);
$src->removeSchedule ($id);
}
$dst->writeSchedules ();
$src->writeSchedules ();
unset ($_REQUEST['schd']);
break;
default:
return;
}
}
// ============================================================
function printForm () {
if (!$this->isAdmin)
return;
$list = $this->readAllSchedules ();
echo
'<form method="POST" action="" onSubmit="return false;" >'.NL.
' <table class="admin" >'.NL.
' <thead>'.NL.
// XXX getLang ()
' <tr><th>Description</th><th>Valeurs</th></tr>'.NL.
' </thead>'.NL.
' <tbody>'.NL;
$this->resetOddEven ();
foreach ($list as $md5 => $item) {
$nameSpace = $item ["nameSpace"];
$schedules = $item ["schedules"];
echo
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">NameSpace</td>'.NL.
' <td class="value"><input type="hidden" name="schd['.$md5.'][ns]" value="'.$nameSpace.'"/>'.$nameSpace.'</td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">MD5</td>'.NL.
' <td class="value">'.$md5.'</td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">Members</td>'.NL.
' <td class="value">'.count ($schedules->memberSchedules).'</td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">Events</td>'.NL.
' <td class="value">'.count ($schedules->datedSchedules).'</td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">Repeated</td>'.NL.
' <td class="value">'.count ($schedules->repeatedSchedules).'</td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">Date</td>'.NL.
' <td><input type="text" name="schd['.$md5.'][date]" value="'.'" placeholder="'.$this->plugin->getLang ('rootMoveDatePH').'"/></td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">Vers</td>'.NL.
' <td><select name="schd['.$md5.'][toNs]"/>'.NL;
foreach ($list as $md5bis => $itemBis)
if ($md5bis != $md5)
echo
' <option value="'.$md5bis.'">'.$itemBis["nameSpace"].'</option>'.NL;
echo
' </select></td>'.NL.
' </tr>'.NL.
' <tr class="'.$this->getOddEven ().'">'.NL.
' <td class="name">Action</td>'.NL.
' <td><input type="submit" name="action" value="moveSchedules" onClick="scheduleAjax(this.form,\'moveSchedules\',\''.$md5.'\')" /></td>'.NL.
' </tr>'.NL;
$this->switchOddEven ();
}
echo
' </tbody>'.NL.
' </table>'.NL.
'</form>'.NL;
}
// ============================================================
function readAllSchedules () {
$exclude_array = explode ("|", ".|..");
if (!is_dir($this->dataRootDir))
return;
$pathDirObj = opendir ($this->dataRootDir);
while (false !== ($file = readdir ($pathDirObj))) {
$subDir = $this->dataRootDir.$file.'/';
if (in_array (strtolower ($file), $exclude_array) || !is_dir ($subDir))
continue;
$list [$file] = $this->readConfig ($subDir);
$list [$file]["schedules"] = new schedules ($this, $list [$file]["nameSpace"]);
$list [$file]["schedules"]->load ();
}
uasort ($list, "cmpScheduleConfig");
return $list;
}
function clearCache () {
$list = $this->readAllSchedules ();
foreach ($list as $md5 => $item) {
$schedules = $item ["schedules"];
$schedules->clearCache ();
}
}
// ============================================================
}

1663
schedules.class.php Normal file

File diff suppressed because it is too large Load Diff

79
script.js Normal file
View File

@ -0,0 +1,79 @@
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Javascript functionality for the include plugin
*/
/* DOKUWIKI:include_once lib/scheduleForm.js */
/* DOKUWIKI:include_once lib/scheduleTable.js */
/* DOKUWIKI:include_once ../ol3/script.js */
/* DOKUWIKI:include_once lib/scheduleCitiesMap.js */
// ========================================
// Ajax function
// ========================================
/* Clear popup message */
function scheduleClearMsgJ (item) {
item.closest ("div").find ("div.popup").each (function () {
jQuery (this).remove ();
});
}
function scheduleClearCache (action, ns) {
jQuery.ajax ({
type: "POST",
url: DOKU_BASE+"lib/plugins/schedule/ajaxClearCache.php",
//success: function (response) { alert (response); },
cache: true,
async: true,
data: "schedule[action]="+action+"&schedule[ns]="+ns
});
}
/* performe ajax request to swap month */
function scheduleAjax (form, action, md5) {
var params = "";
// XXX jquery
for (var idx = 0; idx < form.elements.length; idx++) {
var elem = form.elements[idx];
if (elem.type == "checkbox") {
if (elem.checked)
params += "&"+elem.name+"="+elem.value;
} else if (elem.type == "select" || elem.type == "select-multiple") {
while (elem.options.selectedIndex >= 0) {
opt = elem.options [elem.options.selectedIndex];
params += "&"+elem.name+"="+opt.text;
elem.options [elem.options.selectedIndex] = null;
}
} else
params += "&"+elem.name+"="+elem.value;
}
params += "&schd[action]="+action+"&schd[md5]="+md5;
scheduleSend (form,
DOKU_BASE+"lib/plugins/schedule/ajax.php",
params);
return false;
}
function scheduleSend (sender, uri, params) {
var jDiv = jQuery (sender).closest ("div");
scheduleClearMsgJ (jDiv);
jQuery ('<div class="popup">'+LANG["plugins"]["schedule"]["pleaseWait"]+'</div>').
insertBefore (jDiv.children ().first ());
jQuery.ajax ({
type: "POST",
url: uri,
cache: false,
async: true,
data: params,
success: function (response) {
jDiv.html (response);
scheduleInitMaps ();
scheduleInitPOI ();
}
});
}
// ========================================

528
style.css Normal file
View File

@ -0,0 +1,528 @@
/*
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois <dokuplugin@merciol.fr>
*/
div.schedule {
margin: 1em;
}
div.schedule table {
border: 0 none;
border-spacing: 0;
}
div.schedule table th, div.schedule table th {
border: 0 none;
text-align: center;
margin: 0;
padding: 0;
}
/* ==================== */
div.schedule table.admin {
border-collapse: collapse;
border-spacing: 0;
}
div.schedule table.admin tr {
border: 0 none;
text-align: center;
vertical-align: middle;
margin: 0 4px;
padding: 0 4px;
}
div.schedule table.admin tr.even {
background-color: #DDD;
}
div.schedule table.admin tr td.name {
text-align: right;
}
div.schedule table.admin tr td.value {
text-align: left;
font-weight: bold;
}
div.schedule table.admin tr td input {
width: 100%;
}
div.schedule table.admin select {
width: 100%;
}
/* ==================== */
div.schedule table.long {
border-collapse: collapse;
border-spacing: 0;
}
div.schedule table.long tr.odd {
vertical-align: middle;
}
div.schedule table.long tr.even {
vertical-align: middle;
background-color: #DDD;
}
div.schedule table.long tr th,
div.schedule table.long tr td {
border: 0 none;
text-align: center;
margin: 0 4px;
padding: 0 4px;
}
/* ========================================
* Depend on "scheduleWhat" configuration
* ======================================== */
div.schedule table.long tr.cat_a td.what {
padding-left: 20px;
background-image: url("images/bul_a.png");
background-repeat: no-repeat;
}
div.schedule table.long tr.cat_b td.what {
padding-left: 20px;
background-image: url("images/bul_b.png");
background-repeat: no-repeat;
}
div.schedule table.long tr.cat_c td.what {
padding-left: 20px;
background-image: url("images/bul_c.png");
background-repeat: no-repeat;
}
/* ==================== */
div.schedule table.short {
margin: auto;
border: 0 none;
border-spacing: 0;
}
div.schedule table.short th, div.schedule table.short td {
border: 0 none;
text-align: center;
margin: 0;
padding: 0;
width: 1em;
height: 1em;
z-index: 1;
}
div.schedule table.short td a {
font-weight: bold;
}
div.schedule table.short td.week {
margin: 2px 0;
color: #888;
}
div.schedule table.short td.empty {
opacity: 0.4;
}
div.schedule table.short td.weekend {
background-color: #CCC;
}
div.schedule table.short td.outofscope {
text-decoration: overline line-through underline;
background-color: #888;
color: #666;
}
div.schedule table.short td.free {
background-color: white;
}
div.schedule table.short caption {
font-weight: bold;
text-align: center;
}
div.schedule table.short caption.scheduleShow {
border: 2px solid orange;
}
div.schedule table.short caption.scheduleToday {
border: 2px solid red;
}
/* ========================================
* Depend on "scheduleWhat" configuration
* ======================================== */
div.schedule table.short td.cat_a {
font-weight: bold;
background: url("images/cat_a.png") repeat;
}
div.schedule table.short td.cat_b {
background: url("images/cat_b.png") repeat;
}
div.schedule table.short td.cat_c {
background: url("images/cat_c.png") repeat;
}
div.schedule table.short td.cat_ab {
background: url("images/cat_ab.png") repeat;
}
div.schedule table.short td.cat_ac {
background: url("images/cat_ac.png") repeat;
}
div.schedule table.short td.cat_bc {
background: url("images/cat_bc.png") repeat;
}
div.schedule table.short td.cat_abc {
background: url("images/cat_abc.png") repeat;
}
div.schedule table.short td.op_1 {
opacity: 1;
}
div.schedule table.short td.op_2 {
opacity: 1;
}
div.schedule table.short td.op_3 {
opacity: 1;
}
/* ========================================
*
* ======================================== */
div.schedule .popup {
position: absolute;
top: auto;
left: auto;
width: auto;
height: auto;
margin: 1em;
padding: 1em;
overflow: visible;
z-index: 1000;
opacity: 0.7;
background: #EDDB31;
color: black;
border: 1px solid #AE090D;
font-weight: bold;
}
div.bubble img {
vertical-align: middle;
}
div.bubble a,
div.bubble a:visited,
div.bubble a:hover,
div.bubble a:active,
div.bubble a:link {
/*cursor: pointer;*/
display: block;
text-decoration: none ! important;
font-weight: bold;
color: #AE090D ! important;
}
div.bubble div.date {
font-weight: bold;
text-align: center;
}
div.bubble div.odd {
background-color: #FDD ! important;
padding: 0 4px;
}
div.bubble div.even {
background-color: #FE5 ! important;
padding: 0 4px;
}
div.schedule table.short caption div div.bubble,
div.schedule table.short td div.bubble {
position: absolute;
z-index: 1000;
opacity: 0.8;
background: #EDDB31; /* Définition du fond, sinon on a le même que notre lien */
color: black;
border: 1px solid #AE090D; /* Définition des bordures */
text-align: left;
vertical-align: middle;
padding: 0;
font-size: 75%;
top: auto;
overflow: visible;
width: 16em;
height: auto;
margin-top: 1em;
display: none;
}
div.schedule table.short div.leftBubble {
left: -13em;
}
div.schedule table.short div.rightBubble {
left: 18em;
}
/* Rend visible tout notre bloc bubble et lui attribue une taille */
div.schedule .showBubbleOnFocus:hover div.bubble,
div.schedule .showBubbleOnFocus:focus div.bubble,
div.schedule .showBubbleOnFocus:active div.bubble {
display: block;
}
div.schedule table.short td div.bubble a img {
opacity: 1;
}
div.schedule table.short div.over {
position: absolute;
top: auto;
left: auto;
z-index: 900;
}
div.schedule table.short td div.past {
font-weight: bold;
color: #FFF;
background-color: #444;
opacity: 0.7;
margin: 0 0 0 3px !important;
}
div.schedule table.short td div.scheduleToday {
opacity: 1;
z-index: 3;
font-weight: bold;
margin: -3px -4px 0 0;
border: 3px solid red;
padding: 0;
color: black;
}
div.schedule table.short td div.scheduleShow {
opacity: 1;
z-index: 3;
font-weight: bold;
margin: -3px -4px 0 0;
border: 3px solid orange;
padding: 0;
color: black;
}
div.schedule table.short td div.mapSelect {
z-index: 4;
font-weight: bold;
margin: -3px -4px 0 0;
border: 3px solid #F0F;
padding: 0;
color: #F0F;
}
/* ==================== */
form.scheduleCitiesForm input {
width: 26em;
}
div.schedule table.form select,
div.schedule table.form input {
font-size: 100%;
}
div.scheduleTabForm textarea {
width: 100%;
height: 5em;
}
div.scheduleTabForm input.lat {
width: 4em;
}
div.scheduleTabForm input.lon {
width: 4em;
}
div.scheduleTabForm input.date {
width: 6em;
}
div.scheduleTabForm input.where {
width: 100%;
}
div.scheduleTabForm input.hour {
width: 10em;
}
div.scheduleTabForm input.repeat {
width: 2em;
}
div.scheduleTabForm td.repeat {
text-align: left;
}
div.scheduleTabForm div >* {
vertical-align: top;
}
div.scheduleTabForm p >* {
vertical-align: top;
}
div.scheduleTabForm img.checked {
height: 16px;
background-image: url("images/poi.png"); /* poi.png */
background-size: 10px 16px;
background-repeat: no-repeat;
}
div.scheduleTabForm li:hover img.checked {
background-image: url("images/poiRed.png"); /* selectedPoi.gif */
}
/* ==================== */
.ui-accordion .ui-accordion-content {
height: auto !important;
}
.scheduleCitiesForm ul {
/*padding: 0 !important;*/
margin: 0 !important;
}
.scheduleCitiesForm ul li {
margin-left: 20px;
}
.scheduleCitiesForm ul img {
margin-left: -20px;
}
.scheduleCitiesForm .ui-widget>* {
display: block;
}
.scheduleCitiesForm div>div {
vertical-align: top;
display: inline-block;
}
.scheduleCitiesForm .cities {
min-height: 4em;
max-height: 4em;
overflow-y: scroll;
overflow-x:hidden;
border-style: solid;
border-color: grey;
border-width: 1px;
padding: 1px;
}
.scheduleCitiesForm .cities li {
list-style-type:none;
}
.scheduleCitiesForm .unknown {
background-color: #FDD;
}
div.schedule table.short div.tabSelect {
position: absolute;
top: auto;
left: auto;
z-index: 900;
margin-top: -16px;
width: 16px;
height: 16px;
min-width: 16px;
min-height: 16px;
background-image: url("images/cat_c.gif"); /* selectedPoi.gif */
background-size: 10px 16px;
}
/* ==================== */
.schedule .scheduleMap {
width: 150px;
height: 150px;
}
.schedule div.olControlPanZoom {
display: none;
}
.scheduleScaledMap .scheduleMap {
width: 200px;
height: 300px;
}
.scheduleScaledMap div.olControlPanZoom {
opacity: 0.2;
}
div.scheduleMap div.olControlAttribution,
div.scheduleMap div.olControlScaleLine {
font-family: Verdana;
font-size: 0.5em;
right: 1px;
bottom: 1px;
}
ul.ui-autocomplete {
max-height: 10em;
overflow-y:scroll;
overflow-x:hidden;
}
.poiPinPush {
background-image: url("images/cat_ab.png"); /* poi.png */
opacity: 0.6;
}
.poiPinPop {
background-image: url("images/cat_ac.png"); /* poi.png */
background-size: 10px 16px;
}
.poiPinLight {
background-image: url("images/cat_bc.png"); /* poi.png */
opacity: 0.3;
}
/* ==================== */
.scheduleAddresse {
width: 16em;
max-width: 16em;
min-height: 8em;
text-align: left;
}
.proposal {
border-width: 2px;
border-style: solid none;
border-color: orange;
}
div.scheduleTabForm div.warningPlace {
display: inline-block;
}
div.scheduleTabForm div.warning {
width: 16px;
height: 16px;
}
div.schedule table.long tr.proposal,
div.scheduleTabForm div.warning,
div.scheduleTabForm a.warning,
div.scheduleTabForm input.warning,
div.scheduleTabForm ul.warning {
background-image: url("images/warning.png") !important;
background-repeat: no-repeat !important;
}
div.scheduleTabForm input.warning {
border: 2px solid yellow !important;
background-position: right center !important;
}
div.scheduleAddresse {
}
div.scheduleAddresse.poiAdrLight {
background-color: #DDD;
}

205
syntax/block.php Normal file
View File

@ -0,0 +1,205 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (__DIR__.'/../../../').'/');
if (!defined ('DOKU_PLUGIN'))
define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
require_once (realpath (__DIR__.'/..').'/schedule.class.php');
require_once (realpath (__DIR__.'/..').'/scheduleRoot.class.php');
require_once (realpath (__DIR__.'/..').'/schedules.class.php');
// ============================================================
class syntax_plugin_schedule_block extends DokuWiki_Syntax_Plugin {
// ============================================================
function getType () { return 'substition'; }
function getPType () { return 'block'; }
function getSort () { return 299; }
function connectTo ($mode) {
$this->Lexer->addSpecialPattern ('\{\{schedule[^}]*\}\}', $mode, 'plugin_schedule_block');
}
// ============================================================
function handle ($match, $state, $pos, Doku_Handler $handler) {
switch ($state) {
case DOKU_LEXER_SPECIAL :
return array ($state, trim (substr ($match, 10, -2))); // "{{schedule" => 10 "}}" => 2
}
return false;
}
var $scheduleRoot;
var $schedules;
// ============================================================
function render ($mode, Doku_Renderer $renderer, $indata) {
$dumy = "";
if (empty($indata))
return false;
if ($mode != 'xhtml')
return false;
list ($instr, $data) = $indata;
switch ($instr) {
case DOKU_LEXER_SPECIAL :
$args = " ".$data." ";
if (preg_match_all ("#(\"[^\"]*\")* help (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
$renderer->doc .= $this->scheduleHelp ();
return true;
}
$this->scheduleRoot = new scheduleRoot ($this);
if (preg_match_all ("#(\"[^\"]*\")* admin (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
ob_start ();
echo '<div class="schedule">'.NL;
$this->scheduleRoot->manageAction ($_REQUEST['schd']);
$this->scheduleRoot->printForm ();
echo ' </div>';
$text = ob_get_contents ();
ob_end_clean ();
foreach ($this->scheduleRoot->message as $type => $msg)
$text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
$renderer->doc .= $text;
return true;
}
// namespace
global $ID;
$ns = getNS ($ID);
if (preg_match_all ("#^ >([^ ]*) (.*)#", $args, $dumy) > 0) {
$ns = $dumy[1][0];
$args = ' '.$dumy[2][0];
if (($ns == '*') || ($ns == ':'))
$ns = '';
elseif ($ns == '.')
$ns = getNS ($ID);
else
$ns = cleanID ($ns);
}
$mapId = "";
if (preg_match_all ('/("[^"]*")* id="(?<id>[0-9a-zA-Z_]+)" ("[^"]*")*/', strtolower ($args), $dumy) > 0)
for ($i = 0; $i < count ($dumy['id']); $i++)
$mapId = $dumy ['id'][$i];
$this->schedules = new schedules ($this->scheduleRoot, $ns);
$renderer->info ['cache'] = FALSE;
$request = false;
global $_REQUEST;
if ((isset ($_REQUEST['schd']) && isset ($_REQUEST['schd']['ns']) && $_REQUEST['schd']['ns'] == $ns) ||
(preg_match_all ("#(\"[^\"]*\")* (prop|form|ctrl) (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0))
$request = true;
if ($this->getConf ('useMap') && !is_dir (__DIR__.'/../../ol3'))
$renderer->doc .= '<p><a href="http://www.dokuwiki.org/plugin:ol3">ol3 plugin</a> not installed (see <a href="http://www.dokuwiki.org/plugin:schedule">doc</a>)</p>';
$cache = $this->schedules->readCache ($args);
if ($cache) {
$renderer->doc .= $cache;
return true;
}
$this->schedules->load ();
ob_start ();
if (preg_match_all ("#(\"[^\"]*\")* table (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
echo '<div class="schedule">'.NL;
$this->schedules->printScheduleCalendar (($mapId ? $mapId : "scheduleMapTable"), mktime (0, 0, 0, date ("n"), date ("j"), date ("Y")));
echo '</div>';
} else {
$formLevel = 0;
// form
if (preg_match_all ("#(\"[^\"]*\")* prop (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
$formLevel = max ($formLevel, 3);
if (preg_match_all ("#(\"[^\"]*\")* form (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
$formLevel = max ($formLevel, 2);
if (preg_match_all ("#(\"[^\"]*\")* ctrl (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
$formLevel = max ($formLevel, 1);
$this->scheduleDateFilters ($args);
$this->schedules->setFormLevel ($formLevel);
if ($request)
$this->schedules->manageAction ($_REQUEST['schd']);
$this->scheduleOtherFilters ($args);
$this->schedules->printScheduleList (($mapId ? $mapId : "scheduleMapList"));
}
$text = ob_get_contents ();
ob_end_clean ();
if (!$request)
$this->schedules->writeCache ($args, $text);
$this->schedules->writeSchedules ();
$this->schedules->writeProp ();
foreach ($this->scheduleRoot->message as $type => $msg)
$text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
$renderer->doc .= $text;
}
return true;
}
// ============================================================
function scheduleHelp () {
$url = "http://admin.parlenet.org/plugins/schedule/";
return
' <h1>Help Schedule</h1>'.NL.
' <ul>'.NL.
' <li><b>{{schedule</b> help <b>}}</b></li>'.NL.
' <li><b>{{schedule</b> admin <b>}}</b></li>'.NL.
' <li><b>{{schedule&gt;</b>nameSpace table [(<|=|>)(!|+-delta|jj/mm/aa|jj/mm/aaaa)] <b>}}</b></li>'.NL.
' <li><b>{{schedule&gt;</b>nameSpace id="id" [(<|=|>)(!|+-delta|jj/mm/aa|jj/mm/aaaa)] [#maxLine] [prop|form|ctrl] [(member|what|audience|noMember|noWhat|noAudience)="x1,x2,..."] <b>}}</b></li>'.NL.
' </ul>'.NL.
' <p><a class="urlextern" rel="nofollow" title="'.$url.'" href="'.$url.'">'.$url.'</a></p>'.NL;
}
// ============================================================
function scheduleDateFilters ($args) {
$before = "";
$date = "";
$after = "";
$periode = array ("<" => &$before, "=" => &$date, ">" => &$after);
$dumy = "";
// <! =! >!
if (preg_match_all ("#(\"[^\"]*\")*(?<op>[<=>])!(\"[^\"]*\")*#", $args, $dumy) > 0)
$periode [$dumy ['op'][0]] = "!";
// <+j =+j >+j <-j =-j >-j
if (preg_match_all ("#(\"[^\"]*\")*(?<op>[<=>])(?<delta>[+\-][0-9]*)(\"[^\"]*\")*#", $args, $dumy) > 0)
for ($i = 0; $i < count ($dumy['op']); $i++)
$periode [$dumy ['op'][$i]] = $dumy ['delta'][$i];
// <jj/mm/aaa =jj/mm/aaa >jj/mm/aaa
if (preg_match_all ("# (?<op>[<=>])(?<date>[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{1,4}) #", $args, $dumy) > 0)
for ($i = 0; $i < count ($dumy['op']); $i++)
$periode [$dumy ['op'][$i]] = $dumy ['date'][$i];
$this->schedules->setDateFilters ($before, $date, $after);
}
// ============================================================
function scheduleOtherFilters ($args) {
$max = "";
$filterNames = array ("member", "what", "audience", "noMember", "noWhat", "noAudience");
$filters = array ();
$grouped = "";
$dumy = "";
// maxline
if (preg_match_all ("/(\"[^\"]*\")*#(?<max>[0-9]+)(\"[^\"]*\")*/", strtolower ($args), $dumy) > 0)
for ($i = 0; $i < count ($dumy['max']); $i++)
$max = $dumy ['max'][$i];
// filters
foreach ($filterNames as $filterName) {
if (preg_match_all ("#".$filterName."=\"(?<".$filterName.">[^\"]*)\"#", $args, $dumy) > 0) {
$sep = "";
for ($i = 0; $i < count ($dumy[$filterName]); $i++) {
$filters [$filterName] .= $sep.trim (trim ($dumy[$filterName][$i]), ',');
$sep = ',';
}
}
}
// grouped
if (preg_match_all ("#(\"[^\"]*\")* (?<grouped>grouped|isolated) (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
$grouped = $dumy ['grouped'][0];
$this->schedules->setOtherFilters ($max, $filters, $grouped);
}
// ============================================================
}

136
syntax/display.php Normal file
View File

@ -0,0 +1,136 @@
<?php
/**
* @license http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
* @author Francois Merciol <dokuplugin@merciol.fr>
*
* Plugin Schedule: manage events per wiki @groups
*/
if (!defined ('DOKU_INC'))
define ('DOKU_INC', realpath (__DIR__.'/../../../').'/');
if (!defined ('DOKU_PLUGIN'))
define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
require_once (realpath (__DIR__.'/..').'/scheduleInseeCities.php');
// ============================================================
class syntax_plugin_schedule_display extends DokuWiki_Syntax_Plugin {
// ============================================================
function getInfo() {
return confToHash (__DIR__.'/../INFO.txt');
}
function getType () { return 'substition'; }
function getPType () { return 'block'; }
function getSort () { return 299; }
function connectTo ($mode) {
$this->Lexer->addEntryPattern ('<schedule[^>]*>', $mode, 'plugin_schedule_display');
}
function postConnect () {
$this->Lexer->addExitPattern ('</schedule>', 'plugin_schedule_display');
}
// ============================================================
function handle ($match, $state, $pos, Doku_Handler $handler) {
switch ($state) {
case DOKU_LEXER_ENTER:
return array ($state, trim (substr ($match, 8, -1))); // "<schedule" => 8 ">" => 1
case DOKU_LEXER_UNMATCHED:
return array ($state, $match);
case DOKU_LEXER_EXIT:
return array ($state, '');
}
return false;
}
// ============================================================
function render ($mode, Doku_Renderer $renderer, $indata) {
if (empty($indata))
return false;
if ($mode != 'xhtml')
return false;
list ($instr, $data) = $indata;
switch ($instr) {
case DOKU_LEXER_ENTER :
$args = strtolower (" ".$data." ");
$mapId = "scheduleMapPOI";
$width = "";
$height = "";
if (preg_match_all ('/("[^"]*")* id="(?<id>[0-9a-zA-Z_]+)" ("[^"]*")*/', $args, $dumy) > 0)
for ($i = 0; $i < count ($dumy['id']); $i++)
$mapId = $dumy ['id'][$i];
if (preg_match_all ('/.* width=(?<width>[0-9]+) .*/', $args, $dumy) > 0)
for ($i = 0; $i < count ($dumy['width']); $i++)
$width=' width="'.$dumy ['width'][$i].'"';
if (preg_match_all ('/.* height=(?<height>[0-9]+) .*/', $args, $dumy) > 0)
for ($i = 0; $i < count ($dumy['height']); $i++)
$height=' height="'.$dumy ['height'][$i].'"';
$renderer->doc .=
'<div class="wrap_left plugin_wrap">'.NL.
' <div class="schedulePOI scheduleScaledMap">'.NL;
if ($this->getConf ('useMap')) {
if (!is_dir (realpath (__DIR__.'/../../ol3')))
$renderer->doc .= '<p><a href="http://www.dokuwiki.org/plugin:ol3">ol3 plugin</a> not installed (see <a href="http://www.dokuwiki.org/plugin:schedule">doc</a>)</p>';
$renderer->doc .= ' <div id="'.$mapId.'" class="scheduleMap scheduleMapDisplay"'.$width.$height.'></div>'.NL;
}
break;
case DOKU_LEXER_UNMATCHED :
$data = trim ($data);
$address ="";
if ($this->getConf ('useMap'))
$renderer->doc .= '<span class="wrap_tip wrap_center wrap_centeralign">'.$this->getLang ('reactiveMap').'</span>'.NL;
$renderer->doc .= ' <ul style="display:none;" class="poiLatLon">'.NL;
global $scheduleInseeCities;
if (! empty ($data))
foreach (explode ("\n", preg_replace ('%~[eE][nN][dD]~%', "\n", $data)) as $line) {
$line = trim (preg_replace ("/#.*$/", "", $line));
if (!$line)
continue;
$line = preg_replace ("#\s+\|#", "|", $line);
$line = preg_replace ("#\|\s+#", "|", $line);
$line = trim ($line,'|');
list ($insee, $lat, $lon, $addr, $occ) = explode ("|", $line);
// XXX vérif des formats (nombres, ...)
if (!$insee || !$lon) {
if ($insee && $lat)
$renderer->doc .= ' <li lat="'.$insee.'" lon="'.$lat.'">56000</li>'.NL; // XXX position par defaut
continue;
}
if ($insee && $lat && $lon) {
$iter=$occ?$occ:1;
for ($i = 1; $i <= $iter; $i++)
$renderer->doc .= ' <li lat="'.$lat.'" lon="'.$lon.'">'.$insee.'</li>'.NL;
}
$addrHtml =
($addr ?
preg_replace ('%\\\\\\\\%', "<br/>", preg_replace ('%~[bB][rR]~%', "<br/>", $addr)) :
'<span class="wrap_round wrap_todo">'.$this->lang ('toComplet').'</span><br/>').' '.
// XXX all insee ???
(isset ($scheduleInseeCities[$insee]) ? $scheduleInseeCities[$insee][0] : $insee).'<br/>'.
(($addr && $lat && $lon) ?
'<span style="font-size:50%; background-color:#DDD;">(Lat. : '.$lat.' Long. : '.$lon.')</span>' :
'');
$address .=
'<div class="scheduleAddresse wrap_left plugin_wrap" location="('.$lat.'|'.$lon.')">'.NL.
' <p onMouseOver="javascript:scheduleHighlightLocation (\'('.$lat.'|'.$lon.')\')" onMouseOut="javascript:scheduleHighlightLocation (null)">'.$addrHtml.' </p>'.NL.
'</div>'.NL;
}
$renderer->doc .=
' </ul>'.NL.
' </div>'.NL.
'</div>'.NL.
$address.
'<div class="wrap_clear plugin_wrap"></div>'.NL;
break;
case DOKU_LEXER_EXIT :
break;
}
return true;
}
// ============================================================
}