1<?php
2/**
3 * Plugin datedifference: Display date difference
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Milosz Galazka <milosz@sleeplessbeastie.eu>
7 */
8
9if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
10if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
11
12/**
13 * All DokuWiki plugins to extend the parser/rendering mechanism
14 * need to inherit from this class
15 */
16class syntax_plugin_datedifference extends DokuWiki_Syntax_Plugin {
17
18   /**
19    * Get the type of syntax this plugin defines.
20    *
21    */
22    function getType(){
23        return 'substition';
24    }
25
26   /**
27    * Define how this plugin is handled regarding paragraphs.
28    *
29    */
30    function getPType(){
31        return 'normal';
32    }
33
34   /**
35    * Where to sort in?
36    *
37    * Doku_Parser_Mode_html	190
38    *  --> execute here <--
39    * Doku_Parser_Mode_code	200
40    */
41    function getSort(){
42        return 199;
43    }
44
45   /**
46    * Connect lookup pattern to lexer.
47    *
48    */
49    function connectTo($mode) {
50      $this->Lexer->addSpecialPattern('{{datedifference.*?}}',$mode,'plugin_datedifference');
51    }
52
53   /**
54    * Handler to prepare matched data for the rendering process.
55    *
56    */
57    function handle($match, $state, $pos, &$handler){
58	$data = array();
59
60	// default
61        $data['from']   = 'now';
62        $data['to']     = 'now + 1 minute';
63	$data['finmsg'] = '';
64	$data['arrow']  = 1;
65	$data['debug']  = 0;
66
67	// parse params
68	$provided_data = substr($match, 17, -2);
69	$arguments = explode (',', $provided_data);
70	foreach ($arguments as $argument) {
71		list($key, $value) = explode('=', $argument);
72		switch($key) {
73			case 'from':
74				$data['from'] = $value;
75				break;
76			case 'to':
77				$data['to'] = $value;
78				break;
79			case 'finmsg':
80				$data['finmsg'] = $value;
81				break;
82			case 'arrow':
83				switch(strtolower($value)) {
84					case 'yes':
85						$data['arrow'] = 1;
86						break;
87					default:
88						$data['arrow'] = 0;
89						break;
90				}
91				break;
92			case 'debug':
93				switch(strtolower($value)) {
94					case 'yes':
95						$data['debug'] = 1;
96						break;
97					default:
98						$data['debug'] = 0;
99						break;
100				}
101				break;
102		}
103	}
104        return $data;
105    }
106
107   /**
108    * Handle the actual output creation.
109    *
110    */
111    function render($mode, &$renderer, $data) {
112        if ($mode == 'xhtml'){
113            $renderer->doc .= $this->calculate_difference($data);
114            return true;
115        }
116        return false;
117    }
118
119   /**
120    * Calculate date and time difference
121    *
122    */
123    function calculate_difference($data) {
124	// set params
125	$date_from   = new DateTime($data['from']);
126	$date_to     = new DateTime($data['to']);
127	$date_finmsg = $data['finmsg'];
128	$date_arrow  = $data['arrow'];
129	$date_debug  = $data['debug'];
130
131	// use UTC internally
132	$date_from->setTimezone(new DateTimeZone('UTC'));
133	$date_to->setTimezone(new DateTimeZone('UTC'));
134
135	// debug information
136	if($date_debug == 1)
137		$debug  = "(" . $date_from->format(DateTime::RFC3339) . " &rarr; " . $date_to->format(DateTime::RFC3339) . ")";
138	else
139		$debug = "";
140
141	// arrows
142	// up   - target date is in the future
143	// down - target date is in the past
144	if($date_arrow == 1)
145		if($date_from < $date_to)
146			$arrow = "&uarr;";
147		else
148			$arrow = "&darr;";
149	else
150		$arrow = "";
151
152	// calculate date difference
153	if($date_to <= $date_from && !empty($date_finmsg)) {
154		$result = $date_finmsg;
155		$arrow = "";
156	} else {
157		// calculate interval
158		$interval = date_diff($date_from, $date_to);
159
160		// get details
161		$years    = $interval->format('%y');
162		$months   = $interval->format('%m');
163		$days     = $interval->format('%d');
164		$hours    = $interval->format('%h');
165		$minutes  = $interval->format('%i');
166
167		$result = "";
168		if($years > 1)
169			$result .= "$years years ";
170		elseif($years == 1)
171			$result .= "$years year ";
172
173		if($months > 1)
174			$result .= "$months months ";
175		elseif($months == 1)
176			$result .= "$months month ";
177
178		if($days > 1)
179			$result .= "$days days ";
180		elseif($days == 1)
181			$result .= "$days day ";
182
183		if($hours > 1)
184			$result .= "$hours hours ";
185		elseif($hours == 1)
186			$result .= "$hours hour ";
187
188		if($minutes > 1)
189			$result .= "$minutes minutes ";
190		elseif($minutes == 1)
191			$result .= "$minutes minute ";
192	}
193
194	// concatenate result, debug information and up/down arrow
195	$html = "<span class=\"datedifference\">$result $debug $arrow</span>";
196
197        return $html;
198    }
199}
200
201//Setup VIM: ex: et ts=4 enc=utf-8 :
202?>
203