4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5 * Copyright (C) 2002-2009 The Nucleus Group
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)
14 * A class representing a blog and containing functions to get that blog shown
17 * @license http://nucleuscms.org/license.txt GNU General Public License
18 * @copyright Copyright (C) 2002-2009 The Nucleus Group
19 * @version $Id: BLOG.php 1624 2012-01-09 11:36:20Z sakamocchi $
22 if ( !function_exists('requestVar') ) exit;
23 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
30 // ID of currently selected category
33 // After creating an object of the blog class, contains true if the BLOG object is
34 // valid (the blog exists)
37 // associative array, containing all blogsettings (use the get/set functions instead)
41 * Creates a new BLOG object for the given blog
46 $this->blogid = intval($id);
47 $this->readSettings();
50 // (the parse functions in SKIN.php will override this, so it's mainly useless)
52 $this->setSelectedCategory($catid);
56 * Shows the given amount of items for this blog
59 * String representing the template _NAME_ (!)
60 * @param $amountEntries
61 * amount of entries to show
63 * offset from where items should be shown (e.g. 5 = start at fifth item)
65 * amount of items shown
67 function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
68 return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
72 * Shows an archive for a given month
79 * String representing the template name to be used
81 function showArchive($templatename, $year, $month=0, $day=0) {
83 // create extra where clause for select query
84 if ($day == 0 && $month != 0) {
85 $timestamp_start = mktime(0,0,0,$month,1,$year);
86 $timestamp_end = mktime(0,0,0,$month+1,1,$year); // also works when $month==12
87 } elseif ($month == 0) {
88 $timestamp_start = mktime(0,0,0,1,1,$year);
89 $timestamp_end = mktime(0,0,0,12,31,$year); // also works when $month==12
91 $timestamp_start = mktime(0,0,0,$month,$day,$year);
92 $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
94 $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
95 . ' and i.itime<' . mysqldate($timestamp_end);
98 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
103 * Sets the selected category by id (only when category exists)
105 function setSelectedCategory($catid) {
106 if ($this->isValidCategory($catid) || (intval($catid) == 0))
107 $this->selectedcatid = intval($catid);
111 * Sets the selected category by name
113 function setSelectedCategoryByName($catname) {
114 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
118 * Returns the selected category
120 function getSelectedCategory() {
121 return $this->selectedcatid;
125 * Shows the given amount of items for this blog
128 * String representing the template _NAME_ (!)
129 * @param $amountEntries
130 * amount of entries to show (0 = no limit)
132 * extra conditions to be added to the query
134 * contains a query that should be highlighted
136 * 1=show comments 0=don't show comments
138 * 1=show dateheads 0=don't show dateheads
142 * amount of items shown
144 function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
146 $query = $this->getSqlBlog($extraQuery);
148 if ($amountEntries > 0) {
149 // $offset zou moeten worden:
150 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
151 $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
153 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
157 * Do the job for readLogAmmount
159 function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
160 global $CONF, $manager;
162 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
164 $lastVisit = $this->getCorrectTime($lastVisit);
166 // set templatename as global variable (so plugins can access it)
167 global $currentTemplateName;
168 $currentTemplateName = $templateName;
170 $template =& $manager->getTemplate($templateName);
172 // create parser object & action handler
173 $actions = new ITEMACTIONS($this);
174 $parser = new PARSER($actions->getDefinedActions(),$actions);
175 $actions->setTemplate($template);
176 $actions->setHighlight($highlight);
177 $actions->setLastVisit($lastVisit);
178 $actions->setParser($parser);
179 $actions->setShowComments($comments);
182 $items = sql_query($query);
184 // loop over all items
186 while ($item = sql_fetch_object($items)) {
188 $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
190 // action handler needs to know the item we're handling
191 $actions->setCurrentItem($item);
193 // add date header if needed
195 $new_date = date('dFY',$item->timestamp);
196 if ($new_date != $old_date) {
197 // unless this is the first time, write date footer
198 $timestamp = $item->timestamp;
199 if ($old_date != 0) {
200 $oldTS = strtotime($old_date);
201 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
202 $tmp_footer = i18n::strftime(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
203 $parser->parse($tmp_footer);
204 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
206 $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
207 // note, to use templatvars in the dateheader, the %-characters need to be doubled in
208 // order to be preserved by strftime
209 $tmp_header = i18n::strftime((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
210 $parser->parse($tmp_header);
211 $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
213 $old_date = $new_date;
217 $parser->parse($template['ITEM_HEADER']);
218 $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));
219 $parser->parse($template['ITEM']);
220 $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));
221 $parser->parse($template['ITEM_FOOTER']);
225 $numrows = sql_num_rows($items);
227 // add another date footer if there was at least one item
228 if (($numrows > 0) && $dateheads) {
229 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
230 $parser->parse($template['DATE_FOOTER']);
231 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
234 sql_free_result($items); // free memory
241 * Simplified function for showing only one item
243 function showOneitem($itemid, $template, $highlight) {
244 $extraQuery = ' and inumber=' . intval($itemid);
246 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
251 * Adds an item to this blog
253 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
256 $blogid = intval($blogid);
257 $authorid = intval($authorid);
261 $catid = intval($catid);
263 // convert newlines to <br />
264 if ($this->convertBreaks()) {
265 $body = addBreaks($body);
266 $more = addBreaks($more);
269 if ($closed != '1') $closed = '0';
270 if ($draft != '0') $draft = '1';
272 if (!$this->isValidCategory($catid))
273 $catid = $this->getDefaultCategory();
275 if ($timestamp > $this->getCorrectTime())
278 $timestamp = date('Y-m-d H:i:s',$timestamp);
280 $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
282 $ititle = sql_real_escape_string($title);
283 $ibody = sql_real_escape_string($body);
284 $imore = sql_real_escape_string($more);
286 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
287 . "VALUES ('$ititle', '$ibody', '$imore', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
289 $itemid = sql_insert_id();
291 $manager->notify('PostAddItem',array('itemid' => $itemid));
294 $this->updateUpdateFile();
296 // send notification mail
297 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
298 $this->sendNewItemNotification($itemid, $title, $body);
304 * BLOG::sendNewItemNotification()
305 * Send a new item notification to the notification list
307 * @param String $itemid ID of the item
308 * @param String $title title of the item
309 * @param String $body body of the item
312 function sendNewItemNotification($itemid, $title, $body)
314 global $CONF, $member;
316 $ascii = ENTITY::anchor_footnoting($body);
318 $message = _NOTIFY_NI_MSG . " \n";
319 $temp = parse_url($CONF['Self']);
320 if ( $temp['scheme'] )
322 $message .= LINK::create_item_link($itemid) . "\n\n";
326 $tempurl = $this->getURL();
327 if ( i18n::substr($tempurl, -1) == '/' || i18n::substr($tempurl, -4) == '.php' )
329 $message .= $tempurl . '?itemid=' . $itemid . "\n\n";
333 $message .= $tempurl . '/?itemid=' . $itemid . "\n\n";
336 $message .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
337 $message .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
338 $message .= NOTIFICATION::get_mail_footer();
340 $subject = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
342 $from = $member->getNotifyFromMailAddress();
344 NOTIFICATION::mail($this->getNotifyAddress(), $subject, $message, $from, i18n::get_current_charset());
349 * Creates a new category for this blog
352 * name of the new category. When empty, a name is generated automatically
353 * (starting with newcat)
354 * @param $catDescription
355 * description of the new category. Defaults to 'New Category'
358 * the new category-id in case of success.
361 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
362 global $member, $manager;
364 if ($member->blogAdminRights($this->getID())) {
368 $catName = _CREATED_NEW_CATEGORY_NAME;
371 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
372 while (sql_num_rows($res) > 0)
375 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
378 $catName = $catName . $i;
386 'description' => $catDescription
390 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($catDescription) . "')";
392 $catid = sql_insert_id();
399 'description' => $catDescription,
413 * Searches all months of this blog for the given query
418 * template to be used (__NAME__ of the template)
419 * @param $amountMonths
420 * max amount of months to be search (0 = all)
422 * max number of results to show
426 * amount of hits found
428 function search($query, $template, $amountMonths, $maxresults, $startpos) {
429 global $CONF, $manager;
432 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
436 // no query -> show everything
438 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
441 // add LIMIT to query (to split search results into pages)
442 if (intval($maxresults > 0))
443 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
446 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
448 // when no results were found, show a message
449 if ($amountfound == 0)
451 $template =& $manager->getTemplate($template);
453 'query' => ENTITY::hsc($query),
454 'blogid' => $this->getID()
456 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
464 * Returns an SQL query to use for a search query
468 * @param $amountMonths
469 * amount of months to search back. Default = 0 = unlimited
471 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
472 * @returns $highlight
473 * words to highlight (out parameter)
475 * either a full SQL query, or an empty string (if querystring empty)
477 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
479 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
481 $searchclass = new SEARCH($query);
483 $highlight = $searchclass->inclusive;
485 // if querystring is empty, return empty string
486 if ($searchclass->inclusive == '')
490 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
491 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
493 // get list of blogs to search
494 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
495 $blogs[] = $this->getID(); // also search current blog (duh)
496 $blogs = array_unique($blogs); // remove duplicates
498 if (count($blogs) > 0)
499 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
503 $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';
505 $query .= ', '.$select. ' as score ';
507 $query = 'SELECT COUNT(*) as result ';
510 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
511 . ' WHERE i.iauthor=m.mnumber'
512 . ' and i.icat=c.catid'
513 . ' and i.idraft=0' // exclude drafts
515 // don't show future items
516 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
519 // take into account amount of months to search
520 if ($amountMonths > 0)
522 $localtime = getdate($this->getCorrectTime());
523 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
524 $query .= ' and i.itime>' . mysqldate($timestamp_start);
530 $query .= ' ORDER BY score DESC';
532 $query .= ' ORDER BY i.itime DESC ';
539 * Returns the SQL query that's normally used to display the blog items on the index type skins
542 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
544 * either a full SQL query, or an empty string
546 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
548 function getSqlBlog($extraQuery, $mode = '')
551 $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';
553 $query = 'SELECT COUNT(*) as result ';
555 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
556 . ' WHERE i.iblog='.$this->blogid
557 . ' and i.iauthor=m.mnumber'
558 . ' and i.icat=c.catid'
559 . ' and i.idraft=0' // exclude drafts
560 // don't show future items
561 . ' and i.itime<=' . mysqldate($this->getCorrectTime());
563 if ($this->getSelectedCategory())
564 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
567 $query .= $extraQuery;
570 $query .= ' ORDER BY i.itime DESC';
576 * BLOG::showArchiveList()
577 * Shows the archivelist using the given template
579 * @param String $template template name
580 * @param String $mode year/month/day
581 * @param Integer $limit limit of record count
584 function showArchiveList($template, $mode = 'month', $limit = 0)
586 global $CONF, $catid, $manager;
588 if ( !isset ($linkparams) )
590 $linkparams = array();
595 $linkparams = array('catid' => $catid);
598 $template =& $manager->getTemplate($template);
599 $data['blogid'] = $this->getID();
601 $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER'] : '';
602 echo TEMPLATE::fill($tplt, $data);
604 $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')
605 . ' WHERE iblog=' . $this->getID()
606 . ' and itime <=' . mysqldate($this->getCorrectTime()) // don't show future items!
607 . ' and idraft=0'; // don't show draft items
611 $query .= ' and icat=' . intval($catid);
614 $query .= ' GROUP BY Year';
615 if ( $mode == 'month' || $mode == 'day' )
619 if ( $mode == 'day' )
624 $query .= ' ORDER BY itime DESC';
628 $query .= ' LIMIT ' . intval($limit);
631 $res = sql_query($query);
632 while ($current = sql_fetch_object($res))
634 /* string time -> unix timestamp */
635 $current->itime = strtotime($current->itime);
637 if ( $mode == 'day' )
639 $archivedate = date('Y-m-d',$current->itime);
640 $archive['day'] = date('d',$current->itime);
641 $data['day'] = date('d',$current->itime);
642 $data['month'] = date('m',$current->itime);
643 $archive['month'] = $data['month'];
645 elseif ( $mode == 'year' )
647 $archivedate = date('Y',$current->itime);
650 $archive['day'] = '';
651 $archive['month'] = '';
655 $archivedate = date('Y-m',$current->itime);
656 $data['month'] = date('m',$current->itime);
657 $archive['month'] = $data['month'];
659 $archive['day'] = '';
662 $data['year'] = date('Y',$current->itime);
663 $archive['year'] = $data['year'];
664 $data['archivelink'] = LINK::create_archive_link($this->getID(),$archivedate,$linkparams);
667 'PreArchiveListItem',
673 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
674 echo i18n::strftime($temp,$current->itime);
678 sql_free_result($res);
680 $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER'] : '';
681 echo TEMPLATE::fill($tplt, $data);
686 * BLOG::showCategoryList()
687 * Shows the list of categories using a given template
689 * @param String $template Template Name
692 function showCategoryList($template)
694 global $CONF, $manager;
697 * determine arguments next to catids
698 * I guess this can be done in a better way, but it works
700 global $archive, $archivelist;
702 $linkparams = array();
705 $blogurl = LINK::create_archive_link($this->getID(), $archive, '');
706 $linkparams['blogid'] = $this->getID();
707 $linkparams['archive'] = $archive;
709 else if ( $archivelist )
711 $blogurl = LINK::create_archivelist_link($this->getID(), '');
712 $linkparams['archivelist'] = $archivelist;
716 $blogurl = LINK::create_blogid_link($this->getID(), '');
717 $linkparams['blogid'] = $this->getID();
720 $template =& $manager->getTemplate($template);
722 //: Change: Set nocatselected variable
723 if ( $this->getSelectedCategory() )
725 $nocatselected = 'no';
729 $nocatselected = 'yes';
732 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
734 'blogid' => $this->getID(),
735 'blogurl' => $blogurl,
736 'self' => $CONF['Self'],
737 //: Change: Set catiscurrent template variable for header
738 'catiscurrent' => $nocatselected,
739 'currentcat' => $nocatselected
742 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
743 $res = sql_query($query);
745 while ( $data = sql_fetch_assoc($res) )
747 $data['blogid'] = $this->getID();
748 $data['blogurl'] = $blogurl;
749 $data['catlink'] = LINK::create_link(
752 'catid' => $data['catid'],
753 'name' => $data['catname'],
754 'extra' => $linkparams
756 $data['self'] = $CONF['Self'];
759 //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
760 $data['catiscurrent'] = 'no';
761 $data['currentcat'] = 'no';
762 if ( $this->getSelectedCategory() )
764 if ( $this->getSelectedCategory() == $data['catid'] )
766 $data['catiscurrent'] = 'yes';
767 $data['currentcat'] = 'yes';
773 if ( intval($itemid) && $manager->existsItem(intval($itemid),0,0) )
775 $iobj =& $manager->getItem(intval($itemid),0,0);
776 $cid = $iobj['catid'];
777 if ( $cid == $data['catid'] )
779 $data['catiscurrent'] = 'yes';
780 $data['currentcat'] = 'yes';
786 'PreCategoryListItem',
792 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
795 sql_free_result($res);
797 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
799 'blogid' => $this->getID(),
800 'blogurl' => $blogurl,
801 'self' => $CONF['Self'],
802 //: Change: Set catiscurrent template variable for footer
803 'catiscurrent' => $nocatselected,
804 'currentcat' => $nocatselected
810 * BLOG::showBlogList()
811 * Shows a list of all blogs in the system using a given template
812 * ordered by number, name, shortname or description
813 * in ascending or descending order
815 * @param String $template tempalte name
816 * @param String $bnametype bname/bshortname
817 * @param String $orderby string for 'ORDER BY' SQL
818 * @param String $direction ASC/DESC
821 function showBlogList($template, $bnametype, $orderby, $direction)
823 global $CONF, $manager;
834 $orderby='bshortname';
844 $direction=strtolower($direction);
845 switch ( $direction )
858 $template =& $manager->getTemplate($template);
860 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
862 'sitename' => $CONF['SiteName'],
863 'siteurl' => $CONF['IndexURL']
867 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
868 $res = sql_query($query);
870 while ( $data = sql_fetch_assoc($res) )
873 $list['bloglink'] = LINK::create_blogid_link($data['bnumber']);
874 $list['blogdesc'] = $data['bdesc'];
875 $list['blogurl'] = $data['burl'];
877 if ( $bnametype == 'shortname' )
879 $list['blogname'] = $data['bshortname'];
883 /* all other cases */
884 $list['blogname'] = $data['bname'];
894 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
897 sql_free_result($res);
899 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
901 'sitename' => $CONF['SiteName'],
902 'siteurl' => $CONF['IndexURL']
909 * Read the blog settings
911 function readSettings() {
913 . ' FROM '.sql_table('blog')
914 . ' WHERE bnumber=' . $this->blogid;
915 $res = sql_query($query);
917 $this->isValid = (sql_num_rows($res) > 0);
921 $this->settings = sql_fetch_assoc($res);
925 * Write the blog settings
927 function writeSettings() {
929 // (can't use floatval since not available prior to PHP 4.2)
930 $offset = $this->getTimeOffset();
931 if (!is_float($offset))
932 $offset = intval($offset);
934 $query = 'UPDATE '.sql_table('blog')
935 . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
936 . " bshortname='". sql_real_escape_string($this->getShortName()) . "',"
937 . " bcomments=". intval($this->commentsEnabled()) . ","
938 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
939 . " btimeoffset=" . $offset . ","
940 . " bpublic=" . intval($this->isPublic()) . ","
941 . " breqemail=" . intval($this->emailRequired()) . ","
942 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
943 . " ballowpast=" . intval($this->allowPastPosting()) . ","
944 . " bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
945 . " bnotifytype=" . intval($this->getNotifyType()) . ","
946 . " burl='" . sql_real_escape_string($this->getURL()) . "',"
947 . " bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
948 . " bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
949 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
950 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
951 . " bincludesearch=" . intval($this->getSearchable())
952 . " WHERE bnumber=" . intval($this->getID());
958 * Update the update file if requested
960 function updateUpdatefile() {
961 if ($this->getUpdateFile()) {
962 $f_update = fopen($this->getUpdateFile(),'w');
963 fputs($f_update,$this->getCorrectTime());
970 * Check if a category with a given catid is valid
975 function isValidCategory($catid) {
976 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
977 $res = sql_query($query);
978 return (sql_num_rows($res) != 0);
982 * Get the category name for a given catid
987 function getCategoryName($catid) {
988 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
989 $o = sql_fetch_object($res);
994 * Get the category description for a given catid
999 function getCategoryDesc($catid) {
1000 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
1001 $o = sql_fetch_object($res);
1006 * Get the category id for a given category name
1011 function getCategoryIdFromName($name) {
1012 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
1013 if (sql_num_rows($res) > 0) {
1014 $o = sql_fetch_object($res);
1017 return $this->getDefaultCategory();
1022 * Get the the setting for the line break handling
1023 * [should be named as getConvertBreaks()]
1025 function convertBreaks() {
1026 return $this->getSetting('bconvertbreaks');
1030 * Set the the setting for the line break handling
1033 * new value for bconvertbreaks
1035 function setConvertBreaks($val) {
1036 $this->setSetting('bconvertbreaks',$val);
1040 * Insert a javascript that includes information about the settings
1041 * of an author: ConvertBreaks, MediaUrl and AuthorId
1046 function insertJavaScriptInfo($authorid = '') {
1047 global $member, $CONF;
1049 if ($authorid == '')
1050 $authorid = $member->getID();
1053 <script type="text/javascript">
1054 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
1055 setMediaUrl("<?php echo $CONF['MediaURL']?>");
1056 setAuthorId(<?php echo $authorid?>);
1061 * Set the the setting for allowing to publish postings in the past
1064 * new value for ballowpast
1066 function setAllowPastPosting($val) {
1067 $this->setSetting('ballowpast',$val);
1071 * Get the the setting if it is allowed to publish postings in the past
1072 * [should be named as getAllowPastPosting()]
1074 function allowPastPosting() {
1075 return $this->getSetting('ballowpast');
1078 function getCorrectTime($t=0) {
1079 if ($t == 0) $t = time();
1080 return ($t + 3600 * $this->getTimeOffset());
1083 function getName() {
1084 return $this->getSetting('bname');
1087 function getShortName() {
1088 return $this->getSetting('bshortname');
1091 function getMaxComments() {
1092 return $this->getSetting('bmaxcomments');
1095 function getNotifyAddress() {
1096 return $this->getSetting('bnotify');
1099 function getNotifyType() {
1100 return $this->getSetting('bnotifytype');
1103 function notifyOnComment() {
1104 $n = $this->getNotifyType();
1105 return (($n != 0) && (($n % 3) == 0));
1108 function notifyOnVote() {
1109 $n = $this->getNotifyType();
1110 return (($n != 0) && (($n % 5) == 0));
1113 function notifyOnNewItem() {
1114 $n = $this->getNotifyType();
1115 return (($n != 0) && (($n % 7) == 0));
1118 function setNotifyType($val) {
1119 $this->setSetting('bnotifytype',$val);
1123 function getTimeOffset() {
1124 return $this->getSetting('btimeoffset');
1127 function commentsEnabled() {
1128 return $this->getSetting('bcomments');
1132 return $this->getSetting('burl');
1135 function getDefaultSkin() {
1136 return $this->getSetting('bdefskin');
1139 function getUpdateFile() {
1140 return $this->getSetting('bupdate');
1143 function getDescription() {
1144 return $this->getSetting('bdesc');
1147 function isPublic() {
1148 return $this->getSetting('bpublic');
1151 function emailRequired() {
1152 return $this->getSetting('breqemail');
1155 function getSearchable() {
1156 return $this->getSetting('bincludesearch');
1159 function getDefaultCategory() {
1160 return $this->getSetting('bdefcat');
1163 function setPublic($val) {
1164 $this->setSetting('bpublic',$val);
1167 function setSearchable($val) {
1168 $this->setSetting('bincludesearch',$val);
1171 function setDescription($val) {
1172 $this->setSetting('bdesc',$val);
1175 function setUpdateFile($val) {
1176 $this->setSetting('bupdate',$val);
1179 function setDefaultSkin($val) {
1180 $this->setSetting('bdefskin',$val);
1183 function setURL($val) {
1184 $this->setSetting('burl',$val);
1187 function setName($val) {
1188 $this->setSetting('bname',$val);
1191 function setShortName($val) {
1192 $this->setSetting('bshortname',$val);
1195 function setCommentsEnabled($val) {
1196 $this->setSetting('bcomments',$val);
1199 function setMaxComments($val) {
1200 $this->setSetting('bmaxcomments',$val);
1203 function setNotifyAddress($val) {
1204 $this->setSetting('bnotify',$val);
1207 function setEmailRequired($val) {
1208 $this->setSetting('breqemail',$val);
1211 function setTimeOffset($val) {
1212 // check validity of value
1213 // 1. replace , by . (common mistake)
1214 $val = str_replace(',','.',$val);
1215 // 2. cast to float or int
1216 if (is_numeric($val) && strstr($val,'.5')) {
1217 $val = (float) $val;
1219 $val = intval($val);
1222 $this->setSetting('btimeoffset',$val);
1225 function setDefaultCategory($val) {
1226 $this->setSetting('bdefcat',$val);
1229 function getSetting($key) {
1230 return $this->settings[$key];
1233 function setSetting($key,$value) {
1234 $this->settings[$key] = $value;
1238 * Tries to add a member to the team.
1239 * Returns false if the member was already on the team
1241 function addTeamMember($memberid, $admin) {
1244 $memberid = intval($memberid);
1245 $admin = intval($admin);
1247 // check if member is already a member
1248 $tmem = MEMBER::createFromID($memberid);
1250 if ($tmem->isTeamMember($this->getID()))
1263 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1264 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1268 'PostAddTeamMember',
1277 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1278 ACTIONLOG::add(INFO, $logMsg);
1284 return intval($this->blogid);
1288 * Checks if a blog with a given shortname exists
1289 * Returns true if there is a blog with the given shortname (static)
1294 function exists($name) {
1295 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1296 return (sql_num_rows($r) != 0);
1300 * Checks if a blog with a given id exists
1301 * Returns true if there is a blog with the given ID (static)
1306 function existsID($id) {
1307 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1308 return (sql_num_rows($r) != 0);
1312 * flag there is a future post pending
1314 function setFuturePost() {
1315 $query = 'UPDATE '.sql_table('blog')
1316 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1321 * clear there is a future post pending
1323 function clearFuturePost() {
1324 $query = 'UPDATE '.sql_table('blog')
1325 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1330 * check if we should throw justPosted event
1332 function checkJustPosted() {
1335 if ($this->settings['bfuturepost'] == 1) {
1336 $blogid = $this->getID();
1337 $result = sql_query("SELECT * FROM " . sql_table('item')
1338 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1339 if (sql_num_rows($result) > 0) {
1340 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1341 // Note that the plugins's calling order is subject to thri order in the plugin list
1345 array('blogid' => $blogid,
1346 'pinged' => &$pinged
1350 // clear all expired future posts
1351 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1353 // check to see any pending future post, clear the flag is none
1354 $result = sql_query("SELECT * FROM " . sql_table('item')
1355 . " WHERE iposted=0 AND iblog=" . $blogid);
1356 if (sql_num_rows($result) == 0) {
1357 $this->clearFuturePost();
1364 * Shows the given list of items for this blog
1367 * array of item numbers to be displayed
1369 * String representing the template _NAME_ (!)
1371 * contains a query that should be highlighted
1373 * 1=show comments 0=don't show comments
1375 * 1=show dateheads 0=don't show dateheads
1376 * @param $showDrafts
1377 * 0=do not show drafts 1=show drafts
1378 * @param $showFuture
1379 * 0=do not show future posts 1=show future posts
1381 * amount of items shown
1383 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1385 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1387 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1391 * Returns the SQL query used to fill out templates for a list of items
1394 * an array holding the item numbers of the items to be displayed
1395 * @param $showDrafts
1396 * 0=do not show drafts 1=show drafts
1397 * @param $showFuture
1398 * 0=do not show future posts 1=show future posts
1400 * either a full SQL query, or an empty string
1402 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1404 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1406 if (!is_array($itemarray)) return '';
1407 $showDrafts = intval($showDrafts);
1408 $showFuture = intval($showFuture);
1410 foreach ($itemarray as $value) {
1411 if (intval($value)) $items[] = intval($value);
1413 if (!count($items)) return '';
1414 //$itemlist = implode(',',$items);
1417 foreach ($items as $value) {
1420 . ' i.inumber as itemid,'
1421 . ' i.ititle as title,'
1422 . ' i.ibody as body,'
1423 . ' m.mname as author,'
1424 . ' m.mrealname as authorname,'
1426 . ' i.imore as more,'
1427 . ' m.mnumber as authorid,'
1428 . ' m.memail as authormail,'
1429 . ' m.murl as authorurl,'
1430 . ' c.cname as category,'
1431 . ' i.icat as catid,'
1432 . ' i.iclosed as closed';
1435 . sql_table('item') . ' as i, '
1436 . sql_table('member') . ' as m, '
1437 . sql_table('category') . ' as c'
1439 . ' i.iblog='.$this->blogid
1440 . ' and i.iauthor=m.mnumber'
1441 . ' and i.icat=c.catid';
1442 if (!$showDrafts) $query .= ' and i.idraft=0'; // exclude drafts
1443 if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1445 //$query .= ' and i.inumber IN ('.$itemlist.')';
1446 $query .= ' and i.inumber='.intval($value);
1449 if ($i) $query .= ' UNION ';