OSDN Git Service

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