/** * 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); } } }
/** * 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); } }
/** * 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; }
/** * 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); }
*/ // include global declarations include_once '../shared/global.php'; // load localized strings i18n::bind('scripts'); // load the skin load_skin('scripts'); // the path to this page $context['path_bar'] = array('control/' => i18n::s('Control Panel')); // the title of the page $context['page_title'] = i18n::s('Run one-time scripts'); // the list of script to take into account global $scripts; $scripts = array(); // if the user table exists, check that the user is an admin $query = "SELECT count(*) FROM " . SQL::table_name('users'); if (SQL::query($query) !== FALSE && !Surfer::is_associate()) { Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // open the directory } elseif (!($dir = Safe::opendir($context['path_to_root'] . 'scripts/run_once'))) { Logger::error(sprintf(i18n::s('Impossible to read %s.'), $context['path_to_run_once_scripts'])); } else { while (($item = Safe::readdir($dir)) !== FALSE) { // script name has to start with a number --actually, a date if ($item[0] < '0' || $item[0] > '9') { continue; } // we only consider php scripts, of course if (strlen($item) < 5 || substr($item, -4) != '.php') { continue;
/** * get some statistics * * @return the resulting ($count, $min_date, $max_date) array */ public static function stat() { global $context; // select among active and restricted items $where = "servers.active='Y'"; if (Surfer::is_member()) { $where .= " OR servers.active='R'"; } if (Surfer::is_associate()) { $where .= " OR servers.active='N'"; } // 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('servers') . ' AS servers' . ' WHERE (' . $where . ')'; $output = SQL::query_first($query); return $output; }
} // 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); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // forward to the index page $menu = array('sections/' => i18n::s('Site map')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // look for orphans } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'orphans') { // scan sections $context['text'] .= Skin::build_block(sprintf(i18n::s('Analyzing table %s...'), SQL::table_name('sections')), 'title'); // scan up to 10000 sections $count = 0; $query = "SELECT id, anchor, title FROM " . SQL::table_name('sections') . " ORDER BY anchor LIMIT 0, 10000"; // parse the whole list if ($result = SQL::query($query)) { // retrieve the id and a printable label $errors_count = 0; while ($row = SQL::fetch($result)) { // animate user screen and take care of time $count++; if (!($count % 100)) { $context['text'] .= sprintf(i18n::s('%d records have been processed'), $count) . BR . "\n"; // ensure enough execution time Safe::set_time_limit(30); } // check that the anchor exists, if any if ($row['anchor'] && !Anchors::get($row['anchor'])) { $context['text'] .= sprintf(i18n::s('Orphan: %s'), 'section ' . Skin::build_link(Sections::get_permalink($row), $row['id'] . ' ' . $row['title'], 'section')) . BR . "\n";
} // 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); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // forward to the index page $menu = array('locations/' => i18n::s('Locations')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // look for orphans } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'orphans') { // scan locations $context['text'] .= Skin::build_block(sprintf(i18n::s('Analyzing table %s...'), SQL::table_name('locations')), 'subtitle'); // scan up to 10000 items $count = 0; $query = "SELECT id, anchor, geo_place_name FROM " . SQL::table_name('locations') . " ORDER BY anchor LIMIT 0, 10000"; if (!($result = SQL::query($query))) { $context['text'] .= Logger::error_pop() . BR . "\n"; return; // parse the whole list } else { // fetch one anchor and the linked member $errors_count = 0; while ($row = SQL::fetch($result)) { // animate user screen and take care of time $count++; if (!($count % 100)) { $context['text'] .= sprintf(i18n::s('%d records have been processed'), $count) . BR . "\n"; // ensure enough execution time Safe::set_time_limit(30); }
$text .= Logger::error_pop() . BR . "\n"; } } // tables // $text .= Skin::build_block(i18n::s('Tables'), 'subtitle'); // 'my_articles' article if (Tables::get('my_articles')) { $text .= i18n::s('A sample "my_articles" table already exists.') . BR . "\n"; } elseif ($anchor = Articles::lookup('my_article')) { $fields = array(); $fields['anchor'] = $anchor; $fields['nick_name'] = 'my_articles'; $fields['title'] = i18n::c('My Articles'); $fields['description'] = i18n::c('This is a sample table to let you learn and practice.'); $fields['query'] = "SELECT \n" . "articles.title as titre, \n" . "articles.id as 'id', \n" . "articles.introduction as introduction, \n" . "articles.edit_name as 'last editor', \n" . "articles.edit_date as 'Date' \n" . "FROM " . SQL::table_name('articles') . " AS articles \n" . "WHERE (articles.active='Y') \n" . "ORDER BY articles.rank, articles.edit_date DESC, articles.title LIMIT 0,10"; if (Tables::post($fields)) { $text .= sprintf(i18n::s('A table "%s" has been created.'), $fields['nick_name']) . BR . "\n"; } else { $text .= Logger::error_pop() . BR . "\n"; } } // job done $context['text'] .= $text; // follow-up commands $menu = array(); $menu = array_merge($menu, array('sections/' => i18n::s('Check the updated Site Map'))); $menu = array_merge($menu, array('help/populate.php' => i18n::s('Launch the Content Assistant again'))); $menu = array_merge($menu, array('control/' => i18n::s('Control Panel'))); $context['text'] .= Skin::build_box(i18n::s('What do you want to do now?'), Skin::build_list($menu, 'menu_bar'), 'page_bottom'); // flush the cache
/** * 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; }
/** * get some statistics on threads * * @return the resulting ($count, $min_date, $max_date) array * * @see comments/index.php */ public static function stat_threads() { global $context; // a dynamic where clause $where = ''; // if not associate, restrict to comments at public published not expired pages if (!Surfer::is_associate()) { $where = "(articles.active='Y')" . " AND NOT ((articles.publish_date is NULL) OR (articles.publish_date <= '0000-00-00'))" . " AND ((articles.expiry_date is NULL)" . "\tOR (articles.expiry_date <= '" . NULL_DATE . "') OR (articles.expiry_date > '" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'))"; } // avoid blank records on join if ($where) { $where .= ' AND '; } $where .= '(articles.id > 0)'; // the list of comments $query = "SELECT DISTINCT articles.id as id FROM " . SQL::table_name('comments') . " AS comments" . ", " . SQL::table_name('articles') . " AS articles" . " WHERE (comments.anchor_type LIKE 'article') AND (comments.anchor_id = articles.id)" . "\tAND " . $where; // select among available items $result = SQL::query($query); $output = SQL::count($result); return $output; }
$text .= Skin::build_block(i18n::s('Analysing icons for categories'), 'title'); // query to update $query = "UPDATE " . SQL::table_name('categories') . " SET "; $query .= "icon_url= REPLACE(icon_url,'" . $former_url . "','" . $context['url_to_root'] . "images/')"; // proceed $result = SQL::query($query); // nb of lines if ($result) { $text .= '<p>' . $result . ' line(s) updated</p>'; } else { $text .= '<p>No line updated</p>'; } // VII ANALYSE THUMBNAILS IN FILES TABLE $text .= Skin::build_block(i18n::s('Analysing thumbnails for files'), 'title'); // query to update $query = "UPDATE " . SQL::table_name('files') . " SET "; $query .= "thumbnail_url= REPLACE(thumbnail_url,'" . $former_url . "','" . $context['url_to_root'] . "images/')"; // proceed $result = SQL::query($query); // nb of lines if ($result) { $text .= '<p>' . $result . ' line(s) updated</p>'; } else { $text .= '<p>No line updated</p>'; } // END : report $context['text'] = $text; } } else { $context['text'] = '<p>' . i18n::s('This tools correct the urls of thumbnails and icons of pages after having changed "url_to_root" in control panel') . '</p>'; // the form to get the former URL to root and start the process
/** * 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; }
/** * 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; }
/** * get some statistics * * @return the number of rows in table * * @see control/index.php */ public static function stat() { global $context; // select among available items $query = "SELECT COUNT(*) as count FROM " . SQL::table_name('profiles'); $output = SQL::query_first($query); return $output; }
$query = "UPDATE " . SQL::table_name('sections') . " SET owner_id = " . $user['id'] . " WHERE owner_id = " . $item['id']; if ($count = SQL::query($query)) { $context['text'] .= BR . sprintf(i18n::s('%d sections have been updated'), $count); } // change all pages at once $query = "UPDATE " . SQL::table_name('articles') . " SET owner_id = " . $user['id'] . " WHERE owner_id = " . $item['id']; if ($count = SQL::query($query)) { $context['text'] .= BR . sprintf(i18n::s('%d articles have been updated'), $count); } // change editor records $query = "UPDATE " . SQL::table_name('members') . " SET anchor = 'user:"******"' WHERE anchor LIKE 'user:"******"'"; if ($count = SQL::query($query)) { $context['text'] .= BR . sprintf(i18n::s('%d editor assignments have been updated'), $count); } // change watch lists $query = "UPDATE " . SQL::table_name('members') . " SET member = 'user:"******"'" . ", member_type = 'user', member_id = " . $user['id'] . " WHERE member LIKE 'user:"******"'"; if ($count = SQL::query($query)) { $context['text'] .= BR . sprintf(i18n::s('%d watching assignments have been updated'), $count); } // back to the anchor page $links = array(); $links[] = Skin::build_link(Users::get_permalink($item), i18n::s('Done'), 'button'); $context['text'] .= Skin::finalize_list($links, 'assistant_bar'); // ask for the new owner } else { // delegate to another person $context['text'] .= '<p style="margin-top: 2em;">' . i18n::s('To transfer ownership to another person, type some letters of the name you are looking for.') . '</p>'; // the form to link additional users $context['text'] .= '<form method="post" action="' . $context['script_url'] . '" id="main_form"><p>' . '<input type="text" name="assigned_name" id="name" size="45" maxlength="255" />' . '<input type="hidden" name="id" value="' . encode_field($item['id']) . '">' . '<input type="hidden" name="action" value="set">' . '</p></form>' . "\n"; // enable autocompletion Page::insert_script('$(function() {' . "\n" . ' $("#name").focus();' . "\n" . ' Yacs.autocomplete_names("name",true);' . "\n" . '});' . "\n");
$query = "DELETE FROM " . SQL::table_name('profiles'); if (SQL::query($query) === FALSE) { $context['text'] .= Logger::error_pop() . BR . "\n"; } // display the execution time $time_end = get_micro_time(); $time = round($time_end - $context['start_time'], 2); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // forward to the control panel $menu = array('control/' => i18n::s('Control Panel'), 'control/purge.php' => i18n::s('Purge again')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // delete legacy versioning information } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'versions') { $context['text'] .= '<p>' . i18n::s('Deleting old versions...') . "</p>\n"; // suppress old records $query = "DELETE FROM " . SQL::table_name('versions') . " WHERE (DATE_SUB(CURDATE(),INTERVAL 183 DAY) > edit_date)"; if (SQL::query($query) === FALSE) { $context['text'] .= Logger::error_pop() . BR . "\n"; } // display the execution time $time_end = get_micro_time(); $time = round($time_end - $context['start_time'], 2); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // forward to the control panel $menu = array('control/' => i18n::s('Control Panel'), 'control/purge.php' => i18n::s('Purge again')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // delete formatting code patterns, will be rebuild automaticaly } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'codeyacs') { $context['text'] .= '<p>' . i18n::s('Deleting formatting codes cache...') . "</p>\n"; Safe::unlink($context['path_to_root'] . 'codes/patterns.auto.php'); // display the execution time
/** * surfer has been authenticated * * This function copies user attributes in session storage area. * * Following named attributes from the provided array are copied in session storage area: * - $fields['id'] - id of the logged surfer * - $fields['nick_name'] - nick name of the logged surfer * - $fields['email'] - email address * - $fields['editor'] - preferred on-line editor * - $fields['capability'] - 'A'ssociate or 'M'ember or 'S'ubscriber or '?' * - $fields['phone_number'] - phone number (international format) * * We also remember the IP address of the authenticating workstation, * and the root path of the instance that has validated the surfer. * * @param array session attributes * @param boolean TRUE to remind date of last login in user record */ public static function set($fields, $update_flag = FALSE) { global $context; // save session attributes $_SESSION['surfer_id'] = isset($fields['id']) ? $fields['id'] : ''; $_SESSION['surfer_language'] = isset($fields['language']) ? $fields['language'] : 'none'; if (isset($fields['full_name']) && $fields['full_name']) { $_SESSION['surfer_name'] = $fields['full_name']; } elseif (isset($fields['nick_name']) && $fields['nick_name']) { $_SESSION['surfer_name'] = $fields['nick_name']; } else { $_SESSION['surfer_name'] = ''; } $_SESSION['surfer_email_address'] = isset($fields['email']) ? $fields['email'] : ''; $_SESSION['surfer_phone_number'] = isset($fields['phone_number']) ? $fields['phone_number'] : ''; // provide a default capability only to recorded users if (!$_SESSION['surfer_id']) { $default_capability = ''; } elseif (isset($context['users_with_approved_members']) && $context['users_with_approved_members'] == 'Y') { $default_capability = 'S'; } elseif (isset($context['users_with_email_validation']) && $context['users_with_email_validation'] == 'Y') { $default_capability = 'S'; } else { $default_capability = 'M'; } $_SESSION['surfer_capability'] = isset($fields['capability']) ? $fields['capability'] : $default_capability; // editor preference if (isset($fields['editor'])) { $_SESSION['surfer_editor'] = $fields['editor']; } if (!isset($_SESSION['surfer_editor']) || !$_SESSION['surfer_editor']) { $_SESSION['surfer_editor'] = $context['users_default_editor']; } // interface preference if (isset($fields['interface']) && $fields['interface'] == 'C') { $_SESSION['surfer_interface'] = 'C'; } else { $_SESSION['surfer_interface'] = 'I'; } // remember the address of the authenticating workstation if (isset($_SERVER['REMOTE_ADDR'])) { $_SESSION['workstation_id'] = $_SERVER['REMOTE_ADDR']; } // remember the authenticating instance if (isset($context['url_to_root']) && $context['url_to_root']) { $_SESSION['server_id'] = $context['url_to_root']; } // the surfer has been authenticated, do not challenge him anymore $_SESSION['surfer_is_not_a_robot'] = TRUE; // update user record if (isset($fields['id'])) { // clear tentatives of authentication $query = array(); $query[] = 'authenticate_failures=0'; // remember the date of login if ($update_flag) { $query[] = "login_date='" . gmstrftime('%Y-%m-%d %H:%M:%S') . "'"; $query[] = "login_address='" . $_SERVER['REMOTE_ADDR'] . "'"; } // do the update $query = "UPDATE " . SQL::table_name('users') . " SET " . implode(', ', $query) . " WHERE id = " . $fields['id']; SQL::query($query, FALSE, $context['users_connection']); } // set a semi-permanent cookie for user identification if (isset($fields['handle']) && $fields['handle'] && isset($context['users_with_permanent_authentication']) && $context['users_with_permanent_authentication'] == 'Y') { // time of authentication $now = (string) time(); // token is made of: user id, time of login, gmt offset, salt --salt combines date of login with secret handle $token = $fields['id'] . '|' . $now . '|' . Surfer::get_gmt_offset() . '|' . md5($now . '|' . $fields['handle']); // attempt to set this cookie while answering the current request Surfer::set_cookie('screening', $token); // we will do it again on next transaction, to take care of redirections, if any $_SESSION['surfer_token'] = $token; } }
$label = implode(BR, array($label, $description)); $rows[] = array('left=' . $label, 'left=' . $stamp, 'left=' . $script, 'left=' . $surfer); } $events .= Skin::table($headers, $rows); } else { $events .= '<p>' . i18n::s('No event has been logged') . "</p\\>"; } // display in a separate panel if (trim($events)) { $panels[] = array('events', i18n::s('Events'), 'events_panel', $events); } // // values updated in the background // $values = ''; $query = "SELECT * FROM " . SQL::table_name('values') . " ORDER BY id"; if (!($result = SQL::query($query))) { $values .= Logger::error_pop() . BR . "\n"; } else { $values .= Skin::table_prefix('yc-grid'); while ($row = SQL::fetch($result)) { $values .= '<tr><td>' . $row['id'] . '</td><td>' . str_replace("\n", BR, $row['value']) . '</td><td>' . Surfer::from_GMT($row['edit_date']) . "</td></tr>\n"; } $values .= "</table>\n"; } // display in a separate panel if (trim($values)) { $panels[] = array('values', i18n::s('Values'), 'values_panel', $values); } // // script profiles
/** * 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; }
// 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); }
} elseif ($links_offset) { $context['text'] .= '<p>' . i18n::s('All referrals are looking ok.') . '</p>'; } // display the execution time $time = round(get_micro_time() - $context['start_time'], 2); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // forward to the index page $menu = array('links/' => i18n::s('Links')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // look for orphans } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'orphans') { // scan links $context['text'] .= Skin::build_block(sprintf(i18n::s('Analyzing table %s...'), SQL::table_name('links')), 'title'); // scan many items $count = 0; $query = "SELECT id, anchor, link_url, title FROM " . SQL::table_name('links') . " ORDER BY anchor LIMIT 0, 20000"; if (!($result = SQL::query($query))) { $context['text'] .= Logger::error_pop() . BR . "\n"; return; // parse the whole list } else { // fetch one anchor and the linked member $errors_count = 0; while ($row = SQL::fetch($result)) { // animate user screen and take care of time $count++; if (!($count % 100)) { $context['text'] .= sprintf(i18n::s('%d records have been processed.'), $count) . BR . "\n"; // ensure enough execution time Safe::set_time_limit(30); }
} // 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); $context['text'] .= '<p>' . sprintf(i18n::s('Script terminated in %.2f seconds.'), $time) . '</p>'; // forward to the index page $menu = array('dates/' => i18n::s('Dates')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // look for orphans } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'orphans') { // scan dates $context['text'] .= Skin::build_block(sprintf(i18n::s('Analyzing table %s...'), SQL::table_name('dates')), 'subtitle'); // scan up to 10000 items $count = 0; $query = "SELECT id, anchor, date_stamp FROM " . SQL::table_name('dates') . " ORDER BY anchor LIMIT 0, 10000"; if (!($result = SQL::query($query))) { $context['text'] .= Logger::error_pop() . BR . "\n"; return; // parse the whole list } else { // fetch one anchor and the linked member $errors_count = 0; while ($row = SQL::fetch($result)) { // animate user screen and take care of time $count++; if (!($count % 100)) { $context['text'] .= sprintf(i18n::s('%d records have been processed'), $count) . BR . "\n"; // ensure enough execution time Safe::set_time_limit(30); }
/** * 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; }
// the title of the page $context['page_title'] = i18n::s('Maintenance'); // the user has to be an associate if (!Surfer::is_associate()) { Safe::header('Status: 401 Unauthorized', TRUE, 401); Logger::error(i18n::s('You are not allowed to perform this operation.')); // forward to the index page $menu = array('comments/' => i18n::s('Threads')); $context['text'] .= Skin::build_list($menu, 'menu_bar'); // look for orphans } elseif (isset($_REQUEST['action']) && $_REQUEST['action'] == 'orphans') { // scan comments $context['text'] .= Skin::build_block(sprintf(i18n::s('Analyzing table %s...'), SQL::table_name('comments')), 'title'); // scan up to 20000 items $count = 0; $query = "SELECT id, anchor FROM " . SQL::table_name('comments') . " ORDER BY anchor LIMIT 0, 100000"; if (!($result = SQL::query($query))) { return; } else { // fetch one anchor and the linked member $errors_count = 0; while ($row = SQL::fetch($result)) { // animate user screen and take care of time $count++; if (!($count % 500)) { $context['text'] .= sprintf(i18n::s('%d records have been processed'), $count) . BR . "\n"; // ensure enough execution time Safe::set_time_limit(30); } // check that the anchor exists, if any if ($row['anchor'] && !Anchors::get($row['anchor'])) {
/** * 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; }
/** * 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); }
$cells[] = 'center=' . ($row[1] ? Skin::build_date($row[1]) : '--'); $cells[] = 'center=' . ($row[2] ? Skin::build_date($row[2]) : '--'); $text .= Skin::table_row($cells, $lines++); } else { $text .= Skin::table_row(array(SQL::table_name('versions'), i18n::s('unknown or empty table'), ' ', ' '), $lines++); } // visits if ($row = SQL::table_stat('visits')) { $cells = array(); $cells[] = SQL::table_name('visits'); $cells[] = 'center=' . $row[0]; $cells[] = 'center=' . ($row[1] ? Skin::build_date($row[1]) : '--'); $cells[] = 'center=' . ($row[2] ? Skin::build_date($row[2]) : '--'); $text .= Skin::table_row($cells, $lines++); } else { $text .= Skin::table_row(array(SQL::table_name('visits'), i18n::s('unknown or empty table'), ' ', ' '), $lines++); } // end of the table $text .= Skin::table_suffix(); // total size of the database $query = "SHOW TABLE STATUS"; if (!($result = SQL::query($query))) { $context['text'] .= Logger::error_pop() . BR . "\n"; } else { // consolidate numbers $total_tables = 0; $total_records = 0; $total_size = 0; $data_size = 0; $index_size = 0; $unused_size = 0;
if ($icon) { $suffix .= ' <form method="post" action="' . $context['url_to_root'] . 'categories/set_as_thumbnail.php"><div>' . '<input type="hidden" name="anchor" value="' . encode_field($member) . '" />' . '<input type="hidden" name="id" value="' . $category_id . '" />' . Skin::build_submit_button(i18n::s('Use this thumbnail as the thumbnail of the page')) . '</div></form>'; } // list sub-categories to be linked, if any // display active and restricted items $where = "categories.active='Y'"; if (Surfer::is_member()) { $where .= " OR categories.active='R'"; } if (Surfer::is_associate()) { $where .= " OR categories.active='N'"; } // only consider live categories $where = '(' . $where . ')' . ' AND ((categories.expiry_date is NULL)' . "\tOR (categories.expiry_date <= '" . NULL_DATE . "') OR (categories.expiry_date > '" . $context['now'] . "'))"; // limit the query to top level only $query = "SELECT categories.id, categories.title " . " FROM " . SQL::table_name('categories') . " AS categories " . " WHERE (" . $where . ") AND (categories.anchor='category:" . $category_id . "')" . " ORDER BY categories.title"; $result = SQL::query($query); $sub_categories = array(); while ($result && ($option = SQL::fetch($result))) { $sub_categories['category:' . $option['id']] = $option['title']; } if (count($sub_categories)) { $suffix .= '<form method="post" action="' . $context['script_url'] . '"><div>' . i18n::s('More specific:') . ' <select name="anchor">'; foreach ($sub_categories as $option_reference => $option_label) { $suffix .= '<option value="' . $option_reference . '">' . $option_label . "</option>\n"; } $suffix .= '</select>' . ' ' . Skin::build_submit_button(" >> ") . '<input type="hidden" name="member" value="' . $member . '">' . '<input type="hidden" name="father" value="category:' . $category_id . '">' . '</div></form>' . "\n"; } // format the item $new_categories[$url] = array($prefix, $label, $suffix, $type, $icon); }
/** * count of rows in a table * * @param string name of table to analyze * @return NULL, or an array(count, min_date, max_date) */ public static function table_stat($table) { global $context; // accept foreign user profiles if ($table == 'users') { $connection = $context['users_connection']; } else { $connection = $context['connection']; } // query the database $query = "SELECT count(*), min(edit_date), max(edit_date) FROM " . SQL::table_name($table); if ($result = SQL::query($query)) { if ($row = SQL::fetch_row($result)) { return $row; } } return NULL; }