4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5 * Copyright (C) 2002-2011 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-2011 The Nucleus Group
20 * $NucleusJP: BLOG.php,v 1.12.2.2 2007/08/08 05:26:22 kimitake Exp $
23 if ( !function_exists('requestVar') ) exit;
24 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
31 // ID of currently selected category
34 // After creating an object of the blog class, contains true if the BLOG object is
35 // valid (the blog exists)
38 // associative array, containing all blogsettings (use the get/set functions instead)
42 * Creates a new BLOG object for the given blog
47 $this->blogid = intval($id);
48 $this->readSettings();
51 // (the parse functions in SKIN.php will override this, so it's mainly useless)
53 $this->setSelectedCategory($catid);
57 * Shows the given amount of items for this blog
60 * String representing the template _NAME_ (!)
61 * @param $amountEntries
62 * amount of entries to show
64 * offset from where items should be shown (e.g. 5 = start at fifth item)
66 * amount of items shown
68 function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
69 return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
73 * Shows an archive for a given month
80 * String representing the template name to be used
82 function showArchive($templatename, $year, $month = 0, $day = 0) {
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
92 $timestamp_start = mktime(0,0,0,$month,$day,$year);
93 $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
95 $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
96 . ' and i.itime<' . mysqldate($timestamp_end);
99 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
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);
110 function setSelectedCategoryByName($catname) {
111 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
114 function getSelectedCategory() {
115 return $this->selectedcatid;
119 * Shows the given amount of items for this blog
122 * String representing the template _NAME_ (!)
123 * @param $amountEntries
124 * amount of entries to show (0 = no limit)
126 * extra conditions to be added to the query
128 * contains a query that should be highlighted
130 * 1=show comments 0=don't show comments
132 * 1=show dateheads 0=don't show dateheads
136 * amount of items shown
138 function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
140 $query = $this->getSqlBlog($extraQuery);
142 if ($amountEntries > 0) {
143 // $offset zou moeten worden:
144 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
145 $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
147 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
150 function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
151 global $CONF, $manager;
153 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
155 $lastVisit = $this->getCorrectTime($lastVisit);
157 // set templatename as global variable (so plugins can access it)
158 global $currentTemplateName;
159 $currentTemplateName = $templateName;
161 $template =& $manager->getTemplate($templateName);
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);
173 $items = sql_query($query);
175 // loop over all items
177 while ($item = sql_fetch_object($items)) {
179 $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
181 // action handler needs to know the item we're handling
182 $actions->setCurrentItem($item);
184 // add date header if needed
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 = strftimejp(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
194 $parser->parse($tmp_footer);
195 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
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 = strftimejp((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
201 $parser->parse($tmp_header);
202 $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
204 $old_date = $new_date;
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']);
216 $numrows = sql_num_rows($items);
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)));
225 sql_free_result($items); // free memory
231 function showOneitem($itemid, $template, $highlight) {
232 $extraQuery = ' and inumber=' . intval($itemid);
234 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
239 * Adds an item to this blog
241 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
244 $blogid = intval($blogid);
245 $authorid = intval($authorid);
249 $catid = intval($catid);
251 // convert newlines to <br />
252 if ($this->convertBreaks()) {
253 $body = addBreaks($body);
254 $more = addBreaks($more);
257 if ($closed != '1') $closed = '0';
258 if ($draft != '0') $draft = '1';
260 if (!$this->isValidCategory($catid))
261 $catid = $this->getDefaultCategory();
263 if ($timestamp > $this->getCorrectTime())
266 $timestamp = date('Y-m-d H:i:s',$timestamp);
268 $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
270 $ititle = sql_real_escape_string($title);
271 $ibody = sql_real_escape_string($body);
272 $imore = sql_real_escape_string($more);
274 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
275 . "VALUES ('$ititle', '$ibody', '$imore', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
277 $itemid = sql_insert_id();
279 $manager->notify('PostAddItem',array('itemid' => $itemid));
282 $this->updateUpdateFile();
284 // send notification mail
285 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
286 $this->sendNewItemNotification($itemid, $title, $body);
291 function sendNewItemNotification($itemid, $title, $body) {
292 global $CONF, $member;
294 // create text version of html post
295 $ascii = toAscii($body);
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";
303 $tempurl = $this->getURL();
304 if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
305 $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
307 $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
310 $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
311 $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
312 $mailto_msg .= getMailFooter();
314 $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
316 $frommail = $member->getNotifyFromMailAddress();
318 $notify =& new NOTIFICATION($this->getNotifyAddress());
319 $notify->notify($mailto_title, $mailto_msg , $frommail);
327 * Creates a new category for this blog
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'
336 * the new category-id in case of success.
339 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
340 global $member, $manager;
342 if ($member->blogAdminRights($this->getID())) {
346 $catName = _CREATED_NEW_CATEGORY_NAME;
349 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
350 while (sql_num_rows($res) > 0)
353 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
356 $catName = $catName . $i;
364 'description' => $catDescription
368 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($catDescription) . "')";
370 $catid = sql_insert_id();
377 'description' => $catDescription,
391 * Searches all months of this blog for the given query
396 * template to be used (__NAME__ of the template)
397 * @param $amountMonths
398 * max amount of months to be search (0 = all)
400 * max number of results to show
404 * amount of hits found
406 function search($query, $template, $amountMonths, $maxresults, $startpos) {
407 global $CONF, $manager;
410 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
414 // no query -> show everything
416 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
419 // add LIMIT to query (to split search results into pages)
420 if (intval($maxresults > 0))
421 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
424 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
426 // when no results were found, show a message
427 if ($amountfound == 0)
429 $template =& $manager->getTemplate($template);
431 'query' => htmlspecialchars($query),
432 'blogid' => $this->getID()
434 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
442 * Returns an SQL query to use for a search query
446 * @param $amountMonths
447 * amount of months to search back. Default = 0 = unlimited
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)
453 * either a full SQL query, or an empty string (if querystring empty)
455 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
457 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
459 $searchclass =& new SEARCH($query);
461 $highlight = $searchclass->inclusive;
463 // if querystring is empty, return empty string
464 if ($searchclass->inclusive == '')
468 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
469 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
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
476 if (count($blogs) > 0)
477 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
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';
483 $query .= ', '.$select. ' as score ';
485 $query = 'SELECT COUNT(*) as result ';
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
493 // don't show future items
494 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
497 // take into account amount of months to search
498 if ($amountMonths > 0)
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);
508 $query .= ' ORDER BY score DESC';
510 $query .= ' ORDER BY i.itime DESC ';
517 * Returns the SQL query that's normally used to display the blog items on the index type skins
520 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
522 * either a full SQL query, or an empty string
524 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
526 function getSqlBlog($extraQuery, $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';
531 $query = 'SELECT COUNT(*) as result ';
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());
541 if ($this->getSelectedCategory())
542 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
545 $query .= $extraQuery;
548 $query .= ' ORDER BY i.itime DESC';
554 * Shows the archivelist using the given template
556 function showArchiveList($template, $mode = 'month', $limit = 0) {
557 global $CONF, $catid, $manager;
559 if (!isset ($linkparams)) {
560 $linkparams = array();
564 $linkparams = array('catid' => $catid);
567 $template =& $manager->getTemplate($template);
568 $data['blogid'] = $this->getID();
570 $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER']
572 echo TEMPLATE::fill($tplt, $data);
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
580 $query .= ' and icat=' . intval($catid);
582 $query .= ' GROUP BY Year';
583 if ($mode == 'month' || $mode == 'day')
588 $query .= ' ORDER BY itime DESC';
591 $query .= ' LIMIT ' . intval($limit);
593 $res = sql_query($query);
595 while ($current = sql_fetch_object($res)) {
596 $current->itime = strtotime($current->itime); // string time -> unix timestamp
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);
608 $archive['day'] = '';
609 $archive['month'] = '';
611 $archivedate = date('Y-m',$current->itime);
612 $data['month'] = date('m',$current->itime);
613 $archive['month'] = $data['month'];
615 $archive['day'] = '';
618 $data['year'] = date('Y',$current->itime);
619 $archive['year'] = $data['year'];
620 $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
623 'PreArchiveListItem',
629 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
630 echo strftimejp($temp,$current->itime);
634 sql_free_result($res);
636 $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER']
638 echo TEMPLATE::fill($tplt, $data);
643 * Shows the list of categories using a given template
645 function showCategoryList($template) {
646 global $CONF, $manager;
648 // determine arguments next to catids
649 // I guess this can be done in a better way, but it works
650 global $archive, $archivelist;
652 $linkparams = array();
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;
661 $blogurl = createBlogidLink($this->getID(), '');
662 $linkparams['blogid'] = $this->getID();
665 //$blogurl = $this->getURL() . $qargs;
666 //$blogurl = createBlogLink($this->getURL(), $linkparams);
668 $template =& $manager->getTemplate($template);
670 //: Change: Set nocatselected variable
671 if ($this->getSelectedCategory()) {
672 $nocatselected = 'no';
675 $nocatselected = 'yes';
678 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
680 'blogid' => $this->getID(),
681 'blogurl' => $blogurl,
682 'self' => $CONF['Self'],
683 //: Change: Set catiscurrent template variable for header
684 'catiscurrent' => $nocatselected,
685 'currentcat' => $nocatselected
688 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
689 $res = sql_query($query);
692 while ($data = sql_fetch_assoc($res)) {
693 $data['blogid'] = $this->getID();
694 $data['blogurl'] = $blogurl;
695 $data['catlink'] = createLink(
698 'catid' => $data['catid'],
699 'name' => $data['catname'],
700 'extra' => $linkparams
703 $data['self'] = $CONF['Self'];
706 //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
707 $data['catiscurrent'] = 'no';
708 $data['currentcat'] = 'no';
709 if ($this->getSelectedCategory()) {
710 if ($this->getSelectedCategory() == $data['catid']) {
711 $data['catiscurrent'] = 'yes';
712 $data['currentcat'] = 'yes';
715 $data['catiscurrent'] = 'no';
716 $data['currentcat'] = 'no';
721 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
722 $iobj =& $manager->getItem(intval($itemid),0,0);
723 $cid = $iobj['catid'];
724 if ($cid == $data['catid']) {
725 $data['catiscurrent'] = 'yes';
726 $data['currentcat'] = 'yes';
729 $data['catiscurrent'] = 'no';
730 $data['currentcat'] = 'no';
736 'PreCategoryListItem',
742 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
743 //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
744 //echo strftime($temp, $current->itime);
748 sql_free_result($res);
750 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
752 'blogid' => $this->getID(),
753 'blogurl' => $blogurl,
754 'self' => $CONF['Self']
759 * Shows a list of all blogs in the system using a given template
760 * ordered by number, name, shortname or description
761 * in ascending or descending order
763 function showBlogList($template, $bnametype, $orderby, $direction) {
764 global $CONF, $manager;
774 $orderby='bshortname';
784 $direction=strtolower($direction);
785 switch ($direction) {
797 $template =& $manager->getTemplate($template);
799 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
801 'sitename' => $CONF['SiteName'],
802 'siteurl' => $CONF['IndexURL']
805 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
806 $res = sql_query($query);
808 while ($data = sql_fetch_assoc($res)) {
812 // $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
813 $list['bloglink'] = createBlogidLink($data['bnumber']);
815 $list['blogdesc'] = $data['bdesc'];
817 $list['blogurl'] = $data['burl'];
819 if ($bnametype=='shortname') {
820 $list['blogname'] = $data['bshortname'];
822 else { // all other cases
823 $list['blogname'] = $data['bname'];
833 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
837 sql_free_result($res);
839 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
841 'sitename' => $CONF['SiteName'],
842 'siteurl' => $CONF['IndexURL']
848 * Blogsettings functions
851 function readSettings() {
853 . ' FROM '.sql_table('blog')
854 . ' WHERE bnumber=' . $this->blogid;
855 $res = sql_query($query);
857 $this->isValid = (sql_num_rows($res) > 0);
861 $this->settings = sql_fetch_assoc($res);
864 function writeSettings() {
866 // (can't use floatval since not available prior to PHP 4.2)
867 $offset = $this->getTimeOffset();
868 if (!is_float($offset))
869 $offset = intval($offset);
871 $query = 'UPDATE '.sql_table('blog')
872 . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
873 . " bshortname='". sql_real_escape_string($this->getShortName()) . "',"
874 . " bcomments=". intval($this->commentsEnabled()) . ","
875 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
876 . " btimeoffset=" . $offset . ","
877 . " bpublic=" . intval($this->isPublic()) . ","
878 . " breqemail=" . intval($this->emailRequired()) . ","
879 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
880 . " ballowpast=" . intval($this->allowPastPosting()) . ","
881 . " bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
882 . " bnotifytype=" . intval($this->getNotifyType()) . ","
883 . " burl='" . sql_real_escape_string($this->getURL()) . "',"
884 . " bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
885 . " bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
886 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
887 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
888 . " bincludesearch=" . intval($this->getSearchable())
889 . " WHERE bnumber=" . intval($this->getID());
896 // update update file if requested
897 function updateUpdatefile() {
898 if ($this->getUpdateFile()) {
899 $f_update = fopen($this->getUpdateFile(),'w');
900 fputs($f_update,$this->getCorrectTime());
906 function isValidCategory($catid) {
907 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
908 $res = sql_query($query);
909 return (sql_num_rows($res) != 0);
912 function getCategoryName($catid) {
913 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
914 $o = sql_fetch_object($res);
918 function getCategoryDesc($catid) {
919 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
920 $o = sql_fetch_object($res);
924 function getCategoryIdFromName($name) {
925 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
926 if (sql_num_rows($res) > 0) {
927 $o = sql_fetch_object($res);
930 return $this->getDefaultCategory();
934 function convertBreaks() {
935 return $this->getSetting('bconvertbreaks');
938 function insertJavaScriptInfo($authorid = '') {
939 global $member, $CONF;
942 $authorid = $member->getID();
945 <script type="text/javascript">
946 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
947 setMediaUrl("<?php echo $CONF['MediaURL']?>");
948 setAuthorId(<?php echo $authorid?>);
951 function setConvertBreaks($val) {
952 $this->setSetting('bconvertbreaks',$val);
954 function setAllowPastPosting($val) {
955 $this->setSetting('ballowpast',$val);
957 function allowPastPosting() {
958 return $this->getSetting('ballowpast');
961 function getCorrectTime($t=0) {
962 if ($t == 0) $t = time();
963 return ($t + 3600 * $this->getTimeOffset());
967 return $this->getSetting('bname');
970 function getShortName() {
971 return $this->getSetting('bshortname');
974 function getMaxComments() {
975 return $this->getSetting('bmaxcomments');
978 function getNotifyAddress() {
979 return $this->getSetting('bnotify');
982 function getNotifyType() {
983 return $this->getSetting('bnotifytype');
986 function notifyOnComment() {
987 $n = $this->getNotifyType();
988 return (($n != 0) && (($n % 3) == 0));
991 function notifyOnVote() {
992 $n = $this->getNotifyType();
993 return (($n != 0) && (($n % 5) == 0));
996 function notifyOnNewItem() {
997 $n = $this->getNotifyType();
998 return (($n != 0) && (($n % 7) == 0));
1001 function setNotifyType($val) {
1002 $this->setSetting('bnotifytype',$val);
1006 function getTimeOffset() {
1007 return $this->getSetting('btimeoffset');
1010 function commentsEnabled() {
1011 return $this->getSetting('bcomments');
1015 return $this->getSetting('burl');
1018 function getDefaultSkin() {
1019 return $this->getSetting('bdefskin');
1022 function getUpdateFile() {
1023 return $this->getSetting('bupdate');
1026 function getDescription() {
1027 return $this->getSetting('bdesc');
1030 function isPublic() {
1031 return $this->getSetting('bpublic');
1034 function emailRequired() {
1035 return $this->getSetting('breqemail');
1038 function getSearchable() {
1039 return $this->getSetting('bincludesearch');
1042 function getDefaultCategory() {
1043 return $this->getSetting('bdefcat');
1046 function setPublic($val) {
1047 $this->setSetting('bpublic',$val);
1050 function setSearchable($val) {
1051 $this->setSetting('bincludesearch',$val);
1054 function setDescription($val) {
1055 $this->setSetting('bdesc',$val);
1058 function setUpdateFile($val) {
1059 $this->setSetting('bupdate',$val);
1062 function setDefaultSkin($val) {
1063 $this->setSetting('bdefskin',$val);
1066 function setURL($val) {
1067 $this->setSetting('burl',$val);
1070 function setName($val) {
1071 $this->setSetting('bname',$val);
1074 function setShortName($val) {
1075 $this->setSetting('bshortname',$val);
1078 function setCommentsEnabled($val) {
1079 $this->setSetting('bcomments',$val);
1082 function setMaxComments($val) {
1083 $this->setSetting('bmaxcomments',$val);
1086 function setNotifyAddress($val) {
1087 $this->setSetting('bnotify',$val);
1090 function setEmailRequired($val) {
1091 $this->setSetting('breqemail',$val);
1094 function setTimeOffset($val) {
1095 // check validity of value
1096 // 1. replace , by . (common mistake)
1097 $val = str_replace(',','.',$val);
1098 // 2. cast to float or int
1099 if (is_numeric($val) && strstr($val,'.5')) {
1100 $val = (float) $val;
1102 $val = intval($val);
1105 $this->setSetting('btimeoffset',$val);
1108 function setDefaultCategory($val) {
1109 $this->setSetting('bdefcat',$val);
1112 function getSetting($key) {
1113 return $this->settings[$key];
1116 function setSetting($key,$value) {
1117 $this->settings[$key] = $value;
1121 // tries to add a member to the team. Returns false if the member was already on
1123 function addTeamMember($memberid, $admin) {
1126 $memberid = intval($memberid);
1127 $admin = intval($admin);
1129 // check if member is already a member
1130 $tmem = MEMBER::createFromID($memberid);
1132 if ($tmem->isTeamMember($this->getID()))
1145 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1146 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1150 'PostAddTeamMember',
1159 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1160 ACTIONLOG::add(INFO, $logMsg);
1166 return intVal($this->blogid);
1169 // returns true if there is a blog with the given shortname (static)
1170 function exists($name) {
1171 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1172 return (sql_num_rows($r) != 0);
1175 // returns true if there is a blog with the given ID (static)
1176 function existsID($id) {
1177 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1178 return (sql_num_rows($r) != 0);
1181 // flag there is a future post pending
1182 function setFuturePost() {
1183 $query = 'UPDATE '.sql_table('blog')
1184 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1188 // clear there is a future post pending
1189 function clearFuturePost() {
1190 $query = 'UPDATE '.sql_table('blog')
1191 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1195 // check if we should throw justPosted event
1196 function checkJustPosted() {
1199 if ($this->settings['bfuturepost'] == 1) {
1200 $blogid = $this->getID();
1201 $result = sql_query("SELECT * FROM " . sql_table('item')
1202 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1203 if (sql_num_rows($result) > 0) {
1204 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1205 // Note that the plugins's calling order is subject to thri order in the plugin list
1209 array('blogid' => $blogid,
1210 'pinged' => &$pinged
1214 // clear all expired future posts
1215 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1217 // check to see any pending future post, clear the flag is none
1218 $result = sql_query("SELECT * FROM " . sql_table('item')
1219 . " WHERE iposted=0 AND iblog=" . $blogid);
1220 if (sql_num_rows($result) == 0) {
1221 $this->clearFuturePost();
1228 * Shows the given list of items for this blog
1231 * array of item numbers to be displayed
1233 * String representing the template _NAME_ (!)
1235 * contains a query that should be highlighted
1237 * 1=show comments 0=don't show comments
1239 * 1=show dateheads 0=don't show dateheads
1240 * @param $showDrafts
1241 * 0=do not show drafts 1=show drafts
1242 * @param $showFuture
1243 * 0=do not show future posts 1=show future posts
1245 * amount of items shown
1247 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1249 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1251 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1255 * Returns the SQL query used to fill out templates for a list of items
1258 * an array holding the item numbers of the items to be displayed
1259 * @param $showDrafts
1260 * 0=do not show drafts 1=show drafts
1261 * @param $showFuture
1262 * 0=do not show future posts 1=show future posts
1264 * either a full SQL query, or an empty string
1266 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1268 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1270 if (!is_array($itemarray)) return '';
1271 $showDrafts = intval($showDrafts);
1272 $showFuture = intval($showFuture);
1274 foreach ($itemarray as $value) {
1275 if (intval($value)) $items[] = intval($value);
1277 if (!count($items)) return '';
1278 //$itemlist = implode(',',$items);
1281 foreach ($items as $value) {
1284 . ' i.inumber as itemid,'
1285 . ' i.ititle as title,'
1286 . ' i.ibody as body,'
1287 . ' m.mname as author,'
1288 . ' m.mrealname as authorname,'
1290 . ' i.imore as more,'
1291 . ' m.mnumber as authorid,'
1292 . ' m.memail as authormail,'
1293 . ' m.murl as authorurl,'
1294 . ' c.cname as category,'
1295 . ' i.icat as catid,'
1296 . ' i.iclosed as closed';
1299 . sql_table('item') . ' as i, '
1300 . sql_table('member') . ' as m, '
1301 . sql_table('category').' as c'
1303 . ' i.iblog = ' . $this->blogid
1304 . ' and i.iauthor = m.mnumber'
1305 . ' and i.icat = c.catid';
1307 if (!$showDrafts) $query .= ' and i.idraft=0'; // exclude drafts
1308 if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1310 //$query .= ' and i.inumber IN ('.$itemlist.')';
1311 $query .= ' and i.inumber = '.intval($value);
1314 if ($i) $query .= ' UNION ';