1<?php
2/**
3 * @license    http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.html
4 * @author     Francois Merciol <dokuplugin@merciol.fr>
5 *
6 * Plugin Schedule: manage events per wiki @groups
7 */
8
9if (!defined ('DOKU_INC'))
10    define ('DOKU_INC', realpath (__DIR__.'/../../../').'/');
11if (!defined ('DOKU_PLUGIN'))
12    define ('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
13require_once(DOKU_PLUGIN.'syntax.php');
14
15require_once (realpath (__DIR__.'/..').'/schedule.class.php');
16require_once (realpath (__DIR__.'/..').'/scheduleRoot.class.php');
17require_once (realpath (__DIR__.'/..').'/schedules.class.php');
18
19// ============================================================
20class syntax_plugin_schedule_block extends DokuWiki_Syntax_Plugin {
21
22    // ============================================================
23    function getType () { return 'substition'; }
24    function getPType () { return 'block'; }
25    function getSort () { return 299; }
26    function connectTo ($mode) {
27        $this->Lexer->addSpecialPattern ('\{\{schedule[^}]*\}\}', $mode, 'plugin_schedule_block');
28    }
29
30    // ============================================================
31    function handle ($match, $state, $pos, Doku_Handler $handler) {
32        switch ($state) {
33        case DOKU_LEXER_SPECIAL :
34            return array ($state, trim (substr ($match, 10, -2))); // "{{schedule" => 10 "}}" => 2
35        }
36        return false;
37    }
38
39    var $scheduleRoot;
40    var $schedules;
41
42    // ============================================================
43    function render ($mode, Doku_Renderer $renderer, $indata) {
44        $dumy = "";
45        if (empty($indata))
46            return false;
47        if ($mode != 'xhtml')
48            return false;
49        list ($instr, $data) = $indata;
50        switch ($instr) {
51        case DOKU_LEXER_SPECIAL :
52            $args = " ".$data." ";
53            if (preg_match_all ("#(\"[^\"]*\")* help (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
54                $renderer->doc .= $this->scheduleHelp ();
55                return true;
56            }
57
58            $this->scheduleRoot = new scheduleRoot ($this);
59
60            if (preg_match_all ("#(\"[^\"]*\")* admin (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
61                ob_start ();
62                echo '<div class="schedule">'.NL;
63                $this->scheduleRoot->manageAction ($_REQUEST['schd']);
64                $this->scheduleRoot->printForm ();
65                echo '      </div>';
66                $text = ob_get_contents ();
67                ob_end_clean ();
68                foreach ($this->scheduleRoot->message as $type => $msg)
69                    $text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
70                $renderer->doc .= $text;
71                return true;
72            }
73
74            // namespace
75            global $ID;
76            $ns = getNS ($ID);
77            if (preg_match_all ("#^ >([^ ]*) (.*)#", $args, $dumy) > 0) {
78                $ns = $dumy[1][0];
79                $args = ' '.$dumy[2][0];
80                if (($ns == '*') || ($ns == ':'))
81                    $ns = '';
82                elseif ($ns == '.')
83                    $ns = getNS ($ID);
84                else
85                    $ns = cleanID ($ns);
86            }
87            $mapId = "";
88            if (preg_match_all ('/("[^"]*")* id="(?<id>[0-9a-zA-Z_]+)" ("[^"]*")*/', strtolower ($args), $dumy) > 0)
89                for ($i = 0; $i < count ($dumy['id']); $i++)
90                    $mapId = $dumy ['id'][$i];
91            $this->schedules = new schedules ($this->scheduleRoot, $ns);
92            $renderer->info ['cache'] = FALSE;
93            $request = false;
94            global $_REQUEST;
95            if ((isset ($_REQUEST['schd']) && isset ($_REQUEST['schd']['ns']) && $_REQUEST['schd']['ns'] == $ns) ||
96                (preg_match_all ("#(\"[^\"]*\")* (prop|form|ctrl) (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0))
97                $request = true;
98            if ($this->getConf ('useMap') && !is_dir (__DIR__.'/../../ol3'))
99                $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>';
100            $cache = $this->schedules->readCache ($args);
101            if ($cache) {
102                $renderer->doc .= $cache;
103                return true;
104            }
105            $this->schedules->load ();
106            ob_start ();
107            if (preg_match_all ("#(\"[^\"]*\")* table (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0) {
108                echo '<div class="schedule">'.NL;
109                $this->schedules->printScheduleCalendar (($mapId ? $mapId : "scheduleMapTable"), mktime (0, 0, 0, date ("n"), date ("j"), date ("Y")));
110                echo '</div>';
111            } else {
112                $formLevel = 0;
113                // form
114                if (preg_match_all ("#(\"[^\"]*\")* prop (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
115                    $formLevel = max ($formLevel, 3);
116                if (preg_match_all ("#(\"[^\"]*\")* form (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
117                    $formLevel = max ($formLevel, 2);
118                if (preg_match_all ("#(\"[^\"]*\")* ctrl (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
119                    $formLevel = max ($formLevel, 1);
120                $this->scheduleDateFilters ($args);
121                $this->schedules->setFormLevel ($formLevel);
122                if ($request)
123                    $this->schedules->manageAction ($_REQUEST['schd']);
124                $this->scheduleOtherFilters ($args);
125                $this->schedules->printScheduleList (($mapId ? $mapId : "scheduleMapList"));
126            }
127            $text = ob_get_contents ();
128            ob_end_clean ();
129            if (!$request)
130                $this->schedules->writeCache ($args, $text);
131
132            $this->schedules->writeSchedules ();
133            $this->schedules->writeProp ();
134            foreach ($this->scheduleRoot->message as $type => $msg)
135                $text = '<div class="'.$type.'">'.$msg.'</div>'.$text;
136            $renderer->doc .= $text;
137        }
138        return true;
139    }
140
141    // ============================================================
142    function scheduleHelp () {
143        $url = "http://admin.parlenet.org/plugins/schedule/";
144        return
145            '      <h1>Help Schedule</h1>'.NL.
146            '      <ul>'.NL.
147            '        <li><b>{{schedule</b> help <b>}}</b></li>'.NL.
148            '        <li><b>{{schedule</b> admin <b>}}</b></li>'.NL.
149            '        <li><b>{{schedule&gt;</b>nameSpace table [(<|=|>)(!|+-delta|jj/mm/aa|jj/mm/aaaa)] <b>}}</b></li>'.NL.
150            '        <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.
151            '      </ul>'.NL.
152            '      <p><a class="urlextern" rel="nofollow" title="'.$url.'" href="'.$url.'">'.$url.'</a></p>'.NL;
153    }
154
155    // ============================================================
156    function scheduleDateFilters ($args) {
157        $before = "";
158        $date = "";
159        $after = "";
160        $periode = array ("<" => &$before, "=" => &$date, ">" => &$after);
161        $dumy = "";
162        // <! =! >!
163        if (preg_match_all ("#(\"[^\"]*\")*(?<op>[<=>])!(\"[^\"]*\")*#", $args, $dumy) > 0)
164            $periode [$dumy ['op'][0]] = "!";
165        // <+j =+j >+j <-j =-j >-j
166        if (preg_match_all ("#(\"[^\"]*\")*(?<op>[<=>])(?<delta>[+\-][0-9]*)(\"[^\"]*\")*#", $args, $dumy) > 0)
167            for ($i = 0; $i < count ($dumy['op']); $i++)
168                $periode [$dumy ['op'][$i]] = $dumy ['delta'][$i];
169        // <jj/mm/aaa =jj/mm/aaa >jj/mm/aaa
170        if (preg_match_all ("# (?<op>[<=>])(?<date>[0-9]{1,2}[-/][0-9]{1,2}[-/][0-9]{1,4}) #", $args, $dumy) > 0)
171            for ($i = 0; $i < count ($dumy['op']); $i++)
172                $periode [$dumy ['op'][$i]] = $dumy ['date'][$i];
173        $this->schedules->setDateFilters ($before, $date, $after);
174    }
175
176    // ============================================================
177    function scheduleOtherFilters ($args) {
178        $max = "";
179        $filterNames = array ("member", "what", "audience", "noMember", "noWhat", "noAudience");
180        $filters = array ();
181        $grouped = "";
182        $dumy = "";
183
184        // maxline
185        if (preg_match_all ("/(\"[^\"]*\")*#(?<max>[0-9]+)(\"[^\"]*\")*/", strtolower ($args), $dumy) > 0)
186            for ($i = 0; $i < count ($dumy['max']); $i++)
187                $max = $dumy ['max'][$i];
188        // filters
189        foreach ($filterNames as $filterName) {
190            if (preg_match_all ("#".$filterName."=\"(?<".$filterName.">[^\"]*)\"#", $args, $dumy) > 0) {
191                $sep = "";
192                for ($i = 0; $i < count ($dumy[$filterName]); $i++) {
193                    $filters [$filterName] .= $sep.trim (trim ($dumy[$filterName][$i]), ',');
194                    $sep = ',';
195                }
196            }
197        }
198        // grouped
199        if (preg_match_all ("#(\"[^\"]*\")* (?<grouped>grouped|isolated) (\"[^\"]*\")*#", strtolower ($args), $dumy) > 0)
200            $grouped = $dumy ['grouped'][0];
201        $this->schedules->setOtherFilters ($max, $filters, $grouped);
202    }
203
204    // ============================================================
205}
206