1<?php
2/**
3 * Plugin hcalendar: Using Microformat Calendar
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Juergen A. Lamers <jaloma.ac@googlemail.com>
7 * @seealso    (http://jaloma.ac.googlepages.com/plugin:hcalendar)
8 * @seealso    (http://microformats.org/wiki/internet-explorer-extensions)
9 * @seealso    (http://microformats.org/wiki/firefox-extensions)
10 */
11
12if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14require_once(DOKU_PLUGIN.'syntax.php');
15require_once(DOKU_PLUGIN.'hcalendar/syntax/helper.php');
16require_once(DOKU_PLUGIN.'hcalendar/syntax/hcal_renderer_helper.php');
17/**
18 * All DokuWiki plugins to extend the parser/rendering mechanism
19 * need to inherit from this class
20 */
21class syntax_plugin_hcalendar_hcal2 extends DokuWiki_Syntax_Plugin {
22
23  /**
24   * default parameters of the jalbum tag
25   */
26  var $dflt = array(
27		    'start_date' => 'off',
28		    'start_time' => 'off',
29		    'end_date' => 'off',
30			'end_time' => 'off',
31		    'summary' => 'off',
32		    'location' => 'off',
33			'inline' => 'off',
34		    );
35  var $rendering = true;
36  var $is_inline = false;
37
38  function getInfo(){
39    return array(
40		 'author' => 'Juergen A. Lamers',
41		 'email'  => 'jaloma.ac@googlemail.com',
42		 'date'   => @file_get_contents(DOKU_PLUGIN . 'hcalendar/VERSION'),
43		 'name'   => 'HCalendar HCal2 Plugin',
44		 'desc'   => 'Adds a HCalendar Items
45                     syntax: <hcal startdate="yyyy/mm/dd" starthour="hh:mm:ss"
46					 enddate="yyyy/mm/dd" endhour="hh:mm:ss" summary="" location=""></hcal>
47                     See: http://microformats.org/wiki/',
48		 'url'    => 'http://www.dokuwiki.org/plugin:hcalendar',
49		 );
50  }
51
52  function getType() { return  'substition'; } //'formatting';}//
53  function getSort() { return 351; }
54  function getPType() { return 'normal'; }
55//  function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
56  function connectTo($mode) {
57//    $this->Lexer->addSpecialPattern('<hcal ?[^>\n]*>.*?</hcal>',$mode,'plugin_hcalendar_hcal2');
58  $this->Lexer->addEntryPattern('<hcal.*?>(?=.*?</hcal>)',$mode,'plugin_hcalendar_hcal2');
59
60  }
61    function postConnect() {
62    $this->Lexer->addExitPattern('</hcal>','plugin_hcalendar_hcal2');
63  }
64
65	function matchLength() {
66		return strlen("<hcal");
67	}
68    /**
69     * Handle the match
70     */
71  function handle($match, $state, $pos, &$handler){
72    // break matched cdata into its components
73    switch ($state) {
74      case DOKU_LEXER_ENTER :
75	  	list($str_params, $background) = preg_split("/<\//u", substr($match, $this->matchLength()+1, -1), 2);
76    	$cinfo = $this->_extract_params($str_params);
77    	return array($state, $cinfo);
78      case DOKU_LEXER_UNMATCHED :  return array($state, $match);
79      case DOKU_LEXER_EXIT :       return array($state, '');
80	}
81	return array();
82  }
83
84	/**
85	 * Create output
86	 */
87	function render($mode, & $renderer, $match) {
88	global $conf;
89	    setlocale(LC_ALL,$this->getConf('locale'));
90		if ($mode == 'xhtml') {
91			list($state, $data) = $match;
92            switch ($state) {
93              case DOKU_LEXER_ENTER :
94		  		$renderer->doc .= $this->_connectData($data);
95                break;
96              case DOKU_LEXER_UNMATCHED :
97			  	if ($this->rendering) {
98			  		$r = p_render('xhtml',p_get_instructions($data),$info);
99//			  		$renderer->doc .= $renderer->_xmlEntities($data);
100		            $renderer->doc .= $r;
101				}
102				$renderer->nocache();
103			  	break;
104              case DOKU_LEXER_EXIT :
105			  	if ($this->rendering) {
106			  		if (!$this->is_inline) {
107			  		$renderer->doc .= helper_plugin_hcal::buildTextEnd('tag_vevent');
108					}
109				}
110			  	break;
111            }
112		  return true;
113		}
114		return false;
115	}
116
117	function _connectData($data) {
118		$mm_start=  $ss_start= '00';
119	  	$yy_start =$mth_start= $dy_start =
120			$hh_start=
121	 		$tm_start=
122	  		$yy_end=   $mth_end=   $dy_end=
123	  		$hh_end=   $mm_end=    $ss_end=
124	  		$tm_end= '';
125		  $this->rendering = true;
126		  $start_date = $data['start_date'];
127		  if ($start_date != '' && $start_date != 'off') {
128		  	$time = strtotime($start_date);
129		  	list($yy_start, $mth_start, $dy_start) = hcal_parseDateEntry($start_date);
130
131		  	$start_time = $data['start_time'];
132			if ($start_time == 'hh:mm') { $start_time = 'off';}
133		  	if ($start_time != 'off') {
134				list($hh_start, $mm_start, $ss_start) = hcal_parseTimeEntrie($start_time);
135				if ($mm_start == null || $mm_start == '') {
136					$mm_start = '00';
137				}
138				if ($ss_start == null || $ss_start == '') {
139					$ss_start = '00';
140				}
141		  		$time = strtotime($start_date." ".$hh_start.":".$mm_start);
142		  		$tm_start = $hh_start.":".$mm_start;
143		  	}
144			$dt_start = $time;
145		  }
146		  $end_date = $data['end_date'];
147 		  if ($end_date == 'yyyy/mm/dd') { $end_date = 'off';}
148
149		  if ($end_date != 'off') {
150		  	$time = strtotime($end_date);
151		  	list($yy_end, $mth_end, $dy_end) = hcal_parseDateEntry($end_date);
152
153		  	$end_time = $data['end_time'];
154			if ($end_time == 'hh:mm') { $end_time = 'off';}
155		  	if ($end_time != 'off') {
156				list($hh_end, $mm_end, $ss_end) =  hcal_parseTimeEntrie($end_time);
157				if ($mm_end == null || $mm_end == '') {
158					$mm_end = '00';
159				}
160				if ($ss_end == null || $ss_end == '') {
161					$ss_end = '00';
162				}
163		  		$time = strtotime($end_date." ".$hh_end.":".$mm_end);
164		  		$tm_end = $hh_end.":".$mm_end;
165		  	}
166			$dt_end = $time;
167		  }
168		  $location = $data['location'];
169		  if ($location == 'off') { $location = '';}
170		  $summary = $data['summary'];
171		  if ($summary == 'off') { $summary = '';}
172		$this->is_inline = $data['inline'] != 'off';
173		  if (!$this->is_inline) {
174    	  if ($this->getConf('filterdate') == true) {
175      		$dt_now = strtotime("now");
176      		if ($dt_start < $dt_now && $dt_end < $dt_now) {
177			  $this->rendering = false;
178			  return "";
179			}
180    	  }
181		  }
182		  if ($this->is_inline) { $tag_prefix = 'i';} else { $tag_prefix ='';}
183		  $txt = helper_plugin_hcal::buildText(
184		     $yy_start,$mth_start,$dy_start,$hh_start,$mm_start,$ss_start,$dt_start,
185		     $yy_end  ,$mth_end  ,$dy_end  ,$hh_end,  $mm_end,  $ss_end,  $dt_end,
186		     $summary ,$location, $this->is_inline,
187		     $tag_prefix.'tag_vevent',
188		     $tag_prefix.'tag_summary',
189		     $tag_prefix.'tag_dtstart',
190		     $tag_prefix.'tag_dtend',
191		     $tag_prefix.'tag_location',
192		     $tag_prefix.'tag_uid',
193		     $tag_prefix.'tag_dtstamp',
194			 !$this->is_inline
195		     );
196			 return $txt;
197}
198  /**
199   * extract parameters for the googlemap from the parameter string
200   *
201   * @param   string    $str_params   string of key="value" pairs
202   * @return  array                   associative array of parameters key=>value
203   */
204  function _extract_params($str_params) {
205    $param = array();
206    preg_match_all('/(\w*)="(.*?)"/us',$str_params,$param,PREG_SET_ORDER);
207    if (sizeof($param) == 0) {
208      preg_match_all("/(\w*)='(.*?)'/us",$str_params,$param,PREG_SET_ORDER);
209    }
210    // parse match for instructions, break into key value pairs
211    $gmap = $this->dflt;
212    foreach($param as $kvpair) {
213      list($match,$key,$val) = $kvpair;
214//    $key = strtolower($key);
215      if (isset($gmap[$key])) $gmap[$key] = $val;
216    }
217
218    return $gmap;
219  }
220
221} // class
222