OSDN Git Service

git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/nucleus-jp/trunk@1211 1ca29...
[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-2011 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-2011 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 = strftimejp(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 = strftimejp((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                 $ititle = sql_real_escape_string($title);
271                 $ibody = sql_real_escape_string($body);
272                 $imore = sql_real_escape_string($more);
273
274                 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
275                            . "VALUES ('$ititle', '$ibody', '$imore', $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, $title, $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() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($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 strftimejp($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                 //: Change: Set nocatselected variable
671                 if ($this->getSelectedCategory()) {
672                         $nocatselected = 'no';
673                 }
674                 else {
675                         $nocatselected = 'yes';
676                 } 
677
678                 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
679                                                         array(
680                                                                 'blogid' => $this->getID(),
681                                                                 'blogurl' => $blogurl,
682                                                                 'self' => $CONF['Self'],
683                                                                 //: Change: Set catiscurrent template variable for header
684                                                                 'catiscurrent' => $nocatselected,
685                                                                 'currentcat' => $nocatselected 
686                                                         ));
687
688                 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
689                 $res = sql_query($query);
690
691
692                 while ($data = sql_fetch_assoc($res)) {
693                         $data['blogid'] = $this->getID();
694                         $data['blogurl'] = $blogurl;
695                         $data['catlink'] = createLink(
696                                                                 'category',
697                                                                 array(
698                                                                         'catid' => $data['catid'],
699                                                                         'name' => $data['catname'],
700                                                                         'extra' => $linkparams
701                                                                 )
702                                                         );
703                         $data['self'] = $CONF['Self'];
704                         
705                         //catiscurrent
706                         //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
707                         $data['catiscurrent'] = 'no';
708                         $data['currentcat'] = 'no'; 
709                         if ($this->getSelectedCategory()) {
710                                 if ($this->getSelectedCategory() == $data['catid']) {
711                                         $data['catiscurrent'] = 'yes';
712                                         $data['currentcat'] = 'yes';
713                                 }
714                                 /*else {
715                                         $data['catiscurrent'] = 'no';
716                                         $data['currentcat'] = 'no';
717                                 }*/
718                         }
719                         else {
720                                 global $itemid;
721                                 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
722                                         $iobj =& $manager->getItem(intval($itemid),0,0);
723                                         $cid = $iobj['catid'];
724                                         if ($cid == $data['catid']) {
725                                                 $data['catiscurrent'] = 'yes';
726                                                 $data['currentcat'] = 'yes';
727                                         }
728                                         /*else {
729                                                 $data['catiscurrent'] = 'no';
730                                                 $data['currentcat'] = 'no';
731                                         }*/
732                                 }
733                         }
734
735                         $manager->notify(
736                                 'PreCategoryListItem',
737                                 array(
738                                         'listitem' => &$data
739                                 )
740                         );
741
742                         echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
743                         //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
744                         //echo strftime($temp, $current->itime);
745
746                 }
747
748                 sql_free_result($res);
749
750                 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
751                                                         array(
752                                                                 'blogid' => $this->getID(),
753                                                                 'blogurl' => $blogurl,
754                                                                 'self' => $CONF['Self']
755                                                         ));
756         }
757
758         /**
759           * Shows a list of all blogs in the system using a given template
760           * ordered by  number, name, shortname or description
761           * in ascending or descending order
762           */
763         function showBlogList($template, $bnametype, $orderby, $direction) {
764                 global $CONF, $manager;
765
766                 switch ($orderby) {
767                         case 'number':
768                                 $orderby='bnumber';
769                                 break;
770                         case 'name':
771                                 $orderby='bname';
772                                 break;
773                         case 'shortname':
774                                 $orderby='bshortname';
775                                 break;
776                         case 'description':
777                                 $orderby='bdesc';
778                                 break;
779                         default:
780                                 $orderby='bnumber';
781                                 break;
782                 }
783
784                 $direction=strtolower($direction);
785                 switch ($direction) {
786                         case 'asc':
787                                 $direction='ASC';
788                                 break;
789                         case 'desc':
790                                 $direction='DESC';
791                                 break;
792                         default:
793                                 $direction='ASC';
794                                 break;
795                 }
796
797                 $template =& $manager->getTemplate($template);
798
799                 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
800                                                         array(
801                                                                 'sitename' => $CONF['SiteName'],
802                                                                 'siteurl' => $CONF['IndexURL']
803                                                         ));
804
805                 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
806                 $res = sql_query($query);
807
808                 while ($data = sql_fetch_assoc($res)) {
809
810                         $list = array();
811
812 //                      $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
813                         $list['bloglink'] = createBlogidLink($data['bnumber']);
814
815                         $list['blogdesc'] = $data['bdesc'];
816
817                         $list['blogurl'] = $data['burl'];
818
819                         if ($bnametype=='shortname') {
820                                 $list['blogname'] = $data['bshortname'];
821                         }
822                         else { // all other cases
823                                 $list['blogname'] = $data['bname'];
824                         }
825
826                         $manager->notify(
827                                 'PreBlogListItem',
828                                 array(
829                                         'listitem' => &$list
830                                 )
831                         );
832
833                         echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
834
835                 }
836
837                 sql_free_result($res);
838
839                 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
840                                                         array(
841                                                                 'sitename' => $CONF['SiteName'],
842                                                                 'siteurl' => $CONF['IndexURL']
843                                                         ));
844
845         }
846
847         /**
848           * Blogsettings functions
849           */
850
851         function readSettings() {
852                 $query =  'SELECT *'
853                            . ' FROM '.sql_table('blog')
854                            . ' WHERE bnumber=' . $this->blogid;
855                 $res = sql_query($query);
856
857                 $this->isValid = (sql_num_rows($res) > 0);
858                 if (!$this->isValid)
859                         return;
860
861                 $this->settings = sql_fetch_assoc($res);
862         }
863
864         function writeSettings() {
865
866                 // (can't use floatval since not available prior to PHP 4.2)
867                 $offset = $this->getTimeOffset();
868                 if (!is_float($offset))
869                         $offset = intval($offset);
870
871                 $query =  'UPDATE '.sql_table('blog')
872                            . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
873                            . "   bshortname='". sql_real_escape_string($this->getShortName()) . "',"
874                            . "   bcomments=". intval($this->commentsEnabled()) . ","
875                            . "   bmaxcomments=" . intval($this->getMaxComments()) . ","
876                            . "   btimeoffset=" . $offset . ","
877                            . "   bpublic=" . intval($this->isPublic()) . ","
878                            . "   breqemail=" . intval($this->emailRequired()) . ","
879                            . "   bconvertbreaks=" . intval($this->convertBreaks()) . ","
880                            . "   ballowpast=" . intval($this->allowPastPosting()) . ","
881                            . "   bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
882                            . "   bnotifytype=" . intval($this->getNotifyType()) . ","
883                            . "   burl='" . sql_real_escape_string($this->getURL()) . "',"
884                            . "   bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
885                            . "   bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
886                            . "   bdefcat=" . intval($this->getDefaultCategory()) . ","
887                            . "   bdefskin=" . intval($this->getDefaultSkin()) . ","
888                            . "   bincludesearch=" . intval($this->getSearchable())
889                            . " WHERE bnumber=" . intval($this->getID());
890                 sql_query($query);
891
892         }
893
894
895
896         // update update file if requested
897         function updateUpdatefile() {
898                  if ($this->getUpdateFile()) {
899                         $f_update = fopen($this->getUpdateFile(),'w');
900                         fputs($f_update,$this->getCorrectTime());
901                         fclose($f_update);
902                  }
903
904         }
905
906         function isValidCategory($catid) {
907                 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
908                 $res = sql_query($query);
909                 return (sql_num_rows($res) != 0);
910         }
911
912         function getCategoryName($catid) {
913                 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
914                 $o = sql_fetch_object($res);
915                 return $o->cname;
916         }
917
918         function getCategoryDesc($catid) {
919                 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
920                 $o = sql_fetch_object($res);
921                 return $o->cdesc;
922         }
923
924         function getCategoryIdFromName($name) {
925                 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
926                 if (sql_num_rows($res) > 0) {
927                         $o = sql_fetch_object($res);
928                         return $o->catid;
929                 } else {
930                         return $this->getDefaultCategory();
931                 }
932         }
933
934         function convertBreaks() {
935                 return $this->getSetting('bconvertbreaks');
936         }
937
938         function insertJavaScriptInfo($authorid = '') {
939                 global $member, $CONF;
940
941                 if ($authorid == '')
942                         $authorid = $member->getID();
943
944                 ?>
945                 <script type="text/javascript">
946                         setConvertBreaks(<?php echo  $this->convertBreaks() ? 'true' : 'false' ?>);
947                         setMediaUrl("<?php echo $CONF['MediaURL']?>");
948                         setAuthorId(<?php echo $authorid?>);
949                 </script><?php  }
950
951         function setConvertBreaks($val) {
952                 $this->setSetting('bconvertbreaks',$val);
953         }
954         function setAllowPastPosting($val) {
955                 $this->setSetting('ballowpast',$val);
956         }
957         function allowPastPosting() {
958                 return $this->getSetting('ballowpast');
959         }
960
961         function getCorrectTime($t=0) {
962                 if ($t == 0) $t = time();
963                 return ($t + 3600 * $this->getTimeOffset());
964         }
965
966         function getName() {
967                 return $this->getSetting('bname');
968         }
969
970         function getShortName() {
971                 return $this->getSetting('bshortname');
972         }
973
974         function getMaxComments() {
975                 return $this->getSetting('bmaxcomments');
976         }
977
978         function getNotifyAddress() {
979                 return $this->getSetting('bnotify');
980         }
981
982         function getNotifyType() {
983                 return $this->getSetting('bnotifytype');
984         }
985
986         function notifyOnComment() {
987                 $n = $this->getNotifyType();
988                 return (($n != 0) && (($n % 3) == 0));
989         }
990
991         function notifyOnVote() {
992                 $n = $this->getNotifyType();
993                 return (($n != 0) && (($n % 5) == 0));
994         }
995
996         function notifyOnNewItem() {
997                 $n = $this->getNotifyType();
998                 return (($n != 0) && (($n % 7) == 0));
999         }
1000
1001         function setNotifyType($val) {
1002                 $this->setSetting('bnotifytype',$val);
1003         }
1004
1005
1006         function getTimeOffset() {
1007                 return $this->getSetting('btimeoffset');
1008         }
1009
1010         function commentsEnabled() {
1011                 return $this->getSetting('bcomments');
1012         }
1013
1014         function getURL() {
1015                 return $this->getSetting('burl');
1016         }
1017
1018         function getDefaultSkin() {
1019                 return $this->getSetting('bdefskin');
1020         }
1021
1022         function getUpdateFile() {
1023                 return $this->getSetting('bupdate');
1024         }
1025
1026         function getDescription() {
1027                 return $this->getSetting('bdesc');
1028         }
1029
1030         function isPublic() {
1031                 return $this->getSetting('bpublic');
1032         }
1033
1034         function emailRequired() {
1035                 return $this->getSetting('breqemail');
1036         }
1037
1038         function getSearchable() {
1039                 return $this->getSetting('bincludesearch');
1040         }
1041
1042         function getDefaultCategory() {
1043                 return $this->getSetting('bdefcat');
1044         }
1045
1046         function setPublic($val) {
1047                 $this->setSetting('bpublic',$val);
1048         }
1049
1050         function setSearchable($val) {
1051                 $this->setSetting('bincludesearch',$val);
1052         }
1053
1054         function setDescription($val) {
1055                 $this->setSetting('bdesc',$val);
1056         }
1057
1058         function setUpdateFile($val) {
1059                 $this->setSetting('bupdate',$val);
1060         }
1061
1062         function setDefaultSkin($val) {
1063                 $this->setSetting('bdefskin',$val);
1064         }
1065
1066         function setURL($val) {
1067                 $this->setSetting('burl',$val);
1068         }
1069
1070         function setName($val) {
1071                 $this->setSetting('bname',$val);
1072         }
1073
1074         function setShortName($val) {
1075                 $this->setSetting('bshortname',$val);
1076         }
1077
1078         function setCommentsEnabled($val) {
1079                 $this->setSetting('bcomments',$val);
1080         }
1081
1082         function setMaxComments($val) {
1083                 $this->setSetting('bmaxcomments',$val);
1084         }
1085
1086         function setNotifyAddress($val) {
1087                 $this->setSetting('bnotify',$val);
1088         }
1089
1090         function setEmailRequired($val) {
1091                 $this->setSetting('breqemail',$val);
1092         }
1093
1094         function setTimeOffset($val) {
1095                 // check validity of value
1096                 // 1. replace , by . (common mistake)
1097                 $val = str_replace(',','.',$val);
1098                 // 2. cast to float or int
1099                 if (is_numeric($val) && strstr($val,'.5')) {
1100                         $val = (float) $val;
1101                 } else {
1102                         $val = intval($val);
1103                 }
1104
1105                 $this->setSetting('btimeoffset',$val);
1106         }
1107
1108         function setDefaultCategory($val) {
1109                 $this->setSetting('bdefcat',$val);
1110         }
1111
1112         function getSetting($key) {
1113                 return $this->settings[$key];
1114         }
1115
1116         function setSetting($key,$value) {
1117                 $this->settings[$key] = $value;
1118         }
1119
1120
1121         // tries to add a member to the team. Returns false if the member was already on
1122         // the team
1123         function addTeamMember($memberid, $admin) {
1124                 global $manager;
1125
1126                 $memberid = intval($memberid);
1127                 $admin = intval($admin);
1128
1129                 // check if member is already a member
1130                 $tmem = MEMBER::createFromID($memberid);
1131
1132                 if ($tmem->isTeamMember($this->getID()))
1133                         return 0;
1134
1135                 $manager->notify(
1136                         'PreAddTeamMember',
1137                         array(
1138                                 'blog' => &$this,
1139                                 'member' => &$tmem,
1140                                 'admin' => &$admin
1141                         )
1142                 );
1143
1144                 // add to team
1145                 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1146                            . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1147                 sql_query($query);
1148
1149                 $manager->notify(
1150                         'PostAddTeamMember',
1151                         array(
1152                                 'blog' => &$this,
1153                                 'member' => &$tmem,
1154                                 'admin' => $admin
1155                         )
1156
1157                 );
1158
1159                 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1160                 ACTIONLOG::add(INFO, $logMsg);
1161
1162                 return 1;
1163         }
1164
1165         function getID() {
1166                 return intVal($this->blogid);
1167         }
1168
1169         // returns true if there is a blog with the given shortname (static)
1170         function exists($name) {
1171                 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1172                 return (sql_num_rows($r) != 0);
1173         }
1174
1175         // returns true if there is a blog with the given ID (static)
1176         function existsID($id) {
1177                 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1178                 return (sql_num_rows($r) != 0);
1179         }
1180
1181                 // flag there is a future post pending
1182                 function setFuturePost() {
1183                 $query =  'UPDATE '.sql_table('blog')
1184                            . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1185                 sql_query($query);
1186                 }
1187
1188         // clear there is a future post pending
1189         function clearFuturePost() {
1190                 $query =  'UPDATE '.sql_table('blog')
1191                            . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1192                 sql_query($query);
1193         }
1194
1195         // check if we should throw justPosted event
1196         function checkJustPosted() {
1197                 global $manager;
1198
1199                 if ($this->settings['bfuturepost'] == 1) {
1200                         $blogid = $this->getID();
1201                         $result = sql_query("SELECT * FROM " . sql_table('item')
1202                                           . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1203                         if (sql_num_rows($result) > 0) {
1204                                 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1205                                 // Note that the plugins's calling order is subject to thri order in the plugin list
1206                                 $pinged = false;
1207                                 $manager->notify(
1208                                                 'JustPosted',
1209                                                 array('blogid' => $blogid,
1210                                                 'pinged' => &$pinged
1211                                                 )
1212                                 );
1213
1214                                 // clear all expired future posts
1215                                 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1216
1217                                 // check to see any pending future post, clear the flag is none
1218                                 $result = sql_query("SELECT * FROM " . sql_table('item')
1219                                                   . " WHERE iposted=0 AND iblog=" . $blogid);
1220                                 if (sql_num_rows($result) == 0) {
1221                                         $this->clearFuturePost();
1222                                 }
1223                         }
1224                 }
1225         }
1226
1227         /**
1228          * Shows the given list of items for this blog
1229          *
1230          * @param $itemarray
1231          *        array of item numbers to be displayed
1232          * @param $template
1233          *        String representing the template _NAME_ (!)
1234          * @param $highlight
1235          *        contains a query that should be highlighted
1236          * @param $comments
1237          *        1=show comments 0=don't show comments
1238          * @param $dateheads
1239          *        1=show dateheads 0=don't show dateheads
1240          * @param $showDrafts
1241          *              0=do not show drafts 1=show drafts
1242          * @param $showFuture
1243          *              0=do not show future posts 1=show future posts
1244          * @returns int
1245          *        amount of items shown
1246          */
1247         function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1248                 
1249                 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1250                 
1251                 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1252         }
1253
1254         /**
1255          * Returns the SQL query used to fill out templates for a list of items
1256          *
1257          * @param $itemarray
1258          *        an array holding the item numbers of the items to be displayed
1259          * @param $showDrafts
1260          *              0=do not show drafts 1=show drafts
1261          * @param $showFuture
1262          *              0=do not show future posts 1=show future posts
1263          * @returns
1264          *        either a full SQL query, or an empty string
1265          * @note
1266          *        No LIMIT clause is added. (caller should add this if multiple pages are requested)
1267          */
1268         function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1269         {
1270                 if (!is_array($itemarray)) return '';
1271                 $showDrafts = intval($showDrafts);
1272                 $showFuture = intval($showFuture);
1273                 $items = array();
1274                 foreach ($itemarray as $value) {
1275                         if (intval($value)) $items[] = intval($value);
1276                 }
1277                 if (!count($items)) return '';
1278                 //$itemlist = implode(',',$items);
1279                 $i = count($items);
1280                 $query = '';
1281                 foreach ($items as $value) {
1282                         $query .= '('
1283                                         .   'SELECT'
1284                                         .   ' i.inumber as itemid,'
1285                                         .   ' i.ititle as title,'
1286                                         .   ' i.ibody as body,'
1287                                         .   ' m.mname as author,'
1288                                         .   ' m.mrealname as authorname,'
1289                                         .   ' i.itime,'
1290                                         .   ' i.imore as more,'
1291                                         .   ' m.mnumber as authorid,'
1292                                         .   ' m.memail as authormail,'
1293                                         .   ' m.murl as authorurl,'
1294                                         .   ' c.cname as category,'
1295                                         .   ' i.icat as catid,'
1296                                         .   ' i.iclosed as closed';
1297
1298                         $query .= ' FROM '
1299                                         . sql_table('item') . ' as i, '
1300                                         . sql_table('member') . ' as m, '
1301                                         . sql_table('category').' as c'
1302                                         . ' WHERE'
1303                                         .        ' i.iblog   = ' . $this->blogid
1304                                         . ' and i.iauthor = m.mnumber'
1305                                         . ' and i.icat  = c.catid';
1306                         
1307                         if (!$showDrafts) $query .= ' and i.idraft=0';  // exclude drafts
1308                         if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1309
1310                         //$query .= ' and i.inumber IN ('.$itemlist.')';
1311                         $query .= ' and i.inumber = '.intval($value);
1312                         $query .= ')';
1313                         $i--;
1314                         if ($i) $query .= ' UNION ';
1315                 }
1316
1317                 return $query;
1318         }
1319
1320 }
1321
1322 ?>