OSDN Git Service

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