4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5 * Copyright (C) 2002-2013 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)
13 * A class representing a blog and containing functions to get that blog shown
17 if ( !function_exists('requestVar') ) exit;
18 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
25 // ID of currently selected category
28 // After creating an object of the blog class, contains true if the BLOG object is
29 // valid (the blog exists)
32 // associative array, containing all blogsettings (use the get/set functions instead)
36 * Creates a new BLOG object for the given blog
41 $this->blogid = intval($id);
42 $this->readSettings();
45 // (the parse functions in SKIN.php will override this, so it's mainly useless)
47 $this->setSelectedCategory($catid);
51 * Shows the given amount of items for this blog
54 * String representing the template _NAME_ (!)
55 * @param $amountEntries
56 * amount of entries to show
58 * offset from where items should be shown (e.g. 5 = start at fifth item)
60 * amount of items shown
62 function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
63 return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
67 * Shows an archive for a given month
74 * String representing the template name to be used
76 function showArchive($templatename, $year, $month = 0, $day = 0) {
78 // create extra where clause for select query
79 if ($day == 0 && $month != 0) {
80 $timestamp_start = mktime(0,0,0,$month,1,$year);
81 $timestamp_end = mktime(0,0,0,$month+1,1,$year); // also works when $month==12
82 } elseif ($month == 0) {
83 $timestamp_start = mktime(0,0,0,1,1,$year);
84 $timestamp_end = mktime(0,0,0,12,31,$year); // also works when $month==12
86 $timestamp_start = mktime(0,0,0,$month,$day,$year);
87 $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
89 $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
90 . ' and i.itime<' . mysqldate($timestamp_end);
93 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
98 // sets/gets current category (only when category exists)
99 function setSelectedCategory($catid) {
100 if ($this->isValidCategory($catid) || (intval($catid) == 0))
101 $this->selectedcatid = intval($catid);
104 function setSelectedCategoryByName($catname) {
105 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
108 function getSelectedCategory() {
109 return $this->selectedcatid;
113 * Shows the given amount of items for this blog
116 * String representing the template _NAME_ (!)
117 * @param $amountEntries
118 * amount of entries to show (0 = no limit)
120 * extra conditions to be added to the query
122 * contains a query that should be highlighted
124 * 1=show comments 0=don't show comments
126 * 1=show dateheads 0=don't show dateheads
130 * amount of items shown
132 function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
134 $query = $this->getSqlBlog($extraQuery);
136 if ($amountEntries > 0) {
137 // $offset zou moeten worden:
138 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
139 $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
141 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
144 function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
145 global $CONF, $manager;
147 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
149 $lastVisit = $this->getCorrectTime($lastVisit);
151 // set templatename as global variable (so plugins can access it)
152 global $currentTemplateName;
153 $currentTemplateName = $templateName;
155 $template =& $manager->getTemplate($templateName);
157 // create parser object & action handler
158 $actions = new ITEMACTIONS($this);
159 $parser = new PARSER($actions->getDefinedActions(),$actions);
160 $actions->setTemplate($template);
161 $actions->setHighlight($highlight);
162 $actions->setLastVisit($lastVisit);
163 $actions->setParser($parser);
164 $actions->setShowComments($comments);
167 $items = sql_query($query);
169 // loop over all items
171 while ($item = sql_fetch_object($items)) {
173 $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
175 // action handler needs to know the item we're handling
176 $actions->setCurrentItem($item);
178 // add date header if needed
180 $new_date = date('dFY',$item->timestamp);
181 if ($new_date != $old_date) {
182 // unless this is the first time, write date footer
183 $timestamp = $item->timestamp;
184 if ($old_date != 0) {
185 $oldTS = strtotime($old_date);
188 'timestamp' => $oldTS
190 $manager->notify('PreDateFoot', $param);
191 $tmp_footer = strftimejp(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
192 $parser->parse($tmp_footer);
195 'timestamp' => $oldTS
197 $manager->notify('PostDateFoot', $param);
201 'timestamp' => $timestamp
203 $manager->notify('PreDateHead', $param);
204 // note, to use templatvars in the dateheader, the %-characters need to be doubled in
205 // order to be preserved by strftime
206 $tmp_header = strftimejp((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
207 $parser->parse($tmp_header);
210 'timestamp' => $timestamp
212 $manager->notify('PostDateHead', $param);
214 $old_date = $new_date;
218 $parser->parse($template['ITEM_HEADER']);
223 $manager->notify('PreItem', $param);
224 $parser->parse($template['ITEM']);
229 $manager->notify('PostItem', $param);
230 $parser->parse($template['ITEM_FOOTER']);
234 $numrows = sql_num_rows($items);
236 // add another date footer if there was at least one item
237 if (($numrows > 0) && $dateheads) {
240 'timestamp' => strtotime($old_date)
242 $manager->notify('PreDateFoot', $param);
243 $parser->parse($template['DATE_FOOTER']);
246 'timestamp' => strtotime($old_date)
248 $manager->notify('PostDateFoot', $param);
251 sql_free_result($items); // free memory
257 function showOneitem($itemid, $template, $highlight) {
258 $extraQuery = ' and inumber=' . intval($itemid);
260 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
265 * Adds an item to this blog
267 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
270 $blogid = intval($blogid);
271 $authorid = intval($authorid);
275 $catid = intval($catid);
278 // convert newlines to <br />
279 if ($this->convertBreaks()) {
280 $body = addBreaks($body);
281 $more = addBreaks($more);
284 if ($closed != '1') $closed = '0';
285 if ($draft != '0') $draft = '1';
287 if (!$this->isValidCategory($catid))
288 $catid = $this->getDefaultCategory();
290 if ($timestamp > $this->getCorrectTime())
293 $timestamp = date('Y-m-d H:i:s',$timestamp);
300 'authorid' => &$authorid,
301 'timestamp' => &$timestamp,
302 'closed' => &$closed,
306 $manager->notify('PreAddItem', $param);
308 $ititle = sql_real_escape_string($title);
309 $ibody = sql_real_escape_string($body);
310 $imore = sql_real_escape_string($more);
312 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
313 . "VALUES ('$ititle', '$ibody', '$imore', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
315 $itemid = sql_insert_id();
317 $param = array('itemid' => $itemid);
318 $manager->notify('PostAddItem', $param);
321 $this->updateUpdateFile();
323 // send notification mail
324 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
325 $this->sendNewItemNotification($itemid, $title, $body);
330 function sendNewItemNotification($itemid, $title, $body) {
331 global $CONF, $member;
333 // create text version of html post
334 $ascii = toAscii($body);
336 $mailto_msg = _NOTIFY_NI_MSG . " \n";
337 // $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
338 $temp = parse_url($CONF['Self']);
339 if ($temp['scheme']) {
340 $mailto_msg .= createItemLink($itemid) . "\n\n";
342 $tempurl = $this->getURL();
343 if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
344 $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
346 $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
349 $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
350 $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
351 $mailto_msg .= getMailFooter();
353 $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
355 $frommail = $member->getNotifyFromMailAddress();
357 $notify = new NOTIFICATION($this->getNotifyAddress());
358 $notify->notify($mailto_title, $mailto_msg , $frommail);
366 * Creates a new category for this blog
369 * name of the new category. When empty, a name is generated automatically
370 * (starting with newcat)
371 * @param $catDescription
372 * description of the new category. Defaults to 'New Category'
375 * the new category-id in case of success.
378 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
379 global $member, $manager;
381 if ($member->blogAdminRights($this->getID())) {
385 $catName = _CREATED_NEW_CATEGORY_NAME;
388 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
389 while (sql_num_rows($res) > 0)
392 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
395 $catName = $catName . $i;
401 'description' => $catDescription
403 $manager->notify('PreAddCategory', $param);
405 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($catDescription) . "')";
407 $catid = sql_insert_id();
412 'description' => $catDescription,
415 $manager->notify('PostAddCategory', $param);
426 * Searches all months of this blog for the given query
431 * template to be used (__NAME__ of the template)
432 * @param $amountMonths
433 * max amount of months to be search (0 = all)
435 * max number of results to show
439 * amount of hits found
441 function search($query, $template, $amountMonths, $maxresults, $startpos) {
442 global $CONF, $manager;
445 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
449 // no query -> show everything
451 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
454 // add LIMIT to query (to split search results into pages)
455 if (intval($maxresults > 0))
456 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
459 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
461 // when no results were found, show a message
462 if ($amountfound == 0)
464 $template =& $manager->getTemplate($template);
466 'query' => htmlspecialchars($query),
467 'blogid' => $this->getID()
469 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
477 * Returns an SQL query to use for a search query
481 * @param $amountMonths
482 * amount of months to search back. Default = 0 = unlimited
484 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
485 * @returns $highlight
486 * words to highlight (out parameter)
488 * either a full SQL query, or an empty string (if querystring empty)
490 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
492 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
494 $searchclass = new SEARCH($query);
496 $highlight = $searchclass->inclusive;
498 // if querystring is empty, return empty string
499 if ($searchclass->inclusive == '')
503 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
504 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
506 // get list of blogs to search
507 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
508 $blogs[] = $this->getID(); // also search current blog (duh)
509 $blogs = array_unique($blogs); // remove duplicates
511 if (count($blogs) > 0)
512 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
516 $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';
518 $query .= ', '.$select. ' as score ';
520 $query = 'SELECT COUNT(*) as result ';
523 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
524 . ' WHERE i.iauthor=m.mnumber'
525 . ' and i.icat=c.catid'
526 . ' and i.idraft=0' // exclude drafts
528 // don't show future items
529 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
532 // take into account amount of months to search
533 if ($amountMonths > 0)
535 $localtime = getdate($this->getCorrectTime());
536 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
537 $query .= ' and i.itime>' . mysqldate($timestamp_start);
543 $query .= ' ORDER BY score DESC';
545 $query .= ' ORDER BY i.itime DESC ';
552 * Returns the SQL query that's normally used to display the blog items on the index type skins
555 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
557 * either a full SQL query, or an empty string
559 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
561 function getSqlBlog($extraQuery, $mode = '')
564 $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';
566 $query = 'SELECT COUNT(*) as result ';
568 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
569 . ' WHERE i.iblog='.$this->blogid
570 . ' and i.iauthor=m.mnumber'
571 . ' and i.icat=c.catid'
572 . ' and i.idraft=0' // exclude drafts
573 // don't show future items
574 . ' and i.itime<=' . mysqldate($this->getCorrectTime());
576 if ($this->getSelectedCategory())
577 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
580 $query .= $extraQuery;
583 $query .= ' ORDER BY i.itime DESC';
589 * Shows the archivelist using the given template
591 function showArchiveList($template, $mode = 'month', $limit = 0) {
592 global $CONF, $catid, $manager;
594 if (!isset ($linkparams)) {
595 $linkparams = array();
599 $linkparams = array('catid' => $catid);
602 $template =& $manager->getTemplate($template);
603 $data['blogid'] = $this->getID();
605 $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER']
607 echo TEMPLATE::fill($tplt, $data);
609 $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')
610 . ' WHERE iblog=' . $this->getID()
611 . ' and itime <=' . mysqldate($this->getCorrectTime()) // don't show future items!
612 . ' and idraft=0'; // don't show draft items
615 $query .= ' and icat=' . intval($catid);
617 $query .= ' GROUP BY Year';
618 if ($mode == 'month' || $mode == 'day')
623 $query .= ' ORDER BY itime DESC';
626 $query .= ' LIMIT ' . intval($limit);
628 $res = sql_query($query);
630 while ($current = sql_fetch_object($res)) {
631 $current->itime = strtotime($current->itime); // string time -> unix timestamp
633 if ($mode == 'day') {
634 $archivedate = date('Y-m-d',$current->itime);
635 $archive['day'] = date('d',$current->itime);
636 $data['day'] = date('d',$current->itime);
637 $data['month'] = date('m',$current->itime);
638 $archive['month'] = $data['month'];
639 } elseif ($mode == 'year') {
640 $archivedate = date('Y',$current->itime);
643 $archive['day'] = '';
644 $archive['month'] = '';
646 $archivedate = date('Y-m',$current->itime);
647 $data['month'] = date('m',$current->itime);
648 $archive['month'] = $data['month'];
650 $archive['day'] = '';
653 $data['year'] = date('Y',$current->itime);
654 $archive['year'] = $data['year'];
655 $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
657 $param = array('listitem' => &$data);
658 $manager->notify('PreArchiveListItem', $param);
660 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
661 echo strftimejp($temp,$current->itime);
665 sql_free_result($res);
667 $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER']
669 echo TEMPLATE::fill($tplt, $data);
674 * Shows the list of categories using a given template
676 function showCategoryList($template) {
677 global $CONF, $manager;
679 // determine arguments next to catids
680 // I guess this can be done in a better way, but it works
681 global $archive, $archivelist;
683 $linkparams = array();
685 $blogurl = createArchiveLink($this->getID(), $archive, '');
686 $linkparams['blogid'] = $this->getID();
687 $linkparams['archive'] = $archive;
688 } else if ($archivelist) {
689 $blogurl = createArchiveListLink($this->getID(), '');
690 $linkparams['archivelist'] = $archivelist;
692 $blogurl = createBlogidLink($this->getID(), '');
693 $linkparams['blogid'] = $this->getID();
696 //$blogurl = $this->getURL() . $qargs;
697 //$blogurl = createBlogLink($this->getURL(), $linkparams);
699 $template =& $manager->getTemplate($template);
701 //: Change: Set nocatselected variable
702 if ($this->getSelectedCategory()) {
703 $nocatselected = 'no';
706 $nocatselected = 'yes';
709 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
711 'blogid' => $this->getID(),
712 'blogurl' => $blogurl,
713 'self' => $CONF['Self'],
714 //: Change: Set catiscurrent template variable for header
715 'catiscurrent' => $nocatselected,
716 'currentcat' => $nocatselected
719 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
720 $res = sql_query($query);
723 while ($data = sql_fetch_assoc($res)) {
724 $data['blogid'] = $this->getID();
725 $data['blogurl'] = $blogurl;
726 $data['catlink'] = createLink(
729 'catid' => $data['catid'],
730 'name' => $data['catname'],
731 'extra' => $linkparams
734 $data['self'] = $CONF['Self'];
737 //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
738 $data['catiscurrent'] = 'no';
739 $data['currentcat'] = 'no';
740 if ($this->getSelectedCategory()) {
741 if ($this->getSelectedCategory() == $data['catid']) {
742 $data['catiscurrent'] = 'yes';
743 $data['currentcat'] = 'yes';
746 $data['catiscurrent'] = 'no';
747 $data['currentcat'] = 'no';
752 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
753 $iobj =& $manager->getItem(intval($itemid),0,0);
754 $cid = $iobj['catid'];
755 if ($cid == $data['catid']) {
756 $data['catiscurrent'] = 'yes';
757 $data['currentcat'] = 'yes';
760 $data['catiscurrent'] = 'no';
761 $data['currentcat'] = 'no';
766 $param = array('listitem' => &$data);
767 $manager->notify('PreCategoryListItem', $param);
769 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
770 //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
771 //echo strftime($temp, $current->itime);
775 sql_free_result($res);
777 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
779 'blogid' => $this->getID(),
780 'blogurl' => $blogurl,
781 'self' => $CONF['Self']
786 * Shows a list of all blogs in the system using a given template
787 * ordered by number, name, shortname or description
788 * in ascending or descending order
790 function showBlogList($template, $bnametype, $orderby, $direction) {
791 global $CONF, $manager;
801 $orderby='bshortname';
811 $direction=strtolower($direction);
812 switch ($direction) {
824 $template =& $manager->getTemplate($template);
826 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
828 'sitename' => $CONF['SiteName'],
829 'siteurl' => $CONF['IndexURL']
832 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
833 $res = sql_query($query);
835 while ($data = sql_fetch_assoc($res)) {
839 // $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
840 $list['bloglink'] = createBlogidLink($data['bnumber']);
842 $list['blogdesc'] = $data['bdesc'];
844 $list['blogurl'] = $data['burl'];
846 if ($bnametype=='shortname') {
847 $list['blogname'] = $data['bshortname'];
849 else { // all other cases
850 $list['blogname'] = $data['bname'];
853 $param = array('listitem' => &$list);
854 $manager->notify('PreBlogListItem', $param);
856 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
860 sql_free_result($res);
862 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
864 'sitename' => $CONF['SiteName'],
865 'siteurl' => $CONF['IndexURL']
871 * Blogsettings functions
874 function readSettings() {
876 . ' FROM '.sql_table('blog')
877 . ' WHERE bnumber=' . $this->blogid;
878 $res = sql_query($query);
880 $this->isValid = (sql_num_rows($res) > 0);
884 $this->settings = sql_fetch_assoc($res);
887 function writeSettings() {
889 // (can't use floatval since not available prior to PHP 4.2)
890 $offset = $this->getTimeOffset();
891 if (!is_float($offset))
892 $offset = intval($offset);
894 $query = 'UPDATE '.sql_table('blog')
895 . " SET bname='" . sql_real_escape_string($this->getName()) . "',"
896 . " bshortname='". sql_real_escape_string($this->getShortName()) . "',"
897 . " bcomments=". intval($this->commentsEnabled()) . ","
898 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
899 . " btimeoffset=" . $offset . ","
900 . " bpublic=" . intval($this->isPublic()) . ","
901 . " breqemail=" . intval($this->emailRequired()) . ","
902 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
903 . " ballowpast=" . intval($this->allowPastPosting()) . ","
904 . " bnotify='" . sql_real_escape_string($this->getNotifyAddress()) . "',"
905 . " bnotifytype=" . intval($this->getNotifyType()) . ","
906 . " burl='" . sql_real_escape_string($this->getURL()) . "',"
907 . " bupdate='" . sql_real_escape_string($this->getUpdateFile()) . "',"
908 . " bdesc='" . sql_real_escape_string($this->getDescription()) . "',"
909 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
910 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
911 . " bincludesearch=" . intval($this->getSearchable())
912 . " WHERE bnumber=" . intval($this->getID());
919 // update update file if requested
920 function updateUpdatefile() {
921 if ($this->getUpdateFile()) {
922 $f_update = fopen($this->getUpdateFile(),'w');
923 fputs($f_update,$this->getCorrectTime());
929 function isValidCategory($catid) {
930 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
931 $res = sql_query($query);
932 return (sql_num_rows($res) != 0);
935 function getCategoryName($catid) {
936 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
937 $o = sql_fetch_object($res);
941 function getCategoryDesc($catid) {
942 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
943 $o = sql_fetch_object($res);
947 function getCategoryIdFromName($name) {
948 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
949 if (sql_num_rows($res) > 0) {
950 $o = sql_fetch_object($res);
953 return $this->getDefaultCategory();
957 function convertBreaks() {
958 return $this->getSetting('bconvertbreaks');
961 function insertJavaScriptInfo($authorid = '') {
962 global $member, $CONF;
965 $authorid = $member->getID();
968 <script type="text/javascript">
969 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
970 setMediaUrl("<?php echo $CONF['MediaURL']?>");
971 setAuthorId(<?php echo $authorid?>);
974 function setConvertBreaks($val) {
975 $this->setSetting('bconvertbreaks',$val);
977 function setAllowPastPosting($val) {
978 $this->setSetting('ballowpast',$val);
980 function allowPastPosting() {
981 return $this->getSetting('ballowpast');
984 function getCorrectTime($t=0) {
985 if ($t == 0) $t = time();
986 return ($t + 3600 * $this->getTimeOffset());
990 return $this->getSetting('bname');
993 function getShortName() {
994 return $this->getSetting('bshortname');
997 function getMaxComments() {
998 return $this->getSetting('bmaxcomments');
1001 function getNotifyAddress() {
1002 return $this->getSetting('bnotify');
1005 function getNotifyType() {
1006 return $this->getSetting('bnotifytype');
1009 function notifyOnComment() {
1010 $n = $this->getNotifyType();
1011 return (($n != 0) && (($n % 3) == 0));
1014 function notifyOnVote() {
1015 $n = $this->getNotifyType();
1016 return (($n != 0) && (($n % 5) == 0));
1019 function notifyOnNewItem() {
1020 $n = $this->getNotifyType();
1021 return (($n != 0) && (($n % 7) == 0));
1024 function setNotifyType($val) {
1025 $this->setSetting('bnotifytype',$val);
1029 function getTimeOffset() {
1030 return $this->getSetting('btimeoffset');
1033 function commentsEnabled() {
1034 return $this->getSetting('bcomments');
1038 return $this->getSetting('burl');
1041 function getDefaultSkin() {
1042 return $this->getSetting('bdefskin');
1045 function getUpdateFile() {
1046 return $this->getSetting('bupdate');
1049 function getDescription() {
1050 return $this->getSetting('bdesc');
1053 function isPublic() {
1054 return $this->getSetting('bpublic');
1057 function emailRequired() {
1058 return $this->getSetting('breqemail');
1061 function getSearchable() {
1062 return $this->getSetting('bincludesearch');
1065 function getDefaultCategory() {
1066 return $this->getSetting('bdefcat');
1069 function setPublic($val) {
1070 $this->setSetting('bpublic',$val);
1073 function setSearchable($val) {
1074 $this->setSetting('bincludesearch',$val);
1077 function setDescription($val) {
1078 $this->setSetting('bdesc',$val);
1081 function setUpdateFile($val) {
1082 $this->setSetting('bupdate',$val);
1085 function setDefaultSkin($val) {
1086 $this->setSetting('bdefskin',$val);
1089 function setURL($val) {
1090 $this->setSetting('burl',$val);
1093 function setName($val) {
1094 $this->setSetting('bname',$val);
1097 function setShortName($val) {
1098 $this->setSetting('bshortname',$val);
1101 function setCommentsEnabled($val) {
1102 $this->setSetting('bcomments',$val);
1105 function setMaxComments($val) {
1106 $this->setSetting('bmaxcomments',$val);
1109 function setNotifyAddress($val) {
1110 $this->setSetting('bnotify',$val);
1113 function setEmailRequired($val) {
1114 $this->setSetting('breqemail',$val);
1117 function setTimeOffset($val) {
1118 // check validity of value
1119 // 1. replace , by . (common mistake)
1120 $val = str_replace(',','.',$val);
1121 // 2. cast to float or int
1122 if (is_numeric($val) && strstr($val,'.5')) {
1123 $val = (float) $val;
1125 $val = intval($val);
1128 $this->setSetting('btimeoffset',$val);
1131 function setDefaultCategory($val) {
1132 $this->setSetting('bdefcat',$val);
1135 function getSetting($key) {
1136 return $this->settings[$key];
1139 function setSetting($key,$value) {
1140 $this->settings[$key] = $value;
1144 // tries to add a member to the team. Returns false if the member was already on
1146 function addTeamMember($memberid, $admin) {
1149 $memberid = intval($memberid);
1150 $admin = intval($admin);
1152 // check if member is already a member
1153 $tmem = MEMBER::createFromID($memberid);
1155 if ($tmem->isTeamMember($this->getID()))
1163 $manager->notify('PreAddTeamMember', $param);
1166 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1167 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1176 $manager->notify('PostAddTeamMember', $param);
1178 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1179 ACTIONLOG::add(INFO, $logMsg);
1185 return intVal($this->blogid);
1188 // returns true if there is a blog with the given shortname (static)
1189 function exists($name) {
1190 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1191 return (sql_num_rows($r) != 0);
1194 // returns true if there is a blog with the given ID (static)
1195 function existsID($id) {
1196 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1197 return (sql_num_rows($r) != 0);
1200 // flag there is a future post pending
1201 function setFuturePost() {
1202 $query = 'UPDATE '.sql_table('blog')
1203 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1207 // clear there is a future post pending
1208 function clearFuturePost() {
1209 $query = 'UPDATE '.sql_table('blog')
1210 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1214 // check if we should throw justPosted event
1215 function checkJustPosted() {
1218 if ($this->settings['bfuturepost'] == 1) {
1219 $blogid = $this->getID();
1220 $result = sql_query("SELECT * FROM " . sql_table('item')
1221 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1222 if (sql_num_rows($result) > 0) {
1223 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1224 // Note that the plugins's calling order is subject to thri order in the plugin list
1227 'blogid' => $blogid,
1228 'pinged' => &$pinged
1230 $manager->notify('JustPosted', $param);
1232 // clear all expired future posts
1233 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1235 // check to see any pending future post, clear the flag is none
1236 $result = sql_query("SELECT * FROM " . sql_table('item')
1237 . " WHERE iposted=0 AND iblog=" . $blogid);
1238 if (sql_num_rows($result) == 0) {
1239 $this->clearFuturePost();
1246 * Shows the given list of items for this blog
1249 * array of item numbers to be displayed
1251 * String representing the template _NAME_ (!)
1253 * contains a query that should be highlighted
1255 * 1=show comments 0=don't show comments
1257 * 1=show dateheads 0=don't show dateheads
1258 * @param $showDrafts
1259 * 0=do not show drafts 1=show drafts
1260 * @param $showFuture
1261 * 0=do not show future posts 1=show future posts
1263 * amount of items shown
1265 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1267 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1269 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1273 * Returns the SQL query used to fill out templates for a list of items
1276 * an array holding the item numbers of the items to be displayed
1277 * @param $showDrafts
1278 * 0=do not show drafts 1=show drafts
1279 * @param $showFuture
1280 * 0=do not show future posts 1=show future posts
1282 * either a full SQL query, or an empty string
1284 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1286 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1288 if (!is_array($itemarray)) return '';
1289 $showDrafts = intval($showDrafts);
1290 $showFuture = intval($showFuture);
1292 foreach ($itemarray as $value) {
1293 if (intval($value)) $items[] = intval($value);
1295 if (!count($items)) return '';
1296 //$itemlist = implode(',',$items);
1299 foreach ($items as $value) {
1302 . ' i.inumber as itemid,'
1303 . ' i.ititle as title,'
1304 . ' i.ibody as body,'
1305 . ' m.mname as author,'
1306 . ' m.mrealname as authorname,'
1308 . ' i.imore as more,'
1309 . ' m.mnumber as authorid,'
1310 . ' m.memail as authormail,'
1311 . ' m.murl as authorurl,'
1312 . ' c.cname as category,'
1313 . ' i.icat as catid,'
1314 . ' i.iclosed as closed';
1317 . sql_table('item') . ' as i, '
1318 . sql_table('member') . ' as m, '
1319 . sql_table('category').' as c'
1321 . ' i.iblog = ' . $this->blogid
1322 . ' and i.iauthor = m.mnumber'
1323 . ' and i.icat = c.catid';
1325 if (!$showDrafts) $query .= ' and i.idraft=0'; // exclude drafts
1326 if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1328 //$query .= ' and i.inumber IN ('.$itemlist.')';
1329 $query .= ' and i.inumber = '.intval($value);
1332 if ($i) $query .= ' UNION ';