OSDN Git Service

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