4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5 * Copyright (C) 2002-2012 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-2012 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);
194 'timestamp' => $oldTS
196 $manager->notify('PreDateFoot', $param);
197 $tmp_footer = strftimejp(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
198 $parser->parse($tmp_footer);
201 'timestamp' => $oldTS
203 $manager->notify('PostDateFoot', $param);
207 'timestamp' => $timestamp
209 $manager->notify('PreDateHead', $param);
210 // note, to use templatvars in the dateheader, the %-characters need to be doubled in
211 // order to be preserved by strftime
212 $tmp_header = strftimejp((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
213 $parser->parse($tmp_header);
216 'timestamp' => $timestamp
218 $manager->notify('PostDateHead', $param);
220 $old_date = $new_date;
224 $parser->parse($template['ITEM_HEADER']);
229 $manager->notify('PreItem', $param);
230 $parser->parse($template['ITEM']);
235 $manager->notify('PostItem', $param);
236 $parser->parse($template['ITEM_FOOTER']);
240 $numrows = sql_num_rows($items);
242 // add another date footer if there was at least one item
243 if (($numrows > 0) && $dateheads) {
246 'timestamp' => strtotime($old_date)
248 $manager->notify('PreDateFoot', $param);
249 $parser->parse($template['DATE_FOOTER']);
252 'timestamp' => strtotime($old_date)
254 $manager->notify('PostDateFoot', $param);
257 sql_free_result($items); // free memory
263 function showOneitem($itemid, $template, $highlight) {
264 $extraQuery = ' and inumber=' . intval($itemid);
266 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
271 * Adds an item to this blog
273 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
276 $blogid = intval($blogid);
277 $authorid = intval($authorid);
281 $catid = intval($catid);
284 // convert newlines to <br />
285 if ($this->convertBreaks()) {
286 $body = addBreaks($body);
287 $more = addBreaks($more);
290 if ($closed != '1') $closed = '0';
291 if ($draft != '0') $draft = '1';
293 if (!$this->isValidCategory($catid))
294 $catid = $this->getDefaultCategory();
296 if ($timestamp > $this->getCorrectTime())
299 $timestamp = date('Y-m-d H:i:s',$timestamp);
306 'authorid' => &$authorid,
307 'timestamp' => &$timestamp,
308 'closed' => &$closed,
312 $manager->notify('PreAddItem', $param);
314 $ititle = sql_real_escape_string($title);
315 $ibody = sql_real_escape_string($body);
316 $imore = sql_real_escape_string($more);
318 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
319 . "VALUES ('$ititle', '$ibody', '$imore', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
321 $itemid = sql_insert_id();
323 $param = array('itemid' => $itemid);
324 $manager->notify('PostAddItem', $param);
327 $this->updateUpdateFile();
329 // send notification mail
330 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
331 $this->sendNewItemNotification($itemid, $title, $body);
336 function sendNewItemNotification($itemid, $title, $body) {
337 global $CONF, $member;
339 // create text version of html post
340 $ascii = toAscii($body);
342 $mailto_msg = _NOTIFY_NI_MSG . " \n";
343 // $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
344 $temp = parse_url($CONF['Self']);
345 if ($temp['scheme']) {
346 $mailto_msg .= createItemLink($itemid) . "\n\n";
348 $tempurl = $this->getURL();
349 if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
350 $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
352 $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
355 $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
356 $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
357 $mailto_msg .= getMailFooter();
359 $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
361 $frommail = $member->getNotifyFromMailAddress();
363 $notify = new NOTIFICATION($this->getNotifyAddress());
364 $notify->notify($mailto_title, $mailto_msg , $frommail);
372 * Creates a new category for this blog
375 * name of the new category. When empty, a name is generated automatically
376 * (starting with newcat)
377 * @param $catDescription
378 * description of the new category. Defaults to 'New Category'
381 * the new category-id in case of success.
384 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
385 global $member, $manager;
387 if ($member->blogAdminRights($this->getID())) {
391 $catName = _CREATED_NEW_CATEGORY_NAME;
394 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
395 while (sql_num_rows($res) > 0)
398 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
401 $catName = $catName . $i;
407 'description' => $catDescription
409 $manager->notify('PreAddCategory', $param);
411 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($catDescription) . "')";
413 $catid = sql_insert_id();
418 'description' => $catDescription,
421 $manager->notify('PostAddCategory', $param);
432 * Searches all months of this blog for the given query
437 * template to be used (__NAME__ of the template)
438 * @param $amountMonths
439 * max amount of months to be search (0 = all)
441 * max number of results to show
445 * amount of hits found
447 function search($query, $template, $amountMonths, $maxresults, $startpos) {
448 global $CONF, $manager;
451 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
455 // no query -> show everything
457 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
460 // add LIMIT to query (to split search results into pages)
461 if (intval($maxresults > 0))
462 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
465 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
467 // when no results were found, show a message
468 if ($amountfound == 0)
470 $template =& $manager->getTemplate($template);
472 'query' => htmlspecialchars($query),
473 'blogid' => $this->getID()
475 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
483 * Returns an SQL query to use for a search query
487 * @param $amountMonths
488 * amount of months to search back. Default = 0 = unlimited
490 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
491 * @returns $highlight
492 * words to highlight (out parameter)
494 * either a full SQL query, or an empty string (if querystring empty)
496 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
498 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
500 $searchclass = new SEARCH($query);
502 $highlight = $searchclass->inclusive;
504 // if querystring is empty, return empty string
505 if ($searchclass->inclusive == '')
509 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
510 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
512 // get list of blogs to search
513 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
514 $blogs[] = $this->getID(); // also search current blog (duh)
515 $blogs = array_unique($blogs); // remove duplicates
517 if (count($blogs) > 0)
518 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
522 $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';
524 $query .= ', '.$select. ' as score ';
526 $query = 'SELECT COUNT(*) as result ';
529 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
530 . ' WHERE i.iauthor=m.mnumber'
531 . ' and i.icat=c.catid'
532 . ' and i.idraft=0' // exclude drafts
534 // don't show future items
535 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
538 // take into account amount of months to search
539 if ($amountMonths > 0)
541 $localtime = getdate($this->getCorrectTime());
542 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
543 $query .= ' and i.itime>' . mysqldate($timestamp_start);
549 $query .= ' ORDER BY score DESC';
551 $query .= ' ORDER BY i.itime DESC ';
558 * Returns the SQL query that's normally used to display the blog items on the index type skins
561 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
563 * either a full SQL query, or an empty string
565 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
567 function getSqlBlog($extraQuery, $mode = '')
570 $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';
572 $query = 'SELECT COUNT(*) as result ';
574 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
575 . ' WHERE i.iblog='.$this->blogid
576 . ' and i.iauthor=m.mnumber'
577 . ' and i.icat=c.catid'
578 . ' and i.idraft=0' // exclude drafts
579 // don't show future items
580 . ' and i.itime<=' . mysqldate($this->getCorrectTime());
582 if ($this->getSelectedCategory())
583 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
586 $query .= $extraQuery;
589 $query .= ' ORDER BY i.itime DESC';
595 * Shows the archivelist using the given template
597 function showArchiveList($template, $mode = 'month', $limit = 0) {
598 global $CONF, $catid, $manager;
600 if (!isset ($linkparams)) {
601 $linkparams = array();
605 $linkparams = array('catid' => $catid);
608 $template =& $manager->getTemplate($template);
609 $data['blogid'] = $this->getID();
611 $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER']
613 echo TEMPLATE::fill($tplt, $data);
615 $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')
616 . ' WHERE iblog=' . $this->getID()
617 . ' and itime <=' . mysqldate($this->getCorrectTime()) // don't show future items!
618 . ' and idraft=0'; // don't show draft items
621 $query .= ' and icat=' . intval($catid);
623 $query .= ' GROUP BY Year';
624 if ($mode == 'month' || $mode == 'day')
629 $query .= ' ORDER BY itime DESC';
632 $query .= ' LIMIT ' . intval($limit);
634 $res = sql_query($query);
636 while ($current = sql_fetch_object($res)) {
637 $current->itime = strtotime($current->itime); // string time -> unix timestamp
639 if ($mode == 'day') {
640 $archivedate = date('Y-m-d',$current->itime);
641 $archive['day'] = date('d',$current->itime);
642 $data['day'] = date('d',$current->itime);
643 $data['month'] = date('m',$current->itime);
644 $archive['month'] = $data['month'];
645 } elseif ($mode == 'year') {
646 $archivedate = date('Y',$current->itime);
649 $archive['day'] = '';
650 $archive['month'] = '';
652 $archivedate = date('Y-m',$current->itime);
653 $data['month'] = date('m',$current->itime);
654 $archive['month'] = $data['month'];
656 $archive['day'] = '';
659 $data['year'] = date('Y',$current->itime);
660 $archive['year'] = $data['year'];
661 $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
663 $param = array('listitem' => &$data);
664 $manager->notify('PreArchiveListItem', $param);
666 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
667 echo strftimejp($temp,$current->itime);
671 sql_free_result($res);
673 $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER']
675 echo TEMPLATE::fill($tplt, $data);
680 * Shows the list of categories using a given template
682 function showCategoryList($template) {
683 global $CONF, $manager;
685 // determine arguments next to catids
686 // I guess this can be done in a better way, but it works
687 global $archive, $archivelist;
689 $linkparams = array();
691 $blogurl = createArchiveLink($this->getID(), $archive, '');
692 $linkparams['blogid'] = $this->getID();
693 $linkparams['archive'] = $archive;
694 } else if ($archivelist) {
695 $blogurl = createArchiveListLink($this->getID(), '');
696 $linkparams['archivelist'] = $archivelist;
698 $blogurl = createBlogidLink($this->getID(), '');
699 $linkparams['blogid'] = $this->getID();
702 //$blogurl = $this->getURL() . $qargs;
703 //$blogurl = createBlogLink($this->getURL(), $linkparams);
705 $template =& $manager->getTemplate($template);
707 //: Change: Set nocatselected variable
708 if ($this->getSelectedCategory()) {
709 $nocatselected = 'no';
712 $nocatselected = 'yes';
715 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
717 'blogid' => $this->getID(),
718 'blogurl' => $blogurl,
719 'self' => $CONF['Self'],
720 //: Change: Set catiscurrent template variable for header
721 'catiscurrent' => $nocatselected,
722 'currentcat' => $nocatselected
725 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
726 $res = sql_query($query);
729 while ($data = sql_fetch_assoc($res)) {
730 $data['blogid'] = $this->getID();
731 $data['blogurl'] = $blogurl;
732 $data['catlink'] = createLink(
735 'catid' => $data['catid'],
736 'name' => $data['catname'],
737 'extra' => $linkparams
740 $data['self'] = $CONF['Self'];
743 //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
744 $data['catiscurrent'] = 'no';
745 $data['currentcat'] = 'no';
746 if ($this->getSelectedCategory()) {
747 if ($this->getSelectedCategory() == $data['catid']) {
748 $data['catiscurrent'] = 'yes';
749 $data['currentcat'] = 'yes';
752 $data['catiscurrent'] = 'no';
753 $data['currentcat'] = 'no';
758 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
759 $iobj =& $manager->getItem(intval($itemid),0,0);
760 $cid = $iobj['catid'];
761 if ($cid == $data['catid']) {
762 $data['catiscurrent'] = 'yes';
763 $data['currentcat'] = 'yes';
766 $data['catiscurrent'] = 'no';
767 $data['currentcat'] = 'no';
772 $param = array('listitem' => &$data);
773 $manager->notify('PreCategoryListItem', $param);
775 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
776 //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
777 //echo strftime($temp, $current->itime);
781 sql_free_result($res);
783 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
785 'blogid' => $this->getID(),
786 'blogurl' => $blogurl,
787 'self' => $CONF['Self']
792 * Shows a list of all blogs in the system using a given template
793 * ordered by number, name, shortname or description
794 * in ascending or descending order
796 function showBlogList($template, $bnametype, $orderby, $direction) {
797 global $CONF, $manager;
807 $orderby='bshortname';
817 $direction=strtolower($direction);
818 switch ($direction) {
830 $template =& $manager->getTemplate($template);
832 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
834 'sitename' => $CONF['SiteName'],
835 'siteurl' => $CONF['IndexURL']
838 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
839 $res = sql_query($query);
841 while ($data = sql_fetch_assoc($res)) {
845 // $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
846 $list['bloglink'] = createBlogidLink($data['bnumber']);
848 $list['blogdesc'] = $data['bdesc'];
850 $list['blogurl'] = $data['burl'];
852 if ($bnametype=='shortname') {
853 $list['blogname'] = $data['bshortname'];
855 else { // all other cases
856 $list['blogname'] = $data['bname'];
859 $param = array('listitem' => &$list);
860 $manager->notify('PreBlogListItem', $param);
862 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
866 sql_free_result($res);
868 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
870 'sitename' => $CONF['SiteName'],
871 'siteurl' => $CONF['IndexURL']
877 * Blogsettings functions
880 function readSettings() {
882 . ' FROM '.sql_table('blog')
883 . ' WHERE bnumber=' . $this->blogid;
884 $res = sql_query($query);
886 $this->isValid = (sql_num_rows($res) > 0);
890 $this->settings = sql_fetch_assoc($res);
893 function writeSettings() {
895 // (can't use floatval since not available prior to PHP 4.2)
896 $offset = $this->getTimeOffset();
897 if (!is_float($offset))
898 $offset = intval($offset);
900 $query = 'UPDATE '.sql_table('blog')
901 . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
902 . " bshortname='". sql_real_escape_string($this->getShortName()) . "',"
903 . " bcomments=". intval($this->commentsEnabled()) . ","
904 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
905 . " btimeoffset=" . $offset . ","
906 . " bpublic=" . intval($this->isPublic()) . ","
907 . " breqemail=" . intval($this->emailRequired()) . ","
908 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
909 . " ballowpast=" . intval($this->allowPastPosting()) . ","
910 . " bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
911 . " bnotifytype=" . intval($this->getNotifyType()) . ","
912 . " burl='" . sql_real_escape_string($this->getURL()) . "',"
913 . " bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
914 . " bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
915 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
916 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
917 . " bincludesearch=" . intval($this->getSearchable())
918 . " WHERE bnumber=" . intval($this->getID());
925 // update update file if requested
926 function updateUpdatefile() {
927 if ($this->getUpdateFile()) {
928 $f_update = fopen($this->getUpdateFile(),'w');
929 fputs($f_update,$this->getCorrectTime());
935 function isValidCategory($catid) {
936 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
937 $res = sql_query($query);
938 return (sql_num_rows($res) != 0);
941 function getCategoryName($catid) {
942 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
943 $o = sql_fetch_object($res);
947 function getCategoryDesc($catid) {
948 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
949 $o = sql_fetch_object($res);
953 function getCategoryIdFromName($name) {
954 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
955 if (sql_num_rows($res) > 0) {
956 $o = sql_fetch_object($res);
959 return $this->getDefaultCategory();
963 function convertBreaks() {
964 return $this->getSetting('bconvertbreaks');
967 function insertJavaScriptInfo($authorid = '') {
968 global $member, $CONF;
971 $authorid = $member->getID();
974 <script type="text/javascript">
975 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
976 setMediaUrl("<?php echo $CONF['MediaURL']?>");
977 setAuthorId(<?php echo $authorid?>);
980 function setConvertBreaks($val) {
981 $this->setSetting('bconvertbreaks',$val);
983 function setAllowPastPosting($val) {
984 $this->setSetting('ballowpast',$val);
986 function allowPastPosting() {
987 return $this->getSetting('ballowpast');
990 function getCorrectTime($t=0) {
991 if ($t == 0) $t = time();
992 return ($t + 3600 * $this->getTimeOffset());
996 return $this->getSetting('bname');
999 function getShortName() {
1000 return $this->getSetting('bshortname');
1003 function getMaxComments() {
1004 return $this->getSetting('bmaxcomments');
1007 function getNotifyAddress() {
1008 return $this->getSetting('bnotify');
1011 function getNotifyType() {
1012 return $this->getSetting('bnotifytype');
1015 function notifyOnComment() {
1016 $n = $this->getNotifyType();
1017 return (($n != 0) && (($n % 3) == 0));
1020 function notifyOnVote() {
1021 $n = $this->getNotifyType();
1022 return (($n != 0) && (($n % 5) == 0));
1025 function notifyOnNewItem() {
1026 $n = $this->getNotifyType();
1027 return (($n != 0) && (($n % 7) == 0));
1030 function setNotifyType($val) {
1031 $this->setSetting('bnotifytype',$val);
1035 function getTimeOffset() {
1036 return $this->getSetting('btimeoffset');
1039 function commentsEnabled() {
1040 return $this->getSetting('bcomments');
1044 return $this->getSetting('burl');
1047 function getDefaultSkin() {
1048 return $this->getSetting('bdefskin');
1051 function getUpdateFile() {
1052 return $this->getSetting('bupdate');
1055 function getDescription() {
1056 return $this->getSetting('bdesc');
1059 function isPublic() {
1060 return $this->getSetting('bpublic');
1063 function emailRequired() {
1064 return $this->getSetting('breqemail');
1067 function getSearchable() {
1068 return $this->getSetting('bincludesearch');
1071 function getDefaultCategory() {
1072 return $this->getSetting('bdefcat');
1075 function setPublic($val) {
1076 $this->setSetting('bpublic',$val);
1079 function setSearchable($val) {
1080 $this->setSetting('bincludesearch',$val);
1083 function setDescription($val) {
1084 $this->setSetting('bdesc',$val);
1087 function setUpdateFile($val) {
1088 $this->setSetting('bupdate',$val);
1091 function setDefaultSkin($val) {
1092 $this->setSetting('bdefskin',$val);
1095 function setURL($val) {
1096 $this->setSetting('burl',$val);
1099 function setName($val) {
1100 $this->setSetting('bname',$val);
1103 function setShortName($val) {
1104 $this->setSetting('bshortname',$val);
1107 function setCommentsEnabled($val) {
1108 $this->setSetting('bcomments',$val);
1111 function setMaxComments($val) {
1112 $this->setSetting('bmaxcomments',$val);
1115 function setNotifyAddress($val) {
1116 $this->setSetting('bnotify',$val);
1119 function setEmailRequired($val) {
1120 $this->setSetting('breqemail',$val);
1123 function setTimeOffset($val) {
1124 // check validity of value
1125 // 1. replace , by . (common mistake)
1126 $val = str_replace(',','.',$val);
1127 // 2. cast to float or int
1128 if (is_numeric($val) && strstr($val,'.5')) {
1129 $val = (float) $val;
1131 $val = intval($val);
1134 $this->setSetting('btimeoffset',$val);
1137 function setDefaultCategory($val) {
1138 $this->setSetting('bdefcat',$val);
1141 function getSetting($key) {
1142 return $this->settings[$key];
1145 function setSetting($key,$value) {
1146 $this->settings[$key] = $value;
1150 // tries to add a member to the team. Returns false if the member was already on
1152 function addTeamMember($memberid, $admin) {
1155 $memberid = intval($memberid);
1156 $admin = intval($admin);
1158 // check if member is already a member
1159 $tmem = MEMBER::createFromID($memberid);
1161 if ($tmem->isTeamMember($this->getID()))
1169 $manager->notify('PreAddTeamMember', $param);
1172 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1173 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1182 $manager->notify('PostAddTeamMember', $param);
1184 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1185 ACTIONLOG::add(INFO, $logMsg);
1191 return intVal($this->blogid);
1194 // returns true if there is a blog with the given shortname (static)
1195 function exists($name) {
1196 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1197 return (sql_num_rows($r) != 0);
1200 // returns true if there is a blog with the given ID (static)
1201 function existsID($id) {
1202 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1203 return (sql_num_rows($r) != 0);
1206 // flag there is a future post pending
1207 function setFuturePost() {
1208 $query = 'UPDATE '.sql_table('blog')
1209 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1213 // clear there is a future post pending
1214 function clearFuturePost() {
1215 $query = 'UPDATE '.sql_table('blog')
1216 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1220 // check if we should throw justPosted event
1221 function checkJustPosted() {
1224 if ($this->settings['bfuturepost'] == 1) {
1225 $blogid = $this->getID();
1226 $result = sql_query("SELECT * FROM " . sql_table('item')
1227 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1228 if (sql_num_rows($result) > 0) {
1229 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1230 // Note that the plugins's calling order is subject to thri order in the plugin list
1233 'blogid' => $blogid,
1234 'pinged' => &$pinged
1236 $manager->notify('JustPosted', $param);
1238 // clear all expired future posts
1239 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1241 // check to see any pending future post, clear the flag is none
1242 $result = sql_query("SELECT * FROM " . sql_table('item')
1243 . " WHERE iposted=0 AND iblog=" . $blogid);
1244 if (sql_num_rows($result) == 0) {
1245 $this->clearFuturePost();
1252 * Shows the given list of items for this blog
1255 * array of item numbers to be displayed
1257 * String representing the template _NAME_ (!)
1259 * contains a query that should be highlighted
1261 * 1=show comments 0=don't show comments
1263 * 1=show dateheads 0=don't show dateheads
1264 * @param $showDrafts
1265 * 0=do not show drafts 1=show drafts
1266 * @param $showFuture
1267 * 0=do not show future posts 1=show future posts
1269 * amount of items shown
1271 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1273 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1275 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1279 * Returns the SQL query used to fill out templates for a list of items
1282 * an array holding the item numbers of the items to be displayed
1283 * @param $showDrafts
1284 * 0=do not show drafts 1=show drafts
1285 * @param $showFuture
1286 * 0=do not show future posts 1=show future posts
1288 * either a full SQL query, or an empty string
1290 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1292 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1294 if (!is_array($itemarray)) return '';
1295 $showDrafts = intval($showDrafts);
1296 $showFuture = intval($showFuture);
1298 foreach ($itemarray as $value) {
1299 if (intval($value)) $items[] = intval($value);
1301 if (!count($items)) return '';
1302 //$itemlist = implode(',',$items);
1305 foreach ($items as $value) {
1308 . ' i.inumber as itemid,'
1309 . ' i.ititle as title,'
1310 . ' i.ibody as body,'
1311 . ' m.mname as author,'
1312 . ' m.mrealname as authorname,'
1314 . ' i.imore as more,'
1315 . ' m.mnumber as authorid,'
1316 . ' m.memail as authormail,'
1317 . ' m.murl as authorurl,'
1318 . ' c.cname as category,'
1319 . ' i.icat as catid,'
1320 . ' i.iclosed as closed';
1323 . sql_table('item') . ' as i, '
1324 . sql_table('member') . ' as m, '
1325 . sql_table('category').' as c'
1327 . ' i.iblog = ' . $this->blogid
1328 . ' and i.iauthor = m.mnumber'
1329 . ' and i.icat = c.catid';
1331 if (!$showDrafts) $query .= ' and i.idraft=0'; // exclude drafts
1332 if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1334 //$query .= ' and i.inumber IN ('.$itemlist.')';
1335 $query .= ' and i.inumber = '.intval($value);
1338 if ($i) $query .= ' UNION ';