private function addComment($comment, $OpenIDFields = false) { if (!isset($comment['author']['openid']) || $comment['author']['openid'] == '') { $author = $comment['author']; $author['openid'] = ''; } else { $author = array('name' => $OpenIDFields['nickname'], 'email' => $OpenIDFields['email'], 'website' => $comment['author']['website']); $e = explode('http://', $comment['author']['openid']); $author['openid'] = end($e); if (preg_match('#(.*?)\\/$#s', $author['openid'])) { $author['openid'] = substr($author['openid'], 0, -1); } } if ($author['website'] == 'http://' || $author['website'] == '') { if (trim($comment['author']['openid']) == '') { $author['website'] = ''; } else { $author['website'] = trim($comment['author']['openid']); } } if ($result = !SQL::query("SELECT MAX([comment_number]) AS [max_number] FROM [blog_comments]p WHERE ([post_id] == " . (int) $comment['post_id'] . ")")) { $number = $result->fetchOne(); $number = (int) $number->max_number; } else { $number = 0; } if (!SQL::exec("\r\nINSERT INTO [blog_comments]p\r\n(\r\n[post_id],\r\n[comment_number],\r\n[comment_date],\r\n[comment_content],\r\n[comment_author_openid],\r\n[comment_author_name],\r\n[comment_author_email],\r\n[comment_author_website],\r\n[comment_author_user_agent],\r\n[comment_author_os]\r\n) VALUES (\r\n" . (int) $comment['post_id'] . ",\r\n" . $number . ",\r\n" . time() . ",\r\n'" . SQL::escape(trim($comment['content'])) . "',\r\n'" . SQL::escape(trim($author['openid'])) . "',\r\n'" . SQL::escape(trim($author['name'])) . "',\r\n'" . SQL::escape(strtolower(trim($author['email']))) . "',\r\n'" . SQL::escape(trim($author['website'])) . "',\r\n'" . SQL::escape($_SERVER['HTTP_USER_AGENT']) . "',\r\n'" . '' . "'\r\n)")) { throw new Exception('The comment could not be added.'); } $uri = SITE_ROOT_PATH . str_replace(array('%id', '%slug'), array($comment['post_id'], $comment['post_slug']), CFG_URL_BLOG_POST) . '#comments'; header('Location: ' . $uri); echo '<a href="' . $uri . '">' . $uri . '</a>'; }
/** * Adds tags to the database * * @param array|string tags to enter * @return array keys of the tags entered */ public function add($tags) { if (!is_array($tags) && !is_string($tags)) { trigger_error("Tags is of unvalid type!", E_USER_ERROR); } $tags = $this->clean($tags); $keys = array(); $existingTags = array(); $query = "SELECT id, tag FROM tags WHERE tag = '" . implode("' OR tag = '", $tags) . "'"; trigger_error($query, E_USER_NOTICE); $result = SQL::query($query); while ($tag = $result->fetch_object()) { $existingTags[] = $tag->tag; $keys[] = $tag->id; } $tagsToAdd = array_diff($tags, $existingTags); unset($existingTags); trigger_error("Object {$object} is getting linked with tag(s) '" . implode("', '", $tags) . "' whereof the tag(s): '" . implode("', '", $tagsToAdd) . "' are new to the database.", E_USER_NOTICE); foreach ($tagsToAdd as $tag) { if ($tag != "" && is_string($tag)) { $query = "INSERT INTO tags (id, tag)" . "VALUES ('', '" . SQL::escape($tag) . "')"; } trigger_error("Executing query: '{$query}'", E_USER_NOTICE); SQL::query($query); $keys[] = SQL::insertId(); } if (empty($keys)) { return false; } else { return $keys; } }
/** * cascade to children * * @param string referencing of the changed anchor * @param string rights to be cascaded (e.g., 'Y', 'R' or 'N') */ public static function cascade($reference, $active) { global $context; // only sections may have sub-sections if (strpos($reference, 'section:') === 0) { // cascade to sub-sections if ($items = Sections::list_for_anchor($reference, 'raw')) { // cascade to each section individually foreach ($items as $id => $item) { // limit actual rights $item['active'] = Anchors::ceil_rights($active, $item['active_set']); $query = "UPDATE " . SQL::table_name('sections') . " SET active='" . SQL::escape($item['active']) . "' WHERE id = " . SQL::escape($id); SQL::query($query); // cascade to children Anchors::cascade('section:' . $item['id'], $item['active']); } } } // only categories may have sub-categories if (strpos($reference, 'category:') === 0) { // cascade to sub-categories if ($items = Categories::list_for_anchor($reference, 'raw')) { // cascade to each section individually foreach ($items as $id => $item) { // limit actual rights $item['active'] = Anchors::ceil_rights($active, $item['active_set']); $query = "UPDATE " . SQL::table_name('categories') . " SET active='" . SQL::escape($item['active']) . "' WHERE id = " . SQL::escape($id); SQL::query($query); // cascade to children Anchors::cascade('category:' . $item['id'], $item['active']); } } } // only sections may have articles if (strpos($reference, 'section:') === 0) { // cascade to articles --up to 3000 if ($items =& Articles::list_for_anchor_by('edition', $reference, 0, 3000, 'raw')) { // cascade to each section individually foreach ($items as $id => $item) { // limit actual rights $item['active'] = Anchors::ceil_rights($active, $item['active_set']); $query = "UPDATE " . SQL::table_name('articles') . " SET active='" . SQL::escape($item['active']) . "' WHERE id = " . SQL::escape($id); SQL::query($query); // cascade to children Anchors::cascade('article:' . $item['id'], $item['active']); } } } // cascade to files --up to 3000 if ($items = Files::list_by_date_for_anchor($reference, 0, 3000, 'raw')) { // cascade to each section individually foreach ($items as $id => $item) { // limit actual rights $item['active'] = Anchors::ceil_rights($active, $item['active_set']); $query = "UPDATE " . SQL::table_name('files') . " SET active='" . SQL::escape($item['active']) . "' WHERE id = " . SQL::escape($id); SQL::query($query); } } }
/** * get some statistics for one anchor * * @param the selected anchor (e.g., 'section:12') * @return the resulting ($count, $min_date, $max_date) array */ public static function stat_for_anchor($anchor) { global $context; // sanity check if (!$anchor) { return NULL; } $anchor = SQL::escape($anchor); // select among available items $query = "SELECT COUNT(*) as count, MIN(edit_date) as oldest_date, MAX(edit_date) as newest_date" . " FROM " . SQL::table_name('versions') . " AS versions" . " WHERE (versions.anchor LIKE '" . SQL::escape($anchor) . "')"; $output = SQL::query_first($query); return $output; }
} // keywords have been found if ($keywords && (!isset($item['keywords']) || $item['keywords'] != $keywords)) { if (isset($item['keywords']) && $item['keywords']) { $context['text'] .= BR . '< ' . htmlspecialchars($item['keywords']) . BR . '> ' . $keywords . BR; } else { $context['text'] .= BR . 'k ' . $keywords . BR; } $item['keywords'] = $keywords; $ok = FALSE; } // the link is ok if ($ok) { $context['text'] .= '.'; } else { $query = "UPDATE " . SQL::table_name('referrals') . " SET" . " referer='" . SQL::escape($item['referer']) . "'," . " domain='" . SQL::escape($item['domain']) . "'," . " keywords='" . SQL::escape($item['keywords']) . "'" . " WHERE id = " . $item['id']; SQL::query($query); // update statistics $changes += 1; } } // we have processed one chunk $links_offset += SQL::count($result); $context['text'] .= BR . "\n"; // ensure enough execution time Safe::set_time_limit(30); // detect the end of the list if (SQL::count($result) < CHUNK_SIZE) { break; } // empty list
/** * defer the processing of one message * * This function either processes a message immediately, or it saves provided data in the * database for later processing. * * @param string the target address * @param string message subject * @param string message content * @param string optional headers * @return int the number of queued messages, or 0 on error */ private static function queue($recipient, $subject, $message, $headers = '') { global $context; // we don't have to rate messages if (!isset($context['mail_hourly_maximum']) || $context['mail_hourly_maximum'] < 1) { return Mailer::process($recipient, $subject, $message, $headers); } // transaction attributes $query = array(); $query[] = "edit_date='" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'"; $query[] = "headers='" . SQL::escape($headers) . "'"; $query[] = "message='" . SQL::escape($message) . "'"; $query[] = "recipient='" . SQL::escape($recipient) . "'"; $query[] = "subject='" . SQL::escape($subject) . "'"; // insert a new record $query = "INSERT INTO " . SQL::table_name('messages') . " SET " . implode(', ', $query); if (SQL::query($query) === FALSE) { return 0; } return 1; }
$inu[$index] = $is_unsigned; // next field $index++; } // remove last comma $field_list = rtrim($field_list, ', '); //parse out the table's data and generate the SQL INSERT statements in order to replicate the data itself... while ($row = SQL::fetch_row($result)) { $sql = 'INSERT INTO `' . $table_name . '` (' . $field_list . ') VALUES ('; for ($d = 0; $d < count($row); $d++) { if ($inu[$d] == TRUE) { $sql .= $row[$d]; } elseif ($ina[$d] == TRUE) { $sql .= intval($row[$d]); } else { $sql .= "'" . SQL::escape(strval($row[$d])) . "'"; } if ($d < count($row) - 1) { $sql .= ", "; } } $sql .= ");\n"; if ($compressed) { gzwrite($handle, $sql); } else { fwrite($handle, $sql); } // ensure we have enough time $queries++; if (!($queries % 100)) { Safe::set_time_limit(30);
/** * transcode some references * * @param array of pairs of strings to be used in preg_replace() * * @see images/images.php */ function transcode($transcoded) { global $context; // no item bound if (!isset($this->item['id'])) { return; } // prepare preg_replace() $from = array(); $to = array(); foreach ($transcoded as $pair) { $from[] = $pair[0]; $to[] = $pair[1]; } // transcode various fields $this->item['introduction'] = preg_replace($from, $to, $this->item['introduction']); $this->item['description'] = preg_replace($from, $to, $this->item['description']); // update the database $query = "UPDATE " . SQL::table_name('categories') . " SET " . " introduction = '" . SQL::escape($this->item['introduction']) . "'," . " description = '" . SQL::escape($this->item['description']) . "'" . " WHERE id = " . SQL::escape($this->item['id']); SQL::query($query); // always clear the cache, even on no update Categories::clear($this->item); }
/** * remember that surfer is enrolled in a meeting * * @param string reference of the target page */ public static function confirm($reference) { global $context; // sanity check if (!$reference) { return; } // ensure that the joiner has been enrolled... if (!($item = enrolments::get_record($reference))) { if (Surfer::get_id()) { // fields to save $query = array(); $query[] = "anchor = '" . $reference . "'"; $query[] = "approved = 'Y'"; $query[] = "edit_date = '" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'"; $query[] = "user_id = " . SQL::escape(Surfer::get_id()); $query[] = "user_email = '" . SQL::escape(Surfer::get_email_address()) . "'"; // insert a new record $query = "INSERT INTO " . SQL::table_name('enrolments') . " SET " . implode(', ', $query); SQL::query($query); } // each joiner takes one seat } else { $query = "UPDATE " . SQL::table_name('enrolments') . " SET approved = 'Y' WHERE id = " . SQL::escape($item['id']); SQL::query($query); } }
$context['text'] .= '<p><a href="../setup.php">' . i18n::s('Jump to the installation page') . "</a></p>\n"; // splash screen $context['text'] .= '<p>' . i18n::s('Else follow the link below to load the configuration form.') . "</p>\n"; // link to the configuration page $context['text'] .= '<p><a href="configure.php">' . i18n::s('Jump to the configuration page') . "</a></p>\n"; // no access to the database server yet } elseif (!isset($context['database']) || !$context['database'] || !isset($context['connection']) || !$context['connection']) { // title $context['page_title'] = i18n::s('No access to the database server'); // splash screen $context['text'] .= '<p>' . i18n::s('Impossible to access the database mentioned in your configuration file. Please create a database, or follow the link to change the configuration file.') . "</p>\n"; // link to the configuration page $context['text'] .= '<p><a href="configure.php">' . i18n::s('Jump to the configuration page') . "</a></p>\n"; } else { // try to create a database if it does not exist $query = "CREATE DATABASE IF NOT EXISTS " . SQL::escape($context['database']); SQL::query($query, TRUE, $context['connection']); // still no database if (!SQL::has_database($context['database'])) { // title $context['page_title'] = i18n::s('Please create a database'); // splash screen $context['text'] .= '<p>' . i18n::s('Impossible to access the database mentioned in your configuration file. Please create a database, or follow the link to change the configuration file.') . "</p>\n"; // link to the configuration page $context['text'] .= '<p><a href="configure.php">' . i18n::s('Go to the configuration page to change database parameters') . "</a></p>\n"; // no hooks found yet } elseif (!file_exists('../parameters/hooks.include.php')) { // title $context['page_title'] = i18n::s('Please configure software extensions'); // splash screen $context['text'] .= '<p>' . i18n::s('No configuration file for extensions has been found. If you are installing a brand new server, follow the link to create one.') . "</p>\n";
} if (isset($_REQUEST['without_internet_visibility'])) { $content .= '$context[\'without_internet_visibility\']=\'' . addcslashes($_REQUEST['without_internet_visibility'], "\\'") . "';\n"; } if (isset($_REQUEST['without_language_detection'])) { $content .= '$context[\'without_language_detection\']=\'' . addcslashes($_REQUEST['without_language_detection'], "\\'") . "';\n"; } if (isset($_REQUEST['without_outbound_http'])) { $content .= '$context[\'without_outbound_http\']=\'' . addcslashes($_REQUEST['without_outbound_http'], "\\'") . "';\n"; } if (isset($_REQUEST['static_subdom'])) { $content .= '$context[\'static_subdom\']=\'' . addcslashes($_REQUEST['static_subdom'], "\\'") . "';\n"; } $content .= '?>' . "\n"; // silently attempt to create the database if it does not exist $query = 'CREATE DATABASE IF NOT EXISTS ' . SQL::escape($_REQUEST['database']); SQL::query($query, TRUE); // alert the end user if we are not able to connect to the database if (!($handle = SQL::connect($_REQUEST['database_server'], $_REQUEST['database_user'], $_REQUEST['database_password'], $_REQUEST['database']))) { Logger::error(i18n::s('ERROR: Unsuccessful connection to the database. Please check lines below and <a href="configure.php">configure again</a>.')); // update the parameters file } elseif (!Safe::file_put_contents('parameters/control.include.php', $content)) { Logger::error(sprintf(i18n::s('ERROR: Impossible to write to the file %s. The configuration has not been saved.'), 'parameters/control.include.php')); // allow for a manual update $context['text'] .= '<p style="text-decoration: blink;">' . sprintf(i18n::s('To actually change the configuration, please copy and paste following lines by yourself in file %s.'), 'parameters/control.include.php') . "</p>\n"; // job done } else { $context['text'] .= '<p>' . sprintf(i18n::s('The following configuration has been saved into the file %s.'), 'parameters/control.include.php') . "</p>\n"; // first installation if (!file_exists('../parameters/switch.on') && !file_exists('../parameters/switch.off')) { $context['text'] .= '<p>' . i18n::s('Review provided information and go to the bottom of the page to move forward.') . "</a></p>\n";
$query .= "\n)"; // actual table creation SQL::query($query); // process every other line $queries = 0; $count = 0; while ($tokens = fgetcsv($handle, 2048, $delimiter, $enclosure)) { // insert one record at a time $query = "INSERT INTO " . SQL::escape($_REQUEST['table_name']) . " (" . $headers . ") VALUES ("; // use all provided tokens $index = 0; foreach ($tokens as $token) { if ($index++) { $query .= ', '; } $query .= "'" . SQL::escape($token) . "'"; } // finalize the statement $query .= ')'; // execute the statement if (!SQL::query($query, TRUE) && SQL::errno()) { $context['text'] .= '<p>' . $here . ': ' . $query . BR . SQL::error() . "</p>\n"; } $queries++; // ensure we have enough time if (!($queries % 50)) { Safe::set_time_limit(30); } } // clear the cache Cache::clear();
/** * remember an action once it's done * * This function saves data into the table [code]yacs_issues[/code]. * * @see overlays/overlay.php * * @param string the action 'insert', 'update' or 'delete' * @param array the hosting record * @param string reference of the hosting record (e.g., 'article:123') * @return FALSE on error, TRUE otherwise */ function remember($action, $host, $reference) { global $context; // locate anchor on 'insert' if ($reference) { $this->anchor = Anchors::get($reference); } // remember data from the anchor $this->attributes['anchor_reference'] = ''; $this->attributes['anchor_title'] = ''; $this->attributes['anchor_url'] = ''; if (is_callable(array($this->anchor, 'get_url'))) { $this->attributes['anchor_reference'] = $this->anchor->get_reference(); $this->attributes['anchor_title'] = $this->anchor->get_title(); $this->attributes['anchor_url'] = $this->anchor->get_url(); } // set default values for this editor Surfer::check_default_editor($this->attributes); // default date values if (!isset($this->attributes['create_date']) || $this->attributes['create_date'] <= NULL_DATE) { $this->attributes['create_date'] = $this->attributes['edit_date']; } if (!isset($this->attributes['qualification_date']) || $this->attributes['qualification_date'] <= NULL_DATE) { $this->attributes['qualification_date'] = NULL_DATE; } if (!isset($this->attributes['analysis_date']) || $this->attributes['analysis_date'] <= NULL_DATE) { $this->attributes['analysis_date'] = NULL_DATE; } if (!isset($this->attributes['resolution_date']) || $this->attributes['resolution_date'] <= NULL_DATE) { $this->attributes['resolution_date'] = NULL_DATE; } if (!isset($this->attributes['close_date']) || $this->attributes['close_date'] <= NULL_DATE) { $this->attributes['close_date'] = NULL_DATE; } // add a notification to the anchor page $comments = array(); // build the update query switch ($action) { case 'delete': $query = "DELETE FROM " . SQL::table_name('issues') . " WHERE anchor LIKE '" . $this->attributes['anchor_reference'] . "'"; break; case 'insert': $comments[] = i18n::s('Page has been created'); // set host owner, if any if (isset($this->attributes['owner']) && ($user = Users::get($this->attributes['owner'])) && $user['id'] != Surfer::get_id()) { $fields = array(); $fields['owner_id'] = $user['id']; $this->anchor->set_values($fields); Members::assign('user:'******'id'], $this->anchor->get_reference()); Members::assign($this->anchor->get_reference(), 'user:'******'id']); $comments[] = sprintf(i18n::s('Owner has been changed to %s'), Skin::build_link(Users::get_permalink($user), $user['full_name'])); } $query = "INSERT INTO " . SQL::table_name('issues') . " SET \n" . "anchor='" . SQL::escape($this->attributes['anchor_reference']) . "', \n" . "anchor_url='" . SQL::escape($this->attributes['anchor_url']) . "', \n" . "color='" . SQL::escape(isset($this->attributes['color']) ? $this->attributes['color'] : 'green') . "', \n" . "status='" . SQL::escape(isset($this->attributes['status']) ? $this->attributes['status'] : 'on-going:suspect') . "', \n" . "title='" . SQL::escape($this->attributes['anchor_title']) . "', \n" . "type='" . SQL::escape(isset($this->attributes['type']) ? $this->attributes['type'] : 'incident') . "', \n" . "create_name='" . SQL::escape(isset($this->attributes['create_name']) ? $this->attributes['create_name'] : $this->attributes['edit_name']) . "', \n" . "create_id=" . SQL::escape(isset($this->attributes['create_id']) ? $this->attributes['create_id'] : $this->attributes['edit_id']) . ", \n" . "create_address='" . SQL::escape(isset($this->attributes['create_address']) ? $this->attributes['create_address'] : $this->attributes['edit_address']) . "', \n" . "create_date='" . SQL::escape(isset($this->attributes['create_date']) ? $this->attributes['create_date'] : $this->attributes['edit_date']) . "', \n" . "edit_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "edit_id=" . SQL::escape($this->attributes['edit_id']) . ", \n" . "edit_address='" . SQL::escape($this->attributes['edit_address']) . "', \n" . "edit_action='create', \n" . "edit_date='" . SQL::escape($this->attributes['edit_date']) . "', \n" . "qualification_date='" . SQL::escape(isset($this->attributes['qualification_date']) ? $this->attributes['qualification_date'] : NULL_DATE) . "', \n" . "analysis_date='" . SQL::escape(isset($this->attributes['analysis_date']) ? $this->attributes['analysis_date'] : NULL_DATE) . "', \n" . "resolution_date='" . SQL::escape(isset($this->attributes['resolution_date']) ? $this->attributes['resolution_date'] : NULL_DATE) . "', \n" . "close_date='" . SQL::escape(isset($this->attributes['close_date']) ? $this->attributes['close_date'] : NULL_DATE) . "'"; break; case 'update': // only associates and page owners can update the record if (is_callable(array($this->anchor, 'is_owned')) && $this->anchor->is_owned()) { // detect type modification if ($this->attributes['type'] != $this->snapshot['type']) { $comments[] = sprintf(i18n::s('Workflow has been changed to "%s"'), $this->get_type_label($this->attributes['type'])); } // detect color modification if ($this->attributes['color'] != $this->snapshot['color']) { $comments[] = $this->get_color_label($this->attributes['color']); } // change host owner, if any if ($this->attributes['owner'] && ($user = Users::get($this->attributes['owner'])) && $user['id'] != $this->anchor->get_value('owner_id')) { $fields = array(); $fields['owner_id'] = $user['id']; $this->anchor->set_values($fields); Members::assign('user:'******'id'], $this->anchor->get_reference()); Members::assign($this->anchor->get_reference(), 'user:'******'id']); $comments[] = sprintf(i18n::s('Owner has been changed to %s'), Skin::build_link(Users::get_permalink($user), $user['full_name'])); } // update the table of issues $query = "UPDATE " . SQL::table_name('issues') . " SET \n" . "anchor='" . SQL::escape($this->attributes['anchor_reference']) . "', \n" . "anchor_url='" . SQL::escape($this->attributes['anchor_url']) . "', \n" . "color='" . SQL::escape($this->attributes['color']) . "', \n" . "status='" . SQL::escape($this->attributes['status']) . "', \n" . "title='" . SQL::escape($this->attributes['anchor_title']) . "', \n" . "type='" . SQL::escape($this->attributes['type']) . "', \n" . "create_date='" . SQL::escape(isset($this->attributes['create_date']) ? $this->attributes['create_date'] : $this->attributes['edit_date']) . "', \n" . "qualification_date='" . SQL::escape(isset($this->attributes['qualification_date']) ? $this->attributes['qualification_date'] : NULL_DATE) . "', \n" . "analysis_date='" . SQL::escape(isset($this->attributes['analysis_date']) ? $this->attributes['analysis_date'] : NULL_DATE) . "', \n" . "resolution_date='" . SQL::escape(isset($this->attributes['resolution_date']) ? $this->attributes['resolution_date'] : NULL_DATE) . "', \n" . "close_date='" . SQL::escape(isset($this->attributes['close_date']) ? $this->attributes['close_date'] : NULL_DATE) . "', \n"; // detect status modification if ($this->attributes['status'] != $this->snapshot['status']) { $comments[] = $this->get_status_label($this->attributes['status']); // depending of new status switch ($this->attributes['status']) { // case has been recorded --should not happen case 'on-going:suspect': $query .= "create_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "create_id=" . SQL::escape($this->attributes['edit_id']) . ", \n" . "create_address='" . SQL::escape($this->attributes['edit_address']) . "', \n"; break; // problem has been validated // problem has been validated case 'cancelled:suspect': case 'on-going:problem': $query .= "qualification_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "qualification_id='" . SQL::escape($this->attributes['edit_id']) . "', \n" . "qualification_address='" . SQL::escape($this->attributes['edit_address']) . "', \n"; break; // cause has been identified // cause has been identified case 'cancelled:problem': case 'on-going:issue': $query .= "analysis_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "analysis_id='" . SQL::escape($this->attributes['edit_id']) . "', \n" . "analysis_address='" . SQL::escape($this->attributes['edit_address']) . "', \n"; break; // solution has been achieved // solution has been achieved case 'cancelled:issue': case 'on-going:solution': $query .= "resolution_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "resolution_id='" . SQL::escape($this->attributes['edit_id']) . "', \n" . "resolution_address='" . SQL::escape($this->attributes['edit_address']) . "', \n"; break; // ending the issue // ending the issue case 'cancelled:solution': case 'completed:solution': $query .= "close_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "close_id='" . SQL::escape($this->attributes['edit_id']) . "', \n" . "close_address='" . SQL::escape($this->attributes['edit_address']) . "', \n"; break; } } // track the person who modifies the record $query .= "edit_name='" . SQL::escape($this->attributes['edit_name']) . "', \n" . "edit_id=" . SQL::escape($this->attributes['edit_id']) . ", \n" . "edit_address='" . SQL::escape($this->attributes['edit_address']) . "', \n" . "edit_action='update', \n" . "edit_date='" . SQL::escape($this->attributes['edit_date'] ? $this->attributes['edit_date'] : $this->attributes['edit_date']) . "' \n" . " WHERE anchor LIKE '" . SQL::escape($this->attributes['anchor_reference']) . "'"; } // ensure that this change has been recorded if (!$comments) { $comments[] = i18n::s('Page has been edited'); } break; } // execute the query --don't stop on error if (isset($query) && $query) { SQL::query($query); } // add a comment if ($comments && !$this->anchor->has_option('no_comments')) { include_once $context['path_to_root'] . 'comments/comments.php'; $fields = array(); $fields['anchor'] = $this->attributes['anchor_reference']; $fields['description'] = join(BR, $comments); $fields['type'] = 'notification'; Comments::post($fields); } // job done return TRUE; }
Safe::set_time_limit(30); } // fetch the member if ($row['member'] && !($item = Anchors::get($row['member']))) { // delete this entry $query = "DELETE FROM " . SQL::table_name('members') . " WHERE id = " . SQL::escape($row['id']); SQL::query($query); $context['text'] .= sprintf(i18n::s('Unknown member %s, record has been deleted'), $row['member']) . BR . "\n"; if (++$errors_count >= 50) { $context['text'] .= i18n::s('Too many successive errors. Aborted') . BR . "\n"; break; } // check that the anchor exists, if any } elseif ($row['anchor'] && !Anchors::get($row['anchor'])) { // delete this entry $query = "DELETE FROM " . SQL::table_name('members') . " WHERE id = " . SQL::escape($row['id']); SQL::query($query); $context['text'] .= sprintf(i18n::s('Unknown anchor %s, record has been deleted'), $row['anchor']) . BR . "\n"; if (++$errors_count >= 50) { $context['text'] .= i18n::s('Too many successive errors. Aborted') . BR . "\n"; break; } } else { $errors_count = 0; } } } // ending message $context['text'] .= sprintf(i18n::s('%d records have been processed'), $count) . BR . "\n"; // display the execution time $time = round(get_micro_time() - $context['start_time'], 2);
/** * start a phone call * * @param array e.g., array('user' => '123', 'number' => '33146411313') * @return mixed some error array with code and message, or the id of the on-going call */ function call($parameters) { global $context; // do we have some API key? if (!isset($context['obs_api_key'])) { return array('code' => -32000, 'message' => 'Missing credentials to use OBS API'); } // look for a user id if (empty($parameters['user'])) { return array('code' => -32602, 'message' => 'Invalid parameter "user"'); } // get the matching record if (!($user = Users::get($parameters['user']))) { return array('code' => -32602, 'message' => 'Unable to find this "user"'); } // get the related phone number if (!isset($user['phone_number'])) { return array('code' => -32602, 'message' => 'No phone number for this "user"'); } // look for an external number if (empty($parameters['number'])) { return array('code' => -32602, 'message' => 'Invalid parameter "number"'); } // data to be submitted to OBS $data = array(); $data[] = 'id=' . urlencode($context['obs_api_key']); $data[] = 'from=' . urlencode(ltrim($user['phone_number'], '0+')); $data[] = 'to=' . urlencode(ltrim($parameters['number'], '0+')); // build the endpoint to invoke $url = self::build_obs_link('call/createCall', $data); // do create the call if (!($response = http::proceed_natively($url))) { return array('code' => -32603, 'message' => 'Unable to query the OBS API'); } // ensure we receive correct xml if (!($xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA))) { return array('code' => -32603, 'message' => 'Invalid response from OBS API'); } if (!$xml->status->status_code) { return array('code' => -32603, 'message' => 'Invalid response from OBS API'); } // stop on error if ($xml->status->status_code != 200) { return array('code' => -32000, 'message' => 'Error: ' . $xml->status->status_code . ' ' . $xml->status->status_msg); } // look for call id if (!($id = $xml->call_info->call_id)) { return array('code' => -32603, 'message' => 'Invalid response from OBS API'); } // if surfer has been authenticated, save his phone number if ($user = Users::get(Surfer::get_id())) { // update session data $_SESSION['surfer_phone_number'] = $parameters['number']; // update surfer record too $query = "UPDATE " . SQL::table_name('users') . " SET phone_number='" . SQL::escape($parameters['number']) . "'" . " WHERE id = " . SQL::escape(Surfer::get_id()); SQL::query($query, FALSE, $context['users_connection']); } // provide id to caller, for subsequent actions on the call return array('call_id' => (string) $id); }
/** * get some statistics for one anchor * * @param the selected anchor (e.g., 'article:12') * @return the resulting ($count, $min_date, $max_date) array */ public static function stat_past_for_anchor($anchor) { global $context; // restrict the query to addressable content $where = Articles::get_sql_where(); // put only published pages in boxes if (isset($variant) && $variant == 'boxes') { $where .= " AND NOT ((articles.publish_date is NULL) OR (articles.publish_date <= '0000-00-00'))" . " AND (articles.publish_date < '" . $context['now'] . "')"; // provide published pages to anonymous surfers } elseif (!Surfer::is_logged()) { $where .= " AND NOT ((articles.publish_date is NULL) OR (articles.publish_date <= '0000-00-00'))" . " AND (articles.publish_date < '" . $context['now'] . "')"; // logged surfers that are non-associates are restricted to their own articles, plus published articles } elseif (!Surfer::is_empowered()) { $where .= " AND ((articles.create_id=" . Surfer::get_id() . ") OR (NOT ((articles.publish_date is NULL) OR (articles.publish_date <= '0000-00-00'))" . " AND (articles.publish_date < '" . $context['now'] . "')))"; } // now $match = gmstrftime('%Y-%m-%d %H:%M:%S'); // select among available items $query = "SELECT COUNT(*) as count, MIN(articles.edit_date) as oldest_date, MAX(articles.edit_date) as newest_date " . " FROM " . SQL::table_name('dates') . " as dates " . ", " . SQL::table_name('articles') . " AS articles" . " WHERE ((dates.anchor_type LIKE 'article') AND (dates.anchor_id = articles.id))" . "\tAND (dates.date_stamp < '" . SQL::escape($match) . "') AND\t(articles.anchor = '" . SQL::escape($anchor) . "') AND " . $where; $output = SQL::query_first($query); return $output; }
/** * pull most recent notification * * This script will wait for new updates before providing them to caller. * Because of potential time-outs, you have to care of retries. * * @return array attributes of the oldest notification, if any * * @see users/heartbit.php */ public static function pull() { global $context; // return by reference $output = NULL; // only authenticated surfers can be notified if (!Surfer::get_id()) { Safe::header('Status: 401 Unauthorized', TRUE, 401); die(i18n::s('You are not allowed to perform this operation.')); } // only consider recent records -- 180 = 3 minutes * 60 seconds $threshold = gmstrftime('%Y-%m-%d %H:%M:%S', time() - 180); // the query to get time of last update $query = "SELECT * FROM " . SQL::table_name('notifications') . " AS notifications " . " WHERE (notifications.recipient = " . SQL::escape(Surfer::get_id()) . ")" . "\tAND (edit_date >= '" . SQL::escape($threshold) . "')" . " ORDER BY notifications.edit_date" . " LIMIT 1"; // stop if there is nothing to return if (!($record = SQL::query_first($query)) || !isset($record['data'])) { return 'NTR'; } // restore the entire record $output = Safe::unserialize($record['data']); // localize on server-side message displayed by the client software $lines = array(); switch ($output['type']) { case 'alert': // a new item has been created if (strpos($output['action'], ':create')) { $lines[] = sprintf(i18n::s('New page: %s'), $output['title']) . "\n" . sprintf(i18n::s('%s by %s'), ucfirst(Anchors::get_action_label($output['action'])), $output['nick_name']) . "\n"; // surfer prompt $lines[] = i18n::s('Would you like to browse the page?'); // else consider this as an update } else { // provide a localized message $lines[] = sprintf(i18n::s('Updated: %s'), $output['title']) . "\n" . sprintf(i18n::s('%s by %s'), ucfirst(Anchors::get_action_label($output['action'])), $output['nick_name']) . "\n"; // surfer prompt $lines[] = i18n::s('Would you like to browse the page?'); } break; case 'browse': // message is optional if (isset($output['message']) && trim($output['message'])) { $lines[] = sprintf(i18n::s('From %s:'), $output['nick_name']) . "\n" . $output['message'] . "\n"; } // address is mandatory $lines[] = i18n::s('Would you like to browse the page?'); break; case 'hello': // message is optional if (isset($output['message']) && trim($output['message'])) { $lines[] = sprintf(i18n::s('From %s:'), $output['nick_name']) . "\n" . $output['message'] . "\n"; } // address is present on new chat if (isset($output['address']) && trim($output['address'])) { $lines[] = i18n::s('Would you like to browse the page?'); } break; } // content of the dialog box that will be displayed to surfer if (count($lines)) { $output['dialog_text'] = implode("\n", $lines); } // forget this notification $query = "DELETE FROM " . SQL::table_name('notifications') . " WHERE id = " . SQL::escape($record['id']); SQL::query($query, TRUE); // return the new notification return $output; }
public function getPost($slug) { if (!($result = SQL::query("\r\nSELECT\r\n\t[blog_posts]p.[post_id] AS [post_id],\r\n\t[blog_posts]p.[post_date] AS [post_date],\r\n\t[blog_posts]p.[post_header] AS [post_header],\r\n\t[blog_posts]p.[category_id] AS [category_id],\r\n\t[blog_categories]p.[category_slug] AS [category_slug],\r\n\t[blog_categories]p.[category_header] AS [category_header],\r\n\t[blog_posts_contents]p.[post_prologue] AS [post_prologue],\r\n\t[blog_posts_contents]p.[post_content] AS [post_content],\r\n\tcount([blog_comments]p.[comment_id]) AS [comments_count]\r\nFROM [blog_posts]p\r\nLEFT JOIN [blog_categories]p\r\n\tON [blog_posts]p.[category_id] == [blog_categories]p.[category_id]\r\nLEFT JOIN [blog_posts_contents]p\r\n\tON [blog_posts]p.[post_id] == [blog_posts_contents]p.[post_id]\r\nLEFT JOIN [blog_comments]p\r\n\tON [blog_posts]p.[post_id] == [blog_comments]p.[post_id]\r\nWHERE ([blog_posts]p.[post_slug] == '" . SQL::escape($slug) . "')\r\nGROUP BY [blog_posts]p.[post_id]\r\nORDER BY [blog_posts]p.[post_date]"))) { throw new Exception('The post could not be selected.'); } else { if ($result->numRows() == 0) { Debug::header(404); } $post = $result->fetchOne(); TPL::add('BLOG_CATEGORY_LINK', str_replace(array('%slug', '%id'), array($post->category_slug, $post->category_id), CFG_URL_BLOG_CATEGORY)); TPL::add('BLOG_POST_ID', $post->post_id); TPL::add('BLOG_POST_HEADER', $post->post_header); TPL::add('BLOG_POST_SLUG', $slug); TPL::add('BLOG_POST_DATE', date(ESCMS_DATE_FORMAT, (int) $post->post_date)); TPL::add('BLOG_POST_PROLOGUE', $post->post_prologue); TPL::add('BLOG_POST_CONTENT', $post->post_content); TPL::add('BLOG_CATEGORY_HEADER', $post->category_header); TPL::add('BLOG_CATEGORY_SLUG', $post->category_slug); TPL::add('BLOG_POST_COMMENTS_COUNT', $post->comments_count); } }
/** * get some statistics for some sections * * Only sections matching following criteria are returned: * - section is visible (active='Y') * - section is restricted (active='R'), but surfer is a logged user * - section is hidden (active='N'), but surfer is an associate * * Non-activated and expired sections are counted as well. * * @param string the selected anchor (e.g., 'section:12') * @return array the resulting ($count, $min_date, $max_date) array * * @see sections/delete.php * @see sections/index.php * @see sections/layout_sections.php * @see sections/layout_sections_as_yahoo.php * @see sections/view.php */ public static function stat_for_anchor($anchor = '') { global $context; // limit the query to one level if ($anchor) { $where = "(sections.anchor LIKE '" . SQL::escape($anchor) . "')"; } else { $where = "(sections.anchor='' OR sections.anchor is NULL)"; } // show everything if we are about to suppress a section if (!preg_match('/delete\\.php/', $context['script_url'])) { // display active and restricted items $where .= "AND (sections.active='Y'"; // list restricted sections to authenticated surfers if (Surfer::is_logged()) { $where .= " OR sections.active='R'"; } // list hidden sections to associates, editors and readers if (Surfer::is_empowered('S')) { $where .= " OR sections.active='N'"; } $where .= ")"; // hide sections removed from index maps $where .= " AND (sections.index_map = 'Y')"; // non-associates will have only live sections if ($anchor && !Surfer::is_empowered()) { $where .= " AND ((sections.activation_date is NULL)" . "\tOR (sections.activation_date <= '" . $context['now'] . "'))" . " AND ((sections.expiry_date is NULL)" . "\tOR (sections.expiry_date <= '" . NULL_DATE . "') OR (sections.expiry_date > '" . $context['now'] . "'))"; } } // list sections $query = "SELECT COUNT(*) as count, MIN(edit_date) as oldest_date, MAX(edit_date) as newest_date" . " FROM " . SQL::table_name('sections') . " AS sections" . " WHERE " . $where; $output = SQL::query_first($query); return $output; }
/** * parse one script to build the php documentation * * @param string one script * @param the path to access the script * @return either NULL or an error message */ function parse($script, $path = 'scripts/reference/') { global $context, $page_count; // at least put the script name as a title $this->titles[$script] = $script; // read the file if (!($handle = Safe::fopen($path . $script, 'rb'))) { $this->comments[$script] = sprintf(i18n::s('Impossible to read %s.'), $script); return sprintf(i18n::s('Impossible to read %s.'), $context['path_to_root'] . $path . $script); } // locate php comments $comment = array(); global $first_comment; $first_comment = TRUE; $in_comment = FALSE; $count = 0; while (!feof($handle)) { // up to 4k per line $line = fgets($handle, 4096); // ensure we have enough execution time $count++; if (!($count % 1000)) { Safe::set_time_limit(30); } // a comment ends if ($in_comment && preg_match('/\\s*\\*+\\//', $line)) { $in_comment = FALSE; // a comment continues } elseif ($in_comment) { // strip the '*' at the beginning of the line $comment[] = preg_replace('/^\\s*\\*\\s{0,1}/', '', $line); // comment begins } elseif (preg_match('/\\s*\\/\\*{2,}/', $line)) { $in_comment = TRUE; // class extension } elseif (preg_match('/^\\s*class\\s+(\\w+)\\s+extends\\s+(\\w+)/i', $line, $matches)) { $name = $matches[0]; $this->comment_block($script, $name, $comment); $comment = array(); // class definition } elseif (preg_match('/^\\s*class\\s+(\\w+)/i', $line, $matches)) { $name = $matches[0]; $this->comment_block($script, $name, isset($comment) ? $comment : ''); $comment = array(); // function definition } elseif (preg_match('/^\\s*function\\s+(&{0,1}\\w+)\\s*\\((.*)\\)/i', $line, $matches)) { $name = $matches[0]; $this->comment_block($script, $name, isset($comment) ? $comment : ''); $comment = array(); // only a comment } elseif (preg_match('/^\\s*\\/\\//', $line)) { // a blank line } elseif (preg_match('/^\\s*$/', $line)) { // not a declaration } elseif (@count($comment)) { $this->comment_block($script, '', $comment); $comment = array(); } } // ensure enough execution time Safe::set_time_limit(30); // generate the documentation page for this file $fields['name'] = $script; $fields['anchor'] = dirname($script); $fields['label'] = isset($this->index[$script]) ? $this->index[$script] : '*** you should add a phpDoc label line to this file'; $fields['content'] = isset($this->comments[$script]) ? "[toc]" . $this->comments[$script] : '*** you should expand phpDoc comments for this file'; $query = "INSERT INTO " . SQL::table_name('phpdoc') . " SET " . " name='" . SQL::escape($fields['name']) . "'," . " anchor='" . SQL::escape($fields['anchor']) . "'," . " label='" . SQL::escape($fields['label']) . "'," . " content='" . SQL::escape($fields['content']) . "'," . " edit_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'"; if (SQL::query($query, TRUE) === FALSE) { echo $query . BR . SQL::error() . BR . "\n"; } $page_count++; }
/** * stamp one server profile * * This is used to remember the date of last feed. * * $param int the id of the server to update */ public static function stamp($id) { global $context; // sanity check if (!isset($id) || !$id) { return; } // update the record of authenticated user $query = "UPDATE " . SQL::table_name('servers') . " SET stamp_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'" . " WHERE id = " . SQL::escape($id); // do not report on error SQL::query($query, TRUE); }
/** * unpublish an article * * Clear all publishing information * * @param int the id of the item to unpublish * @return string either a null string, or some text describing an error to be inserted into the html response * @see articles/unpublish.php **/ public static function unpublish($id) { global $context; // id cannot be empty if (!$id || !is_numeric($id)) { return i18n::s('No item has the provided id.'); } // set default values $fields = array(); Surfer::check_default_editor($fields); // update an existing record, except the date $query = "UPDATE " . SQL::table_name('articles') . " SET " . " publish_name=''," . " publish_id=0," . " publish_address=''," . " publish_date=''," . " edit_name='" . SQL::escape($fields['edit_name']) . "'," . " edit_id=" . SQL::escape($fields['edit_id']) . "," . " edit_address='" . SQL::escape($fields['edit_address']) . "'," . " edit_action='article:update'" . " WHERE id = " . SQL::escape($id); SQL::query($query); // end of job return NULL; }
// look for some notification } elseif (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { // change session data to extend life of related file if (!isset($_SESSION['heartbit'])) { $_SESSION['heartbit'] = 0; } $_SESSION['heartbit']++; // refresh the watchdog $_SESSION['watchdog'] = time(); // update surfer presence $query = "UPDATE " . SQL::table_name('users') . " SET click_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'" . " WHERE (id = " . SQL::escape(Surfer::get_id()) . ")"; SQL::query($query, FALSE, $context['users_connection']); // assign article for more time if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'edit' && isset($_REQUEST['reference']) && !strncmp($_REQUEST['reference'], 'article:', 8)) { // refresh record of this article $query = "UPDATE " . SQL::table_name('articles') . " SET " . " assign_date = '" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'" . " WHERE (id = " . SQL::escape(substr($_REQUEST['reference'], 8)) . ") AND (assign_id = " . SQL::escape(Surfer::get_id()) . ")"; SQL::query($query); } // look for one notification -- script will be be killed if none is available $response = Notifications::pull(); // encode result in JSON $output = json_encode($response); // allow for data compression render_raw('application/json; charset=' . $context['charset']); // actual transmission except on a HEAD request if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') { echo $output; } // the post-processing hook, then exit finalize_page(TRUE); }
/** * get some statistics for one anchor * * @param the selected anchor (e.g., 'article:12') * @return the resulting ($count, $oldest_date, $newest_date, $total_size) array */ public static function stat_for_anchor($anchor) { global $context; // sanity check if (!$anchor) { return NULL; } // limit the scope of the request $where = Files::get_sql_where(); // select among available items $query = "SELECT COUNT(*) as count, MIN(edit_date) as oldest_date, MAX(edit_date) as newest_date" . ", SUM(file_size) as total_size" . " FROM " . SQL::table_name('files') . " AS files" . " WHERE files.anchor LIKE '" . SQL::escape($anchor) . "' AND " . $where; $output = SQL::query_first($query); return $output; }
/** * 查询记录 * * string $table * @param array $where * @return array */ public static function getAll2($table, $where) { if (!is_array($where) && count($where) > 0) { return false; } $table = SQL::escape($table); $where = SQL::_parseWhere($where); $sql = "SELECT * FROM `{$table}` WHERE {$where}"; return SQL::getAll($sql); }
/** * notify watchers or not? * * This function is used in various scripts to customize notification of watchers. * * @see articles/edit.php * @see articles/publish.php * * @param array if provided, a notification that can be sent to customised recipients * @return boolean always FALSE for events, since notifications are made through enrolment */ function should_notify_watchers($mail = NULL) { global $context; // sent notification to all enrolled persons if ($mail) { // list enrolment for this meeting $query = "SELECT user_id FROM " . SQL::table_name('enrolments') . " WHERE anchor LIKE '" . SQL::escape($this->anchor->get_reference()) . "'"; if ($result = SQL::query($query)) { // browse the list while ($item = SQL::fetch($result)) { // a user registered on this server if ($item['user_id'] && ($watcher = Users::get($item['user_id']))) { // skip banned users if ($watcher['capability'] == '?') { continue; } // skip current surfer if (Surfer::get_id() && Surfer::get_id() == $item['user_id']) { continue; } // ensure this surfer wants to be alerted if ($watcher['without_alerts'] != 'Y') { Users::alert($watcher, $mail); } } } } } // prevent normal cascading of notifications return FALSE; }
/** * set or change some value * * @param string the id of this item * @param string the related value */ public static function set($id, $value = '') { global $context; // suppress existing content, if any $query = "DELETE FROM " . SQL::table_name('values') . " WHERE id LIKE '" . SQL::escape($id) . "'"; // do not report on error SQL::query($query, TRUE); // update the database $query = "INSERT INTO " . SQL::table_name('values') . " SET" . " id='" . SQL::escape($id) . "'," . " value='" . SQL::escape($value) . "'," . " edit_date='" . SQL::escape(gmstrftime('%Y-%m-%d %H:%M:%S')) . "'"; // do not report on error SQL::query($query, TRUE); }
/** * update surfer presence * * This function is used to track presence information. * Errors are not reported, if any * * @param string web address of visited page * @param string related title * @param string the target anchor, if any * @param string level of visibility for this anchor (e.g., 'Y', 'R' or 'N') */ public static function is_visiting($link, $label, $anchor = NULL, $active = 'Y') { global $context; // don't track crawlers if (Surfer::is_crawler()) { return; } // update the history stack if (!isset($context['pages_without_history']) || $context['pages_without_history'] != 'Y') { // put at top of stack if (!isset($_SESSION['visited'])) { $_SESSION['visited'] = array(); } $_SESSION['visited'] = array_merge(array($link => $label), $_SESSION['visited']); // limit to 20 most recent pages if (count($_SESSION['visited']) > 20) { array_pop($_SESSION['visited']); } } // no anchor to remember if (!$anchor) { return; } // ensure regular operation of the server if (!file_exists($context['path_to_root'] . 'parameters/switch.on')) { return; } // nothing remembered for anonymous surfers if (!Surfer::get_id()) { return; } // we need a GET if (!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] != 'GET') { return; } // Firefox pre-fetch is not a real visit if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') { return; } // ensure the back-end is there if (!is_callable(array('SQL', 'query'))) { return; } // update the record of the surfer $query = "UPDATE " . SQL::table_name('users') . " SET click_anchor='" . SQL::escape($anchor) . "', click_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'" . " WHERE id = " . SQL::escape(Surfer::get_id()); SQL::query($query, FALSE, $context['users_connection']); // also update recent visits include_once $context['path_to_root'] . 'users/visits.php'; Visits::track($anchor, $active); // job done return; }
/** * get some statistics for one anchor * * @param the selected anchor (e.g., 'article:12') * @return the resulting ($count, $min_date, $max_date) array * * @see articles/delete.php * @see articles/view.php * @see categories/delete.php * @see categories/view.php * @see sections/delete.php * @see sections/sections.php * @see sections/view.php * @see skins/layout_home_articles_as_alistapart.php * @see skins/layout_home_articles_as_hardboiled.php * @see skins/layout_home_articles_as_daily.php * @see skins/layout_home_articles_as_newspaper.php * @see skins/layout_home_articles_as_slashdot.php * @see skins/skin_skeleton.php * @see users/delete.php */ public static function stat_for_anchor($anchor) { global $context; // select among available items $query = "SELECT COUNT(*) as count, MIN(edit_date) as oldest_date, MAX(edit_date) as newest_date" . " FROM " . SQL::table_name('links') . " AS links" . " WHERE links.anchor LIKE '" . SQL::escape($anchor) . "'"; $output = SQL::query_first($query); return $output; }
/** * list referrals for a given URL * * @param string the referenced url * @param int the offset from the start of the list; usually, 0 or 1 * @param int the number of items to display * * @see index.php * @see agents/index.php * @see articles/index.php * @see articles/view.php * @see categories/index.php * @see categories/view.php * @see codes/index.php * @see comments/index.php * @see comments/view.php * @see feeds/index.php * @see files/index.php * @see files/view.php * @see images/index.php * @see images/view.php * @see letters/index.php * @see links/index.php * @see locations/index.php * @see locations/view.php * @see overlays/index.php * @see scripts/index.php * @see scripts/view.php * @see sections/index.php * @see sections/view.php * @see servers/index.php * @see servers/view.php * @see services/index.php * @see skins/index.php * @see smileys/index.php * @see tables/index.php * @see tables/view.php * @see users/index.php * @see users/view.php */ public static function list_by_hits_for_url($url, $offset = 0, $count = 10) { global $context; // the front page is a special case if ($url == '/' || $url == $context['url_to_root']) { $where = "(url LIKE '/') OR (url LIKE '" . $context['url_to_root'] . "')"; } else { $where = "url LIKE '" . SQL::escape($url) . "'"; } // the list of referrals $query = "SELECT * FROM " . SQL::table_name('referrals') . " WHERE " . $where . " ORDER BY hits DESC LIMIT " . $offset . ', ' . $count; if (!($result = SQL::query($query, $context['connection']))) { return NULL; } // empty list if (!SQL::count($result)) { return NULL; } // render a compact list, and including the number of referrals $items = array(); while ($row = SQL::fetch($result)) { // hack to make this compliant to XHTML $url = str_replace('&', '&', $row['referer']); if (isset($row['keywords']) && $row['keywords']) { $items[$url] = array('', $row['keywords'], ' (' . Skin::build_number($row['hits']) . ')', 'basic', ''); } else { $items[$url] = array('', $row['domain'], ' (' . Skin::build_number($row['hits']) . ')', 'basic', ''); } } if (count($items)) { return Skin::build_list($items, 'compact'); } return NULL; }