summaryrefslogtreecommitdiff
path: root/platform/www/lib/plugins/meta/syntax.php
diff options
context:
space:
mode:
Diffstat (limited to 'platform/www/lib/plugins/meta/syntax.php')
-rw-r--r--platform/www/lib/plugins/meta/syntax.php205
1 files changed, 205 insertions, 0 deletions
diff --git a/platform/www/lib/plugins/meta/syntax.php b/platform/www/lib/plugins/meta/syntax.php
new file mode 100644
index 0000000..733e5b5
--- /dev/null
+++ b/platform/www/lib/plugins/meta/syntax.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * Meta Plugin: Sets metadata for the current page
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_meta extends DokuWiki_Syntax_Plugin
+{
+ function getType()
+ {
+ return 'substition';
+ }
+
+ function getSort()
+ {
+ return 99;
+ }
+
+ function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern('~~META:.*?~~',$mode,'plugin_meta');
+ }
+
+ /**
+ * Handle the match
+ */
+ public function handle($match, $state, $pos, Doku_Handler $handler)
+ {
+ // strip ~~META: from start and ~~ from end
+ $match = substr($match,7,-2);
+
+ $data = array();
+ $pairs = explode('&', $match);
+ foreach ($pairs as $pair) {
+ list($key, $value) = explode('=', $pair, 2);
+ list($key, $subkey) = explode(' ', $key, 2);
+ if (trim($subkey)) {
+ $data[trim($key)][trim($subkey)] = trim($value);
+ } else {
+ $data[trim($key)] = trim($value);
+ }
+ }
+ $data = array_change_key_case($data, CASE_LOWER);
+
+ return $data;
+ }
+
+ /**
+ * Create output
+ */
+ public function render($mode, Doku_Renderer $renderer, $data)
+ {
+ if ($mode == 'xthml') {
+ // don't output anything
+ return true;
+ } elseif ($mode == 'metadata') {
+ /** @var Doku_Renderer_metadata $renderer */
+
+ // do some validation / conversion for date metadata
+ if (isset($data['date'])) {
+ if (is_array($data['date'])) {
+ foreach ($data['date'] as $key => $date) {
+ $date = $this->convertDate(trim($date));
+ if (!$date) {
+ unset($data['date'][$key]);
+ } else {
+ $data['date'][$key] = $date;
+ }
+ }
+ } else {
+ unset($data['date']);
+ }
+ }
+
+ // now merge the arrays
+ $protected = array('description', 'date', 'contributor');
+ foreach ($data as $key => $value) {
+
+ // be careful with sub-arrays of $meta['relation']
+ if ($key == 'relation') {
+ foreach ($value as $subkey => $subvalue) {
+ if ($subkey == 'media') {
+ $renderer->meta[$key][$subkey][cleanID($subvalue)] = @file_exists(mediaFN($subvalue));
+ } elseif ($subkey == 'firstimage') {
+ /* The metadata renderer overrides the first image value with its internal value at the end.
+ Therefore the only thing we can do is setting this internal value by calling _firstimage.
+ This fails if there has already been a first image saved. */
+ $renderer->_firstimage($subvalue);
+ } else {
+ // for everything else assume that we have a page id
+ $renderer->meta[$key][$subkey][cleanID($subvalue)] = page_exists($subvalue);
+ }
+ }
+ } elseif (in_array($key, $protected)) {
+ // be careful with some sensitive arrays of $meta
+ if (is_array($renderer->meta) && is_array($value) && array_key_exists($key, $renderer->meta)) {
+ $renderer->meta[$key] = array_merge($renderer->meta[$key], (array)$value);
+ } else {
+ $renderer->meta[$key] = $value;
+ }
+ } else {
+ // no special treatment for the rest
+ $renderer->meta[$key] = $value;
+ }
+ }
+ }
+ }
+
+ /**
+ * converts YYYY-MM-DD[ hh:mm:ss][ -> [YYYY-MM-DD ]hh:mm:ss] to PHP timestamps
+ */
+ private function convertDate($date)
+ {
+ list($start, $end) = explode('->', $date, 2);
+
+ if (!$end) {
+ // single date
+ list($date, $time) = explode(' ', trim($start), 2);
+ if (!preg_match('/\d{4}\-\d{2}\-\d{2}/', $date)) {
+ return false;
+ }
+ $time = $this->autocompleteTime($time);
+ return strtotime($date.' '.$time);
+ } else {
+ // duration
+
+ // start
+ list($startdate, $starttime) = explode(' ', trim($start), 2);
+ $startdate = $this->autocompleteDate($startdate);
+ if (!$startdate) {
+ return false;
+ }
+ $starttime = $this->autocompleteTime($starttime);
+
+ // end
+ list($enddate, $endtime) = explode(' ', trim($end), 2);
+ if (!trim($endtime)) {
+ // only time given
+ $end_date = $this->autocompleteDate($enddate, true);
+ if (!$end_date) {
+ $endtime = $this->autocompleteTime($enddate, true);
+ $enddate = $startdate;
+ } else {
+ // only date given
+ $enddate = $end_date;
+ $endtime = '23:59:59';
+ }
+ } else {
+ $enddate = $this->autocompleteDate($enddate, true);
+ if (!$enddate) {
+ $enddate = $startdate;
+ }
+ $endtime = $this->autocompleteTime($endtime, true);
+ }
+
+ $start = strtotime($startdate.' '.$starttime);
+ $end = strtotime($enddate.' '.$endtime);
+ if (!$start || !$end) {
+ return false;
+ }
+ return array('start' => $start, 'end' => $end);
+ }
+ }
+
+ private function autocompleteDate($date, $end=false)
+ {
+ if (!preg_match('/^\d{4}\-\d{2}\-\d{2}$/', $date)) {
+ if (preg_match('/^\d{4}\-\d{2}$/', $date)) {
+ // we don't know which month
+ return ($end) ? $date.'-28' : $date.'-01';
+ } elseif (preg_match('/^\d{4}$/', $date)) {
+ return ($end) ? $date.'-12-31' : $date.'-01-01';
+ } else {
+ return false;
+ }
+ } else {
+ return $date;
+ }
+ }
+
+ private function autocompleteTime($time, $end=false)
+ {
+ if (!preg_match('/^\d{2}:\d{2}:\d{2}$/', $time)) {
+ if (preg_match('/^\d{2}:\d{2}$/', $time)) {
+ return ($end) ? $time.':59' : $time.':00';
+ } elseif (preg_match('/^\d{2}$/', $time)) {
+ return ($end) ? $time.':59:59': $time.':00:00';
+ } else {
+ return ($end) ? '23:59:59' : '00:00:00';
+ }
+ } else {
+ return $time;
+ }
+ }
+}
+// vim:ts=4:sw=4:et:enc=utf-8: