4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
5 * Copyright (C) 2002-2009 The Nucleus Group
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 * (see nucleus/documentation/index.html#license for more info)
14 * A class representing a blog and containing functions to get that blog shown
17 * @license http://nucleuscms.org/license.txt GNU General Public License
18 * @copyright Copyright (C) 2002-2009 The Nucleus Group
19 * @version $Id: BLOG.php 1624 2012-01-09 11:36:20Z sakamocchi $
22 if ( !function_exists('requestVar') ) exit;
23 require_once dirname(__FILE__) . '/ITEMACTIONS.php';
30 // ID of currently selected category
33 // After creating an object of the blog class, contains true if the BLOG object is
34 // valid (the blog exists)
37 // associative array, containing all blogsettings (use the get/set functions instead)
41 * Creates a new BLOG object for the given blog
46 $this->blogid = intval($id);
47 $this->readSettings();
50 // (the parse functions in SKIN.php will override this, so it's mainly useless)
52 $this->setSelectedCategory($catid);
56 * Shows the given amount of items for this blog
59 * String representing the template _NAME_ (!)
60 * @param $amountEntries
61 * amount of entries to show
63 * offset from where items should be shown (e.g. 5 = start at fifth item)
65 * amount of items shown
67 function readLog($template, $amountEntries, $offset = 0, $startpos = 0) {
68 return $this->readLogAmount($template,$amountEntries,'','',1,1,$offset, $startpos);
72 * Shows an archive for a given month
79 * String representing the template name to be used
81 function showArchive($templatename, $year, $month=0, $day=0) {
83 // create extra where clause for select query
84 if ($day == 0 && $month != 0) {
85 $timestamp_start = mktime(0,0,0,$month,1,$year);
86 $timestamp_end = mktime(0,0,0,$month+1,1,$year); // also works when $month==12
87 } elseif ($month == 0) {
88 $timestamp_start = mktime(0,0,0,1,1,$year);
89 $timestamp_end = mktime(0,0,0,12,31,$year); // also works when $month==12
91 $timestamp_start = mktime(0,0,0,$month,$day,$year);
92 $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
94 $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
95 . ' and i.itime<' . mysqldate($timestamp_end);
98 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
103 * Sets the selected category by id (only when category exists)
105 function setSelectedCategory($catid) {
106 if ($this->isValidCategory($catid) || (intval($catid) == 0))
107 $this->selectedcatid = intval($catid);
111 * Sets the selected category by name
113 function setSelectedCategoryByName($catname) {
114 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
118 * Returns the selected category
120 function getSelectedCategory() {
121 return $this->selectedcatid;
125 * Shows the given amount of items for this blog
128 * String representing the template _NAME_ (!)
129 * @param $amountEntries
130 * amount of entries to show (0 = no limit)
132 * extra conditions to be added to the query
134 * contains a query that should be highlighted
136 * 1=show comments 0=don't show comments
138 * 1=show dateheads 0=don't show dateheads
142 * amount of items shown
144 function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
146 $query = $this->getSqlBlog($extraQuery);
148 if ($amountEntries > 0) {
149 // $offset zou moeten worden:
150 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
151 $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
153 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
157 * Do the job for readLogAmmount
159 function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
160 global $CONF, $manager;
162 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
164 $lastVisit = $this->getCorrectTime($lastVisit);
166 // set templatename as global variable (so plugins can access it)
167 global $currentTemplateName;
168 $currentTemplateName = $templateName;
170 $template =& $manager->getTemplate($templateName);
172 // create parser object & action handler
173 $actions = new ITEMACTIONS($this);
174 $parser = new PARSER($actions->getDefinedActions(),$actions);
175 $actions->setTemplate($template);
176 $actions->setHighlight($highlight);
177 $actions->setLastVisit($lastVisit);
178 $actions->setParser($parser);
179 $actions->setShowComments($comments);
182 $items = sql_query($query);
184 // loop over all items
186 while ($item = sql_fetch_object($items)) {
188 $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
190 // action handler needs to know the item we're handling
191 $actions->setCurrentItem($item);
193 // add date header if needed
195 $new_date = date('dFY',$item->timestamp);
196 if ($new_date != $old_date) {
197 // unless this is the first time, write date footer
198 $timestamp = $item->timestamp;
199 if ($old_date != 0) {
200 $oldTS = strtotime($old_date);
201 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
202 $tmp_footer = i18n::strftime(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
203 $parser->parse($tmp_footer);
204 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
206 $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
207 // note, to use templatvars in the dateheader, the %-characters need to be doubled in
208 // order to be preserved by strftime
209 $tmp_header = i18n::strftime((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
210 $parser->parse($tmp_header);
211 $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
213 $old_date = $new_date;
217 $parser->parse($template['ITEM_HEADER']);
218 $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));
219 $parser->parse($template['ITEM']);
220 $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));
221 $parser->parse($template['ITEM_FOOTER']);
225 $numrows = sql_num_rows($items);
227 // add another date footer if there was at least one item
228 if (($numrows > 0) && $dateheads) {
229 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
230 $parser->parse($template['DATE_FOOTER']);
231 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
234 sql_free_result($items); // free memory
241 * Simplified function for showing only one item
243 function showOneitem($itemid, $template, $highlight) {
244 $extraQuery = ' and inumber=' . intval($itemid);
246 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
251 * Adds an item to this blog
253 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
256 $blogid = intval($blogid);
257 $authorid = intval($authorid);
261 $catid = intval($catid);
263 // convert newlines to <br />
264 if ($this->convertBreaks()) {
265 $body = addBreaks($body);
266 $more = addBreaks($more);
269 if ($closed != '1') $closed = '0';
270 if ($draft != '0') $draft = '1';
272 if (!$this->isValidCategory($catid))
273 $catid = $this->getDefaultCategory();
275 if ($timestamp > $this->getCorrectTime())
278 $timestamp = date('Y-m-d H:i:s',$timestamp);
280 $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
282 $ititle = sql_real_escape_string($title);
283 $ibody = sql_real_escape_string($body);
284 $imore = sql_real_escape_string($more);
286 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
287 . "VALUES ('$ititle', '$ibody', '$imore', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
289 $itemid = sql_insert_id();
291 $manager->notify('PostAddItem',array('itemid' => $itemid));
294 $this->updateUpdateFile();
296 // send notification mail
297 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
298 $this->sendNewItemNotification($itemid, $title, $body);
304 * BLOG::sendNewItemNotification()
305 * Send a new item notification to the notification list
307 * @param String $itemid ID of the item
308 * @param String $title title of the item
309 * @param String $body body of the item
312 function sendNewItemNotification($itemid, $title, $body)
314 global $CONF, $member;
316 // FIXME: create text version of html post. this seems to be needless...
317 $ascii = toAscii($body);
319 $message = _NOTIFY_NI_MSG . " \n";
320 $temp = parse_url($CONF['Self']);
321 if ( $temp['scheme'] )
323 $message .= createItemLink($itemid) . "\n\n";
327 $tempurl = $this->getURL();
328 if ( i18n::substr($tempurl, -1) == '/' || i18n::substr($tempurl, -4) == '.php' )
330 $message .= $tempurl . '?itemid=' . $itemid . "\n\n";
334 $message .= $tempurl . '/?itemid=' . $itemid . "\n\n";
337 $message .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
338 $message .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
339 $message .= NOTIFICATION::get_mail_footer();
341 $subject = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
343 $from = $member->getNotifyFromMailAddress();
345 NOTIFICATION::mail($this->getNotifyAddress(), $subject, $message, $from, i18n::get_current_charset());
351 * Creates a new category for this blog
354 * name of the new category. When empty, a name is generated automatically
355 * (starting with newcat)
356 * @param $catDescription
357 * description of the new category. Defaults to 'New Category'
360 * the new category-id in case of success.
363 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
364 global $member, $manager;
366 if ($member->blogAdminRights($this->getID())) {
370 $catName = _CREATED_NEW_CATEGORY_NAME;
373 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
374 while (sql_num_rows($res) > 0)
377 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
380 $catName = $catName . $i;
388 'description' => $catDescription
392 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . sql_real_escape_string($catName) . "', '" . sql_real_escape_string($catDescription) . "')";
394 $catid = sql_insert_id();
401 'description' => $catDescription,
415 * Searches all months of this blog for the given query
420 * template to be used (__NAME__ of the template)
421 * @param $amountMonths
422 * max amount of months to be search (0 = all)
424 * max number of results to show
428 * amount of hits found
430 function search($query, $template, $amountMonths, $maxresults, $startpos) {
431 global $CONF, $manager;
434 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
438 // no query -> show everything
440 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
443 // add LIMIT to query (to split search results into pages)
444 if (intval($maxresults > 0))
445 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
448 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
450 // when no results were found, show a message
451 if ($amountfound == 0)
453 $template =& $manager->getTemplate($template);
455 'query' => i18n::hsc($query),
456 'blogid' => $this->getID()
458 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
466 * Returns an SQL query to use for a search query
470 * @param $amountMonths
471 * amount of months to search back. Default = 0 = unlimited
473 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
474 * @returns $highlight
475 * words to highlight (out parameter)
477 * either a full SQL query, or an empty string (if querystring empty)
479 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
481 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
483 $searchclass = new SEARCH($query);
485 $highlight = $searchclass->inclusive;
487 // if querystring is empty, return empty string
488 if ($searchclass->inclusive == '')
492 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
493 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
495 // get list of blogs to search
496 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
497 $blogs[] = $this->getID(); // also search current blog (duh)
498 $blogs = array_unique($blogs); // remove duplicates
500 if (count($blogs) > 0)
501 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
505 $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';
507 $query .= ', '.$select. ' as score ';
509 $query = 'SELECT COUNT(*) as result ';
512 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
513 . ' WHERE i.iauthor=m.mnumber'
514 . ' and i.icat=c.catid'
515 . ' and i.idraft=0' // exclude drafts
517 // don't show future items
518 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
521 // take into account amount of months to search
522 if ($amountMonths > 0)
524 $localtime = getdate($this->getCorrectTime());
525 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
526 $query .= ' and i.itime>' . mysqldate($timestamp_start);
532 $query .= ' ORDER BY score DESC';
534 $query .= ' ORDER BY i.itime DESC ';
541 * Returns the SQL query that's normally used to display the blog items on the index type skins
544 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
546 * either a full SQL query, or an empty string
548 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
550 function getSqlBlog($extraQuery, $mode = '')
553 $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';
555 $query = 'SELECT COUNT(*) as result ';
557 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
558 . ' WHERE i.iblog='.$this->blogid
559 . ' and i.iauthor=m.mnumber'
560 . ' and i.icat=c.catid'
561 . ' and i.idraft=0' // exclude drafts
562 // don't show future items
563 . ' and i.itime<=' . mysqldate($this->getCorrectTime());
565 if ($this->getSelectedCategory())
566 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
569 $query .= $extraQuery;
572 $query .= ' ORDER BY i.itime DESC';
578 * Shows the archivelist using the given template
580 function showArchiveList($template, $mode = 'month', $limit = 0) {
581 global $CONF, $catid, $manager;
583 if (!isset ($linkparams)) {
584 $linkparams = array();
588 $linkparams = array('catid' => $catid);
591 $template =& $manager->getTemplate($template);
592 $data['blogid'] = $this->getID();
594 $tplt = isset($template['ARCHIVELIST_HEADER']) ? $template['ARCHIVELIST_HEADER']
596 echo TEMPLATE::fill($tplt, $data);
598 $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')
599 . ' WHERE iblog=' . $this->getID()
600 . ' and itime <=' . mysqldate($this->getCorrectTime()) // don't show future items!
601 . ' and idraft=0'; // don't show draft items
604 $query .= ' and icat=' . intval($catid);
606 $query .= ' GROUP BY Year';
607 if ($mode == 'month' || $mode == 'day')
612 $query .= ' ORDER BY itime DESC';
615 $query .= ' LIMIT ' . intval($limit);
617 $res = sql_query($query);
619 while ($current = sql_fetch_object($res)) {
620 $current->itime = strtotime($current->itime); // string time -> unix timestamp
622 if ($mode == 'day') {
623 $archivedate = date('Y-m-d',$current->itime);
624 $archive['day'] = date('d',$current->itime);
625 $data['day'] = date('d',$current->itime);
626 $data['month'] = date('m',$current->itime);
627 $archive['month'] = $data['month'];
628 } elseif ($mode == 'year') {
629 $archivedate = date('Y',$current->itime);
632 $archive['day'] = '';
633 $archive['month'] = '';
635 $archivedate = date('Y-m',$current->itime);
636 $data['month'] = date('m',$current->itime);
637 $archive['month'] = $data['month'];
639 $archive['day'] = '';
642 $data['year'] = date('Y',$current->itime);
643 $archive['year'] = $data['year'];
644 $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
647 'PreArchiveListItem',
653 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
654 echo i18n::strftime($temp,$current->itime);
658 sql_free_result($res);
660 $tplt = isset($template['ARCHIVELIST_FOOTER']) ? $template['ARCHIVELIST_FOOTER']
662 echo TEMPLATE::fill($tplt, $data);
667 * Shows the list of categories using a given template
669 function showCategoryList($template) {
670 global $CONF, $manager;
672 // determine arguments next to catids
673 // I guess this can be done in a better way, but it works
674 global $archive, $archivelist;
676 $linkparams = array();
678 $blogurl = createArchiveLink($this->getID(), $archive, '');
679 $linkparams['blogid'] = $this->getID();
680 $linkparams['archive'] = $archive;
681 } else if ($archivelist) {
682 $blogurl = createArchiveListLink($this->getID(), '');
683 $linkparams['archivelist'] = $archivelist;
685 $blogurl = createBlogidLink($this->getID(), '');
686 $linkparams['blogid'] = $this->getID();
689 //$blogurl = $this->getURL() . $qargs;
690 //$blogurl = createBlogLink($this->getURL(), $linkparams);
692 $template =& $manager->getTemplate($template);
694 //: Change: Set nocatselected variable
695 if ($this->getSelectedCategory()) {
696 $nocatselected = 'no';
699 $nocatselected = 'yes';
702 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
704 'blogid' => $this->getID(),
705 'blogurl' => $blogurl,
706 'self' => $CONF['Self'],
707 //: Change: Set catiscurrent template variable for header
708 'catiscurrent' => $nocatselected,
709 'currentcat' => $nocatselected
712 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
713 $res = sql_query($query);
716 while ($data = sql_fetch_assoc($res)) {
717 $data['blogid'] = $this->getID();
718 $data['blogurl'] = $blogurl;
719 $data['catlink'] = createLink(
722 'catid' => $data['catid'],
723 'name' => $data['catname'],
724 'extra' => $linkparams
727 $data['self'] = $CONF['Self'];
730 //: Change: Bugfix for catiscurrent logic so it gives catiscurrent = no when no category is selected.
731 $data['catiscurrent'] = 'no';
732 $data['currentcat'] = 'no';
733 if ($this->getSelectedCategory()) {
734 if ($this->getSelectedCategory() == $data['catid']) {
735 $data['catiscurrent'] = 'yes';
736 $data['currentcat'] = 'yes';
739 $data['catiscurrent'] = 'no';
740 $data['currentcat'] = 'no';
745 if (intval($itemid) && $manager->existsItem(intval($itemid),0,0)) {
746 $iobj =& $manager->getItem(intval($itemid),0,0);
747 $cid = $iobj['catid'];
748 if ($cid == $data['catid']) {
749 $data['catiscurrent'] = 'yes';
750 $data['currentcat'] = 'yes';
753 $data['catiscurrent'] = 'no';
754 $data['currentcat'] = 'no';
760 'PreCategoryListItem',
766 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
767 //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
768 //echo strftime($temp, $current->itime);
772 sql_free_result($res);
774 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
776 'blogid' => $this->getID(),
777 'blogurl' => $blogurl,
778 'self' => $CONF['Self'],
779 //: Change: Set catiscurrent template variable for footer
780 'catiscurrent' => $nocatselected,
781 'currentcat' => $nocatselected
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'];
860 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
864 sql_free_result($res);
866 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
868 'sitename' => $CONF['SiteName'],
869 'siteurl' => $CONF['IndexURL']
875 * Read the blog settings
877 function readSettings() {
879 . ' FROM '.sql_table('blog')
880 . ' WHERE bnumber=' . $this->blogid;
881 $res = sql_query($query);
883 $this->isValid = (sql_num_rows($res) > 0);
887 $this->settings = sql_fetch_assoc($res);
891 * Write the blog settings
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());
924 * Update the update file if requested
926 function updateUpdatefile() {
927 if ($this->getUpdateFile()) {
928 $f_update = fopen($this->getUpdateFile(),'w');
929 fputs($f_update,$this->getCorrectTime());
936 * Check if a category with a given catid is valid
941 function isValidCategory($catid) {
942 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
943 $res = sql_query($query);
944 return (sql_num_rows($res) != 0);
948 * Get the category name for a given catid
953 function getCategoryName($catid) {
954 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
955 $o = sql_fetch_object($res);
960 * Get the category description for a given catid
965 function getCategoryDesc($catid) {
966 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
967 $o = sql_fetch_object($res);
972 * Get the category id for a given category name
977 function getCategoryIdFromName($name) {
978 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . sql_real_escape_string($name) . '"');
979 if (sql_num_rows($res) > 0) {
980 $o = sql_fetch_object($res);
983 return $this->getDefaultCategory();
988 * Get the the setting for the line break handling
989 * [should be named as getConvertBreaks()]
991 function convertBreaks() {
992 return $this->getSetting('bconvertbreaks');
996 * Set the the setting for the line break handling
999 * new value for bconvertbreaks
1001 function setConvertBreaks($val) {
1002 $this->setSetting('bconvertbreaks',$val);
1006 * Insert a javascript that includes information about the settings
1007 * of an author: ConvertBreaks, MediaUrl and AuthorId
1012 function insertJavaScriptInfo($authorid = '') {
1013 global $member, $CONF;
1015 if ($authorid == '')
1016 $authorid = $member->getID();
1019 <script type="text/javascript">
1020 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
1021 setMediaUrl("<?php echo $CONF['MediaURL']?>");
1022 setAuthorId(<?php echo $authorid?>);
1027 * Set the the setting for allowing to publish postings in the past
1030 * new value for ballowpast
1032 function setAllowPastPosting($val) {
1033 $this->setSetting('ballowpast',$val);
1037 * Get the the setting if it is allowed to publish postings in the past
1038 * [should be named as getAllowPastPosting()]
1040 function allowPastPosting() {
1041 return $this->getSetting('ballowpast');
1044 function getCorrectTime($t=0) {
1045 if ($t == 0) $t = time();
1046 return ($t + 3600 * $this->getTimeOffset());
1049 function getName() {
1050 return $this->getSetting('bname');
1053 function getShortName() {
1054 return $this->getSetting('bshortname');
1057 function getMaxComments() {
1058 return $this->getSetting('bmaxcomments');
1061 function getNotifyAddress() {
1062 return $this->getSetting('bnotify');
1065 function getNotifyType() {
1066 return $this->getSetting('bnotifytype');
1069 function notifyOnComment() {
1070 $n = $this->getNotifyType();
1071 return (($n != 0) && (($n % 3) == 0));
1074 function notifyOnVote() {
1075 $n = $this->getNotifyType();
1076 return (($n != 0) && (($n % 5) == 0));
1079 function notifyOnNewItem() {
1080 $n = $this->getNotifyType();
1081 return (($n != 0) && (($n % 7) == 0));
1084 function setNotifyType($val) {
1085 $this->setSetting('bnotifytype',$val);
1089 function getTimeOffset() {
1090 return $this->getSetting('btimeoffset');
1093 function commentsEnabled() {
1094 return $this->getSetting('bcomments');
1098 return $this->getSetting('burl');
1101 function getDefaultSkin() {
1102 return $this->getSetting('bdefskin');
1105 function getUpdateFile() {
1106 return $this->getSetting('bupdate');
1109 function getDescription() {
1110 return $this->getSetting('bdesc');
1113 function isPublic() {
1114 return $this->getSetting('bpublic');
1117 function emailRequired() {
1118 return $this->getSetting('breqemail');
1121 function getSearchable() {
1122 return $this->getSetting('bincludesearch');
1125 function getDefaultCategory() {
1126 return $this->getSetting('bdefcat');
1129 function setPublic($val) {
1130 $this->setSetting('bpublic',$val);
1133 function setSearchable($val) {
1134 $this->setSetting('bincludesearch',$val);
1137 function setDescription($val) {
1138 $this->setSetting('bdesc',$val);
1141 function setUpdateFile($val) {
1142 $this->setSetting('bupdate',$val);
1145 function setDefaultSkin($val) {
1146 $this->setSetting('bdefskin',$val);
1149 function setURL($val) {
1150 $this->setSetting('burl',$val);
1153 function setName($val) {
1154 $this->setSetting('bname',$val);
1157 function setShortName($val) {
1158 $this->setSetting('bshortname',$val);
1161 function setCommentsEnabled($val) {
1162 $this->setSetting('bcomments',$val);
1165 function setMaxComments($val) {
1166 $this->setSetting('bmaxcomments',$val);
1169 function setNotifyAddress($val) {
1170 $this->setSetting('bnotify',$val);
1173 function setEmailRequired($val) {
1174 $this->setSetting('breqemail',$val);
1177 function setTimeOffset($val) {
1178 // check validity of value
1179 // 1. replace , by . (common mistake)
1180 $val = str_replace(',','.',$val);
1181 // 2. cast to float or int
1182 if (is_numeric($val) && strstr($val,'.5')) {
1183 $val = (float) $val;
1185 $val = intval($val);
1188 $this->setSetting('btimeoffset',$val);
1191 function setDefaultCategory($val) {
1192 $this->setSetting('bdefcat',$val);
1195 function getSetting($key) {
1196 return $this->settings[$key];
1199 function setSetting($key,$value) {
1200 $this->settings[$key] = $value;
1204 * Tries to add a member to the team.
1205 * Returns false if the member was already on the team
1207 function addTeamMember($memberid, $admin) {
1210 $memberid = intval($memberid);
1211 $admin = intval($admin);
1213 // check if member is already a member
1214 $tmem = MEMBER::createFromID($memberid);
1216 if ($tmem->isTeamMember($this->getID()))
1229 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1230 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1234 'PostAddTeamMember',
1243 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1244 ACTIONLOG::add(INFO, $logMsg);
1250 return intval($this->blogid);
1254 * Checks if a blog with a given shortname exists
1255 * Returns true if there is a blog with the given shortname (static)
1260 function exists($name) {
1261 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.sql_real_escape_string($name).'"');
1262 return (sql_num_rows($r) != 0);
1266 * Checks if a blog with a given id exists
1267 * Returns true if there is a blog with the given ID (static)
1272 function existsID($id) {
1273 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1274 return (sql_num_rows($r) != 0);
1278 * flag there is a future post pending
1280 function setFuturePost() {
1281 $query = 'UPDATE '.sql_table('blog')
1282 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1287 * clear there is a future post pending
1289 function clearFuturePost() {
1290 $query = 'UPDATE '.sql_table('blog')
1291 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1296 * check if we should throw justPosted event
1298 function checkJustPosted() {
1301 if ($this->settings['bfuturepost'] == 1) {
1302 $blogid = $this->getID();
1303 $result = sql_query("SELECT * FROM " . sql_table('item')
1304 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1305 if (sql_num_rows($result) > 0) {
1306 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1307 // Note that the plugins's calling order is subject to thri order in the plugin list
1311 array('blogid' => $blogid,
1312 'pinged' => &$pinged
1316 // clear all expired future posts
1317 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1319 // check to see any pending future post, clear the flag is none
1320 $result = sql_query("SELECT * FROM " . sql_table('item')
1321 . " WHERE iposted=0 AND iblog=" . $blogid);
1322 if (sql_num_rows($result) == 0) {
1323 $this->clearFuturePost();
1330 * Shows the given list of items for this blog
1333 * array of item numbers to be displayed
1335 * String representing the template _NAME_ (!)
1337 * contains a query that should be highlighted
1339 * 1=show comments 0=don't show comments
1341 * 1=show dateheads 0=don't show dateheads
1342 * @param $showDrafts
1343 * 0=do not show drafts 1=show drafts
1344 * @param $showFuture
1345 * 0=do not show future posts 1=show future posts
1347 * amount of items shown
1349 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1,$showDrafts = 0, $showFuture = 0) {
1351 $query = $this->getSqlItemList($itemarray,$showDrafts,$showFuture);
1353 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1357 * Returns the SQL query used to fill out templates for a list of items
1360 * an array holding the item numbers of the items to be displayed
1361 * @param $showDrafts
1362 * 0=do not show drafts 1=show drafts
1363 * @param $showFuture
1364 * 0=do not show future posts 1=show future posts
1366 * either a full SQL query, or an empty string
1368 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1370 function getSqlItemList($itemarray,$showDrafts = 0,$showFuture = 0)
1372 if (!is_array($itemarray)) return '';
1373 $showDrafts = intval($showDrafts);
1374 $showFuture = intval($showFuture);
1376 foreach ($itemarray as $value) {
1377 if (intval($value)) $items[] = intval($value);
1379 if (!count($items)) return '';
1380 //$itemlist = implode(',',$items);
1383 foreach ($items as $value) {
1386 . ' i.inumber as itemid,'
1387 . ' i.ititle as title,'
1388 . ' i.ibody as body,'
1389 . ' m.mname as author,'
1390 . ' m.mrealname as authorname,'
1392 . ' i.imore as more,'
1393 . ' m.mnumber as authorid,'
1394 . ' m.memail as authormail,'
1395 . ' m.murl as authorurl,'
1396 . ' c.cname as category,'
1397 . ' i.icat as catid,'
1398 . ' i.iclosed as closed';
1401 . sql_table('item') . ' as i, '
1402 . sql_table('member') . ' as m, '
1403 . sql_table('category') . ' as c'
1405 . ' i.iblog='.$this->blogid
1406 . ' and i.iauthor=m.mnumber'
1407 . ' and i.icat=c.catid';
1408 if (!$showDrafts) $query .= ' and i.idraft=0'; // exclude drafts
1409 if (!$showFuture) $query .= ' and i.itime<=' . mysqldate($this->getCorrectTime()); // don't show future items
1411 //$query .= ' and i.inumber IN ('.$itemlist.')';
1412 $query .= ' and i.inumber='.intval($value);
1415 if ($i) $query .= ' UNION ';