/** * Get a netlink block / direct to a netlink site. * * @param URLPATH The URL we grab our netlink from. If this is not blank, instead of getting a netlink block, we direct to a netlink site. * @return tempcode The netlink block */ function do_netlink($redir_url = '') { header('Content-type: text/plain; charset=' . get_charset()); // If we are redirecting if ($redir_url != '') { if (strpos($redir_url, chr(10)) !== false || strpos($redir_url, chr(13)) !== false) { log_hack_attack_and_exit('HEADER_SPLIT_HACK'); } header('Location: ' . $redir_url); exit; } // Ok we're displaying a netlink, which will be dumped right into the body of the reading site // - this isn't actually a weburl that is actually displayed, its loaded by ocPortal and embedded-inline // For all the names in our network require_code('textfiles'); $lines = explode(chr(10), read_text_file('netlink', NULL, true)); if (count($lines) == 0) { return new ocp_tempcode(); } $content = new ocp_tempcode(); foreach ($lines as $line) { $parts = explode('=', $line, 2); if (count($parts) != 2) { continue; } $name = rtrim($parts[0]); $url = trim($parts[1]); // Are we looking at the source site in the network? $selected = strtolower($url) == strtolower(get_param('source', '')); $content->attach(form_input_list_entry(base64_encode($url), $selected, $name)); } return do_template('NETLINK', array('_GUID' => '180321222dc5dc99a231597c803f0726', 'CONTENT' => $content)); }
/** * Function to quickly (efficiently) check to see if there's been any chat activity. */ function chat_poller() { $message_id = get_param_integer('message_id', -1); $event_id = get_param_integer('event_id', -1); if (file_exists(get_custom_file_base() . '/data_custom/modules/chat/chat_last_full_check.dat') && filemtime(get_custom_file_base() . '/data_custom/modules/chat/chat_last_full_check.dat') > time() - 3 && ($message_id != -1 && file_exists(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat') && intval(file_get_contents(get_custom_file_base() . '/data_custom/modules/chat/chat_last_msg.dat', FILE_TEXT)) <= $message_id) && ($event_id != -1 && file_exists(get_custom_file_base() . '/data_custom/modules/chat/chat_last_event.dat') && intval(file_get_contents(get_custom_file_base() . '/data_custom/modules/chat/chat_last_event.dat', FILE_TEXT)) <= $event_id)) { load_user_stuff(); require_code('zones'); // Zone is needed because zones are where all ocPortal pages reside require_code('config'); // Config is needed for much active stuff require_code('users'); // Users are important due to permissions $room_id = get_param_integer('room_id', -1); require_code('chat'); chat_room_prune($room_id); header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past header('Content-Type: application/xml'); $output = '<?xml version="1.0" encoding="' . get_charset() . '" ?' . '> <response> <result> <chat_null>' . strval($room_id) . '</chat_null> </result> </response>'; exit($output); } touch(get_custom_file_base() . '/data_custom/modules/chat/chat_last_full_check.dat'); }
/** * Standard modular run function for ajax-tree hooks. Generates XML for a tree list, which is interpreted by Javascript and expanded on-demand (via new calls). * * @param ?ID_TEXT The ID to do under (NULL: root) * @param array Options being passed through * @param ?ID_TEXT The ID to select by default (NULL: none) * @return string XML in the special category,entry format */ function run($id, $options, $default = NULL) { require_code('galleries'); $only_owned = array_key_exists('only_owned', $options) ? is_null($options['only_owned']) ? NULL : intval($options['only_owned']) : NULL; $editable_filter = array_key_exists('editable_filter', $options) ? $options['editable_filter'] : false; $tree = get_gallery_content_tree('images', $only_owned, $id, NULL, NULL, is_null($id) ? 0 : 1, false, $editable_filter); if (!has_actual_page_access(NULL, 'galleries')) { $tree = array(); } $out = ''; foreach ($tree as $t) { $_id = $t['id']; if ($id === $_id) { foreach ($t['entries'] as $eid => $etitle) { if (is_object($etitle)) { $etitle = @html_entity_decode(strip_tags($etitle->evaluate()), ENT_QUOTES, get_charset()); } $out .= '<entry id="' . xmlentities(strval($eid)) . '" title="' . xmlentities($etitle) . '" selectable="true"></entry>'; } continue; } $title = $t['title']; $has_children = $t['child_count'] != 0 || $t['child_entry_count'] != 0; $out .= '<category id="' . xmlentities($_id) . '" title="' . xmlentities($title) . '" has_children="' . ($has_children ? 'true' : 'false') . '" selectable="false"></category>'; } // Mark parent cats for pre-expansion if (!is_null($default) && $default != '') { $cat = $GLOBALS['SITE_DB']->query_value_null_ok('images', 'cat', array('id' => intval($default))); while (!is_null($cat) && $cat != '') { $out .= '<expand>' . $cat . '</expand>'; $cat = $GLOBALS['SITE_DB']->query_value_null_ok('galleries', 'parent_id', array('name' => $cat)); } } return '<result>' . $out . '</result>'; }
/** * Run the loader, to load up field-restrictions from the XML file. * * @param string The default breadcrumbs * @param string The breadcrumb XML data */ function go($current_breadcrumbs, $data) { $this->tag_stack = array(); $this->attribute_stack = array(); $this->substitution_current_match_key = NULL; $this->substitution_current_label = NULL; $this->links = array(); $this->substitutions = array(); $breadcrumb_tpl = do_template('BREADCRUMB_ESCAPED'); $this->breadcrumb_tpl = $breadcrumb_tpl->evaluate(); $this->current_breadcrumbs = $current_breadcrumbs; // Create and setup our parser $xml_parser = @xml_parser_create(); if ($xml_parser === false) { return; // PHP5 default build on windows comes with this function disabled, so we need to be able to escape on error } xml_set_object($xml_parser, $this); @xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, get_charset()); @xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0); xml_set_element_handler($xml_parser, 'startElement', 'endElement'); xml_set_character_data_handler($xml_parser, 'startText'); // Run the parser if (@xml_parse($xml_parser, $data, true) == 0) { attach_message('breadcrumbs.xml: ' . xml_error_string(xml_get_error_code($xml_parser)), 'warn'); return; } @xml_parser_free($xml_parser); }
/** * Standard modular run function for ajax-tree hooks. Generates XML for a tree list, which is interpreted by Javascript and expanded on-demand (via new calls). * * @param ?ID_TEXT The ID to do under (NULL: root) * @param array Options being passed through * @param ?ID_TEXT The ID to select by default (NULL: none) * @return string XML in the special category,entry format */ function run($id, $options, $default = NULL) { require_code('galleries'); require_lang('galleries'); $must_accept_images = array_key_exists('must_accept_images', $options) ? $options['must_accept_images'] : false; $must_accept_videos = array_key_exists('must_accept_videos', $options) ? $options['must_accept_videos'] : false; $filter = array_key_exists('filter', $options) ? $options['filter'] : NULL; $purity = array_key_exists('purity', $options) ? $options['purity'] : false; $member_id = array_key_exists('member_id', $options) ? $options['member_id'] : NULL; $compound_list = array_key_exists('compound_list', $options) ? $options['compound_list'] : false; $addable_filter = array_key_exists('addable_filter', $options) ? $options['addable_filter'] : false; $stripped_id = $compound_list ? preg_replace('#,.*$#', '', $id) : $id; $tree = get_gallery_tree(is_null($id) ? 'root' : $stripped_id, '', NULL, true, $filter, false, false, $purity, $compound_list, is_null($id) ? 0 : 1, $member_id, $addable_filter); if (!has_actual_page_access(NULL, 'galleries')) { $tree = array(); } if ($compound_list) { list($tree, ) = $tree; } $out = ''; for ($i = 0; $i < count($tree); $i++) { $t = $tree[$i]; $_id = $compound_list ? $t['compound_list'] : $t['id']; if ($stripped_id === $t['id']) { // Possible when we look under as a root if (array_key_exists('children', $t)) { $tree = $t['children']; $i = 0; } continue; } $title = $t['title']; if (is_object($title)) { $title = @html_entity_decode(strip_tags($title->evaluate()), ENT_QUOTES, get_charset()); } $has_children = $t['child_count'] != 0; $selectable = ($addable_filter !== true || $t['addable']) && ($t['accept_videos'] == 1 && $t['is_member_synched'] == 0 || !$must_accept_videos) && ($t['accept_images'] == 1 && $t['is_member_synched'] == 0 || !$must_accept_images); $tag = 'category'; // category $out .= '<' . $tag . ' id="' . xmlentities($_id) . '" title="' . xmlentities($title) . '" has_children="' . ($has_children ? 'true' : 'false') . '" selectable="' . ($selectable ? 'true' : 'false') . '"></' . $tag . '>'; // Mark parent cats for pre-expansion if (!is_null($default) && $default != '') { $cat = $default; while (!is_null($cat) && $cat != '') { $out .= '<expand>' . $cat . '</expand>'; $cat = $GLOBALS['SITE_DB']->query_value_null_ok('galleries', 'parent_id', array('name' => $cat)); } } } $tag = 'result'; // result return '<' . $tag . '>' . $out . '</' . $tag . '>'; }
public function fileGet() { $filename = _DIR($this->in['filename']); if (!is_readable($filename)) { show_json($this->L['no_permission_read'], false); } if (filesize($filename) >= 1024 * 1024 * 20) { show_json($this->L['edit_too_big'], false); } $filecontents = file_get_contents($filename); //文件内容 $charset = get_charset($filecontents); if ($charset != '' || $charset != 'utf-8') { $filecontents = mb_convert_encoding($filecontents, 'utf-8', $charset); } $data = array('ext' => get_path_ext($filename), 'name' => iconv_app(get_path_this($filename)), 'filename' => rawurldecode($this->in['filename']), 'charset' => $charset, 'content' => $filecontents); show_json($data); }
/** * Get a database connection. This function shouldn't be used by you, as a connection to the database is established automatically. * * @param boolean Whether to create a persistant connection * @param string The database name * @param string The database host (the server) * @param string The database connection username * @param string The database connection password * @param boolean Whether to on error echo an error and return with a NULL, rather than giving a critical error * @return ?array A database connection (note for mySQL, it's actually a pair, containing the database name too: because we need to select the name before each query on the connection) (NULL: error) */ function db_get_connection($persistent, $db_name, $db_host, $db_user, $db_password, $fail_ok = false) { if (!function_exists('dbx_connect')) { $error = 'dbx not on server (anymore?). Try using the \'mysql\' database driver. To use it, edit the info.php config file.'; if ($fail_ok) { echo $error; return NULL; } critical_error('PASSON', $error); } // Potential cacheing global $CACHE_DB; $x = serialize(array($db_name, $db_host)); if (array_key_exists($x, $CACHE_DB)) { return array($x, $db_name); } $db = @dbx_connect('mysql', $db_host, $db_name, $db_user, $db_password, $persistent ? 1 : 0); if ($db === false || is_null($db)) { $error = 'Could not connect to database/database-server'; if ($fail_ok) { echo $error . chr(10); return NULL; } critical_error('PASSON', $error); //warn_exit(do_lang_tempcode('CONNECT_DB_ERROR')); // purposely not ===false } global $LAST_SELECT_DB; $LAST_SELECT_DB = $db; global $SITE_INFO; if (!array_key_exists('database_charset', $SITE_INFO)) { $SITE_INFO['database_charset'] = strtolower(get_charset()) == 'utf-8' ? 'utf8' : 'latin1'; } @dbx_query($db, 'SET NAMES "' . addslashes($SITE_INFO['database_charset']) . '"'); @dbx_query($db, 'SET SQL_BIG_SELECTS=1'); if (get_forum_type() == 'ocf') { @dbx_query($db, 'SET sql_mode=STRICT_ALL_TABLES'); } return array($db, $db_name); }
/** * AJAX script for returning realtime-rain data. */ function realtime_rain_script() { header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past @ini_set('ocproducts.xss_detect', '0'); header('Content-Type: text/xml'); echo '<?xml version="1.0" encoding="' . get_charset() . '"?' . '>'; echo '<request><result>'; require_code('realtime_rain'); require_lang('realtime_rain'); $time_now = time(); $from = get_param_integer('from', $time_now - 10); $to = get_param_integer('to', $time_now); if (get_param_integer('keep_realtime_test', 0) == 1) { $types = array('post', 'news', 'recommend', 'polls', 'ecommerce', 'actionlog', 'security', 'chat', 'stats', 'join', 'calendar', 'search', 'point_charges', 'banners', 'point_gifts'); shuffle($types); $events = array(); $cnt = count($types); for ($i = 0; $i < max($cnt, 5); $i++) { $timestamp = mt_rand($from, $to); $type = array_pop($types); $event = rain_get_special_icons(get_ip_address(), $timestamp) + array('TYPE' => $type, 'FROM_MEMBER_ID' => NULL, 'TO_MEMBER_ID' => NULL, 'TITLE' => 'Test', 'IMAGE' => rain_get_country_image(get_ip_address()), 'TIMESTAMP' => strval($timestamp), 'RELATIVE_TIMESTAMP' => strval($timestamp - $from), 'TICKER_TEXT' => NULL, 'URL' => NULL, 'IS_POSITIVE' => $type == 'ecommerce' || $type == 'join', 'IS_NEGATIVE' => $type == 'security' || $type == 'point_charges', 'FROM_ID' => NULL, 'TO_ID' => NULL, 'GROUP_ID' => 'example_' . strval(mt_rand(0, 4))); $event['SPECIAL_ICON'] = 'email-icon'; $event['MULTIPLICITY'] = '10'; $events[] = $event; } } else { $events = get_realtime_events($from, $to); } shuffle($events); $out = new ocp_tempcode(); foreach ($events as $event) { $out->attach(do_template('REALTIME_RAIN_BUBBLE', $event)); } $out->evaluate_echo(); echo '</result></request>'; }
/** * Get the contents of an HTML page. * HTML isn't great... no dynamicness/reconfigurability at all. * We prefer comcode with [html]HTML goes here[/html] usage * * @param PATH The relative (to ocPortals base directory) path to the HTML page * @param ?PATH The file base to load from (NULL: standard) * @return string The page */ function load_html_page($string, $file_base = NULL) { if (is_null($file_base)) { $file_base = get_file_base(); } global $PAGE_STRING; if (is_null($PAGE_STRING)) { $PAGE_STRING = $string; } $html = file_get_contents($file_base . '/' . $string, FILE_TEXT); // Post-processing if (strpos($html, '<html') !== false) { $matches = array(); // Fix links to anything in same dir, by assuming either uploads/website_specific or an ocP page in same zone $link_attributes = array('src', 'href', 'action', 'data', 'codebase'); foreach ($link_attributes as $attribute) { $num_matches = preg_match_all('#<[^<>]* ' . $attribute . '="([^&"]+\\.[^&"\\.]+)"[^<>]*>#mis', $html, $matches); for ($i = 0; $i < $num_matches; $i++) { $old_link = $matches[1][$i]; $zone = '_SELF'; if ($old_link[0] == '/') { $old_link = substr($old_link, 1); $zone = ''; } $possible_zone = str_replace('/', '_', dirname($old_link)); if ($possible_zone == '.') { $possible_zone = ''; } if ($possible_zone != '' && $possible_zone != get_zone_name() && file_exists(get_file_base() . '/' . $possible_zone)) { $zone = $possible_zone; } if (substr($old_link, -4) == '.htm') { $_new_link = build_url(array('page' => basename(substr($old_link, 0, strlen($old_link) - 4))), $zone); $new_link = $_new_link->evaluate(); } elseif (substr($old_link, -5) == '.html') { $_new_link = build_url(array('page' => basename(substr($old_link, 0, strlen($old_link) - 5))), $zone); $new_link = $_new_link->evaluate(); } else { $new_link = $old_link; if (url_is_local($old_link)) { if (is_file(get_custom_file_base() . '/' . dirname($string) . '/' . $old_link)) { $new_link = get_custom_base_url() . '/' . dirname($string) . '/' . $old_link; } else { $new_link = get_custom_base_url() . '/uploads/website_specific/' . $old_link; } } } $html = str_replace(' ' . $attribute . '="' . $old_link . '"', ' ' . $attribute . '="' . $new_link . '"', $html); } } // Extract script, style, and link elements from head if (preg_match('#<\\s*head[^<>]*>(.*)<\\s*/\\s*head\\s*>#mis', $html, $matches) != 0) { global $EXTRA_HEAD; $head = $matches[1]; $head_patterns = array('#<\\s*script.*<\\s*/\\s*script\\s*>#misU', '#<\\s*link[^<>]*>#misU', '#<\\s*style.*<\\s*/\\s*style\\s*>#misU'); foreach ($head_patterns as $pattern) { $num_matches = preg_match_all($pattern, $head, $matches); for ($i = 0; $i < $num_matches; $i++) { $EXTRA_HEAD->attach($matches[0][$i]); } } } // Extra meta keywords and description, and title global $SEO_KEYWORDS, $SEO_DESCRIPTION, $SEO_TITLE; if (preg_match('#<\\s*meta\\s+name\\s*=\\s*"keywords"\\s+content="([^"]*)"#mi', $html, $matches) != 0) { $SEO_KEYWORDS = explode(',', @html_entity_decode(trim($matches[1]), ENT_QUOTES, get_charset())); } if (preg_match('#<\\s*meta\\s+name\\s*=\\s*"description"\\s+content="([^"]*)"#mi', $html, $matches) != 0) { $SEO_DESCRIPTION = @html_entity_decode(trim($matches[1]), ENT_QUOTES, get_charset()); } if (preg_match('#<\\s*title\\s*>([^<>]*)<\\s*/\\s*title\\s*>#mis', $html, $matches) != 0) { $SEO_TITLE = @html_entity_decode(trim($matches[1]), ENT_QUOTES, get_charset()); } // Extract body if (preg_match('#<\\s*body[^>]*>(.*)<\\s*/\\s*body\\s*>#mis', $html, $matches) != 0) { $html = $matches[1]; } else { $html = ''; } } return $html; }
/** * The UI for recommending the site. * * @return tempcode The UI. */ function gui() { require_code('form_templates'); global $EXTRA_HEAD; $EXTRA_HEAD->attach('<meta name="robots" content="noindex" />'); // XHTMLXHTML global $NON_CANONICAL_PARAMS; $NON_CANONICAL_PARAMS[] = 'page_title'; $NON_CANONICAL_PARAMS[] = 'subject'; $NON_CANONICAL_PARAMS[] = 's_message'; $NON_CANONICAL_PARAMS[] = 'from'; $NON_CANONICAL_PARAMS[] = 'title'; $NON_CANONICAL_PARAMS[] = 'ocp'; $page_title = get_param('page_title', NULL, true); $submit_name = !is_null($page_title) ? make_string_tempcode($page_title) : do_lang_tempcode('SEND'); $post_url = build_url(array('page' => '_SELF', 'type' => 'actual'), '_SELF', NULL, true); $hidden = new ocp_tempcode(); $name = post_param('name', is_guest() ? '' : $GLOBALS['FORUM_DRIVER']->get_username(get_member())); $recommender_email_address = post_param('recommender_email_address', $GLOBALS['FORUM_DRIVER']->get_member_email_address(get_member())); $fields = new ocp_tempcode(); $fields->attach(form_input_line(do_lang_tempcode('YOUR_NAME'), '', 'name', $name, true)); $fields->attach(form_input_email(do_lang_tempcode('YOUR_EMAIL_ADDRESS'), '', 'recommender_email_address', $recommender_email_address, true)); $already = array(); foreach ($_POST as $key => $email_address) { if (substr($key, 0, 14) != 'email_address_') { continue; } if (get_magic_quotes_gpc()) { $email_address = stripslashes($email_address); } $already[] = $email_address; } if (is_guest()) { $fields->attach(form_input_email(do_lang_tempcode('FRIEND_EMAIL_ADDRESS'), '', 'email_address_0', array_key_exists(0, $already) ? $already[0] : '', true)); } else { $fields->attach(form_input_line_multi(do_lang_tempcode('FRIEND_EMAIL_ADDRESS'), do_lang_tempcode('THEIR_ADDRESS'), 'email_address_', $already, 1, NULL, 'email')); } if (may_use_invites() && get_forum_type() == 'ocf' && !is_guest()) { $invites = get_num_invites(get_member()); if ($invites > 0) { require_lang('ocf'); $invite = count($_POST) == 0 ? true : post_param_integer('invite', 0) == 1; $fields->attach(form_input_tick(do_lang_tempcode('USE_INVITE'), do_lang_tempcode('USE_INVITE_DESCRIPTION', $GLOBALS['FORUM_DRIVER']->is_super_admin(get_member()) ? do_lang('NA_EM') : integer_format($invites)), 'invite', $invite)); } } $message = post_param('message', NULL); $subject = get_param('subject', do_lang('RECOMMEND_MEMBER_SUBJECT', get_site_name()), true); if (is_null($message)) { $message = get_param('s_message', '', true); if ($message == '') { $from = get_param('from', NULL, true); if (!is_null($from)) { $resource_title = get_param('title', '', true); if ($resource_title == '') { $downloaded_at_link = http_download_file($from, 3000, false); if (is_string($downloaded_at_link)) { $matches = array(); if (preg_match('#\\s*<title[^>]*\\s*>\\s*(.*)\\s*\\s*<\\s*/title\\s*>#mi', $downloaded_at_link, $matches) != 0) { $resource_title = trim(str_replace('–', '-', str_replace('—', '-', @html_entity_decode($matches[1], ENT_QUOTES, get_charset())))); $resource_title = preg_replace('#^' . str_replace('#', '\\#', preg_quote(get_site_name())) . ' - #', '', $resource_title); $resource_title = preg_replace('#\\s+[^\\d\\s][^\\d\\s]?[^\\d\\s]?\\s+' . str_replace('#', '\\#', preg_quote(get_site_name())) . '$#i', '', $resource_title); } } } if ($resource_title == '') { $resource_title = do_lang('THIS'); // Could not find at all, so say 'this' } else { $subject = get_param('subject', do_lang('RECOMMEND_MEMBER_SUBJECT_SPECIFIC', get_site_name(), $resource_title), true); } $message = do_lang('FOUND_THIS_ON', get_site_name(), comcode_escape($from), comcode_escape($resource_title)); } } if (get_param_integer('ocp', 0) == 1) { $message = do_lang('RECOMMEND_OCPORTAL'); } } $text = is_null($page_title) ? do_lang_tempcode('RECOMMEND_SITE_TEXT') : new ocp_tempcode(); if (!is_null(get_param('from', NULL, true))) { if (is_null($page_title)) { $title = get_page_title('RECOMMEND_LINK'); } else { $title = get_page_title($page_title, false); } $submit_name = do_lang_tempcode('SEND'); $text = do_lang_tempcode('RECOMMEND_AUTO_TEXT', get_site_name()); $need_message = true; } else { if (is_null($page_title)) { $title = get_page_title('_RECOMMEND_SITE', true, array(escape_html(get_site_name()))); } else { $title = get_page_title($page_title, false); } $hidden->attach(form_input_hidden('wrap_message', '1')); $need_message = false; } //add an upload CSV contacts file field $_help_url = build_url(array('page' => 'recommend_help'), get_page_zone('recommend_help')); $help_url = $_help_url->evaluate(); if (get_value('disable_csv_recommend') !== '1' && !is_guest()) { $fields->attach(form_input_upload(do_lang_tempcode('ALT_FIELD', do_lang_tempcode('UPLOAD')), do_lang_tempcode('DESCRIPTION_UPLOAD_CSV_FILE', escape_html($help_url)), 'upload', false, NULL, NULL, false)); } handle_max_file_size($hidden); $fields->attach(form_input_line(do_lang_tempcode('SUBJECT'), '', 'subject', $subject, true)); $fields->attach(form_input_text_comcode(do_lang_tempcode('MESSAGE'), do_lang_tempcode('RECOMMEND_SUP_MESSAGE'), 'message', $message, $need_message)); if (addon_installed('captcha')) { require_code('captcha'); if (use_captcha()) { $fields->attach(form_input_captcha()); $text->attach(' '); $text->attach(do_lang_tempcode('FORM_TIME_SECURITY')); } } $hidden->attach(form_input_hidden('comcode__message', '1')); if (get_value('disable_csv_recommend') !== '1' && !is_guest()) { $javascript = 'standardAlternateFields(\'upload\',\'email_address_0\');'; } else { $javascript = ''; } $javascript .= function_exists('captcha_ajax_check') ? captcha_ajax_check() : ''; return do_template('FORM_SCREEN', array('_GUID' => '08a538ca8d78597b0417f464758a59fd', 'JAVASCRIPT' => $javascript, 'SKIP_VALIDATION' => true, 'TITLE' => $title, 'HIDDEN' => $hidden, 'FIELDS' => $fields, 'URL' => $post_url, 'SUBMIT_NAME' => $submit_name, 'TEXT' => $text)); }
/** * Convert Comcode-Text to Comcode-XML. * * @param LONG_TEXT The comcode to convert * @param boolean Whether to not include a wrapper element (<comcode>) * @return LONG_TEXT The converted comcode */ function comcode_text__to__comcode_xml($comcode, $skip_wrapper = false) { require_code('comcode_xml'); require_code('comcode_text'); require_code('comcode_renderer'); if (substr($comcode, 0, 8) == '<comcode') { if ($skip_wrapper) { return str_replace('<comcode>', '', str_replace('</comcode>', '', $comcode)); } return $comcode; } $xml = ''; global $ALLOWED_ENTITIES, $CODE_TAGS, $DANGEROUS_TAGS, $VALID_COMCODE_TAGS, $BLOCK_TAGS, $POTENTIAL_JS_NAUGHTY_ARRAY, $TEXTUAL_TAGS, $LEET_FILTER, $IMPORTED_CUSTOM_COMCODE, $REPLACE_TARGETS; $len = strlen($comcode); require_lang('comcode'); require_code('type_validation'); if (function_exists('set_time_limit') && ini_get('max_execution_time') != '0') { @set_time_limit(300); } $comcode_dangerous = true; $comcode_dangerous_html = true; // Tag level $current_tag = ''; $attribute_map = array(); $continuation = ''; $close = mixed(); // Properties that come from our tag $white_space_area = true; $textual_area = true; $formatting_allowed = true; $in_html = false; $in_semihtml = false; $in_separate_parse_section = false; // Not escaped because it has to be passed to a secondary filter $in_code_tag = false; $lax = false; // Our state $status = CCP_NO_MANS_LAND; $tag_stack = array(); $pos = 0; $line_starting = true; $just_ended = false; $none_wrap_length = 0; $just_new_line = true; // So we can detect lists starting right away $just_title = false; global $NUM_LINES; $NUM_LINES = 0; $wrap_pos = 60; $preparse_mode = false; $is_all_semihtml = false; $smilies = $GLOBALS['FORUM_DRIVER']->find_emoticons(); // We'll be needing the smiley array $shortcuts = array('(c)' => '©', '(r)' => '®', '--' => '–', '---' => '—'); // Text syntax possibilities, that get maintained as our cursor moves through the text block $list_indent = 0; $list_type = 'ul'; while ($pos < $len) { $next = $comcode[$pos]; ++$pos; // State machine switch ($status) { case CCP_NO_MANS_LAND: if ($next == '[') { // Look ahead to make sure it's a valid tag. If it's not then it's considered normal user input, not a tag at all $dif = $pos < $len && $comcode[$pos] == '/' ? 1 : 0; $ahead = substr($comcode, $pos + $dif, 19); $equal_pos = strpos($ahead, '='); $space_pos = strpos($ahead, ' '); $end_pos = strpos($ahead, ']'); $cl_pos = strpos($ahead, chr(10)); if ($equal_pos === false) { $equal_pos = 22; } if ($space_pos === false) { $space_pos = 22; } if ($end_pos === false) { $end_pos = 22; } if ($cl_pos === false) { $cl_pos = 22; } $use_pos = min($equal_pos, $space_pos, $end_pos, $cl_pos); $potential_tag = strtolower(substr($ahead, 0, $use_pos)); if ($use_pos != 22 && (!$in_html || $potential_tag == 'html' || $potential_tag == 'semihtml') && (!$in_code_tag || isset($CODE_TAGS[$potential_tag]))) { if (!isset($VALID_COMCODE_TAGS[$potential_tag])) { if (!$IMPORTED_CUSTOM_COMCODE) { _custom_comcode_import($GLOBALS['SITE_DB']); } } if (isset($VALID_COMCODE_TAGS[$potential_tag]) && substr($ahead, 0, 2) != 'i ') { $close = false; $current_tag = ''; $xml .= $continuation; $continuation = ''; if ($potential_tag == 'html' || $potential_tag == 'semihtml') { list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; } $status = CCP_STARTING_TAG; continue; } } } if ($in_html || $in_semihtml && ($next == '<' || $next == '>')) { $ahead = substr($comcode, $pos - 1, 20); $ahead_lower = strtolower($ahead); if ($next == chr(10)) { ++$NUM_LINES; } $continuation .= $next; } else { // Text-format possibilities if ($just_new_line && $formatting_allowed) { $xml .= $continuation; $continuation = ''; // List $found_list = false; $old_list_indent = $list_indent; if ($pos + 1 < $len && is_numeric($next) && $comcode[$pos] == ')' && $comcode[$pos + 1] == ' ') { if ($list_indent != 0 && $list_type == 'ul') { list($temp_tpl, $old_list_indent) = _close_open_lists($list_indent, $list_type); $xml .= $temp_tpl; } $list_indent = 1; $found_list = true; $scan_pos = $pos; $list_type = '1'; } elseif ($pos + 1 < $len && ord($next) >= ord('a') && ord($next) <= ord('z') && $comcode[$pos] == ')' && $comcode[$pos + 1] == ' ') { if ($list_indent != 0 && $list_type == 'ul') { list($temp_tpl, $old_list_indent) = _close_open_lists($list_indent, $list_type); $xml .= $temp_tpl; } $list_indent = 1; $found_list = true; $scan_pos = $pos; $list_type = 'a'; } elseif ($next == ' ') { if ($old_list_indent != 0 && $list_type != 'ul') { list($temp_tpl, $old_list_indent) = _close_open_lists($list_indent, $list_type); $xml .= $temp_tpl; } $scan_pos = $pos - 1; $list_indent = 0; while ($scan_pos < $len) { $scan_next = $comcode[$scan_pos]; if ($scan_next == '-' && $comcode[$scan_pos + 1] == ' ') { $found_list = true; break; } else { if ($scan_next == ' ') { ++$list_indent; } else { break; } } ++$scan_pos; } if (!$found_list) { $list_indent = 0; } } else { list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; if ($next == '-' && !$just_title) { $scan_pos = $pos; $found_rule = true; while ($scan_pos < $len) { $scan_next = $comcode[$scan_pos]; if ($scan_next != '-') { if ($scan_next == chr(10)) { ++$NUM_LINES; break; } else { $found_rule = false; } } ++$scan_pos; } if ($found_rule) { $xml .= '<rule />'; $pos = $scan_pos + 1; $just_ended = true; $none_wrap_length = 0; continue; } } } // List handling if ($list_indent == $old_list_indent && $old_list_indent != 0) { $xml .= '</listElement>'; } for ($i = $list_indent; $i < $old_list_indent; ++$i) { $xml .= '</listElement>'; $xml .= '</list>'; } if ($list_indent < $old_list_indent && $list_indent != 0) { $xml .= '</listElement>'; } if ($found_list) { if ($list_indent - $old_list_indent > 1 && !$lax) { $error = comcode_parse_error($preparse_mode, array('CCP_LIST_JUMPYNESS'), $pos, $comcode); return $error->evaluate(); } for ($i = $old_list_indent; $i < $list_indent; ++$i) { switch ($list_type) { case 'ul': $xml .= '<list>'; break; case '1': $xml .= '<list type="1">'; break; case 'a': $xml .= '<list type="a">'; break; } if ($i < $list_indent - 1) { $xml .= '<listElement>'; } } $xml .= '<listElement>'; $just_ended = true; $none_wrap_length = 0; $next = ''; $pos = $scan_pos + 2; } } if ($next == chr(10) && $white_space_area && !$just_ended) { ++$NUM_LINES; $line_starting = true; $xml .= $continuation; $continuation = ''; $just_new_line = true; $none_wrap_length = 0; if ($list_indent == 0) { $xml .= '<br />' . chr(10); } } else { $just_new_line = false; if ($next == ' ' && $white_space_area) { if ($line_starting || $pos != 0 && $comcode[$pos - 2] == ' ') { $next = ' '; ++$none_wrap_length; } else { $none_wrap_length = 0; } $continuation .= $next; } elseif ($next == "\t" && $white_space_area) { $xml .= $continuation; $continuation = ''; $tab_tpl = do_template('COMCODE_TEXTCODE_TAB'); // $_tab_tpl = $tab_tpl->evaluate(); $none_wrap_length += strlen($_tab_tpl); $xml .= $tab_tpl->evaluate(); } else { if ($next == ' ' || $next == "\t" || $just_ended) { $none_wrap_length = 0; } else { if (!is_null($wrap_pos) && $none_wrap_length >= $wrap_pos && $textual_area && !$in_semihtml) { $xml .= $continuation; $continuation = ''; $xml .= '<br />' . chr(10); $none_wrap_length = 0; } elseif ($textual_area) { ++$none_wrap_length; } } $line_starting = false; $just_ended = false; $differented = false; // If somehow via lookahead we've changed this to HTML and thus won't use it in raw form // Symbol lookahead if (!$in_code_tag) { if ($next == '{' && ($comcode[$pos] == '$' || $comcode[$pos] == '+' || $comcode[$pos] == '!') && $comcode_dangerous) { $xml .= $continuation; $continuation = ''; if ($comcode[$pos] == '+') { $p_end = $pos + 5; while ($p_end < $len) { $p_portion = substr($comcode, $pos - 1, $p_end - ($pos - 1) + 5); if (substr_count($p_portion, '{+START') == substr_count($p_portion, '{+END')) { break; } $p_end++; } $p_len = 1; while ($pos + $p_len < $len) { $p_portion = substr($comcode, $pos - 1, $p_len); if (substr_count($p_portion, '{') == substr_count($p_portion, '}')) { break; } $p_len++; } $p_len--; $p_portion = substr($comcode, $pos + $p_len, $p_end - ($pos + $p_len)); $_ret = template_to_tempcode_static(substr($comcode, $pos - 1, $p_len + 1) . '!' . substr($comcode, $p_end, 6)); $ret = '<directive type="' . escape_html($_ret->bits[0][2]) . '">'; foreach ($_ret->bits[0][3] as $val) { $ret .= '<directiveParam>' . escape_html($val->evaluate()) . '</directiveParam>'; } $ret .= comcode_text__to__comcode_xml($p_portion, true); $ret .= '</directive>'; $pos = $p_end + 6; } else { $_ret = new ocp_tempcode(); $_ret->bits = array(read_single_uncompiled_variable($comcode, $pos, $len)); if ($_ret->bits[0][1] == TC_SYMBOL) { $ret = '<symbol>'; if (isset($_ret->bits[0][3])) { foreach ($_ret->bits[0][3] as $val) { $ret .= '<symbolParam>' . escape_html($val) . '</symbolParam>'; } } $ret .= $_ret->bits[0][2] . '</symbol>'; } else { $ret = '<language>'; if (isset($_ret->bits[0][3])) { foreach ($_ret->bits[0][3] as $val) { $ret .= '<languageParam>' . escape_html($val) . '</languageParam>'; } } $ret .= $_ret->bits[0][2] . '</language>'; } } $differented = true; $xml .= $ret; } } // Escaping of comcode tag starts lookahead if ($next == '\\' && !$in_code_tag) { if ($pos != $len && $comcode[$pos] == '"') { $continuation .= '"'; ++$pos; $differented = true; } elseif ($pos != $len && $comcode[$pos] == '[') { $continuation .= '['; ++$pos; $differented = true; } elseif ($pos != $len && $comcode[$pos] == '{') { $continuation .= '{'; ++$pos; $differented = true; } elseif ($pos == $len || $comcode[$pos] == '\\') { $continuation .= '\\'; ++$pos; $differented = true; } } // Smiley lookahead if (!$differented) { if (($textual_area || $in_semihtml) && trim($next) != '') { foreach ($smilies as $smiley => $imgcode) { if ($in_semihtml) { $smiley = ' ' . $smiley . ' '; } if ($next == $smiley[0]) { if (substr($comcode, $pos - 1, strlen($smiley)) == $smiley) { $xml .= $continuation; $continuation = ''; $pos += strlen($smiley) - 1; $differented = true; $xml .= '<emoticon>' . escape_html($imgcode) . '</emoticon>'; break; } } } } } if ($textual_area && trim($next) != '' && !$differented && addon_installed('cedi')) { // CEDI pages if ($pos < $len && $next == '[') { $matches = array(); if (preg_match('#^\\[([^\\[\\]]*)\\]\\]#', substr($comcode, $pos, 40), $matches) != 0) { $cedi_page_name = $matches[1]; $xml .= $continuation; $continuation = ''; $hash_pos = strpos($cedi_page_name, '#'); if ($hash_pos !== false) { $jump_to = substr($cedi_page_name, $hash_pos + 1); $cedi_page_name = substr($cedi_page_name, 0, $hash_pos); $xml .= '<cedi anchor="' . escape_html($jump_to) . '">' . escape_html($cedi_page_name) . '</cedi>'; } else { $xml .= '<cedi>' . escape_html($cedi_page_name) . '</cedi>'; } $pos += strlen($matches[1]) + 3; $differented = true; } } // Usernames if ($pos < $len && $next == '{') { $matches = array(); if (preg_match('#^\\{([^"{}&\'\\$<>]*)\\}\\}#', substr($comcode, $pos, 40), $matches) != 0) { $xml .= $continuation; $continuation = ''; $username = $matches[1]; if ($username[0] == '?') { $username = substr($username, 1); $xml .= '<member boxed="1">' . escape_html($username) . '</member>'; } else { $xml .= '<member>' . escape_html($username) . '</member>'; } $pos += strlen($matches[1]) + 3; $differented = true; } } if (!$in_code_tag && trim($next) != '' && !$differented) { // Shortcut lookahead if (!$differented) { foreach ($shortcuts as $code => $replacement) { if ($next == $code[0] && substr($comcode, $pos - 1, strlen($code)) == $code) { $xml .= $continuation; $continuation = ''; $pos += strlen($code) - 1; $differented = true; $xml .= $replacement; break; } } } } // Table syntax if (!$differented) { if ($pos < $len && $comcode[$pos] == '|') { $end_tbl = strpos($comcode, chr(10) . '|}', $pos); if ($end_tbl !== false) { $end_fst_line_pos = strpos($comcode, chr(10), $pos); $caption = substr($comcode, $pos + 2, max($end_fst_line_pos - $pos - 2, 0)); $pos += strlen($caption) + 1; $rows = preg_split('#(\\|-|\\|\\})#Um', substr($comcode, $pos, $end_tbl - $pos)); if (count($rows) == 1 && $caption == 'floats') { $cells = preg_split('/(\\n\\! | \\!\\! |\\n\\| | \\|\\| )/', $rows[0], -1, PREG_SPLIT_DELIM_CAPTURE); array_shift($cells); // First one is non-existant empty $spec = true; // Find which to float $to_float = NULL; foreach ($cells as $i => $cell) { if (!$spec) { if (strpos($cell, '!') !== false || is_null($to_float)) { $to_float = $i; } } $spec = !$spec; } $xml .= '<float>'; // Do floated one $xml .= '<fh>'; $xml .= comcode_text__to__comcode_xml(rtrim($cells[$to_float]), true); $xml .= '</fh>'; // Do non-floated ones foreach ($cells as $i => $cell) { if ($i % 2 == 1 && $i != $to_float) { $xml .= '<fd>'; $xml .= comcode_text__to__comcode_xml(rtrim($cells[$to_float]), true); $xml .= '</fd>'; } } $xml .= '</float>'; } else { $xml .= '<table summary="' . escape_html($caption) . '">'; foreach ($rows as $table_row) { $xml .= '<tr>'; $cells = preg_split('/(\\n\\! | \\!\\! |\\n\\| | \\|\\| )/', $table_row, -1, PREG_SPLIT_DELIM_CAPTURE); array_shift($cells); // First one is non-existant empty $spec = true; $c_type = ''; foreach ($cells as $cell) { if ($spec) { $c_type = strpos($cell, '!') !== false ? 'th' : 'td'; } else { $xml .= '<' . $c_type . '>'; $xml .= comcode_text__to__comcode_xml(rtrim($cell), true); $xml .= '</' . $c_type . '>'; } $spec = !$spec; } $xml .= '</tr>'; } $xml .= '</table>'; } $pos = $end_tbl + 3; $differented = true; } } } // Link lookahead if (!$differented) { if (!$in_semihtml && $next == 'h' && (substr($comcode, $pos - 1, strlen('http://')) == 'http://' || substr($comcode, $pos - 1, strlen('https://')) == 'https://' || substr($comcode, $pos - 1, strlen('ftp://')) == 'ftp://')) { list($link_end_pos, $auto_link) = detect_link($comcode, $pos); $xml .= $continuation; $continuation = ''; $downloaded_at_link = http_download_file($auto_link, 3000, false); $link_captions_title = ''; if (is_string($downloaded_at_link)) { $matches = array(); if (preg_match('#<title>\\s*(.*)\\s*</title>#', $downloaded_at_link, $matches) != 0) { require_code('character_sets'); $link_captions_title = @html_entity_decode(convert_to_internal_encoding($matches[1]), ENT_QUOTES, get_charset()); } } $xml .= '<url param="' . escape_html($auto_link) . '">' . escape_html($link_captions_title) . '</url>'; $pos += $link_end_pos - $pos; $differented = true; break; } } } if (!$differented) { if (!$in_separate_parse_section && (!$in_semihtml || !$comcode_dangerous && !$is_all_semihtml)) { if ($next == '&') { $ahead = substr($comcode, $pos, 20); $ahead_lower = strtolower($ahead); $matches = array(); $entity = preg_match('#(\\#)?([\\w]*);#', $ahead_lower, $matches) != 0; // If it is a SAFE entity, use it if ($entity) { if ($matches[1] == '' && isset($ALLOWED_ENTITIES[$matches[2]])) { $pos += strlen($matches[2]) + 1; $continuation .= '&' . $matches[2] . ';'; } elseif (is_numeric($matches[2]) && $matches[1] == '#') { $matched_entity = intval(base_convert($matches[1], 16, 10)); if ($matched_entity < 127 && array_key_exists(chr($matched_entity), $POTENTIAL_JS_NAUGHTY_ARRAY)) { $continuation .= escape_html($next); } else { $pos += strlen($matches[2]) + 2; $continuation .= '&#' . $matches[2] . ';'; } } else { $continuation .= '&'; } } else { $continuation .= '&'; } } else { $continuation .= escape_html($next); } } else { $continuation .= $next; } } } } } break; case CCP_IN_TAG_NAME: if ($next == '=') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT; $current_attribute_name = 'param'; } elseif (trim($next) == '') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTES; } elseif ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { if ($close) { if ($formatting_allowed) { list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; } if (count($tag_stack) == 0) { warn_exit(do_lang_tempcode('CCP_NO_CLOSE', escape_html($current_tag))); } $_last = array_pop($tag_stack); if ($_last[0] != $current_tag) { warn_exit(do_lang_tempcode('CCP_NO_CLOSE_MATCH', escape_html($current_tag), escape_html($_last))); } // Do the comcode for this tag if ($in_semihtml) { foreach ($_last[1] as $index => $conv) { $_last[1][$index] = @html_entity_decode(str_replace('<br />', chr(10), $conv), ENT_QUOTES, get_charset()); } } $attributes = $_last[1]; if ($current_tag == 'html') { $in_html = false; $_last[0] = 'htmlWrap'; } elseif ($current_tag == 'semihtml') { $in_semihtml = false; $_last[0] = 'htmlWrap'; } elseif ($current_tag == 'external_table' || $current_tag == 'internal_table') { $_last[0] = 'box'; } elseif ($current_tag == 'php') { $_last[0] = 'code'; $attributes['param'] = 'php'; } elseif ($current_tag == 'codebox') { $_last[0] = 'code'; $attributes['scroll'] = '1'; } elseif ($current_tag == 'sql') { $_last[0] = 'code'; $attributes['param'] = 'sql'; } elseif ($current_tag == 'snapback') { $_last[0] = 'post'; } elseif ($current_tag == 'thread') { $_last[0] = 'topic'; } elseif ($current_tag == 'list') { $sub_elements = explode('[*]', str_replace('[/*]', '', $xml)); $xml = ''; foreach ($sub_elements as $sub_element) { $xml .= '<listElement>' . $sub_element . '</listElement>'; } } if ($_last[0] == 'box' && isset($attributes['breadth']) && !isset($attributes['dimensions'])) { $attributes['dimensions'] = $attributes['breadth']; unset($attributes['breadth']); } if ($_last[0] == 'page' && array_keys($attributes) != array('param')) { $zone = isset($attributes['param']) ? $attributes['param'] : '_SEARCH'; $page = $xml; $xml = $attributes['caption']; unset($attributes['param']); unset($attributes['caption']); $pagelink = $zone . ':' . $page; foreach ($attributes as $key => $val) { $pagelink .= ':' . $key . '=' . $val; } $attributes = array('pageLink' => $pagelink); } if ($_last[0] == 'block') { foreach ($attributes as $key => $val) { $xml .= '<blockParam key="' . escape_html($key) . '" value="' . escape_html($val) . '" />'; } $attributes = array(); } if ($_last[0] == 'random') { foreach ($attributes as $key => $val) { $xml .= '<randomTarget pickIfAbove="' . escape_html($key) . '">' . comcode_text__to__comcode_xml($val, true) . '</randomTarget>'; } $attributes = array(); } if ($_last[0] == 'jumping') { foreach ($attributes as $key => $val) { $xml .= '<jumpingTarget>' . comcode_text__to__comcode_xml($val, true) . '</jumpingTarget>'; } $attributes = array(); } if ($_last[0] == 'concepts') { foreach ($attributes as $_key => $_value) { if (substr($_key, -4) == '_key') { $key = $_value; $cid = substr($_key, 0, strlen($_key) - 4); $value = $attributes[$cid . '_value']; $xml .= '<showConcept key="' . escape_html($key) . '" value="' . escape_html($value) . '" />'; } } $attributes = array(); } if (($_last[0] == 'attachment' || $_last[0] == 'attachment_safe') && isset($attributes['description'])) { $xml .= '<attachmentDescription>' . comcode_text__to__comcode_xml($attributes['description'], true) . '</attachmentDescription>'; unset($attributes['description']); } if ($_last[0] == 'hide' && isset($attributes['param'])) { $xml .= '<hideTitle>' . comcode_text__to__comcode_xml($attributes['param'], true) . '</hideTitle>'; unset($attributes['param']); } if ($_last[0] == 'tooltip' && isset($attributes['param'])) { $xml .= '<tooltipMessage>' . comcode_text__to__comcode_xml($attributes['param'], true) . '</tooltipMessage>'; unset($attributes['param']); } global $COMCODE_XML_PARAM_RENAMING, $COMCODE_XML_SWITCH_AROUND; if (isset($attributes['param']) && isset($COMCODE_XML_PARAM_RENAMING[$_last[0]])) { $attributes[$COMCODE_XML_PARAM_RENAMING[$_last[0]]] = $attributes['param']; unset($attributes['param']); } $comcode_xml_switch_around = $COMCODE_XML_SWITCH_AROUND; if ($_last[0] == 'email' && (!isset($attributes['param']) || !is_valid_email_address($attributes['param'])) && is_valid_email_address($xml)) { $comcode_xml_switch_around[] = 'email'; } if ($_last[0] == 'url' && (!isset($attributes['param']) || !looks_like_url($attributes['param'])) && looks_like_url($xml)) { $comcode_xml_switch_around[] = 'url'; } if (in_array($_last[0], $comcode_xml_switch_around)) { $x = 'param'; if ($_last[0] == 'reference') { $x = 'title'; } if (isset($attributes[$x])) { $temp = $attributes[$x]; $attributes[$x] = $xml; $xml = comcode_text__to__comcode_xml($temp, true); } else { $attributes[$x] = $xml; } } $in_code_tag = false; $white_space_area = $_last[3]; $in_separate_parse_section = $_last[4]; $formatting_allowed = $_last[5]; $textual_area = $_last[6]; if ($_last[0] == 'htmlWrap') { $embed_output = '<htmlWrap xmlns="http://www.w3.org/1999/xhtml">'; } else { $embed_output = '<' . to_camelCase($_last[0]); foreach ($attributes as $key => $val) { $embed_output .= ' ' . to_camelCase($key) . '="' . escape_html($val) . '"'; } $embed_output .= '>'; } $embed_output .= $xml . '</' . to_camelCase($_last[0]) . '>'; $just_ended = isset($BLOCK_TAGS[$current_tag]); $xml = $_last[2] . $embed_output; if ($current_tag == 'title') { if (strlen($comcode) > $pos + 1 && $comcode[$pos] == chr(10) && $comcode[$pos + 1] == chr(10)) { $NUM_LINES += 2; $pos += 2; $just_new_line = true; list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; } } $status = CCP_NO_MANS_LAND; } else { array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } } else { $current_tag .= strtolower($next); } break; case CCP_STARTING_TAG: if ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { warn_exit(do_lang_tempcode('CCP_TAG_CLOSE_ANOMALY')); } elseif ($next == '/') { $close = true; } else { $current_tag .= strtolower($next); $status = CCP_IN_TAG_NAME; } break; case CCP_IN_TAG_BETWEEN_ATTRIBUTES: if ($next == ']') { array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } elseif ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif (trim($next) != '') { $status = CCP_IN_TAG_ATTRIBUTE_NAME; $current_attribute_name = $next; } break; case CCP_IN_TAG_ATTRIBUTE_NAME: if ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { $at_map_keys = array_keys($attribute_map); $old_attribute_name = $at_map_keys[count($at_map_keys) - 1]; $attribute_map[$old_attribute_name] .= ' ' . $current_attribute_name; array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } elseif ($next == '=') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT; } elseif ($next != ' ') { $current_attribute_name .= strtolower($next); } else { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_LEFT; } break; case CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_LEFT: if ($next == '=') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT; } elseif (trim($next) != '') { warn_exit(do_lang_tempcode('CCP_ATTRIBUTE_ERROR', escape_html($current_attribute_name), escape_html($current_tag))); } break; case CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT: if ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { warn_exit(do_lang_tempcode('CCP_TAG_CLOSE_ANOMALY')); } elseif ($next == '"' || $in_semihtml && substr($comcode, $pos - 1, 6) == '"') { if ($next != '"') { $pos += 5; } $status = CCP_IN_TAG_ATTRIBUTE_VALUE; $current_attribute_value = ''; } elseif ($next != '') { $status = CCP_IN_TAG_ATTRIBUTE_VALUE_NO_QUOTE; $current_attribute_value = $next; } break; case CCP_IN_TAG_ATTRIBUTE_VALUE_NO_QUOTE: if ($next == ' ') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTES; if (isset($attribute_map[$current_attribute_name])) { warn_exit(do_lang_tempcode('CCP_DUPLICATE_ATTRIBUTES', escape_html($current_attribute_name), escape_html($current_tag))); } $attribute_map[$current_attribute_name] = $current_attribute_value; } elseif ($next == ']') { if (isset($attribute_map[$current_attribute_name])) { warn_exit(do_lang_tempcode('CCP_DUPLICATE_ATTRIBUTES', escape_html($current_attribute_name), escape_html($current_tag))); } $attribute_map[$current_attribute_name] = $current_attribute_value; array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } else { $current_attribute_value .= $next; } break; case CCP_IN_TAG_ATTRIBUTE_VALUE: if ($next == '"' || $in_semihtml && substr($comcode, $pos - 1, 6) == '"') { if ($next != '"') { $pos += 5; } $status = CCP_IN_TAG_BETWEEN_ATTRIBUTES; if (isset($attribute_map[$current_attribute_name])) { warn_exit(do_lang_tempcode('CCP_DUPLICATE_ATTRIBUTES', escape_html($current_attribute_name), escape_html($current_tag))); } $attribute_map[$current_attribute_name] = $current_attribute_value; } else { if ($next == '\\') { if ($comcode[$pos] == '"') { $current_attribute_value .= '"'; ++$pos; } elseif ($comcode[$pos] == '\\') { $current_attribute_value .= '\\'; ++$pos; } else { $current_attribute_value .= $next; } } else { $current_attribute_value .= $next; } } break; } } $xml .= $continuation; $continuation = ''; list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; if ($status != CCP_NO_MANS_LAND || count($tag_stack) != 0) { $stack_top = array_pop($tag_stack); warn_exit(do_lang_tempcode('CCP_BROKEN_END', escape_html($stack_top[0]))); } if (!$skip_wrapper) { $xml = '<comcode>' . $xml . '</comcode>'; } return $xml; }
/** * Convert WowBB URLs pasted in text fields into ocPortal ones. * * @param string The text field text (e.g. a post) * @param object The DB connection to import from * @param string The table prefix the target prefix is using * @param PATH The base directory we are importing from * @return string The new text field text */ function fix_links($post, $db, $table_prefix, $file_base) { require $file_base . '/config.php'; $OLD_BASE_URL = constant('HOMEPAGE'); $post = preg_replace_callback('#' . preg_quote($OLD_BASE_URL) . '/(view_topic\\.php\\?id=)(\\d*)&forum_id=(\\d*)#', array($this, '_fix_links_callback_topic'), $post); $post = preg_replace_callback('#' . preg_quote($OLD_BASE_URL) . '/(view_forum\\.php\\?id=)(\\d*)#', array($this, '_fix_links_callback_forum'), $post); $post = preg_replace_callback('#' . preg_quote($OLD_BASE_URL) . '/(view_user\\.php\\?id=)(\\d*)#', array($this, '_fix_links_callback_member'), $post); $post = preg_replace('#:[0-9a-f]{10}#', '', $post); $post = @html_entity_decode($post, ENT_QUOTES, get_charset()); return $post; }
/** * Standard import function. * * @param object The DB connection to import from * @param string The table prefix the target prefix is using * @param PATH The base directory we are importing from */ function import_ocf_posts($db, $table_prefix, $file_base) { global $STRICT_FILE; $row_start = 0; $rows = array(); do { $rows = $db->query('SELECT * FROM ' . $table_prefix . 'post WHERE visible=1 ORDER BY postid', 200, $row_start); foreach ($rows as $row) { if (import_check_if_imported('post', strval($row['postid']))) { continue; } $topic_id = import_id_remap_get('topic', strval($row['threadid']), true); if (is_null($topic_id)) { import_id_remap_put('post', strval($row['postid']), -1); continue; } $member_id = import_id_remap_get('member', strval($row['userid']), true); if (is_null($member_id)) { $member_id = db_get_first_id(); } // This speeds up addition... using the cache can reduce about 7/8 of a query per post on average global $TOPIC_FORUM_CACHE; if (array_key_exists($topic_id, $TOPIC_FORUM_CACHE)) { $forum_id = $TOPIC_FORUM_CACHE[$topic_id]; } else { $forum_id = $GLOBALS['FORUM_DB']->query_value_null_ok('f_topics', 't_forum_id', array('id' => $topic_id)); if (is_null($forum_id)) { continue; } $TOPIC_FORUM_CACHE[$topic_id] = $forum_id; } $title = ''; if ($row['parentid'] == 0) { $topics = $db->query('SELECT title FROM ' . $table_prefix . 'thread WHERE threadid=' . $row['threadid']); $title = $topics[0]['title']; } elseif (!is_null($row['title'])) { $title = $row['title']; } $post = $this->fix_links($row['pagetext'], $db, $table_prefix); $last_edit_by = NULL; $id_new = ocf_make_post($topic_id, @html_entity_decode($title, ENT_QUOTES, get_charset()), $post, 0, $row['parentid'] == 0, $row['visible'], 0, $row['username'], $row['ipaddress'], $row['dateline'], $member_id, NULL, NULL, $last_edit_by, false, false, $forum_id, false); import_id_remap_put('post', strval($row['postid']), $id_new); } $row_start += 200; } while (count($rows) > 0); }
/** * Make some Comcode more readable. * * @param string Comcode text to change * @return string Clean text */ function comcode_to_clean_text($message_plain) { //$message_plain=str_replace("\n",'',$message_plain); if (strpos($message_plain, '[') === false && strpos($message_plain, '{') === false) { return $message_plain; } require_code('tempcode_compiler'); if (strpos($message_plain, '[code') === false && strpos($message_plain, '[no_parse') === false && strpos($message_plain, '[tt') === false) { // Change username links to plain username namings $message_plain = preg_replace('#\\{\\{([^\\}\\{]*)\\}\\}#', '\\1', $message_plain); // Remove directives etc do { $before = $message_plain; $message_plain = preg_replace('#\\{([^\\}\\{]*)\\}#', '', $message_plain); } while ($message_plain != $before); if (strpos($message_plain, '{') !== false) { $message_plain = static_evaluate_tempcode(template_to_tempcode($message_plain, 0, false, '', NULL, NULL, true)); } } $match = array(); if (preg_match("#\\[semihtml\\](.*)\\[\\/semihtml\\]#Us", $message_plain, $match) != 0) { require_code('comcode_from_html'); $message_plain = str_replace($match[0], semihtml_to_comcode($match[0]), $message_plain); } if (preg_match("#^\\s*\\[html\\](.*)\\[\\/html\\]\\s*\$#Us", $message_plain, $match) != 0) { require_code('comcode_from_html'); $message_plain = str_replace($match[0], semihtml_to_comcode($match[0]), $message_plain); } $message_plain = array_key_exists(1, $match) ? $match[1] : $message_plain; $message_plain = preg_replace("#\\[url=\"([^\"]*)\"(.*)\\]([^\\[\\]]*)\\[/url\\]#", '${1}', $message_plain); $message_plain = preg_replace("#\\[img(.*)\\]([^\\[\\]]*)\\[/img\\]#", '', $message_plain); $message_plain = @html_entity_decode(strip_tags($message_plain), ENT_QUOTES, get_charset()); $message_plain = str_replace(']http', ']' . chr(10) . 'http', str_replace('[/url]', chr(10) . '[/url]', $message_plain)); $message_plain = preg_replace('#\\[random [^=]*="([^"]*)"[^\\]]*\\].*\\[/random\\]#Us', '${1}', $message_plain); $message_plain = preg_replace('#\\[abbr="([^"]*)"[^\\]]*\\].*\\[/abbr\\]#Us', '${1}', $message_plain); $message_plain = preg_replace_callback('#\\[indent[^\\]]*\\](.*)\\[/indent\\]#Us', '_indent_callback', $message_plain); $message_plain = preg_replace_callback('#\\[title([^\\]])*\\](.*)\\[/title\\]#Us', '_title_callback', $message_plain); $message_plain = preg_replace_callback('#\\[box="([^"]*)"[^\\]]*\\](.*)\\[/box\\]#Us', '_box_callback', $message_plain); $tags_to_strip_inards = array('if_in_group', 'snapback', 'post', 'thread', 'topic', 'include', 'staff_note', 'attachment', 'attachment2', 'attachment_safe', 'contents', 'block', 'random'); foreach ($tags_to_strip_inards as $s) { $message_plain = preg_replace('#\\[' . $s . '[^\\]]*\\].*\\[/' . $s . '\\]#Us', '', $message_plain); } $message_plain = preg_replace('#\\[surround="accessibility_hidden"\\].*\\[/surround\\]#Us', '', $message_plain); $tags_to_strip = array('surround', 'ticker', 'jumping', 'right', 'center', 'left', 'align', 'list', 'concepts', 'html', 'semihtml', 'concept', 'size', 'color', 'font', 'tt', 'address', 'sup', 'sub', 'box'); foreach ($tags_to_strip as $s) { $message_plain = preg_replace('#\\[' . $s . '[^\\]]*\\](.*)\\[/' . $s . '\\]#U', '${1}', $message_plain); } $message_plain = str_replace(array('[/*]', '[*]', '[list]' . chr(10), chr(10) . '[/list]', '[list]', '[/list]', '[b]', '[/b]', '[i]', '[/i]', '[u]', '[/u]', '[highlight]', '[/highlight]'), array('', ' - ', '', '', '', '', '**', '**', '*', '*', '__', '__', '***', '***'), $message_plain); $message_plain = preg_replace('#\\[list[^\\[\\]]*\\]#', '', $message_plain); $message_plain = preg_replace('#\\{\\$,[^\\{\\}]*\\}#', '', $message_plain); return trim($message_plain); }
$sql .= ", {$tbl_repeat} T" . " WHERE E.repeat_id={$repeat_id}" . " AND E.repeat_id=T.id"; } else { $sql .= " WHERE E.id={$id}"; } $sql .= " AND E.room_id=R.id\n AND R.area_id=A.id"; if ($series) { $sql .= " ORDER BY E.ical_recur_id"; } $res = sql_query($sql); if ($res === FALSE) { trigger_error(sql_error(), E_USER_WARNING); fatal_error(FALSE, get_vocab("fatal_db_error")); } // Export the calendar require_once "functions_ical.inc"; header("Content-Type: application/ics; charset=" . get_charset() . "; name=\"" . $mail_settings['ics_filename'] . ".ics\""); header("Content-Disposition: attachment; filename=\"" . $mail_settings['ics_filename'] . ".ics\""); export_icalendar($res, $keep_private); exit; } } // PHASE 1 - VIEW THE ENTRY // ------------------------ print_header($day, $month, $year, $area, isset($room) ? $room : ""); // Need to tell all the links where to go back to after an edit or delete if (!isset($returl)) { if (isset($HTTP_REFERER)) { $returl = $HTTP_REFERER; } else { switch ($default_view) { case "month":
/** * The UI to translate code. * * @return tempcode The UI */ function interface_code() { $lang = filter_naughty_harsh(get_param('lang', '')); $lang_new = get_param('lang_new', $lang); if ($lang_new != '') { require_code('type_validation'); if (!is_alphanumeric($lang_new, true)) { warn_exit(do_lang_tempcode('BAD_CODENAME')); } if (strlen($lang_new) > 5) { warn_exit(do_lang_tempcode('INVALID_LANG_CODE')); } $lang = $lang_new; } if ($lang == '') { $title = get_page_title('TRANSLATE_CODE'); $GLOBALS['HELPER_PANEL_TEXT'] = comcode_lang_string('DOC_FIND_LANG_STRING_TIP'); return $this->choose_lang($title, true, true, do_lang_tempcode('CHOOSE_EDIT_LIST_LANG_FILE')); } breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('CHOOSE')))); breadcrumb_set_self(do_lang_tempcode('TRANSLATE_CODE')); $base_lang = fallback_lang(); $map_a = get_file_base() . '/lang/langs.ini'; $map_b = get_custom_file_base() . '/lang_custom/langs.ini'; $search = get_param('search', '', true); if ($search != '') { $title = get_page_title('TRANSLATE_CODE'); require_code('form_templates'); $fields = new ocp_tempcode(); global $LANGUAGE; foreach ($LANGUAGE[user_lang()] as $key => $value) { if (strpos(strtolower($value), strtolower($search)) !== false) { $fields->attach(form_input_text($key, '', 'l_' . $key, str_replace('\\n', chr(10), $value), false)); } } if ($fields->is_empty()) { inform_exit(do_lang_tempcode('NO_ENTRIES')); } $post_url = build_url(array('page' => '_SELF', 'type' => '_code2'), '_SELF'); $hidden = new ocp_tempcode(); $hidden->attach(form_input_hidden('redirect', get_self_url(true))); $hidden->attach(form_input_hidden('lang', $lang)); return do_template('FORM_SCREEN', array('_GUID' => '2d7356fd2c4497ceb19450e65331c9c5', 'TITLE' => $title, 'HIDDEN' => $hidden, 'FIELDS' => $fields, 'URL' => $post_url, 'TEXT' => '', 'SUBMIT_NAME' => do_lang('TRANSLATE_CODE'))); } $lang_file = get_param('lang_file'); if (!file_exists($map_b)) { $map_b = $map_a; } $map = better_parse_ini_file($map_b); $title = get_page_title('_TRANSLATE_CODE', true, array(escape_html($lang_file), escape_html(array_key_exists($lang, $map) ? $map[$lang] : $lang))); // Upgrade to custom if not there yet (or maybe we are creating a new lang - same difference) $custom_dir = get_custom_file_base() . '/lang_custom/' . $lang; if (!file_exists($custom_dir)) { require_code('abstract_file_manager'); force_have_afm_details(); afm_make_directory('lang_custom/' . $lang, true); $cached_dir = get_custom_file_base() . '/lang_cached/' . $lang; if (!file_exists($cached_dir)) { afm_make_directory('lang_cached/' . $lang, true); } // Make comcode page dirs $zones = find_all_zones(); foreach ($zones as $zone) { $_special_dir = get_custom_file_base() . '/' . $zone . '/pages/comcode_custom/' . $lang; if (!file_exists($_special_dir)) { afm_make_directory($zone . ($zone == '' ? '' : '/') . 'pages/comcode_custom/' . $lang, true); } $_special_dir = get_custom_file_base() . '/' . $zone . '/pages/html_custom/' . $lang; if (!file_exists($_special_dir)) { afm_make_directory($zone . ($zone == '' ? '' : '/') . 'pages/html_custom/' . $lang, true); } } // Make templates_cached dirs require_code('themes2'); $themes = find_all_themes(); foreach (array_keys($themes) as $theme) { $_special_dir = get_custom_file_base() . '/themes/' . $theme . '/templates_cached/' . $lang; if (!file_exists($_special_dir)) { afm_make_directory('themes/' . $theme . '/templates_cached/' . $lang, true); } } } // Get some stuff $for_lang = get_lang_file_map($lang, $lang_file); $for_base_lang = get_lang_file_map($base_lang, $lang_file, true); $descriptions = get_lang_file_descriptions($base_lang, $lang_file); // Make our translation page $lines = ''; $intertrans = $this->get_intertran_conv($lang); $actions = new ocp_tempcode(); $next = 0; $trans_lot = ''; $delimit = chr(10) . '=-=-=-=-=-=-=-=-' . chr(10); foreach ($for_base_lang as $name => $old) { if (array_key_exists($name, $for_lang)) { $current = $for_lang[$name]; } else { $current = ''; //$this->find_lang_matches($old,$lang); Too slow / useless for code translation } if ($current == '' && strtolower($name) != $name) { $trans_lot .= str_replace('\\n', chr(10), str_replace(array('{', '}'), array('(((', ')))'), $old)) . $delimit; } } $translated_stuff = array(); if ($trans_lot != '' && $intertrans != '') { $result = http_download_file('http://translate.google.com/translate_t', NULL, false, false, 'ocPortal', array('text' => $trans_lot, 'langpair' => 'en|' . $intertrans)); if (!is_null($result)) { require_code('character_sets'); $result = convert_to_internal_encoding($result); $matches = array(); if (preg_match('#<div id=result_box dir="ltr">(.*)</div>#Us', convert_to_internal_encoding($result), $matches) != 0) { $result2 = $matches[1]; $result2 = @html_entity_decode($result2, ENT_QUOTES, get_charset()); $result2 = preg_replace('#\\s?<br>\\s?#', chr(10), $result2); $result2 = str_replace('> ', '>', str_replace(' <', ' <', str_replace('</ ', '</', str_replace(array('(((', ')))'), array('{', '}'), $result2)))); $translated_stuff = explode(trim($delimit), $result2 . chr(10)); } } } foreach ($for_base_lang + $for_lang as $name => $old) { if (array_key_exists($name, $for_lang)) { $current = $for_lang[$name]; } else { $current = ''; //$this->find_lang_matches($old,$lang); Too slow / useless for code translation } $description = array_key_exists($name, $descriptions) ? $descriptions[$name] : ''; if ($current == '' && strtolower($name) != $name && array_key_exists($next, $translated_stuff)) { $_current = ''; $translate_auto = trim($translated_stuff[$next]); $next++; } else { $_current = str_replace('\\n', chr(10), $current); $translate_auto = NULL; } if ($_current == '') { $_current = str_replace('\\n', chr(10), $old); } if ($intertrans != '' && get_value('google_translate_api_key') !== NULL) { $actions = do_template('TRANSLATE_ACTION', array('_GUID' => '9e9a68cb2c1a1e23a901b84c9af2280b', 'LANG_FROM' => get_site_default_lang(), 'LANG_TO' => $lang, 'NAME' => 'trans_' . $name, 'OLD' => $_current)); } $temp = do_template('TRANSLATE_LINE', array('_GUID' => '9cb331f5852ee043e6ad30b45aedc43b', 'TRANSLATE_AUTO' => $translate_auto, 'DESCRIPTION' => $description, 'NAME' => $name, 'OLD' => str_replace('\\n', chr(10), $old), 'CURRENT' => $_current, 'ACTIONS' => $actions)); $lines .= $temp->evaluate(); } $url = build_url(array('page' => '_SELF', 'type' => '_code', 'lang_file' => $lang_file, 'lang' => $lang), '_SELF'); return do_template('TRANSLATE_SCREEN', array('_GUID' => 'b3429f8bd0b4eb79c33709ca43e3207c', 'PAGE' => $lang_file, 'INTERTRANS' => get_value('google_translate_api_key') !== NULL ? $intertrans : '', 'LANG' => $lang, 'LINES' => $lines, 'TITLE' => $title, 'URL' => $url)); }
/** * Get an array of topics in the given forum. Each topic is an array with the following attributes: * - id, the topic ID * - title, the topic title * - lastusername, the username of the last poster * - lasttime, the timestamp of the last reply * - closed, a Boolean for whether the topic is currently closed or not * - firsttitle, the title of the first post * - firstpost, the first post (only set if $show_first_posts was true) * * @param mixed The forum name or an array of forum IDs * @param integer The limit * @param integer The start position * @param integer The total rows (not a parameter: returns by reference) * @param SHORT_TEXT The topic title filter * @param boolean Whether to show the first posts * @param string The date key to sort by * @set lasttime firsttime * @param boolean Whether to limit to hot topics * @param SHORT_TEXT The topic description filter * @return ?array The array of topics (NULL: error) */ function show_forum_topics($name, $limit, $start, &$max_rows, $filter_topic_title = '', $show_first_posts = false, $date_key = 'lasttime', $hot = false, $filter_topic_description = '') { require_code('xhtml'); if (is_integer($name)) { $id_list = 'forum_id=' . strval((int) $name); } elseif (!is_array($name)) { if ($name == '<announce>' || is_null($name)) { $id_list = '(forum_id IS NULL)'; } else { $id = $this->forum_id_from_name($name); if (is_null($id)) { return NULL; } $id_list = 'forum_id=' . strval((int) $id); } } else { $id_list = ''; $id_list_2 = ''; foreach (array_keys($name) as $id) { if ($id_list != '') { $id_list .= ' OR '; } if (is_null($id) || $id == '') { $id_list .= '(forum_id IS NULL)'; } else { $id_list .= 'forum_id=' . strval((int) $id); } } if ($id_list == '') { return NULL; } } $topic_filter = $filter_topic_title != '' ? 'AND title LIKE \'' . db_encode_like($this->ipb_escape($filter_topic_title)) . '\'' : ''; if ($filter_topic_description != '') { $topic_filter .= ' AND description LIKE \'' . db_encode_like($this->ipb_escape($filter_topic_description)) . '\''; } $rows = $this->connection->query('SELECT * FROM ' . $this->connection->get_table_prefix() . 'topics WHERE (' . $id_list . ') ' . $topic_filter . ' ORDER BY ' . ($date_key == 'lasttime' ? 'last_post' : 'start_date') . ' DESC', $limit, $start); $max_rows = $this->connection->query_value_null_ok_full('SELECT COUNT(*) FROM ' . $this->connection->get_table_prefix() . 'topics WHERE (' . $id_list . ') ' . $topic_filter); $emoticons_set_dir = $this->get_emo_dir(); $out = array(); foreach ($rows as $i => $r) { $out[$i] = array(); $out[$i]['id'] = $r['tid']; $out[$i]['num'] = $r['posts']; $out[$i]['title'] = $this->ipb_unescape($r['title']); $out[$i]['firstusername'] = $this->ipb_unescape($r['starter_name']); $out[$i]['lastusername'] = $this->ipb_unescape($r['last_poster_name']); $out[$i]['firstmemberid'] = $r['starter_id']; $out[$i]['lastmemberid'] = $r['last_poster_id']; $out[$i]['firsttime'] = $r['start_date']; $out[$i]['lasttime'] = $r['last_post']; $out[$i]['closed'] = $r['state'] == 'closed'; $fp_rows = $this->connection->query('SELECT * FROM ' . $this->connection->get_table_prefix() . 'posts WHERE post NOT LIKE \'' . db_encode_like(do_lang('SPACER_POST', '', '', '', get_site_default_lang()) . '%') . '\' AND topic_id=' . strval((int) $out[$i]['id']) . ' ORDER BY post_date', 1); if (!array_key_exists(0, $fp_rows)) { unset($out[$i]); continue; } $out[$i]['firsttitle'] = $this->ipb_unescape($fp_rows[0]['post_title']); if ($show_first_posts) { $post_id = $fp_rows[0]['pid']; $post = $fp_rows[0]['post']; if (array_key_exists('post_htmlstate', $fp_rows[0]) && $fp_rows[0]['post_htmlstate'] != 0) { if ($fp_rows[0]['post_htmlstate'] == 1) { $post = str_replace('<br />', '', $post); } $post = @html_entity_decode($post, ENT_QUOTES, get_charset()); } $post = preg_replace('#public/style_emoticons/<\\#EMO_DIR\\#>(.+?)\'#is', $emoticons_set_dir . '\\1\'', $post); $post = str_replace("class='quotetop'", "class='comcode_quote_h4'", $post); $post = str_replace("class='quotemain'", "class='comcode_quote_content'", $post); // Attachments $attachments = $this->connection->query_select('attachments', array('attach_member_id', 'attach_id', 'attach_file', 'attach_location', 'attach_thumb_location', 'attach_is_image', 'attach_filesize', 'attach_hits'), array('attach_post_key' => $fp_rows[0]['post_key'])); foreach ($attachments as $attachment) { if ($attachment['attach_thumb_location'] != '' || $attachment['attach_is_image'] == 0) { $url = get_forum_base_url() . '/index.php?act=Attach&type=post&id=' . $attachment['attach_id']; if ($attachment['attach_thumb_location'] != '') { $special = do_template('FORUM_ATTACHMENT_IMAGE_THUMB', array('_GUID' => '98a66462f270f53101c4c0a1b63f0bfc', 'FULL' => $url, 'URL' => get_forum_base_url() . '/uploads/' . $attachment['attach_thumb_location'])); } else { $special = do_template('FORUM_ATTACHMENT_LINK', array('_GUID' => '002a3220f35debbe567ce7a225aa221e', 'FULL' => $url, 'FILENAME' => $attachment['attach_file'], 'CLEAN_SIZE' => clean_file_size($attachment['attach_filesize']), 'NUM_DOWNLOADS' => integer_format($attachment['attach_hits']))); } } else { $special = do_template('FORUM_ATTACHMENT_IMAGE', array('_GUID' => '49dbf65cb5e20340a5ad4379ea6344c3', 'URL' => get_forum_base_url() . '/uploads/' . $attachment['attach_location'])); } // See if we have to place it somewhere special inside the post $old_post = $post; $post = str_replace('[attachmentid=' . $attachment['attach_id'] . ']', $special->evaluate(), $post); if ($old_post == $post) { $post .= $special->evaluate(); } } global $LAX_COMCODE; $end = 0; while (($pos = strpos($post, '[right]', $end)) !== false) { $e_pos = strpos($post, '[/right]', $pos); if ($e_pos === false) { break; } $end = $e_pos + strlen('[/right]'); $segment = substr($post, $pos, $end - $pos); $temp = $LAX_COMCODE; $LAX_COMCODE = true; $comcode = comcode_to_tempcode($segment, $r['starter_id']); $LAX_COMCODE = $temp; $post = substr($post, 0, $pos) . $comcode->evaluate() . substr($post, $end); } $temp = $LAX_COMCODE; $LAX_COMCODE = true; $out[$i]['firstpost'] = comcode_to_tempcode(xhtmlise_html($post), $r['starter_id'], false, 60, NULL, NULL, false, false, true); // Assumes HTML for posts $LAX_COMCODE = $temp; } } if (count($out) != 0) { return $out; } return NULL; }
/** * Standard modular run function. * * @param array A map of parameters. * @return tempcode The result of execution. */ function run($map) { require_all_lang(); require_code('zones2'); $skip_pages = array_key_exists('skip', $map) ? explode(',', $map['skip']) : array(); $comcode_page_rows = $GLOBALS['SITE_DB']->query_select('comcode_pages', array('*')); $_zones = array(); $zones = find_all_zones(false, true); $GLOBALS['MEMORY_OVER_SPEED'] = true; $low_memory = ini_get('memory_limit') != '-1' && ini_get('memory_limit') != '0' && ini_get('memory_limit') != '' && intval(preg_replace('#M$#', '', ini_get('memory_limit'))) < 26 || get_option('has_low_memory_limit') === '1'; // Reorder a bit $zones2 = array(); foreach (array('', 'site') as $zone_match) { foreach ($zones as $i => $zone) { if ($zone[0] == $zone_match) { $zones2[] = $zone; unset($zones[$i]); } } } $zones2 = array_merge($zones2, $zones); foreach ($zones2 as $z) { list($zone, $zone_title, , $zone_default_page) = $z; if (has_zone_access(get_member(), $zone)) { $_pages = array(); $pages = find_all_pages_wrap($zone); if (isset($pages[$zone_default_page])) { $default = $pages[$zone_default_page]; $pages = array($zone_default_page => $default) + $pages; } foreach ($pages as $page => $page_type) { if (is_integer($page)) { $page = strval($page); } if (substr($page, 0, 6) == 'panel_') { continue; } if (substr($page, 0, 1) == '_') { continue; } if (in_array($page, $skip_pages)) { continue; } if (in_array($zone . ':' . $page, $skip_pages)) { continue; } if ($page == '404') { continue; } if (strpos($page, '_tree_made') !== false) { continue; } if ($page == 'sitemap') { continue; } if ($page == 'forums' && substr($page_type, 0, 7) == 'modules' && (get_forum_type() == 'ocf' || get_forum_type() == 'none')) { continue; } if ($page == 'join' && substr($page_type, 0, 7) == 'modules' && !is_guest()) { continue; } if (has_page_access(get_member(), $page, $zone)) { $_entrypoints = array(); $__entrypoints = $low_memory ? array(NULL) : extract_module_functions_page($zone, $page, array('get_entry_points')); if (!is_null($__entrypoints[0])) { $entrypoints = is_array($__entrypoints[0]) ? call_user_func_array($__entrypoints[0][0], $__entrypoints[0][1]) : (strpos($__entrypoints[0], '::') !== false ? NULL : eval($__entrypoints[0])); // The strpos thing is a little hack that allows it to work for base-class derived modules if (is_null($entrypoints)) { $path = zone_black_magic_filterer($zone . ($zone == '' ? '' : '/') . 'pages/' . $page_type . '/' . $page . '.php', true); if ($low_memory && !defined('HIPHOP_PHP') && strpos(file_get_contents(get_file_base() . '/' . $path), ' extends standard_aed_module') !== false) { $new_code = str_replace(',parent::get_entry_points()', '', str_replace('parent::get_entry_points(),', '', $__entrypoints[0])); if (strpos($new_code, 'parent::') !== false) { continue; } $entrypoints = eval($new_code); } else { require_code($path); if (class_exists('Mx_' . filter_naughty_harsh($page))) { $object = object_factory('Mx_' . filter_naughty_harsh($page)); } else { $object = object_factory('Module_' . filter_naughty_harsh($page)); } $entrypoints = $object->get_entry_points(); } } } else { $entrypoints = array('!'); } if (!is_array($entrypoints)) { $entrypoints = array('!'); } if ($entrypoints == array('!')) { $url = build_url(array('page' => $page), $zone, NULL, false, false, true); $title = ucwords(str_replace('_', ' ', $page)); if (substr($page_type, 0, 7) == 'comcode') { foreach ($comcode_page_rows as $page_row) { if ($page_row['p_validated'] == 0 && $page_row['the_page'] == $page && $page_row['the_zone'] == $zone) { continue 2; } } $path = zone_black_magic_filterer((strpos($page_type, '_custom') !== false ? get_custom_file_base() : get_file_base()) . '/' . filter_naughty($zone) . '/pages/' . filter_naughty($page_type) . '/' . $page . '.txt'); if (!is_file($path)) { $path = zone_black_magic_filterer(get_file_base() . '/' . filter_naughty($zone) . '/pages/' . filter_naughty($page_type) . '/' . $page . '.txt'); } $page_contents = file_get_contents($path); $matches = array(); if (preg_match('#\\[title[^\\]]*\\]#', $page_contents, $matches) != 0) { $start = strpos($page_contents, $matches[0]) + strlen($matches[0]); $end = strpos($page_contents, '[/title]', $start); $matches = array(); $title_portion = str_replace('{$SITE_NAME}', get_site_name(), substr($page_contents, $start, $end - $start)); if (preg_match('#\\{\\!([\\w:]+)\\}#', $title_portion, $matches) != 0) { $title_portion = str_replace($matches[0], do_lang($matches[1]), $title_portion); } if (preg_match('#^[^<>\\[\\{\\&]*$#', $title_portion, $matches) != 0) { $title = $matches[0]; } elseif (!$low_memory) { $_title = comcode_to_tempcode($title_portion); $title = strip_tags(@html_entity_decode($_title->evaluate(), ENT_QUOTES, get_charset())); } } } elseif (substr($page_type, 0, 4) == 'html') { $path = zone_black_magic_filterer((strpos($page_type, '_custom') !== false ? get_custom_file_base() : get_file_base()) . '/' . filter_naughty($zone) . '/pages/' . filter_naughty($page_type) . '/' . $page . '.htm'); $page_contents = file_get_contents($path); $matches = array(); if (preg_match('#\\<title[^\\>]*\\>#', $page_contents, $matches) != 0) { $start = strpos($page_contents, $matches[0]) + strlen($matches[0]); $end = strpos($page_contents, '</title>', $start); $title = strip_tags(@html_entity_decode(substr($page_contents, $start, $end - $start), ENT_QUOTES, get_charset())); } } $temp = do_template('BLOCK_MAIN_SITEMAP_NEST', array('_GUID' => '92e657f8b9a3642df053f54e724e66f6', 'URL' => $url, 'NAME' => $title, 'CHILDREN' => array())); $_pages[$title] = $temp->evaluate(); // FUDGEFUDGE } elseif (count($entrypoints) != 0) { foreach ($entrypoints as $entrypoint => $title) { if (($entrypoint == 'concede' || $entrypoint == 'invisible' || $entrypoint == 'logout') && is_guest()) { continue; } if ($entrypoint == '!') { $url = build_url(array('page' => $page), $zone, NULL, false, false, true); } else { $url = build_url(array('page' => $page, 'type' => $entrypoint), $zone, NULL, false, false, true); } $_entrypoints[$title] = do_template('BLOCK_MAIN_SITEMAP_NEST', array('_GUID' => 'ae2ed2549644a8e699e0938b3ab98ddb', 'URL' => $url, 'NAME' => do_lang_tempcode($title), 'CHILDREN' => array())); } //ksort($_entrypoints); $title = do_lang('MODULE_TRANS_NAME_' . $page, NULL, NULL, NULL, NULL, false); if (is_null($title)) { $title = ucwords(str_replace('_', ' ', preg_replace('#^ocf\\_#', '', preg_replace('#^' . str_replace('#', '\\#', preg_quote($zone)) . '_#', '', preg_replace('#^' . str_replace('#', '\\#', preg_quote(str_replace('zone', '', $zone))) . '_#', '', $page))))); } if (count($_entrypoints) == 1) { $temp_keys = array_keys($_entrypoints); $temp = $_entrypoints[$temp_keys[0]]; } else { $temp = do_template('BLOCK_MAIN_SITEMAP_NEST', array('_GUID' => 'dfc5cc7db0301acd938d3b2e3fceaab8', 'URL' => new ocp_tempcode(), 'NAME' => $title, 'CHILDREN' => $_entrypoints)); } $_pages[$title] = $temp->evaluate(); // FUDGEFUDGE } } } $url = new ocp_tempcode(); if ($_pages != array()) { $keys = array_keys($_pages); $first = $_pages[$keys[0]]; ksort($_pages); $_pages = array($keys[0] => $first) + $_pages; } $temp = do_template('BLOCK_MAIN_SITEMAP_NEST', array('_GUID' => '38abb0a0e5bec968b28b4791320dd0dc', 'URL' => $url, 'NAME' => $zone_title, 'CHILDREN' => $_pages)); $_zones[] = $temp->evaluate(); // FUDGEFUDGE } } // To avoid running out of memory $out = do_template('BLOCK_MAIN_SITEMAP', array('_GUID' => 'd0807b30925e47d10cdb2c36231436ab', 'CHILDREN' => $_zones)); $e = $out->evaluate(); $explode = explode('__keep__', $e); // the URLs are build without keep and the templates tack it on the end if (strpos($e, '__keep__') !== false) { $out = new ocp_tempcode(); foreach ($explode as $i => $bit) { if ($i != 0) { $out->attach(symbol_tempcode('KEEP', NULL, array(ENTITY_ESCAPED))); } if ($GLOBALS['XSS_DETECT']) { ocp_mark_as_escaped($bit); } $out->attach($bit); } } $e = $out->evaluate(); if (strpos($e, '__keep1__') !== false) { $explode = explode('__keep1__', $e); $out = new ocp_tempcode(); foreach ($explode as $i => $bit) { if ($i != 0) { $out->attach(symbol_tempcode('KEEP', array('1'), array(ENTITY_ESCAPED))); } if ($GLOBALS['XSS_DETECT']) { ocp_mark_as_escaped($bit); } $out->attach($bit); } } return $out; }
/** * The UI to create an automated what's new newsletter. * * @return tempcode The UI */ function automatic_whats_new() { $GLOBALS['HELPER_PANEL_PIC'] = 'pagepics/newsletter_from_changes'; $title = get_page_title('NEW_CONTENT'); $lang = choose_language($title); if (is_object($lang)) { return $lang; } if (post_param('message', '') != '') { return $this->send_gui(post_param('message')); } $_hooks = find_all_hooks('modules', 'admin_newsletter'); $chosen_content = post_param_integer('chosen_content', 0); if ($chosen_content == 0) { require_code('form_templates'); require_lang('menus'); $fields = new ocp_tempcode(); $_cutoff_time = get_value('newsletter_whatsnew'); $cutoff_time = is_null($_cutoff_time) ? NULL : intval($_cutoff_time); if (is_null($cutoff_time)) { $cutoff_time = time() - 60 * 60 * 24 * 365 * 3; } $fields->attach(form_input_date(do_lang_tempcode('CUTOFF_DATE'), do_lang_tempcode('DESCRIPTION_CUTOFF_DATE'), 'cutoff', false, false, true, $cutoff_time, 3, intval(date('Y')) - 3, NULL, true)); //$fields->attach(do_template('FORM_SCREEN_FIELD_SPACER',array('TITLE'=>do_lang_tempcode('CONTENT')))); $fields->attach(form_input_tick(do_lang_tempcode('EMBED_FULL_ARTICLES'), do_lang_tempcode('DESCRIPTION_EMBED_FULL_ARTICLES'), 'in_full', post_param_integer('in_full', 0) == 1)); //$_fields=array(); $chosen_categories = ''; foreach (array_keys($_hooks) as $hook) { require_code('hooks/modules/admin_newsletter/' . filter_naughty_harsh($hook)); $object = object_factory('Hook_whats_news_' . filter_naughty_harsh($hook), true); if (is_null($object)) { continue; } $done = false; if (method_exists($object, 'choose_categories')) { list($cats, $_title) = $object->choose_categories(); //$field=form_input_multi_list($_title,'','whatsnew_'.$hook.'_filter',$cats); if (is_object($cats)) { $cats = $cats->evaluate($lang); } $matches = array(); $num_matches = preg_match_all('#<option [^>]*value="([^"]*)"[^>]*>([^<]*)</option>#', $cats, $matches); if ($num_matches < 500) { for ($i = 0; $i < $num_matches; $i++) { $hook_result = $object->run(0, $lang, $matches[1][$i]); if ($hook_result == array()) { continue; } list($hook_content, $_title) = $hook_result; if (!$hook_content->is_empty()) { $decoded = @html_entity_decode($matches[2][$i], ENT_QUOTES, get_charset()); $chosen_categories .= $_title . ': ' . trim($decoded) . ' [' . $hook . '/' . $matches[1][$i] . "]\n"; } } $done = true; } } if (!$done) { $new = $object->run(0, $lang, ''); if ($new != array()) { list($hook_content, $_title) = $new; if (!$hook_content->is_empty()) { //$field=form_input_tick($_title,'','whatsnew_'.$hook.'_include',false); $chosen_categories .= $_title . ' [' . $hook . "]\n"; } } } //$_fields[$_title]=$field; } /*ksort($_fields); foreach ($_fields as $field) { $fields->attach($field); }*/ $fields->attach(form_input_huge(do_lang_tempcode('CONTENT'), do_lang('NEWSLETTER_CONTENT_SELECT'), 'chosen_categories', $chosen_categories, true)); $hidden = new ocp_tempcode(); $hidden->attach(form_input_hidden('chosen_content', '1')); if (cron_installed()) { $periodic_options = new ocp_tempcode(); $current_periodic_newsletters = $GLOBALS['SITE_DB']->query_select('newsletter_periodic', array('*')); if (count($current_periodic_newsletters) == 0) { $extra_help = do_lang('PERIODIC_NEWSLETTER_EMPTY'); $periodic_choice_name = do_lang('PERIODIC_CREATE'); $periodic_choice_help = do_lang('PERIODIC_CREATE_HELP'); $periodic_options->attach(form_input_list_entry('no_change', true, do_lang('DONT_MAKE_PERIODIC_NEWSLETTER'), false, false)); $periodic_options->attach(form_input_list_entry('make_periodic', false, do_lang('MAKE_PERIODIC_NEWSLETTER'), false, false)); } else { $extra_help = do_lang('PERIODIC_NEWSLETTER_EXISTS'); $periodic_choice_name = do_lang('PERIODIC_REPLACE'); $periodic_choice_help = do_lang('PERIODIC_REPLACE_HELP'); $periodic_options->attach(form_input_list_entry('no_change', true, do_lang('LEAVE_PERIODIC_NEWSLETTER'), false, false)); $periodic_options->attach(form_input_list_entry('make_periodic', false, do_lang('MAKE_PERIODIC_NEWSLETTER'), false, false)); foreach ($current_periodic_newsletters as $current_periodic_newsletter) { $periodic_options->attach(form_input_list_entry('remove_existing_' . strval($current_periodic_newsletter['id']), false, do_lang('REMOVE_PERIODIC', $current_periodic_newsletter['np_subject'], strval($current_periodic_newsletter['id'])), false, false)); $periodic_options->attach(form_input_list_entry('replace_existing_' . strval($current_periodic_newsletter['id']), false, do_lang('REPLACE_PERIODIC', $current_periodic_newsletter['np_subject'], strval($current_periodic_newsletter['id'])), false, false)); } } $fields->attach(do_template('FORM_SCREEN_FIELD_SPACER', array('TITLE' => do_lang('PERIODIC_NEWSLETTER_SETTINGS'), 'HELP' => do_lang('PERIODIC_NEWSLETTER_HELP', $extra_help)))); $fields->attach(form_input_list($periodic_choice_name, $periodic_choice_help, 'periodic_choice', $periodic_options, NULL, false, false)); } return do_template('FORM_SCREEN', array('SKIP_VALIDATION' => true, 'HIDDEN' => $hidden, 'TITLE' => $title, 'TEXT' => do_lang_tempcode('SELECT_CATEGORIES_WANTED'), 'FIELDS' => $fields, 'SUBMIT_NAME' => do_lang_tempcode('NEXT'), 'URL' => get_self_url(false, false, array('lang' => $lang)))); } else { $cutoff_time = get_input_date('cutoff'); } $matches = array(); // Bit of a hack, but we include the remove option here for simplicity // It has a confirm screen if (preg_match('#^remove\\_existing\\_(\\d+)$#', post_param('periodic_choice', ''), $matches) != 0) { $hidden = new ocp_tempcode(); $hidden->attach(form_input_hidden('chosen_content', '1')); $hidden->attach(form_input_hidden('periodic_choice', 'periodic_remove_confirmed_' . $matches[1])); return do_template('PERIODIC_NEWSLETTER_REMOVE', array('TITLE' => get_page_title('REMOVE_PERIODIC_NEWSLETTER'), 'URL' => get_self_url(), 'HIDDEN' => $hidden)); } // It has an actualiser if (preg_match('#^periodic\\_remove\\_confirmed\\_(\\d+)$#', post_param('periodic_choice', ''), $matches) != 0) { $GLOBALS['SITE_DB']->query_delete('newsletter_periodic', array('id' => intval($matches[1])), '', 1); // We redirect back to the admin_newsletter main page $url = build_url(array('page' => 'admin_newsletter', 'type' => 'misc', 'redirected' => '1'), get_module_zone('admin_newsletter')); return redirect_screen(do_lang('PERIODIC_REMOVED'), $url, do_lang('PERIODIC_REMOVED_TEXT')); } $in_full = post_param_integer('in_full', 0) == 1; $chosen_categories = post_param('chosen_categories'); $message = $this->generate_whats_new_comcode($chosen_categories, $in_full, $lang, $cutoff_time); return $this->send_gui($message); }
/** * Perform a transaction. * * @param ?ID_TEXT The transaction ID (NULL: generate one) * @param SHORT_TEXT Cardholder name * @param SHORT_TEXT Card number * @param SHORT_TEXT Transaction amount * @param SHORT_TEXT Card Expiry date * @param integer Card Issue number * @param SHORT_TEXT Card Start date * @param SHORT_TEXT Card Type * @set "Visa" "Master Card" "Switch" "UK Maestro" "Maestro" "Solo" "Delta" "American Express" "Diners Card" "JCB" * @param SHORT_TEXT Card CV2 number (security number) * @param ?integer The subscription length in the units. (NULL: not a subscription) * @param ?ID_TEXT The length units. (NULL: not a subscription) * @set d w m y * @return array A tuple: success (boolean), trans-id (string), message (string), raw message (string) */ function do_transaction($trans_id, $name, $card_number, $amount, $expiry_date, $issue_number, $start_date, $card_type, $cv2, $length = NULL, $length_units = NULL) { if (is_null($trans_id)) { $trans_id = $this->generate_trans_id(); } $username = $this->_get_username(); $password_2 = get_option('vpn_password'); $digest = md5($trans_id . strval($amount) . get_option('ipn_password')); $options = 'currency=' . get_option('currency') . ',card_type=' . str_replace(',', '', $card_type) . ',digest=' . $digest . ',cv2=' . strval(intval($cv2)); if (ecommerce_test_mode()) { $options .= ',test_status=true'; } if (!is_null($length)) { list($length_units_2, $first_repeat) = $this->_translate_subscription_details($length, $length_units); $options .= ',repeat=' . $first_repeat . '/' . $length_units_2 . '/0/' . $amount; } require_lang('ecommerce'); require_code('xmlrpc'); $result = xml_rpc('https://www.secpay.com:443/secxmlrpc/make_call', 'SECVPN.validateCardFull', array($username, $password_2, $trans_id, get_ip_address(), $name, $card_number, $amount, $expiry_date, $issue_number, $start_date, '', '', '', $options)); $pos_1 = strpos($result, '<value>'); if ($pos_1 === false) { fatal_exit(do_lang('INTERNAL_ERROR')); } $pos_2 = strpos($result, '</value>'); $value = @html_entity_decode(trim(substr($result, $pos_1 + 7, $pos_2 - $pos_1 - 7)), ENT_QUOTES, get_charset()); if (substr($value, 0, 1) == '?') { $value = substr($value, 1); } $_map = explode('&', $value); $map = array(); foreach ($_map as $x) { $explode = explode('=', $x); if (count($explode) == 2) { $map[$explode[0]] = $explode[1]; } } $success = array_key_exists('code', $map) && ($map['code'] == 'A' || $map['code'] == 'P:P'); $message_raw = array_key_exists('message', $map) ? $map['message'] : ''; $message = $success ? do_lang('ACCEPTED_MESSAGE', $message_raw) : do_lang('DECLINED_MESSAGE', $message_raw); $purchase_id = post_param_integer('customfld1', '-1'); if (addon_installed('shopping')) { $this->store_shipping_address($purchase_id); } return array($success, $trans_id, $message, $message_raw); }
/** * Make a string uppercase, with utf-8 awareness where possible/required. * * @param string Subject. * @return string Result. */ function ocp_mb_strtoupper($in) { if (strtoupper(get_charset()) != 'utf-8') { return strtoupper($in); } if (function_exists('mb_strtoupper')) { return mb_strtoupper($in); } return strtoupper($in); }
$page_contents = file_get_contents($path); $matches = array(); if (preg_match('#\\[title[^\\]]*\\]#', $page_contents, $matches) != 0) { $start = strpos($page_contents, $matches[0]) + strlen($matches[0]); $end = strpos($page_contents, '[/title]', $start); $_title = comcode_to_tempcode(substr($page_contents, $start, $end - $start), NULL, true); $title = strip_tags(@html_entity_decode($_title->evaluate(), ENT_QUOTES, get_charset())); } } elseif (substr($page_type, 0, 4) == 'html') { $path = zone_black_magic_filterer((strpos($page_type, '_custom') !== false ? get_custom_file_base() : get_file_base()) . '/' . filter_naughty($zone) . '/pages/' . filter_naughty($page_type) . '/' . $page . '.htm'); $page_contents = file_get_contents($path); $matches = array(); if (preg_match('#\\<title[^\\>]*\\>#', $page_contents, $matches) != 0) { $start = strpos($page_contents, $matches[0]) + strlen($matches[0]); $end = strpos($page_contents, '</title>', $start); $title = strip_tags(@html_entity_decode(substr($page_contents, $start, $end - $start), ENT_QUOTES, get_charset())); } } $temp = '<DT><A HREF="' . escape_html($url->evaluate()) . '">' . escape_html($title) . '</A>'; $_pages[$title] = $temp; } elseif (count($entrypoints) != 0) { foreach ($entrypoints as $entrypoint => $title) { if ($entrypoint == '!') { $url = build_url(array('page' => $page), $zone, NULL, false, false, true); } else { $url = build_url(array('page' => $page, 'type' => $entrypoint), $zone, NULL, false, false, true); } $_entrypoints[$title] = '<DT><A HREF="' . escape_html($url->evaluate()) . '">' . do_lang($title) . '</A>'; } //ksort($_entrypoints); $url = new ocp_tempcode();
function renderPage() { $LINKSDB = new LinkDB($GLOBALS['config']['DATASTORE'], isLoggedIn(), $GLOBALS['config']['HIDE_PUBLIC_LINKS'], $GLOBALS['redirector'], $GLOBALS['config']['REDIRECTOR_URLENCODE']); $updater = new Updater(read_updates_file($GLOBALS['config']['UPDATES_FILE']), $GLOBALS, $LINKSDB, isLoggedIn()); try { $newUpdates = $updater->update(); if (!empty($newUpdates)) { write_updates_file($GLOBALS['config']['UPDATES_FILE'], $updater->getDoneUpdates()); } } catch (Exception $e) { die($e->getMessage()); } $PAGE = new PageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('privateLinkcount', count_private($LINKSDB)); // Determine which page will be rendered. $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $targetPage = Router::findPage($query, $_GET, isLoggedIn()); // Call plugin hooks for header, footer and includes, specifying which page will be rendered. // Then assign generated data to RainTPL. $common_hooks = array('includes', 'header', 'footer'); $pluginManager = PluginManager::getInstance(); foreach ($common_hooks as $name) { $plugin_data = array(); $pluginManager->executeHooks('render_' . $name, $plugin_data, array('target' => $targetPage, 'loggedin' => isLoggedIn())); $PAGE->assign('plugins_' . $name, $plugin_data); } // -------- Display login form. if ($targetPage == Router::$PAGE_LOGIN) { if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli $token = ''; if (ban_canLogin()) { $token = getToken(); } // Do not waste token generation if not useful. $PAGE->assign('token', $token); if (isset($_GET['username'])) { $PAGE->assign('username', escape($_GET['username'])); } $PAGE->assign('returnurl', isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''); $PAGE->renderPage('loginform'); exit; } // -------- User wants to logout. if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) { invalidateCaches($GLOBALS['config']['PAGECACHE']); logout(); header('Location: ?'); exit; } // -------- Picture wall if ($targetPage == Router::$PAGE_PICWALL) { // Optionally filter the results: $links = $LINKSDB->filterSearch($_GET); $linksToDisplay = array(); // Get only links which have a thumbnail. foreach ($links as $link) { $permalink = '?' . escape(smallhash($link['linkdate'])); $thumb = lazyThumbnail($link['url'], $permalink); if ($thumb != '') { $link['thumbnail'] = $thumb; // Thumbnail HTML code. $linksToDisplay[] = $link; // Add to array. } } $data = array('linksToDisplay' => $linksToDisplay); $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('picwall'); exit; } // -------- Tag cloud if ($targetPage == Router::$PAGE_TAGCLOUD) { $tags = $LINKSDB->allTags(); // We sort tags alphabetically, then choose a font size according to count. // First, find max value. $maxcount = 0; foreach ($tags as $value) { $maxcount = max($maxcount, $value); } // Sort tags alphabetically: case insensitive, support locale if avalaible. uksort($tags, function ($a, $b) { // Collator is part of PHP intl. if (class_exists('Collator')) { $c = new Collator(setlocale(LC_COLLATE, 0)); if (!intl_is_failure(intl_get_error_code())) { return $c->compare($a, $b); } } return strcasecmp($a, $b); }); $tagList = array(); foreach ($tags as $key => $value) { // Tag font size scaling: // default 15 and 30 logarithm bases affect scaling, // 22 and 6 are arbitrary font sizes for max and min sizes. $size = log($value, 15) / log($maxcount, 30) * 2.2 + 0.8; $tagList[$key] = array('count' => $value, 'size' => number_format($size, 2, '.', '')); } $data = array('tags' => $tagList); $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tagcloud'); exit; } // Daily page. if ($targetPage == Router::$PAGE_DAILY) { showDaily($PAGE, $LINKSDB); } // ATOM and RSS feed. if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) { $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM; header('Content-Type: application/' . $feedType . '+xml; charset=utf-8'); // Cache system $query = $_SERVER['QUERY_STRING']; $cache = new CachedPage($GLOBALS['config']['PAGECACHE'], page_url($_SERVER), startsWith($query, 'do=' . $targetPage) && !isLoggedIn()); $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } // Generate data. $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn()); $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); $feedGenerator->setHideDates($GLOBALS['config']['HIDE_TIMESTAMPS'] && !isLoggedIn()); $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS']); if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) { $feedGenerator->setPubsubhubUrl($GLOBALS['config']['PUBSUBHUB_URL']); } $data = $feedGenerator->buildData(); // Process plugin hook. $pluginManager = PluginManager::getInstance(); $pluginManager->executeHooks('render_feed', $data, array('loggedin' => isLoggedIn(), 'target' => $targetPage)); // Render the template. $PAGE->assignAll($data); $PAGE->renderPage('feed.' . $feedType); $cache->cache(ob_get_contents()); ob_end_flush(); exit; } // Display openseach plugin (XML) if ($targetPage == Router::$PAGE_OPENSEARCH) { header('Content-Type: application/xml; charset=utf-8'); $PAGE->assign('serverurl', index_url($_SERVER)); $PAGE->renderPage('opensearch'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags=' . urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['addtag'])) { unset($params['addtag']); } // Check if this tag is already in the search query and ignore it if it is. // Each tag is always separated by a space if (isset($params['searchtags'])) { $current_tags = explode(' ', $params['searchtags']); } else { $current_tags = array(); } $addtag = true; foreach ($current_tags as $value) { if ($value === $_GET['addtag']) { $addtag = false; break; } } // Append the tag if necessary if (empty($params['searchtags'])) { $params['searchtags'] = trim($_GET['addtag']); } else { if ($addtag) { $params['searchtags'] = trim($params['searchtags']) . ' ' . trim($_GET['addtag']); } } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) header('Location: ?' . http_build_query($params)); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['removetag'])) { unset($params['removetag']); } if (isset($params['searchtags'])) { $tags = explode(' ', $params['searchtags']); // Remove value from array $tags. $tags = array_diff($tags, array($_GET['removetag'])); $params['searchtags'] = implode(' ', $tags); if (empty($params['searchtags'])) { unset($params['searchtags']); } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?' . http_build_query($params)); exit; } // -------- User wants to change the number of links per page (linksperpage=...) if (isset($_GET['linksperpage'])) { if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE'] = abs(intval($_GET['linksperpage'])); } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('linksperpage'))); exit; } // -------- User wants to see only private links (toggle) if (isset($_GET['privateonly'])) { if (empty($_SESSION['privateonly'])) { $_SESSION['privateonly'] = 1; // See only private links } else { unset($_SESSION['privateonly']); // See all links } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('privateonly'))); exit; } // -------- Handle other actions allowed for non-logged in users: if (!isLoggedIn()) { // User tries to post new link but is not logged in: // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header('Location: ?do=login&post=' . urlencode($_GET['post']) . (!empty($_GET['title']) ? '&title=' . urlencode($_GET['title']) : '') . (!empty($_GET['description']) ? '&description=' . urlencode($_GET['description']) : '') . (!empty($_GET['source']) ? '&source=' . urlencode($_GET['source']) : '')); // Redirect to login page, then back to post link. exit; } showLinkList($PAGE, $LINKSDB); if (isset($_GET['edit_link'])) { header('Location: ?do=login&edit_link=' . escape($_GET['edit_link'])); exit; } exit; // Never remove this one! All operations below are reserved for logged in user. } // -------- All other functions are reserved for the registered user: // -------- Display the Tools menu if requested (import/export/bookmarklet...) if ($targetPage == Router::$PAGE_TOOLS) { $data = array('pageabsaddr' => index_url($_SERVER)); $pluginManager->executeHooks('render_tools', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tools'); exit; } // -------- User wants to change his/her password. if ($targetPage == Router::$PAGE_CHANGEPASSWORD) { if ($GLOBALS['config']['OPEN_SHAARLI']) { die('You are not supposed to change a password on an Open Shaarli.'); } if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! // Make sure old password is correct. $oldhash = sha1($_POST['oldpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); if ($oldhash != $GLOBALS['hash']) { echo '<script>alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } // Save new password $GLOBALS['salt'] = sha1(uniqid('', true) . '_' . mt_rand()); // Salt renders rainbow-tables attacks useless. $GLOBALS['hash'] = sha1($_POST['setpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after changing password.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('token', getToken()); $PAGE->renderPage('changepassword'); exit; } } // -------- User wants to change configuration if ($targetPage == Router::$PAGE_CONFIGURE) { if (!empty($_POST['title'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); // Go away! } $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city']) && isTimeZoneValid($_POST['continent'], $_POST['city'])) { $tz = $_POST['continent'] . '/' . $_POST['city']; } $GLOBALS['timezone'] = $tz; $GLOBALS['title'] = $_POST['title']; $GLOBALS['titleLink'] = $_POST['titleLink']; $GLOBALS['redirector'] = $_POST['redirector']; $GLOBALS['disablesessionprotection'] = !empty($_POST['disablesessionprotection']); $GLOBALS['privateLinkByDefault'] = !empty($_POST['privateLinkByDefault']); $GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = !empty($_POST['enableRssPermalinks']); $GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']); $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after configuration update.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('token', getToken()); $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title']); $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']); list($timezone_form, $timezone_js) = generateTimeZoneForm($GLOBALS['timezone']); $PAGE->assign('timezone_form', $timezone_form); $PAGE->assign('timezone_js', $timezone_js); $PAGE->renderPage('configure'); exit; } } // -------- User wants to rename a tag or delete it if ($targetPage == Router::$PAGE_CHANGETAG) { if (empty($_POST['fromtag']) || empty($_POST['totag']) && isset($_POST['renametag'])) { $PAGE->assign('token', getToken()); $PAGE->assign('tags', $LINKSDB->allTags()); $PAGE->renderPage('changetag'); exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Delete a tag: if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); unset($tags[array_search($needle, $tags)]); // Remove tag. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); echo '<script>alert("Tag was removed from ' . count($linksToAlter) . ' links.");document.location=\'?\';</script>'; exit; } // Rename a tag: if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); $tags[array_search($needle, $tags)] = trim($_POST['totag']); // Replace tags value. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. echo '<script>alert("Tag was renamed in ' . count($linksToAlter) . ' links.");document.location=\'?searchtags=' . urlencode($_POST['totag']) . '\';</script>'; exit; } } // -------- User wants to add a link without using the bookmarklet: Show form. if ($targetPage == Router::$PAGE_ADDLINK) { $PAGE->renderPage('addlink'); exit; } // -------- User clicked the "Save" button when editing a link: Save link to database. if (isset($_POST['save_edit'])) { // Go away! if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Remove multiple spaces. $tags = trim(preg_replace('/\\s\\s+/', ' ', $_POST['lf_tags'])); // Remove first '-' char in tags. $tags = preg_replace('/(^| )\\-/', '$1', $tags); // Remove duplicates. $tags = implode(' ', array_unique(explode(' ', $tags))); $linkdate = $_POST['lf_linkdate']; $url = trim($_POST['lf_url']); if (!startsWith($url, 'http:') && !startsWith($url, 'https:') && !startsWith($url, 'ftp:') && !startsWith($url, 'magnet:') && !startsWith($url, '?') && !startsWith($url, 'javascript:')) { $url = 'http://' . $url; } $link = array('title' => trim($_POST['lf_title']), 'url' => $url, 'description' => $_POST['lf_description'], 'private' => isset($_POST['lf_private']) ? 1 : 0, 'linkdate' => $linkdate, 'tags' => str_replace(',', ' ', $tags)); // If title is empty, use the URL as title. if ($link['title'] == '') { $link['title'] = $link['url']; } $pluginManager->executeHooks('save_link', $link); $LINKSDB[$linkdate] = $link; $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); pubsubhub(); // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = !empty($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); // Scroll to the link which has been edited. $location .= '#' . smallHash($_POST['lf_linkdate']); // After saving the link, redirect to the page the user was on. header('Location: ' . $location); exit; } // -------- User clicked the "Cancel" button when editing a link. if (isset($_POST['cancel_edit'])) { // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $returnurl .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); header('Location: ' . $returnurl); // After canceling, redirect to the page the user was on. exit; } // -------- User clicked the "Delete" button when editing a link: Delete link from database. if (isset($_POST['delete_link'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // We do not need to ask for confirmation: // - confirmation is handled by JavaScript // - we are protected from XSRF by the token. $linkdate = $_POST['lf_linkdate']; $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); unset($LINKSDB[$linkdate]); $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } // Pick where we're going to redirect // ============================================================= // Basically, we can't redirect to where we were previously if it was a permalink // or an edit_link, because it would 404. // Cases: // - / : nothing in $_GET, redirect to self // - /?page : redirect to self // - /?searchterm : redirect to self (there might be other links) // - /?searchtags : redirect to self // - /permalink : redirect to / (the link does not exist anymore) // - /?edit_link : redirect to / (the link does not exist anymore) // PHP treats the permalink as a $_GET variable, so we need to check if every condition for self // redirect is not satisfied, and only then redirect to / $location = "?"; // Self redirection if (count($_GET) == 0 || isset($_GET['page']) || isset($_GET['searchterm']) || isset($_GET['searchtags'])) { if (isset($_POST['returnurl'])) { $location = $_POST['returnurl']; // Handle redirects given by the form } else { $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('delete_link')); } } header('Location: ' . $location); // After deleting the link, redirect to appropriate location exit; } // -------- User clicked the "EDIT" button on a link: Display link edit form. if (isset($_GET['edit_link'])) { $link = $LINKSDB[$_GET['edit_link']]; // Read database if (!$link) { header('Location: ?'); exit; } // Link not found in database. $data = array('link' => $link, 'link_is_new' => false, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { $url = cleanup_url($_GET['post']); $link_is_new = false; // Check if URL is not already in database (in this case, we will edit the existing link) $link = $LINKSDB->getLinkFromUrl($url); if (!$link) { $link_is_new = true; $linkdate = strval(date('Ymd_His')); // Get title if it was provided in URL (by the bookmarklet). $title = empty($_GET['title']) ? '' : escape($_GET['title']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] $description = empty($_GET['description']) ? '' : escape($_GET['description']); $tags = empty($_GET['tags']) ? '' : escape($_GET['tags']); $private = !empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0; // If this is an HTTP(S) link, we try go get the page to extract the title (otherwise we will to straight to the edit form.) if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { // Short timeout to keep the application responsive list($headers, $content) = get_http_response($url, 4); if (strpos($headers[0], '200 OK') !== false) { // Retrieve charset. $charset = get_charset($headers, $content); // Extract title. $title = html_extract_title($content); // Re-encode title in utf-8 if necessary. if (!empty($title) && strtolower($charset) != 'utf-8') { $title = mb_convert_encoding($title, 'utf-8', $charset); } } } if ($url == '') { $url = '?' . smallHash($linkdate); $title = 'Note: '; } $url = escape($url); $title = escape($title); $link = array('linkdate' => $linkdate, 'title' => $title, 'url' => $url, 'description' => $description, 'tags' => $tags, 'private' => $private); } $data = array('link' => $link, 'link_is_new' => $link_is_new, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'source' => isset($_GET['source']) ? $_GET['source'] : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } if ($targetPage == Router::$PAGE_EXPORT) { // Export links as a Netscape Bookmarks file if (empty($_GET['selection'])) { $PAGE->renderPage('export'); exit; } // export as bookmarks_(all|private|public)_YYYYmmdd_HHMMSS.html $selection = $_GET['selection']; if (isset($_GET['prepend_note_url'])) { $prependNoteUrl = $_GET['prepend_note_url']; } else { $prependNoteUrl = false; } try { $PAGE->assign('links', NetscapeBookmarkUtils::filterAndFormat($LINKSDB, $selection, $prependNoteUrl, index_url($_SERVER))); } catch (Exception $exc) { header('Content-Type: text/plain; charset=utf-8'); echo $exc->getMessage(); exit; } $now = new DateTime(); header('Content-Type: text/html; charset=utf-8'); header('Content-disposition: attachment; filename=bookmarks_' . $selection . '_' . $now->format(LinkDB::LINK_DATE_FORMAT) . '.html'); $PAGE->assign('date', $now->format(DateTime::RFC822)); $PAGE->assign('eol', PHP_EOL); $PAGE->assign('selection', $selection); $PAGE->renderPage('export.bookmarks'); exit; } // -------- User is uploading a file for import if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=upload')) { // If file is too big, some form field may be missing. if (!isset($_POST['token']) || !isset($_FILES) || isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { $returnurl = empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER']; echo '<script>alert("The file you are trying to upload is probably bigger than what this webserver can accept (' . getMaxFileSize() . ' bytes). Please upload in smaller chunks.");document.location=\'' . escape($returnurl) . '\';</script>'; exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } importFile($LINKSDB); exit; } // -------- Show upload/import dialog: if ($targetPage == Router::$PAGE_IMPORT) { $PAGE->assign('token', getToken()); $PAGE->assign('maxfilesize', getMaxFileSize()); $PAGE->renderPage('import'); exit; } // Plugin administration page if ($targetPage == Router::$PAGE_PLUGINSADMIN) { $pluginMeta = $pluginManager->getPluginsMeta(); // Split plugins into 2 arrays: ordered enabled plugins and disabled. $enabledPlugins = array_filter($pluginMeta, function ($v) { return $v['order'] !== false; }); // Load parameters. $enabledPlugins = load_plugin_parameter_values($enabledPlugins, $GLOBALS['plugins']); uasort($enabledPlugins, function ($a, $b) { return $a['order'] - $b['order']; }); $disabledPlugins = array_filter($pluginMeta, function ($v) { return $v['order'] === false; }); $PAGE->assign('enabledPlugins', $enabledPlugins); $PAGE->assign('disabledPlugins', $disabledPlugins); $PAGE->renderPage('pluginsadmin'); exit; } // Plugin administration form action if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) { try { if (isset($_POST['parameters_form'])) { unset($_POST['parameters_form']); foreach ($_POST as $param => $value) { $GLOBALS['plugins'][$param] = escape($value); } } else { $GLOBALS['config']['ENABLED_PLUGINS'] = save_plugin_config($_POST); } writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while saving plugin configuration:.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=' . Router::$PAGE_PLUGINSADMIN . '\';</script>'; exit; } header('Location: ?do=' . Router::$PAGE_PLUGINSADMIN); exit; } // -------- Otherwise, simply display search form and links: showLinkList($PAGE, $LINKSDB); exit; }
/** * Create a data-mash from the file at a URL. This is data useful for the search engine. * * @param URLPATH The URL to make a data-mash of, or a filename if $data isn't blank * @param ?string Data (NULL: use URL) * @param ?ID_TEXT File extension (NULL: get from URL) * @param boolean Whether a direct file path was given instead of a URL * @return LONG_TEXT The data-mash */ function create_data_mash($url, $data = NULL, $extension = NULL, $direct_path = false) { if (function_exists('set_time_limit')) { @set_time_limit(300); } if (get_value('no_dload_search_index') === '1') { return ''; } if (running_script('stress_test_loader')) { return ''; } if (function_exists('memory_get_usage') && ini_get('memory_usage') == '8M') { return ''; } // Some cowardice... don't want to tempt fate if (is_null($extension)) { $extension = get_file_extension($url); } $tmp_file = NULL; if (is_null($data)) { if ($direct_path || url_is_local($url)) { $actual_path = $direct_path ? $url : get_custom_file_base() . '/' . rawurldecode($url); if (file_exists($actual_path)) { switch ($extension) { case 'zip': case 'odt': case 'odp': case 'docx': case 'tar': case 'gz': if (filesize($actual_path) > 1024 * 1024 * 3) { return ''; } break; } $tmp_file = $actual_path; if (filesize($actual_path) > 1024 * 1024 * 3) { $myfile = fopen($actual_path, 'rb'); $data = ''; for ($i = 0; $i < 384; $i++) { $data .= fread($myfile, 8192); } fclose($myfile); } else { $data = file_get_contents($actual_path); } } else { $data = ''; } } else { switch ($extension) { case 'txt': case '1st': case 'rtf': case 'pdf': case 'htm': case 'html': case 'xml': case 'doc': case 'xls': break; // Continue through to download good stuff // Continue through to download good stuff default: return ''; // Don't download, it's not worth it break; } $data = http_download_file($url, 3 * 1024 * 1024, false); // 3MB is enough if (is_null($data)) { return ''; } } } $mash = ''; switch ($extension) { case 'zip': case 'odt': case 'odp': case 'docx': require_code('m_zip'); $tmp_file = ocp_tempnam('dcdm_'); $myfile2 = fopen($tmp_file, 'wb'); fwrite($myfile2, $data); fclose($myfile2); $myfile_zip = @zip_open($tmp_file); if (!is_integer($myfile_zip)) { while (($entry = @zip_read($myfile_zip)) !== false) { $entry_name = @zip_entry_name($entry); $mash .= ' ' . $entry_name; if (substr($entry_name, -1) != '/') { $_entry = @zip_entry_open($myfile_zip, $entry); if ($_entry !== false) { $file_data = ''; while (true) { $it = @zip_entry_read($entry, 1024); if ($it === false || $it == '') { break; } $file_data .= $it; if (strlen($file_data) >= 3 * 1024 * 1024) { break; } // 3MB is enough } @zip_entry_close($entry); $mash .= ' ' . create_data_mash($entry_name, $file_data); if (strlen($mash) >= 3 * 1024 * 1024) { break; } // 3MB is enough } } } @zip_close($myfile_zip); } @unlink($tmp_file); break; case 'tar': require_code('tar'); $tmp_file = ocp_tempnam('dcdm_'); $myfile = fopen($tmp_file, 'wb'); fwrite($myfile, $data); fclose($myfile); $myfile_tar = tar_open($tmp_file, 'rb'); if ($myfile_tar !== false) { $directory = tar_get_directory($myfile_tar); foreach ($directory as $entry) { $entry_name = $entry['path']; $mash .= ' ' . $entry_name; if ($entry['size'] >= 3 * 1024 * 1024) { continue; } // 3MB is enough $_entrya = tar_get_file($myfile_tar, $entry['path']); if (!is_null($_entrya)) { $mash .= ' ' . create_data_mash($entry_name, $_entrya['data']); if (strlen($mash) >= 3 * 1024 * 1024) { break; } // 3MB is enough } } tar_close($myfile_tar); } @unlink($tmp_file); break; case 'gz': if (function_exists('gzopen')) { if (function_exists('gzeof')) { if (function_exists('gzread')) { $tmp_file = ocp_tempnam('dcdm_'); $myfile = fopen($tmp_file, 'wb'); fwrite($myfile, $data); fclose($myfile); $myfile = gzopen($tmp_file, 'rb'); if ($myfile !== false) { $file_data = ''; while (!gzeof($myfile)) { $it = gzread($myfile, 1024); $file_data .= $it; if (strlen($file_data) >= 3 * 1024 * 1024) { break; } // 3MB is enough } $mash = ' ' . create_data_mash(preg_replace('#\\.gz#i', '', $url), $file_data); } @unlink($tmp_file); } } } break; case 'txt': case '1st': $mash .= $data; break; case 'rtf': $len = strlen($data); $skipping_section_depth = 0; $escape = false; for ($i = 0; $i < $len; $i++) { $byte = $data[$i]; if (!$escape && $byte == "\\") { $escape = true; } elseif (!$escape && $byte == '{') { if ($skipping_section_depth != 0) { $skipping_section_depth++; } } elseif (!$escape && $byte == '}') { if ($skipping_section_depth != 0) { $skipping_section_depth--; } } elseif ($escape && $byte != '{' && $byte != "\\" && $byte != '}') { $end_pos_1 = strpos($data, "\\", $i + 1); if ($end_pos_1 === false) { $end_pos_1 = $len; } $end_pos_2 = strpos($data, chr(10), $i + 1); if ($end_pos_2 === false) { $end_pos_2 = $len; } $end_pos_3 = strpos($data, ' ', $i + 1); if ($end_pos_3 === false) { $end_pos_3 = $len; } $end_pos_4 = strpos($data, "\t", $i + 1); if ($end_pos_4 === false) { $end_pos_4 = $len; } $end_pos_5 = strpos($data, '{', $i + 1); if ($end_pos_5 === false) { $end_pos_5 = $len; } $end_pos_6 = strpos($data, '}', $i + 1); if ($end_pos_6 === false) { $end_pos_6 = $len; } $end_pos = min($end_pos_1, $end_pos_2, $end_pos_3, $end_pos_4, $end_pos_5, $end_pos_6); $tag = substr($data, $i, $end_pos - $i); $tag = preg_replace('#[\\-0-9]*#', '', $tag); if ($skipping_section_depth == 0 && ($tag == 'pgdsc' || $tag == 'comment' || $tag == 'object' || $tag == 'pict' || $tag == 'stylesheet' || $tag == 'fonttbl')) { $skipping_section_depth = 1; } if ($tag == 'par') { $mash .= chr(10); } $i = $end_pos - 1; $escape = false; } elseif ($skipping_section_depth == 0) { if ($byte != chr(13) && $byte != chr(10)) { $mash .= $byte; } $escape = false; } else { $escape = false; } } break; case 'pdf': if (str_replace(array('on', 'true', 'yes'), array('1', '1', '1'), strtolower(ini_get('safe_mode'))) != '1' && strpos(@ini_get('disable_functions'), 'shell_exec') === false && !is_null($tmp_file)) { $enc = get_charset() == 'utf-8' ? ' -enc UTF-8' : ''; $path = 'pdftohtml -i -noframes -stdout -hidden' . $enc . ' -q -xml ' . @escapeshellarg($tmp_file); if (strpos(strtolower(PHP_OS), 'win') !== false) { if (file_exists(get_file_base() . '/data_custom/pdftohtml.exe')) { $path = '"' . get_file_base() . DIRECTORY_SEPARATOR . 'data_custom' . DIRECTORY_SEPARATOR . '"' . $path; } } $tmp_file_2 = ocp_tempnam('pdfxml_'); @shell_exec($path . ' > ' . $tmp_file_2); $mash = create_data_mash($tmp_file_2, NULL, 'xml', true); @unlink($tmp_file_2); } break; case 'htm': case 'html': $head_patterns = array('#<\\s*script.*<\\s*/\\s*script\\s*>#misU', '#<\\s*link[^<>]*>#misU', '#<\\s*style.*<\\s*/\\s*style\\s*>#misU'); foreach ($head_patterns as $pattern) { $data = preg_replace($pattern, '', $data); } case 'xml': $mash = str_replace(''', '\'', str_replace(' false ', ' ', str_replace(' true ', ' ', @html_entity_decode(preg_replace('#\\<[^\\<\\>]*\\>#', ' ', $data), ENT_QUOTES, get_charset())))); $mash = preg_replace('#Error : Bad \\w+#', '', $mash); break; case 'xls': case 'doc': case 'ppt': case 'hlp': // default: // Binary formats are complex to parse, but whatsmore, as textual tagging isn't used, extraction can be done automatically as all identified text is good. $data = str_replace("", '', $data); // Strip out interleaved nulls because they are used in wide-chars, obscuring the data $mash = ''; $needs_delimiter_next = false; $in_portion = false; $min_length = 10; if ($extension == 'xls') { $min_length = 4; } for ($i = 0; $i < strlen($data); $i++) { $ch = $data[$i]; $chx = 1; $next_ok = _is_valid_data_mash_char($ch); if ($next_ok && !$in_portion) { $x = $ch; for ($j = $i + 1; $j < strlen($data); $j++) { $_ch = $data[$j]; $_next_ok = _is_valid_data_mash_char($_ch); if ($_next_ok) { $x .= $_ch; $chx++; } else { break; } } if (strlen($x) < $min_length || $x == strtoupper($x) || $x == 'Microsoft Word Document' || $x == 'WordDocument' || $x == 'SummaryInformation' || $x == 'DocumentSummaryInformation') { $i = $j; continue; } } if ($next_ok && $in_portion) { $mash .= $ch; } elseif ($next_ok && $chx >= $min_length) { if ($needs_delimiter_next) { $mash .= ' '; $needs_delimiter_next = false; } $mash .= $ch; $in_portion = true; } else { if ($in_portion) { $needs_delimiter_next = true; $in_portion = false; } } } break; } if (strlen($mash) > 1024 * 1024 * 3) { $mash = substr($mash, 0, 1024 * 1024 * 3); } $mash = preg_replace('# +#', ' ', preg_replace('#[^\\w\\d-\\-\']#', ' ', $mash)); if (strlen($mash) > intval(1024 * 1024 * 1 * 0.4)) { $mash = substr($mash, 0, intval(1024 * 1024 * 0.4)); } return $mash; }
/** * Run the loader, to load up field-restrictions from the XML file. */ function go() { if (!addon_installed('xml_fields')) { return; } if (!is_file(get_custom_file_base() . '/data_custom/fields.xml')) { return; } $this->tag_stack = array(); $this->attribute_stack = array(); $this->levels_from_filtered = 0; $this->field_qualification_stack = array('*'); // Create and setup our parser $xml_parser = @xml_parser_create(); if ($xml_parser === false) { return; // PHP5 default build on windows comes with this function disabled, so we need to be able to escape on error } xml_set_object($xml_parser, $this); @xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, get_charset()); xml_set_element_handler($xml_parser, 'startElement', 'endElement'); xml_set_character_data_handler($xml_parser, 'startText'); // Run the parser $data = file_get_contents(get_custom_file_base() . '/data_custom/fields.xml', FILE_TEXT); if (trim($data) == '') { return; } if (@xml_parse($xml_parser, $data, true) == 0) { attach_message('fields.xml: ' . xml_error_string(xml_get_error_code($xml_parser)), 'warn'); return; } @xml_parser_free($xml_parser); }
// Try to decode the mail and display all of its parts. $mail = new Mail_mimeDecode(get_magic_quotes_gpc() ? stripslashes($contents) : $contents); $args['include_bodies'] = true; $args['decode_bodies'] = true; $args['decode_headers'] = false; // the inconv decoding will handle the headers $structure = $mail->decode($args); $smarty->assign("message", display_parts($structure)); $headers = $structure->headers; foreach ($headers as $key => $value) { if (is_array($value)) { foreach ($value as $itemkey => $item) { $headers["{$key}"][$itemkey] = htmlspecialchars(last_ditch_mime_decode(iconv_mime_decode($item, 2, 'utf-8'), get_charset($structure)), ENT_QUOTES, 'utf-8'); } } else { $headers["{$key}"] = htmlspecialchars(last_ditch_mime_decode(iconv_mime_decode($value, 2, 'utf-8'), get_charset($structure)), ENT_QUOTES, 'utf-8'); } } if (isset($headers['content-type'])) { unset($headers['content-type']); } $smarty->assign('headers', $headers); $smarty->assign('sender_email', $sender_email); } else { // Dump the raw contents of the e-mail, making sure to // escape any HTML tags it might contain, so the raw source // gets displayed. $smarty->assign("message", "<pre>" . htmlentities(wordwrap($contents, 70)) . "</pre>"); } $smarty->assign("error", ""); } else {
function renderPage() { $LINKSDB = new LinkDB($GLOBALS['config']['DATASTORE'], isLoggedIn(), $GLOBALS['config']['HIDE_PUBLIC_LINKS'], $GLOBALS['redirector']); $PAGE = new pageBuilder(); // Determine which page will be rendered. $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $targetPage = Router::findPage($query, $_GET, isLoggedIn()); // Call plugin hooks for header, footer and includes, specifying which page will be rendered. // Then assign generated data to RainTPL. $common_hooks = array('header', 'footer', 'includes'); $pluginManager = PluginManager::getInstance(); foreach ($common_hooks as $name) { $plugin_data = array(); $pluginManager->executeHooks('render_' . $name, $plugin_data, array('target' => $targetPage, 'loggedin' => isLoggedIn())); $PAGE->assign('plugins_' . $name, $plugin_data); } // -------- Display login form. if ($targetPage == Router::$PAGE_LOGIN) { if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli $token = ''; if (ban_canLogin()) { $token = getToken(); } // Do not waste token generation if not useful. $PAGE->assign('token', $token); $PAGE->assign('returnurl', isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''); $PAGE->renderPage('loginform'); exit; } // -------- User wants to logout. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=logout')) { invalidateCaches($GLOBALS['config']['PAGECACHE']); logout(); header('Location: ?'); exit; } // -------- Picture wall if ($targetPage == Router::$PAGE_PICWALL) { // Optionally filter the results: if (!empty($_GET['searchterm'])) { $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); } elseif (!empty($_GET['searchtags'])) { $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); } else { $links = $LINKSDB; } $linksToDisplay = array(); // Get only links which have a thumbnail. foreach ($links as $link) { $permalink = '?' . escape(smallhash($link['linkdate'])); $thumb = lazyThumbnail($link['url'], $permalink); if ($thumb != '') { $link['thumbnail'] = $thumb; // Thumbnail HTML code. $linksToDisplay[] = $link; // Add to array. } } $data = array('linkcount' => count($LINKSDB), 'linksToDisplay' => $linksToDisplay); $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('picwall'); exit; } // -------- Tag cloud if ($targetPage == Router::$PAGE_TAGCLOUD) { $tags = $LINKSDB->allTags(); // We sort tags alphabetically, then choose a font size according to count. // First, find max value. $maxcount = 0; foreach ($tags as $key => $value) { $maxcount = max($maxcount, $value); } ksort($tags); $tagList = array(); foreach ($tags as $key => $value) { $tagList[$key] = array('count' => $value, 'size' => log($value, 15) / log($maxcount, 30) * (22 - 6) + 6); } $data = array('linkcount' => count($LINKSDB), 'tags' => $tagList); $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tagcloud'); exit; } // Daily page. if ($targetPage == Router::$PAGE_DAILY) { showDaily($PAGE); } // Display openseach plugin (XML) if ($targetPage == Router::$PAGE_OPENSEARCH) { header('Content-Type: application/xml; charset=utf-8'); $PAGE->assign('serverurl', index_url($_SERVER)); $PAGE->renderPage('opensearch'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags=' . urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['addtag'])) { unset($params['addtag']); } // Check if this tag is already in the search query and ignore it if it is. // Each tag is always separated by a space if (isset($params['searchtags'])) { $current_tags = explode(' ', $params['searchtags']); } else { $current_tags = array(); } $addtag = true; foreach ($current_tags as $value) { if ($value === $_GET['addtag']) { $addtag = false; break; } } // Append the tag if necessary if (empty($params['searchtags'])) { $params['searchtags'] = trim($_GET['addtag']); } else { if ($addtag) { $params['searchtags'] = trim($params['searchtags']) . ' ' . trim($_GET['addtag']); } } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) header('Location: ?' . http_build_query($params)); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['removetag'])) { unset($params['removetag']); } if (isset($params['searchtags'])) { $tags = explode(' ', $params['searchtags']); // Remove value from array $tags. $tags = array_diff($tags, array($_GET['removetag'])); $params['searchtags'] = implode(' ', $tags); if (empty($params['searchtags'])) { unset($params['searchtags']); } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?' . http_build_query($params)); exit; } // -------- User wants to change the number of links per page (linksperpage=...) if (isset($_GET['linksperpage'])) { if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE'] = abs(intval($_GET['linksperpage'])); } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('linksperpage'))); exit; } // -------- User wants to see only private links (toggle) if (isset($_GET['privateonly'])) { if (empty($_SESSION['privateonly'])) { $_SESSION['privateonly'] = 1; // See only private links } else { unset($_SESSION['privateonly']); // See all links } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('privateonly'))); exit; } // -------- Handle other actions allowed for non-logged in users: if (!isLoggedIn()) { // User tries to post new link but is not logged in: // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header('Location: ?do=login&post=' . urlencode($_GET['post']) . (!empty($_GET['title']) ? '&title=' . urlencode($_GET['title']) : '') . (!empty($_GET['description']) ? '&description=' . urlencode($_GET['description']) : '') . (!empty($_GET['source']) ? '&source=' . urlencode($_GET['source']) : '')); // Redirect to login page, then back to post link. exit; } // Same case as above except that user tried to access ?do=addlink without being logged in // Note: passing empty parameters makes Shaarli generate default URLs and descriptions. if (isset($_GET['do']) && $_GET['do'] === 'addlink') { header('Location: ?do=login&post='); exit; } showLinkList($PAGE, $LINKSDB); if (isset($_GET['edit_link'])) { header('Location: ?do=login&edit_link=' . escape($_GET['edit_link'])); exit; } exit; // Never remove this one! All operations below are reserved for logged in user. } // -------- All other functions are reserved for the registered user: // -------- Display the Tools menu if requested (import/export/bookmarklet...) if ($targetPage == Router::$PAGE_TOOLS) { $data = array('linkcount' => count($LINKSDB), 'pageabsaddr' => index_url($_SERVER)); $pluginManager->executeHooks('render_tools', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tools'); exit; } // -------- User wants to change his/her password. if ($targetPage == Router::$PAGE_CHANGEPASSWORD) { if ($GLOBALS['config']['OPEN_SHAARLI']) { die('You are not supposed to change a password on an Open Shaarli.'); } if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! // Make sure old password is correct. $oldhash = sha1($_POST['oldpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); if ($oldhash != $GLOBALS['hash']) { echo '<script>alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } // Save new password $GLOBALS['salt'] = sha1(uniqid('', true) . '_' . mt_rand()); // Salt renders rainbow-tables attacks useless. $GLOBALS['hash'] = sha1($_POST['setpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after changing password.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->renderPage('changepassword'); exit; } } // -------- User wants to change configuration if ($targetPage == Router::$PAGE_CONFIGURE) { if (!empty($_POST['title'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city'])) { if (isTimeZoneValid($_POST['continent'], $_POST['city'])) { $tz = $_POST['continent'] . '/' . $_POST['city']; } } $GLOBALS['timezone'] = $tz; $GLOBALS['title'] = $_POST['title']; $GLOBALS['titleLink'] = $_POST['titleLink']; $GLOBALS['redirector'] = $_POST['redirector']; $GLOBALS['disablesessionprotection'] = !empty($_POST['disablesessionprotection']); $GLOBALS['privateLinkByDefault'] = !empty($_POST['privateLinkByDefault']); $GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = !empty($_POST['enableRssPermalinks']); $GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']); $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after configuration update.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title']); $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']); list($timezone_form, $timezone_js) = generateTimeZoneForm($GLOBALS['timezone']); $PAGE->assign('timezone_form', $timezone_form); $PAGE->assign('timezone_js', $timezone_js); $PAGE->renderPage('configure'); exit; } } // -------- User wants to rename a tag or delete it if ($targetPage == Router::$PAGE_CHANGETAG) { if (empty($_POST['fromtag']) || empty($_POST['totag']) && isset($_POST['renametag'])) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('tags', $LINKSDB->allTags()); $PAGE->renderPage('changetag'); exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Delete a tag: if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); unset($tags[array_search($needle, $tags)]); // Remove tag. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); echo '<script>alert("Tag was removed from ' . count($linksToAlter) . ' links.");document.location=\'?\';</script>'; exit; } // Rename a tag: if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); $tags[array_search($needle, $tags)] = trim($_POST['totag']); // Replace tags value. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. echo '<script>alert("Tag was renamed in ' . count($linksToAlter) . ' links.");document.location=\'?searchtags=' . urlencode($_POST['totag']) . '\';</script>'; exit; } } // -------- User wants to add a link without using the bookmarklet: Show form. if ($targetPage == Router::$PAGE_ADDLINK) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('addlink'); exit; } // -------- User clicked the "Save" button when editing a link: Save link to database. if (isset($_POST['save_edit'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! $tags = trim(preg_replace('/\\s\\s+/', ' ', $_POST['lf_tags'])); // Remove multiple spaces. $tags = implode(' ', array_unique(explode(' ', $tags))); // Remove duplicates. $linkdate = $_POST['lf_linkdate']; $url = trim($_POST['lf_url']); if (!startsWith($url, 'http:') && !startsWith($url, 'https:') && !startsWith($url, 'ftp:') && !startsWith($url, 'magnet:') && !startsWith($url, '?') && !startsWith($url, 'javascript:')) { $url = 'http://' . $url; } $link = array('title' => trim($_POST['lf_title']), 'url' => $url, 'description' => trim($_POST['lf_description']), 'private' => isset($_POST['lf_private']) ? 1 : 0, 'linkdate' => $linkdate, 'tags' => str_replace(',', ' ', $tags)); if ($link['title'] == '') { $link['title'] = $link['url']; } // If title is empty, use the URL as title. $pluginManager->executeHooks('save_link', $link); $LINKSDB[$linkdate] = $link; $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. pubsubhub(); // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = !empty($_POST['returnurl']) ? escape($_POST['returnurl']) : '?'; $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); $location .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. header('Location: ' . $location); // After saving the link, redirect to the page the user was on. exit; } // -------- User clicked the "Cancel" button when editing a link. if (isset($_POST['cancel_edit'])) { // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $returnurl .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); header('Location: ' . $returnurl); // After canceling, redirect to the page the user was on. exit; } // -------- User clicked the "Delete" button when editing a link: Delete link from database. if (isset($_POST['delete_link'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // We do not need to ask for confirmation: // - confirmation is handled by JavaScript // - we are protected from XSRF by the token. $linkdate = $_POST['lf_linkdate']; $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); unset($LINKSDB[$linkdate]); $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } // Pick where we're going to redirect // ============================================================= // Basically, we can't redirect to where we were previously if it was a permalink // or an edit_link, because it would 404. // Cases: // - / : nothing in $_GET, redirect to self // - /?page : redirect to self // - /?searchterm : redirect to self (there might be other links) // - /?searchtags : redirect to self // - /permalink : redirect to / (the link does not exist anymore) // - /?edit_link : redirect to / (the link does not exist anymore) // PHP treats the permalink as a $_GET variable, so we need to check if every condition for self // redirect is not satisfied, and only then redirect to / $location = "?"; // Self redirection if (count($_GET) == 0 || isset($_GET['page']) || isset($_GET['searchterm']) || isset($_GET['searchtags'])) { if (isset($_POST['returnurl'])) { $location = $_POST['returnurl']; // Handle redirects given by the form } else { $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('delete_link')); } } header('Location: ' . $location); // After deleting the link, redirect to appropriate location exit; } // -------- User clicked the "EDIT" button on a link: Display link edit form. if (isset($_GET['edit_link'])) { $link = $LINKSDB[$_GET['edit_link']]; // Read database if (!$link) { header('Location: ?'); exit; } // Link not found in database. $data = array('linkcount' => count($LINKSDB), 'link' => $link, 'link_is_new' => false, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { $url = cleanup_url(escape($_GET['post'])); $link_is_new = false; // Check if URL is not already in database (in this case, we will edit the existing link) $link = $LINKSDB->getLinkFromUrl($url); if (!$link) { $link_is_new = true; $linkdate = strval(date('Ymd_His')); // Get title if it was provided in URL (by the bookmarklet). $title = empty($_GET['title']) ? '' : escape($_GET['title']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] $description = empty($_GET['description']) ? '' : escape($_GET['description']); $tags = empty($_GET['tags']) ? '' : escape($_GET['tags']); $private = !empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0; // If this is an HTTP(S) link, we try go get the page to extract the title (otherwise we will to straight to the edit form.) if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { // Short timeout to keep the application responsive list($headers, $content) = get_http_response($url, 4); if (strpos($headers[0], '200 OK') !== false) { // Retrieve charset. $charset = get_charset($headers, $content); // Extract title. $title = html_extract_title($content); // Re-encode title in utf-8 if necessary. if (!empty($title) && $charset != 'utf-8') { $title = mb_convert_encoding($title, $charset, 'utf-8'); } } } if ($url == '') { $url = '?' . smallHash($linkdate); $title = 'Note: '; } $link = array('linkdate' => $linkdate, 'title' => $title, 'url' => $url, 'description' => $description, 'tags' => $tags, 'private' => $private); } $data = array('linkcount' => count($LINKSDB), 'link' => $link, 'link_is_new' => $link_is_new, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'source' => isset($_GET['source']) ? $_GET['source'] : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } // -------- Export as Netscape Bookmarks HTML file. if ($targetPage == Router::$PAGE_EXPORT) { if (empty($_GET['what'])) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('export'); exit; } $exportWhat = $_GET['what']; if (!array_intersect(array('all', 'public', 'private'), array($exportWhat))) { die('What are you trying to export???'); } header('Content-Type: text/html; charset=utf-8'); header('Content-disposition: attachment; filename=bookmarks_' . $exportWhat . '_' . strval(date('Ymd_His')) . '.html'); $currentdate = date('Y/m/d H:i:s'); echo <<<HTML <!DOCTYPE NETSCAPE-Bookmark-file-1> <!-- This is an automatically generated file. It will be read and overwritten. DO NOT EDIT! --> <!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} --> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> HTML; foreach ($LINKSDB as $link) { if ($exportWhat == 'all' || $exportWhat == 'private' && $link['private'] != 0 || $exportWhat == 'public' && $link['private'] == 0) { echo '<DT><A HREF="' . $link['url'] . '" ADD_DATE="' . linkdate2timestamp($link['linkdate']) . '" PRIVATE="' . $link['private'] . '"'; if ($link['tags'] != '') { echo ' TAGS="' . str_replace(' ', ',', $link['tags']) . '"'; } echo '>' . $link['title'] . "</A>\n"; if ($link['description'] != '') { echo '<DD>' . $link['description'] . "\n"; } } } exit; } // -------- User is uploading a file for import if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=upload')) { // If file is too big, some form field may be missing. if (!isset($_POST['token']) || !isset($_FILES) || isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { $returnurl = empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER']; echo '<script>alert("The file you are trying to upload is probably bigger than what this webserver can accept (' . getMaxFileSize() . ' bytes). Please upload in smaller chunks.");document.location=\'' . escape($returnurl) . '\';</script>'; exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } importFile(); exit; } // -------- Show upload/import dialog: if ($targetPage == Router::$PAGE_IMPORT) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('maxfilesize', getMaxFileSize()); $PAGE->renderPage('import'); exit; } // -------- Otherwise, simply display search form and links: showLinkList($PAGE, $LINKSDB); exit; }
/** * Standard import function. * * @param object The DB connection to import from * @param string The table prefix the target prefix is using * @param PATH The base directory we are importing from */ function import_ocf_personal_topics($db, $table_prefix, $old_base_dir) { $rows = $db->query('SELECT * FROM ' . $table_prefix . 'pm p ORDER BY pm_time'); // Group them up into what will become topics $groups = array(); foreach ($rows as $row) { // Do some fiddling around for duplication if ($row['pm_from'] > $row['pm_to']) { $a = $row['pm_to']; $b = $row['pm_from']; } else { $a = $row['pm_from']; $b = $row['pm_to']; } $row['pm_subject'] = str_replace('Re: ', '', $row['pm_subject']); $groups[strval($a) . ':' . strval($b) . ':' . $row['pm_subject']][] = $row; } // Import topics foreach ($groups as $group) { $row = $group[0]; if (import_check_if_imported('pt', strval($row['pmid']))) { continue; } // Create topic $from_id = import_id_remap_get('member', strval($row['pm_from']), true); if (is_null($from_id)) { $from_id = $GLOBALS['OCF_DRIVER']->get_guest_id(); } $to_id = import_id_remap_get('member', strval($row['pm_to']), true); if (is_null($to_id)) { $to_id = $GLOBALS['OCF_DRIVER']->get_guest_id(); } $topic_id = ocf_make_topic(NULL, '', '', 1, 1, 0, 0, 0, $from_id, $to_id, false); $first_post = true; foreach ($group as $_post) { if ($first_post) { $title = $row['pm_subject']; } else { $title = ''; } $title = @html_entity_decode($title, ENT_QUOTES, get_charset()); $post = $this->fix_links($_post['pm_body'], $db, $table_prefix, $old_base_dir); $validated = 1; $from_id = import_id_remap_get('member', strval($_post['pm_from']), true); if (is_null($from_id)) { $from_id = $GLOBALS['OCF_DRIVER']->get_guest_id(); } $poster_name_if_guest = $GLOBALS['OCF_DRIVER']->get_username($from_id); $ip_address = ''; $time = $_post['pm_time']; $poster = $from_id; $last_edit_time = NULL; $last_edit_by = NULL; ocf_make_post($topic_id, $title, $post, 0, $first_post, $validated, 0, $poster_name_if_guest, $ip_address, $time, $poster, NULL, $last_edit_time, $last_edit_by, false, false, NULL, false); $first_post = false; } import_id_remap_put('pt', strval($row['pmid']), $topic_id); } }
function report_header() { global $output_format, $ajax; global $custom_fields, $tbl_entry; global $approval_somewhere, $confirmation_somewhere; global $field_order_list; // Don't do anything if this is an Ajax request: we only want to send the data if ($ajax) { return; } // Build an array of values to go into the header row $values = array(); foreach ($field_order_list as $field) { // We give some columns an stype data value so that the JavaScript knows how to sort them switch ($field) { case 'name': $values[] = get_vocab("namebooker"); break; case 'area_name': $values[] = get_vocab("area"); break; case 'room_name': $values[] = get_vocab("room"); break; case 'start_time': $values[] = stype_wrap(get_vocab("start_date"), 'title-numeric'); break; case 'end_time': $values[] = stype_wrap(get_vocab("end_date"), 'title-numeric'); $values[] = stype_wrap(get_vocab("duration"), 'title-numeric'); break; case 'description': $values[] = get_vocab("fulldescription_short"); break; case 'type': $values[] = get_vocab("type"); break; case 'create_by': $values[] = get_vocab("createdby"); break; case 'confirmation_enabled': if ($confirmation_somewhere) { $values[] = get_vocab("confirmation_status"); } break; case 'approval_enabled': if ($approval_somewhere) { $values[] = get_vocab("approval_status"); } break; case 'last_updated': $values[] = stype_wrap(get_vocab("lastupdate"), 'title-numeric'); break; default: // the custom fields if (array_key_exists($field, $custom_fields)) { $values[] = get_loc_field_name($tbl_entry, $field); } break; } // switch } // foreach // Find out what the non-breaking space is in this character set $charset = get_charset(); $nbsp = mrbs_entity_decode(' ', ENT_NOQUOTES, $charset); for ($i = 0; $i < count($values); $i++) { if ($output_format != OUTPUT_HTML) { // Remove any HTML entities from the values $values[$i] = mrbs_entity_decode($values[$i], ENT_NOQUOTES, $charset); // Trim non-breaking spaces from the string $values[$i] = trim($values[$i], $nbsp); // And do an ordinary trim $values[$i] = trim($values[$i]); // We don't escape HTML output here because the vocab strings are trusted. // And some of them contain HTML entities such as on purpose $values[$i] = escape($values[$i]); } } $head_rows = array(); $head_rows[] = $values; output_head_rows($head_rows, $output_format); }
/** * Do an AJAX comment post */ function post_comment_script() { header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past // Read in context of what we're doing $options = post_param('options'); secure_serialized_data($options); list($page_name, $content_id, $allow_comments, $submitter, $content_url, $content_title, $forum) = unserialize($options); // Check security $hash = post_param('hash'); if (best_hash($options, get_site_salt()) != $hash) { header('Content-Type: text/plain; charset=' . get_charset()); exit; } // Post comment actualise_post_comment($allow_comments >= 1, $page_name, $content_id, $content_url, $content_title, $forum); // Get new comments state $comment_details = get_comments($page_name, $allow_comments == 1, $content_id, false, $forum, NULL, NULL, false, false, $submitter, $allow_comments == 2); // And output as text header('Content-Type: text/plain; charset=' . get_charset()); $comment_details->evaluate_echo(); }