/** * Create "What's Related" links for a story * Creates an HTML-formatted list of links to be used for the What's Related * block next to a story (in article view). * * @param string $related contents of gl_stories 'related' field * @param int $uid user id of the author * @param int $sid story id * @return string HTML-formatted list of links */ function STORY_whatsRelated($related, $uid, $sid) { global $_CONF, $_TABLES, $LANG24; // Is it enabled? // Disabled' => 0, 'Enabled' => 1, 'Enabled (No Links)' => 2, 'Enabled (No Outbound Links)' => 3 if ($_CONF['whats_related']) { // get the links from the story text if ($_CONF['whats_related'] != 2) { if (!empty($related)) { $rel = explode("\n", $related); } else { $rel = array(); } // Used to hunt out duplicates. Stores urls that have already passed filters $urls = array(); foreach ($rel as $key => &$value) { if (preg_match("/<a[^>]*href=[\"']([^\"']*)[\"'][^>]*>(.*?)<\\/a>/i", $value, $matches) === 1) { // Go through array and remove links with no link text except link. Since a max of only 23 characters of link text showen then compare only this if (substr($matches[1], 0, 23) != substr($matches[2], 0, 23)) { // Check if outbound links (if needed) $passd_check = false; if ($_CONF['whats_related'] == 3) { // no outbound links if ($_CONF['site_url'] == substr($matches[1], 0, strlen($_CONF['site_url']))) { $passd_check = true; } } else { $passd_check = true; } if ($passd_check) { // Go through array and remove any duplicates of this link if (in_array($matches[1], $urls)) { // remove it from the array unset($rel[$key]); } else { $urls[] = $matches[1]; // Now Check Words $value = '<a href="' . $matches[1] . '">' . COM_checkWords($matches[2], 'story') . '</a>'; } } else { // remove it from the array unset($rel[$key]); } } else { // remove it from the array unset($rel[$key]); } } else { $value = COM_checkWords($value, 'story'); } } } $topics = array(); if (!COM_isAnonUser() || $_CONF['loginrequired'] == 0 && $_CONF['searchloginrequired'] == 0) { // add a link to "search by author" if ($_CONF['contributedbyline'] == 1) { $author = $LANG24[37] . ' ' . COM_getDisplayName($uid); if ($_CONF['whats_related_trim'] > 0 && MBYTE_strlen($author) > $_CONF['whats_related_trim']) { $author = substr($author, 0, $_CONF['whats_related_trim'] - 3) . '...'; } $topics[] = "<a href=\"{$_CONF['site_url']}/search.php?mode=search&type=stories&author={$uid}\">{$author}</a>"; } // Retrieve topics $tids = TOPIC_getTopicIdsForObject('article', $sid, 0); foreach ($tids as $tid) { // add a link to "search by topic" $topic = $LANG24[38] . ' ' . stripslashes(DB_getItem($_TABLES['topics'], 'topic', "tid = '{$tid}'")); // trim topics if needed if ($_CONF['whats_related_trim'] > 0 && MBYTE_strlen($topic) > $_CONF['whats_related_trim']) { $topic = substr($topic, 0, $_CONF['whats_related_trim'] - 3) . '...'; } $topics[] = '<a href="' . $_CONF['site_url'] . '/search.php?mode=search&type=stories&topic=' . $tid . '">' . $topic . '</a>'; } } // If line limit then split between related links and topics if ($_CONF['whats_related_max'] > 0) { if ($_CONF['whats_related_max'] < 3) { $rel = array(); // Reset related links so at least user search and default topic search is displayed $topics = array_slice($topics, 0, 2); } else { $rel_max_num_items = intval($_CONF['whats_related_max'] / 2); $topic_max_num_items = $rel_max_num_items; if ($rel_max_num_items + $topic_max_num_items != $_CONF['whats_related_max']) { $topic_max_num_items = $topic_max_num_items + 1; } // Now check if we have enough topics to display else give it to links $topic_num_items = count($topics); $rel_num_items = count($rel); $added_flag = false; if ($topic_num_items < $topic_max_num_items) { $rel_max_num_items = $rel_max_num_items + ($topic_max_num_items - $topic_num_items); $added_flag = true; } if (!$added_flag && $rel_num_items < $rel_max_num_items) { $topic_max_num_items = $topic_max_num_items + ($rel_max_num_items - $rel_num_items); } $rel = array_slice($rel, 0, $rel_max_num_items); $topics = array_slice($topics, 0, $topic_max_num_items); } } $result = array_merge($rel, $topics); $related = ''; if (count($result) > 0) { $related = COM_makeList($result, 'list-whats-related'); } } else { $related = ''; } return $related; }
/** * Get an existing static page * * @param array args Contains all the data provided by the client * @param string &output OUTPUT parameter containing the returned text * @param string &svc_msg OUTPUT parameter containing any service messages * @return int Response code as defined in lib-plugins.php */ function service_get_staticpages($args, &$output, &$svc_msg) { global $_CONF, $_TABLES, $LANG_ACCESS, $LANG12, $LANG_STATIC, $_SP_CONF, $topic; $output = ''; $svc_msg['output_fields'] = array('sp_hits', 'sp_format', 'draft_flag', 'cache_time', 'owner_id', 'group_id', 'perm_owner', 'perm_group', 'perm_members', 'perm_anon', 'sp_help', 'sp_php', 'sp_inblock', 'commentcode'); if (empty($args['sp_id']) && !empty($args['id'])) { $args['sp_id'] = $args['id']; } if ($args['gl_svc']) { if (isset($args['sp_id'])) { $args['sp_id'] = COM_applyBasicFilter($args['sp_id']); } if (isset($args['mode'])) { $args['mode'] = COM_applyBasicFilter($args['mode']); } if (empty($args['sp_id'])) { $svc_msg['gl_feed'] = true; } else { $svc_msg['gl_feed'] = false; } } else { $svc_msg['gl_feed'] = false; } if (!$svc_msg['gl_feed']) { $page = ''; if (isset($args['sp_id'])) { $page = $args['sp_id']; } $mode = ''; if (isset($args['mode'])) { $mode = $args['mode']; } $error = 0; if ($page == '') { $error = 1; } $perms = SP_getPerms(); if (!SEC_hasRights('staticpages.edit')) { if (!empty($perms)) { $perms .= ' AND'; } $perms .= '(draft_flag = 0)'; } if (!empty($perms)) { $perms = ' AND ' . $perms; } // Topic Permissions $topic_perms = COM_getTopicSQL('', 0, 'ta'); if ($topic_perms != "") { $topic_perms = " AND (" . $topic_perms . ""; if (COM_onFrontpage()) { $topic_perms .= " OR (ta.tid = '" . TOPIC_HOMEONLY_OPTION . "' OR ta.tid = '" . TOPIC_ALL_OPTION . "'))"; } else { // $topic_perms .= " OR ta.tid = '" . TOPIC_ALL_OPTION . "')"; $topic_perms .= " OR (ta.tid = '" . TOPIC_HOMEONLY_OPTION . "' OR ta.tid = '" . TOPIC_ALL_OPTION . "'))"; } } $topic_perms .= " GROUP BY sp_id"; $sql = array(); $sql['mysql'] = "SELECT sp_id,sp_title,sp_page_title,sp_content,sp_hits,created,modified,sp_format," . "commentcode,meta_description,meta_keywords,template_flag,template_id,draft_flag," . "owner_id,group_id,perm_owner,perm_group," . "perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time " . "FROM {$_TABLES['staticpage']}, {$_TABLES['topic_assignments']} ta " . "WHERE (sp_id = '{$page}')" . $perms . " AND ta.type = 'staticpages' AND ta.id = sp_id " . $topic_perms; $sql['pgsql'] = "SELECT sp_id,sp_title,sp_page_title,sp_content,sp_hits," . "created,modified,sp_format," . "commentcode,meta_description,meta_keywords,template_flag,template_id,draft_flag," . "owner_id,group_id,perm_owner,perm_group," . "perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time " . "sp_inblock FROM {$_TABLES['staticpage']}, {$_TABLES['topic_assignments']} ta " . "WHERE (sp_id = '{$page}')" . $perms . " AND ta.type = 'staticpages' AND ta.id = sp_id " . $topic_perms; $result = DB_query($sql); $count = DB_numRows($result); if ($count == 0 || $count > 1) { $error = 1; } if (!$error) { $output = DB_fetchArray($result, false); $page = $output['sp_id']; // reset page id so case mimics id perfectly since this affects the cache file and canonical link // WE ASSUME $output doesn't have any confidential fields // Generate output now (omly if not grabing a template since template is combined with variables first and then generated) if (!isset($args['template'])) { $output['sp_content'] = SP_render_content($page, $output['sp_content'], $output['sp_php'], $output['cache_time'], $output['template_id']); } } else { // an error occured (page not found, access denied, ...) /** * if the user has edit permissions and the page does not exist, * send them to the editor so they can create it "wiki style" */ $create_page = false; if ($mode !== 'autotag' && $count == 0 && SEC_hasRights('staticpages.edit')) { // check again without permissions if (DB_count($_TABLES['staticpage'], 'sp_id', $page) == 0) { $url = $_CONF['site_admin_url'] . '/plugins/staticpages/index.php?mode=edit&sp_new_id=' . $page . '&msg=21'; $output = COM_refresh($url); $create_page = true; } } if (!$create_page) { if (empty($page)) { $failflg = 0; } else { $failflg = DB_getItem($_TABLES['staticpage'], 'sp_nf', "sp_id = '{$page}'"); } if ($failflg) { $output .= SEC_loginRequiredForm(); if ($mode !== 'autotag') { $output = COM_createHTMLDocument($output, array('rightblock' => true)); } } else { if ($mode !== 'autotag') { COM_handle404(); } } } return PLG_RET_ERROR; } if ($args['gl_svc']) { // This date format is PHP 5 only, // but only the web-service uses the value $output['published'] = date('c', strtotime($output['created'])); $output['updated'] = date('c', strtotime($output['modified'])); $output['id'] = $page; $output['title'] = $output['sp_title']; $output['page_title'] = $output['sp_page_title']; $output['category'] = TOPIC_getTopicIdsForObject('staticpages', $page); $output['content'] = $output['sp_content']; $output['content_type'] = 'html'; $owner_data = SESS_getUserDataFromId($output['owner_id']); $output['author_name'] = $owner_data['username']; $output['link_edit'] = $page; } } else { $output = array(); $mode = ''; if (isset($args['mode'])) { $mode = $args['mode']; } $perms = SP_getPerms(); if (!empty($perms)) { $perms = ' WHERE ' . $perms; } $offset = 0; if (isset($args['offset'])) { $offset = COM_applyBasicFilter($args['offset'], true); } $max_items = $_SP_CONF['atom_max_items'] + 1; $limit = " LIMIT {$offset}, {$max_items}"; $order = " ORDER BY modified DESC"; $sql = array(); $sql['mysql'] = "SELECT sp_id,sp_title,sp_page_title,sp_content,sp_hits,created,modified,sp_format,meta_description,meta_keywords,template_flag,template_id,draft_flag,owner_id," . "group_id,perm_owner,perm_group,perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time " . " FROM {$_TABLES['staticpage']}" . $perms . $order . $limit; $sql['pgsql'] = "SELECT sp_id,sp_title,sp_page_title,sp_content,sp_hits,created,modified,sp_format,meta_description,meta_keywords,template_flag,template_id,draft_flag,owner_id," . "group_id,perm_owner,perm_group,perm_members,perm_anon,sp_help,sp_php,sp_inblock,cache_time " . "FROM {$_TABLES['staticpage']}" . $perms . $order . $limit; $result = DB_query($sql); $count = 0; while (($output_item = DB_fetchArray($result, false)) !== false) { // WE ASSUME $output doesn't have any confidential fields $count++; if ($count == $max_items) { $svc_msg['offset'] = $offset + $_SP_CONF['atom_max_items']; break; } if ($args['gl_svc']) { // This date format is PHP 5 only, but only the web-service uses the value $output_item['published'] = date('c', strtotime($output_item['created'])); $output_item['updated'] = date('c', strtotime($output_item['modified'])); $output_item['id'] = $output_item['sp_id']; $output_item['title'] = $output_item['sp_title']; $output_item['page_title'] = $output_item['sp_page_title']; //$output_item['category'] = array($output_item['sp_tid']); $output_item['category'] = TOPIC_getTopicIdsForObject('staticpages', $page); //$output_item['content'] = $output_item['sp_content']; $output['content'] = SP_render_content($output['sp_id'], $output['sp_content'], $output['sp_php'], $output['cache_time'], $output['template_id']); $output_item['content_type'] = 'html'; $owner_data = SESS_getUserDataFromId($output_item['owner_id']); $output_item['author_name'] = $owner_data['username']; } $output[] = $output_item; } } return PLG_RET_OK; }
/** * used for the list of stories in admin/story.php * * @param string $fieldName * @param string $fieldValue * @param array $A * @param array $icon_arr * @return string */ function ADMIN_getListField_stories($fieldName, $fieldValue, $A, $icon_arr) { global $_CONF, $_TABLES, $LANG24, $LANG_ACCESS, $_IMAGE_TYPE; static $topics; if (!isset($topics)) { $topics = array(); } $retval = ''; switch ($fieldName) { case 'unixdate': $currentTime = COM_getUserDateTimeFormat($A['unixdate']); $retval = strftime($_CONF['daytime'], $currentTime[1]); break; case 'title': $A['title'] = str_replace('$', '$', $A['title']); $article_url = COM_buildURL($_CONF['site_url'] . '/article.php?story=' . $A['sid']); $attr = array(); if (!empty($A['page_title'])) { $attr['title'] = htmlspecialchars($A['page_title']); } $retval = COM_createLink(stripslashes($A['title']), $article_url, $attr); break; case 'draft_flag': if ($A['draft_flag'] == 1) { $retval = $LANG24[35]; } else { $retval = $LANG24[36]; } break; case 'access': case 'copy': case 'edit': case 'edit_adv': $access = SEC_hasAccess($A['owner_id'], $A['group_id'], $A['perm_owner'], $A['perm_group'], $A['perm_members'], $A['perm_anon']); if ($access == 3) { if (TOPIC_hasMultiTopicAccess('article', $A['sid']) == 3) { $access = $LANG_ACCESS['edit']; } else { $access = $LANG_ACCESS['readonly']; } } else { $access = $LANG_ACCESS['readonly']; } if ($fieldName === 'access') { $retval = $access; } elseif ($access === $LANG_ACCESS['edit']) { if ($fieldName == 'edit_adv') { $editMode = 'adv'; } elseif ($fieldName === 'edit') { $editMode = 'std'; } if ($fieldName === 'copy') { $copyUrl = $_CONF['site_admin_url'] . '/story.php?mode=clone&sid=' . $A['sid']; $retval = COM_createLink($icon_arr['copy'], $copyUrl); } else { $editUrl = $_CONF['site_admin_url'] . '/story.php?mode=edit&editor=' . $editMode . '&sid=' . $A['sid']; $retval = COM_createLink($icon_arr['edit'], $editUrl); } } break; case 'featured': if ($A['featured'] == 1) { $retval = $LANG24[35]; } else { $retval = $LANG24[36]; } break; case 'ping': // Allow ping if all topics allow anonymous access that story belongs too $topic_anon = 0; $tids = TOPIC_getTopicIdsForObject('article', $A['sid']); foreach ($tids as $tid) { $current_access = DB_getItem($_TABLES['topics'], 'perm_anon', "tid = '" . DB_escapeString($tid) . "'"); if ($topic_anon < $current_access) { $topic_anon = $current_access; } } if ($A['draft_flag'] == 0 && $A['unixdate'] < time() && $A['perm_anon'] != 0 && $topic_anon != 0) { $pingico = '<img src="' . $_CONF['layout_url'] . '/images/sendping.' . $_IMAGE_TYPE . '" alt="' . $LANG24[21] . '" title="' . $LANG24[21] . '"' . XHTML . '>'; $url = $_CONF['site_admin_url'] . '/trackback.php?mode=sendall&id=' . $A['sid']; $retval = COM_createLink($pingico, $url); } else { $retval = ''; } break; case 'tid': $retval = TOPIC_getTopicAdminColumn('article', $A['sid']); break; case 'username': case 'fullname': $retval = COM_getDisplayName($A['uid'], $A['username'], $A['fullname']); break; default: $retval = $fieldValue; break; } return $retval; }
/** * Saves the story in it's final state to the database. * Handles all the SID magic etc. * * @return int status result from a constant list. */ public function saveToDatabase() { global $_TABLES, $_DB_dbms; $tids = TOPIC_getTopicIdsForObject('topic'); $archive_tid = DB_getItem($_TABLES['topics'], 'tid', 'archive_flag=1'); if (!empty($tids) && !empty($archive_tid)) { if (in_array($archive_tid, $tids)) { $this->_featured = 0; $this->_frontpage = 0; $this->_statuscode = STORY_ARCHIVE_ON_EXPIRE; } } /* if a featured, non-draft, that goes live straight away, unfeature * other stories in same topic: */ if ($this->_featured == '1') { // there can only be one non-draft featured story if ($this->_draft_flag == 0 and $this->_date <= time()) { if ($this->_frontpage == 1) { // un-feature any featured frontpage story DB_query("UPDATE {$_TABLES['stories']} SET featured = 0 WHERE featured = 1 AND draft_flag = 0 AND frontpage = 1 AND date <= NOW()"); } // un-feature any featured story in the same topic //DB_query("UPDATE {$_TABLES['stories']} SET featured = 0 WHERE featured = 1 AND draft_flag = 0 AND tid = '{$this->_tid}' AND date <= NOW()"); $tids = TOPIC_getTopicIdsForObject('topic'); if (!empty($tids)) { DB_query("UPDATE {$_TABLES['stories']} s, {$_TABLES['topic_assignments']} ta SET s.featured = 0 WHERE s.featured = 1 AND s.draft_flag = 0 AND (ta.tid IN ('" . implode("','", $tids) . "')) AND ta.type = 'article' AND ta.id = s.sid AND s.date <= NOW()"); } } } $oldArticleExists = false; $currentSidExists = false; // Fix up old sid => new sid stuff $checkSid = DB_escapeString($this->_originalSid); // needed below if ($this->_sid != $this->_originalSid) { /* The sid has changed. Load from request will have * ensured that if the new sid exists an error has * been thrown, but we need to know if the old sid * actually existed (as opposed to being a generated * sid that was then thrown away) to reduce the sheer * number of SQL queries we do. */ $newSid = DB_escapeString($this->_sid); $sql = "SELECT 1 FROM {$_TABLES['stories']} WHERE sid='{$checkSid}'"; $result = DB_query($sql); if ($result && DB_numRows($result) > 0) { $oldArticleExists = true; } if ($oldArticleExists) { // Move Comments $sql = "UPDATE {$_TABLES['comments']} SET sid='{$newSid}' WHERE type='article' AND sid='{$checkSid}'"; DB_query($sql); // Move Images $sql = "UPDATE {$_TABLES['article_images']} SET ai_sid = '{$newSid}' WHERE ai_sid = '{$checkSid}'"; DB_query($sql); // Move trackbacks $sql = "UPDATE {$_TABLES['trackback']} SET sid='{$newSid}' WHERE sid='{$checkSid}' AND type='article'"; DB_query($sql); } } // Acquire Comment Count $sql = "SELECT COUNT(1) FROM {$_TABLES['comments']} WHERE type='article' AND sid='{$this->_sid}'"; $result = DB_query($sql); if ($result && DB_numRows($result) == 1) { $array = DB_fetchArray($result); $this->_comments = $array[0]; } else { $this->_comments = 0; } /* Format dates for storage: */ /* * Doing this here would use the webserver's timezone, but we need * to use the DB server's timezone so that ye olde timezone hack * still works. See use of FROM_UNIXTIME in the SQL below. * * $this->_date = date('Y-m-d H:i:s', $this->_date); * $this->_expire = date('Y-m-d H:i:s', $this->_expire); * */ // Get the related URLs $this->_related = implode("\n", STORY_extractLinks($this->DisplayElements('introtext') . ' ' . $this->DisplayElements('bodytext'))); $fields = ''; $values = ''; reset($this->_dbFields); $this->_text_version = GLTEXT_LATEST_VERSION; // Apply HTML filter to the text just before save // with the permissions of current editor $this->_introtext = GLText::applyHTMLFilter($this->_introtext, $this->_postmode, 'story.edit', $this->_text_version); $this->_bodytext = GLText::applyHTMLFilter($this->_bodytext, $this->_postmode, 'story.edit', $this->_text_version); /* This uses the database field array to generate a SQL Statement. This * means that when adding new fields to save and load, all we need to do * is add the field name to the array, and the code will magically cope. */ while (list($fieldName, $save) = each($this->_dbFields)) { if ($save === 1) { $varName = '_' . $fieldName; $fields .= $fieldName . ', '; if ($fieldName === 'date' || $fieldName === 'expire' || $fieldName === 'comment_expire') { // let the DB server do this conversion (cf. timezone hack) $values .= 'FROM_UNIXTIME(' . $this->{$varName} . '), '; } else { if ($this->{$varName} === '') { $values .= "'', "; } else { if (is_numeric($this->{$varName})) { $values .= DB_escapeString($this->{$varName}) . ', '; } else { $values .= '\'' . DB_escapeString($this->{$varName}) . '\', '; } } } } } $fields = substr($fields, 0, strlen($fields) - 2); $values = substr($values, 0, strlen($values) - 2); DB_save($_TABLES['stories'], $fields, $values); // Save Topics selected TOPIC_saveTopicSelectionControl('article', $this->_sid); if ($oldArticleExists) { // Clean up the old story DB_delete($_TABLES['stories'], 'sid', $checkSid); // Delete Topic Assignments for this old article id since we just created new ones TOPIC_deleteTopicAssignments('article', $checkSid); } if ($this->type === 'submission') { // there might be a submission, clean it up DB_delete($_TABLES['storysubmission'], 'sid', $checkSid); } return STORY_SAVED; }