5 * @copyright Copyright (c) 2008, Bellière Ludovic
6 * @license http://opensource.org/licenses/mit-license.php MIT license
9 class News_Node_Exception
extends Exception
{}
12 * @author Bellière Ludovic
15 * @copyright Copyright (c) 2008, Bellière Ludovic
16 * @license http://opensource.org/licenses/mit-license.php MIT license
18 class news_node
implements Countable
{
20 public $_dateFormat = 'r';
21 public $_dateFormatMinimal = 'd.m.o';
22 protected $_content = array();
23 protected $_count = 0;
24 private $_filters = array();
25 private $_requiered_keynode;
28 private $_searchString;
30 const DEFAULT_VIEW
= 0xEFFFF69C;
31 const SEARCH_VIEW
= 0xE925030B;
32 const ARCHIVE_VIEW
= 0x9A2B1B01;
34 const FORMAT_LIGHT
= 'formatLight';
35 const FORMAT_FULL
= 'formatFull';
37 public $_default_view_options = array(
38 'sql_limit' => '0, 10',
41 public function __construct() {
42 $this->_view
= self
::DEFAULT_VIEW
;
45 public function setView($view) {
49 public function setPDO (PDO
$pdo) {
54 * Set the date format. If not used, default values will be used.
55 * @param string $formatFull Used for the full news view.
56 * @param string $formatLight Used for the light news view.
58 public function setDateFormat ($formatFull, $formatLight) {
59 $this->_dateFormat
= $formatFull;
60 $this->_dateFormatMinimal
= $formatLight;
64 * Get a row by his id.
65 * If raw is true, get the row without escapement.
67 public function get ($key, $raw=false) {
69 foreach ($key as $parent_key => $child_key) {
70 if (array_key_exists($child_key,$this->_content
[$parent_key])) {
71 return (!is_array($this->_content
[$parent_key]) && $raw == true) ? self
::escape($this->_content
[$parent_key]) : $this->_content
[$parent_key];
76 if (array_key_exists($key,$this->_content
)) {
77 return (!is_array($this->_content
[$parent_key]) && $raw == true) ? self
::escape($this->_content
[$parent_key]) : $this->_content
[$parent_key];
82 * Add a filter function for the node $node
84 * @param string $function
86 * @param integer $place
88 * @throws News_Node_Exception for invalid type / not a function
90 public function add_filter($function,$node='all',$place=null) {
91 if (is_callable($function,true)) {
92 if (is_null($place)) {
93 $this->_filters
[$node][] = $function;
95 if (!is_int($place)) {
96 throw new News_Node_Exception('The param `place\' is not an integer');
99 if (isset($this->_filters
[$place])) {
100 $for = (is_array($function)) ?
$function[0].'->'.$function[1] : $function ;
101 trigger_error('Replacement of filter number '.$place.' for content <em>'.$for.'</em>',E_USER_NOTICE
);
104 $this->_filters
[$node][$place] = $function;
107 throw new News_Node_Exception('The <em>function</em> parameter "'.$function.'" is not callable.');
111 public function render($reload=false, $paginate=false, $format='formatFull') {
113 self
::getNews($reload,$paginate);
114 } catch (News_Node_Exception
$e) {
115 die ($e->getMessage());
119 $txt = self
::reloadCache($format);
121 foreach ($this->_content
as $node) {
122 $txt.= $node['data'];
129 * Searches news for needle.
130 * @param string $needle The searched value.
132 public function search($needle) {
133 $this->_searchString
= $needle;
134 self
::setView(self
::SEARCH_VIEW
);
138 protected function getDate($timestamp,$context) {
140 case self
::FORMAT_LIGHT
:
141 $date = date($this->_dateFormatMinimal
,$timestamp);
143 case self
::FORMAT_FULL
:
144 $date = date($this->_dateFormat
,$timestamp);
150 protected function add_nodes(array $content) {
151 foreach ($content as $node) {
152 if (!isset($this->_content
['n-'.$node['id']])) {
153 $this->_content
['n-'.$node['id']] = $node;
159 protected function escape ($content,$tag) {
160 foreach($this->_filters
as $node => $filters) {
161 if ($node == 'all' ||
$tag == $node) {
162 foreach ($filters as $filter) {
163 $content = call_user_func_array($filter,array(&$content));
171 * Fetch all data from cache or database.
173 private function getNews ($reload=false,$paginate=false) {
175 $cacheData = scandir(CACHE_PATH
);
176 // custom action for ARCHIVE_VIEW
177 if ($this->_view
== self
::ARCHIVE_VIEW
) {
178 $elements = $paginate->elements
;
179 $limit = explode(', ',str_replace('LIMIT ','',$paginate->get_sql_limit_statement()));
182 foreach ($cacheData as $file) {
183 if ($file[0] == '.') {
186 $id = substr($file,2);
187 // custom action for ARCHIVE_VIEW
188 if ($this->_view
== self
::ARCHIVE_VIEW
) {
189 if ($id-1 < intval($limit[0])) {
192 if ($id-1 > intval($limit[1])) {
197 if ($format == self
::FORMAT_LIGHT
) {
200 $allnodes[] = array (
203 'data' => file_get_contents(CACHE_PATH
.$file)
206 if (!isset($allnodes)) {
207 $this->_content
[]['data'] = '<p>no news in database</p>';
209 $allnodes = array_reverse($allnodes);
210 self
::add_nodes($allnodes);
213 switch ($this->_view
) {
214 case self
::DEFAULT_VIEW
:
215 $PDOStatement = $this->_PDO
->query('SELECT * FROM news ORDER BY id DESC LIMIT '.$this->_default_view_options
['sql_limit']);
217 case self
::SEARCH_VIEW
:
218 $PDOStatement = $this->_PDO
->query('SELECT * FROM news WHERE text LIKE \'%'.addslashes($this->_searchString
).'%\' ORDER BY id DESC');
220 case self
::ARCHIVE_VIEW
:
221 if ($format == self
::FORMAT_FULL
) {
222 $PDOStatement = $this->_PDO
->query('SELECT * FROM news ORDER BY id DESC LIMIT '.$this->_default_view_options
['sql_limit']);
224 if ($paginate instanceof paginate
) {
225 $PDOStatement = $this->_PDO
->query('SELECT * FROM news ORDER BY id DESC '.$paginate->get_sql_limit_statement());
227 throw new News_Node_Exception('$paginate is not a instance of paginate object.');
232 throw new News_Node_Exception('View \''.$this->_view
.'\' not registered.');
234 self
::add_nodes($PDOStatement->fetchAll());
239 * Write all files in cache directory
241 private function reloadCache($format='full') {
243 $searchedTags = array('%key%', '%title%', '%text%', '%author%');
244 foreach($this->_content
as $key => $data) {
245 $replaceString = array(
247 self
::escape($data['title'],'title'),
248 self
::escape($data['text'],'text'),
249 self
::escape($data['author'],'author'),
251 $replaceDate = array(
252 self
::getDate($data['postedon'],self
::FORMAT_FULL
),
253 (isset($data['editdon'])) ? self
::getDate($data['editdon'],self
::FORMAT_LIGHT
) : 'Never'
255 $txt_tmp = file_get_contents('templates/_newsFull.tpl');
256 $txt_tmp = str_replace($searchedTags, $replaceString,$txt_tmp);
257 $txt_tmp = str_replace(array('%postdate%', '%editdate%'),$replaceDate,$txt_tmp);
259 $min_tmp = file_get_contents('templates/_newsMinimal.tpl');
260 $min_tmp = str_replace($searchedTags, $replaceString,$min_tmp);
261 $min_tmp = str_replace(array('%postdate%', '%editdate%'),$replaceDate,$min_tmp);
263 file_put_contents(CACHE_PATH
.$key.'.minimal',$min_tmp);
264 file_put_contents(CACHE_PATH
.$key,$txt_tmp);
266 if ($format == self
::FORMAT_FULL
) {
272 unset($txt_tmp,$min_tmp);
281 public function __get($key) {
282 return $this->_content
[$key];
285 protected function __isset($name) {
286 return isset($this->_content
[$name]);
289 public function count() {
290 return $this->_count
;