OSDN Git Service

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