OSDN Git Service

merged from v3.31sp1
[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-2007 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-2007 The Nucleus Group
19  * @version $Id: BLOG.php,v 1.15 2008-02-08 09:31:22 kimitake Exp $
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 = mysql_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($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 = mysql_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                 mysql_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 = mysql_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 = 'New category') {
337                 global $member, $manager;
338
339                 if ($member->blogAdminRights($this->getID())) {
340                         // generate
341                         if ($catName == '')
342                         {
343                                 $catName = 'newcat';
344                                 $i = 1;
345
346                                 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
347                                 while (mysql_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 = mysql_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 ($catid)
557                         $linkparams = array('catid' => $catid);
558
559                 $template =& $manager->getTemplate($template);
560                 $data['blogid'] = $this->getID();
561
562                 echo TEMPLATE::fill($template['ARCHIVELIST_HEADER'],$data);
563
564                 $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')
565                 . ' WHERE iblog=' . $this->getID()
566                 . ' and itime <=' . mysqldate($this->getCorrectTime())  // don't show future items!
567                 . ' and idraft=0'; // don't show draft items
568
569                 if ($catid)
570                         $query .= ' and icat=' . intval($catid);
571
572                 $query .= ' GROUP BY Year, Month';
573                 if ($mode == 'day')
574                         $query .= ', Day';
575
576
577                 $query .= ' ORDER BY itime DESC';
578
579                 if ($limit > 0)
580                         $query .= ' LIMIT ' . intval($limit);
581
582                 $res = sql_query($query);
583
584                 while ($current = mysql_fetch_object($res)) {
585                         $current->itime = strtotime($current->itime);   // string time -> unix timestamp
586
587                         if ($mode == 'day') {
588                                 $archivedate = date('Y-m-d',$current->itime);
589                                 $archive['day'] = date('d',$current->itime);
590                         } else {
591                                 $archivedate = date('Y-m',$current->itime);
592                         }
593                         $data['month'] = date('m',$current->itime);
594                         $data['year'] = date('Y',$current->itime);
595                         $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
596
597                         $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
598                         echo strftime($temp,$current->itime);
599
600                 }
601
602                 mysql_free_result($res);
603
604                 echo TEMPLATE::fill($template['ARCHIVELIST_FOOTER'],$data);
605         }
606
607
608         /**
609           * Shows the list of categories using a given template
610           */
611         function showCategoryList($template) {
612                 global $CONF, $manager;
613
614                 // determine arguments next to catids
615                 // I guess this can be done in a better way, but it works
616                 global $archive, $archivelist;
617
618                 $linkparams = array();
619                 if ($archive) {
620                         $blogurl = createArchiveLink($this->getID(), $archive, '');
621                         $linkparams['blogid'] = $this->getID();
622                         $linkparams['archive'] = $archive;
623                 } else if ($archivelist) {
624                         $blogurl = createArchiveListLink($this->getID(), '');
625                         $linkparams['archivelist'] = $archivelist;
626                 } else {
627                         $blogurl = createBlogidLink($this->getID(), '');
628                         $linkparams['blogid'] = $this->getID();
629                 }
630
631                 //$blogurl = $this->getURL() . $qargs;
632                 //$blogurl = createBlogLink($this->getURL(), $linkparams);
633
634                 $template =& $manager->getTemplate($template);
635
636                 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
637                                                         array(
638                                                                 'blogid' => $this->getID(),
639                                                                 'blogurl' => $blogurl,
640                                                                 'self' => $CONF['Self']
641                                                         ));
642
643                 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
644                 $res = sql_query($query);
645
646
647                 while ($data = mysql_fetch_assoc($res)) {
648                         $data['blogid'] = $this->getID();
649                         $data['blogurl'] = $blogurl;
650                         $data['catlink'] = createLink(
651                                                                 'category',
652                                                                 array(
653                                                                         'catid' => $data['catid'],
654                                                                         'name' => $data['catname'],
655                                                                         'extra' => $linkparams
656                                                                 )
657                                                            );
658                         $data['self'] = $CONF['Self'];
659
660                         echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
661                         //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
662                         //echo strftime($temp, $current->itime);
663
664                 }
665
666                 mysql_free_result($res);
667
668                 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
669                                                         array(
670                                                                 'blogid' => $this->getID(),
671                                                                 'blogurl' => $blogurl,
672                                                                 'self' => $CONF['Self']
673                                                         ));
674         }
675         
676         /**
677           * Shows a list of all blogs in the system using a given template
678           */
679         function showBlogList($template, $bnametype) {
680                 global $CONF, $manager;
681                 
682                 $template =& $manager->getTemplate($template);
683                 
684                 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
685                                                         array(
686                                                                 'sitename' => $CONF['SiteName'],
687                                                                 'siteurl' => $CONF['IndexURL']
688                                                         ));
689                 
690                 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY bnumber ASC';
691                 $res = sql_query($query);
692                 
693                 while ($data = mysql_fetch_assoc($res)) {
694                 
695                         $list = array();
696                 
697 //                      $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
698                         $list['bloglink'] = createBlogidLink($data['bnumber']);
699                 
700                         $list['blogdesc'] = $data['bdesc'];
701                         
702                         if ($bnametype=='shortname') {
703                                 $list['blogname'] = $data['bshortname'];
704                         }
705                         else { // all other cases
706                                 $list['blogname'] = $data['bname'];
707                         }
708                         
709                         echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
710                         
711                 }
712                 
713                 mysql_free_result($res);
714                 
715                 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
716                                                         array(
717                                                                 'sitename' => $CONF['SiteName'],
718                                                                 'siteurl' => $CONF['IndexURL']
719                                                         ));
720
721         }
722
723         /**
724           * Blogsettings functions
725           */
726
727         function readSettings() {
728                 $query =  'SELECT *'
729                            . ' FROM '.sql_table('blog')
730                            . ' WHERE bnumber=' . $this->blogid;
731                 $res = sql_query($query);
732
733                 $this->isValid = (mysql_num_rows($res) > 0);
734                 if (!$this->isValid)
735                         return;
736
737                 $this->settings = mysql_fetch_assoc($res);
738         }
739
740         function writeSettings() {
741
742                 // (can't use floatval since not available prior to PHP 4.2)
743                 $offset = $this->getTimeOffset();
744                 if (!is_float($offset))
745                         $offset = intval($offset);
746
747                 $query =  'UPDATE '.sql_table('blog')
748                            . " SET bname='" . addslashes($this->getName()) . "',"
749                            . "     bshortname='". addslashes($this->getShortName()) . "',"
750                            . "     bcomments=". intval($this->commentsEnabled()) . ","
751                            . "     bmaxcomments=" . intval($this->getMaxComments()) . ","
752                            . "     btimeoffset=" . $offset . ","
753                            . "     bpublic=" . intval($this->isPublic()) . ","
754                            . "     breqemail=" . intval($this->emailRequired()) . ","
755                            . "     bsendping=" . intval($this->sendPing()) . ","
756                            . "     bconvertbreaks=" . intval($this->convertBreaks()) . ","
757                            . "     ballowpast=" . intval($this->allowPastPosting()) . ","
758                            . "     bnotify='" . addslashes($this->getNotifyAddress()) . "',"
759                            . "     bnotifytype=" . intval($this->getNotifyType()) . ","
760                            . "     burl='" . addslashes($this->getURL()) . "',"
761                            . "     bupdate='" . addslashes($this->getUpdateFile()) . "',"
762                            . "     bdesc='" . addslashes($this->getDescription()) . "',"
763                            . "     bdefcat=" . intval($this->getDefaultCategory()) . ","
764                            . "     bdefskin=" . intval($this->getDefaultSkin()) . ","
765                            . "     bincludesearch=" . intval($this->getSearchable())
766                            . " WHERE bnumber=" . intval($this->getID());
767                 sql_query($query);
768
769         }
770
771
772
773         // update update file if requested
774         function updateUpdatefile() {
775                  if ($this->getUpdateFile()) {
776                         $f_update = fopen($this->getUpdateFile(),'w');
777                         fputs($f_update,$this->getCorrectTime());
778                         fclose($f_update);
779                  }
780
781         }
782
783         function isValidCategory($catid) {
784                 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
785                 $res = sql_query($query);
786                 return (mysql_num_rows($res) != 0);
787         }
788
789         function getCategoryName($catid) {
790                 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
791                 $o = mysql_fetch_object($res);
792                 return $o->cname;
793         }
794
795         function getCategoryDesc($catid) {
796                 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
797                 $o = mysql_fetch_object($res);
798                 return $o->cdesc;
799         }
800
801         function getCategoryIdFromName($name) {
802                 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . addslashes($name) . '"');
803                 if (mysql_num_rows($res) > 0) {
804                         $o = mysql_fetch_object($res);
805                         return $o->catid;
806                 } else {
807                         return $this->getDefaultCategory();
808                 }
809         }
810
811         function sendPing() {
812                 return $this->getSetting('bsendping');
813         }
814
815         function setPingUserland($val) {
816                 $this->setSetting('bsendping',$val);
817         }
818
819         function convertBreaks() {
820                 return $this->getSetting('bconvertbreaks');
821         }
822
823         function insertJavaScriptInfo($authorid = '') {
824                 global $member, $CONF;
825
826                 if ($authorid == '')
827                         $authorid = $member->getID();
828
829                 ?>
830                 <script type="text/javascript">
831                         setConvertBreaks(<?php echo  $this->convertBreaks() ? 'true' : 'false' ?>);
832                         setMediaUrl("<?php echo $CONF['MediaURL']?>");
833                         setAuthorId(<?php echo $authorid?>);
834                 </script><?php  }
835
836         function setConvertBreaks($val) {
837                 $this->setSetting('bconvertbreaks',$val);
838         }
839         function setAllowPastPosting($val) {
840                 $this->setSetting('ballowpast',$val);
841         }
842         function allowPastPosting() {
843                 return $this->getSetting('ballowpast');
844         }
845
846         function getCorrectTime($t=0) {
847                 if ($t == 0) $t = time();
848                 return ($t + 3600 * $this->getTimeOffset());
849         }
850
851         function getName() {
852                 return $this->getSetting('bname');
853         }
854
855         function getShortName() {
856                 return $this->getSetting('bshortname');
857         }
858
859         function getMaxComments() {
860                 return $this->getSetting('bmaxcomments');
861         }
862
863         function getNotifyAddress() {
864                 return $this->getSetting('bnotify');
865         }
866
867         function getNotifyType() {
868                 return $this->getSetting('bnotifytype');
869         }
870
871         function notifyOnComment() {
872                 $n = $this->getNotifyType();
873                 return (($n != 0) && (($n % 3) == 0));
874         }
875
876         function notifyOnVote() {
877                 $n = $this->getNotifyType();
878                 return (($n != 0) && (($n % 5) == 0));
879         }
880
881         function notifyOnNewItem() {
882                 $n = $this->getNotifyType();
883                 return (($n != 0) && (($n % 7) == 0));
884         }
885
886         function setNotifyType($val) {
887                 $this->setSetting('bnotifytype',$val);
888         }
889
890
891         function getTimeOffset() {
892                 return $this->getSetting('btimeoffset');
893         }
894
895         function commentsEnabled() {
896                 return $this->getSetting('bcomments');
897         }
898
899         function getURL() {
900                 return $this->getSetting('burl');
901         }
902
903         function getDefaultSkin() {
904                 return $this->getSetting('bdefskin');
905         }
906
907         function getUpdateFile() {
908                 return $this->getSetting('bupdate');
909         }
910
911         function getDescription() {
912                 return $this->getSetting('bdesc');
913         }
914
915         function isPublic() {
916                 return $this->getSetting('bpublic');
917         }
918
919         function emailRequired() {
920                 return $this->getSetting('breqemail');
921         }
922
923         function getSearchable() {
924                 return $this->getSetting('bincludesearch');
925         }
926
927         function getDefaultCategory() {
928                 return $this->getSetting('bdefcat');
929         }
930
931         function setPublic($val) {
932                 $this->setSetting('bpublic',$val);
933         }
934
935         function setSearchable($val) {
936                 $this->setSetting('bincludesearch',$val);
937         }
938
939         function setDescription($val) {
940                 $this->setSetting('bdesc',$val);
941         }
942
943         function setUpdateFile($val) {
944                 $this->setSetting('bupdate',$val);
945         }
946
947         function setDefaultSkin($val) {
948                 $this->setSetting('bdefskin',$val);
949         }
950
951         function setURL($val) {
952                 $this->setSetting('burl',$val);
953         }
954
955         function setName($val) {
956                 $this->setSetting('bname',$val);
957         }
958
959         function setShortName($val) {
960                 $this->setSetting('bshortname',$val);
961         }
962
963         function setCommentsEnabled($val) {
964                 $this->setSetting('bcomments',$val);
965         }
966
967         function setMaxComments($val) {
968                 $this->setSetting('bmaxcomments',$val);
969         }
970
971         function setNotifyAddress($val) {
972                 $this->setSetting('bnotify',$val);
973         }
974
975         function setEmailRequired($val) {
976                 $this->setSetting('breqemail',$val);
977         }
978
979         function setTimeOffset($val) {
980                 // check validity of value
981                 // 1. replace , by . (common mistake)
982                 $val = str_replace(',','.',$val);
983                 // 2. cast to float or int
984                 if (is_numeric($val) && strstr($val,'.5')) {
985                         $val = (float) $val;
986                 } else {
987                         $val = intval($val);
988                 }
989
990                 $this->setSetting('btimeoffset',$val);
991         }
992
993         function setDefaultCategory($val) {
994                 $this->setSetting('bdefcat',$val);
995         }
996
997         function getSetting($key) {
998                 return $this->settings[$key];
999         }
1000
1001         function setSetting($key,$value) {
1002                 $this->settings[$key] = $value;
1003         }
1004
1005
1006         // tries to add a member to the team. Returns false if the member was already on
1007         // the team
1008         function addTeamMember($memberid, $admin) {
1009                 global $manager;
1010
1011                 $memberid = intval($memberid);
1012                 $admin = intval($admin);
1013
1014                 // check if member is already a member
1015                 $tmem = MEMBER::createFromID($memberid);
1016
1017                 if ($tmem->isTeamMember($this->getID()))
1018                         return 0;
1019
1020                 $manager->notify(
1021                         'PreAddTeamMember',
1022                         array(
1023                                 'blog' => &$this,
1024                                 'member' => &$tmem,
1025                                 'admin' => &$admin
1026                         )
1027                 );
1028
1029                 // add to team
1030                 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1031                            . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1032                 sql_query($query);
1033
1034                 $manager->notify(
1035                         'PostAddTeamMember',
1036                         array(
1037                                 'blog' => &$this,
1038                                 'member' => &$tmem,
1039                                 'admin' => $admin
1040                         )
1041
1042                 );
1043
1044                 ACTIONLOG::add(INFO, 'Added ' . $tmem->getDisplayName() . ' (ID=' .
1045                                            $memberid .') to the team of blog "' . $this->getName() . '"');
1046
1047                 return 1;
1048         }
1049
1050         function getID() {
1051                 return intVal($this->blogid);
1052         }
1053
1054         // returns true if there is a blog with the given shortname (static)
1055         function exists($name) {
1056                 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
1057                 return (mysql_num_rows($r) != 0);
1058         }
1059
1060         // returns true if there is a blog with the given ID (static)
1061         function existsID($id) {
1062                 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1063                 return (mysql_num_rows($r) != 0);
1064         }
1065
1066         // flag there is a future post pending
1067         function setFuturePost() {
1068                 $query =  'UPDATE '.sql_table('blog')
1069                            . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1070                 sql_query($query);
1071         }
1072
1073         // clear there is a future post pending
1074         function clearFuturePost() {
1075                 $query =  'UPDATE '.sql_table('blog')
1076                            . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1077                 sql_query($query);
1078         }
1079
1080         // check if we should throw justPosted event
1081         function checkJustPosted() {
1082                 global $manager;
1083
1084                 if ($this->settings['bfuturepost'] == 1) {
1085                         $blogid = $this->getID();
1086                         $result = sql_query("SELECT * FROM " . sql_table('item')
1087                                   . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1088                         if (mysql_num_rows($result) > 0) {
1089                                 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1090                                 // Note that the plugins's calling order is subject to thri order in the plugin list
1091                                 $pinged = false;
1092                                 $manager->notify(
1093                                                 'JustPosted',
1094                                                 array('blogid' => $blogid,
1095                                                 'pinged' => &$pinged
1096                                                 )
1097                                 );
1098
1099                                 // clear all expired future posts
1100                                 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1101
1102                                 // check to see any pending future post, clear the flag is none 
1103                                 $result = sql_query("SELECT * FROM " . sql_table('item') 
1104                                           . " WHERE iposted=0 AND iblog=" . $blogid);
1105                                 if (mysql_num_rows($result) == 0) {
1106                                         $this->clearFuturePost();
1107                                 }
1108                         }
1109                 }
1110         }
1111
1112 }
1113
1114 ?>