OSDN Git Service

MERGE: リビジョン1894〜1990
[nucleus-jp/nucleus-next.git] / nucleus / libs / BLOG.php
1 <?php
2
3 /*
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5  * Copyright (C) 2002-2012 The Nucleus Group
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * (see nucleus/documentation/index.html#license for more info)
12  */
13 /**
14  * A class representing a blog and containing functions to get that blog shown
15  * on the screen
16  *
17  * @license http://nucleuscms.org/license.txt GNU General Public License
18  * @copyright Copyright (C) 2002-2009 The Nucleus Group
19  * @version $Id: BLOG.php 1624 2012-01-09 11:36:20Z sakamocchi $
20  */
21
22 if ( !function_exists('requestVar') ) exit;
23 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
24
25 class Blog
26 {
27         // blog id
28         public $blogid;
29
30         // After creating an object of the blog class, contains true if the BLOG object is
31         // valid (the blog exists)
32         public $isValid;
33
34         // associative array, containing all blogsettings (use the get/set functions instead)
35         private $settings;
36         
37         // ID of currently selected category
38         private $selectedcatid;
39
40         /**
41          * Blog::_\construct()
42          * Creates a new BLOG object for the given blog
43          *
44          * @param       integer $id     blogid
45          * @return      void
46          */
47         public function __construct($id)
48         {
49                 global $catid;
50                 
51                 $this->blogid = (integer) $id;
52                 $this->readSettings();
53                 $this->setSelectedCategory($catid);
54                 return;
55         }
56         
57         /**
58          * Blog::readLog()
59          * Shows the given amount of items for this blog
60          *
61          * @param       string  $template       String representing the template _NAME_ (!)
62          * @param       integer $amountEntries  amount of entries to show
63          * @param       integer $startpos       offset from where items should be shown (e.g. 5 = start at fifth item)
64          * @return      integer amount of items shown
65          */
66         public function readLog($template, $amountEntries, $offset = 0, $startpos = 0)
67         {
68                 return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
69         }
70         
71         /**
72          * Blog::showArchive()
73          * Shows an archive for a given month
74          *
75          * @param       integer $year           year
76          * @param       integer $month          month
77          * @param       string  $template       String representing the template name to be used
78          * @return      void
79          */
80         public function showArchive($templatename, $year, $month=0, $day=0)
81         {
82                 // create extra where clause for select query
83                 if ( $day == 0 && $month != 0 )
84                 {
85                         $timestamp_start = mktime(0,0,0,$month,1,$year);
86                         // also works when $month==12
87                         $timestamp_end = mktime(0,0,0,$month+1,1,$year);
88                 }
89                 elseif ( $month == 0 )
90                 {
91                         $timestamp_start = mktime(0,0,0,1,1,$year);
92                         // also works when $month==12
93                         $timestamp_end = mktime(0,0,0,12,31,$year);
94                 }
95                 else
96                 {
97                         $timestamp_start = mktime(0,0,0,$month,$day,$year);
98                         $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
99                 }
100                 $extra_query = " and i.itime>=%s and i.itime<%s";
101                 $extra_query = sprintf($extra_query, DB::formatDateTime($timestamp_start), DB::formatDateTime($timestamp_end));
102                 
103                 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
104                 return;
105         }
106         
107         /**
108          * Blog::setSelectedCategory()
109          * Sets the selected category by id (only when category exists)
110          * 
111          * @param       integer $catid  ID for category
112          * @return      void
113          */
114         public function setSelectedCategory($catid)
115         {
116                 if ( $this->isValidCategory($catid) || (intval($catid) == 0) )
117                 {
118                         $this->selectedcatid = intval($catid);
119                 }
120                 return;
121         }
122         
123         /**
124          * Blog::setSelectedCategoryByName()
125          * Sets the selected category by name
126          * 
127          * @param       string  $catname        name of category
128          * @return      void
129          */
130         public function setSelectedCategoryByName($catname)
131         {
132                 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
133                 return;
134         }
135         
136         /**
137          * Blog::getSelectedCategory()
138          * Returns the selected category
139          * 
140          * @param       void
141          * @return      integer
142          */
143         public function getSelectedCategory()
144         {
145                 return $this->selectedcatid;
146         }
147         
148         /**
149          * Shows the given amount of items for this blog
150          *
151          * @param       string  $template               string representing the template _NAME_ (!)
152          * @param       integer $amountEntries  amount of entries to show (0 = no limit)
153          * @param       string  $extraQuery             extra conditions to be added to the query
154          * @param       string  $highlight              contains a query that should be highlighted
155          * @param       integer $comments               1=show comments 0=don't show comments
156          * @param       integer $dateheads              1=show dateheads 0=don't show dateheads
157          * @param       integer $offset                 offset
158          * @return      integer amount of items shown
159          */
160         private function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0)
161         {
162                 $query = $this->getSqlBlog($extraQuery);
163                 
164                 if ( $amountEntries > 0 )
165                 {
166                         // $offset zou moeten worden:
167                         // (($startpos / $amountentries) + 1) * $offset ... later testen ...
168                         $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
169                 }
170                 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
171         }
172         
173         /**
174          * Blog::showUsingQuery()
175          * Do the job for readLogAmmount
176          * 
177          * @param       string  $templateName   template name
178          * @param       string  $query                  string for query
179          * @param       string  $highlight              string to be highlighted
180          * @param       integer $comments               the number of comments
181          * @param       boolean $dateheads              date header is needed or not
182          * @return      integer the number of rows as a result of mysql query
183          */
184         private function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1)
185         {
186                 global $CONF, $manager, $currentTemplateName;
187                 
188                 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
189                 if ( $lastVisit != 0 )
190                 {
191                         $lastVisit = $this->getCorrectTime($lastVisit);
192                 }
193                 
194                 // set templatename as global variable (so plugins can access it)
195                 $currentTemplateName = $templateName;
196                 $template =& $manager->getTemplate($templateName);
197                 
198                 // create parser object & action handler
199                 $handler = new ItemActions($this);
200                 $handler->setTemplate($template);
201                 $handler->setHighlight($highlight);
202                 $handler->setLastVisit($lastVisit);
203                 $handler->setShowComments($comments);
204                 
205                 $parser = new Parser($handler);
206                 
207                 // execute query
208                 $items = DB::getResult($query);
209                 
210                 // loop over all items
211                 $old_date = 0;
212                 foreach ( $items as $item )
213                 {
214                         // string timestamp -> unix timestamp
215                         $item['timestamp'] = strtotime($item['itime']);
216                         
217                         // action handler needs to know the item we're handling
218                         $handler->setCurrentItem($item);
219                         
220                         // add date header if needed
221                         if ( $dateheads )
222                         {
223                                 $new_date = date('dFY', $item['timestamp']);
224                                 if ( $new_date != $old_date )
225                                 {
226                                         // unless this is the first time, write date footer
227                                         $timestamp = $item['timestamp'];
228                                         if ( $old_date != 0 )
229                                         {
230                                                 $oldTS = strtotime($old_date);
231                                                 $data = array('blog' => &$this, 'timestamp' => $oldTS);
232                                                 $manager->notify('PreDateFoot', $data);
233                                                 
234                                                 if ( !in_array('DATE_FOOTER', $template) || empty($template['DATE_FOOTER']) )
235                                                 {
236                                                         $tmp_footer = '';
237                                                 }
238                                                 else
239                                                 {
240                                                         $tmp_footer = i18n::formatted_datetime($template['DATE_FOOTER'], $oldTS);
241                                                 }
242                                                 $parser->parse($tmp_footer);
243                                                 $manager->notify('PostDateFoot', $data);
244                                         }
245                                         
246                                         $data = array('blog' => &$this, 'timestamp' => $timestamp);
247                                         $manager->notify('PreDateHead', $data);
248                                         
249                                         // note, to use templatvars in the dateheader, the %-characters need to be doubled in
250                                         // order to be preserved by strftime
251                                         if ( !in_array('DATE_HEADER', $template) || empty($template['DATE_HEADER']) )
252                                         {
253                                                 $tmp_header = '';
254                                         }
255                                         else
256                                         {
257                                                 $tmp_header = i18n::formatted_datetime($template['DATE_HEADER'], $timestamp);
258                                         }
259                                         $parser->parse($tmp_header);
260                                         $manager->notify('PostDateHead', $data);
261                                 }
262                                 $old_date = $new_date;
263                         }
264                         
265                         // parse item
266                         $parser->parse($template['ITEM_HEADER']);
267                         $data = array('blog' => &$this, 'item' => &$item);
268                         $manager->notify('PreItem', $data);
269                         $parser->parse($template['ITEM']);
270                         $manager->notify('PostItem', $data);
271                         $parser->parse($template['ITEM_FOOTER']);
272                 }
273                 
274                 $numrows = $items->rowCount();
275                 
276                 // add another date footer if there was at least one item
277                 if ( ($numrows > 0) && $dateheads )
278                 {
279                         $data = array('blog' => &$this, 'timestamp' => strtotime($old_date));
280                         $manager->notify('PreDateFoot', $data);
281                         $parser->parse($template['DATE_FOOTER']);
282                         $manager->notify('PostDateFoot', $data);
283                 }
284                 
285                 $items->closeCursor();
286                 return $numrows;
287         }
288         
289         /**
290          * Blog::showOneitem()
291          * Simplified function for showing only one item
292          * 
293          * @param       integer $itemid         ID for item
294          * @param       array   $template       template for item
295          * @param       string  $highlight      string for highlight
296          * @return      integer 1
297          */
298         public function showOneitem($itemid, $template, $highlight)
299         {
300                 $extraQuery = ' and inumber=' . intval($itemid);
301                 
302                 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
303         }
304         
305         /**
306          * Blog::addItem()
307          * Adds an item to this blog
308          * 
309          * @param       integer         $catid  ID for category
310          * @param       string          $title  ID for 
311          * @param       string          $body   text for body
312          * @param       string          $more   text for more
313          * @param       integer         $blogid ID for blog
314          * @param       integer         $authorid       ID for author
315          * @param       timestamp       $timestamp      UNIX timestamp for post
316          * @param       boolean         $closed opened or closed
317          * @param       boolean         $draft  draft or not
318          * @param       boolean         $posted posted or not
319          * @return      integer ID for added item
320          */
321         function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1')
322         {
323                 global $manager;
324                 
325                 $blogid         = (integer) $blogid;
326                 $authorid       = (integer) $authorid;
327                 $title          = $title;
328                 $body           = $body;
329                 $more           = $more;
330                 $catid          = intval($catid);
331                 
332                 // convert newlines to <br />
333                 if ( $this->convertBreaks() )
334                 {
335                         $body = addBreaks($body);
336                         $more = addBreaks($more);
337                 }
338
339                 if ( $closed != '1' )
340                 {
341                         $closed = '0';
342                 }
343                 if ( $draft != '0' )
344                 {
345                         $draft = '1';
346                 }
347                 
348                 if ( !$this->isValidCategory($catid) )
349                 {
350                         $catid = $this->getDefaultCategory();
351                 }
352                 
353                 $isFuture = 0;
354                 if ( $timestamp > $this->getCorrectTime() )
355                 {
356                         $isFuture = 1;
357                 }
358                 
359                 $timestamp = date('Y-m-d H:i:s',$timestamp);
360
361                 $data = array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => $this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid);
362                 $manager->notify('PreAddItem', $data);
363                 
364                 $ititle = DB::quoteValue($title);
365                 $ibody = DB::quoteValue($body);
366                 $imore = DB::quoteValue($more);
367                 $timestamp = DB::formatDateTime(strtotime($timestamp));
368                 
369                 $query = "INSERT INTO %s (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) VALUES (%s, %s, %s, %d, %d, %s, %s, %s, %s, %s)";
370                 $query = sprintf($query, sql_table('item'), $ititle, $ibody, $imore, $blogid, $authorid, $timestamp, $closed, $draft, $catid, $posted);
371                 DB::execute($query);
372                 $itemid = DB::getInsertId();
373
374                 $data = array('itemid' => $itemid);
375                 $manager->notify('PostAddItem', $data);
376                 
377                 if ( !$draft )
378                 {
379                         $this->updateUpdateFile();
380                 }
381                 // send notification mail
382                 if ( !$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem() )
383                 {
384                         $this->sendNewItemNotification($itemid, $title, $body);
385                 }
386                 return $itemid;
387         }
388         
389         /**
390          * Blog::sendNewItemNotification()
391          * Send a new item notification to the notification list
392          * 
393          * @param       string  $itemid ID of the item
394          * @param       string  $title  title of the item
395          * @param       string  $body   body of the item
396          * @return      void
397          */
398         public function sendNewItemNotification($itemid, $title, $body)
399         {
400                 global $CONF, $member;
401                 
402                 $ascii = Entity::anchor_footnoting($body);
403                 
404                 $message = _NOTIFY_NI_MSG . " \n";
405                 $temp = parse_url($CONF['Self']);
406                 if ( $temp['scheme'] )
407                 {
408                         $message .= Link::create_item_link($itemid) . "\n\n";
409                 }
410                 else
411                 {
412                         $tempurl = $this->getURL();
413                         if ( i18n::substr($tempurl, -1) == '/' || i18n::substr($tempurl, -4) == '.php' )
414                         {
415                                 $message .= $tempurl . '?itemid=' . $itemid . "\n\n";
416                         }
417                         else
418                         {
419                                 $message .= $tempurl . '/?itemid=' . $itemid . "\n\n";
420                         }
421                 }
422                 $message .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
423                 $message .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
424                 $message .= NOTIFICATION::get_mail_footer();
425                 
426                 $subject = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
427                 
428                 $from = $member->getNotifyFromMailAddress();
429                 
430                 NOTIFICATION::mail($this->getNotifyAddress(), $subject, $message, $from, i18n::get_current_charset());
431                 return;
432         }
433         
434         /**
435          * Blog::createNewCategory()
436          * Creates a new category for this blog
437          *
438          * @param       string  $catName                name of the new category. When empty, a name is generated automatically (starting with newcat)
439          * @param       string  $catDescription description of the new category. Defaults to 'New Category'
440          * @return      integer ID for new category on success. 0 on failure
441          */
442         public function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC)
443         {
444                 global $member, $manager;
445                 
446                 if ( !$member->blogAdminRights($this->blogid) )
447                 {
448                         return 0;
449                 }
450                 
451                 // generate
452                 if ( $catName == '' )
453                 {
454                         $catName = _CREATED_NEW_CATEGORY_NAME;
455                         $i = 1;
456                         
457                         $res = DB::getResult('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->blogid);
458                         while ( $res->rowCount() > 0 )
459                         {
460                                 $i++;
461                                 $res = DB::getResult('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->blogid);
462                         }
463                         
464                         $catName = $catName . $i;
465                 }
466                 
467                 $data = array(
468                         'blog'                  => &$this,
469                         'name'                  => &$catName,
470                         'description'   => $catDescription
471                 );
472                 $manager->notify('PreAddCategory', $data);
473                 
474                 $query = "INSERT INTO %s (cblog, cname, cdesc) VALUES (%d, %s, %s)";
475                 $query = sprintf($query, sql_table('category'), (integer) $this->blogid, DB::quoteValue($catName), DB::quoteValue($catDescription));
476                 DB::execute($query);
477                 $catid = DB::getInsertId();
478                 
479                 $data = array(
480                         'blog'                  => &$this,
481                         'name'                  => $catName,
482                         'description'   => $catDescription,
483                         'catid'                 => $catid
484                 );
485                 $manager->notify('PostAddCategory', $data);
486                 
487                 return $catid;
488         }
489         
490         /**
491          * Blog::search()
492          * Searches all months of this blog for the given query
493          *
494          * @param       string  $query                  search query
495          * @param       array   $template               template to be used (__NAME__ of the template)
496          * @param       integer $amountMonths   max amount of months to be search (0 = all)
497          * @param       integer $maxresults             max number of results to show
498          * @param       integer $startpos               offset
499          * @return      amount of hits found
500          */
501         public function search($query, $template, $amountMonths, $maxresults, $startpos) {
502                 global $CONF, $manager;
503                 
504                 $highlight      = '';
505                 $sqlquery       = $this->getSqlSearch($query, $amountMonths, $highlight);
506                 
507                 if ( $sqlquery == '' )
508                 {
509                         // no query -> show everything
510                         $extraquery = '';
511                         $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
512                 }
513                 else
514                 {
515                         // add LIMIT to query (to split search results into pages)
516                         if ( intval($maxresults > 0) )
517                         {
518                                 $sqlquery .= ' LIMIT ' . intval($startpos) . ',' . intval($maxresults);
519                         }
520                         
521                         // show results
522                         $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
523                         
524                         // when no results were found, show a message
525                         if ( $amountfound == 0 )
526                         {
527                                 $template =& $manager->getTemplate($template);
528                                 $vars = array(
529                                         'query'         => Entity::hsc($query),
530                                         'blogid'        => $this->blogid
531                                 );
532                                 echo Template::fill($template['SEARCH_NOTHINGFOUND'], $vars);
533                         }
534                 }
535                 return $amountfound;
536         }
537         
538         /**
539          * Blog::getSqlSearch()
540          * Returns an SQL query to use for a search query
541          * No LIMIT clause is added. (caller should add this if multiple pages are requested)
542          *
543          * @param       string  $query                  search query
544          * @param       integer $amountMonths   amount of months to search back. Default = 0 = unlimited
545          * @param       string  $mode                   either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
546          * @return      string  $highlight              words to highlight (out parameter)
547          * @return      string  either a full SQL query, or an empty string (if querystring empty)
548          */
549         public function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
550         {
551                 $searchclass = new Search($query);
552                 
553                 $highlight       = $searchclass->inclusive;
554                 
555                 // if querystring is empty, return empty string
556                 if ( $searchclass->inclusive == '' )
557                 {
558                         return '';
559                 }
560                 
561                 $where  = $searchclass->boolean_sql_where('ititle,ibody,imore');
562                 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
563                 
564                 // get list of blogs to search
565                 $blogs          = $searchclass->blogs;  // array containing blogs that always need to be included
566                 $blogs[]        = $this->blogid;                // also search current blog (duh)
567                 $blogs          = array_unique($blogs); // remove duplicates
568                 $selectblogs = '';
569                 if ( count($blogs) > 0 )
570                 {
571                         $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
572                 }
573                 
574                 if ( $mode == '' )
575                 {
576                         $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, i.itime, i.imore as more, i.icat as catid, i.iclosed as closed,
577                                 m.mname as author, m.mrealname as authorname, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl,
578                                 c.cname as category';
579                         
580                         if ( $select )
581                         {
582                                 $query .= ', '.$select. ' as score ';
583                         }
584                 }
585                 else
586                 {
587                         $query = 'SELECT COUNT(*) as result ';
588                 }
589                 
590                 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
591                                 . ' WHERE i.iauthor=m.mnumber'
592                                 . ' and i.icat=c.catid'
593                                 // exclude drafts
594                                 . ' and i.idraft=0'
595                                 . $selectblogs
596                                         // don't show future items
597                                 . ' and i.itime<=' . DB::formatDateTime($this->getCorrectTime())
598                                 . ' and '.$where;
599                 
600                 // take into account amount of months to search
601                 if ( $amountMonths > 0 )
602                 {
603                         $localtime = getdate($this->getCorrectTime());
604                         $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
605                         $query .= ' and i.itime>' . DB::formatDateTime($timestamp_start);
606                 }
607                 
608                 if ( $mode == '' )
609                 {
610                         if ( $select )
611                         {
612                                 $query .= ' ORDER BY score DESC';
613                         }
614                         else
615                         {
616                                 $query .= ' ORDER BY i.itime DESC ';
617                         }
618                 }
619                 
620                 return $query;
621         }
622         
623         /**
624          * Blog::getSqlBlog()
625          * Returns the SQL query that's normally used to display the blog items on the index type skins
626          * No LIMIT clause is added. (caller should add this if multiple pages are requested)
627          *
628          * @param       string  $extraQuery     extra query string
629          * @param       string  $mode           either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
630          * @return      string  either a full SQL query, or an empty string
631          */
632         public function getSqlBlog($extraQuery, $mode = '')
633         {
634                 if ( $mode == '' )
635                 {
636                         $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author,
637                                 m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail,
638                                 m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
639                 }
640                 else
641                 {
642                         $query = 'SELECT COUNT(*) as result ';
643                 }
644                 
645                 $query  .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
646                                 . ' WHERE i.iblog='.$this->blogid
647                                 . ' and i.iauthor=m.mnumber'
648                                 . ' and i.icat=c.catid'
649                                 . ' and i.idraft=0' // exclude drafts
650                                 . ' and i.itime<=' . DB::formatDateTime($this->getCorrectTime()); // don't show future items
651                 
652                 if ( $this->selectedcatid )
653                 {
654                         $query .= ' and i.icat=' . $this->selectedcatid . ' ';
655                 }
656                 
657                 $query .= $extraQuery;
658                 
659                 if ( $mode == '' )
660                 {
661                         $query .= ' ORDER BY i.itime DESC';
662                 }
663                 return $query;
664         }
665         
666         /**
667          * Blog::showArchiveList()
668          * Shows the archivelist using the given template
669          * 
670          * @param       string  $template       template name
671          * @param       string  $mode   year/month/day
672          * @param       integer $limit  limit of record count
673          * @return      void
674          */
675         public function showArchiveList($template, $mode = 'month', $limit = 0)
676         {
677                 global $CONF, $catid, $manager;
678                 
679                 if ( !isset ($linkparams) )
680                 {
681                         $linkparams = array();
682                 }
683                 
684                 if ( $catid )
685                 {
686                         $linkparams = array('catid' => $catid);
687                 }
688                 
689                 $template =& $manager->getTemplate($template);
690                 $listitem['blogid'] = $this->blogid;
691                 
692                 if ( !array_key_exists('ARCHIVELIST_HEADER', $template) || !$template['ARCHIVELIST_HEADER'] )
693                 {
694                         $tplt = '';
695                 }
696                 else
697                 {
698                         $tplt = $template['ARCHIVELIST_HEADER'];
699                 }
700                 
701                 echo Template::fill($tplt, $listitem);
702                 
703                 $query = 'SELECT itime, SUBSTRING(itime,1,4) AS Year, SUBSTRING(itime,6,2) AS Month, SUBSTRING(itime,9,2) AS Day'
704                                 . ' FROM '.sql_table('item')
705                                 . ' WHERE iblog=' . $this->blogid
706                                 . ' AND itime <=' . DB::formatDateTime($this->getCorrectTime()) // don't show future items!
707                                 . ' AND idraft=0'; // don't show draft items
708                 
709                 if ( $catid )
710                 {
711                         $query .= ' and icat=' . intval($catid);
712                 }
713                 
714                 $query .= ' GROUP BY Year';
715                 if ( $mode == 'month' || $mode == 'day' )
716                 {
717                         $query .= ', Month';
718                 }
719                 if ( $mode == 'day' )
720                 {
721                         $query .= ', Day';
722                 }
723                 
724                 $query .= ' ORDER BY itime DESC';
725                 
726                 if ( $limit > 0 )
727                 {
728                         $query .= ' LIMIT ' . intval($limit);
729                 }
730                 
731                 $res = DB::getResult($query);
732                 foreach ( $res as $current )
733                 {
734                         /* string time -> unix timestamp */
735                         $current['itime'] = strtotime($current['itime']);
736                         
737                         if ( $mode == 'day' )
738                         {
739                                 $archivedate = date('Y-m-d',$current['itime']);
740                                 $archive['day'] = date('d',$current['itime']);
741                                 $listitem['day'] = date('d',$current['itime']);
742                                 $listitem['month'] = date('m',$current['itime']);
743                                 $archive['month'] = $listitem['month'];
744                         }
745                         elseif ( $mode == 'year' )
746                         {
747                                 $archivedate = date('Y',$current['itime']);
748                                 $listitem['day'] = '';
749                                 $listitem['month'] = '';
750                                 $archive['day'] = '';
751                                 $archive['month'] = '';
752                         }
753                         else
754                         {
755                                 $archivedate = date('Y-m',$current['itime']);
756                                 $listitem['month'] = date('m',$current['itime']);
757                                 $archive['month'] = $listitem['month'];
758                                 $listitem['day'] = '';
759                                 $archive['day'] = '';
760                         }
761                         
762                         $listitem['year'] = date('Y',$current['itime']);
763                         $archive['year'] = $listitem['year'];
764                         $listitem['archivelink'] = Link::create_archive_link($this->blogid,$archivedate,$linkparams);
765
766                         $data = array('listitem' => &$listitem);
767                         $manager->notify('PreArchiveListItem', $data);
768                         
769                         $temp = Template::fill($template['ARCHIVELIST_LISTITEM'],$listitem);
770                         echo i18n::formatted_datetime($temp, $current['itime']);
771                         return;
772                 }
773                 
774                 $res->closeCursor();
775                 
776                 if ( !array_key_exists('ARCHIVELIST_FOOTER', $template) || !$template['ARCHIVELIST_FOOTER'] )
777                 {
778                         $tplt = '';
779                 }
780                 else
781                 {
782                         $tplt = $template['ARCHIVELIST_FOOTER'];
783                 }
784                 
785                 echo Template::fill($tplt, $listitem);
786                 return;
787         }
788         
789         /**
790          * Blog::showCategoryList()
791          * Shows the list of categories using a given template
792          * 
793          * @param       string  $template       Template Name
794          * @return      void
795          */
796         public function showCategoryList($template)
797         {
798                 global $CONF, $archive, $archivelist, $manager;
799                 
800                 /*
801                  * determine arguments next to catids
802                  * I guess this can be done in a better way, but it works
803                  */
804                 $linkparams = array();
805                 if ( $archive )
806                 {
807                         $blogurl = Link::create_archive_link($this->blogid, $archive, '');
808                         $linkparams['blogid'] = $this->blogid;
809                         $linkparams['archive'] = $archive;
810                 }
811                 else if ( $archivelist )
812                 {
813                         $blogurl = Link::create_archivelist_link($this->blogid, '');
814                         $linkparams['archivelist'] = $archivelist;
815                 }
816                 else
817                 {
818                         $blogurl = Link::create_blogid_link($this->blogid, '');
819                         $linkparams['blogid'] = $this->blogid;
820                 }
821                 
822                 $template =& $manager->getTemplate($template);
823                 
824                 //: Change: Set nocatselected variable
825                 if ( $this->selectedcatid )
826                 {
827                         $nocatselected = 'no';
828                 }
829                 else
830                 {
831                         $nocatselected = 'yes';
832                 } 
833                 
834                 $args = array(
835                         'blogid'        => $this->blogid,
836                         'blogurl'       => $blogurl,
837                         'self'          => $CONF['Self'],
838                         'catiscurrent'  => $nocatselected, // Change: Set catiscurrent template variable for header
839                         'currentcat'    => $nocatselected 
840                 );
841                 
842                 /* output header of category list item */
843                 if ( !array_key_exists('CATLIST_HEADER', $template) || empty($template['CATLIST_HEADER']) )
844                 {
845                         echo Template::fill(NULL, $args);
846                 }
847                 else
848                 {
849                         echo Template::fill($template['CATLIST_HEADER'], $args);
850                 }
851                 
852                 $query = "SELECT catid, cdesc as catdesc, cname as catname FROM %s WHERE cblog=%d ORDER BY cname ASC;";
853                 $query = sprintf($query, sql_table('category'), (integer) $this->blogid);
854                 $res = DB::getResult($query);
855                 
856                 foreach ( $res as $row )
857                 {
858                         $args = array(
859                                 'catid' => $row['catid'],
860                                 'name'  => $row['catname'],
861                                 'extra' => $linkparams
862                         );
863                         
864                         $row['blogid']          = $this->blogid;
865                         $row['blogurl']         = $blogurl;
866                         $row['catlink']         = Link::create_link('category', $args);
867                         $row['self']            = $CONF['Self'];
868                         
869                         // this gives catiscurrent = no when no category is selected.
870                         $row['catiscurrent'] = 'no';
871                         $row['currentcat'] = 'no';
872                         
873                         if ( $this->selectedcatid )
874                         {
875                                 if ( $this->selectedcatid == $row['catid'] )
876                                 {
877                                         $row['catiscurrent']    = 'yes';
878                                         $row['currentcat']              = 'yes';
879                                 }
880                         }
881                         else
882                         {
883                                 global $itemid;
884                                 if ( (integer) $itemid && $manager->existsItem((integer) $itemid, 0, 0) )
885                                 {
886                                         $iobj   =& $manager->getItem($itemid, 0, 0);
887                                         $cid    = $iobj['catid'];
888                                         
889                                         if ( $cid == $row['catid'] )
890                                         {
891                                                 $row['catiscurrent']    = 'yes';
892                                                 $row['currentcat']              = 'yes';
893                                         }
894                                 }
895                         }
896
897                         $data = array('listitem' => &$row);
898                         $manager->notify('PreCategoryListItem', $data);
899                         
900                         if ( !array_key_exists('CATLIST_LISTITEM', $template) || empty($template['CATLIST_LISTITEM']))
901                         {
902                                 echo Template::fill(NULL, $row);
903                         }
904                         else
905                         {
906                                 echo Template::fill($template['CATLIST_LISTITEM'], $row);
907                         }
908                 }
909                 
910                 $res->closeCursor();
911                 
912                 $args = array(
913                         'blogid'                => $this->blogid,
914                         'blogurl'               => $blogurl,
915                         'self'                  => $CONF['Self'],
916                         'catiscurrent'  => $nocatselected, //: Change: Set catiscurrent template variable for footer
917                         'currentcat'    => $nocatselected
918                 );
919                 
920                 if ( !array_key_exists('CATLIST_FOOTER', $template) || empty($template['CATLIST_FOOTER']))
921                 {
922                         echo Template::fill(NULL, $args);
923                 }
924                 else
925                 {
926                         echo Template::fill($template['CATLIST_FOOTER'], $args);
927                 }
928                 
929                 return;
930         }
931         
932         /**
933          * Blog::showBlogList()
934          * Shows a list of all blogs in the system using a given template
935          * ordered by number, name, shortname or description
936          * in ascending or descending order
937          * 
938          * @param       string  $template       tempalte name
939          * @param       string  $bnametype      bname/bshortname
940          * @param       string  $orderby        string for 'ORDER BY' SQL
941          * @param       string  $direction      ASC/DESC
942          * @return      void
943          */
944         static public function showBlogList($template, $bnametype, $orderby, $direction)
945         {
946                 global $CONF, $manager;
947                 
948                 switch ( $orderby )
949                 {
950                         case 'number':
951                                 $orderby='bnumber';
952                                 break;
953                         case 'name':
954                                 $orderby='bname';
955                                 break;
956                         case 'shortname':
957                                 $orderby='bshortname';
958                                 break;
959                         case 'description':
960                                 $orderby='bdesc';
961                                 break;
962                         default:
963                                 $orderby='bnumber';
964                                 break;
965                 }
966                 
967                 $direction=strtolower($direction);
968                 switch ( $direction )
969                 {
970                         case 'asc':
971                                 $direction='ASC';
972                                 break;
973                         case 'desc':
974                                 $direction='DESC';
975                                 break;
976                         default:
977                                 $direction='ASC';
978                                 break;
979                 }
980                 
981                 $template =& $manager->getTemplate($template);
982                 
983                 if ( array_key_exists('BLOGLIST_HEADER', $template) && !empty($template['BLOGLIST_HEADER']) )
984                 {
985                         $vars = array(
986                                 'sitename'      => $CONF['SiteName'],
987                                 'siteurl'       => $CONF['IndexURL']
988                         );
989                         
990                         echo Template::fill($template['BLOGLIST_HEADER'], $vars);
991                 }
992                 
993                 if ( array_key_exists('BLOGLIST_LISTITEM', $template) && !empty($template['BLOGLIST_LISTITEM']) )
994                 {
995                         $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
996                         $res = DB::getResult($query);
997                         
998                         foreach ( $res as $row )
999                         {
1000                                 $list = array();
1001                                 $list['bloglink'] = Link::create_blogid_link($row['bnumber']);
1002                                 $list['blogdesc'] = $row['bdesc'];
1003                                 $list['blogurl'] = $row['burl'];
1004                                 
1005                                 if ( $bnametype == 'shortname' )
1006                                 {
1007                                         $list['blogname'] = $row['bshortname'];
1008                                 }
1009                                 else
1010                                 {
1011                                         /* all other cases */
1012                                         $list['blogname'] = $row['bname'];
1013                                 }
1014
1015                                 $data = array('listitem' => &$list);
1016                                 $manager->notify('PreBlogListItem', $data);
1017                                 
1018                                 echo Template::fill($template['BLOGLIST_LISTITEM'], $list);
1019                         }
1020                         
1021                         $res->closeCursor();
1022                 }
1023                 
1024                 
1025                 if ( array_key_exists('BLOGLIST_FOOTER', $template) && !empty($template['BLOGLIST_FOOTER']) )
1026                 {
1027                         $vars = array(
1028                                 'sitename' => $CONF['SiteName'],
1029                                 'siteurl' => $CONF['IndexURL']
1030                         );
1031                         echo Template::fill($template['BLOGLIST_FOOTER']);
1032                 }
1033                 return;
1034         }
1035         
1036         /**
1037          * Blog::readSettings()
1038          * Read the blog settings
1039          * 
1040          * @param       void
1041          * @return      void
1042          */
1043         public function readSettings()
1044         {
1045                 $query =  'SELECT * FROM %s WHERE bnumber=%d;';
1046                 $query = sprintf($query, sql_table('blog'), (integer) $this->blogid);
1047                 $res = DB::getResult($query);
1048                 
1049                 $this->isValid = ($res->rowCount() > 0);
1050                 if ( $this->isValid )
1051                 {
1052                         $this->settings = $res->fetch(PDO::FETCH_ASSOC);
1053                 }
1054                 return;
1055         }
1056         
1057         /**
1058          * Blog::writeSettings()
1059          * Write the blog settings
1060          */
1061         public function writeSettings()
1062         {
1063                 // (can't use floatval since not available prior to PHP 4.2)
1064                 $offset = $this->getTimeOffset();
1065                 if ( !is_float($offset) )
1066                 {
1067                         $offset = (integer) $offset;
1068                 }
1069                 
1070                 $query =  'UPDATE '.sql_table('blog')
1071                            . ' SET bname=' . DB::quoteValue($this->getName()) . ','
1072                            . '     bshortname='. DB::quoteValue($this->getShortName()) . ','
1073                            . '     bcomments='. intval($this->commentsEnabled()) . ','
1074                            . '     bmaxcomments=' . intval($this->getMaxComments()) . ','
1075                            . '     btimeoffset=' . $offset . ','
1076                            . '     bpublic=' . intval($this->isPublic()) . ','
1077                            . '     breqemail=' . intval($this->emailRequired()) . ','
1078                            . '     bconvertbreaks=' . intval($this->convertBreaks()) . ','
1079                            . '     ballowpast=' . intval($this->allowPastPosting()) . ','
1080                            . '     bnotify=' . DB::quoteValue($this->getNotifyAddress()) . ','
1081                            . '     bnotifytype=' . intval($this->getNotifyType()) . ','
1082                            . '     burl=' . DB::quoteValue($this->getURL()) . ','
1083                            . '     bupdate=' . DB::quoteValue($this->getUpdateFile()) . ','
1084                            . '     bdesc=' . DB::quoteValue($this->getDescription()) . ','
1085                            . '     bdefcat=' . intval($this->getDefaultCategory()) . ','
1086                            . '     bdefskin=' . intval($this->getDefaultSkin()) . ','
1087                            . '     bincludesearch=' . intval($this->getSearchable())
1088                            . ' WHERE bnumber=' . intval($this->blogid);
1089                 DB::execute($query);
1090                 return;
1091         }
1092         
1093         /**
1094          * Blog::updateUpdatefile()
1095          * Update the update file if requested
1096          * 
1097          * @param       void
1098          * @return      void
1099          */
1100         public function updateUpdatefile()
1101         {
1102                 if ( $this->getUpdateFile() )
1103                 {
1104                         $f_update = fopen($this->getUpdateFile(), 'w');
1105                         fputs($f_update,$this->getCorrectTime());
1106                         fclose($f_update);
1107                 }
1108                 return;
1109         }
1110         
1111         /**
1112          * Blog::isValidCategory()
1113          * Check if a category with a given catid is valid
1114          * 
1115          * @param       integer $catid  ID for category
1116          * @return      boolean exists or not
1117          */
1118         public function isValidCategory($catid)
1119         {
1120                 $query = 'SELECT * FROM %s WHERE cblog=%d and catid=%d;';
1121                 $query = sprintf($query, sql_table('category'), (integer) $this->blogid, (integer) $catid);
1122                 $res = DB::getResult($query);
1123                 return ($res->rowCount() != 0);
1124         }
1125         
1126         /**
1127          * Blog::getCategoryName()
1128          * Get the category name for a given catid
1129          * 
1130          * @param       integer $catid  ID for category
1131          * @return      string  name of category
1132          */
1133         public function getCategoryName($catid)
1134         {
1135                 $query = 'SELECT cname FROM %s WHERE cblog=%d and catid=%d;';
1136                 $query = sprintf($query, sql_table('category'), (integer) $this->blogid, (integer) $catid);
1137                 $res = DB::getValue($query);
1138                 return $res;
1139         }
1140         
1141         /**
1142          * Blog::getCategoryDesc()
1143          * Get the category description for a given catid
1144          * 
1145          * @param $catid
1146          *      category id
1147          */
1148         public function getCategoryDesc($catid)
1149         {
1150                 $query = 'SELECT cdesc FROM %s WHERE cblog=%d and catid=%d;';
1151                 $query = sprintf($query, sql_table('category'), (integer) $this->blogid, (integer) $catid);
1152                 $res = DB::getValue($query);
1153                 return $res;
1154         }
1155         
1156         /**
1157          * Blog::getCategoryIdFromName
1158          * Get the category id for a given category name
1159          * 
1160          * @param       string  $name   category name
1161          * @return      ID for category
1162          */
1163         public function getCategoryIdFromName($name)
1164         {
1165                 $query = 'SELECT catid FROM %s WHERE cblog=%d and cname=%s;';
1166                 $query = sprintf($query, sql_table('category'), (integer) $this->blogid, DB::quoteValue($name));
1167                 
1168                 $res = DB::getValue();
1169                 if ( !$res )
1170                 {
1171                         return $this->getDefaultCategory();
1172                 }
1173                 return $res;
1174         }
1175         
1176         /**
1177          * Blog::insertJavaScriptInfo()
1178          * Insert a javascript that includes information about the settings
1179          * of an author:  ConvertBreaks, MediaUrl and AuthorId
1180          * 
1181          * @param       $authorid       id of the author
1182          */
1183         public function insertJavaScriptInfo($authorid = '')
1184         {
1185                 global $member, $CONF;
1186                 
1187                 if ( $authorid == '' )
1188                 {
1189                         $authorid = $member->getID();
1190                 }
1191                 
1192                 echo "<script type=\"text/javascript\">\n";
1193                 
1194                 if ( !$this->convertBreaks() )
1195                 {
1196                         echo "setConvertBreaks(false);\n";
1197                 }
1198                 else
1199                 {
1200                         echo "setConvertBreaks(true);\n";
1201                 }
1202                 echo "setMediaUrl('{$CONF['MediaURL']}');\n";
1203                 echo "setAuthorId('{$authorid}');\n";
1204                 echo "</script>\n";
1205                 return;
1206         }
1207         
1208         /**
1209          * Blog::setAllowPastPosting()
1210          * Set the the setting for allowing to publish postings in the past
1211          * 
1212          * @param       boolean $val    new value for ballowpast
1213          * @return      void
1214          */
1215         public function setAllowPastPosting($val)
1216         {
1217                 $this->setSetting('ballowpast', $val);
1218                 return;
1219         }
1220         
1221         /**
1222          * Blog::allowPastPosting()
1223          * Get the the setting if it is allowed to publish postings in the past
1224          * [should be named as getAllowPastPosting()]
1225          * 
1226          * @param       void
1227          * @return      boolean
1228          */
1229         public function allowPastPosting()
1230         {
1231                 return $this->getSetting('ballowpast');
1232         }
1233         
1234         /**
1235          * Blog::getCorrectTime()
1236          * 
1237          * @param       integer $t
1238          * @return      integer
1239          */
1240         public function getCorrectTime($t=0)
1241         {
1242                 if ( $t == 0 )
1243                 {
1244                         $t = time();
1245                 }
1246                 return ($t + 3600 * $this->getTimeOffset());
1247         }
1248         
1249         /**
1250          * Blog::getName()
1251          * 
1252          * @param       void
1253          * @return      string name of this weblog
1254          */
1255         public function getName()
1256         {
1257                 return $this->getSetting('bname');
1258         }
1259         
1260         /**
1261          * Blog::getShortName()
1262          * 
1263          * @param       void
1264          * @return      string  short name of this weblog
1265          */
1266         public function getShortName()
1267         {
1268                 return $this->getSetting('bshortname');
1269         }
1270         
1271         /**
1272          * Blog::getMaxComments()
1273          * 
1274          * @param       void
1275          * @return      integer maximum number of comments
1276          */
1277         public function getMaxComments()
1278         {
1279                 return $this->getSetting('bmaxcomments');
1280         }
1281         
1282         /**
1283          * Blog::getNotifyAddress()
1284          * 
1285          * @param       void
1286          * @return      string  mail address for notifying
1287          */
1288         public function getNotifyAddress()
1289         {
1290                 return $this->getSetting('bnotify');
1291         }
1292         
1293         /**
1294          * Blog::getNotifyType()
1295          * 
1296          * @param       void
1297          * @return      integer notifycation type
1298          */
1299         public function getNotifyType()
1300         {
1301                 return $this->getSetting('bnotifytype');
1302         }
1303         
1304         /**
1305          * Blog::notifyOnComment()
1306          * 
1307          * @param       void
1308          * @return      boolean
1309          */
1310         public function notifyOnComment()
1311         {
1312                 $n = $this->getNotifyType();
1313                 return (($n != 0) && (($n % 3) == 0));
1314         }
1315         
1316         /**
1317          * Blog::notifyOnVote()
1318          * 
1319          * @param       void
1320          * @return      boolean
1321          */
1322         public function notifyOnVote()
1323         {
1324                 $n = $this->getNotifyType();
1325                 return (($n != 0) && (($n % 5) == 0));
1326         }
1327         
1328         /**
1329          * Blog::notifyOnNewItem()
1330          * 
1331          * @param       void
1332          * @return      boolean
1333          */
1334         public function notifyOnNewItem()
1335         {
1336                 $n = $this->getNotifyType();
1337                 return (($n != 0) && (($n % 7) == 0));
1338         }
1339         
1340         /**
1341          * Blog::setNotifyType()
1342          * 
1343          * @param       integer $val
1344          * @return      void
1345          */
1346         public function setNotifyType($val)
1347         {
1348                 $this->setSetting('bnotifytype',$val);
1349                 return;
1350         }
1351         
1352         /**
1353          * Blog::getTimeOffset()
1354          * @param       void
1355          * @return      
1356          */
1357         public function getTimeOffset()
1358         {
1359                 return $this->getSetting('btimeoffset');
1360         }
1361         
1362         /**
1363          * Blog::commentsEnabled()
1364          * @param       void
1365          * @return      integer enabled or not
1366          */
1367         public function commentsEnabled()
1368         {
1369                 return $this->getSetting('bcomments');
1370         }
1371         
1372         /**
1373          * Blog::getURL()
1374          * @param       void
1375          * @return      string  URI for this weblog
1376          */
1377         public function getURL()
1378         {
1379                 return $this->getSetting('burl');
1380         }
1381         
1382         /**
1383          * Blog::getDefaultSkin()
1384          * @param       void
1385          * @return      name of skin as default for this weblog
1386          */
1387         public function getDefaultSkin()
1388         {
1389                 return $this->getSetting('bdefskin');
1390         }
1391         
1392         /**
1393          * Blog::getUpdateFile()
1394          * @param       void
1395          * @return      string  name of file to be updated when weblog is updated
1396          */
1397         public function getUpdateFile()
1398         {
1399                 return $this->getSetting('bupdate');
1400         }
1401         
1402         /**
1403          * Blog::getDescription()
1404          * @param       void
1405          * @return      string  description for this weblog
1406          */
1407         public function getDescription()
1408         {
1409                 return $this->getSetting('bdesc');
1410         }
1411         
1412         /**
1413          * Blog::isPublic()
1414          * @param       void
1415          * @return      integer publlic or not
1416          */
1417         public function isPublic()
1418         {
1419                 return $this->getSetting('bpublic');
1420         }
1421         
1422         /**
1423          * Blog::emailRequired()
1424          * @param       void
1425          * @return      integer email is required when posting comment or not
1426          */
1427         public function emailRequired()
1428         {
1429                 return $this->getSetting('breqemail');
1430         }
1431         
1432         /**
1433          * Blog::getSearchable()
1434          * @param       void
1435          * @return      integer searchable or not
1436          */
1437         public function getSearchable()
1438         {
1439                 return $this->getSetting('bincludesearch');
1440         }
1441         
1442         /**
1443          * Blog::getDefaultCategory()
1444          * @param       void
1445          * @return      ID for category as a default
1446          */
1447         public function getDefaultCategory()
1448         {
1449                 return $this->getSetting('bdefcat');
1450         }
1451         
1452         /**
1453          * Blog::setPublic()
1454          * @param       integer $val    allow comments by non-registered members or not
1455          * @return      void
1456          */
1457         public function setPublic($val)
1458         {
1459                 $this->setSetting('bpublic', $val);
1460                 return;
1461         }
1462         
1463         /**
1464          * Blog::setSearchable()
1465          * @param       integer $val    searchable from the other blogs or not
1466          * @return      void
1467          */
1468         public function setSearchable($val)
1469         {
1470                 $this->setSetting('bincludesearch', $val);
1471                 return;
1472         }
1473         
1474         /**
1475          * Blog::setDescription
1476          * @param       string  $val    description for this weblog
1477          * @return      void
1478          */
1479         public function setDescription($val)
1480         {
1481                 $this->setSetting('bdesc',$val);
1482                 return;
1483         }
1484         
1485         /**
1486          * Blog::setUpdateFile()
1487          * @param       string  $val    name of file to beupdated when weblog is updated
1488          * @return      
1489          */
1490         public function setUpdateFile($val)
1491         {
1492                 $this->setSetting('bupdate',$val);
1493                 return;
1494         }
1495         
1496         /**
1497          * Blog::setDefaultSkin()
1498          * @param       integer $val    ID for default skin to use when displaying this weblog
1499          * @return      void
1500          */
1501         public function setDefaultSkin($val)
1502         {
1503                 $this->setSetting('bdefskin', $val);
1504                 return;
1505         }
1506         
1507         /**
1508          * Blog::setURL()
1509          * @param       string  $val    URI for this weblog
1510          * @return      
1511          */
1512         public function setURL($val)
1513         {
1514                 $this->setSetting('burl', $val);
1515                 return;
1516         }
1517         
1518         /**
1519          * Blog::setName()
1520          * @param       string  $val    name of this weblog
1521          * @return      void
1522          */
1523         public function setName($val)
1524         {
1525                 $this->setSetting('bname', $val);
1526                 return;
1527         }
1528         
1529         /**
1530          * Blog::setShortName()
1531          * @param       string  $val    short name for this weblog
1532          * @return      void
1533          */
1534         public function setShortName($val)
1535         {
1536                 $this->setSetting('bshortname', $val);
1537                 return;
1538         }
1539         
1540         /**
1541          * Blog::setCommentsEnabled()
1542          * @param       integer $val    enabling posting comment or not
1543          * @return      void
1544          */
1545         public function setCommentsEnabled($val)
1546         {
1547                 $this->setSetting('bcomments',$val);
1548                 return;
1549         }
1550         
1551         /**
1552          * Blog::setMaxComments()
1553          * @param       integer $val    maximum number of comments for this weblog
1554          * @return      void
1555          */
1556         public function setMaxComments($val)
1557         {
1558                 $this->setSetting('bmaxcomments', $val);
1559                 return;
1560         }
1561         
1562         /**
1563          * Blog::setNotifyAddress()
1564          * @param       string  $val    email to be notified if weblog updated
1565          * @return      void
1566          */
1567         public function setNotifyAddress($val)
1568         {
1569                 $this->setSetting('bnotify', $val);
1570                 return;
1571         }
1572         
1573         /**
1574          * Blog::setEmailRequired()
1575          * @param       string  requiring comments with email or not from non member
1576          * @return      void
1577          */
1578         public function setEmailRequired($val)
1579         {
1580                 $this->setSetting('breqemail', $val);
1581                 return;
1582         }
1583         
1584         /**
1585          * Blog::setTimeOffset()
1586          * @param       integer $val    time offset
1587          * @return      void
1588          */
1589         public function setTimeOffset($val)
1590         {
1591                 // check validity of value
1592                 // 1. replace , by . (common mistake)
1593                 $val = str_replace(',','.',$val);
1594                 
1595                 // 2. cast to float or int
1596                 if ( is_numeric($val) && (i18n::strpos($val, '.5') === (i18n::strlen($val) - 2)) )
1597                 {
1598                         $val = (float) $val;
1599                 }
1600                 else
1601                 {
1602                         $val = (integer) $val;
1603                 }
1604                 
1605                 $this->setSetting('btimeoffset',$val);
1606                 return;
1607         }
1608         
1609         /**
1610          * Blog::setDefaultCategory()
1611          * @param       integer $val    ID for default category for this weblog
1612          * @return      
1613          */
1614         public function setDefaultCategory($val)
1615         {
1616                 $this->setSetting('bdefcat',$val);
1617                 return;
1618         }
1619         
1620         /**
1621          * Blog::getSetting()
1622          * @param       string  $key    key for setting of this weblog
1623          * @return      mixed   value for the setting
1624          */
1625         public function getSetting($key)
1626         {
1627                 return $this->settings[$key];
1628         }
1629         
1630         /**
1631          * Blog::setSetting()
1632          * @param       string  $key    key for setting of this weblog
1633          * @param       mixed   $value  value for the key
1634          * @return      
1635          */
1636         public function setSetting($key, $value)
1637         {
1638                 $this->settings[$key] = $value;
1639                 return;
1640         }
1641         
1642         /**
1643          * Blog::addTeamMember()
1644          * Tries to add a member to the team. 
1645          * Returns false if the member was already on the team
1646          * 
1647          * @param       integer $memberid       id for member
1648          * @param       boolean $admin  super-admin or not
1649          * @return      boolean Success/Fail
1650          */
1651         public function addTeamMember($memberid, $admin)
1652         {
1653                 global $manager;
1654                 
1655                 $memberid = intval($memberid);
1656                 $admin = intval($admin);
1657                 
1658                 // check if member is already a member
1659                 $tmem =& $manager->getMember($memberid);
1660                 
1661                 if ( $tmem->isTeamMember($this->blogid) )
1662                 {
1663                         return 0;
1664                 }
1665                 
1666                 $data = array(
1667                         'blog'          => &$this,
1668                         'member'        => &$tmem,
1669                         'admin'         => &$admin
1670                 );
1671                 $manager->notify('PreAddTeamMember', $data);
1672                 
1673                 // add to team
1674                 $query = "INSERT INTO %s (TMEMBER, TBLOG, TADMIN) VALUES (%d, %d, %d);";
1675                 $query = sprintf($query, sql_table('team'), (integer) $memberid, (integer) $this->blogid, (integer) $admin);
1676                 DB::execute($query);
1677                 
1678                 $data = array(
1679                         'blog'          => &$this,
1680                         'member'        => &$tmem,
1681                         'admin'         =>  $admin
1682                 );
1683                 $manager->notify('PostAddTeamMember', $data);
1684                 
1685                 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1686                 ActionLog::add(INFO, $logMsg);
1687                 
1688                 return 1;
1689         }
1690         
1691         /**
1692          * Blog::getID()
1693          * @param       void
1694          * @return      integer ID for this weblog
1695          */
1696         public function getID()
1697         {
1698                 return (integer) $this->blogid;
1699         }
1700         
1701         /**
1702          * Checks if a blog with a given shortname exists 
1703          * Returns true if there is a blog with the given shortname (static)
1704          * 
1705          * @param       string  $name           blog shortname
1706          * @return      boolean exists or not
1707          */
1708         public function exists($name)
1709         {
1710                 $r = DB::getResult('SELECT * FROM '.sql_table('blog').' WHERE bshortname='. DB::quoteValue($name));
1711                 return ($r->rowCount() != 0);
1712         }
1713         
1714         /**
1715          * Checks if a blog with a given id exists 
1716          * Returns true if there is a blog with the given ID (static)
1717          * 
1718          * @param       integer $id     ID for searched weblog
1719          * @return      boolean exists or not
1720          */
1721         public function existsID($id)
1722         {
1723                 $r = DB::getResult('SELECT * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1724                 return ($r->rowCount() != 0);
1725         }
1726         
1727         /**
1728          * Blog::setFuturePost()
1729          * flag there is a future post pending
1730          * 
1731          * @param       void
1732          * @return      void
1733          */
1734         public function setFuturePost()
1735         {
1736                 $query =  "UPDATE %s SET bfuturepost='1' WHERE bnumber=%d;";
1737                 $query = sprintf($query, sql_table('blog'), (integer) $this->blogid);
1738                 DB::execute($query);
1739                 return;
1740         }
1741         
1742         /**
1743          * Blog::clearFuturePost()
1744          * clear there is a future post pending
1745          * 
1746          * @param       void
1747          * @return      void
1748          */
1749         public function clearFuturePost()
1750         {
1751                 $query =  "UPDATE %s SET bfuturepost='0' WHERE bnumber=%d;";
1752                 $query = sprintf($query, sql_table('blog'), (integer) $this->blogid);
1753                 DB::execute($query);
1754                 return;
1755         }
1756         
1757         /**
1758          * Blog::checkJustPosted()
1759          * check if we should throw justPosted event 
1760          * 
1761          * @param       void
1762          * @return      void
1763          */
1764         public function checkJustPosted()
1765         {
1766                 global $manager;
1767                 
1768                 if ( $this->settings['bfuturepost'] == 1 )
1769                 {
1770                         $query = "SELECT * FROM %s WHERE iposted=0 AND iblog=%d AND itime < NOW();";
1771                         $query = sprintf($query, sql_table('item'), (integer) $this->blogid);
1772                         
1773                         $result = DB::getResult($query);
1774                         if ( $result->rowCount() > 0 )
1775                         {
1776                                 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1777                                 // Note that the plugins's calling order is subject to thri order in the plugin list
1778                                 $pinged = FALSE;
1779                                 $data = array('blogid' => $this->blogid, 'pinged' => &$pinged);
1780                                 $manager->notify('JustPosted', $data);
1781                                 
1782                                 // clear all expired future posts
1783                                 $query = "UPDATE %s SET iposted='1' WHERE iblog=%d AND itime < NOW();";
1784                                 $query = spriintf($query, sql_table('item'), (integer) $this->blogid);
1785                                 DB::execute($query);
1786                                 
1787                                 // check to see any pending future post, clear the flag is none
1788                                 $query = "SELECT * FROM %s WHERE iposted=0 AND iblog=%d;";
1789                                 $query = sprintf($query, sql_table('item'), (integer) $this->blogid);
1790                                 
1791                                 $result = DB::getResult($query);
1792                                 if ( $result->rowCount() == 0 )
1793                                 {
1794                                         $this->clearFuturePost();
1795                                 }
1796                         }
1797                 }
1798                 return;
1799         }
1800         
1801         /**
1802          * Blog::readLogFromList()
1803          * Shows the given list of items for this blog
1804          *
1805          * @param       array   $itemarray      array of item numbers to be displayed
1806          * @param       string  $template       string representing the template _NAME_ (!)
1807          * @param       string  $highlight      contains a query that should be highlighted
1808          * @param       boolean $comments       1=show comments 0=don't show comments
1809          * @param       boolean $dateheads      1=show dateheads 0=don't show dateheads
1810          * @param       boolean $showDrafts     0=do not show drafts 1=show drafts
1811          * @param       boolean $showFuture     0=do not show future posts 1=show future posts
1812          * @return      integer amount of items shown
1813          */
1814         public function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0)
1815         {
1816                 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1817                 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1818         }
1819         
1820         /**
1821          * Blog::getSqlItemList()
1822          * Returns the SQL query used to fill out templates for a list of items
1823          * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1824          *
1825          * @param       array   $itemarray      an array holding the item numbers of the items to be displayed
1826          * @param       integer $showDrafts     0=do not show drafts 1=show drafts
1827          * @param       integer $showFuture     0=do not show future posts 1=show future posts
1828          * @return      string  either a full SQL query, or an empty string
1829          */
1830         public function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1831         {
1832                 if ( !is_array($itemarray) )
1833                 {
1834                         return '';
1835                 }
1836                 
1837                 $showDrafts = intval($showDrafts);
1838                 $showFuture = intval($showFuture);
1839                 $items = array();
1840                 
1841                 foreach ( $itemarray as $value )
1842                 {
1843                         if ( intval($value) )
1844                         {
1845                                 $items[] = intval($value);
1846                         }
1847                 }
1848                 if ( !count($items) )
1849                 {
1850                         return '';
1851                 }
1852                 
1853                 $i = count($items);
1854                 $query = '';
1855                 foreach ( $items as $value )
1856                 {
1857                         $query .= '('
1858                                         .       'SELECT'
1859                                         .       ' i.inumber as itemid,'
1860                                         .       ' i.ititle as title,'
1861                                         .       ' i.ibody as body,'
1862                                         .       ' m.mname as author,'
1863                                         .       ' m.mrealname as authorname,'
1864                                         .       ' i.itime,'
1865                                         .       ' i.imore as more,'
1866                                         .       ' m.mnumber as authorid,'
1867                                         .       ' m.memail as authormail,'
1868                                         .       ' m.murl as authorurl,'
1869                                         .       ' c.cname as category,'
1870                                         .       ' i.icat as catid,'
1871                                         .       ' i.iclosed as closed';
1872                         
1873                         $query .= ' FROM '
1874                                         . sql_table('item') . ' as i, '
1875                                         . sql_table('member') . ' as m, '
1876                                         . sql_table('category') . ' as c'
1877                                         . ' WHERE'
1878                                     .    ' i.iblog='.$this->blogid
1879                                    . ' and i.iauthor=m.mnumber'
1880                                    . ' and i.icat=c.catid';
1881                         
1882                         // exclude drafts       
1883                         if ( !$showDrafts )
1884                         {
1885                                 $query .= ' and i.idraft=0';
1886                         }
1887                         if ( !$showFuture )
1888                         {
1889                                 // don't show future items
1890                                 $query .= ' and i.itime<=' . DB::formatDateTime($this->getCorrectTime());
1891                         }
1892                         
1893                         $query .= ' and i.inumber='.intval($value);
1894                         $query .= ')';
1895                         $i--;
1896                         if ($i) $query .= ' UNION ';
1897                 }
1898                 
1899                 return $query;
1900         }
1901         
1902         /**
1903          * Blog::convertBreaks()
1904          * Get the the setting for the line break handling
1905          * [should be named as getConvertBreaks()]
1906          * 
1907          * @deprecated
1908          * @param       void
1909          * @return      
1910          */
1911         public function convertBreaks()
1912         {
1913                 return $this->getSetting('bconvertbreaks');
1914         }
1915         
1916         /**
1917          * Set the the setting for the line break handling
1918          * 
1919          * @deprecated
1920          * @param       boolean $val    new value for bconvertbreaks
1921          * @return      void
1922          */
1923         public function setConvertBreaks($val)
1924         {
1925                 $this->setSetting('bconvertbreaks', $val);
1926                 return;
1927         }
1928 }