OSDN Git Service

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