OSDN Git Service

716bd532ec1346ce78442aae3e1845e847dffc30
[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 = 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(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 = 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 = _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 (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 (!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, Month';
578                 if ($mode == 'day')
579                         $query .= ', Day';
580
581
582                 $query .= ' ORDER BY itime DESC';
583
584                 if ($limit > 0)
585                         $query .= ' LIMIT ' . intval($limit);
586
587                 $res = sql_query($query);
588
589                 while ($current = mysql_fetch_object($res)) {
590                         $current->itime = strtotime($current->itime);   // string time -> unix timestamp
591
592                         if ($mode == 'day') {
593                                 $archivedate    = date('Y-m-d',$current->itime);
594                                 $archive['day'] = date('d',$current->itime);
595                                 $data['day']    = date('d',$current->itime);
596                         } else {
597                                 $archivedate = date('Y-m',$current->itime);
598                         }
599                         $data['month'] = date('m',$current->itime);
600                         $data['year'] = date('Y',$current->itime);
601                         $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
602
603                         $manager->notify(
604                                 'PreArchiveListItem',
605                                 array(
606                                         'listitem' => &$data
607                                 )
608                         );
609
610                         $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
611                         echo strftime($temp,$current->itime);
612
613                 }
614
615                 mysql_free_result($res);
616
617                 echo TEMPLATE::fill($template['ARCHIVELIST_FOOTER'],$data);
618         }
619
620
621         /**
622           * Shows the list of categories using a given template
623           */
624         function showCategoryList($template) {
625                 global $CONF, $manager;
626
627                 // determine arguments next to catids
628                 // I guess this can be done in a better way, but it works
629                 global $archive, $archivelist;
630
631                 $linkparams = array();
632                 if ($archive) {
633                         $blogurl = createArchiveLink($this->getID(), $archive, '');
634                         $linkparams['blogid'] = $this->getID();
635                         $linkparams['archive'] = $archive;
636                 } else if ($archivelist) {
637                         $blogurl = createArchiveListLink($this->getID(), '');
638                         $linkparams['archivelist'] = $archivelist;
639                 } else {
640                         $blogurl = createBlogidLink($this->getID(), '');
641                         $linkparams['blogid'] = $this->getID();
642                 }
643
644                 //$blogurl = $this->getURL() . $qargs;
645                 //$blogurl = createBlogLink($this->getURL(), $linkparams);
646
647                 $template =& $manager->getTemplate($template);
648
649                 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
650                                                         array(
651                                                                 'blogid' => $this->getID(),
652                                                                 'blogurl' => $blogurl,
653                                                                 'self' => $CONF['Self']
654                                                         ));
655
656                 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
657                 $res = sql_query($query);
658
659
660                 while ($data = mysql_fetch_assoc($res)) {
661                         $data['blogid'] = $this->getID();
662                         $data['blogurl'] = $blogurl;
663                         $data['catlink'] = createLink(
664                                                                 'category',
665                                                                 array(
666                                                                         'catid' => $data['catid'],
667                                                                         'name' => $data['catname'],
668                                                                         'extra' => $linkparams
669                                                                 )
670                                                            );
671                         $data['self'] = $CONF['Self'];
672
673                         $manager->notify(
674                                 'PreCategoryListItem',
675                                 array(
676                                         'listitem' => &$data
677                                 )
678                         );
679
680                         echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
681                         //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
682                         //echo strftime($temp, $current->itime);
683
684                 }
685
686                 mysql_free_result($res);
687
688                 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
689                                                         array(
690                                                                 'blogid' => $this->getID(),
691                                                                 'blogurl' => $blogurl,
692                                                                 'self' => $CONF['Self']
693                                                         ));
694         }
695
696         /**
697           * Shows a list of all blogs in the system using a given template
698           * ordered by  number, name, shortname or description
699           * in ascending or descending order
700           */
701         function showBlogList($template, $bnametype, $orderby, $direction) {
702                 global $CONF, $manager;
703
704                 switch ($orderby) {
705                         case 'number':
706                                 $orderby='bnumber';
707                                 break;
708                         case 'name':
709                                 $orderby='bname';
710                                 break;
711                         case 'shortname':
712                                 $orderby='bshortname';
713                                 break;
714                         case 'description':
715                                 $orderby='bdesc';
716                                 break;
717                         default:
718                                 $orderby='bnumber';
719                                 break;
720                 }
721
722                 $direction=strtolower($direction);
723                 switch ($direction) {
724                         case 'asc':
725                                 $direction='ASC';
726                                 break;
727                         case 'desc':
728                                 $direction='DESC';
729                                 break;
730                         default:
731                                 $direction='ASC';
732                                 break;
733                 }
734
735                 $template =& $manager->getTemplate($template);
736
737                 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
738                                                         array(
739                                                                 'sitename' => $CONF['SiteName'],
740                                                                 'siteurl' => $CONF['IndexURL']
741                                                         ));
742
743                 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
744                 $res = sql_query($query);
745
746                 while ($data = mysql_fetch_assoc($res)) {
747
748                         $list = array();
749
750 //                      $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
751                         $list['bloglink'] = createBlogidLink($data['bnumber']);
752
753                         $list['blogdesc'] = $data['bdesc'];
754
755                         $list['blogurl'] = $data['burl'];
756
757                         if ($bnametype=='shortname') {
758                                 $list['blogname'] = $data['bshortname'];
759                         }
760                         else { // all other cases
761                                 $list['blogname'] = $data['bname'];
762                         }
763
764                         $manager->notify(
765                                 'PreBlogListItem',
766                                 array(
767                                         'listitem' => &$list
768                                 )
769                         );
770
771                         echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
772
773                 }
774
775                 mysql_free_result($res);
776
777                 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
778                                                         array(
779                                                                 'sitename' => $CONF['SiteName'],
780                                                                 'siteurl' => $CONF['IndexURL']
781                                                         ));
782
783         }
784
785         /**
786           * Blogsettings functions
787           */
788
789         function readSettings() {
790                 $query =  'SELECT *'
791                            . ' FROM '.sql_table('blog')
792                            . ' WHERE bnumber=' . $this->blogid;
793                 $res = sql_query($query);
794
795                 $this->isValid = (mysql_num_rows($res) > 0);
796                 if (!$this->isValid)
797                         return;
798
799                 $this->settings = mysql_fetch_assoc($res);
800         }
801
802         function writeSettings() {
803
804                 // (can't use floatval since not available prior to PHP 4.2)
805                 $offset = $this->getTimeOffset();
806                 if (!is_float($offset))
807                         $offset = intval($offset);
808
809                 $query =  'UPDATE '.sql_table('blog')
810                            . " SET bname='" . addslashes($this->getName()) . "',"
811                            . "     bshortname='". addslashes($this->getShortName()) . "',"
812                            . "     bcomments=". intval($this->commentsEnabled()) . ","
813                            . "     bmaxcomments=" . intval($this->getMaxComments()) . ","
814                            . "     btimeoffset=" . $offset . ","
815                            . "     bpublic=" . intval($this->isPublic()) . ","
816                            . "     breqemail=" . intval($this->emailRequired()) . ","
817                            . "     bsendping=" . intval($this->sendPing()) . ","
818                            . "     bconvertbreaks=" . intval($this->convertBreaks()) . ","
819                            . "     ballowpast=" . intval($this->allowPastPosting()) . ","
820                            . "     bnotify='" . addslashes($this->getNotifyAddress()) . "',"
821                            . "     bnotifytype=" . intval($this->getNotifyType()) . ","
822                            . "     burl='" . addslashes($this->getURL()) . "',"
823                            . "     bupdate='" . addslashes($this->getUpdateFile()) . "',"
824                            . "     bdesc='" . addslashes($this->getDescription()) . "',"
825                            . "     bdefcat=" . intval($this->getDefaultCategory()) . ","
826                            . "     bdefskin=" . intval($this->getDefaultSkin()) . ","
827                            . "     bincludesearch=" . intval($this->getSearchable())
828                            . " WHERE bnumber=" . intval($this->getID());
829                 sql_query($query);
830
831         }
832
833
834
835         // update update file if requested
836         function updateUpdatefile() {
837                  if ($this->getUpdateFile()) {
838                         $f_update = fopen($this->getUpdateFile(),'w');
839                         fputs($f_update,$this->getCorrectTime());
840                         fclose($f_update);
841                  }
842
843         }
844
845         function isValidCategory($catid) {
846                 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
847                 $res = sql_query($query);
848                 return (mysql_num_rows($res) != 0);
849         }
850
851         function getCategoryName($catid) {
852                 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
853                 $o = mysql_fetch_object($res);
854                 return $o->cname;
855         }
856
857         function getCategoryDesc($catid) {
858                 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
859                 $o = mysql_fetch_object($res);
860                 return $o->cdesc;
861         }
862
863         function getCategoryIdFromName($name) {
864                 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . addslashes($name) . '"');
865                 if (mysql_num_rows($res) > 0) {
866                         $o = mysql_fetch_object($res);
867                         return $o->catid;
868                 } else {
869                         return $this->getDefaultCategory();
870                 }
871         }
872
873         function sendPing() {
874                 return $this->getSetting('bsendping');
875         }
876
877         function setPingUserland($val) {
878                 $this->setSetting('bsendping',$val);
879         }
880
881         function convertBreaks() {
882                 return $this->getSetting('bconvertbreaks');
883         }
884
885         function insertJavaScriptInfo($authorid = '') {
886                 global $member, $CONF;
887
888                 if ($authorid == '')
889                         $authorid = $member->getID();
890
891                 ?>
892                 <script type="text/javascript">
893                         setConvertBreaks(<?php echo  $this->convertBreaks() ? 'true' : 'false' ?>);
894                         setMediaUrl("<?php echo $CONF['MediaURL']?>");
895                         setAuthorId(<?php echo $authorid?>);
896                 </script><?php  }
897
898         function setConvertBreaks($val) {
899                 $this->setSetting('bconvertbreaks',$val);
900         }
901         function setAllowPastPosting($val) {
902                 $this->setSetting('ballowpast',$val);
903         }
904         function allowPastPosting() {
905                 return $this->getSetting('ballowpast');
906         }
907
908         function getCorrectTime($t=0) {
909                 if ($t == 0) $t = time();
910                 return ($t + 3600 * $this->getTimeOffset());
911         }
912
913         function getName() {
914                 return $this->getSetting('bname');
915         }
916
917         function getShortName() {
918                 return $this->getSetting('bshortname');
919         }
920
921         function getMaxComments() {
922                 return $this->getSetting('bmaxcomments');
923         }
924
925         function getNotifyAddress() {
926                 return $this->getSetting('bnotify');
927         }
928
929         function getNotifyType() {
930                 return $this->getSetting('bnotifytype');
931         }
932
933         function notifyOnComment() {
934                 $n = $this->getNotifyType();
935                 return (($n != 0) && (($n % 3) == 0));
936         }
937
938         function notifyOnVote() {
939                 $n = $this->getNotifyType();
940                 return (($n != 0) && (($n % 5) == 0));
941         }
942
943         function notifyOnNewItem() {
944                 $n = $this->getNotifyType();
945                 return (($n != 0) && (($n % 7) == 0));
946         }
947
948         function setNotifyType($val) {
949                 $this->setSetting('bnotifytype',$val);
950         }
951
952
953         function getTimeOffset() {
954                 return $this->getSetting('btimeoffset');
955         }
956
957         function commentsEnabled() {
958                 return $this->getSetting('bcomments');
959         }
960
961         function getURL() {
962                 return $this->getSetting('burl');
963         }
964
965         function getDefaultSkin() {
966                 return $this->getSetting('bdefskin');
967         }
968
969         function getUpdateFile() {
970                 return $this->getSetting('bupdate');
971         }
972
973         function getDescription() {
974                 return $this->getSetting('bdesc');
975         }
976
977         function isPublic() {
978                 return $this->getSetting('bpublic');
979         }
980
981         function emailRequired() {
982                 return $this->getSetting('breqemail');
983         }
984
985         function getSearchable() {
986                 return $this->getSetting('bincludesearch');
987         }
988
989         function getDefaultCategory() {
990                 return $this->getSetting('bdefcat');
991         }
992
993         function setPublic($val) {
994                 $this->setSetting('bpublic',$val);
995         }
996
997         function setSearchable($val) {
998                 $this->setSetting('bincludesearch',$val);
999         }
1000
1001         function setDescription($val) {
1002                 $this->setSetting('bdesc',$val);
1003         }
1004
1005         function setUpdateFile($val) {
1006                 $this->setSetting('bupdate',$val);
1007         }
1008
1009         function setDefaultSkin($val) {
1010                 $this->setSetting('bdefskin',$val);
1011         }
1012
1013         function setURL($val) {
1014                 $this->setSetting('burl',$val);
1015         }
1016
1017         function setName($val) {
1018                 $this->setSetting('bname',$val);
1019         }
1020
1021         function setShortName($val) {
1022                 $this->setSetting('bshortname',$val);
1023         }
1024
1025         function setCommentsEnabled($val) {
1026                 $this->setSetting('bcomments',$val);
1027         }
1028
1029         function setMaxComments($val) {
1030                 $this->setSetting('bmaxcomments',$val);
1031         }
1032
1033         function setNotifyAddress($val) {
1034                 $this->setSetting('bnotify',$val);
1035         }
1036
1037         function setEmailRequired($val) {
1038                 $this->setSetting('breqemail',$val);
1039         }
1040
1041         function setTimeOffset($val) {
1042                 // check validity of value
1043                 // 1. replace , by . (common mistake)
1044                 $val = str_replace(',','.',$val);
1045                 // 2. cast to float or int
1046                 if (is_numeric($val) && strstr($val,'.5')) {
1047                         $val = (float) $val;
1048                 } else {
1049                         $val = intval($val);
1050                 }
1051
1052                 $this->setSetting('btimeoffset',$val);
1053         }
1054
1055         function setDefaultCategory($val) {
1056                 $this->setSetting('bdefcat',$val);
1057         }
1058
1059         function getSetting($key) {
1060                 return $this->settings[$key];
1061         }
1062
1063         function setSetting($key,$value) {
1064                 $this->settings[$key] = $value;
1065         }
1066
1067
1068         // tries to add a member to the team. Returns false if the member was already on
1069         // the team
1070         function addTeamMember($memberid, $admin) {
1071                 global $manager;
1072
1073                 $memberid = intval($memberid);
1074                 $admin = intval($admin);
1075
1076                 // check if member is already a member
1077                 $tmem = MEMBER::createFromID($memberid);
1078
1079                 if ($tmem->isTeamMember($this->getID()))
1080                         return 0;
1081
1082                 $manager->notify(
1083                         'PreAddTeamMember',
1084                         array(
1085                                 'blog' => &$this,
1086                                 'member' => &$tmem,
1087                                 'admin' => &$admin
1088                         )
1089                 );
1090
1091                 // add to team
1092                 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1093                            . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1094                 sql_query($query);
1095
1096                 $manager->notify(
1097                         'PostAddTeamMember',
1098                         array(
1099                                 'blog' => &$this,
1100                                 'member' => &$tmem,
1101                                 'admin' => $admin
1102                         )
1103
1104                 );
1105
1106                 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1107                 ACTIONLOG::add(INFO, $logMsg);
1108
1109                 return 1;
1110         }
1111
1112         function getID() {
1113                 return intVal($this->blogid);
1114         }
1115
1116         // returns true if there is a blog with the given shortname (static)
1117         function exists($name) {
1118                 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
1119                 return (mysql_num_rows($r) != 0);
1120         }
1121
1122         // returns true if there is a blog with the given ID (static)
1123         function existsID($id) {
1124                 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1125                 return (mysql_num_rows($r) != 0);
1126         }
1127
1128         // flag there is a future post pending
1129         function setFuturePost() {
1130                 $query =  'UPDATE '.sql_table('blog')
1131                            . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1132                 sql_query($query);
1133         }
1134
1135         // clear there is a future post pending
1136         function clearFuturePost() {
1137                 $query =  'UPDATE '.sql_table('blog')
1138                            . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1139                 sql_query($query);
1140         }
1141
1142         // check if we should throw justPosted event
1143         function checkJustPosted() {
1144                 global $manager;
1145
1146                 if ($this->settings['bfuturepost'] == 1) {
1147                         $blogid = $this->getID();
1148                         $result = sql_query("SELECT * FROM " . sql_table('item')
1149                                   . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1150                         if (mysql_num_rows($result) > 0) {
1151                                 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1152                                 // Note that the plugins's calling order is subject to thri order in the plugin list
1153                                 $pinged = false;
1154                                 $manager->notify(
1155                                                 'JustPosted',
1156                                                 array('blogid' => $blogid,
1157                                                 'pinged' => &$pinged
1158                                                 )
1159                                 );
1160
1161                                 // clear all expired future posts
1162                                 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1163
1164                                 // check to see any pending future post, clear the flag is none
1165                                 $result = sql_query("SELECT * FROM " . sql_table('item')
1166                                           . " WHERE iposted=0 AND iblog=" . $blogid);
1167                                 if (mysql_num_rows($result) == 0) {
1168                                         $this->clearFuturePost();
1169                                 }
1170                         }
1171                 }
1172         }
1173
1174         /**
1175          * Shows the given list of items for this blog
1176          *
1177          * @param $itemarray
1178          *              array of item numbers to be displayed
1179          * @param $template
1180          *              String representing the template _NAME_ (!)
1181          * @param $highlight
1182          *              contains a query that should be highlighted
1183          * @param $comments
1184          *              1=show comments 0=don't show comments
1185          * @param $dateheads
1186          *              1=show dateheads 0=don't show dateheads
1187          * @returns int
1188          *              amount of items shown
1189          */
1190         function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1) {
1191
1192                 $query = $this->getSqlItemList($itemarray);
1193
1194                 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1195         }
1196
1197         /**
1198          * Returns the SQL query used to fill out templates for a list of items
1199          *
1200          * @param $itemarray
1201          *              an array holding the item numbers of the items to be displayed
1202          * @returns
1203          *              either a full SQL query, or an empty string
1204          * @note
1205          *              No LIMIT clause is added. (caller should add this if multiple pages are requested)
1206          */
1207         function getSqlItemList($itemarray)
1208         {
1209                 if (!is_array($itemarray)) return '';
1210                 $items = array();
1211                 foreach ($itemarray as $value) {
1212                         if (intval($value)) $items[] = intval($value);
1213                 }
1214                 if (!count($items)) return '';
1215                 //$itemlist = implode(',',$items);
1216                 $i = count($items);
1217                 $query = '';
1218                 foreach ($items as $value) {
1219                         $query .= '('
1220                                         .   'SELECT'
1221                                         .   ' i.inumber as itemid,'
1222                                         .   ' i.ititle as title,'
1223                                         .   ' i.ibody as body,'
1224                                         .   ' m.mname as author,'
1225                                         .   ' m.mrealname as authorname,'
1226                                         .   ' i.itime,'
1227                                         .   ' i.imore as more,'
1228                                         .   ' m.mnumber as authorid,'
1229                                         .   ' m.memail as authormail,'
1230                                         .   ' m.murl as authorurl,'
1231                                         .   ' c.cname as category,'
1232                                         .   ' i.icat as catid,'
1233                                         .   ' i.iclosed as closed';
1234
1235                         $query .= ' FROM '
1236                                         . sql_table('item') . ' as i, '
1237                                         . sql_table('member') . ' as m, '
1238                                         . sql_table('category').' as c'
1239                                     . ' WHERE'
1240                                         .     ' i.iblog   = ' . $this->blogid
1241                                     . ' and i.iauthor = m.mnumber'
1242                                     . ' and i.icat    = c.catid'
1243                                     . ' and i.idraft  = 0'      // exclude drafts
1244                                                 // don't show future items
1245                                     . ' and i.itime  <= ' . mysqldate($this->getCorrectTime());
1246
1247                         //$query .= ' and i.inumber IN ('.$itemlist.')';
1248                         $query .= ' and i.inumber = '.intval($value);
1249                         $query .= ')';
1250                         $i--;
1251                         if ($i) $query .= ' UNION ';
1252                 }
1253
1254                 return $query;
1255         }
1256
1257 }
1258
1259 ?>