Example #1
0
File: new.php Project: rair/yacs
     $recipients_processed = 1;
 } else {
     $context['text'] .= '<b>' . i18n::s('No recipient has been defined.') . "</b>" . BR . "\n";
 }
 // do the job
 if ($recipients_processed) {
     $recipients_ok = Mailer::post($from, $to, $subject, $message, NULL, $headers);
     Mailer::close();
     // we may have more recipients than expected
     if ($recipients_ok > $recipients_processed) {
         $recipients_processed = $recipients_ok;
     }
     // reports on error
     $recipients_errors = $recipients_processed - $recipients_ok;
     if ($recipients_errors || count($context['error'])) {
         $context['text'] .= Logger::error_pop() . BR . "\n";
         $context['text'] .= '<b>' . i18n::s('Error has been encountered while sending the letter.') . "</b>" . BR . "\n";
     }
 }
 // report on counters
 $context['text'] .= BR . "\n";
 // list of recipients
 if ($recipients_processed == 0) {
     $context['text'] .= i18n::s('No recipient has been processed.') . BR . "\n";
 } elseif ($recipients_processed == 1) {
     $context['text'] .= i18n::s('One recipient has been processed.') . BR . "\n";
 } else {
     $context['text'] .= sprintf(i18n::s('%d recipients have been processed'), $recipients_processed) . BR . "\n";
 }
 // invalid addresses
 if ($recipients_skipped == 1) {
Example #2
0
 /**
  * create a page out of a textual entity
  *
  * If a target is provided, it is extended with the text of this entity.
  * Else if the anchor is an article, a comment is created. Otherwise an article is created.
  *
  * @param array of entity attributes
  * @param string the textual entity to process
  * @param array poster attributes
  * @param string an optional anchor (e.g., 'article:123')
  * @param string reference of the object to be extended, if any
  * @return string reference to the created or updated object, or NULL
  */
 public static function submit_page($entity_headers, $text, $user, $anchor = NULL, $target = NULL)
 {
     global $context;
     // retrieve queue parameters
     list($server, $account, $password, $allowed, $match, $section, $options, $hooks, $prefix, $suffix) = $context['mail_queue'];
     // preserve breaks
     $text = preg_replace('/\\s*<(br|div|h|p)/is', "\n\n<\$1", $text);
     // suppress dangerous html tags
     $text = strip_tags($text, $context['users_allowed_tags']);
     // trim white spaces
     while (TRUE) {
         $text = trim($text, " \t\r\n");
         if (!strncmp($text, '<br>', 4)) {
             $text = substr($text, 4);
         } elseif (!strncmp($text, '<br/>', 5)) {
             $text = substr($text, 5);
         } elseif (!strncmp($text, '<br />', 6)) {
             $text = substr($text, 6);
         } else {
             break;
         }
     }
     // parse article content
     include_once $context['path_to_root'] . 'articles/article.php';
     $article = new Article();
     $entry_fields = array();
     $entry_fields = $article->parse($text, $entry_fields);
     // trim the header
     if ($prefix) {
         $tokens = explode($prefix, $entry_fields['description']);
         if (isset($tokens[1])) {
             $entry_fields['description'] = $tokens[1];
         } else {
             $entry_fields['description'] = $tokens[0];
         }
     }
     // trim the signature
     if ($suffix) {
         list($entry_fields['description'], $dropped) = explode($suffix, $entry_fields['description']);
     }
     // strip extra text
     $entry_fields['description'] = trim(preg_replace('/\\(See attached file: [^\\)]+?\\)/', '', $entry_fields['description']));
     // anchor this item to something
     $entry_fields['anchor'] = $anchor;
     // make a title
     if (!isset($entry_fields['title'])) {
         $entry_fields['title'] = $context['mail_subject'];
     }
     // message creation stamp
     $entry_fields['create_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', strtotime($context['mail_date']));
     if (!isset($entry_fields['create_name'])) {
         $entry_fields['create_name'] = $user['nick_name'];
     }
     if (!isset($entry_fields['create_id'])) {
         $entry_fields['create_id'] = $user['id'];
     }
     if (!isset($entry_fields['create_address'])) {
         $entry_fields['create_address'] = $user['email'];
     }
     // message edition stamp
     $entry_fields['edit_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', time());
     if (!isset($entry_fields['edit_name'])) {
         $entry_fields['edit_name'] = $user['nick_name'];
     }
     if (!isset($entry_fields['edit_id'])) {
         $entry_fields['edit_id'] = $user['id'];
     }
     if (!isset($entry_fields['edit_address'])) {
         $entry_fields['edit_address'] = $user['email'];
     }
     // we have to extend an existing article --this entity is mutable
     if ($target && !strncmp($target, 'article:', 8) && ($article = Articles::get(substr($target, 8), TRUE))) {
         // append the text to article description field
         $fields = array();
         $fields['id'] = $article['id'];
         $fields['description'] = $article['description'] . $entry_fields['description'];
         $fields['silent'] = TRUE;
         Articles::put_attributes($fields);
         return $target;
         // we have to extend an existing comment --this entity is mutable
     } elseif ($target && !strncmp($target, 'comment:', 8) && ($comment = Comments::get(substr($target, 8), TRUE))) {
         // append the text to comment description field
         $comment['description'] .= $entry_fields['description'];
         Comments::post($comment);
         return $target;
         // we have to comment an existing page
     } elseif (!strncmp($anchor, 'article:', 8)) {
         // insert comment in the database
         if (!($entry_fields['id'] = Comments::post($entry_fields))) {
             Logger::remember('agents/messages.php: ' . Logger::error_pop());
             return NULL;
         }
         // debug, if required to do so
         if ($context['debug_messages'] == 'Y') {
             Logger::remember('agents/messages.php: Messages::submit_page() as a comment', $entry_fields, 'debug');
         }
         // increment the post counter of the surfer
         Users::increment_posts($user['id']);
         // clear cache
         $parent = Anchors::get($entry_fields['anchor']);
         // touch the related anchor
         if (is_object($parent) && isset($entry_fields['id'])) {
             $parent->touch('comment:create', $entry_fields['id'], TRUE);
         }
         return 'comment:' . $entry_fields['id'];
         // create a new page
     } else {
         // publish automatically, if required to do so
         $section = Anchors::get($entry_fields['anchor']);
         if (isset($context['users_with_auto_publish']) && $context['users_with_auto_publish'] == 'Y' || preg_match('/\\bauto_publish\\b/i', $options) || is_object($section) && $section->has_option('auto_publish')) {
             $entry_fields['publish_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', time());
             if (!isset($entry_fields['publish_name'])) {
                 $entry_fields['publish_name'] = $user['nick_name'];
             }
             if (!isset($entry_fields['publish_id'])) {
                 $entry_fields['publish_id'] = $user['id'];
             }
             if (!isset($entry_fields['publish_address'])) {
                 $entry_fields['publish_address'] = $user['email'];
             }
         }
         // ensure we are using ids instead of nicknames
         if (is_object($section)) {
             $entry_fields['anchor'] = $section->get_reference();
         }
         // save in the database
         if (!($entry_fields['id'] = Articles::post($entry_fields))) {
             Logger::remember('agents/messages.php: ' . Logger::error_pop());
             return NULL;
         }
         // debugging log
         if (isset($context['debug_messages']) && $context['debug_messages'] == 'Y') {
             $entry_fields['description'] = substr($entry_fields['description'], 0, 1024);
             Logger::remember('agents/messages.php: Messages::submit_page() as an article', $entry_fields, 'debug');
         }
         // increment the post counter of the surfer
         Users::increment_posts($user['id']);
         // do whatever is necessary on page creation
         if (isset($entry_fields['publish_date']) && $entry_fields['publish_date'] > NULL_DATE) {
             Articles::finalize_publication($section, $entry_fields);
         } else {
             Articles::finalize_submission($section, $entry_fields);
         }
         // get the new item
         $article = Anchors::get($anchor);
         // if replies are allowed
         if (!preg_match('/\\bno_reply\\b/i', $options)) {
             // let the sender know about his post
             if (isset($entry_fields['publish_date']) && $entry_fields['publish_date'] > NULL_DATE) {
                 $splash = i18n::s("The page received by e-mail has been successfully published. Please review it now to ensure that it reflects your mind.");
             } else {
                 $splash = i18n::s("The page received by e-mail has been posted. Don't forget to read it online. Then click on the Publish command to make it publicly available.");
             }
             $message = '<p>' . $splash . '</p>' . '<p><a href="' . $context['url_to_home'] . $context['url_to_root'] . $article->get_url() . '">' . $article->get_title() . '</a></p>' . '<div>' . $article->get_teaser('basic') . '</div>' . '<p>' . i18n::c('Thank you for your contribution') . '</p>';
             // enable threading
             $headers = Mailer::set_thread($section);
             // send a mail message
             Mailer::notify(NULL, $post_sender, 'Re: ' . $post_subject, $message, $headers);
         }
         // reference to the new page
         return 'article:' . $entry_fields['id'];
     }
     // job ends
     return NULL;
 }
Example #3
0
File: index.php Project: rair/yacs
     }
     $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
 //
 $profiles = '';
