OSDN Git Service

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