$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) {
/** * 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; }
} $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 = '';
// 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>';
// $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
/** * pop last error message * * @obsolete * @return string most recent error message, or NULL */ public static function error_pop() { return Logger::error_pop(); }
/** * 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; }
// '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
$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
/** * 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; } }