4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2012 The Nucleus Group
\r
7 * This program is free software; you can redistribute it and/or
\r
8 * modify it under the terms of the GNU General Public License
\r
9 * as published by the Free Software Foundation; either version 2
\r
10 * of the License, or (at your option) any later version.
\r
11 * (see nucleus/documentation/index.html#license for more info)
\r
14 * A class representing a blog and containing functions to get that blog shown
\r
17 * @license http://nucleuscms.org/license.txt GNU General Public License
\r
18 * @copyright Copyright (C) 2002-2009 The Nucleus Group
\r
19 * @version $Id: BLOG.php 1624 2012-01-09 11:36:20Z sakamocchi $
\r
22 if ( !function_exists('requestVar') ) exit;
\r
23 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
\r
30 // ID of currently selected category
\r
33 // After creating an object of the blog class, contains true if the BLOG object is
\r
34 // valid (the blog exists)
\r
37 // associative array, containing all blogsettings (use the get/set functions instead)
\r
41 * Creates a new BLOG object for the given blog
\r
45 function BLOG($id) {
\r
46 $this->blogid = intval($id);
\r
47 $this->readSettings();
\r
50 // (the parse functions in SKIN.php will override this, so it's mainly useless)
\r
52 $this->setSelectedCategory($catid);
\r
56 * Shows the given amount of items for this blog
\r
59 * String representing the template _NAME_ (!)
\r
60 * @param $amountEntries
\r
61 * amount of entries to show
\r
63 * offset from where items should be shown (e.g. 5 = start at fifth item)
\r
65 * amount of items shown
\r
67 function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
\r
68 return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
\r
72 * Blog::showArchive()
\r
73 * Shows an archive for a given month
\r
75 * @param integer $year year
\r
76 * @param integer $month month
\r
77 * @param string $template String representing the template name to be used
\r
81 function showArchive($templatename, $year, $month=0, $day=0)
\r
83 // create extra where clause for select query
\r
84 if ( $day == 0 && $month != 0 )
\r
86 $timestamp_start = mktime(0,0,0,$month,1,$year);
\r
87 // also works when $month==12
\r
88 $timestamp_end = mktime(0,0,0,$month+1,1,$year);
\r
90 elseif ( $month == 0 )
\r
92 $timestamp_start = mktime(0,0,0,1,1,$year);
\r
93 // also works when $month==12
\r
94 $timestamp_end = mktime(0,0,0,12,31,$year);
\r
98 $timestamp_start = mktime(0,0,0,$month,$day,$year);
\r
99 $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
\r
101 $extra_query = " and i.itime>='%s' and i.itime<'%s'";
\r
102 $extra_query = sprintf($extra_query, i18n::formatted_datetime('mysql', $timestamp_start), i18n::formatted_datetime('mysql', $timestamp_end));
\r
104 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
\r
109 * Sets the selected category by id (only when category exists)
\r
111 function setSelectedCategory($catid) {
\r
112 if ($this->isValidCategory($catid) || (intval($catid) == 0))
\r
113 $this->selectedcatid = intval($catid);
\r
117 * Sets the selected category by name
\r
119 function setSelectedCategoryByName($catname) {
\r
120 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
\r
124 * Returns the selected category
\r
126 function getSelectedCategory() {
\r
127 return $this->selectedcatid;
\r
131 * Shows the given amount of items for this blog
\r
134 * String representing the template _NAME_ (!)
\r
135 * @param $amountEntries
\r
136 * amount of entries to show (0 = no limit)
\r
137 * @param $extraQuery
\r
138 * extra conditions to be added to the query
\r
139 * @param $highlight
\r
140 * contains a query that should be highlighted
\r
142 * 1=show comments 0=don't show comments
\r
143 * @param $dateheads
\r
144 * 1=show dateheads 0=don't show dateheads
\r
148 * amount of items shown
\r
150 function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
\r
152 $query = $this->getSqlBlog($extraQuery);
\r
154 if ($amountEntries > 0) {
\r
155 // $offset zou moeten worden:
\r
156 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
\r
157 $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
\r
159 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
\r
163 * Blog::showUsingQuery()
\r
164 * Do the job for readLogAmmount
\r
166 * @param string $templateName template name
\r
167 * @param string $query string for query
\r
168 * @param string $highlight string to be highlighted
\r
169 * @param integer $comments the number of comments
\r
170 * @param boolean $dateheads date header is needed or not
\r
171 * @return integer the number of rows as a result of mysql query
\r
174 function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1)
\r
176 global $CONF, $manager, $currentTemplateName;
\r
178 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
\r
179 if ( $lastVisit != 0 )
\r
181 $lastVisit = $this->getCorrectTime($lastVisit);
\r
184 // set templatename as global variable (so plugins can access it)
\r
185 $currentTemplateName = $templateName;
\r
186 $template =& $manager->getTemplate($templateName);
\r
188 // create parser object & action handler
\r
189 $actions = new ItemActions($this);
\r
190 $parser = new Parser($actions->getDefinedActions(),$actions);
\r
191 $actions->setTemplate($template);
\r
192 $actions->setHighlight($highlight);
\r
193 $actions->setLastVisit($lastVisit);
\r
194 $actions->setParser($parser);
\r
195 $actions->setShowComments($comments);
\r
198 $items = sql_query($query);
\r
200 // loop over all items
\r
202 while ( $item = sql_fetch_object($items) )
\r
204 $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
\r
206 // action handler needs to know the item we're handling
\r
207 $actions->setCurrentItem($item);
\r
209 // add date header if needed
\r
212 $new_date = date('dFY',$item->timestamp);
\r
213 if ( $new_date != $old_date )
\r
215 // unless this is the first time, write date footer
\r
216 $timestamp = $item->timestamp;
\r
217 if ( $old_date != 0 )
\r
219 $oldTS = strtotime($old_date);
\r
220 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
\r
222 if ( !in_array('DATE_FOOTER', $template) || !empty($template['DATE_FOOTER']) )
\r
224 $tmp_footer = i18n::formatted_datetime('', $oldTS);
\r
228 $tmp_footer = i18n::formatted_datetime($template['DATE_FOOTER'], $oldTS);
\r
230 $parser->parse($tmp_footer);
\r
231 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
\r
234 $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
\r
236 // note, to use templatvars in the dateheader, the %-characters need to be doubled in
\r
237 // order to be preserved by strftime
\r
238 if ( !in_array('DATE_HEADER', $template) || !empty($template['DATE_HEADER']) )
\r
240 $tmp_footer = i18n::formatted_datetime('', $timestamp);
\r
244 $tmp_footer = i18n::formatted_datetime($template['DATE_FOOTER'], $timestamp);
\r
247 $parser->parse($tmp_header);
\r
248 $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
\r
250 $old_date = $new_date;
\r
254 $parser->parse($template['ITEM_HEADER']);
\r
255 $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));
\r
256 $parser->parse($template['ITEM']);
\r
257 $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));
\r
258 $parser->parse($template['ITEM_FOOTER']);
\r
261 $numrows = sql_num_rows($items);
\r
263 // add another date footer if there was at least one item
\r
264 if ( ($numrows > 0) && $dateheads )
\r
266 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
\r
267 $parser->parse($template['DATE_FOOTER']);
\r
268 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
\r
271 sql_free_result($items);
\r
276 * Simplified function for showing only one item
\r
278 function showOneitem($itemid, $template, $highlight) {
\r
279 $extraQuery = ' and inumber=' . intval($itemid);
\r
281 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
\r
287 * Adds an item to this blog
\r
289 * @param Integer $catid ID for category
\r
290 * @param String $title ID for
\r
291 * @param String $body text for body
\r
292 * @param String $more text for more
\r
293 * @param Integer $blogid ID for blog
\r
294 * @param Integer $authorid ID for author
\r
295 * @param Timestamp $timestamp UNIX timestamp for post
\r
296 * @param Boolean $closed opened or closed
\r
297 * @param Boolean $draft draft or not
\r
298 * @param Boolean $posted posted or not
\r
301 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1')
\r
305 $blogid = intval($blogid);
\r
306 $authorid = intval($authorid);
\r
310 $catid = intval($catid);
\r
312 // convert newlines to <br />
\r
313 if ( $this->convertBreaks() )
\r
315 $body = addBreaks($body);
\r
316 $more = addBreaks($more);
\r
319 if ( $closed != '1' )
\r
323 if ( $draft != '0' )
\r
328 if ( !$this->isValidCategory($catid) )
\r
330 $catid = $this->getDefaultCategory();
\r
333 if ( $timestamp > $this->getCorrectTime() )
\r
338 $timestamp = date('Y-m-d H:i:s',$timestamp);
\r
340 $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
\r
342 $ititle = sql_real_escape_string($title);
\r
343 $ibody = sql_real_escape_string($body);
\r
344 $imore = sql_real_escape_string($more);
\r
346 $query = "INSERT INTO %s (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) VALUES ('%s', '%s', '%s', %d, %d, '%s', %s, %s, %s, %s)";
\r
347 $query = sprintf($query, sql_table('item'), $ititle, $ibody, $imore, $blogid, $authorid, $timestamp, $closed, $draft, $catid, $posted);
\r
349 $itemid = sql_insert_id();
\r
351 $manager->notify('PostAddItem',array('itemid' => $itemid));
\r
355 $this->updateUpdateFile();
\r
357 // send notification mail
\r
358 if ( !$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem() )
\r
360 $this->sendNewItemNotification($itemid, $title, $body);
\r
366 * Blog::sendNewItemNotification()
\r
367 * Send a new item notification to the notification list
\r
369 * @param String $itemid ID of the item
\r
370 * @param String $title title of the item
\r
371 * @param String $body body of the item
\r
374 function sendNewItemNotification($itemid, $title, $body)
\r
376 global $CONF, $member;
\r
378 $ascii = Entity::anchor_footnoting($body);
\r
380 $message = _NOTIFY_NI_MSG . " \n";
\r
381 $temp = parse_url($CONF['Self']);
\r
382 if ( $temp['scheme'] )
\r
384 $message .= Link::create_item_link($itemid) . "\n\n";
\r
388 $tempurl = $this->getURL();
\r
389 if ( i18n::substr($tempurl, -1) == '/' || i18n::substr($tempurl, -4) == '.php' )
\r
391 $message .= $tempurl . '?itemid=' . $itemid . "\n\n";
\r
395 $message .= $tempurl . '/?itemid=' . $itemid . "\n\n";
\r
398 $message .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
\r
399 $message .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
\r
400 $message .= NOTIFICATION::get_mail_footer();
\r
402 $subject = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
\r
404 $from = $member->getNotifyFromMailAddress();
\r
406 NOTIFICATION::mail($this->getNotifyAddress(), $subject, $message, $from, i18n::get_current_charset());
\r
411 * Blog::createNewCategory()
\r
412 * Creates a new category for this blog
\r
414 * @param String $catName name of the new category. When empty, a name is generated automatically (starting with newcat)
\r
415 * @param String $catDescription description of the new category. Defaults to 'New Category'
\r
416 * @returns Integer the new category-id in case of success. 0 on failure
\r
418 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC)
\r
420 global $member, $manager;
\r
422 if ( $member->blogAdminRights($this->getID()) )
\r
425 if ( $catName == '' )
\r
427 $catName = _CREATED_NEW_CATEGORY_NAME;
\r
430 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
\r
431 while ( sql_num_rows($res) > 0 )
\r
434 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
\r
437 $catName = $catName . $i;
\r
444 'name' => &$catName,
\r
445 'description' => $catDescription
\r
449 $query = "INSERT INTO %s (cblog, cname, cdesc) VALUES (%d, '%s', '%s')";
\r
450 $query = sprintf($query, sql_table('category'), (integer) $this->getID(), sql_real_escape_string($catName), sql_real_escape_string($catDescription));
\r
452 $catid = sql_insert_id();
\r
458 'name' => $catName,
\r
459 'description' => $catDescription,
\r
470 * Searches all months of this blog for the given query
\r
475 * template to be used (__NAME__ of the template)
\r
476 * @param $amountMonths
\r
477 * max amount of months to be search (0 = all)
\r
478 * @param $maxresults
\r
479 * max number of results to show
\r
483 * amount of hits found
\r
485 function search($query, $template, $amountMonths, $maxresults, $startpos) {
\r
486 global $CONF, $manager;
\r
489 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
\r
491 if ($sqlquery == '')
\r
493 // no query -> show everything
\r
495 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
\r
498 // add LIMIT to query (to split search results into pages)
\r
499 if (intval($maxresults > 0))
\r
500 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
\r
503 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
\r
505 // when no results were found, show a message
\r
506 if ($amountfound == 0)
\r
508 $template =& $manager->getTemplate($template);
\r
510 'query' => Entity::hsc($query),
\r
511 'blogid' => $this->getID()
\r
513 echo Template::fill($template['SEARCH_NOTHINGFOUND'],$vars);
\r
517 return $amountfound;
\r
521 * Blog::getSqlSearch()
\r
522 * Returns an SQL query to use for a search query
\r
523 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
\r
525 * @param string $query search query
\r
526 * @param integer $amountMonths amount of months to search back. Default = 0 = unlimited
\r
527 * @param string $mode either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
\r
528 * @return string $highlight words to highlight (out parameter)
\r
529 * @return string either a full SQL query, or an empty string (if querystring empty)
\r
531 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
\r
533 $searchclass = new Search($query);
\r
535 $highlight = $searchclass->inclusive;
\r
537 // if querystring is empty, return empty string
\r
538 if ( $searchclass->inclusive == '' )
\r
543 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
\r
544 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
\r
546 // get list of blogs to search
\r
547 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
\r
548 $blogs[] = $this->getID(); // also search current blog (duh)
\r
549 $blogs = array_unique($blogs); // remove duplicates
\r
551 if ( count($blogs) > 0 )
\r
553 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
\r
558 $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, i.itime, i.imore as more, i.icat as catid, i.iclosed as closed,
\r
559 m.mname as author, m.mrealname as authorname, m.mnumber as authorid, m.memail as authormail, m.murl as authorurl,
\r
560 c.cname as category';
\r
564 $query .= ', '.$select. ' as score ';
\r
569 $query = 'SELECT COUNT(*) as result ';
\r
572 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
\r
573 . ' WHERE i.iauthor=m.mnumber'
\r
574 . ' and i.icat=c.catid'
\r
576 . ' and i.idraft=0'
\r
578 // don't show future items
\r
579 . ' and i.itime<="' . i18n::formatted_datetime('mysql', $this->getCorrectTime()) . '"'
\r
582 // take into account amount of months to search
\r
583 if ( $amountMonths > 0 )
\r
585 $localtime = getdate($this->getCorrectTime());
\r
586 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
\r
587 $query .= ' and i.itime>"' . i18n::formatted_datetime('mysql', $timestamp_start) . '"';
\r
594 $query .= ' ORDER BY score DESC';
\r
598 $query .= ' ORDER BY i.itime DESC ';
\r
606 * Blog::getSqlBlog()
\r
607 * Returns the SQL query that's normally used to display the blog items on the index type skins
\r
608 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
\r
610 * @param string $extraQuery extra query string
\r
611 * @param string $mode either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
\r
612 * @return string either a full SQL query, or an empty string
\r
614 function getSqlBlog($extraQuery, $mode = '')
\r
618 $query = 'SELECT i.inumber as itemid, i.ititle as title, i.ibody as body, m.mname as author,
\r
619 m.mrealname as authorname, i.itime, i.imore as more, m.mnumber as authorid, m.memail as authormail,
\r
620 m.murl as authorurl, c.cname as category, i.icat as catid, i.iclosed as closed';
\r
624 $query = 'SELECT COUNT(*) as result ';
\r
627 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
\r
628 . ' WHERE i.iblog='.$this->blogid
\r
629 . ' and i.iauthor=m.mnumber'
\r
630 . ' and i.icat=c.catid'
\r
632 . ' and i.idraft=0'
\r
633 // don't show future items
\r
634 . ' and i.itime<="' . i18n::formatted_datetime('mysql', $this->getCorrectTime()) . '"';
\r
636 if ( $this->getSelectedCategory() )
\r
638 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
\r
641 $query .= $extraQuery;
\r
645 $query .= ' ORDER BY i.itime DESC';
\r
651 * Blog::showArchiveList()
\r
652 * Shows the archivelist using the given template
\r
654 * @param String $template template name
\r
655 * @param String $mode year/month/day
\r
656 * @param Integer $limit limit of record count
\r
659 function showArchiveList($template, $mode = 'month', $limit = 0)
\r
661 global $CONF, $catid, $manager;
\r
663 if ( !isset ($linkparams) )
\r
665 $linkparams = array();
\r
670 $linkparams = array('catid' => $catid);
\r
673 $template =& $manager->getTemplate($template);
\r
674 $data['blogid'] = $this->getID();
\r
676 if ( !array_key_exists('ARCHIVELIST_HEADER', $template) || !$template['ARCHIVELIST_HEADER'] )
\r
682 $tplt = $template['ARCHIVELIST_HEADER'];
\r
685 echo Template::fill($tplt, $data);
\r
687 $query = 'SELECT itime, SUBSTRING(itime,1,4) AS Year, SUBSTRING(itime,6,2) AS Month, SUBSTRING(itime,9,2) AS Day'
\r
688 . ' FROM '.sql_table('item')
\r
689 . ' WHERE iblog=' . $this->getID()
\r
690 // don't show future items!
\r
691 . ' AND itime <="' . i18n::formatted_datetime('mysql', $this->getCorrectTime()) . '"'
\r
692 // don't show draft items
\r
697 $query .= ' and icat=' . intval($catid);
\r
700 $query .= ' GROUP BY Year';
\r
701 if ( $mode == 'month' || $mode == 'day' )
\r
703 $query .= ', Month';
\r
705 if ( $mode == 'day' )
\r
710 $query .= ' ORDER BY itime DESC';
\r
714 $query .= ' LIMIT ' . intval($limit);
\r
717 $res = sql_query($query);
\r
718 while ( $current = sql_fetch_object($res) )
\r
720 /* string time -> unix timestamp */
\r
721 $current->itime = strtotime($current->itime);
\r
723 if ( $mode == 'day' )
\r
725 $archivedate = date('Y-m-d',$current->itime);
\r
726 $archive['day'] = date('d',$current->itime);
\r
727 $data['day'] = date('d',$current->itime);
\r
728 $data['month'] = date('m',$current->itime);
\r
729 $archive['month'] = $data['month'];
\r
731 elseif ( $mode == 'year' )
\r
733 $archivedate = date('Y',$current->itime);
\r
735 $data['month'] = '';
\r
736 $archive['day'] = '';
\r
737 $archive['month'] = '';
\r
741 $archivedate = date('Y-m',$current->itime);
\r
742 $data['month'] = date('m',$current->itime);
\r
743 $archive['month'] = $data['month'];
\r
745 $archive['day'] = '';
\r
748 $data['year'] = date('Y',$current->itime);
\r
749 $archive['year'] = $data['year'];
\r
750 $data['archivelink'] = Link::create_archive_link($this->getID(),$archivedate,$linkparams);
\r
753 'PreArchiveListItem',
\r
755 'listitem' => &$data
\r
759 $temp = Template::fill($template['ARCHIVELIST_LISTITEM'],$data);
\r
760 echo i18n::formatted_datetime($temp, $current->itime);
\r
764 sql_free_result($res);
\r
766 if ( !array_key_exists('ARCHIVELIST_FOOTER', $template) || !$template['ARCHIVELIST_FOOTER'] )
\r
772 $tplt = $template['ARCHIVELIST_FOOTER'];
\r
775 echo Template::fill($tplt, $data);
\r
780 * Blog::showCategoryList()
\r
781 * Shows the list of categories using a given template
\r
783 * @param string $template Template Name
\r
786 function showCategoryList($template)
\r
788 global $CONF, $manager;
\r
791 * determine arguments next to catids
\r
792 * I guess this can be done in a better way, but it works
\r
794 global $archive, $archivelist;
\r
796 $linkparams = array();
\r
799 $blogurl = Link::create_archive_link($this->getID(), $archive, '');
\r
800 $linkparams['blogid'] = $this->getID();
\r
801 $linkparams['archive'] = $archive;
\r
803 else if ( $archivelist )
\r
805 $blogurl = Link::create_archivelist_link($this->getID(), '');
\r
806 $linkparams['archivelist'] = $archivelist;
\r
810 $blogurl = Link::create_blogid_link($this->getID(), '');
\r
811 $linkparams['blogid'] = $this->getID();
\r
814 $template =& $manager->getTemplate($template);
\r
816 //: Change: Set nocatselected variable
\r
817 if ( $this->getSelectedCategory() )
\r
819 $nocatselected = 'no';
\r
823 $nocatselected = 'yes';
\r
827 'blogid' => $this->getID(),
\r
828 'blogurl' => $blogurl,
\r
829 'self' => $CONF['Self'],
\r
830 //: Change: Set catiscurrent template variable for header
\r
831 'catiscurrent' => $nocatselected,
\r
832 'currentcat' => $nocatselected
\r
835 /* output header of category list item */
\r
836 if ( !array_key_exists('CATLIST_HEADER', $template) || empty($template['CATLIST_HEADER']) )
\r
838 echo Template::fill(NULL, $args);
\r
842 echo Template::fill($template['CATLIST_HEADER'], $args);
\r
845 $query = "SELECT catid, cdesc as catdesc, cname as catname FROM %s WHERE cblog=%d ORDER BY cname ASC;";
\r
846 $query = sprintf($query, sql_table('category'), (integer) $this->getID());
\r
847 $res = sql_query($query);
\r
849 while ( $data = sql_fetch_assoc($res) )
\r
852 'catid' => $data['catid'],
\r
853 'name' => $data['catname'],
\r
854 'extra' => $linkparams
\r
857 $data['blogid'] = $this->getID();
\r
858 $data['blogurl'] = $blogurl;
\r
859 $data['catlink'] = Link::create_link('category', $args);
\r
860 $data['self'] = $CONF['Self'];
\r
862 // this gives catiscurrent = no when no category is selected.
\r
863 $data['catiscurrent'] = 'no';
\r
864 $data['currentcat'] = 'no';
\r
866 if ( $this->getSelectedCategory() )
\r
868 if ( $this->getSelectedCategory() == $data['catid'] )
\r
870 $data['catiscurrent'] = 'yes';
\r
871 $data['currentcat'] = 'yes';
\r
877 if ( intval($itemid) && $manager->existsItem(intval($itemid), 0, 0) )
\r
879 $iobj =& $manager->getItem(intval($itemid), 0, 0);
\r
880 $cid = $iobj['catid'];
\r
882 if ( $cid == $data['catid'] )
\r
884 $data['catiscurrent'] = 'yes';
\r
885 $data['currentcat'] = 'yes';
\r
891 'PreCategoryListItem',
\r
893 'listitem' => &$data
\r
896 if ( !array_key_exists('CATLIST_LISTITEM', $template) || empty($template['CATLIST_LISTITEM']))
\r
898 echo Template::fill(NULL, $data);
\r
902 echo Template::fill($template['CATLIST_LISTITEM'], $data);
\r
906 sql_free_result($res);
\r
909 'blogid' => $this->getID(),
\r
910 'blogurl' => $blogurl,
\r
911 'self' => $CONF['Self'],
\r
912 //: Change: Set catiscurrent template variable for footer
\r
913 'catiscurrent' => $nocatselected,
\r
914 'currentcat' => $nocatselected
\r
917 if ( !array_key_exists('CATLIST_FOOTER', $template) || empty($template['CATLIST_FOOTER']))
\r
919 echo Template::fill(NULL, $args);
\r
923 echo Template::fill($template['CATLIST_FOOTER'], $args);
\r
930 * Blog::showBlogList()
\r
931 * Shows a list of all blogs in the system using a given template
\r
932 * ordered by number, name, shortname or description
\r
933 * in ascending or descending order
\r
935 * @param String $template tempalte name
\r
936 * @param String $bnametype bname/bshortname
\r
937 * @param String $orderby string for 'ORDER BY' SQL
\r
938 * @param String $direction ASC/DESC
\r
941 function showBlogList($template, $bnametype, $orderby, $direction)
\r
943 global $CONF, $manager;
\r
945 switch ( $orderby )
\r
948 $orderby='bnumber';
\r
954 $orderby='bshortname';
\r
956 case 'description':
\r
960 $orderby='bnumber';
\r
964 $direction=strtolower($direction);
\r
965 switch ( $direction )
\r
978 $template =& $manager->getTemplate($template);
\r
980 echo Template::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
\r
982 'sitename' => $CONF['SiteName'],
\r
983 'siteurl' => $CONF['IndexURL']
\r
987 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
\r
988 $res = sql_query($query);
\r
990 while ( $data = sql_fetch_assoc($res) )
\r
993 $list['bloglink'] = Link::create_blogid_link($data['bnumber']);
\r
994 $list['blogdesc'] = $data['bdesc'];
\r
995 $list['blogurl'] = $data['burl'];
\r
997 if ( $bnametype == 'shortname' )
\r
999 $list['blogname'] = $data['bshortname'];
\r
1003 /* all other cases */
\r
1004 $list['blogname'] = $data['bname'];
\r
1008 'PreBlogListItem',
\r
1010 'listitem' => &$list
\r
1014 echo Template::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
\r
1017 sql_free_result($res);
\r
1019 echo Template::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
\r
1021 'sitename' => $CONF['SiteName'],
\r
1022 'siteurl' => $CONF['IndexURL']
\r
1029 * Read the blog settings
\r
1031 function readSettings() {
\r
1032 $query = 'SELECT *'
\r
1033 . ' FROM '.sql_table('blog')
\r
1034 . ' WHERE bnumber=' . $this->blogid;
\r
1035 $res = sql_query($query);
\r
1037 $this->isValid = (sql_num_rows($res) > 0);
\r
1038 if (!$this->isValid)
\r
1041 $this->settings = sql_fetch_assoc($res);
\r
1045 * Write the blog settings
\r
1047 function writeSettings() {
\r
1049 // (can't use floatval since not available prior to PHP 4.2)
\r
1050 $offset = $this->getTimeOffset();
\r
1051 if (!is_float($offset))
\r
1052 $offset = intval($offset);
\r
1054 $query = 'UPDATE '.sql_table('blog')
\r
1055 . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
\r
1056 . " bshortname='". sql_real_escape_string($this->getShortName()) . "',"
\r
1057 . " bcomments=". intval($this->commentsEnabled()) . ","
\r
1058 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
\r
1059 . " btimeoffset=" . $offset . ","
\r
1060 . " bpublic=" . intval($this->isPublic()) . ","
\r
1061 . " breqemail=" . intval($this->emailRequired()) . ","
\r
1062 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
\r
1063 . " ballowpast=" . intval($this->allowPastPosting()) . ","
\r
1064 . " bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
\r
1065 . " bnotifytype=" . intval($this->getNotifyType()) . ","
\r
1066 . " burl='" . sql_real_escape_string($this->getURL()) . "',"
\r
1067 . " bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
\r
1068 . " bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
\r
1069 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
\r
1070 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
\r
1071 . " bincludesearch=" . intval($this->getSearchable())
\r
1072 . " WHERE bnumber=" . intval($this->getID());
\r
1073 sql_query($query);
\r
1078 * Update the update file if requested
\r
1080 function updateUpdatefile() {
\r
1081 if ($this->getUpdateFile()) {
\r
1082 $f_update = fopen($this->getUpdateFile(),'w');
\r
1083 fputs($f_update,$this->getCorrectTime());
\r
1084 fclose($f_update);
\r
1090 * Check if a category with a given catid is valid
\r
1095 function isValidCategory($catid) {
\r
1096 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
\r
1097 $res = sql_query($query);
\r
1098 return (sql_num_rows($res) != 0);
\r
1102 * Get the category name for a given catid
\r
1107 function getCategoryName($catid) {
\r
1108 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
\r
1109 $o = sql_fetch_object($res);
\r
1114 * Get the category description for a given catid
\r
1119 function getCategoryDesc($catid) {
\r
1120 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
\r
1121 $o = sql_fetch_object($res);
\r
1126 * Get the category id for a given category name
\r
1131 function getCategoryIdFromName($name) {
\r
1132 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
\r
1133 if (sql_num_rows($res) > 0) {
\r
1134 $o = sql_fetch_object($res);
\r
1137 return $this->getDefaultCategory();
\r
1142 * Get the the setting for the line break handling
\r
1143 * [should be named as getConvertBreaks()]
\r
1145 function convertBreaks() {
\r
1146 return $this->getSetting('bconvertbreaks');
\r
1150 * Set the the setting for the line break handling
\r
1153 * new value for bconvertbreaks
\r
1155 function setConvertBreaks($val) {
\r
1156 $this->setSetting('bconvertbreaks',$val);
\r
1160 * Insert a javascript that includes information about the settings
\r
1161 * of an author: ConvertBreaks, MediaUrl and AuthorId
\r
1163 * @param $authorid
\r
1164 * id of the author
\r
1166 function insertJavaScriptInfo($authorid = '') {
\r
1167 global $member, $CONF;
\r
1169 if ($authorid == '')
\r
1170 $authorid = $member->getID();
\r
1173 <script type="text/javascript">
\r
1174 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
\r
1175 setMediaUrl("<?php echo $CONF['MediaURL']?>");
\r
1176 setAuthorId(<?php echo $authorid?>);
\r
1181 * Set the the setting for allowing to publish postings in the past
\r
1184 * new value for ballowpast
\r
1186 function setAllowPastPosting($val) {
\r
1187 $this->setSetting('ballowpast',$val);
\r
1191 * Get the the setting if it is allowed to publish postings in the past
\r
1192 * [should be named as getAllowPastPosting()]
\r
1194 function allowPastPosting() {
\r
1195 return $this->getSetting('ballowpast');
\r
1198 function getCorrectTime($t=0) {
\r
1199 if ($t == 0) $t = time();
\r
1200 return ($t + 3600 * $this->getTimeOffset());
\r
1203 function getName() {
\r
1204 return $this->getSetting('bname');
\r
1207 function getShortName() {
\r
1208 return $this->getSetting('bshortname');
\r
1211 function getMaxComments() {
\r
1212 return $this->getSetting('bmaxcomments');
\r
1215 function getNotifyAddress() {
\r
1216 return $this->getSetting('bnotify');
\r
1219 function getNotifyType() {
\r
1220 return $this->getSetting('bnotifytype');
\r
1223 function notifyOnComment() {
\r
1224 $n = $this->getNotifyType();
\r
1225 return (($n != 0) && (($n % 3) == 0));
\r
1228 function notifyOnVote() {
\r
1229 $n = $this->getNotifyType();
\r
1230 return (($n != 0) && (($n % 5) == 0));
\r
1233 function notifyOnNewItem() {
\r
1234 $n = $this->getNotifyType();
\r
1235 return (($n != 0) && (($n % 7) == 0));
\r
1238 function setNotifyType($val) {
\r
1239 $this->setSetting('bnotifytype',$val);
\r
1243 function getTimeOffset() {
\r
1244 return $this->getSetting('btimeoffset');
\r
1247 function commentsEnabled() {
\r
1248 return $this->getSetting('bcomments');
\r
1251 function getURL() {
\r
1252 return $this->getSetting('burl');
\r
1255 function getDefaultSkin() {
\r
1256 return $this->getSetting('bdefskin');
\r
1259 function getUpdateFile() {
\r
1260 return $this->getSetting('bupdate');
\r
1263 function getDescription() {
\r
1264 return $this->getSetting('bdesc');
\r
1267 function isPublic() {
\r
1268 return $this->getSetting('bpublic');
\r
1271 function emailRequired() {
\r
1272 return $this->getSetting('breqemail');
\r
1275 function getSearchable() {
\r
1276 return $this->getSetting('bincludesearch');
\r
1279 function getDefaultCategory() {
\r
1280 return $this->getSetting('bdefcat');
\r
1283 function setPublic($val) {
\r
1284 $this->setSetting('bpublic',$val);
\r
1287 function setSearchable($val) {
\r
1288 $this->setSetting('bincludesearch',$val);
\r
1291 function setDescription($val) {
\r
1292 $this->setSetting('bdesc',$val);
\r
1295 function setUpdateFile($val) {
\r
1296 $this->setSetting('bupdate',$val);
\r
1299 function setDefaultSkin($val) {
\r
1300 $this->setSetting('bdefskin',$val);
\r
1303 function setURL($val) {
\r
1304 $this->setSetting('burl',$val);
\r
1307 function setName($val) {
\r
1308 $this->setSetting('bname',$val);
\r
1311 function setShortName($val) {
\r
1312 $this->setSetting('bshortname',$val);
\r
1315 function setCommentsEnabled($val) {
\r
1316 $this->setSetting('bcomments',$val);
\r
1319 function setMaxComments($val) {
\r
1320 $this->setSetting('bmaxcomments',$val);
\r
1323 function setNotifyAddress($val) {
\r
1324 $this->setSetting('bnotify',$val);
\r
1327 function setEmailRequired($val) {
\r
1328 $this->setSetting('breqemail',$val);
\r
1331 function setTimeOffset($val) {
\r
1332 // check validity of value
\r
1333 // 1. replace , by . (common mistake)
\r
1334 $val = str_replace(',','.',$val);
\r
1335 // 2. cast to float or int
\r
1336 if (is_numeric($val) && strstr($val,'.5')) {
\r
1337 $val = (float) $val;
\r
1339 $val = intval($val);
\r
1342 $this->setSetting('btimeoffset',$val);
\r
1345 function setDefaultCategory($val) {
\r
1346 $this->setSetting('bdefcat',$val);
\r
1349 function getSetting($key) {
\r
1350 return $this->settings[$key];
\r
1353 function setSetting($key,$value) {
\r
1354 $this->settings[$key] = $value;
\r
1358 * Blog::addTeamMember()
\r
1359 * Tries to add a member to the team.
\r
1360 * Returns false if the member was already on the team
\r
1362 * @param Integer $memberid id for member
\r
1363 * @param Boolean $admin super-admin or not
\r
1364 * @return Boolean Success/Fail
\r
1366 function addTeamMember($memberid, $admin)
\r
1370 $memberid = intval($memberid);
\r
1371 $admin = intval($admin);
\r
1373 // check if member is already a member
\r
1374 $tmem = Member::createFromID($memberid);
\r
1376 if ( $tmem->isTeamMember($this->getID()) )
\r
1382 'PreAddTeamMember',
\r
1385 'member' => &$tmem,
\r
1386 'admin' => &$admin
\r
1391 $query = "INSERT INTO %s (TMEMBER, TBLOG, TADMIN) ' . 'VALUES (%d, %d, %d)";
\r
1392 $query = sprintf($query, sql_table('team'), $memberid, $this->getID(), $admin);
\r
1393 sql_query($query);
\r
1396 'PostAddTeamMember',
\r
1399 'member' => &$tmem,
\r
1404 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
\r
1405 ActionLog::add(INFO, $logMsg);
\r
1410 function getID() {
\r
1411 return (integer) $this->blogid;
\r
1415 * Checks if a blog with a given shortname exists
\r
1416 * Returns true if there is a blog with the given shortname (static)
\r
1421 function exists($name) {
\r
1422 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
\r
1423 return (sql_num_rows($r) != 0);
\r
1427 * Checks if a blog with a given id exists
\r
1428 * Returns true if there is a blog with the given ID (static)
\r
1433 function existsID($id) {
\r
1434 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
\r
1435 return (sql_num_rows($r) != 0);
\r
1439 * flag there is a future post pending
\r
1441 function setFuturePost() {
\r
1442 $query = 'UPDATE '.sql_table('blog')
\r
1443 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
\r
1444 sql_query($query);
\r
1448 * clear there is a future post pending
\r
1450 function clearFuturePost() {
\r
1451 $query = 'UPDATE '.sql_table('blog')
\r
1452 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
\r
1453 sql_query($query);
\r
1457 * check if we should throw justPosted event
\r
1459 function checkJustPosted() {
\r
1462 if ($this->settings['bfuturepost'] == 1) {
\r
1463 $blogid = $this->getID();
\r
1464 $result = sql_query("SELECT * FROM " . sql_table('item')
\r
1465 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
\r
1466 if (sql_num_rows($result) > 0) {
\r
1467 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
\r
1468 // Note that the plugins's calling order is subject to thri order in the plugin list
\r
1472 array('blogid' => $blogid,
\r
1473 'pinged' => &$pinged
\r
1477 // clear all expired future posts
\r
1478 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
\r
1480 // check to see any pending future post, clear the flag is none
\r
1481 $result = sql_query("SELECT * FROM " . sql_table('item')
\r
1482 . " WHERE iposted=0 AND iblog=" . $blogid);
\r
1483 if (sql_num_rows($result) == 0) {
\r
1484 $this->clearFuturePost();
\r
1491 * Shows the given list of items for this blog
\r
1493 * @param $itemarray
\r
1494 * array of item numbers to be displayed
\r
1495 * @param $template
\r
1496 * String representing the template _NAME_ (!)
\r
1497 * @param $highlight
\r
1498 * contains a query that should be highlighted
\r
1499 * @param $comments
\r
1500 * 1=show comments 0=don't show comments
\r
1501 * @param $dateheads
\r
1502 * 1=show dateheads 0=don't show dateheads
\r
1503 * @param $showDrafts
\r
1504 * 0=do not show drafts 1=show drafts
\r
1505 * @param $showFuture
\r
1506 * 0=do not show future posts 1=show future posts
\r
1508 * amount of items shown
\r
1510 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
\r
1512 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
\r
1514 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
\r
1518 * Blog::getSqlItemList()
\r
1519 * Returns the SQL query used to fill out templates for a list of items
\r
1520 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
\r
1522 * @param array $itemarray an array holding the item numbers of the items to be displayed
\r
1523 * @param integer $showDrafts 0=do not show drafts 1=show drafts
\r
1524 * @param integer $showFuture 0=do not show future posts 1=show future posts
\r
1525 * @return string either a full SQL query, or an empty string
\r
1528 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
\r
1530 if ( !is_array($itemarray) )
\r
1535 $showDrafts = intval($showDrafts);
\r
1536 $showFuture = intval($showFuture);
\r
1539 foreach ( $itemarray as $value )
\r
1541 if ( intval($value) )
\r
1543 $items[] = intval($value);
\r
1546 if ( !count($items) )
\r
1551 $i = count($items);
\r
1553 foreach ( $items as $value )
\r
1557 . ' i.inumber as itemid,'
\r
1558 . ' i.ititle as title,'
\r
1559 . ' i.ibody as body,'
\r
1560 . ' m.mname as author,'
\r
1561 . ' m.mrealname as authorname,'
\r
1563 . ' i.imore as more,'
\r
1564 . ' m.mnumber as authorid,'
\r
1565 . ' m.memail as authormail,'
\r
1566 . ' m.murl as authorurl,'
\r
1567 . ' c.cname as category,'
\r
1568 . ' i.icat as catid,'
\r
1569 . ' i.iclosed as closed';
\r
1571 $query .= ' FROM '
\r
1572 . sql_table('item') . ' as i, '
\r
1573 . sql_table('member') . ' as m, '
\r
1574 . sql_table('category') . ' as c'
\r
1576 . ' i.iblog='.$this->blogid
\r
1577 . ' and i.iauthor=m.mnumber'
\r
1578 . ' and i.icat=c.catid';
\r
1580 // exclude drafts
\r
1581 if ( !$showDrafts )
\r
1583 $query .= ' and i.idraft=0';
\r
1585 if ( !$showFuture )
\r
1587 // don't show future items
\r
1588 $query .= " and i.itime<='" . i18n::formatted_datetime('mysql', $this->getCorrectTime()) . "'";
\r
1591 $query .= ' and i.inumber='.intval($value);
\r
1594 if ($i) $query .= ' UNION ';
\r