OSDN Git Service

Update project date from '2002 - 2009' to '2002 - 2010'.
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / BLOG.php
1 <?php
2
3 /*
4  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5  * Copyright (C) 2002-2010 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-2010 The Nucleus Group
19  * @version $Id$
20  * $NucleusJP: BLOG.php,v 1.12.2.2 2007/08/08 05:26:22 kimitake Exp $
21  */
22
23 if ( !function_exists('requestVar') ) exit;
24 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
25
26 class BLOG {
27
28     // blog id
29     var $blogid;
30
31     // ID of currently selected category
32     var $selectedcatid;
33
34     // After creating an object of the blog class, contains true if the BLOG object is
35     // valid (the blog exists)
36     var $isValid;
37
38     // associative array, containing all blogsettings (use the get/set functions instead)
39     var $settings;
40
41     /**
42      * Creates a new BLOG object for the given blog
43      *
44      * @param $id blogid
45      */
46     function BLOG($id) {
47         $this->blogid = intval($id);
48         $this->readSettings();
49
50         // try to set catid
51         // (the parse functions in SKIN.php will override this, so it's mainly useless)
52         global $catid;
53         $this->setSelectedCategory($catid);
54     }
55
56     /**
57      * Shows the given amount of items for this blog
58      *
59      * @param $template
60      *      String representing the template _NAME_ (!)
61      * @param $amountEntries
62      *      amount of entries to show
63      * @param $startpos
64      *      offset from where items should be shown (e.g. 5 = start at fifth item)
65      * @returns int
66      *      amount of items shown
67      */
68     function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
69         return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
70     }
71
72     /**
73      * Shows an archive for a given month
74      *
75      * @param $year
76      *      year
77      * @param $month
78      *      month
79      * @param $template
80      *      String representing the template name to be used
81      */
82     function showArchive($templatename, $year, $month = 0, $day = 0) {
83
84         // create extra where clause for select query
85         if ($day == 0 && $month != 0) {
86             $timestamp_start = mktime(0,0,0,$month,1,$year);
87             $timestamp_end = mktime(0,0,0,$month+1,1,$year);  // also works when $month==12
88         } elseif ($month == 0) {
89             $timestamp_start = mktime(0,0,0,1,1,$year);
90             $timestamp_end = mktime(0,0,0,12,31,$year);  // also works when $month==12
91         } else {
92             $timestamp_start = mktime(0,0,0,$month,$day,$year);
93             $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
94         }
95         $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
96                      . ' and i.itime<' . mysqldate($timestamp_end);
97
98
99         $this->readLogAmount($templatename,0,$extra_query,'',1,1);
100
101     }
102
103
104     // sets/gets current category (only when category exists)
105     function setSelectedCategory($catid) {
106         if ($this->isValidCategory($catid) || (intval($catid) == 0))
107             $this->selectedcatid = intval($catid);
108     }
109
110     function setSelectedCategoryByName($catname) {
111         $this->setSelectedCategory($this->getCategoryIdFromName($catname));
112     }
113
114     function getSelectedCategory() {
115         return $this->selectedcatid;
116     }
117
118     /**
119      * Shows the given amount of items for this blog
120      *
121      * @param $template
122      *      String representing the template _NAME_ (!)
123      * @param $amountEntries
124      *      amount of entries to show (0 = no limit)
125      * @param $extraQuery
126      *      extra conditions to be added to the query
127      * @param $highlight
128      *      contains a query that should be highlighted
129      * @param $comments
130      *      1=show comments 0=don't show comments
131      * @param $dateheads
132      *      1=show dateheads 0=don't show dateheads
133      * @param $offset
134      *      offset
135      * @returns int
136      *      amount of items shown
137      */
138     function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
139
140         $query = $this->getSqlBlog($extraQuery);
141
142         if ($amountEntries > 0) {
143                 // $offset zou moeten worden:
144                 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
145                $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
146         }
147         return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
148     }
149
150     function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
151         global $CONF, $manager;
152
153         $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
154         if ($lastVisit != 0)
155             $lastVisit = $this->getCorrectTime($lastVisit);
156
157         // set templatename as global variable (so plugins can access it)
158         global $currentTemplateName;
159         $currentTemplateName = $templateName;
160
161         $template =& $manager->getTemplate($templateName);
162
163         // create parser object & action handler
164         $actions =& new ITEMACTIONS($this);
165         $parser =& new PARSER($actions->getDefinedActions(),$actions);
166         $actions->setTemplate($template);
167         $actions->setHighlight($highlight);
168         $actions->setLastVisit($lastVisit);
169         $actions->setParser($parser);
170         $actions->setShowComments($comments);
171
172         // execute query
173         $items = sql_query($query);
174
175         // loop over all items
176         $old_date = 0;
177         while ($item = sql_fetch_object($items)) {
178
179             $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
180
181             // action handler needs to know the item we're handling
182             $actions->setCurrentItem($item);
183
184             // add date header if needed
185             if ($dateheads) {
186                 $new_date = date('dFY',$item->timestamp);
187                 if ($new_date != $old_date) {
188                     // unless this is the first time, write date footer
189                     $timestamp = $item->timestamp;
190                     if ($old_date != 0) {
191                         $oldTS = strtotime($old_date);
192                         $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
193                         $tmp_footer = strftime(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
194                         $parser->parse($tmp_footer);
195                         $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
196                     }
197                     $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
198                     // note, to use templatvars in the dateheader, the %-characters need to be doubled in
199                     // order to be preserved by strftime
200                     $tmp_header = strftime((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
201                     $parser->parse($tmp_header);
202                     $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
203                 }
204                 $old_date = $new_date;
205             }
206
207             // parse item
208             $parser->parse($template['ITEM_HEADER']);
209             $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));
210             $parser->parse($template['ITEM']);
211             $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));
212             $parser->parse($template['ITEM_FOOTER']);
213
214         }
215
216         $numrows = sql_num_rows($items);
217
218         // add another date footer if there was at least one item
219         if (($numrows > 0) && $dateheads) {
220             $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
221             $parser->parse($template['DATE_FOOTER']);
222             $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
223         }
224
225         sql_free_result($items);    // free memory
226
227         return $numrows;
228
229     }
230
231     function showOneitem($itemid, $template, $highlight) {
232         $extraQuery = ' and inumber=' . intval($itemid);
233
234         return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
235     }
236
237
238     /**
239       * Adds an item to this blog
240       */
241     function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
242         global $manager;
243
244         $blogid     = intval($blogid);
245         $authorid   = intval($authorid);
246         $title      = $title;
247         $body       = $body;
248         $more       = $more;
249         $catid      = intval($catid);
250
251         // convert newlines to <br />
252         if ($this->convertBreaks()) {
253             $body = addBreaks($body);
254             $more = addBreaks($more);
255         }
256
257         if ($closed != '1') $closed = '0';
258         if ($draft != '0') $draft = '1';
259
260         if (!$this->isValidCategory($catid))
261             $catid = $this->getDefaultCategory();
262
263         if ($timestamp > $this->getCorrectTime())
264             $isFuture = 1;
265
266         $timestamp = date('Y-m-d H:i:s',$timestamp);
267
268         $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
269
270         $title = addslashes($title);
271         $body = addslashes($body);
272         $more = addslashes($more);
273
274         $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
275                . "VALUES ('$title', '$body', '$more', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
276         sql_query($query);
277         $itemid = sql_insert_id();
278
279         $manager->notify('PostAddItem',array('itemid' => $itemid));
280
281         if (!$draft)
282             $this->updateUpdateFile();
283
284         // send notification mail
285         if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
286             $this->sendNewItemNotification($itemid, stripslashes($title), stripslashes($body));
287
288         return $itemid;
289     }
290
291     function sendNewItemNotification($itemid, $title, $body) {
292         global $CONF, $member;
293
294         // create text version of html post
295         $ascii = toAscii($body);
296
297         $mailto_msg = _NOTIFY_NI_MSG . " \n";
298 //              $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
299         $temp = parse_url($CONF['Self']);
300         if ($temp['scheme']) {
301             $mailto_msg .= createItemLink($itemid) . "\n\n";
302         } else {
303             $tempurl = $this->getURL();
304             if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
305                 $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
306             } else {
307                 $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
308             }
309         }
310         $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
311         $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
312         $mailto_msg .= getMailFooter();
313
314         $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
315
316         $frommail = $member->getNotifyFromMailAddress();
317
318         $notify =& new NOTIFICATION($this->getNotifyAddress());
319         $notify->notify($mailto_title, $mailto_msg , $frommail);
320
321
322
323     }
324
325
326     /**
327       * Creates a new category for this blog
328       *
329       * @param $catName
330       *     name of the new category. When empty, a name is generated automatically
331       *     (starting with newcat)
332       * @param $catDescription
333       *     description of the new category. Defaults to 'New Category'
334       *
335       * @returns
336       *     the new category-id in case of success.
337       *     0 on failure
338       */
339     function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
340         global $member, $manager;
341
342         if ($member->blogAdminRights($this->getID())) {
343             // generate
344             if ($catName == '')
345             {
346                 $catName = _CREATED_NEW_CATEGORY_NAME;
347                 $i = 1;
348
349                 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
350                 while (sql_num_rows($res) > 0)
351                 {
352                     $i++;
353                     $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
354                 }
355
356                 $catName = $catName . $i;
357             }
358
359             $manager->notify(
360                 'PreAddCategory',
361                 array(
362                     'blog' => &$this,
363                     'name' => &$catName,
364                     'description' => $catDescription
365                 )
366             );
367
368             $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . addslashes($catName) . "', '" . addslashes($catDescription) . "')";
369             sql_query($query);
370             $catid = sql_insert_id();
371
372             $manager->notify(
373                 'PostAddCategory',
374                 array(
375                     'blog' => &$this,
376                     'name' => $catName,
377                     'description' => $catDescription,
378                     'catid' => $catid
379                 )
380             );
381
382             return $catid;
383         } else {
384             return 0;
385         }
386
387     }
388
389
390     /**
391      * Searches all months of this blog for the given query
392      *
393      * @param $query
394      *      search query
395      * @param $template
396      *      template to be used (__NAME__ of the template)
397      * @param $amountMonths
398      *      max amount of months to be search (0 = all)
399      * @param $maxresults
400      *      max number of results to show
401      * @param $startpos
402      *      offset
403      * @returns
404      *      amount of hits found
405      */
406     function search($query, $template, $amountMonths, $maxresults, $startpos) {
407         global $CONF, $manager;
408
409         $highlight  = '';
410         $sqlquery   = $this->getSqlSearch($query, $amountMonths, $highlight);
411
412         if ($sqlquery == '')
413         {
414             // no query -> show everything
415             $extraquery = '';
416             $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
417         } else {
418
419             // add LIMIT to query (to split search results into pages)
420             if (intval($maxresults > 0))
421                 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
422
423             // show results
424             $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
425
426             // when no results were found, show a message
427             if ($amountfound == 0)
428             {
429                 $template =& $manager->getTemplate($template);
430                 $vars = array(
431                     'query'     => htmlspecialchars($query),
432                     'blogid'    => $this->getID()
433                 );
434                 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
435             }
436         }
437
438         return $amountfound;
439     }
440
441     /**
442      * Returns an SQL query to use for a search query
443      *
444      * @param $query
445      *      search query
446      * @param $amountMonths
447      *      amount of months to search back. Default = 0 = unlimited
448      * @param $mode
449      *      either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
450      * @returns $highlight
451      *      words to highlight (out parameter)
452      * @returns
453      *      either a full SQL query, or an empty string (if querystring empty)
454      * @note
455      *      No LIMIT clause is added. (caller should add this if multiple pages are requested)
456      */
457     function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
458     {
459         $searchclass =& new SEARCH($query);
460
461         $highlight    = $searchclass->inclusive;
462
463         // if querystring is empty, return empty string
464         if ($searchclass->inclusive == '')
465             return '';
466
467
468         $where  = $searchclass->boolean_sql_where('ititle,ibody,imore');
469         $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
470
471         // get list of blogs to search
472         $blogs      = $searchclass->blogs;      // array containing blogs that always need to be included
473         $blogs[]    = $this->getID();           // also search current blog (duh)
474         $blogs      = array_unique($blogs);     // remove duplicates
475         $selectblogs = '';
476         if (count($blogs) > 0)
477             $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
478
479         if ($mode == '')
480         {
481             $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
482             if ($select)
483                 $query .= ', '.$select. ' as score ';
484         } else {
485             $query = 'SELECT COUNT(*) as result ';
486         }
487
488         $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
489                . ' WHERE i.iauthor=m.mnumber'
490                . ' and i.icat=c.catid'
491                . ' and i.idraft=0'  // exclude drafts
492                . $selectblogs
493                     // don't show future items
494                . ' and i.itime<=' . mysqldate($this->getCorrectTime())
495                . ' and '.$where;
496
497         // take into account amount of months to search
498         if ($amountMonths > 0)
499         {
500             $localtime = getdate($this->getCorrectTime());
501             $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
502             $query .= ' and i.itime>' . mysqldate($timestamp_start);
503         }
504
505         if ($mode == '')
506         {
507             if ($select)
508                 $query .= ' ORDER BY score DESC';
509             else
510                 $query .= ' ORDER BY i.itime DESC ';
511         }
512
513         return $query;
514     }
515
516     /**
517      * Returns the SQL query that's normally used to display the blog items on the index type skins
518      *
519      * @param $mode
520      *      either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
521      * @returns
522      *      either a full SQL query, or an empty string
523      * @note
524      *      No LIMIT clause is added. (caller should add this if multiple pages are requested)
525      */
526     function getSqlBlog($extraQuery, $mode = '')
527     {
528         if ($mode == '')
529             $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author, m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
530         else
531             $query = 'SELECT COUNT(*) as result ';
532
533         $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
534                . ' WHERE i.iblog='.$this->blogid
535                . ' and i.iauthor=m.mnumber'
536                . ' and i.icat=c.catid'
537                . ' and i.idraft=0'  // exclude drafts
538                     // don't show future items
539                . ' and i.itime<=' . mysqldate($this->getCorrectTime());
540
541         if ($this->getSelectedCategory())
542             $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
543
544
545         $query .= $extraQuery;
546
547         if ($mode == '')
548             $query .= ' ORDER BY i.itime DESC';
549
550         return $query;
551     }
552
553     /**
554       * Shows the archivelist using the given template
555       */
556     function showArchiveList($template, $mode = 'month', $limit = 0) {
557         global $CONF, $catid, $manager;
558
559         if (!isset ($linkparams)) {
560         $linkparams = array();
561         }
562
563         if ($catid) {
564             $linkparams = array('catid' => $catid);
565         }
566
567         $template =& $manager->getTemplate($template);
568         $data['blogid'] = $this->getID();
569
570         $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER']
571                                                        : '';
572         echo TEMPLATE::fill($tplt, $data);
573
574         $query = 'SELECT itime, SUBSTRING(itime,1,4) AS Year, SUBSTRING(itime,6,2) AS Month, SUBSTRING(itime,9,2) as Day FROM '.sql_table('item')
575         . ' WHERE iblog=' . $this->getID()
576         . ' and itime <=' . mysqldate($this->getCorrectTime())  // don't show future items!
577         . ' and idraft=0'; // don't show draft items
578
579         if ($catid)
580             $query .= ' and icat=' . intval($catid);
581
582         $query .= ' GROUP BY Year';
583         if ($mode == 'month' || $mode == 'day')
584             $query .= ', Month';
585         if ($mode == 'day')
586             $query .= ', Day';
587
588         $query .= ' ORDER BY itime DESC';
589
590         if ($limit > 0)
591             $query .= ' LIMIT ' . intval($limit);
592
593         $res = sql_query($query);
594
595         while ($current = sql_fetch_object($res)) {
596             $current->itime = strtotime($current->itime);   // string time -> unix timestamp
597
598             if ($mode == 'day') {
599                 $archivedate      = date('Y-m-d',$current->itime);
600                 $archive['day']   = date('d',$current->itime);
601                 $data['day']      = date('d',$current->itime);
602                 $data['month']    = date('m',$current->itime);
603                 $archive['month'] = $data['month'];
604             } elseif ($mode == 'year') {
605                 $archivedate      = date('Y',$current->itime);
606                 $data['day']      = '';
607                 $data['month']    = '';
608                 $archive['day']   = '';
609                 $archive['month'] = '';
610             } else {
611                 $archivedate = date('Y-m',$current->itime);
612                 $data['month'] = date('m',$current->itime);
613                 $archive['month'] = $data['month'];
614                 $data['day'] = '';
615                 $archive['day'] = '';
616             }
617
618             $data['year'] = date('Y',$current->itime);
619             $archive['year'] = $data['year'];
620             $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
621
622             $manager->notify(
623                 'PreArchiveListItem',
624                 array(
625                     'listitem' => &$data
626                 )
627             );
628
629             $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
630             echo strftime($temp,$current->itime);
631
632         }
633
634         sql_free_result($res);
635
636         $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER']
637                                                        : '';
638         echo TEMPLATE::fill($tplt, $data);
639     }
640
641
642     /**
643       * Shows the list of categories using a given template
644       */
645     function showCategoryList($template) {
646         global $CONF, $manager;
647
648         // determine arguments next to catids
649         // I guess this can be done in a better way, but it works
650         global $archive, $archivelist;
651
652         $linkparams = array();
653         if ($archive) {
654             $blogurl = createArchiveLink($this->getID(), $archive, '');
655             $linkparams['blogid'] = $this->getID();
656             $linkparams['archive'] = $archive;
657         } else if ($archivelist) {
658             $blogurl = createArchiveListLink($this->getID(), '');
659             $linkparams['archivelist'] = $archivelist;
660         } else {
661             $blogurl = createBlogidLink($this->getID(), '');
662             $linkparams['blogid'] = $this->getID();
663         }
664
665         //$blogurl = $this->getURL() . $qargs;
666         //$blogurl = createBlogLink($this->getURL(), $linkparams);
667
668         $template =& $manager->getTemplate($template);
669
670         echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
671                             array(
672                                 'blogid' => $this->getID(),
673                                 'blogurl' => $blogurl,
674                                 'self' => $CONF['Self']
675                             ));
676
677         $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
678         $res = sql_query($query);
679
680
681         while ($data = sql_fetch_assoc($res)) {
682             $data['blogid'] = $this->getID();
683             $data['blogurl'] = $blogurl;
684             $data['catlink'] = createLink(
685                                 'category',
686                                 array(
687                                     'catid' => $data['catid'],
688                                     'name' => $data['catname'],
689                                     'extra' => $linkparams
690                                 )
691                                );
692             $data['self'] = $CONF['Self'];
693             
694             //catiscurrent
695             if ($this->getSelectedCategory()) {
696                 if ($this->getSelectedCategory() == $data['catid']) {
697                     $data['catiscurrent'] = 'yes';
698                     $data['currentcat'] = 'yes';
699                 }
700                 else {
701                     $data['catiscurrent'] = 'no';
702                     $data['currentcat'] = 'no';
703                 }
704             }
705             else {
706                 global $itemid;
707                 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
708                     $iobj =& $manager->getItem(intval($itemid),0,0);
709                     $cid = $iobj['catid'];
710                     if ($cid == $data['catid']) {
711                         $data['catiscurrent'] = 'yes';
712                         $data['currentcat'] = 'yes';
713                     }
714                     else {
715                         $data['catiscurrent'] = 'no';
716                         $data['currentcat'] = 'no';
717                     }
718                 }
719             }
720
721             $manager->notify(
722                 'PreCategoryListItem',
723                 array(
724                     'listitem' => &$data
725                 )
726             );
727
728             echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
729             //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
730             //echo strftime($temp, $current->itime);
731
732         }
733
734         sql_free_result($res);
735
736         echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
737                             array(
738                                 'blogid' => $this->getID(),
739                                 'blogurl' => $blogurl,
740                                 'self' => $CONF['Self']
741                             ));
742     }
743
744     /**
745       * Shows a list of all blogs in the system using a given template
746       * ordered by  number, name, shortname or description
747       * in ascending or descending order
748       */
749     function showBlogList($template, $bnametype, $orderby, $direction) {
750         global $CONF, $manager;
751
752         switch ($orderby) {
753             case 'number':
754                 $orderby='bnumber';
755                 break;
756             case 'name':
757                 $orderby='bname';
758                 break;
759             case 'shortname':
760                 $orderby='bshortname';
761                 break;
762             case 'description':
763                 $orderby='bdesc';
764                 break;
765             default:
766                 $orderby='bnumber';
767                 break;
768         }
769
770         $direction=strtolower($direction);
771         switch ($direction) {
772             case 'asc':
773                 $direction='ASC';
774                 break;
775             case 'desc':
776                 $direction='DESC';
777                 break;
778             default:
779                 $direction='ASC';
780                 break;
781         }
782
783         $template =& $manager->getTemplate($template);
784
785         echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
786                             array(
787                                 'sitename' => $CONF['SiteName'],
788                                 'siteurl' => $CONF['IndexURL']
789                             ));
790
791         $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
792         $res = sql_query($query);
793
794         while ($data = sql_fetch_assoc($res)) {
795
796             $list = array();
797
798 //                      $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
799             $list['bloglink'] = createBlogidLink($data['bnumber']);
800
801             $list['blogdesc'] = $data['bdesc'];
802
803             $list['blogurl'] = $data['burl'];
804
805             if ($bnametype=='shortname') {
806                 $list['blogname'] = $data['bshortname'];
807             }
808             else { // all other cases
809                 $list['blogname'] = $data['bname'];
810             }
811
812             $manager->notify(
813                 'PreBlogListItem',
814                 array(
815                     'listitem' => &$list
816                 )
817             );
818
819             echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
820
821         }
822
823         sql_free_result($res);
824
825         echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
826                             array(
827                                 'sitename' => $CONF['SiteName'],
828                                 'siteurl' => $CONF['IndexURL']
829                             ));
830
831     }
832
833     /**
834       * Blogsettings functions
835       */
836
837     function readSettings() {
838         $query =  'SELECT *'
839                . ' FROM '.sql_table('blog')
840                . ' WHERE bnumber=' . $this->blogid;
841         $res = sql_query($query);
842
843         $this->isValid = (sql_num_rows($res) > 0);
844         if (!$this->isValid)
845             return;
846
847         $this->settings = sql_fetch_assoc($res);
848     }
849
850     function writeSettings() {
851
852         // (can't use floatval since not available prior to PHP 4.2)
853         $offset = $this->getTimeOffset();
854         if (!is_float($offset))
855             $offset = intval($offset);
856
857         $query =  'UPDATE '.sql_table('blog')
858                . " SET bname='" . addslashes($this->getName()) . "',"
859                . "     bshortname='". addslashes($this->getShortName()) . "',"
860                . "     bcomments=". intval($this->commentsEnabled()) . ","
861                . "     bmaxcomments=" . intval($this->getMaxComments()) . ","
862                . "     btimeoffset=" . $offset . ","
863                . "     bpublic=" . intval($this->isPublic()) . ","
864                . "     breqemail=" . intval($this->emailRequired()) . ","
865                . "     bconvertbreaks=" . intval($this->convertBreaks()) . ","
866                . "     ballowpast=" . intval($this->allowPastPosting()) . ","
867                . "     bnotify='" . addslashes($this->getNotifyAddress()) . "',"
868                . "     bnotifytype=" . intval($this->getNotifyType()) . ","
869                . "     burl='" . addslashes($this->getURL()) . "',"
870                . "     bupdate='" . addslashes($this->getUpdateFile()) . "',"
871                . "     bdesc='" . addslashes($this->getDescription()) . "',"
872                . "     bdefcat=" . intval($this->getDefaultCategory()) . ","
873                . "     bdefskin=" . intval($this->getDefaultSkin()) . ","
874                . "     bincludesearch=" . intval($this->getSearchable())
875                . " WHERE bnumber=" . intval($this->getID());
876         sql_query($query);
877
878     }
879
880
881
882     // update update file if requested
883     function updateUpdatefile() {
884          if ($this->getUpdateFile()) {
885             $f_update = fopen($this->getUpdateFile(),'w');
886             fputs($f_update,$this->getCorrectTime());
887             fclose($f_update);
888          }
889
890     }
891
892     function isValidCategory($catid) {
893         $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
894         $res = sql_query($query);
895         return (sql_num_rows($res) != 0);
896     }
897
898     function getCategoryName($catid) {
899         $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
900         $o = sql_fetch_object($res);
901         return $o->cname;
902     }
903
904     function getCategoryDesc($catid) {
905         $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
906         $o = sql_fetch_object($res);
907         return $o->cdesc;
908     }
909
910     function getCategoryIdFromName($name) {
911         $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . addslashes($name) . '"');
912         if (sql_num_rows($res) > 0) {
913             $o = sql_fetch_object($res);
914             return $o->catid;
915         } else {
916             return $this->getDefaultCategory();
917         }
918     }
919
920     function convertBreaks() {
921         return $this->getSetting('bconvertbreaks');
922     }
923
924     function insertJavaScriptInfo($authorid = '') {
925         global $member, $CONF;
926
927         if ($authorid == '')
928             $authorid = $member->getID();
929
930         ?>
931         <script type="text/javascript">
932             setConvertBreaks(<?php echo  $this->convertBreaks() ? 'true' : 'false' ?>);
933             setMediaUrl("<?php echo $CONF['MediaURL']?>");
934             setAuthorId(<?php echo $authorid?>);
935         </script><?php  }
936
937     function setConvertBreaks($val) {
938         $this->setSetting('bconvertbreaks',$val);
939     }
940     function setAllowPastPosting($val) {
941         $this->setSetting('ballowpast',$val);
942     }
943     function allowPastPosting() {
944         return $this->getSetting('ballowpast');
945     }
946
947     function getCorrectTime($t=0) {
948         if ($t == 0) $t = time();
949         return ($t + 3600 * $this->getTimeOffset());
950     }
951
952     function getName() {
953         return $this->getSetting('bname');
954     }
955
956     function getShortName() {
957         return $this->getSetting('bshortname');
958     }
959
960     function getMaxComments() {
961         return $this->getSetting('bmaxcomments');
962     }
963
964     function getNotifyAddress() {
965         return $this->getSetting('bnotify');
966     }
967
968     function getNotifyType() {
969         return $this->getSetting('bnotifytype');
970     }
971
972     function notifyOnComment() {
973         $n = $this->getNotifyType();
974         return (($n != 0) && (($n % 3) == 0));
975     }
976
977     function notifyOnVote() {
978         $n = $this->getNotifyType();
979         return (($n != 0) && (($n % 5) == 0));
980     }
981
982     function notifyOnNewItem() {
983         $n = $this->getNotifyType();
984         return (($n != 0) && (($n % 7) == 0));
985     }
986
987     function setNotifyType($val) {
988         $this->setSetting('bnotifytype',$val);
989     }
990
991
992     function getTimeOffset() {
993         return $this->getSetting('btimeoffset');
994     }
995
996     function commentsEnabled() {
997         return $this->getSetting('bcomments');
998     }
999
1000     function getURL() {
1001         return $this->getSetting('burl');
1002     }
1003
1004     function getDefaultSkin() {
1005         return $this->getSetting('bdefskin');
1006     }
1007
1008     function getUpdateFile() {
1009         return $this->getSetting('bupdate');
1010     }
1011
1012     function getDescription() {
1013         return $this->getSetting('bdesc');
1014     }
1015
1016     function isPublic() {
1017         return $this->getSetting('bpublic');
1018     }
1019
1020     function emailRequired() {
1021         return $this->getSetting('breqemail');
1022     }
1023
1024     function getSearchable() {
1025         return $this->getSetting('bincludesearch');
1026     }
1027
1028     function getDefaultCategory() {
1029         return $this->getSetting('bdefcat');
1030     }
1031
1032     function setPublic($val) {
1033         $this->setSetting('bpublic',$val);
1034     }
1035
1036     function setSearchable($val) {
1037         $this->setSetting('bincludesearch',$val);
1038     }
1039
1040     function setDescription($val) {
1041         $this->setSetting('bdesc',$val);
1042     }
1043
1044     function setUpdateFile($val) {
1045         $this->setSetting('bupdate',$val);
1046     }
1047
1048     function setDefaultSkin($val) {
1049         $this->setSetting('bdefskin',$val);
1050     }
1051
1052     function setURL($val) {
1053         $this->setSetting('burl',$val);
1054     }
1055
1056     function setName($val) {
1057         $this->setSetting('bname',$val);
1058     }
1059
1060     function setShortName($val) {
1061         $this->setSetting('bshortname',$val);
1062     }
1063
1064     function setCommentsEnabled($val) {
1065         $this->setSetting('bcomments',$val);
1066     }
1067
1068     function setMaxComments($val) {
1069         $this->setSetting('bmaxcomments',$val);
1070     }
1071
1072     function setNotifyAddress($val) {
1073         $this->setSetting('bnotify',$val);
1074     }
1075
1076     function setEmailRequired($val) {
1077         $this->setSetting('breqemail',$val);
1078     }
1079
1080     function setTimeOffset($val) {
1081         // check validity of value
1082         // 1. replace , by . (common mistake)
1083         $val = str_replace(',','.',$val);
1084         // 2. cast to float or int
1085         if (is_numeric($val) && strstr($val,'.5')) {
1086             $val = (float) $val;
1087         } else {
1088             $val = intval($val);
1089         }
1090
1091         $this->setSetting('btimeoffset',$val);
1092     }
1093
1094     function setDefaultCategory($val) {
1095         $this->setSetting('bdefcat',$val);
1096     }
1097
1098     function getSetting($key) {
1099         return $this->settings[$key];
1100     }
1101
1102     function setSetting($key,$value) {
1103         $this->settings[$key] = $value;
1104     }
1105
1106
1107     // tries to add a member to the team. Returns false if the member was already on
1108     // the team
1109     function addTeamMember($memberid, $admin) {
1110         global $manager;
1111
1112         $memberid = intval($memberid);
1113         $admin = intval($admin);
1114
1115         // check if member is already a member
1116         $tmem = MEMBER::createFromID($memberid);
1117
1118         if ($tmem->isTeamMember($this->getID()))
1119             return 0;
1120
1121         $manager->notify(
1122             'PreAddTeamMember',
1123             array(
1124                 'blog' => &$this,
1125                 'member' => &$tmem,
1126                 'admin' => &$admin
1127             )
1128         );
1129
1130         // add to team
1131         $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1132                . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1133         sql_query($query);
1134
1135         $manager->notify(
1136             'PostAddTeamMember',
1137             array(
1138                 'blog' => &$this,
1139                 'member' => &$tmem,
1140                 'admin' => $admin
1141             )
1142
1143         );
1144
1145         $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1146         ACTIONLOG::add(INFO, $logMsg);
1147
1148         return 1;
1149     }
1150
1151     function getID() {
1152         return intVal($this->blogid);
1153     }
1154
1155     // returns true if there is a blog with the given shortname (static)
1156     function exists($name) {
1157         $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
1158         return (sql_num_rows($r) != 0);
1159     }
1160
1161     // returns true if there is a blog with the given ID (static)
1162     function existsID($id) {
1163         $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1164         return (sql_num_rows($r) != 0);
1165     }
1166
1167         // flag there is a future post pending
1168         function setFuturePost() {
1169         $query =  'UPDATE '.sql_table('blog')
1170                . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1171         sql_query($query);
1172         }
1173
1174     // clear there is a future post pending
1175     function clearFuturePost() {
1176         $query =  'UPDATE '.sql_table('blog')
1177                . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1178         sql_query($query);
1179     }
1180
1181     // check if we should throw justPosted event
1182     function checkJustPosted() {
1183         global $manager;
1184
1185         if ($this->settings['bfuturepost'] == 1) {
1186             $blogid = $this->getID();
1187             $result = sql_query("SELECT * FROM " . sql_table('item')
1188                       . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1189             if (sql_num_rows($result) > 0) {
1190                 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1191                 // Note that the plugins's calling order is subject to thri order in the plugin list
1192                 $pinged = false;
1193                 $manager->notify(
1194                         'JustPosted',
1195                         array('blogid' => $blogid,
1196                         'pinged' => &$pinged
1197                         )
1198                 );
1199
1200                 // clear all expired future posts
1201                 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1202
1203                 // check to see any pending future post, clear the flag is none
1204                 $result = sql_query("SELECT * FROM " . sql_table('item')
1205                           . " WHERE iposted=0 AND iblog=" . $blogid);
1206                 if (sql_num_rows($result) == 0) {
1207                     $this->clearFuturePost();
1208                 }
1209             }
1210         }
1211     }
1212
1213     /**
1214      * Shows the given list of items for this blog
1215      *
1216      * @param $itemarray
1217      *      array of item numbers to be displayed
1218      * @param $template
1219      *      String representing the template _NAME_ (!)
1220      * @param $highlight
1221      *      contains a query that should be highlighted
1222      * @param $comments
1223      *      1=show comments 0=don't show comments
1224      * @param $dateheads
1225      *      1=show dateheads 0=don't show dateheads
1226      * @returns int
1227      *      amount of items shown
1228      */
1229     function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1) {
1230
1231         $query = $this->getSqlItemList($itemarray);
1232
1233         return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1234     }
1235
1236     /**
1237      * Returns the SQL query used to fill out templates for a list of items
1238      *
1239      * @param $itemarray
1240      *      an array holding the item numbers of the items to be displayed
1241      * @returns
1242      *      either a full SQL query, or an empty string
1243      * @note
1244      *      No LIMIT clause is added. (caller should add this if multiple pages are requested)
1245      */
1246     function getSqlItemList($itemarray)
1247     {
1248         if (!is_array($itemarray)) return '';
1249         $items = array();
1250         foreach ($itemarray as $value) {
1251             if (intval($value)) $items[] = intval($value);
1252         }
1253         if (!count($items)) return '';
1254         //$itemlist = implode(',',$items);
1255         $i = count($items);
1256         $query = '';
1257         foreach ($items as $value) {
1258             $query .= '('
1259                     .   'SELECT'
1260                     .   ' i.inumber as itemid,'
1261                     .   ' i.ititle as title,'
1262                     .   ' i.ibody as body,'
1263                     .   ' m.mname as author,'
1264                     .   ' m.mrealname as authorname,'
1265                     .   ' i.itime,'
1266                     .   ' i.imore as more,'
1267                     .   ' m.mnumber as authorid,'
1268                     .   ' m.memail as authormail,'
1269                     .   ' m.murl as authorurl,'
1270                     .   ' c.cname as category,'
1271                     .   ' i.icat as catid,'
1272                     .   ' i.iclosed as closed';
1273
1274             $query .= ' FROM '
1275                     . sql_table('item') . ' as i, '
1276                     . sql_table('member') . ' as m, '
1277                     . sql_table('category').' as c'
1278                     . ' WHERE'
1279                     .     ' i.iblog   = ' . $this->blogid
1280                     . ' and i.iauthor = m.mnumber'
1281                     . ' and i.icat    = c.catid'
1282                     . ' and i.idraft  = 0'  // exclude drafts
1283                         // don't show future items
1284                     . ' and i.itime  <= ' . mysqldate($this->getCorrectTime());
1285
1286             //$query .= ' and i.inumber IN ('.$itemlist.')';
1287             $query .= ' and i.inumber = '.intval($value);
1288             $query .= ')';
1289             $i--;
1290             if ($i) $query .= ' UNION ';
1291         }
1292
1293         return $query;
1294     }
1295
1296 }
1297
1298 ?>