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);
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);
283 // convert newlines to <br />
284 if ($this->convertBreaks()) {
285 $body = addBreaks($body);
286 $more = addBreaks($more);
289 if ($closed != '1') $closed = '0';
290 if ($draft != '0') $draft = '1';
292 if (!$this->isValidCategory($catid))
293 $catid = $this->getDefaultCategory();
295 if ($timestamp > $this->getCorrectTime())
298 $timestamp = date('Y-m-d H:i:s',$timestamp);
305 'authorid' => &$authorid,
306 'timestamp' => &$timestamp,
307 'closed' => &$closed,
311 $manager->notify('PreAddItem', $param);
313 $ititle = sql_real_escape_string($title);
314 $ibody = sql_real_escape_string($body);
315 $imore = sql_real_escape_string($more);
317 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
318 . "VALUES ('$ititle', '$ibody', '$imore', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
320 $itemid = sql_insert_id();
322 $param = array('itemid' => $itemid);
323 $manager->notify('PostAddItem', $param);
326 $this->updateUpdateFile();
328 // send notification mail
329 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
330 $this->sendNewItemNotification($itemid, $title, $body);
335 function sendNewItemNotification($itemid, $title, $body) {
336 global $CONF, $member;
338 // create text version of html post
339 $ascii = toAscii($body);
341 $mailto_msg = _NOTIFY_NI_MSG . " \n";
342 // $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
343 $temp = parse_url($CONF['Self']);
344 if ($temp['scheme']) {
345 $mailto_msg .= createItemLink($itemid) . "\n\n";
347 $tempurl = $this->getURL();
348 if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
349 $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
351 $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
354 $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
355 $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
356 $mailto_msg .= getMailFooter();
358 $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
360 $frommail = $member->getNotifyFromMailAddress();
362 $notify = new NOTIFICATION($this->getNotifyAddress());
363 $notify->notify($mailto_title, $mailto_msg , $frommail);
371 * Creates a new category for this blog
374 * name of the new category. When empty, a name is generated automatically
375 * (starting with newcat)
376 * @param $catDescription
377 * description of the new category. Defaults to 'New Category'
380 * the new category-id in case of success.
383 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
384 global $member, $manager;
386 if ($member->blogAdminRights($this->getID())) {
390 $catName = _CREATED_NEW_CATEGORY_NAME;
393 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
394 while (sql_num_rows($res) > 0)
397 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
400 $catName = $catName . $i;
406 'description' => $catDescription
408 $manager->notify('PreAddCategory', $param);
410 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($catDescription) . "')";
412 $catid = sql_insert_id();
417 'description' => $catDescription,
420 $manager->notify('PostAddCategory', $param);
431 * Searches all months of this blog for the given query
436 * template to be used (__NAME__ of the template)
437 * @param $amountMonths
438 * max amount of months to be search (0 = all)
440 * max number of results to show
444 * amount of hits found
446 function search($query, $template, $amountMonths, $maxresults, $startpos) {
447 global $CONF, $manager;
450 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
454 // no query -> show everything
456 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
459 // add LIMIT to query (to split search results into pages)
460 if (intval($maxresults > 0))
461 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
464 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
466 // when no results were found, show a message
467 if ($amountfound == 0)
469 $template =& $manager->getTemplate($template);
471 'query' => htmlspecialchars($query),
472 'blogid' => $this->getID()
474 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
482 * Returns an SQL query to use for a search query
486 * @param $amountMonths
487 * amount of months to search back. Default = 0 = unlimited
489 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
490 * @returns $highlight
491 * words to highlight (out parameter)
493 * either a full SQL query, or an empty string (if querystring empty)
495 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
497 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
499 $searchclass = new SEARCH($query);
501 $highlight = $searchclass->inclusive;
503 // if querystring is empty, return empty string
504 if ($searchclass->inclusive == '')
508 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
509 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
511 // get list of blogs to search
512 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
513 $blogs[] = $this->getID(); // also search current blog (duh)
514 $blogs = array_unique($blogs); // remove duplicates
516 if (count($blogs) > 0)
517 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
521 $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';
523 $query .= ', '.$select. ' as score ';
525 $query = 'SELECT COUNT(*) as result ';
528 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
529 . ' WHERE i.iauthor=m.mnumber'
530 . ' and i.icat=c.catid'
531 . ' and i.idraft=0' // exclude drafts
533 // don't show future items
534 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
537 // take into account amount of months to search
538 if ($amountMonths > 0)
540 $localtime = getdate($this->getCorrectTime());
541 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
542 $query .= ' and i.itime>' . mysqldate($timestamp_start);
548 $query .= ' ORDER BY score DESC';
550 $query .= ' ORDER BY i.itime DESC ';
557 * Returns the SQL query that's normally used to display the blog items on the index type skins
560 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
562 * either a full SQL query, or an empty string
564 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
566 function getSqlBlog($extraQuery, $mode = '')
569 $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';
571 $query = 'SELECT COUNT(*) as result ';
573 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
574 . ' WHERE i.iblog='.$this->blogid
575 . ' and i.iauthor=m.mnumber'
576 . ' and i.icat=c.catid'
577 . ' and i.idraft=0' // exclude drafts
578 // don't show future items
579 . ' and i.itime<=' . mysqldate($this->getCorrectTime());
581 if ($this->getSelectedCategory())
582 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
585 $query .= $extraQuery;
588 $query .= ' ORDER BY i.itime DESC';
594 * Shows the archivelist using the given template
596 function showArchiveList($template, $mode = 'month', $limit = 0) {
597 global $CONF, $catid, $manager;
599 if (!isset ($linkparams)) {
600 $linkparams = array();
604 $linkparams = array('catid' => $catid);
607 $template =& $manager->getTemplate($template);
608 $data['blogid'] = $this->getID();
610 $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER']
612 echo TEMPLATE::fill($tplt, $data);
614 $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')
615 . ' WHERE iblog=' . $this->getID()
616 . ' and itime <=' . mysqldate($this->getCorrectTime()) // don't show future items!
617 . ' and idraft=0'; // don't show draft items
620 $query .= ' and icat=' . intval($catid);
622 $query .= ' GROUP BY Year';
623 if ($mode == 'month' || $mode == 'day')
628 $query .= ' ORDER BY itime DESC';
631 $query .= ' LIMIT ' . intval($limit);
633 $res = sql_query($query);
635 while ($current = sql_fetch_object($res)) {
636 $current->itime = strtotime($current->itime); // string time -> unix timestamp
638 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'];
644 } elseif ($mode == 'year') {
645 $archivedate = date('Y',$current->itime);
648 $archive['day'] = '';
649 $archive['month'] = '';
651 $archivedate = date('Y-m',$current->itime);
652 $data['month'] = date('m',$current->itime);
653 $archive['month'] = $data['month'];
655 $archive['day'] = '';
658 $data['year'] = date('Y',$current->itime);
659 $archive['year'] = $data['year'];
660 $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
662 $param = array('listitem' => &$data);
663 $manager->notify('PreArchiveListItem', $param);
665 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
666 echo strftimejp($temp,$current->itime);
670 sql_free_result($res);
672 $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER']
674 echo TEMPLATE::fill($tplt, $data);
679 * Shows the list of categories using a given template
681 function showCategoryList($template) {
682 global $CONF, $manager;
684 // determine arguments next to catids
685 // I guess this can be done in a better way, but it works
686 global $archive, $archivelist;
688 $linkparams = array();
690 $blogurl = createArchiveLink($this->getID(), $archive, '');
691 $linkparams['blogid'] = $this->getID();
692 $linkparams['archive'] = $archive;
693 } else if ($archivelist) {
694 $blogurl = createArchiveListLink($this->getID(), '');
695 $linkparams['archivelist'] = $archivelist;
697 $blogurl = createBlogidLink($this->getID(), '');
698 $linkparams['blogid'] = $this->getID();
701 //$blogurl = $this->getURL() . $qargs;
702 //$blogurl = createBlogLink($this->getURL(), $linkparams);
704 $template =& $manager->getTemplate($template);
706 //: Change: Set nocatselected variable
707 if ($this->getSelectedCategory()) {
708 $nocatselected = 'no';
711 $nocatselected = 'yes';
714 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
716 'blogid' => $this->getID(),
717 'blogurl' => $blogurl,
718 'self' => $CONF['Self'],
719 //: Change: Set catiscurrent template variable for header
720 'catiscurrent' => $nocatselected,
721 'currentcat' => $nocatselected
724 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
725 $res = sql_query($query);
728 while ($data = sql_fetch_assoc($res)) {
729 $data['blogid'] = $this->getID();
730 $data['blogurl'] = $blogurl;
731 $data['catlink'] = createLink(
734 'catid' => $data['catid'],
735 'name' => $data['catname'],
736 'extra' => $linkparams
739 $data['self'] = $CONF['Self'];
742 //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
743 $data['catiscurrent'] = 'no';
744 $data['currentcat'] = 'no';
745 if ($this->getSelectedCategory()) {
746 if ($this->getSelectedCategory() == $data['catid']) {
747 $data['catiscurrent'] = 'yes';
748 $data['currentcat'] = 'yes';
751 $data['catiscurrent'] = 'no';
752 $data['currentcat'] = 'no';
757 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
758 $iobj =& $manager->getItem(intval($itemid),0,0);
759 $cid = $iobj['catid'];
760 if ($cid == $data['catid']) {
761 $data['catiscurrent'] = 'yes';
762 $data['currentcat'] = 'yes';
765 $data['catiscurrent'] = 'no';
766 $data['currentcat'] = 'no';
771 $param = array('listitem' => &$data);
772 $manager->notify('PreCategoryListItem', $param);
774 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
775 //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
776 //echo strftime($temp, $current->itime);
780 sql_free_result($res);
782 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
784 'blogid' => $this->getID(),
785 'blogurl' => $blogurl,
786 'self' => $CONF['Self']
791 * Shows a list of all blogs in the system using a given template
792 * ordered by number, name, shortname or description
793 * in ascending or descending order
795 function showBlogList($template, $bnametype, $orderby, $direction) {
796 global $CONF, $manager;
806 $orderby='bshortname';
816 $direction=strtolower($direction);
817 switch ($direction) {
829 $template =& $manager->getTemplate($template);
831 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
833 'sitename' => $CONF['SiteName'],
834 'siteurl' => $CONF['IndexURL']
837 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
838 $res = sql_query($query);
840 while ($data = sql_fetch_assoc($res)) {
844 // $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
845 $list['bloglink'] = createBlogidLink($data['bnumber']);
847 $list['blogdesc'] = $data['bdesc'];
849 $list['blogurl'] = $data['burl'];
851 if ($bnametype=='shortname') {
852 $list['blogname'] = $data['bshortname'];
854 else { // all other cases
855 $list['blogname'] = $data['bname'];
858 $param = array('listitem' => &$list);
859 $manager->notify('PreBlogListItem', $param);
861 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
865 sql_free_result($res);
867 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
869 'sitename' => $CONF['SiteName'],
870 'siteurl' => $CONF['IndexURL']
876 * Blogsettings functions
879 function readSettings() {
881 . ' FROM '.sql_table('blog')
882 . ' WHERE bnumber=' . $this->blogid;
883 $res = sql_query($query);
885 $this->isValid = (sql_num_rows($res) > 0);
889 $this->settings = sql_fetch_assoc($res);
892 function writeSettings() {
894 // (can't use floatval since not available prior to PHP 4.2)
895 $offset = $this->getTimeOffset();
896 if (!is_float($offset))
897 $offset = intval($offset);
899 $query = 'UPDATE '.sql_table('blog')
900 . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
901 . " bshortname='". sql_real_escape_string($this->getShortName()) . "',"
902 . " bcomments=". intval($this->commentsEnabled()) . ","
903 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
904 . " btimeoffset=" . $offset . ","
905 . " bpublic=" . intval($this->isPublic()) . ","
906 . " breqemail=" . intval($this->emailRequired()) . ","
907 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
908 . " ballowpast=" . intval($this->allowPastPosting()) . ","
909 . " bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
910 . " bnotifytype=" . intval($this->getNotifyType()) . ","
911 . " burl='" . sql_real_escape_string($this->getURL()) . "',"
912 . " bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
913 . " bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
914 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
915 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
916 . " bincludesearch=" . intval($this->getSearchable())
917 . " WHERE bnumber=" . intval($this->getID());
924 // update update file if requested
925 function updateUpdatefile() {
926 if ($this->getUpdateFile()) {
927 $f_update = fopen($this->getUpdateFile(),'w');
928 fputs($f_update,$this->getCorrectTime());
934 function isValidCategory($catid) {
935 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
936 $res = sql_query($query);
937 return (sql_num_rows($res) != 0);
940 function getCategoryName($catid) {
941 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
942 $o = sql_fetch_object($res);
946 function getCategoryDesc($catid) {
947 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
948 $o = sql_fetch_object($res);
952 function getCategoryIdFromName($name) {
953 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
954 if (sql_num_rows($res) > 0) {
955 $o = sql_fetch_object($res);
958 return $this->getDefaultCategory();
962 function convertBreaks() {
963 return $this->getSetting('bconvertbreaks');
966 function insertJavaScriptInfo($authorid = '') {
967 global $member, $CONF;
970 $authorid = $member->getID();
973 <script type="text/javascript">
974 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
975 setMediaUrl("<?php echo $CONF['MediaURL']?>");
976 setAuthorId(<?php echo $authorid?>);
979 function setConvertBreaks($val) {
980 $this->setSetting('bconvertbreaks',$val);
982 function setAllowPastPosting($val) {
983 $this->setSetting('ballowpast',$val);
985 function allowPastPosting() {
986 return $this->getSetting('ballowpast');
989 function getCorrectTime($t=0) {
990 if ($t == 0) $t = time();
991 return ($t + 3600 * $this->getTimeOffset());
995 return $this->getSetting('bname');
998 function getShortName() {
999 return $this->getSetting('bshortname');
1002 function getMaxComments() {
1003 return $this->getSetting('bmaxcomments');
1006 function getNotifyAddress() {
1007 return $this->getSetting('bnotify');
1010 function getNotifyType() {
1011 return $this->getSetting('bnotifytype');
1014 function notifyOnComment() {
1015 $n = $this->getNotifyType();
1016 return (($n != 0) && (($n % 3) == 0));
1019 function notifyOnVote() {
1020 $n = $this->getNotifyType();
1021 return (($n != 0) && (($n % 5) == 0));
1024 function notifyOnNewItem() {
1025 $n = $this->getNotifyType();
1026 return (($n != 0) && (($n % 7) == 0));
1029 function setNotifyType($val) {
1030 $this->setSetting('bnotifytype',$val);
1034 function getTimeOffset() {
1035 return $this->getSetting('btimeoffset');
1038 function commentsEnabled() {
1039 return $this->getSetting('bcomments');
1043 return $this->getSetting('burl');
1046 function getDefaultSkin() {
1047 return $this->getSetting('bdefskin');
1050 function getUpdateFile() {
1051 return $this->getSetting('bupdate');
1054 function getDescription() {
1055 return $this->getSetting('bdesc');
1058 function isPublic() {
1059 return $this->getSetting('bpublic');
1062 function emailRequired() {
1063 return $this->getSetting('breqemail');
1066 function getSearchable() {
1067 return $this->getSetting('bincludesearch');
1070 function getDefaultCategory() {
1071 return $this->getSetting('bdefcat');
1074 function setPublic($val) {
1075 $this->setSetting('bpublic',$val);
1078 function setSearchable($val) {
1079 $this->setSetting('bincludesearch',$val);
1082 function setDescription($val) {
1083 $this->setSetting('bdesc',$val);
1086 function setUpdateFile($val) {
1087 $this->setSetting('bupdate',$val);
1090 function setDefaultSkin($val) {
1091 $this->setSetting('bdefskin',$val);
1094 function setURL($val) {
1095 $this->setSetting('burl',$val);
1098 function setName($val) {
1099 $this->setSetting('bname',$val);
1102 function setShortName($val) {
1103 $this->setSetting('bshortname',$val);
1106 function setCommentsEnabled($val) {
1107 $this->setSetting('bcomments',$val);
1110 function setMaxComments($val) {
1111 $this->setSetting('bmaxcomments',$val);
1114 function setNotifyAddress($val) {
1115 $this->setSetting('bnotify',$val);
1118 function setEmailRequired($val) {
1119 $this->setSetting('breqemail',$val);
1122 function setTimeOffset($val) {
1123 // check validity of value
1124 // 1. replace , by . (common mistake)
1125 $val = str_replace(',','.',$val);
1126 // 2. cast to float or int
1127 if (is_numeric($val) && strstr($val,'.5')) {
1128 $val = (float) $val;
1130 $val = intval($val);
1133 $this->setSetting('btimeoffset',$val);
1136 function setDefaultCategory($val) {
1137 $this->setSetting('bdefcat',$val);
1140 function getSetting($key) {
1141 return $this->settings[$key];
1144 function setSetting($key,$value) {
1145 $this->settings[$key] = $value;
1149 // tries to add a member to the team. Returns false if the member was already on
1151 function addTeamMember($memberid, $admin) {
1154 $memberid = intval($memberid);
1155 $admin = intval($admin);
1157 // check if member is already a member
1158 $tmem = MEMBER::createFromID($memberid);
1160 if ($tmem->isTeamMember($this->getID()))
1168 $manager->notify('PreAddTeamMember', $param);
1171 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1172 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1181 $manager->notify('PostAddTeamMember', $param);
1183 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1184 ACTIONLOG::add(INFO, $logMsg);
1190 return intVal($this->blogid);
1193 // returns true if there is a blog with the given shortname (static)
1194 function exists($name) {
1195 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1196 return (sql_num_rows($r) != 0);
1199 // returns true if there is a blog with the given ID (static)
1200 function existsID($id) {
1201 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1202 return (sql_num_rows($r) != 0);
1205 // flag there is a future post pending
1206 function setFuturePost() {
1207 $query = 'UPDATE '.sql_table('blog')
1208 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1212 // clear there is a future post pending
1213 function clearFuturePost() {
1214 $query = 'UPDATE '.sql_table('blog')
1215 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1219 // check if we should throw justPosted event
1220 function checkJustPosted() {
1223 if ($this->settings['bfuturepost'] == 1) {
1224 $blogid = $this->getID();
1225 $result = sql_query("SELECT * FROM " . sql_table('item')
1226 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1227 if (sql_num_rows($result) > 0) {
1228 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1229 // Note that the plugins's calling order is subject to thri order in the plugin list
1232 'blogid' => $blogid,
1233 'pinged' => &$pinged
1235 $manager->notify('JustPosted', $param);
1237 // clear all expired future posts
1238 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1240 // check to see any pending future post, clear the flag is none
1241 $result = sql_query("SELECT * FROM " . sql_table('item')
1242 . " WHERE iposted=0 AND iblog=" . $blogid);
1243 if (sql_num_rows($result) == 0) {
1244 $this->clearFuturePost();
1251 * Shows the given list of items for this blog
1254 * array of item numbers to be displayed
1256 * String representing the template _NAME_ (!)
1258 * contains a query that should be highlighted
1260 * 1=show comments 0=don't show comments
1262 * 1=show dateheads 0=don't show dateheads
1263 * @param $showDrafts
1264 * 0=do not show drafts 1=show drafts
1265 * @param $showFuture
1266 * 0=do not show future posts 1=show future posts
1268 * amount of items shown
1270 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1272 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1274 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1278 * Returns the SQL query used to fill out templates for a list of items
1281 * an array holding the item numbers of the items to be displayed
1282 * @param $showDrafts
1283 * 0=do not show drafts 1=show drafts
1284 * @param $showFuture
1285 * 0=do not show future posts 1=show future posts
1287 * either a full SQL query, or an empty string
1289 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1291 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1293 if (!is_array($itemarray)) return '';
1294 $showDrafts = intval($showDrafts);
1295 $showFuture = intval($showFuture);
1297 foreach ($itemarray as $value) {
1298 if (intval($value)) $items[] = intval($value);
1300 if (!count($items)) return '';
1301 //$itemlist = implode(',',$items);
1304 foreach ($items as $value) {
1307 . ' i.inumber as itemid,'
1308 . ' i.ititle as title,'
1309 . ' i.ibody as body,'
1310 . ' m.mname as author,'
1311 . ' m.mrealname as authorname,'
1313 . ' i.imore as more,'
1314 . ' m.mnumber as authorid,'
1315 . ' m.memail as authormail,'
1316 . ' m.murl as authorurl,'
1317 . ' c.cname as category,'
1318 . ' i.icat as catid,'
1319 . ' i.iclosed as closed';
1322 . sql_table('item') . ' as i, '
1323 . sql_table('member') . ' as m, '
1324 . sql_table('category').' as c'
1326 . ' i.iblog = ' . $this->blogid
1327 . ' and i.iauthor = m.mnumber'
1328 . ' and i.icat = c.catid';
1330 if (!$showDrafts) $query .= ' and i.idraft=0'; // exclude drafts
1331 if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1333 //$query .= ' and i.inumber IN ('.$itemlist.')';
1334 $query .= ' and i.inumber = '.intval($value);
1337 if ($i) $query .= ' UNION ';