1<?php
2/**
3 *
4 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
5 */
6if(!defined('DOKU_INC')) die();
7if(!defined('DOKU_META')) define('DOKU_META',DOKU_INC.'data/meta/newsfeed/');
8
9class helper_plugin_news extends Dokuwiki_Plugin {
10    var $wasUpdated = false;
11	var $header;
12	var $sub_feed = "";
13    var $has_permission = -1;
14    function getMethods(){
15        $result = array();
16
17        $result[] = array(
18                'name'   => 'pageUpdated',
19                'desc'   => 'Check if news for $ID is updated',
20                'params' => array(),
21                'return' => array('result' => 'bool')
22                );
23
24        $result[] = array(
25                'name'   => 'setUpdate',
26                'desc'   => 'set boolean to signal page was updated',
27                'params' => array(),
28                'return' => array()
29               );
30        $result[] = array(
31                'name'   => 'saveFeedData',
32                'desc'   => 'Save feed data for page',
33                'params' => array(),
34                'return' => array()
35               );
36
37       return $result;
38    }
39
40    /***
41     */
42    function set_permission($perm) {
43        $this->has_permission = $perm;
44    }
45    function has_permission() {
46        return $this->has_permission;
47    }
48
49    function pageUpdated(){
50        return $this->wasUpdated;
51    }
52    function setUpdate($ar = null){
53       if($ar) {
54        $this->header = $ar[0];
55        $this->sub_feed = trim($ar[1]);
56        }
57        $this->wasUpdated = true;
58
59    }
60   function setSubFeed($ns) {
61        $this->sub_feed = trim($ns);
62   }
63    function getMetaDirectory() {
64       if(preg_match("/notset/i", $this->sub_feed)) {
65          $this->sub_feed ='/';
66          return "newsfeed:";
67       }
68       return 'newsfeed:' .  $this->sub_feed . ':';
69    }
70    function getMetaFN($file,$ext) {
71          $ns = $this->getMetaDirectory();
72          $file = $ns . $file;
73          return metaFN($file, $ext);
74    }
75
76	function saveFeedData($id=null) {
77	   if(!$id) return;
78
79	    if(!$this->header) {
80	        $md_5  = $this->_parse_items($id);
81		}
82		elseif($this->header) {
83		   $md_5  = $this->_parse_headers($id) ;
84		}
85	   $metafile = $this->getMetaFN('pagedata', '.ser');
86
87	    $ar = $this->_readFile($metafile, true);
88
89	    if(!$md_5) {
90			if(isset($ar[$md_5])) {
91				unset($ar[$md_5]);
92				$this->_writeFile($metafile,$ar,true);
93			}
94
95			return;
96	   }
97	    $file_path = wikiFN($id);
98	   	$tm =  filemtime ($file_path);
99	   // update page db
100	    $result = array();
101	    $result['id'] = $id;
102	    $result['url'] = DOKU_URL . 'doku.php?id=' . $id;
103	    $result['time'] = $tm;
104	    $result['gmtime'] = gmdate('r',$tm);
105        if(empty($ar[$md_5]['create_time'])) {
106           $result['create_time'] = gmdate('r',$tm);
107        }
108        else $result['create_time'] = $ar[$md_5]['create_time'];
109		$result['header'] = $this->header;
110	    $ar[$md_5] = $result;
111
112	    $this->_writeFile($metafile,$ar,true);
113
114	}
115
116	function _parse_items($id) {
117		   // get page contents
118	    $data = file_get_contents(wikiFN($id));
119		$n = preg_match_all("#<news(.*?)>.*?(?=</news>)#ms", $data, $matches);
120		if($n == 0) return false;
121
122		$data = $matches[0];
123		$titles = $matches[1];
124		$feed_data = array();
125		for($i=0; $i<count($data); $i++) {
126			list($news,$title) = explode(':',$titles[$i]);
127			if(isset($title)) {
128				   $title = trim($title);
129			   }
130			if(isset($title) && $title) {
131			        $feed_data[$i]['title'] = $title;
132			  }
133			 else $feed_data[$i]['title'] = "News Item";
134			$data[$i] = preg_replace("#^\s*<news(.*?)>#","",$data[$i]);
135			$feed_data[$i]['item'] = $this->render_text($data[$i]);
136			$feed_data[$i]['name'] = 'rss_' . ($i+1);
137       }
138
139	   $md_5 = md5($id);
140       $metafile = $this->getMetaFN($md_5, '.gz');
141	   $this->_writeFile($metafile,$feed_data,true);
142       return $md_5;
143	}
144
145	function _parse_headers($id) {
146		$data = file_get_contents(wikiFN($id));
147
148    	$segs = $this->header;
149		$ar = preg_split("/(={" . $segs  . ",}.*?={" . $segs . ",})\s*\n/",$data, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
150        if(count($ar) == 0) return false;
151        array_shift($ar);  //removes ~~NEWSFEED.*?~~ and any text above first header
152
153		$feed_data = array();
154		for($i=0, $j=0; $i<count($ar); $i+=2, $j++) {
155		    $feed_data[$j]['title'] = str_replace('=',"",$ar[$i]);
156		    $feed_data[$j]['item'] = $this->render_text($ar[$i+1]);
157			$check=false;
158			$feed_data[$j]['name'] =  sectionID($ar[$i],$check);
159		}
160        $md_5 = md5($id);
161        $metafile = $this->getMetaFN($md_5, '.gz');
162	    $this->_writeFile($metafile,$feed_data,true);
163		return $md_5;
164    }
165
166	function _readFile($file, $ser=false) {
167	    $ret = io_readFile($file,$ser);
168		if($ser) {
169		  if(!$ret) return array();
170		  return unserialize($ret);
171		  }
172		return $ret;
173
174	}
175
176	function _writeFile($file,$data,$ser) {
177			if($ser) {
178			   $data = serialize($data);
179			}
180			io_saveFile($file,$data);
181	}
182    function ttl() {
183        return $this->getConf('ttl');
184    }
185}
186