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
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, $day=0) {
84 // create extra where clause for select query
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
89 $timestamp_start = mktime(0,0,0,$month,$day,$year);
90 $timestamp_end = mktime(0,0,0,$month,$day+1,$year);
92 $extra_query = ' and i.itime>=' . mysqldate($timestamp_start)
93 . ' and i.itime<' . mysqldate($timestamp_end);
96 $this->readLogAmount($templatename,0,$extra_query,'',1,1);
101 // sets/gets current category (only when category exists)
102 function setSelectedCategory($catid) {
103 if ($this->isValidCategory($catid) || (intval($catid) == 0))
104 $this->selectedcatid = intval($catid);
107 function setSelectedCategoryByName($catname) {
108 $this->setSelectedCategory($this->getCategoryIdFromName($catname));
111 function getSelectedCategory() {
112 return $this->selectedcatid;
116 * Shows the given amount of items for this blog
119 * String representing the template _NAME_ (!)
120 * @param $amountEntries
121 * amount of entries to show (0 = no limit)
123 * extra conditions to be added to the query
125 * contains a query that should be highlighted
127 * 1=show comments 0=don't show comments
129 * 1=show dateheads 0=don't show dateheads
133 * amount of items shown
135 function readLogAmount($template, $amountEntries, $extraQuery, $highlight, $comments, $dateheads, $offset = 0, $startpos = 0) {
137 $query = $this->getSqlBlog($extraQuery);
139 if ($amountEntries > 0) {
140 // $offset zou moeten worden:
141 // (($startpos / $amountentries) + 1) * $offset ... later testen ...
142 $query .= ' LIMIT ' . intval($startpos + $offset).',' . intval($amountEntries);
144 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
147 function showUsingQuery($templateName, $query, $highlight = '', $comments = 0, $dateheads = 1) {
148 global $CONF, $manager;
150 $lastVisit = cookieVar($CONF['CookiePrefix'] .'lastVisit');
152 $lastVisit = $this->getCorrectTime($lastVisit);
154 // set templatename as global variable (so plugins can access it)
155 global $currentTemplateName;
156 $currentTemplateName = $templateName;
158 $template =& $manager->getTemplate($templateName);
160 // create parser object & action handler
161 $actions =& new ITEMACTIONS($this);
162 $parser =& new PARSER($actions->getDefinedActions(),$actions);
163 $actions->setTemplate($template);
164 $actions->setHighlight($highlight);
165 $actions->setLastVisit($lastVisit);
166 $actions->setParser($parser);
167 $actions->setShowComments($comments);
170 $items = sql_query($query);
172 // loop over all items
174 while ($item = mysql_fetch_object($items)) {
176 $item->timestamp = strtotime($item->itime); // string timestamp -> unix timestamp
178 // action handler needs to know the item we're handling
179 $actions->setCurrentItem($item);
181 // add date header if needed
183 $new_date = date('dFY',$item->timestamp);
184 if ($new_date != $old_date) {
185 // unless this is the first time, write date footer
186 $timestamp = $item->timestamp;
187 if ($old_date != 0) {
188 $oldTS = strtotime($old_date);
189 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
190 $tmp_footer = strftime(isset($template['DATE_FOOTER'])?$template['DATE_FOOTER']:'', $oldTS);
191 $parser->parse($tmp_footer);
192 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => $oldTS));
194 $manager->notify('PreDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
195 // note, to use templatvars in the dateheader, the %-characters need to be doubled in
196 // order to be preserved by strftime
197 $tmp_header = strftime((isset($template['DATE_HEADER']) ? $template['DATE_HEADER'] : null), $timestamp);
198 $parser->parse($tmp_header);
199 $manager->notify('PostDateHead',array('blog' => &$this, 'timestamp' => $timestamp));
201 $old_date = $new_date;
205 $parser->parse($template['ITEM_HEADER']);
206 $manager->notify('PreItem', array('blog' => &$this, 'item' => &$item));
207 $parser->parse($template['ITEM']);
208 $manager->notify('PostItem', array('blog' => &$this, 'item' => &$item));
209 $parser->parse($template['ITEM_FOOTER']);
213 $numrows = mysql_num_rows($items);
215 // add another date footer if there was at least one item
216 if (($numrows > 0) && $dateheads) {
217 $manager->notify('PreDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
218 $parser->parse($template['DATE_FOOTER']);
219 $manager->notify('PostDateFoot',array('blog' => &$this, 'timestamp' => strtotime($old_date)));
222 mysql_free_result($items); // free memory
228 function showOneitem($itemid, $template, $highlight) {
229 $extraQuery = ' and inumber=' . intval($itemid);
231 return $this->readLogAmount($template, 1, $extraQuery, $highlight, 0, 0);
236 * Adds an item to this blog
238 function additem($catid, $title, $body, $more, $blogid, $authorid, $timestamp, $closed, $draft, $posted='1') {
241 $blogid = intval($blogid);
242 $authorid = intval($authorid);
246 $catid = intval($catid);
248 // convert newlines to <br />
249 if ($this->convertBreaks()) {
250 $body = addBreaks($body);
251 $more = addBreaks($more);
254 if ($closed != '1') $closed = '0';
255 if ($draft != '0') $draft = '1';
257 if (!$this->isValidCategory($catid))
258 $catid = $this->getDefaultCategory();
260 if ($timestamp > $this->getCorrectTime())
263 $timestamp = date('Y-m-d H:i:s',$timestamp);
265 $manager->notify('PreAddItem',array('title' => &$title, 'body' => &$body, 'more' => &$more, 'blog' => &$this, 'authorid' => &$authorid, 'timestamp' => &$timestamp, 'closed' => &$closed, 'draft' => &$draft, 'catid' => &$catid));
267 $title = addslashes($title);
268 $body = addslashes($body);
269 $more = addslashes($more);
271 $query = 'INSERT INTO '.sql_table('item').' (ITITLE, IBODY, IMORE, IBLOG, IAUTHOR, ITIME, ICLOSED, IDRAFT, ICAT, IPOSTED) '
272 . "VALUES ('$title', '$body', '$more', $blogid, $authorid, '$timestamp', $closed, $draft, $catid, $posted)";
274 $itemid = mysql_insert_id();
276 $manager->notify('PostAddItem',array('itemid' => $itemid));
279 $this->updateUpdateFile();
281 // send notification mail
282 if (!$draft && !$isFuture && $this->getNotifyAddress() && $this->notifyOnNewItem())
283 $this->sendNewItemNotification($itemid, stripslashes($title), stripslashes($body));
288 function sendNewItemNotification($itemid, $title, $body) {
289 global $CONF, $member;
291 // create text version of html post
292 $ascii = toAscii($body);
294 $mailto_msg = _NOTIFY_NI_MSG . " \n";
295 // $mailto_msg .= $CONF['IndexURL'] . 'index.php?itemid=' . $itemid . "\n\n";
296 $temp = parse_url($CONF['Self']);
297 if ($temp['scheme']) {
298 $mailto_msg .= createItemLink($itemid) . "\n\n";
300 $tempurl = $this->getURL();
301 if (substr($tempurl, -1) == '/' || substr($tempurl, -4) == '.php') {
302 $mailto_msg .= $tempurl . '?itemid=' . $itemid . "\n\n";
304 $mailto_msg .= $tempurl . '/?itemid=' . $itemid . "\n\n";
307 $mailto_msg .= _NOTIFY_TITLE . ' ' . strip_tags($title) . "\n";
308 $mailto_msg .= _NOTIFY_CONTENTS . "\n " . $ascii . "\n";
309 $mailto_msg .= getMailFooter();
311 $mailto_title = $this->getName() . ': ' . _NOTIFY_NI_TITLE;
313 $frommail = $member->getNotifyFromMailAddress();
315 $notify =& new NOTIFICATION($this->getNotifyAddress());
316 $notify->notify($mailto_title, $mailto_msg , $frommail);
324 * Creates a new category for this blog
327 * name of the new category. When empty, a name is generated automatically
328 * (starting with newcat)
329 * @param $catDescription
330 * description of the new category. Defaults to 'New Category'
333 * the new category-id in case of success.
336 function createNewCategory($catName = '', $catDescription = _CREATED_NEW_CATEGORY_DESC) {
337 global $member, $manager;
339 if ($member->blogAdminRights($this->getID())) {
343 $catName = _CREATED_NEW_CATEGORY_NAME;
346 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
347 while (mysql_num_rows($res) > 0)
350 $res = sql_query('SELECT * FROM '.sql_table('category')." WHERE cname='".$catName.$i."' and cblog=".$this->getID());
353 $catName = $catName . $i;
361 'description' => $catDescription
365 $query = 'INSERT INTO '.sql_table('category').' (cblog, cname, cdesc) VALUES (' . $this->getID() . ", '" . addslashes($catName) . "', '" . addslashes($catDescription) . "')";
367 $catid = mysql_insert_id();
374 'description' => $catDescription,
388 * Searches all months of this blog for the given query
393 * template to be used (__NAME__ of the template)
394 * @param $amountMonths
395 * max amount of months to be search (0 = all)
397 * max number of results to show
401 * amount of hits found
403 function search($query, $template, $amountMonths, $maxresults, $startpos) {
404 global $CONF, $manager;
407 $sqlquery = $this->getSqlSearch($query, $amountMonths, $highlight);
411 // no query -> show everything
413 $amountfound = $this->readLogAmount($template, $maxresults, $extraQuery, $query, 1, 1);
416 // add LIMIT to query (to split search results into pages)
417 if (intval($maxresults > 0))
418 $sqlquery .= ' LIMIT ' . intval($startpos).',' . intval($maxresults);
421 $amountfound = $this->showUsingQuery($template, $sqlquery, $highlight, 1, 1);
423 // when no results were found, show a message
424 if ($amountfound == 0)
426 $template =& $manager->getTemplate($template);
428 'query' => htmlspecialchars($query),
429 'blogid' => $this->getID()
431 echo TEMPLATE::fill($template['SEARCH_NOTHINGFOUND'],$vars);
439 * Returns an SQL query to use for a search query
443 * @param $amountMonths
444 * amount of months to search back. Default = 0 = unlimited
446 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
447 * @returns $highlight
448 * words to highlight (out parameter)
450 * either a full SQL query, or an empty string (if querystring empty)
452 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
454 function getSqlSearch($query, $amountMonths = 0, &$highlight, $mode = '')
456 $searchclass =& new SEARCH($query);
458 $highlight = $searchclass->inclusive;
460 // if querystring is empty, return empty string
461 if ($searchclass->inclusive == '')
465 $where = $searchclass->boolean_sql_where('ititle,ibody,imore');
466 $select = $searchclass->boolean_sql_select('ititle,ibody,imore');
468 // get list of blogs to search
469 $blogs = $searchclass->blogs; // array containing blogs that always need to be included
470 $blogs[] = $this->getID(); // also search current blog (duh)
471 $blogs = array_unique($blogs); // remove duplicates
473 if (count($blogs) > 0)
474 $selectblogs = ' and i.iblog in (' . implode(',', $blogs) . ')';
478 $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';
480 $query .= ', '.$select. ' as score ';
482 $query = 'SELECT COUNT(*) as result ';
485 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
486 . ' WHERE i.iauthor=m.mnumber'
487 . ' and i.icat=c.catid'
488 . ' and i.idraft=0' // exclude drafts
490 // don't show future items
491 . ' and i.itime<=' . mysqldate($this->getCorrectTime())
494 // take into account amount of months to search
495 if ($amountMonths > 0)
497 $localtime = getdate($this->getCorrectTime());
498 $timestamp_start = mktime(0,0,0,$localtime['mon'] - $amountMonths,1,$localtime['year']);
499 $query .= ' and i.itime>' . mysqldate($timestamp_start);
505 $query .= ' ORDER BY score DESC';
507 $query .= ' ORDER BY i.itime DESC ';
514 * Returns the SQL query that's normally used to display the blog items on the index type skins
517 * either empty, or 'count'. In this case, the query will be a SELECT COUNT(*) query
519 * either a full SQL query, or an empty string
521 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
523 function getSqlBlog($extraQuery, $mode = '')
526 $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';
528 $query = 'SELECT COUNT(*) as result ';
530 $query .= ' FROM '.sql_table('item').' as i, '.sql_table('member').' as m, '.sql_table('category').' as c'
531 . ' WHERE i.iblog='.$this->blogid
532 . ' and i.iauthor=m.mnumber'
533 . ' and i.icat=c.catid'
534 . ' and i.idraft=0' // exclude drafts
535 // don't show future items
536 . ' and i.itime<=' . mysqldate($this->getCorrectTime());
538 if ($this->getSelectedCategory())
539 $query .= ' and i.icat=' . $this->getSelectedCategory() . ' ';
542 $query .= $extraQuery;
545 $query .= ' ORDER BY i.itime DESC';
551 * Shows the archivelist using the given template
553 function showArchiveList($template, $mode = 'month', $limit = 0) {
554 global $CONF, $catid, $manager;
556 if (!isset ($linkparams)) {
557 $linkparams = array();
561 $linkparams = array('catid' => $catid);
564 $template =& $manager->getTemplate($template);
565 $data['blogid'] = $this->getID();
567 echo TEMPLATE::fill($template['ARCHIVELIST_HEADER'],$data);
569 $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')
570 . ' WHERE iblog=' . $this->getID()
571 . ' and itime <=' . mysqldate($this->getCorrectTime()) // don't show future items!
572 . ' and idraft=0'; // don't show draft items
575 $query .= ' and icat=' . intval($catid);
577 $query .= ' GROUP BY Year, Month';
582 $query .= ' ORDER BY itime DESC';
585 $query .= ' LIMIT ' . intval($limit);
587 $res = sql_query($query);
589 while ($current = mysql_fetch_object($res)) {
590 $current->itime = strtotime($current->itime); // string time -> unix timestamp
592 if ($mode == 'day') {
593 $archivedate = date('Y-m-d',$current->itime);
594 $archive['day'] = date('d',$current->itime);
595 $data['day'] = date('d',$current->itime);
597 $archivedate = date('Y-m',$current->itime);
599 $data['month'] = date('m',$current->itime);
600 $data['year'] = date('Y',$current->itime);
601 $data['archivelink'] = createArchiveLink($this->getID(),$archivedate,$linkparams);
604 'PreArchiveListItem',
610 $temp = TEMPLATE::fill($template['ARCHIVELIST_LISTITEM'],$data);
611 echo strftime($temp,$current->itime);
615 mysql_free_result($res);
617 echo TEMPLATE::fill($template['ARCHIVELIST_FOOTER'],$data);
622 * Shows the list of categories using a given template
624 function showCategoryList($template) {
625 global $CONF, $manager;
627 // determine arguments next to catids
628 // I guess this can be done in a better way, but it works
629 global $archive, $archivelist;
631 $linkparams = array();
633 $blogurl = createArchiveLink($this->getID(), $archive, '');
634 $linkparams['blogid'] = $this->getID();
635 $linkparams['archive'] = $archive;
636 } else if ($archivelist) {
637 $blogurl = createArchiveListLink($this->getID(), '');
638 $linkparams['archivelist'] = $archivelist;
640 $blogurl = createBlogidLink($this->getID(), '');
641 $linkparams['blogid'] = $this->getID();
644 //$blogurl = $this->getURL() . $qargs;
645 //$blogurl = createBlogLink($this->getURL(), $linkparams);
647 $template =& $manager->getTemplate($template);
649 echo TEMPLATE::fill((isset($template['CATLIST_HEADER']) ? $template['CATLIST_HEADER'] : null),
651 'blogid' => $this->getID(),
652 'blogurl' => $blogurl,
653 'self' => $CONF['Self']
656 $query = 'SELECT catid, cdesc as catdesc, cname as catname FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' ORDER BY cname ASC';
657 $res = sql_query($query);
660 while ($data = mysql_fetch_assoc($res)) {
661 $data['blogid'] = $this->getID();
662 $data['blogurl'] = $blogurl;
663 $data['catlink'] = createLink(
666 'catid' => $data['catid'],
667 'name' => $data['catname'],
668 'extra' => $linkparams
671 $data['self'] = $CONF['Self'];
674 'PreCategoryListItem',
680 echo TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
681 //$temp = TEMPLATE::fill((isset($template['CATLIST_LISTITEM']) ? $template['CATLIST_LISTITEM'] : null), $data);
682 //echo strftime($temp, $current->itime);
686 mysql_free_result($res);
688 echo TEMPLATE::fill((isset($template['CATLIST_FOOTER']) ? $template['CATLIST_FOOTER'] : null),
690 'blogid' => $this->getID(),
691 'blogurl' => $blogurl,
692 'self' => $CONF['Self']
697 * Shows a list of all blogs in the system using a given template
698 * ordered by number, name, shortname or description
699 * in ascending or descending order
701 function showBlogList($template, $bnametype, $orderby, $direction) {
702 global $CONF, $manager;
712 $orderby='bshortname';
722 $direction=strtolower($direction);
723 switch ($direction) {
735 $template =& $manager->getTemplate($template);
737 echo TEMPLATE::fill((isset($template['BLOGLIST_HEADER']) ? $template['BLOGLIST_HEADER'] : null),
739 'sitename' => $CONF['SiteName'],
740 'siteurl' => $CONF['IndexURL']
743 $query = 'SELECT bnumber, bname, bshortname, bdesc, burl FROM '.sql_table('blog').' ORDER BY '.$orderby.' '.$direction;
744 $res = sql_query($query);
746 while ($data = mysql_fetch_assoc($res)) {
750 // $list['bloglink'] = createLink('blog', array('blogid' => $data['bnumber']));
751 $list['bloglink'] = createBlogidLink($data['bnumber']);
753 $list['blogdesc'] = $data['bdesc'];
755 $list['blogurl'] = $data['burl'];
757 if ($bnametype=='shortname') {
758 $list['blogname'] = $data['bshortname'];
760 else { // all other cases
761 $list['blogname'] = $data['bname'];
771 echo TEMPLATE::fill((isset($template['BLOGLIST_LISTITEM']) ? $template['BLOGLIST_LISTITEM'] : null), $list);
775 mysql_free_result($res);
777 echo TEMPLATE::fill((isset($template['BLOGLIST_FOOTER']) ? $template['BLOGLIST_FOOTER'] : null),
779 'sitename' => $CONF['SiteName'],
780 'siteurl' => $CONF['IndexURL']
786 * Blogsettings functions
789 function readSettings() {
791 . ' FROM '.sql_table('blog')
792 . ' WHERE bnumber=' . $this->blogid;
793 $res = sql_query($query);
795 $this->isValid = (mysql_num_rows($res) > 0);
799 $this->settings = mysql_fetch_assoc($res);
802 function writeSettings() {
804 // (can't use floatval since not available prior to PHP 4.2)
805 $offset = $this->getTimeOffset();
806 if (!is_float($offset))
807 $offset = intval($offset);
809 $query = 'UPDATE '.sql_table('blog')
810 . " SET bname='" . addslashes($this->getName()) . "',"
811 . " bshortname='". addslashes($this->getShortName()) . "',"
812 . " bcomments=". intval($this->commentsEnabled()) . ","
813 . " bmaxcomments=" . intval($this->getMaxComments()) . ","
814 . " btimeoffset=" . $offset . ","
815 . " bpublic=" . intval($this->isPublic()) . ","
816 . " breqemail=" . intval($this->emailRequired()) . ","
817 . " bsendping=" . intval($this->sendPing()) . ","
818 . " bconvertbreaks=" . intval($this->convertBreaks()) . ","
819 . " ballowpast=" . intval($this->allowPastPosting()) . ","
820 . " bnotify='" . addslashes($this->getNotifyAddress()) . "',"
821 . " bnotifytype=" . intval($this->getNotifyType()) . ","
822 . " burl='" . addslashes($this->getURL()) . "',"
823 . " bupdate='" . addslashes($this->getUpdateFile()) . "',"
824 . " bdesc='" . addslashes($this->getDescription()) . "',"
825 . " bdefcat=" . intval($this->getDefaultCategory()) . ","
826 . " bdefskin=" . intval($this->getDefaultSkin()) . ","
827 . " bincludesearch=" . intval($this->getSearchable())
828 . " WHERE bnumber=" . intval($this->getID());
835 // update update file if requested
836 function updateUpdatefile() {
837 if ($this->getUpdateFile()) {
838 $f_update = fopen($this->getUpdateFile(),'w');
839 fputs($f_update,$this->getCorrectTime());
845 function isValidCategory($catid) {
846 $query = 'SELECT * FROM '.sql_table('category').' WHERE cblog=' . $this->getID() . ' and catid=' . intval($catid);
847 $res = sql_query($query);
848 return (mysql_num_rows($res) != 0);
851 function getCategoryName($catid) {
852 $res = sql_query('SELECT cname FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
853 $o = mysql_fetch_object($res);
857 function getCategoryDesc($catid) {
858 $res = sql_query('SELECT cdesc FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and catid=' . intval($catid));
859 $o = mysql_fetch_object($res);
863 function getCategoryIdFromName($name) {
864 $res = sql_query('SELECT catid FROM '.sql_table('category').' WHERE cblog='.$this->getID().' and cname="' . addslashes($name) . '"');
865 if (mysql_num_rows($res) > 0) {
866 $o = mysql_fetch_object($res);
869 return $this->getDefaultCategory();
873 function sendPing() {
874 return $this->getSetting('bsendping');
877 function setPingUserland($val) {
878 $this->setSetting('bsendping',$val);
881 function convertBreaks() {
882 return $this->getSetting('bconvertbreaks');
885 function insertJavaScriptInfo($authorid = '') {
886 global $member, $CONF;
889 $authorid = $member->getID();
892 <script type="text/javascript">
893 setConvertBreaks(<?php echo $this->convertBreaks() ? 'true' : 'false' ?>);
894 setMediaUrl("<?php echo $CONF['MediaURL']?>");
895 setAuthorId(<?php echo $authorid?>);
898 function setConvertBreaks($val) {
899 $this->setSetting('bconvertbreaks',$val);
901 function setAllowPastPosting($val) {
902 $this->setSetting('ballowpast',$val);
904 function allowPastPosting() {
905 return $this->getSetting('ballowpast');
908 function getCorrectTime($t=0) {
909 if ($t == 0) $t = time();
910 return ($t + 3600 * $this->getTimeOffset());
914 return $this->getSetting('bname');
917 function getShortName() {
918 return $this->getSetting('bshortname');
921 function getMaxComments() {
922 return $this->getSetting('bmaxcomments');
925 function getNotifyAddress() {
926 return $this->getSetting('bnotify');
929 function getNotifyType() {
930 return $this->getSetting('bnotifytype');
933 function notifyOnComment() {
934 $n = $this->getNotifyType();
935 return (($n != 0) && (($n % 3) == 0));
938 function notifyOnVote() {
939 $n = $this->getNotifyType();
940 return (($n != 0) && (($n % 5) == 0));
943 function notifyOnNewItem() {
944 $n = $this->getNotifyType();
945 return (($n != 0) && (($n % 7) == 0));
948 function setNotifyType($val) {
949 $this->setSetting('bnotifytype',$val);
953 function getTimeOffset() {
954 return $this->getSetting('btimeoffset');
957 function commentsEnabled() {
958 return $this->getSetting('bcomments');
962 return $this->getSetting('burl');
965 function getDefaultSkin() {
966 return $this->getSetting('bdefskin');
969 function getUpdateFile() {
970 return $this->getSetting('bupdate');
973 function getDescription() {
974 return $this->getSetting('bdesc');
977 function isPublic() {
978 return $this->getSetting('bpublic');
981 function emailRequired() {
982 return $this->getSetting('breqemail');
985 function getSearchable() {
986 return $this->getSetting('bincludesearch');
989 function getDefaultCategory() {
990 return $this->getSetting('bdefcat');
993 function setPublic($val) {
994 $this->setSetting('bpublic',$val);
997 function setSearchable($val) {
998 $this->setSetting('bincludesearch',$val);
1001 function setDescription($val) {
1002 $this->setSetting('bdesc',$val);
1005 function setUpdateFile($val) {
1006 $this->setSetting('bupdate',$val);
1009 function setDefaultSkin($val) {
1010 $this->setSetting('bdefskin',$val);
1013 function setURL($val) {
1014 $this->setSetting('burl',$val);
1017 function setName($val) {
1018 $this->setSetting('bname',$val);
1021 function setShortName($val) {
1022 $this->setSetting('bshortname',$val);
1025 function setCommentsEnabled($val) {
1026 $this->setSetting('bcomments',$val);
1029 function setMaxComments($val) {
1030 $this->setSetting('bmaxcomments',$val);
1033 function setNotifyAddress($val) {
1034 $this->setSetting('bnotify',$val);
1037 function setEmailRequired($val) {
1038 $this->setSetting('breqemail',$val);
1041 function setTimeOffset($val) {
1042 // check validity of value
1043 // 1. replace , by . (common mistake)
1044 $val = str_replace(',','.',$val);
1045 // 2. cast to float or int
1046 if (is_numeric($val) && strstr($val,'.5')) {
1047 $val = (float) $val;
1049 $val = intval($val);
1052 $this->setSetting('btimeoffset',$val);
1055 function setDefaultCategory($val) {
1056 $this->setSetting('bdefcat',$val);
1059 function getSetting($key) {
1060 return $this->settings[$key];
1063 function setSetting($key,$value) {
1064 $this->settings[$key] = $value;
1068 // tries to add a member to the team. Returns false if the member was already on
1070 function addTeamMember($memberid, $admin) {
1073 $memberid = intval($memberid);
1074 $admin = intval($admin);
1076 // check if member is already a member
1077 $tmem = MEMBER::createFromID($memberid);
1079 if ($tmem->isTeamMember($this->getID()))
1092 $query = 'INSERT INTO '.sql_table('team').' (TMEMBER, TBLOG, TADMIN) '
1093 . 'VALUES (' . $memberid .', '.$this->getID().', "'.$admin.'")';
1097 'PostAddTeamMember',
1106 $logMsg = sprintf(_TEAM_ADD_NEWTEAMMEMBER, $tmem->getDisplayName(), $memberid, $this->getName());
1107 ACTIONLOG::add(INFO, $logMsg);
1113 return intVal($this->blogid);
1116 // returns true if there is a blog with the given shortname (static)
1117 function exists($name) {
1118 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bshortname="'.addslashes($name).'"');
1119 return (mysql_num_rows($r) != 0);
1122 // returns true if there is a blog with the given ID (static)
1123 function existsID($id) {
1124 $r = sql_query('select * FROM '.sql_table('blog').' WHERE bnumber='.intval($id));
1125 return (mysql_num_rows($r) != 0);
1128 // flag there is a future post pending
1129 function setFuturePost() {
1130 $query = 'UPDATE '.sql_table('blog')
1131 . " SET bfuturepost='1' WHERE bnumber=" . $this->getID();
1135 // clear there is a future post pending
1136 function clearFuturePost() {
1137 $query = 'UPDATE '.sql_table('blog')
1138 . " SET bfuturepost='0' WHERE bnumber=" . $this->getID();
1142 // check if we should throw justPosted event
1143 function checkJustPosted() {
1146 if ($this->settings['bfuturepost'] == 1) {
1147 $blogid = $this->getID();
1148 $result = sql_query("SELECT * FROM " . sql_table('item')
1149 . " WHERE iposted=0 AND iblog=" . $blogid . " AND itime<NOW()");
1150 if (mysql_num_rows($result) > 0) {
1151 // This $pinged is allow a plugin to tell other hook to the event that a ping is sent already
1152 // Note that the plugins's calling order is subject to thri order in the plugin list
1156 array('blogid' => $blogid,
1157 'pinged' => &$pinged
1161 // clear all expired future posts
1162 sql_query("UPDATE " . sql_table('item') . " SET iposted='1' WHERE iblog=" . $blogid . " AND itime<NOW()");
1164 // check to see any pending future post, clear the flag is none
1165 $result = sql_query("SELECT * FROM " . sql_table('item')
1166 . " WHERE iposted=0 AND iblog=" . $blogid);
1167 if (mysql_num_rows($result) == 0) {
1168 $this->clearFuturePost();
1175 * Shows the given list of items for this blog
1178 * array of item numbers to be displayed
1180 * String representing the template _NAME_ (!)
1182 * contains a query that should be highlighted
1184 * 1=show comments 0=don't show comments
1186 * 1=show dateheads 0=don't show dateheads
1188 * amount of items shown
1190 function readLogFromList($itemarray, $template, $highlight = '', $comments = 1, $dateheads = 1) {
1192 $query = $this->getSqlItemList($itemarray);
1194 return $this->showUsingQuery($template, $query, $highlight, $comments, $dateheads);
1198 * Returns the SQL query used to fill out templates for a list of items
1201 * an array holding the item numbers of the items to be displayed
1203 * either a full SQL query, or an empty string
1205 * No LIMIT clause is added. (caller should add this if multiple pages are requested)
1207 function getSqlItemList($itemarray)
1209 if (!is_array($itemarray)) return '';
1211 foreach ($itemarray as $value) {
1212 if (intval($value)) $items[] = intval($value);
1214 if (!count($items)) return '';
1215 //$itemlist = implode(',',$items);
1218 foreach ($items as $value) {
1221 . ' i.inumber as itemid,'
1222 . ' i.ititle as title,'
1223 . ' i.ibody as body,'
1224 . ' m.mname as author,'
1225 . ' m.mrealname as authorname,'
1227 . ' i.imore as more,'
1228 . ' m.mnumber as authorid,'
1229 . ' m.memail as authormail,'
1230 . ' m.murl as authorurl,'
1231 . ' c.cname as category,'
1232 . ' i.icat as catid,'
1233 . ' i.iclosed as closed';
1236 . sql_table('item') . ' as i, '
1237 . sql_table('member') . ' as m, '
1238 . sql_table('category').' as c'
1240 . ' i.iblog = ' . $this->blogid
1241 . ' and i.iauthor = m.mnumber'
1242 . ' and i.icat = c.catid'
1243 . ' and i.idraft = 0' // exclude drafts
1244 // don't show future items
1245 . ' and i.itime <= ' . mysqldate($this->getCorrectTime());
1247 //$query .= ' and i.inumber IN ('.$itemlist.')';
1248 $query .= ' and i.inumber = '.intval($value);
1251 if ($i) $query .= ' UNION ';