Example #4
0
File: post.php Project: rair/yacs
         // reference user profile if any
         if ($user['id']) {
             $fields['create_id'] = $user['id'];
             $fields['create_name'] = $user['nick_name'];
             $fields['create_address'] = $user['email'];
             $fields['edit_id'] = $user['id'];
             $fields['edit_name'] = $user['nick_name'];
             $fields['edit_address'] = $user['email'];
         }
         // save the request if debug mode
         if ($context['debug_comment'] == 'Y') {
             Logger::remember('comments/post.php: comments post item', $fields, 'debug');
         }
         // save in the database
         if (!($fields['id'] = Comments::post($fields))) {
             $response = array('faultCode' => 1, 'faultString' => Logger::error_pop());
         } else {
             // touch the related anchor
             $anchor->touch('comment:create', $fields['id']);
             // clear cache
             Comments::clear($fields);
             // increment the post counter of the surfer
             if ($user['id']) {
                 Users::increment_posts($user['id']);
             }
         }
     }
 }
 // an error has been encountered
 if (is_array($response)) {
     $response = '<?xml version="1.0" encoding="' . $context['charset'] . '"?>' . "\n" . '<response>' . "\n" . '<error>' . $response['faultCode'] . '</error>' . "\n" . '<message>' . $response['faultString'] . '</message>' . "\n" . '</response>';
Example #5
0
    //
    $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
    Cache::clear();
    // ask for confirmation
} else {
    // splash message
Example #6
0
 /**
  * pop last error message
  *
  * @obsolete
  * @return string most recent error message, or NULL
  */
 public static function error_pop()
 {
     return Logger::error_pop();
 }
Example #7
0
File: sql.php Project: rair/yacs
 /**
  * Create or alter the structure of one table
  *
  * @param string the name of the table to setup
  * @param array of $field_name => $field_declaration
  * @param array of $index_name => $index_declaration
  * @param array of SQL statements to be executed
  * @return a text string to print
  */
 public static function setup_table($table, $fields, $indexes, $statements = NULL)
 {
     global $context;
     // sanity check
     if (!$table) {
         return '';
     }
     // if the table does not exist
     if (!SQL::has_table($table)) {
         // create it
         $query = "CREATE TABLE " . SQL::table_name($table) . " ( ";
         $count = 0;
         foreach ($fields as $field => $definition) {
             if ($count++) {
                 $query .= ", ";
             }
             $query .= '`' . $field . '` ' . $definition;
         }
         foreach ($indexes as $index => $definition) {
             if ($count++) {
                 $query .= ", ";
             }
             $query .= $index . ' ' . $definition;
         }
         $query .= " ) ENGINE MyISAM";
         // else if the table exists
     } else {
         // check its structure
         $query = "ALTER TABLE " . SQL::table_name($table) . " ";
         // analyse table structure
         $query2 = "DESCRIBE " . SQL::table_name($table);
         if (!($result = SQL::query($query2))) {
             return '<p>' . Logger::error_pop() . "</p>\n";
         }
         // build the list of fields
         while ($row = SQL::fetch($result)) {
             $actual[] = $row['Field'];
         }
         // check all fields
         $count = 0;
         foreach ($fields as $field => $definition) {
             if ($count++) {
                 $query .= ", ";
             }
             if (in_array($field, $actual)) {
                 $query .= "MODIFY";
             } else {
                 $query .= "ADD";
             }
             $query .= ' `' . $field . '` ' . $definition;
         }
         // drop the primary index
         $query .= ", DROP PRIMARY KEY";
         // list existing indexes
         $query2 = "SHOW INDEX FROM " . SQL::table_name($table);
         if (!($result = SQL::query($query2))) {
             return '<p>' . Logger::error_pop() . "</p>\n";
         }
         // drop other indexes
         while ($row = SQL::fetch($result)) {
             if ($row['Seq_in_index'] == 1 && $row['Key_name'] != 'PRIMARY') {
                 $query .= ', DROP INDEX ' . $row['Key_name'];
             }
         }
         SQL::free($result);
         // build new indexes
         foreach ($indexes as $index => $definition) {
             $query .= ", ADD " . $index . ' ' . $definition;
         }
     }
     // execute the query
     if (SQL::query($query) !== FALSE) {
         // message to the user
         $text = BR . i18n::s('The table') . " '" . $table . "'";
         // it's a success
         if (strpos($query, 'CREATE') === 0) {
             $text .= ' ' . i18n::s('has been created');
         } else {
             $text .= ' ' . i18n::s('has been updated');
         }
         // ensure utf8 character set for this table
         $query = "ALTER TABLE " . SQL::table_name($table) . "  DEFAULT CHARACTER SET utf8";
         if (SQL::query($query) !== FALSE) {
             $text .= ' (utf8)';
         }
         // silently analyze table
         $query = "ANALYZE TABLE " . SQL::table_name($table);
         if (($result = SQL::query($query)) && ($row = SQL::fetch($result)) && $row['Msg_type'] == 'status') {
             $text .= ' ' . i18n::s('and analyzed');
             SQL::free($result);
         }
         // optimize the table
         $query = "OPTIMIZE TABLE " . SQL::table_name($table);
         if (($result = SQL::query($query)) && ($row = SQL::fetch($result)) && $row['Msg_type'] == 'status') {
             $text .= ' ' . i18n::s('and optimized');
             SQL::free($result);
         }
         // add views, eventually
         if ($statements && is_array($statements)) {
             // process each statement in sequence
             foreach ($statements as $statement) {
                 // detect errors, if any
                 if (SQL::query($statement) === FALSE) {
                     $text .= '<p>' . sprintf(i18n::s('ERROR for the table %s'), $table) . BR . $statement . BR . SQL::error() . '</p>';
                 }
             }
         }
         // houston, we got a problem
     } else {
         // message to the user
         $text = '<p>' . sprintf(i18n::s('ERROR for the table %s'), $table) . BR . $query . BR . SQL::error() . '</p>';
     }
     return $text;
 }
Example #8
0
File: info.php Project: rair/yacs
     // 'SHOW VARIABLES'
     $query = "SHOW VARIABLES";
     if (!($result = SQL::query($query))) {
         $content = Logger::error_pop() . BR . "\n";
     } else {
         $content = "<table>\n";
         while ($row = SQL::fetch($result)) {
             $content .= '<tr><td>' . $row['Variable_name'] . '</td><td>' . $row['Value'] . "</td></tr>\n";
         }
         $content .= "</table>\n";
     }
     $context['text'] .= Skin::build_box(i18n::s('SQL variables'), $content, 'folded');
     // 'SHOW CHARACTER SET'
     $query = "SHOW CHARACTER SET";
     if (!($result = SQL::query($query))) {
         $content = Logger::error_pop() . BR . "\n";
     } else {
         $content = "<table>\n";
         while ($row = SQL::fetch($result)) {
             $content .= '<tr><td>' . $row['Charset'] . '</td><td>' . $row['Description'] . "</td></tr>\n";
         }
         $content .= "</table>\n";
     }
     $context['text'] .= Skin::build_box(i18n::s('Supported charsets'), $content, 'folded');
     break;
 case 'images':
     // support of graphics
     // GD has not been activated at all
     if (!is_callable('ImageTypes')) {
         $context['text'] .= '<p>' . i18n::s('Please activate the GD module, else YACS can not resize images.') . "</p>\n";
         // ok, GD is present
Example #9
0
File: faceme.php Project: rair/yacs
        $hash = hash_hmac('sha1', $credentials, $context['opentok_api_secret']);
        // finalize the authentication token expected by OpenTok
        $response['token'] = 'T1==' . base64_encode('partner_id=' . $context['opentok_api_key'] . '&sig=' . $hash . ':' . $credentials);
        // handle the output correctly
        render_raw('application/json; charset=' . $context['charset']);
        // actual transmission except on a HEAD request
        if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'HEAD') {
            echo Safe::json_encode($response);
        }
        // the post-processing hook
        finalize_page();
        return;
    }
    // some error has occured
    Safe::header('Status: 400 Bad Request', TRUE, 400);
    die(Logger::error_pop());
    // manage the OpenTok session
} else {
    // leverage URL rewriting if possible
    switch ($context['with_friendly_urls']) {
        case 'Y':
            $link = $context['url_to_home'] . $context['url_to_root'] . 'faceme.php/';
            break;
        case 'R':
            $link = $context['url_to_home'] . $context['url_to_root'] . 'faceme/';
            break;
        default:
            $link = $context['url_to_home'] . $context['url_to_root'] . 'faceme.php?id=';
            break;
    }
    // the spinning wheel
Example #10
0
File: feeds.php Project: rair/yacs
 /**
  * get news from remote servers
  *
  * This function queries remote sources and populate the table of links based on fetched news.
  *
  * On tick, the including hook calls [code]Feeds::tick_hook()[/code].
  * See [script]control/scan.php[/script] for a more complete description of hooks.
  *
  * The function browses the database to locate servers acting as feeders, and read the URLs to use.
  *
  * A round-robin algorithm is implemented, meaning that servers are polled in sequence throughout successive ticks.
  * At most 1 feed is parsed on each tick, to limit impact when the "poor-man" cron mechanism is used,
  * which is the default setting.
  *
  * XML feeds are fetched and parsed according to their type.
  * At the moment YACS is able to process RSS and slashdot feeds.
  * Link records are created or updated in the database saving as much of possible of provided data.
  * Item data is reflected in Link, Title, and Description fields.
  * Channel	data is used to populate the Source field.
  * Stamping information is based on feeding date, and channel title.
  * Also, the edit action 'link:feed' marks links that are collected from feeders.
  * The anchor field is set to the category assigned in the server profile.
  *
  * At the end of the feeding process, the database is purged from oldest links according to the limit
  * defined in parameters/feeds.include.php, set through feeds/configure.php.
  * See Links::purge_old_news().
  *
  * @param boolean if set to true, fetch news on each call; else use normal period of time
  * @return a string to be displayed in resulting page, if any
  *
  * @see control/scan.php
  * @see feeds/configure.php
  */
 public static function tick_hook($forced = FALSE)
 {
     global $context;
     // load librairies only once
     include_once $context['path_to_root'] . 'links/links.php';
     include_once $context['path_to_root'] . 'servers/servers.php';
     include_once $context['path_to_root'] . 'shared/values.php';
     // feeds.tick
     // get feeding parameters
     Safe::load('parameters/feeds.include.php');
     // delay between feeds - minimum is 5 minutes
     if (!isset($context['minutes_between_feeds']) || $context['minutes_between_feeds'] < 5) {
         $context['minutes_between_feeds'] = 5;
     }
     // do not wait for the end of a feeding cycle
     if ($forced) {
         $threshold = gmstrftime('%Y-%m-%d %H:%M:%S');
     } else {
         $threshold = gmstrftime('%Y-%m-%d %H:%M:%S', time() - $context['minutes_between_feeds'] * 60);
     }
     // get a batch of feeders
     if (!($feeders = Servers::list_for_feed(0, 1, 'feed'))) {
         return 'feeds/feeds.php: no feed has been defined' . BR;
     }
     // remember start time
     $start_time = get_micro_time();
     // list banned tokens
     $banned_pattern = Servers::get_banned_pattern();
     // browse each feed
     $count = 0;
     foreach ($feeders as $server_id => $attributes) {
         // get specific feed parameters
         list($feed_url, $feed_title, $anchor, $stamp) = $attributes;
         // skip servers processed recently
         if ($stamp > $threshold) {
             continue;
         }
         // flag this record to enable round-robin even on error
         Servers::stamp($server_id);
         // fetch news from the provided link
         if (!($news = Feeds::get_remote_news_from($feed_url)) || !is_array($news)) {
             continue;
         }
         // no anchor has been defined for this feed
         if (!$anchor) {
             // create a default section if necessary
             if (!($anchor = Sections::lookup('external_news'))) {
                 $fields = array();
                 $fields['nick_name'] = 'external_news';
                 $fields['create_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', time());
                 $fields['edit_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', time());
                 $fields['index_map'] = 'N';
                 $fields['locked'] = 'Y';
                 // no direct contributions
                 $fields['rank'] = 40000;
                 // at the end of the list
                 $fields['title'] = i18n::c('External News');
                 $fields['description'] = i18n::c('Received from feeding servers');
                 if (!($fields['id'] = Sections::post($fields))) {
                     Logger::remember('feeds/feeds.php: Impossible to add a section.');
                     return;
                 }
                 $anchor = 'section:' . $fields['id'];
             }
         }
         // process retrieved links
         $links = 0;
         foreach ($news as $item) {
             // link has to be valid
             if (!isset($item['link']) || !($item['title'] . $item['description'])) {
                 if (isset($context['debug_feeds']) && $context['debug_feeds'] == 'Y') {
                     Logger::remember('feeds/feeds.php: feed item is invalid', $item, 'debug');
                 }
                 continue;
             }
             // skip banned servers
             if ($banned_pattern && preg_match($banned_pattern, $item['link'])) {
                 if (isset($context['debug_feeds']) && $context['debug_feeds'] == 'Y') {
                     Logger::remember('feeds/feeds.php: feed host has been banned', $item['link'], 'debug');
                 }
                 continue;
             }
             // one link processed
             $links++;
             // link description
             $fields = array();
             $fields['anchor'] = $anchor;
             $fields['link_url'] = $item['link'];
             $fields['title'] = $item['title'];
             $fields['description'] = $item['description'];
             if ($item['category']) {
                 $fields['description'] .= ' (' . $item['category'] . ')';
             }
             $fields['edit_name'] = $feed_title;
             $fields['edit_address'] = $feed_url;
             $fields['edit_action'] = 'link:feed';
             if ($item['pubDate']) {
                 $fields['edit_date'] = gmstrftime('%Y-%m-%d %H:%M:%S', strtotime($item['pubDate']));
             }
             // update links that already exist in the database
             if (Links::have($item['link'], $anchor, $fields)) {
                 continue;
             }
             // save link in the database
             if (!Links::post($fields)) {
                 Logger::remember('feeds/feeds.php: Impossible to save feed link: ' . Logger::error_pop());
             }
         }
         // one feed has been processed
         $count += 1;
         // remember tick date
         Values::set('feeds.tick.' . $feed_url, $links);
     }
     // cap the number of links used for news
     if (!isset($context['maximum_news']) || !$context['maximum_news']) {
         $context['maximum_news'] = 1000;
     }
     if ($context['maximum_news'] > 10) {
         include_once $context['path_to_root'] . 'links/links.php';
         Links::purge_old_news($context['maximum_news']);
     }
     // compute execution time
     $time = round(get_micro_time() - $start_time, 2);
     // report on work achieved
     if ($count > 1) {
         return 'feeds/feeds.php: ' . $count . ' feeds have been processed (' . $time . ' seconds)' . BR;
     } elseif ($count == 1) {
         return 'feeds/feeds.php: 1 feed has been processed (' . $time . ' seconds)' . BR;
     } else {
         return 'feeds/feeds.php: nothing to do (' . $time . ' seconds)' . BR;
     }
 }