* * 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" => "(?[0-9]{1,2})[ /-](?[0-9]{1,2})[ /-](?[0-9]{1,2})", "longScan" => "(?[0-9]{1,2})[ /-](?[0-9]{1,2})[ /-](?[0-9]{4})", "fieldName" => array ("d", "m", "Y"), "prettyPrint" => "d/m/Y", "dayMonth" => "d/m"), "mdY" => array ("shortScan" => "(?[0-9]{1,2})[ /-](?[0-9]{1,2})[ /-](?[0-9]{1,2})", "longScan" => "(?[0-9]{1,2})[ /-](?[0-9]{1,2})[ /-](?[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] .= '
'.NL; $this->message[$type] .= $text; } function startMessage ($type, $text) { if (isset ($this->message[$type])) $this->message[$type] = '
'.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', '
'.$text.'
'); } /* 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').'
'.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 ("#\+(?[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 ("#\-(?[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 ("#(?[0-9][0-9][0-9][0-9])(?[0-9][0-9])(?[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 ("#(?[0-9][0-9][0-9][0-9])(?[0-9][0-9])(?[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 '
'.NL. ' '.NL. ' '.NL. // XXX getLang () ' '.NL. ' '.NL. ' '.NL; $this->resetOddEven (); foreach ($list as $md5 => $item) { $nameSpace = $item ["nameSpace"]; $schedules = $item ["schedules"]; echo ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL. ' '.NL; $this->switchOddEven (); } echo ' '.NL. '
DescriptionValeurs
NameSpace'.$nameSpace.'
MD5'.$md5.'
Members'.count ($schedules->memberSchedules).'
Events'.count ($schedules->datedSchedules).'
Repeated'.count ($schedules->repeatedSchedules).'
Date
Vers
Action
'.NL. '
'.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 (); } } // ============================================================ }