コード例 #1
0
ファイル: anchors.php プロジェクト: rair/yacs
 /**
  * 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);
         }
     }
 }
コード例 #2
0
ファイル: enrolments.php プロジェクト: rair/yacs
 /**
  * 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);
     }
 }
コード例 #3
0
ファイル: links.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #4
0
ファイル: category.php プロジェクト: rair/yacs
 /**
  * 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);
 }
コード例 #5
0
ファイル: run_once.php プロジェクト: rair/yacs
 */
// 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;
コード例 #6
0
ファイル: servers.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #7
0
ファイル: check.php プロジェクト: rair/yacs
    }
    // 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";
コード例 #8
0
ファイル: check.php プロジェクト: rair/yacs
    }
    // 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);
            }
コード例 #9
0
ファイル: populate.php プロジェクト: rair/yacs
         $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
コード例 #10
0
ファイル: event.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #11
0
ファイル: comments.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #12
0
ファイル: update_thumbs_url.php プロジェクト: rair/yacs
        $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
コード例 #13
0
ファイル: files.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #14
0
ファイル: articles.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #15
0
ファイル: profiles.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #16
0
ファイル: transfer.php プロジェクト: rair/yacs
    $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");
コード例 #17
0
ファイル: purge.php プロジェクト: rair/yacs
    $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
コード例 #18
0
ファイル: surfer.php プロジェクト: rair/yacs
 /**
  * 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;
     }
 }
コード例 #19
0
ファイル: index.php プロジェクト: rair/yacs
         $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
コード例 #20
0
ファイル: versions.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #21
0
ファイル: heartbit.php プロジェクト: rair/yacs
    // 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);
}
コード例 #22
0
ファイル: check.php プロジェクト: rair/yacs
    } 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);
            }
コード例 #23
0
ファイル: check.php プロジェクト: rair/yacs
    }
    // 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);
            }
コード例 #24
0
ファイル: notifications.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #25
0
ファイル: check.php プロジェクト: rair/yacs
// 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'])) {
コード例 #26
0
ファイル: sections.php プロジェクト: rair/yacs
 /**
  * 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;
 }
コード例 #27
0
ファイル: values.php プロジェクト: rair/yacs
 /**
  * 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);
 }
コード例 #28
0
ファイル: index.php プロジェクト: rair/yacs
     $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;
コード例 #29
0
ファイル: select.php プロジェクト: rair/yacs
     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);
 }
コード例 #30
0
ファイル: sql.php プロジェクト: rair/yacs
 /**
  * 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;
 }