/** * Standard modular run function for OcCLE hooks. * * @param array The options with which the command was called * @param array The parameters with which the command was called * @param object A reference to the OcCLE filesystem object * @return array Array of stdcommand, stdhtml, stdout, and stderr responses */ function run($options, $parameters, &$occle_fs) { if (array_key_exists('h', $options) || array_key_exists('help', $options)) { return array('', do_command_help('grep', array('h'), array(true, true)), '', ''); } else { if (!array_key_exists(0, $parameters)) { return array('', '', '', do_lang('MISSING_PARAM', '1', 'grep')); } if (!array_key_exists(1, $parameters)) { return array('', '', '', do_lang('MISSING_PARAM', '2', 'grep')); } else { $parameters[1] = $occle_fs->_pwd_to_array($parameters[1]); } if (!$occle_fs->_is_file($parameters[1])) { return array('', '', '', do_lang('NOT_A_FILE', '2')); } $_lines = unixify_line_format($occle_fs->read_file($parameters[1])); $lines = explode("\n", $_lines); if ($parameters[0] == '' || $parameters[0][0] != '#' && $parameters[0][0] != '/') { $parameters[0] = '#' . $parameters[0] . '#'; } $matches = preg_grep($parameters[0], $lines); $output = ''; foreach ($matches as $value) { $output .= $value . "\n"; } return array('', '', $output, ''); } }
/** * A template has not been structurally cached, so compile it and store in the cache. * * @param ID_TEXT The theme the template is in the context of * @param PATH The path to the template file * @param ID_TEXT The codename of the template (e.g. foo) * @param ID_TEXT The actual codename to use for the template (e.g. thin_foo) * @param LANGUAGE_NAME The language the template is in the context of * @param string File type suffix of template file * @param ?ID_TEXT The theme to cache in (NULL: main theme) * @return tempcode The compiled tempcode */ function _do_template($theme, $path, $codename, $_codename, $lang, $suffix, $theme_orig = NULL) { if (is_null($theme_orig)) { $theme_orig = $theme; } $base_dir = ($theme == 'default' && ($suffix != '.css' || strpos($path, '/css_custom') === false) ? get_file_base() : get_custom_file_base()) . '/themes/'; global $CACHE_TEMPLATES, $FILE_ARRAY, $TEMPLATE_PREVIEW_OP, $MEM_CACHE; if (isset($FILE_ARRAY)) { $html = unixify_line_format(file_array_get('themes/' . $theme . $path . $codename . $suffix)); } else { $html = unixify_line_format(file_get_contents($base_dir . filter_naughty($theme . $path . $codename) . $suffix, FILE_TEXT)); } if (strpos($html, '{$,Parser hint: pure}') !== false) { return make_string_tempcode(preg_replace('#\\{\\$,.*\\}#U', '/*no minify*/', $html)); } if ($GLOBALS['SEMI_DEBUG_MODE'] && strpos($html, '.innerHTML') !== false && strpos($html, 'Parser hint: .innerHTML okay') === false) { require_code('site'); attach_message('Do not use the .innerHTML property in your Javascript because it will not work in true XHTML (when the browsers real XML parser is in action). Use ocPortal\'s global setInnerHTML/getInnerHTML functions.', 'warn'); } // Strip off trailing final lines from single lines templates. Editors often put these in, and it causes annoying "visible space" issues if (substr($html, -1, 1) == chr(10) && substr_count($html, chr(10)) == 1) { $html = substr($html, 0, strlen($html) - 1); } if ($TEMPLATE_PREVIEW_OP) { $test = post_param($codename, NULL); if (!is_null($test)) { $html = post_param($test . '_new'); } } $result = template_to_tempcode($html, 0, false, $codename, $theme, $lang); if ($CACHE_TEMPLATES && ($suffix == '.tpl' || $codename == 'no_cache')) { if (!is_null($MEM_CACHE)) { persistant_cache_set(array('TEMPLATE', $theme, $lang, $_codename), $result->to_assembly(), strpos($path, 'default/templates/') !== false); } else { $path2 = get_custom_file_base() . '/themes/' . $theme_orig . '/templates_cached/' . filter_naughty($lang) . '/'; $myfile = @fopen($path2 . filter_naughty($_codename) . $suffix . '.tcd', 'wb'); if ($myfile === false) { if (@mkdir($path2, 0777)) { require_code('files'); fix_permissions($path2, 0777); } else { if (file_exists($path2 . filter_naughty($_codename) . $suffix . '.tcd')) { warn_exit(do_lang_tempcode('WRITE_ERROR', $path2 . filter_naughty($_codename) . $suffix . '.tcd')); } else { warn_exit(do_lang_tempcode('WRITE_ERROR_CREATE', $path2 . filter_naughty($_codename) . $suffix . '.tcd')); } } } else { fwrite($myfile, $result->to_assembly($lang)); fclose($myfile); fix_permissions($path2 . filter_naughty($_codename) . $suffix . '.tcd'); } } } return $result; }
/** * Get Javascript to restrict post lengths. * * @return string The post Javascript */ function _post_javascript() { $size = ocf_get_member_best_group_property(get_member(), 'max_post_length_comcode'); $javascript = ''; $javascript .= "\n\t\t\tvar form=document.getElementById('post').form;\n\t\t\tform.old_submit=form.onsubmit;\n\t\t\tform.onsubmit=function() {\n\t\t\t\tvar post=form.elements['post'];\n\t\t\t\tvar text_value;\n\t\t\t\tif (is_wysiwyg_field(post))\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\ttext_value=window.CKEDITOR.instances['post'].getData();\n\t\t\t\t\t}\n\t\t\t\t\tcatch (e) {};\n\t\t\t\t} else\n\t\t\t\t{\n\t\t\t\t\tif ((!post.value) && (post[1])) post=post[1];\n\t\t\t\t\ttext_value=post.value;\n\t\t\t\t}\n\t\t\t\tif (text_value.length>" . strval($size) . ")\n\t\t\t\t{\n\t\t\t\t\twindow.fauxmodal_alert('" . php_addslashes(do_lang('_POST_TOO_LONG')) . "');\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t"; $stub = unixify_line_format(either_param('stub', '')); if ($stub != '') { $javascript .= "\n\t\t\t\tvar df='" . str_replace(chr(10), '\\n', addslashes($stub)) . "';\n\n\t\t\t\tvar pv=post.value;\n\t\t\t\tif ((post) && (pv.substring(0,df.length)==df))\n\t\t\t\t{\n\t\t\t\t\tpv=pv.substring(df.length,pv.length);\n\t\t\t\t}\n\t\t\t\tpost.value=pv;\n\t\t"; } $javascript .= "\n\t\t\t\tif (typeof form.old_submit!='undefined' && form.old_submit) return form.old_submit();\n\n\t\t\t\treturn true;\n\t\t\t};\n\t\t"; return $javascript; }
/** * A template has not been structurally cached, so compile it and store in the cache. * * @param ID_TEXT The theme the template is in the context of * @param PATH The path to the template file * @param ID_TEXT The codename of the template (e.g. foo) * @param ID_TEXT The actual codename to use for the template (e.g. foo_mobile) * @param LANGUAGE_NAME The language the template is in the context of * @param string File type suffix of template file (e.g. .tpl) * @param ?ID_TEXT The theme to cache in (NULL: main theme) * @return tempcode The compiled tempcode */ function _do_template($theme, $path, $codename, $_codename, $lang, $suffix, $theme_orig = NULL) { if (is_null($theme_orig)) { $theme_orig = $theme; } if (is_null($GLOBALS['CURRENT_SHARE_USER'])) { $base_dir = ($theme == 'default' && ($suffix != '.css' || strpos($path, '/css_custom') === false) ? get_file_base() : get_custom_file_base()) . '/themes/'; } else { $base_dir = get_custom_file_base() . '/themes/'; if (!is_file($base_dir . $theme . $path . $codename . $suffix)) { $base_dir = get_file_base() . '/themes/'; } } global $CACHE_TEMPLATES, $FILE_ARRAY, $TEMPLATE_PREVIEW_OP, $MEM_CACHE; if (isset($FILE_ARRAY)) { $html = unixify_line_format(file_array_get('themes/' . $theme . $path . $codename . $suffix)); } else { $html = unixify_line_format(file_get_contents($base_dir . filter_naughty($theme . $path . $codename) . $suffix, FILE_TEXT)); } if ($GLOBALS['SEMI_DEBUG_MODE'] && strpos($html, '.innerHTML') !== false && !running_script('install') && strpos($html, 'Parser hint: .innerHTML okay') === false) { attach_message('Do not use the .innerHTML property in your Javascript because it will not work in true XHTML (when the browsers real XML parser is in action). Use ocPortal\'s global setInnerHTML/getInnerHTML functions.', 'warn'); } // Strip off trailing final lines from single lines templates. Editors often put these in, and it causes annoying "visible space" issues if (substr($html, -1, 1) == chr(10) && substr_count($html, chr(10)) == 1) { $html = substr($html, 0, strlen($html) - 1); } if ($TEMPLATE_PREVIEW_OP) { $test = post_param($codename, NULL); if (!is_null($test)) { $html = post_param($test . '_new'); } } $result = template_to_tempcode($html, 0, false, $suffix != '.tpl' ? '' : $codename, $theme_orig, $lang); if ($CACHE_TEMPLATES && !$TEMPLATE_PREVIEW_OP && ($suffix == '.tpl' || $codename == 'no_cache')) { $path2 = get_custom_file_base() . '/themes/' . $theme_orig . '/templates_cached/' . filter_naughty($lang) . '/'; $myfile = @fopen($path2 . filter_naughty($_codename) . $suffix . '.tcp', 'wb'); if ($myfile === false) { @mkdir(dirname($path2), 0777); fix_permissions(dirname($path2), 0777); sync_file(dirname($path2)); if (@mkdir($path2, 0777)) { fix_permissions($path2, 0777); sync_file($path2); } else { if ($codename == 'SCREEN_TITLE') { critical_error('PASSON', do_lang('WRITE_ERROR', escape_html($path2 . filter_naughty($_codename) . $suffix . '.tcp'))); } // Bail out hard if would cause a loop intelligent_write_error($path2 . filter_naughty($_codename) . $suffix . '.tcp'); } } else { $data_to_write = '<' . '?php' . chr(10) . $result->to_assembly($lang) . chr(10) . '?' . '>'; if (fwrite($myfile, $data_to_write) >= strlen($data_to_write)) { // Success fclose($myfile); require_code('files'); fix_permissions($path2 . filter_naughty($_codename) . $suffix . '.tcp'); } else { // Failure fclose($myfile); @unlink($path2 . filter_naughty($_codename) . $suffix . '.tcp'); // Can't leave this around, would cause problems } } } return $result; }
/** * Constructs the XML reader: parses the given data. Check $gleamed and $error after constructing. * * @param string The XML data */ function ocp_simple_xml_reader($xml_data) { $this->gleamed = array(); $this->error = NULL; $this->tag_stack = array(); $this->attribute_stack = array(); $this->children_stack = array(); $this->text_stack = array(); if (!function_exists('xml_parser_create')) { $this->error = do_lang_tempcode('XML_NEEDED'); return; } // Our internal charset $parser_charset = get_charset(); if (!in_array(strtoupper($parser_charset), array('ISO-8859-1', 'US-ASCII', 'UTF-8'))) { $parser_charset = 'ISO-8859-1'; } // Create and setup our parser $xml_parser = function_exists('xml_parser_create_ns') ? @xml_parser_create_ns($parser_charset) : @xml_parser_create($parser_charset); if ($xml_parser === false) { $this->error = do_lang_tempcode('XML_PARSING_NOT_SUPPORTED'); 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, $parser_charset); xml_set_element_handler($xml_parser, 'startElement', 'endElement'); xml_set_character_data_handler($xml_parser, 'startText'); $xml_data = unixify_line_format('<' . '?xml version="1.0" encoding="' . xmlentities($parser_charset) . '"?' . '>' . $xml_data, $parser_charset); // Fixes Windows characters if (xml_parse($xml_parser, $xml_data, true) == 0) { warn_exit(xml_error_string(xml_get_error_code($xml_parser))); } @xml_parser_free($xml_parser); }
/** * Import ical events to members's event calendar. * * @param PATH File path */ function ical_import($file_name) { $data = unixify_line_format(file_get_contents($file_name)); $whole = end(explode('BEGIN:VCALENDAR', $data)); $events = explode('BEGIN:VEVENT', $whole); $calendar_nodes = array(); foreach ($events as $key => $items) { $items = preg_replace('#(.+)\\n +(.*)\\n#', '${1}${2}' . "\n", $items); // Merge split lines $nodes = explode("\n", $items); foreach ($nodes as $_child) { if (strpos($_child, ':') === false) { continue; } $child = array('', ''); $in_quotes = false; $j = 0; for ($i = 0; $i < strlen($_child); $i++) { $char = $_child[$i]; if ($char == '"') { $in_quotes = !$in_quotes; } if ($j != 1 && !$in_quotes && $char == ':') { $j++; } else { $child[$j] .= $char; } } $matches = array(); if (preg_match('#;TZID=(.*)#', $child[0], $matches)) { $calendar_nodes[$key]['TZID'] = $matches[1]; } $child[0] = preg_replace('#;.*#', '', $child[0]); if (array_key_exists(1, $child) && $child[0] !== 'PRODID' && $child[0] !== 'VERSION' && $child[0] !== 'END') { $calendar_nodes[$key][$child[0]] = trim($child[1]); } } if ($key != 0) { list(, $type_id, $type, $recurrence, $recurrences, $seg_recurrences, $title, $content, $priority, $is_public, $start_year, $start_month, $start_day, $start_hour, $start_minute, $end_year, $end_month, $end_day, $end_hour, $end_minute, $timezone, $validated, $allow_rating, $allow_comments, $allow_trackbacks, $notes) = get_event_data_ical($calendar_nodes[$key]); if (is_null($type_id)) { require_code('calendar2'); $type_id = add_event_type(ucfirst($type), 'calendar/general'); } $id = add_calendar_event($type, $recurrence, $recurrences, $seg_recurrences, $title, $content, $priority, $is_public, $start_year, $start_month, $start_day, $start_hour, $start_minute, $end_year, $end_month, $end_day, $end_hour, $end_minute, $timezone, 1, $validated, $allow_rating, $allow_comments, $allow_trackbacks, $notes); } } }
/** * The UI to import subscribers into the newsletter. * * @return tempcode The UI */ function import_subscribers() { $title = get_page_title('IMPORT_NEWSLETTER_SUBSCRIBERS'); $_lang = choose_language($title); if (is_object($_lang)) { return $_lang; } require_lang('ocf'); $newsletter_id = post_param('id', NULL); $level = post_param_integer('level', 4); // Select newsletter and attach CSV if (is_null($newsletter_id)) { $fields = new ocp_tempcode(); $hidden = new ocp_tempcode(); require_code('form_templates'); // Selection $newsletters = new ocp_tempcode(); $rows = $GLOBALS['SITE_DB']->query_select('newsletters', array('id', 'title')); foreach ($rows as $newsletter) { $newsletters->attach(form_input_list_entry(strval($newsletter['id']), false, get_translated_text($newsletter['title']))); } if ($newsletters->is_empty()) { inform_exit(do_lang_tempcode('NO_CATEGORIES')); } $fields->attach(form_input_list(do_lang_tempcode('NEWSLETTER'), '', 'id', $newsletters)); $fields->attach(form_input_upload(do_lang_tempcode('UPLOAD'), do_lang_tempcode('DESCRIPTION_UPLOAD_CSV_2'), 'file', true, NULL, NULL, true, 'csv,txt')); // Choose level if (get_option('interest_levels') == '0') { $l = new ocp_tempcode(); $l->attach(form_input_list_entry('0', false, do_lang_tempcode('NEWSLETTER_0'))); $l->attach(form_input_list_entry('4', $level == 4, do_lang_tempcode('NEWSLETTER_IMPORT'))); $fields->attach(form_input_list(do_lang_tempcode('SETTINGS'), do_lang_tempcode('DESCRIPTION_SUBSCRIPTION_LEVEL_3'), 'level', $l)); } else { $l = new ocp_tempcode(); $l->attach(form_input_list_entry('0', false, do_lang_tempcode('NEWSLETTER_0'))); $l->attach(form_input_list_entry('1', $level == 1, do_lang_tempcode('NEWSLETTER_1'))); $l->attach(form_input_list_entry('2', $level == 2, do_lang_tempcode('NEWSLETTER_2'))); $l->attach(form_input_list_entry('3', $level == 3, do_lang_tempcode('NEWSLETTER_3'))); $l->attach(form_input_list_entry('4', $level == 4, do_lang_tempcode('NEWSLETTER_4'))); $fields->attach(form_input_list(do_lang_tempcode('SUBSCRIPTION_LEVEL'), do_lang_tempcode('DESCRIPTION_SUBSCRIPTION_LEVEL_2'), 'level', $l)); } $submit_name = do_lang_tempcode('IMPORT_NEWSLETTER_SUBSCRIBERS'); $post_url = get_self_url(); $hidden->attach(form_input_hidden('lang', $_lang)); handle_max_file_size($hidden); return do_template('FORM_SCREEN', array('SKIP_VALIDATION' => true, 'HIDDEN' => $hidden, 'TITLE' => $title, 'TEXT' => '', 'FIELDS' => $fields, 'SUBMIT_NAME' => $submit_name, 'URL' => $post_url)); } // Read data $ok = false; require_code('uploads'); if (is_swf_upload(true) && array_key_exists('file', $_FILES) || array_key_exists('file', $_FILES) && is_uploaded_file($_FILES['file']['tmp_name'])) { $fixed_contents = unixify_line_format(file_get_contents($_FILES['file']['tmp_name'])); $myfile = @fopen($_FILES['file']['tmp_name'], 'wb'); if ($myfile !== false) { fwrite($myfile, $fixed_contents); fclose($myfile); } $myfile = fopen($_FILES['file']['tmp_name'], 'rb'); $del = ','; $csv_test_line = fgetcsv($myfile, 4096, $del); if (count($csv_test_line) == 1 && strpos($csv_test_line[0], ';') !== false) { $del = ';'; } rewind($myfile); $email_index = 0; $forename_index = 1; $surname_index = 2; $username_index = 3; $hash_index = 6; $salt_index = 7; $lang_index = 8; $code_confirm_index = 9; $jointime_index = 10; $count = 0; $count2 = 0; do { $i = 0; $_csv_data = array(); while (($csv_line = fgetcsv($myfile, 4096, $del)) !== false) { $_csv_data[] = $csv_line; $i++; if ($i == 500) { break; } } // Process data foreach ($_csv_data as $i => $csv_line) { if ($i <= 1 && count($csv_line) >= 1 && !is_null($csv_line[$email_index]) && strpos($csv_line[$email_index], '@') === false) { foreach ($csv_line as $j => $val) { if (in_array(strtolower($val), array('e-mail', 'email', 'email address', 'e-mail address', strtolower(do_lang('EMAIL_ADDRESS'))))) { $email_index = $j; } if (in_array(strtolower($val), array('forename', 'forenames', 'first name', strtolower(do_lang('FORENAME'))))) { $forename_index = $j; } if (in_array(strtolower($val), array('surname', 'surnames', 'last name', strtolower(do_lang('SURNAME'))))) { $surname_index = $j; } if (in_array(strtolower($val), array('username', strtolower(do_lang('NAME'))))) { $username_index = $j; } if (in_array(strtolower($val), array('hash', 'password', 'pass', 'code', 'secret', strtolower(do_lang('PASSWORD_HASH'))))) { $hash_index = $j; } if (in_array(strtolower($val), array('salt', strtolower(do_lang('SALT'))))) { $salt_index = $j; } if (in_array(strtolower($val), array('lang', 'language', strtolower(do_lang('LANGUAGE'))))) { $hash_index = $j; } if (in_array(strtolower($val), array('confirm code', strtolower(do_lang('CONFIRM_CODE'))))) { $code_confirm_index = $j; } if (strpos(strtolower($val), 'time') !== false || strpos(strtolower($val), 'date') !== false || strtolower($val) == do_lang('JOIN_DATE')) { $jointime_index = $j; } } continue; } if (count($csv_line) >= 1 && !is_null($csv_line[$email_index]) && strpos($csv_line[$email_index], '@') !== false) { $email = $csv_line[$email_index]; $forename = array_key_exists($forename_index, $csv_line) ? $csv_line[$forename_index] : ''; if ($forename == $email) { $forename = ucfirst(strtolower(preg_replace('#^(\\w+)([^\\w].*)?$#', '\\1', $forename))); if (in_array($forename, array('Sales', 'Info', 'Business', 'Enquiries', 'Admin'))) { $forename = ''; } } $surname = array_key_exists($surname_index, $csv_line) ? $csv_line[$surname_index] : ''; $username = array_key_exists($username_index, $csv_line) ? $csv_line[$username_index] : ''; $hash = array_key_exists($hash_index, $csv_line) ? $csv_line[$hash_index] : ''; $salt = array_key_exists($salt_index, $csv_line) ? $csv_line[$salt_index] : ''; $lang = array_key_exists($lang_index, $csv_line) && (file_exists(get_custom_file_base() . '/lang/' . $csv_line[$lang_index]) || file_exists(get_custom_file_base() . '/lang_custom/' . $csv_line[$lang_index])) ? $csv_line[$lang_index] : $_lang; if ($lang == '') { $lang = $_lang; } $code_confirm = array_key_exists($code_confirm_index, $csv_line) ? intval($csv_line[$code_confirm_index]) : 0; $jointime = array_key_exists($jointime_index, $csv_line) ? strtotime($csv_line[$jointime_index]) : time(); if ($jointime === false) { $jointime = time(); } $test = $GLOBALS['SITE_DB']->query_value_null_ok('newsletter', 'id', array('email' => $email)); if (is_null($test)) { $GLOBALS['SITE_DB']->query_insert('newsletter', array('email' => $email, 'join_time' => $jointime, 'code_confirm' => $code_confirm, 'the_password' => $hash, 'pass_salt' => $salt, 'language' => $lang, 'n_forename' => $forename, 'n_surname' => $surname)); $count++; } else { $GLOBALS['SITE_DB']->query_update('newsletter', array('n_forename' => $forename, 'n_surname' => $surname), array('email' => $email), '', 1); } // In case $email is already a subscriber, we delete first $GLOBALS['SITE_DB']->query_delete('newsletter_subscribe', array('newsletter_id' => $newsletter_id, 'email' => $email), '', 1); if ($level != 0) { $GLOBALS['SITE_DB']->query_insert('newsletter_subscribe', array('newsletter_id' => $newsletter_id, 'the_level' => $level, 'email' => $email)); } $count2++; } } } while (count($_csv_data) != 0); fclose($myfile); } else { warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN_UPLOAD')); } return inform_screen($title, do_lang_tempcode('NEWSLETTER_IMPORTED_THIS', integer_format($count), integer_format($count2))); }
/** * The UI for the second stage of recommending the site - when CSV file is posted * * @return tempcode The UI. */ function gui2() { require_code('form_templates'); $submit_name = do_lang_tempcode('PROCEED'); $post_url = build_url(array('page' => '_SELF', 'type' => 'actual'), '_SELF'); $fields = new ocp_tempcode(); $hidden = new ocp_tempcode(); $already = array(); $email_counter = 0; foreach ($_POST as $key => $input_value) { //stripslashes if necessary if (get_magic_quotes_gpc()) { $input_value = stripslashes($input_value); } if (substr($key, 0, 14) == 'email_address_') { $already[] = $input_value; //email address $email_counter++; $hidden->attach(form_input_hidden($key, $input_value)); } else { //add hidden field to the form if ($key != 'upload') { $hidden->attach(form_input_hidden($key, $input_value)); } } } $hidden->attach(form_input_hidden('select_contacts_page', '1')); $text = do_lang_tempcode('RECOMMEND_SITE_TEXT_CHOOSE_CONTACTS'); $page_title = get_param('page_title', NULL, true); 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); } } 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')); } $success_read = false; //start processing CSV file if (get_value('disable_csv_recommend') !== '1' && !is_guest()) { if (array_key_exists('upload', $_FILES)) { if (is_uploaded_file($_FILES['upload']['tmp_name']) && preg_match('#\\.csv#', $_FILES['upload']['name']) != 0) { $possible_email_fields = array('E-mail', 'Email', 'E-mail address', 'Email address', 'Primary Email'); $possible_name_fields = array('Name', 'Forename', 'First Name', 'Display Name', 'First'); $fixed_contents = unixify_line_format(file_get_contents($_FILES['upload']['tmp_name'])); $myfile = @fopen($_FILES['upload']['tmp_name'], 'wb'); if ($myfile !== false) { fwrite($myfile, $fixed_contents); fclose($myfile); } $myfile = fopen($_FILES['upload']['tmp_name'], 'rb'); $del = ','; $csv_header_line_fields = fgetcsv($myfile, 10240, $del); if (count($csv_header_line_fields) == 1 && strpos($csv_header_line_fields[0], ';') !== false) { $del = ';'; rewind($myfile); $csv_header_line_fields = fgetcsv($myfile, 10240, $del); } $skip_next_process = false; if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding') && strlen(mb_detect_encoding($csv_header_line_fields[0], "ASCII,UTF-8,UTF-16,UTF16")) == 0) { //test string just for Apple mail detection $test_unicode = utf8_decode(mb_convert_encoding($csv_header_line_fields[0], "UTF-8", "UTF-16")); if (preg_match('#\\?\\?ame#u', $test_unicode) != 0) { //THIS SHOULD BE APPLE MAIL foreach ($csv_header_line_fields as $key => $value) { $csv_header_line_fields[$key] = utf8_decode(mb_convert_encoding($csv_header_line_fields[$key], "UTF-8", "UTF-16")); $found_email_address = ''; $found_name = ''; $first_row_exploded = explode(';', $csv_header_line_fields[0]); $email_index = 1; //by default $name_index = 0; //by default foreach ($csv_header_line_fields as $key2 => $value2) { if (preg_match('#\\?\\?ame#', $value2) != 0) { $name_index = $key2; } //Windows mail if (preg_match('#E\\-mail#', $value2) != 0) { $email_index = $key2; } //both } while (($csv_line = fgetcsv($myfile, 10240, $del)) !== false) { foreach ($csv_line as $key2 => $value2) { $csv_line[$key2] = utf8_decode(mb_convert_encoding($value2, "UTF-8", "UTF-16")); } $found_email_address = array_key_exists($email_index, $csv_line) && strlen($csv_line[$email_index]) > 0 ? $csv_line[$email_index] : ''; $found_email_address = preg_match('#.*\\@.*\\..*#', $found_email_address) != 0 ? preg_replace("#\"#", '', $found_email_address) : ''; $found_name = $found_email_address; if (strlen($found_email_address) > 0) { $skip_next_process = true; //Add to the list what we've found $fields->attach(form_input_tick($found_name, $found_email_address, 'use_details_' . strval($email_counter), true)); $hidden->attach(form_input_hidden('details_email_' . strval($email_counter), $found_email_address)); $hidden->attach(form_input_hidden('details_name_' . strval($email_counter), $found_name)); $email_counter++; $success_read = true; } } } } } if (!$skip_next_process) { //there is a strange symbol that appears at start of the Windows Mail file, so we need to convert the first file line to catch these if (function_exists('mb_check_encoding') && mb_check_encoding($csv_header_line_fields[0], 'UTF-8')) { $csv_header_line_fields[0] = utf8_decode($csv_header_line_fields[0]); } //this means that we need to import from Windows mail (also for Outlook Express) export file, which is different from others csv export formats if (array_key_exists(0, $csv_header_line_fields) && (preg_match('#\\?Name#', $csv_header_line_fields[0]) != 0 || preg_match('#Name\\;E\\-mail\\sAddress#', $csv_header_line_fields[0]) != 0)) { $found_email_address = ''; $found_name = ''; $first_row_exploded = explode(';', $csv_header_line_fields[0]); $email_index = 1; //by default $name_index = 0; //by default foreach ($first_row_exploded as $key => $value) { if (preg_match('#\\?Name#', $value) != 0) { $name_index = $key; } //Windows mail if (preg_match('#^Name$#', $value) != 0) { $name_index = $key; } //Outlook Express if (preg_match('#E\\-mail\\sAddress#', $value) != 0) { $email_index = $key; } //both } while (($csv_line = fgetcsv($myfile, 10240, $del)) !== false) { $row_exploded = array_key_exists(0, $csv_line) && strlen($csv_line['0']) > 0 ? explode(';', $csv_line[0]) : array('', ''); $found_email_address = strlen($row_exploded[$email_index]) > 0 ? $row_exploded[$email_index] : ''; $found_name = strlen($row_exploded[$name_index]) > 0 ? $row_exploded[$name_index] : ''; if (strlen($found_email_address) > 0) { //Add to the list what we've found $fields->attach(form_input_tick($found_name, do_lang_tempcode('RECOMMENDING_TO_LINE', escape_html($found_name), escape_html($found_email_address)), 'use_details_' . strval($email_counter), true)); $hidden->attach(form_input_hidden('details_email_' . strval($email_counter), $found_email_address)); $hidden->attach(form_input_hidden('details_name_' . strval($email_counter), $found_name)); $email_counter++; $success_read = true; } } } else { while (($csv_line = fgetcsv($myfile, 10240, $del)) !== false) { $found_email_address = ''; $found_name = ''; foreach ($possible_email_fields as $field) { foreach ($csv_header_line_fields as $i => $header_field) { if (strtolower($header_field) == strtolower($field) && array_key_exists($i, $csv_line) && $csv_line[$i] != '') { $found_email_address = $csv_line[$i]; $success_read = true; } } } foreach ($possible_name_fields as $field) { foreach ($csv_header_line_fields as $i => $header_field) { if (strtolower($header_field) == strtolower($field) && array_key_exists($i, $csv_line) && $csv_line[$i] != '') { $found_name = $csv_line[$i]; } } } if (strlen($found_email_address) > 0) { //Add to the list what we've found $fields->attach(form_input_tick($found_name, do_lang_tempcode('RECOMMENDING_TO_LINE', escape_html($found_name), escape_html($found_email_address)), 'use_details_' . strval($email_counter), true)); $hidden->attach(form_input_hidden('details_email_' . strval($email_counter), $found_email_address)); $hidden->attach(form_input_hidden('details_name_' . strval($email_counter), $found_name)); $email_counter++; } } } } fclose($myfile); } } } if (!$success_read) { warn_exit(do_lang_tempcode('ERROR_NO_CONTACTS_SELECTED')); } return do_template('FORM_SCREEN', array('PREVIEW' => true, 'SKIP_VALIDATION' => true, 'TITLE' => $title, 'HIDDEN' => $hidden, 'FIELDS' => $fields, 'URL' => $post_url, 'SUBMIT_NAME' => $submit_name, 'TEXT' => $text)); }
/** * Attempt to send an e-mail to the specified recipient. The mail will be forwarding to the CC address specified in the options (if there is one, and if not specified not to cc). * The mail will be sent in dual HTML/text format, where the text is the unconverted comcode source: if a member does not read HTML mail, they may wish to fallback to reading that. * * @param string The subject of the mail in plain text * @param LONG_TEXT The message, as Comcode * @param ?array The destination (recipient) e-mail addresses [array of strings] (NULL: site staff address) * @param ?mixed The recipient name. Array or string. (NULL: site name) * @param EMAIL The from address (blank: site staff address) * @param string The from name (blank: site name) * @param integer The message priority (1=urgent, 3=normal, 5=low) * @range 1 5 * @param ?array An list of attachments (each attachment being a map, path=>filename) (NULL: none) * @param boolean Whether to NOT CC to the CC address * @param ?MEMBER Convert comcode->tempcode as this member (a privilege thing: we don't want people being able to use admin rights by default!) (NULL: guest) * @param boolean Replace above with arbitrary admin * @param boolean HTML-only * @param boolean Whether to bypass queueing, because this code is running as a part of the queue management tools * @param ID_TEXT The template used to show the email * @param boolean Whether to bypass queueing * @return ?tempcode A full page (not complete XHTML) piece of tempcode to output (NULL: it worked so no tempcode message) */ function mail_wrap($subject_tag, $message_raw, $to_email = NULL, $to_name = NULL, $from_email = '', $from_name = '', $priority = 3, $attachments = NULL, $no_cc = false, $as = NULL, $as_admin = false, $in_html = false, $coming_out_of_queue = false, $mail_template = 'MAIL', $bypass_queue = false) { if (running_script('stress_test_loader')) { return NULL; } global $EMAIL_ATTACHMENTS; $EMAIL_ATTACHMENTS = array(); require_code('site'); require_code('mime_types'); $bypass_queue = $bypass_queue || $priority < 3 || strpos(serialize($attachments), 'tmpfile') !== false; if (is_null($as)) { $as = $GLOBALS['FORUM_DRIVER']->get_guest_id(); } if (!$coming_out_of_queue) { $GLOBALS['SITE_DB']->query('DELETE FROM ' . get_table_prefix() . 'logged_mail_messages WHERE m_date_and_time<' . strval(time() - 60 * 60 * 24 * 14) . ' AND m_queued=0'); // Log it all for 2 weeks, then delete $through_queue = !$bypass_queue && (get_option('mail_queue_debug') === '1' || get_option('mail_queue') === '1' && cron_installed()); $GLOBALS['SITE_DB']->query_insert('logged_mail_messages', array('m_subject' => substr($subject_tag, 0, 255), 'm_message' => $message_raw, 'm_to_email' => serialize($to_email), 'm_to_name' => serialize($to_name), 'm_from_email' => $from_email, 'm_from_name' => $from_name, 'm_priority' => $priority, 'm_attachments' => serialize($attachments), 'm_no_cc' => $no_cc ? 1 : 0, 'm_as' => $as, 'm_as_admin' => $as_admin ? 1 : 0, 'm_in_html' => $in_html ? 1 : 0, 'm_date_and_time' => time(), 'm_member_id' => get_member(), 'm_url' => get_self_url(true), 'm_queued' => $through_queue ? 1 : 0, 'm_template' => $mail_template), false, !$through_queue); // No errors if we don't NEED this to work if ($through_queue) { return NULL; } } if (count($attachments) == 0) { $attachments = NULL; } global $SENDING_MAIL; if ($SENDING_MAIL) { return NULL; } $SENDING_MAIL = true; // To and from, and language $staff_address = get_option('staff_address'); if (is_null($to_email)) { $to_email = array($staff_address); } $to_email_new = array(); foreach ($to_email as $test_address) { if ($test_address != '') { $to_email_new[] = $test_address; } } $to_email = $to_email_new; if ($to_email == array()) { $SENDING_MAIL = false; return NULL; } if ($to_email[0] == $staff_address) { $lang = get_site_default_lang(); } else { $lang = user_lang(); if (method_exists($GLOBALS['FORUM_DRIVER'], 'get_member_from_email_address')) { $member_id = $GLOBALS['FORUM_DRIVER']->get_member_from_email_address($to_email[0]); if (!is_null($member_id)) { $lang = get_lang($member_id); } } } if (is_null($to_name)) { if ($to_email[0] == $staff_address) { $to_name = get_site_name(); } else { $to_name = ''; } } if ($from_email == '') { $from_email = get_option('staff_address'); } if ($from_name == '') { $from_name = get_site_name(); } $from_email = str_replace("\r", '', $from_email); $from_email = str_replace("\n", '', $from_email); $from_name = str_replace("\r", '', $from_name); $from_name = str_replace("\n", '', $from_name); $theme = method_exists($GLOBALS['FORUM_DRIVER'], 'get_theme') ? $GLOBALS['FORUM_DRIVER']->get_theme() : 'default'; if ($theme == 'default') { $theme = $GLOBALS['FORUM_DRIVER']->get_theme(''); // ... So get theme of welcome zone } // Line termination is fiddly. It is safer to rely on sendmail supporting \n than undetectable-qmail/postfix-masquerading-as-sendmail not supporting the correct \r\n /*$sendmail_path=ini_get('sendmail_path'); if ((strpos($sendmail_path,'qmail')!==false) || (strpos($sendmail_path,'sendmail')!==false)) $line_term="\n"; else $line_term="\r\n"; */ if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' || get_option('smtp_sockets_use') == '1') { $line_term = "\r\n"; /*} elseif (strtoupper(substr(PHP_OS,0,3))=='MAC') { $line_term="\r";*/ } else { $line_term = "\n"; } // We use the boundary to seperate message parts $_boundary = uniqid('ocPortal', true); $boundary = $_boundary . '_1'; $boundary2 = $_boundary . '_2'; $boundary3 = $_boundary . '_3'; // Our subject $subject = do_template('MAIL_SUBJECT', array('_GUID' => '44a57c666bb00f96723256e26aade9e5', 'SUBJECT_TAG' => $subject_tag), $lang, false, NULL, '.tpl', 'templates', $theme); $tightened_subject = $subject->evaluate($lang); // Note that this is slightly against spec, because characters aren't forced to be printable us-ascii. But it's better we allow this (which works in practice) than risk incompatibility via charset-base64 encoding. $tightened_subject = str_replace(chr(10), '', $tightened_subject); $tightened_subject = str_replace(chr(13), '', $tightened_subject); $regexp = '#^[\\x' . dechex(32) . '-\\x' . dechex(126) . ']*$#'; if (preg_match($regexp, $tightened_subject) == 0) { $tightened_subject = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($tightened_subject) . "?="; } if (preg_match($regexp, $from_name) == 0) { $from_name = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($from_name) . "?="; } if (is_array($to_name)) { foreach ($to_name as $i => $_to_name) { if (preg_match($regexp, $_to_name) == 0) { $to_name[$i] = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($_to_name) . "?="; } } } else { if (preg_match($regexp, $to_name) == 0) { $to_name = '=?' . do_lang('charset', NULL, NULL, NULL, $lang) . '?B?' . base64_encode($to_name) . "?="; } } $simplify_when_can = true; // Used for testing. Not actually needed // Evaluate message. Needs doing early so we know if we have any headers $GLOBALS['NO_LINK_TITLES'] = true; global $LAX_COMCODE; $temp = $LAX_COMCODE; $LAX_COMCODE = true; $html_content = comcode_to_tempcode($message_raw, $as, $as_admin); $LAX_COMCODE = $temp; $GLOBALS['NO_LINK_TITLES'] = false; $attachments = array_merge(is_null($attachments) ? array() : $attachments, $EMAIL_ATTACHMENTS); // Headers $website_email = get_option('website_email'); if ($website_email == '') { $website_email = $from_email; } if (get_value('use_true_from') !== '1') { $headers = 'From: "' . $from_name . '" <' . $website_email . '>' . $line_term; } else { $headers = 'From: <' . $from_email . '>' . $line_term; } $headers .= 'Reply-To: <' . $from_email . '>' . $line_term; $headers .= 'Return-Path: <' . $website_email . '>' . $line_term; $headers .= 'X-Sender: <' . $website_email . '>' . $line_term; $cc_address = $no_cc ? '' : get_option('cc_address'); if ($cc_address != '' && !in_array($cc_address, $to_email)) { $headers .= (get_option('bcc') == '1' ? 'Bcc: <' : 'Cc: <') . $cc_address . '>' . $line_term; } $headers .= 'Message-ID: <' . $_boundary . '@' . get_domain() . '>' . $line_term; $headers .= 'X-Priority: ' . strval($priority) . $line_term; $brand_name = get_value('rebrand_name'); if (is_null($brand_name)) { $brand_name = 'ocPortal'; } $headers .= 'X-Mailer: ' . $brand_name . $line_term; $headers .= 'MIME-Version: 1.0' . $line_term; if (!is_null($attachments) || !$simplify_when_can) { $headers .= 'Content-Type: multipart/mixed;' . "\n\t" . 'boundary="' . $boundary . '"'; } else { $headers .= 'Content-Type: multipart/alternative;' . "\n\t" . 'boundary="' . $boundary2 . '"'; } $sending_message = ''; $sending_message .= 'This is a multi-part message in MIME format.' . $line_term . $line_term; if (!is_null($attachments) || !$simplify_when_can) { $sending_message .= '--' . $boundary . $line_term; $sending_message .= 'Content-Type: multipart/alternative;' . "\n\t" . 'boundary="' . $boundary2 . '"' . $line_term . $line_term . $line_term; } global $CID_IMG_ATTACHMENT; $CID_IMG_ATTACHMENT = array(); // Message starts (actually: it is kind of in header form also as it uses mime multi-part) if (!$in_html) { $_html_content = $html_content->evaluate($lang); $_html_content = preg_replace('#(keep|for)_session=[\\d\\w]*#', 'filtered=1', $_html_content); $message_html = strpos($_html_content, '<html') !== false ? make_string_tempcode($_html_content) : do_template($mail_template, array('_GUID' => 'b23069c20202aa59b7450ebf8d49cde1', 'CSS' => '{CSS}', 'LOGOURL' => get_logo_url(''), 'LANG' => $lang, 'TITLE' => $subject, 'CONTENT' => $_html_content), $lang, false, NULL, '.tpl', 'templates', $theme); $css = css_tempcode(true, true, $message_html->evaluate($lang), $theme); $_css = $css->evaluate($lang); if (get_option('allow_ext_images') != '1') { $_css = preg_replace_callback('#url\\(["\']?(http://[^"]*)["\']?\\)#U', '_mail_css_rep_callback', $_css); } $html_evaluated = $message_html->evaluate($lang); $html_evaluated = str_replace('{CSS}', $_css, $html_evaluated); // Cleanup the Comcode a bit $message_plain = comcode_to_clean_text($message_raw); } else { $html_evaluated = $message_raw; } $base64_encode = get_value('base64_emails') === '1'; // More robust, but more likely to be spam-blocked, and some servers can scramble it. // Plain version if (!$in_html) { $sending_message .= '--' . $boundary2 . $line_term; $sending_message .= 'Content-Type: text/plain; charset=' . (preg_match($regexp, $message_plain) == 0 ? do_lang('charset', NULL, NULL, NULL, $lang) : 'us-ascii') . $line_term; // '; name="message.txt"'. Outlook doesn't like: makes it think it's an attachment if ($base64_encode) { $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term . $line_term; $sending_message .= chunk_split(base64_encode(unixify_line_format($message_plain)) . $line_term, 76, $line_term); } else { $sending_message .= 'Content-Transfer-Encoding: 8bit' . $line_term . $line_term; $sending_message .= wordwrap(str_replace(chr(10), $line_term, unixify_line_format($message_plain)) . $line_term, 998, $line_term); } } // HTML version $sending_message .= '--' . $boundary2 . $line_term; $sending_message .= 'Content-Type: multipart/related;' . "\n\t" . 'type="text/html";' . "\n\t" . 'boundary="' . $boundary3 . '"' . $line_term . $line_term . $line_term; $sending_message .= '--' . $boundary3 . $line_term; $sending_message .= 'Content-Type: text/html; charset=' . (preg_match($regexp, $html_evaluated) == 0 ? do_lang('charset', NULL, NULL, NULL, $lang) : 'us-ascii') . $line_term; // .'; name="message.html"'. Outlook doesn't like: makes it think it's an attachment if (get_option('allow_ext_images') != '1') { $html_evaluated = preg_replace_callback('#<img\\s([^>]*)src="(http://[^"]*)"#U', '_mail_img_rep_callback', $html_evaluated); $matches = array(); foreach (array('#<([^"<>]*\\s)style="([^"]*)"#', '#<style( [^<>]*)?' . '>(.*)</style>#Us') as $over) { $num_matches = preg_match_all($over, $html_evaluated, $matches); for ($i = 0; $i < $num_matches; $i++) { $altered_inner = preg_replace_callback('#url\\(["\']?(http://[^"]*)["\']?\\)#U', '_mail_css_rep_callback', $matches[2][$i]); if ($matches[2][$i] != $altered_inner) { $altered_outer = str_replace($matches[2][$i], $altered_inner, $matches[0][$i]); $html_evaluated = str_replace($matches[0][$i], $altered_outer, $html_evaluated); } } } } if ($base64_encode) { $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term . $line_term; $sending_message .= chunk_split(base64_encode(unixify_line_format($html_evaluated)) . $line_term, 76, $line_term); } else { $sending_message .= 'Content-Transfer-Encoding: 8bit' . $line_term . $line_term; // Requires RFC 1652 $sending_message .= wordwrap(str_replace(chr(10), $line_term, unixify_line_format($html_evaluated)) . $line_term, 998, $line_term); } $total_filesize = 0; foreach ($CID_IMG_ATTACHMENT as $id => $img) { $sending_message .= '--' . $boundary3 . $line_term; $file_path_stub = convert_url_to_path($img); $mime_type = get_mime_type(get_file_extension($img)); $filename = basename($img); if (!is_null($file_path_stub)) { $total_filesize += @filesize($file_path_stub); if ($total_filesize > 1024 * 1024 * 5) { continue; } // Too large to process into an email $file_contents = @file_get_contents($file_path_stub); } else { $file_contents = http_download_file($img, NULL, false); $total_filesize += strlen($file_contents); if ($total_filesize >= 1024 * 1024 * 5) { continue; } // Too large to process into an email if (!is_null($GLOBALS['HTTP_DOWNLOAD_MIME_TYPE'])) { $mime_type = $GLOBALS['HTTP_DOWNLOAD_MIME_TYPE']; } if (!is_null($GLOBALS['HTTP_FILENAME'])) { $filename = $GLOBALS['HTTP_FILENAME']; } } $sending_message .= 'Content-Type: ' . str_replace("\r", '', str_replace("\n", '', $mime_type)) . $line_term; $sending_message .= 'Content-ID: <' . $id . '>' . $line_term; $sending_message .= 'Content-Disposition: inline; filename="' . str_replace("\r", '', str_replace("\n", '', $filename)) . '"' . $line_term; $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term . $line_term; if (is_string($file_contents)) { $sending_message .= chunk_split(base64_encode($file_contents), 76, $line_term); } } $sending_message .= $line_term . '--' . $boundary3 . '--' . $line_term . $line_term; $sending_message .= $line_term . '--' . $boundary2 . '--' . $line_term . $line_term; // Attachments if (!is_null($attachments)) { foreach ($attachments as $path => $filename) { $sending_message .= '--' . $boundary . $line_term; $sending_message .= 'Content-Type: ' . get_mime_type(get_file_extension($filename)) . $line_term; // .'; name="'.str_replace("\r",'',str_replace("\n",'',$filename)).'"' http://www.imc.org/ietf-822/old-archive2/msg02121.html $sending_message .= 'Content-Transfer-Encoding: base64' . $line_term; $sending_message .= 'Content-Disposition: attachment; filename="' . str_replace("\r", '', str_replace("\n", '', $filename)) . '"' . $line_term . $line_term; if (strpos($path, '://') === false) { $sending_message .= chunk_split(base64_encode(file_get_contents($path)), 76, $line_term); } else { require_code('files'); $sending_message .= chunk_split(base64_encode(http_download_file($path)), 76, $line_term); } } $sending_message .= $line_term . '--' . $boundary . '--' . $line_term; } // Support for SMTP sockets rather than PHP mail() $error = NULL; if (get_option('smtp_sockets_use') == '1') { $worked = false; $host = get_option('smtp_sockets_host'); $port = intval(get_option('smtp_sockets_port')); $errno = 0; $errstr = ''; foreach ($to_email as $i => $to) { $socket = @fsockopen($host, $port, $errno, $errstr, 30.0); if ($socket !== false) { $rcv = fread($socket, 1024); $base_url = parse_url(get_base_url()); $domain = $base_url['host']; // Login if necessary $username = get_option('smtp_sockets_username'); $password = get_option('smtp_sockets_password'); if ($username != '') { fwrite($socket, 'EHLO ' . $domain . "\r\n"); $rcv = fread($socket, 1024); fwrite($socket, "AUTH LOGIN\r\n"); $rcv = fread($socket, 1024); if (strtolower(substr($rcv, 0, 3)) == '334') { fwrite($socket, base64_encode($username) . "\r\n"); $rcv = fread($socket, 1024); if (strtolower(substr($rcv, 0, 3)) == '235' || strtolower(substr($rcv, 0, 3)) == '334') { fwrite($socket, base64_encode($password) . "\r\n"); $rcv = fread($socket, 1024); if (strtolower(substr($rcv, 0, 3)) == '235') { } else { $error = do_lang('MAIL_ERROR_CONNECT_PASSWORD') . ' (' . str_replace($password, '*', $rcv) . ')'; } } else { $error = do_lang('MAIL_ERROR_CONNECT_USERNAME') . ' (' . $rcv . ')'; } } else { $error = do_lang('MAIL_ERROR_CONNECT_AUTH') . ' (' . $rcv . ')'; } } else { fwrite($socket, 'HELO ' . $domain . "\r\n"); $rcv = fread($socket, 1024); } if (is_null($error)) { $smtp_from_address = get_option('smtp_from_address'); if ($smtp_from_address == '') { $smtp_from_address = $from_email; } fwrite($socket, 'MAIL FROM:<' . $website_email . ">\r\n"); $rcv = fread($socket, 1024); if (strtolower(substr($rcv, 0, 3)) == '250' || strtolower(substr($rcv, 0, 3)) == '251') { $sent_one = false; fwrite($socket, "RCPT TO:<" . $to_email[$i] . ">\r\n"); $rcv = fread($socket, 1024); if (strtolower(substr($rcv, 0, 3)) != '250' && strtolower(substr($rcv, 0, 3)) != '251') { $error = do_lang('MAIL_ERROR_TO') . ' (' . $rcv . ')' . ' ' . $to_email[$i]; } else { $sent_one = true; } if ($sent_one) { fwrite($socket, "DATA\r\n"); $rcv = fread($socket, 1024); if (strtolower(substr($rcv, 0, 3)) == '354') { $attractive_date = strftime('%d %B %Y %H:%M:%S', time()); $_to_name = preg_replace('#@.*$#', '', is_array($to_name) ? $to_name[$i] : $to_name); // preg_replace is because some servers may reject sending names that look like e-mail addresses. ocP tries this from recommend module. if (count($to_email) == 1) { if ($_to_name == '') { fwrite($socket, 'To: ' . $to_email[$i] . "\r\n"); } else { fwrite($socket, 'To: ' . $_to_name . ' <' . $to_email[$i] . '>' . "\r\n"); } } else { fwrite($socket, 'To: ' . $_to_name . "\r\n"); } fwrite($socket, 'Subject: ' . $tightened_subject . "\r\n"); fwrite($socket, 'Date: ' . $attractive_date . "\r\n"); $headers = preg_replace('#^\\.#m', '..', $headers); $sending_message = preg_replace('#^\\.#m', '..', $sending_message); fwrite($socket, $headers . "\r\n"); fwrite($socket, $sending_message); fwrite($socket, "\r\n.\r\n"); $rcv = fread($socket, 1024); fwrite($socket, "QUIT\r\n"); $rcv = fread($socket, 1024); } else { $error = do_lang('MAIL_ERROR_DATA') . ' (' . $rcv . ')'; } } } else { $error = do_lang('MAIL_ERROR_FROM') . ' (' . $rcv . ')'; } if (@fwrite($socket, "RSET\r\n") === false) { @fclose($socket); $socket = NULL; } else { $rcv = fread($socket, 1024); } } if (!is_null($socket)) { fclose($socket); } if (is_null($error)) { $worked = true; } } else { $error = do_lang('MAIL_ERROR_CONNECT', $host, strval($port)); } } } else { $worked = false; foreach ($to_email as $i => $to) { //exit($headers.chr(10).$sending_message); $GLOBALS['SUPPRESS_ERROR_DEATH'] = true; $additional = ''; if (get_option('enveloper_override') == '1') { $additional = '-f ' . $website_email; } $_to_name = preg_replace('#@.*$#', '', is_array($to_name) ? $to_name[$i] : $to_name); // preg_replace is because some servers may reject sending names that look like e-mail addresses. ocP tries this from recommend module. if ($_to_name == '' || strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') { $to_line = $to; } else { $to_line = '"' . $_to_name . '" <' . $to . '>'; } //if (function_exists('mb_language')) mb_language('en'); Stop overridden mbstring mail function from messing and base64'ing stuff. Actually we don't need this as we make sure to pass through as headers with blank message, bypassing any filtering. if (str_replace(array('on', 'true', 'yes'), array('1', '1', '1'), strtolower(ini_get('safe_mode'))) == '1') { $worked = mail($to_line, $tightened_subject, $sending_message, $headers); } else { $worked = mail($to_line, $tightened_subject, $sending_message, $headers, $additional); } if (!$worked && isset($php_errormsg)) { $error = $php_errormsg; } $GLOBALS['SUPPRESS_ERROR_DEATH'] = false; } } if (!$worked) { $SENDING_MAIL = false; if (get_param_integer('keep_hide_mail_failure', 0) == 0) { require_code('site'); attach_message(!is_null($error) ? make_string_tempcode($error) : do_lang_tempcode('MAIL_FAIL', escape_html(get_option('staff_address'))), 'warn'); } else { return warn_screen(get_page_title('ERROR_OCCURRED'), do_lang_tempcode('MAIL_FAIL', escape_html(get_option('staff_address')))); } } $SENDING_MAIL = false; return NULL; }
/** * Constructs the RSS reader: downloads the URL and parses it. Check $error after constructing. * * @param URLPATH The URL to the RSS we will be reading * @param boolean Whether the 'url' is actually a filesystem path */ function rss($url, $is_filesystem_path = false) { require_lang('rss'); $this->namespace_stack = array(); $this->tag_stack = array(); $this->attribute_stack = array(); $this->gleamed_feed = array(); $this->gleamed_items = array(); $this->feed_url = $url; $this->error = NULL; if (!function_exists('xml_parser_create')) { $this->error = do_lang_tempcode('XML_NEEDED'); return; } if (!$is_filesystem_path && url_is_local($url)) { $url = get_custom_base_url() . '/' . $url; } //echo $url;exit(); if ($is_filesystem_path) { $GLOBALS['HTTP_CHARSET'] = ''; $data = @file_get_contents($url); } else { $GLOBALS['HTTP_CHARSET'] = ''; $data = http_download_file($url, NULL, false); // if (!is_null($data)) break; } if (is_null($data)) { $this->error = do_lang('RSS_XML_MISSING', $url) . ' [' . $GLOBALS['HTTP_MESSAGE'] . ']'; } else { // Try and detect feed charset $exp = '#<\\?xml\\s+version\\s*=\\s*["\'][\\d\\.]+["\']\\s*(encoding\\s*=\\s*["\']([^"\'<>]+)["\'])?\\s*(standalone\\s*=\\s*["\']([^"\'<>]+)["\'])?\\s*\\?' . '>#'; $matches = array(); if (preg_match($exp, $data, $matches) != 0 && array_key_exists(2, $matches)) { $GLOBALS['HTTP_CHARSET'] = $matches[2]; if (strtolower($GLOBALS['HTTP_CHARSET']) == 'windows-1252') { $GLOBALS['HTTP_CHARSET'] = 'ISO-8859-1'; } } // Weed out if isn't supported if (is_null($GLOBALS['HTTP_CHARSET']) || !in_array(strtoupper($GLOBALS['HTTP_CHARSET']), array('ISO-8859-1', 'US-ASCII', 'UTF-8'))) { $GLOBALS['HTTP_CHARSET'] = 'UTF-8'; } // Our internal charset $parser_charset = get_charset(); if (!in_array(strtoupper($parser_charset), array('ISO-8859-1', 'US-ASCII', 'UTF-8'))) { $parser_charset = 'UTF-8'; } // Create and setup our parser $xml_parser = function_exists('xml_parser_create_ns') ? @xml_parser_create_ns($GLOBALS['HTTP_CHARSET']) : @xml_parser_create($GLOBALS['HTTP_CHARSET']); if ($xml_parser === false) { $this->error = do_lang_tempcode('XML_PARSING_NOT_SUPPORTED'); 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, $parser_charset); xml_set_element_handler($xml_parser, 'startElement', 'endElement'); xml_set_character_data_handler($xml_parser, 'startText'); //xml_set_external_entity_ref_handler($xml_parser,'extEntity'); if (function_exists('xml_set_start_namespace_decl_handler')) { xml_set_start_namespace_decl_handler($xml_parser, 'startNamespace'); } if (function_exists('xml_set_end_namespace_decl_handler')) { xml_set_end_namespace_decl_handler($xml_parser, 'endNameSpace'); } //$data=convert_to_internal_encoding($data); xml_parser does it for us, and we can't disable it- so run with it instead of our own. Shame as it's inferior. if (strpos($data, '<!ENTITY') === false) { $extra_data = "<" . "?xml version=\"1.0\" encoding=\"" . $GLOBALS['HTTP_CHARSET'] . "\" ?" . ">\n<!DOCTYPE atom [\n<!ENTITY nbsp \" \" >\n]>\n"; $data = preg_replace($exp, $extra_data, trim($data)); if ($extra_data != '' && strpos($data, $extra_data) === false) { $data = $extra_data . $data; } if (strtoupper($GLOBALS['HTTP_CHARSET']) == 'ISO-8859-1' || strtoupper($GLOBALS['HTTP_CHARSET']) == 'UTF-8') { $table = array_flip(get_html_translation_table(HTML_ENTITIES)); if (strtoupper($GLOBALS['HTTP_CHARSET']) == 'UTF-8') { foreach ($table as $x => $y) { $table[$x] = utf8_encode($y); } } unset($table['&']); unset($table['>']); unset($table['<']); $data = strtr($data, $table); } $convert_bad_entities = true; } else { $convert_bad_entities = false; if (strpos($data, "<" . "?xml") === false) { $data = "<" . "?xml version=\"1.0\" encoding=\"" . $GLOBALS['HTTP_CHARSET'] . "\" ?" . ">" . $data; } $data = preg_replace($exp, "<" . "?xml version=\"1.0\" encoding=\"" . $GLOBALS['HTTP_CHARSET'] . "\" ?" . ">", $data); // Strip out internal encoding (we already detected and sanitised it) } $data = unixify_line_format($data, $GLOBALS['HTTP_CHARSET']); // Fixes Windows characters if ($convert_bad_entities) { if (strtoupper(get_charset()) == 'ISO-8859-1') { $table = array_flip(get_html_translation_table(HTML_ENTITIES)); unset($table['&']); unset($table['>']); unset($table['<']); $data = strtr($data, $table); } } if (xml_parse($xml_parser, $data, true) == 0) { $this->error = do_lang('RSS_XML_ERROR', xml_error_string(xml_get_error_code($xml_parser)), strval(xml_get_current_line_number($xml_parser))); } @xml_parser_free($xml_parser); $new_items = array(); foreach ($this->gleamed_items as $i) { if (!isset($i['bogus']) || !$i['bogus']) { $new_items[] = $i; } } $this->gleamed_items = $new_items; } }
/** * The actualiser for importing a CSV file. * * @return tempcode The UI */ function _import_csv() { $title = get_page_title('IMPORT_MEMBER_CSV'); disable_php_memory_limit(); // Even though we split into chunks, PHP does leak memory :( $GLOBALS['HELPER_PANEL_PIC'] = 'pagepics/import_csv'; if (function_exists('set_time_limit')) { @set_time_limit(0); } require_lang('ocf'); require_code('ocf_members_action'); $default_password = post_param('default_password'); $num_added = 0; $num_edited = 0; $done = 0; $headings = $this->_get_csv_headings(); $all_cpfs = $GLOBALS['FORUM_DB']->query_select('f_custom_fields', array('id', 'cf_default', 'cf_type', 'cf_name'), NULL, 'ORDER BY cf_order'); foreach ($all_cpfs as $i => $c) { $c['text_original'] = get_translated_text($c['cf_name'], $GLOBALS['FORUM_DB']); $all_cpfs[$i] = $c; $headings[$c['text_original']] = NULL; } $_all_groups = $GLOBALS['FORUM_DRIVER']->get_usergroup_list(false, false, true); $all_groups = array_flip($_all_groups); $all_members = collapse_2d_complexity('id', 'm_username', $GLOBALS['FORUM_DB']->query_select('f_members', array('id', 'm_username'))); $all_members_flipped = array_flip($all_members); // Import require_code('uploads'); if (is_swf_upload(true) || array_key_exists('file', $_FILES) && is_uploaded_file($_FILES['file']['tmp_name'])) { $_csv_data = array(); $fixed_contents = unixify_line_format(file_get_contents($_FILES['file']['tmp_name'])); $myfile = @fopen($_FILES['file']['tmp_name'], 'wb'); if ($myfile !== false) { fwrite($myfile, $fixed_contents); fclose($myfile); } $myfile = fopen($_FILES['file']['tmp_name'], 'rb'); $del = ','; $csv_header = fgetcsv($myfile, 102400, $del); if ($csv_header === false) { warn_exit(do_lang_tempcode('NO_DATA_IMPORTED')); } if (count($csv_header) == 1 && strpos($csv_header[0], ';') !== false) { $del = ';'; rewind($myfile); $csv_header = fgetcsv($myfile, 102400, $del); } while (($csv_line = fgetcsv($myfile, 102400, $del)) !== false) { $line = array(); foreach ($csv_header as $i => $h) { $extracted_value = trim(unixify_line_format(array_key_exists($i, $csv_line) ? $csv_line[$i] : '')); if (strpos($h, ':') !== false) { $parts = explode(':', $h, 2); $h = trim($parts[0]); if ($extracted_value != '') { $extracted_value = $parts[1] . ': ' . $extracted_value; } } if (array_key_exists($h, $line)) { if ($extracted_value != '') { $line[$h] .= ($line[$h] != '' ? chr(10) : '') . $extracted_value; } } else { $line[$h] = $extracted_value; } } if (!array_key_exists('Username', $line) || $line['Username'] == '') { // Can we auto-generate it $forename = NULL; if (array_key_exists('Forenames', $line)) { $forename = $line['Forenames']; } if (array_key_exists('Forename', $line)) { $forename = $line['Forename']; } if (array_key_exists('First name', $line)) { $forename = $line['First name']; } if (array_key_exists('First Name', $line)) { $forename = $line['First Name']; } $surname = NULL; if (array_key_exists('Surname', $line)) { $surname = $line['Surname']; } if (array_key_exists('Last name', $line)) { $surname = $line['Last name']; } if (array_key_exists('Last Name', $line)) { $surname = $line['Last Name']; } if (!is_null($forename) || !is_null($surname)) { // Can we get a year too? $year = ''; foreach ($line as $tl_key => $tl_val) { if (substr($tl_key, 0, 4) == 'Year') { $year = $tl_val; break; } } if (strlen($year) == 4 && (substr($year, 0, 2) == '19' || substr($year, 0, 2) == '20')) { $year = substr($year, 2); } // Tidy up forename $_forename = preg_replace('#[^\\w]#', '', preg_replace('#[\\s\\.].*#', '', $forename)); // Tidy up surname (last bit strips like 'OBE') $_surname = preg_replace('#[^\\w]#', '', trim(preg_replace('#\\s*[A-Z\\d][A-Z\\d]+#', '', $surname))); // Put it together $line['Username'] = ucfirst($_forename) . ucfirst($_surname) . $year; } else { continue; // This field is needed } } $username = $line['Username']; $linked_id = NULL; if (array_key_exists('ID', $line)) { $linked_id = $line['ID'] != '' && array_key_exists(intval($line['ID']), $all_members) ? intval($line['ID']) : NULL; } if (is_null($linked_id)) { $linked_id = array_key_exists($username, $all_members_flipped) ? $all_members_flipped[$username] : NULL; } $new_member = is_null($linked_id); $email_address_key = 'E-mail address'; if (array_key_exists('Email address', $line)) { $email_address_key = 'Email address'; } if (array_key_exists('E-mail Address', $line)) { $email_address_key = 'E-mail Address'; } if (array_key_exists('Email Address', $line)) { $email_address_key = 'Email Address'; } if (array_key_exists('E-mail', $line)) { $email_address_key = 'E-mail'; } if (array_key_exists('Email', $line)) { $email_address_key = 'Email'; } $dob_key = 'Date of birth'; if (array_key_exists('Date Of Birth', $line)) { $dob_key = 'Date Of Birth'; } if (array_key_exists('DOB', $line)) { $dob_key = 'DOB'; } // If it's an edited member, add in their existing CSV details, so that if it's a partial merge it'll still work without deleting anything! if (!$new_member) { $member_groups = $GLOBALS['FORUM_DB']->query_select('f_group_members', array('gm_member_id', 'gm_group_id'), array('gm_validated' => 1, 'gm_member_id' => $linked_id)); $member_cpfs = list_to_map('mf_member_id', $GLOBALS['FORUM_DB']->query_select('f_member_custom_fields', array('*'), array('mf_member_id' => $linked_id), '', 1)); $this_record = $this->_get_csv_member_record($member_cpfs, $GLOBALS['FORUM_DRIVER']->get_member_row($linked_id), $_all_groups, $headings, $all_cpfs, $member_groups); // Remember "+" in PHP won't overwrite existing keys if (!array_key_exists($email_address_key, $line)) { unset($this_record['E-mail address']); } if (!array_key_exists($dob_key, $line)) { unset($this_record['Date of birth']); } $line += $this_record; } // Set up member row if (array_key_exists('Password', $line) && $line['Password'] != '') { $parts = explode('/', $line['Password']); $password = $parts[0]; $salt = array_key_exists(1, $parts) ? $parts[1] : NULL; $password_compatibility_scheme = array_key_exists(2, $parts) ? $parts[2] : NULL; } else { $password = NULL; $salt = NULL; $password_compatibility_scheme = NULL; } $matches = array(); if (array_key_exists($email_address_key, $line)) { $email_address = $line[$email_address_key]; } else { $email_address = NULL; } if (preg_match('#^([^\\s]*)\\s+\\(.*\\)$#', $email_address, $matches) != 0) { $email_address = $matches[1]; } if (preg_match('#^.*\\s+<(.*)>$#', $email_address, $matches) != 0) { $email_address = $matches[1]; } if (array_key_exists($dob_key, $line)) { $parts = explode('/', $line[$dob_key]); $dob_day = array_key_exists(2, $parts) ? intval($parts[2]) : NULL; $dob_month = array_key_exists(1, $parts) ? intval($parts[1]) : NULL; $dob_year = array_key_exists(0, $parts) ? intval($parts[0]) : NULL; } else { $dob_day = NULL; $dob_month = NULL; $dob_year = NULL; } $validated = array_key_exists('Validated', $line) ? strtoupper($line['Validated']) == 'YES' || $line['Validated'] == '1' || strtoupper($line['Validated']) == 'Y' || strtoupper($line['Validated']) == 'ON' ? 1 : 0 : 1; if (array_key_exists('Join time', $line)) { if (strpos($line['Join time'], '-') !== false) { $parts = explode('-', $line['Join time']); } else { $parts = explode('/', $line['Join time']); } if (!array_key_exists(1, $parts)) { $parts[1] = '1'; } if (!array_key_exists(2, $parts)) { $parts[2] = '1'; } if (strlen($parts[2]) != 4) { $join_time = mktime(0, 0, 0, intval($parts[1]), intval($parts[2]), intval($parts[0])); // yy(yy)-mm-dd } else { $join_time = mktime(0, 0, 0, intval($parts[1]), intval($parts[0]), intval($parts[2])); // dd-mm-yyyy } if ($join_time > time()) { $join_time = time(); } // Fixes MySQL out of range error that could happen } else { $join_time = NULL; } $avatar_url = array_key_exists('Avatar', $line) ? $line['Avatar'] : ''; if (!is_null($avatar_url)) { if (substr($avatar_url, 0, strlen(get_base_url() . '/')) == get_base_url() . '/') { $avatar_url = substr($avatar_url, strlen(get_base_url() . '/')); } } $signature = array_key_exists('Signature', $line) ? $line['Signature'] : ''; $is_perm_banned = array_key_exists('Banned', $line) ? strtoupper($line['Banned']) == 'YES' || $line['Banned'] == '1' || strtoupper($line['Banned']) == 'Y' || strtoupper($line['Banned']) == 'ON' ? 1 : 0 : 0; $reveal_age = array_key_exists('Reveal age', $line) ? strtoupper($line['Reveal age']) == 'YES' || $line['Reveal age'] == '1' || strtoupper($line['Reveal age']) == 'Y' || strtoupper($line['Reveal age']) == 'ON' ? 1 : 0 : 0; $language = array_key_exists('Language', $line) ? $line['Language'] : ''; $allow_emails = array_key_exists('Accept member e-mails', $line) ? strtoupper($line['Accept member e-mails']) == 'YES' || $line['Accept member e-mails'] == '1' || strtoupper($line['Accept member e-mails']) == 'Y' || strtoupper($line['Accept member e-mails']) == 'ON' ? 1 : 0 : 0; $allow_emails_from_staff = array_key_exists('Opt-in', $line) ? strtoupper($line['Opt-in']) == 'YES' || $line['Opt-in'] == '1' || strtoupper($line['Opt-in']) == 'Y' || strtoupper($line['Opt-in']) == 'ON' ? 1 : 0 : 0; $primary_group = NULL; $groups = NULL; if (array_key_exists('Usergroup', $line)) { $parts = explode('/', $line['Usergroup']); foreach ($parts as $p) { if (!array_key_exists($p, $all_groups)) { require_code('ocf_groups_action'); $g_id = ocf_make_group($p, 0, 0, 0, ''); $all_groups[$p] = $g_id; $_group_edit_url = build_url(array('page' => 'admin_ocf_groups', 'type' => '_ed', 'id' => $g_id), get_module_zone('admin_ocf_groups')); $group_edit_url = $_group_edit_url->evaluate(); attach_message(do_lang_tempcode('MEMBER_IMPORT_GROUP_ADDED', escape_html($p), escape_html($group_edit_url)), 'inform'); } } $primary_group = $all_groups[$parts[0]]; unset($parts[0]); $groups = array(); foreach ($parts as $p) { $groups[] = $all_groups[$p]; } } $photo_url = array_key_exists('Photo', $line) ? $line['Photo'] : ''; if ($photo_url != '') { require_code('images'); $photo_thumb_url = 'uploads/ocf_photos_thumbs/' . uniqid('', true) . '.png'; convert_image($photo_url, $photo_thumb_url, -1, -1, intval(get_option('thumb_width')), false); } else { $photo_thumb_url = ''; } $custom_fields = array(); foreach ($all_cpfs as $cpf) { $custom_fields[$cpf['id']] = array_key_exists($cpf['text_original'], $line) ? $line[$cpf['text_original']] : $cpf['cf_default']; if (!array_key_exists($cpf['text_original'], $line) && $cpf['cf_type'] == 'list') { $parts = explode($custom_fields[$cpf['id']], '|'); $custom_fields[$cpf['id']] = $parts[0]; } if ($cpf['cf_type'] == 'integer') { $custom_fields[$cpf['id']] = intval($custom_fields[$cpf['id']]); } elseif ($cpf['cf_type'] == 'tick') { $custom_fields[$cpf['id']] = strtoupper($custom_fields[$cpf['id']]) == 'YES' || strtoupper($custom_fields[$cpf['id']]) == 'Y' || strtoupper($custom_fields[$cpf['id']]) == 'ON' || $custom_fields[$cpf['id']] == '1' ? 1 : 0; } elseif ($cpf['cf_type'] == 'short_text' || $cpf['cf_type'] == 'short_trans') { $custom_fields[$cpf['id']] = substr(str_replace(chr(10), ', ', str_replace(',' . chr(10), chr(10), $custom_fields[$cpf['id']])), 0, 255); } elseif ($cpf['cf_type'] == 'long_text' || $cpf['cf_type'] == 'long_trans') { //$custom_fields[$cpf['id']]=$custom_fields[$cpf['id']]; } elseif ($cpf['cf_type'] == 'float') { if (preg_match('#^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\n(\\d\\d\\d\\d)$#', $custom_fields[$cpf['id']]) != 0) { $parts = explode(chr(10), $custom_fields[$cpf['id']], 2); $month_lookup = array('Jan' => 0.1, 'Feb' => 0.2, 'Mar' => 0.3, 'Apr' => 0.4, 'May' => 0.5, 'Jun' => 0.6, 'Jul' => 0.7, 'Aug' => 0.8, 'Sep' => 0.9, 'Oct' => 0.1, 'Nov' => 0.11, 'Dec' => 0.12); $custom_fields[$cpf['id']] = floatval($parts[1]) + $month_lookup[$parts[0]]; } else { $custom_fields[$cpf['id']] = floatval($custom_fields[$cpf['id']]); } } unset($line[$cpf['text_original']]); } foreach (array_keys($headings) as $h) { unset($line[$h]); } unset($line[$email_address_key]); unset($line[$dob_key]); foreach ($line as $h => $f) { $cf_id = ocf_make_custom_field($h, 0, '', '', 0, 0, 0, 0, 'long_text'); $_cpf_edit_url = build_url(array('page' => 'admin_ocf_customprofilefields', 'type' => '_ed', 'id' => $cf_id), get_module_zone('admin_ocf_customprofilefields')); $cpf_edit_url = $_cpf_edit_url->evaluate(); attach_message(do_lang_tempcode('MEMBER_IMPORT_CPF_ADDED', escape_html($h), escape_html($cpf_edit_url)), 'inform'); $custom_fields[$cf_id] = $f; $all_cpfs[] = array('id' => $cf_id, 'cf_default' => '', 'text_original' => $h, 'cf_type' => 'short_line'); } if ($new_member) { if (is_null($password)) { $password = $default_password; } if (is_null($salt)) { $salt = ''; } if (is_null($password_compatibility_scheme)) { $password_compatibility_scheme = ''; } $linked_id = ocf_make_member($username, $password, is_null($email_address) ? '' : $email_address, $groups, $dob_day, $dob_month, $dob_year, $custom_fields, NULL, $primary_group, $validated, $join_time, NULL, '', $avatar_url, $signature, $is_perm_banned, get_option('default_preview_guests') == '1' ? 1 : 0, $reveal_age, '', $photo_url, $photo_thumb_url, 1, 1, $language, $allow_emails, $allow_emails_from_staff, '', NULL, '', false, $password_compatibility_scheme, $salt, 1, NULL, NULL, 0, '*', ''); $all_members[$linked_id] = $username; $all_members_flipped[$username] = $linked_id; $num_added++; } else { $old_username = $GLOBALS['OCF_DRIVER']->get_member_row_field($linked_id, 'm_username'); if ($old_username == $username) { $username = NULL; } ocf_edit_member($linked_id, $email_address, NULL, $dob_day, $dob_month, $dob_year, NULL, $primary_group, $custom_fields, NULL, $reveal_age, NULL, NULL, $language, $allow_emails, $allow_emails_from_staff, $validated, $username, $password, NULL, NULL, NULL, NULL, NULL, $join_time, $avatar_url, $signature, $is_perm_banned, $photo_url, $photo_thumb_url, $salt, $password_compatibility_scheme, true); $num_edited++; } $done++; } fclose($myfile); } else { warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN_UPLOAD')); } if ($done == 0) { warn_exit(do_lang_tempcode('NO_DATA_IMPORTED')); } breadcrumb_set_parents(array(array('_SEARCH:admin_ocf_join:menu', do_lang_tempcode('MEMBERS')), array('_SEARCH:admin_ocf_join:import_csv', do_lang_tempcode('IMPORT_MEMBER_CSV')))); breadcrumb_set_self(do_lang_tempcode('DONE')); return inform_screen($title, do_lang_tempcode('NUM_MEMBERS_IMPORTED', escape_html(integer_format($num_added)), escape_html(integer_format($num_edited)))); }
/** * The UI to edit a CSS file. * * @return tempcode The UI */ function edit_css() { $file = filter_naughty(get_param('file', 'global.css')); $title = get_page_title('_EDIT_CSS', true, array($file)); if (get_option('editarea') == '1') { $GLOBALS['EXTRA_HEAD']->attach(make_string_tempcode(' <script language="javascript" type="text/javascript" src="' . get_base_url() . '/data/editarea/edit_area_full.js"></script> <script type="text/javascript">// <![CDATA[ editAreaLoader.init({ id : "css" ,syntax: "css" ,start_highlight: true ,language: "' . (file_exists(get_file_base() . '/data/editarea/langs/' . strtolower(user_lang())) ? strtolower(user_lang()) : 'en') . '" ,allow_resize: true ,toolbar: "search, go_to_line, fullscreen, |, undo, redo, |, select_font,|, reset_highlight, word_wrap" }); //]]></script>')); } $GLOBALS['HELPER_PANEL_TEXT'] = comcode_lang_string('DOC_CSS'); $GLOBALS['HELPER_PANEL_TUTORIAL'] = 'tut_markup'; require_javascript('javascript_ajax'); $theme = get_param('theme', ''); if ($theme == '') { return $this->choose_theme($title); } //if ((get_file_base()!=get_custom_file_base()) && ($theme=='default')) warn_exit(do_lang_tempcode('SHARED_INSTALL_PROHIBIT')); $url = build_url(array('page' => '_SELF', 'file' => $file, 'type' => '_edit_css'), '_SELF'); if (get_param('restore_from', '') != '') { $file .= '.' . get_param('restore_from'); } $path = get_custom_file_base() . '/themes/' . filter_naughty($theme) . '/css_custom/' . $file; if (!file_exists($path)) { $path = get_custom_file_base() . '/themes/' . filter_naughty($theme) . '/css/' . $file; } if (!file_exists($path)) { $path = get_custom_file_base() . '/themes/default/css_custom/' . $file; } if (!file_exists($path)) { $path = get_file_base() . '/themes/default/css/' . $file; } $css = unixify_line_format(file_get_contents($path)); $file = preg_replace('#\\.\\d+#', '', $file); $old_contents = @file_get_contents(get_file_base() . '/themes/default/css/' . $file); if ($old_contents === false) { $old_contents = ''; } $GLOBALS['SEO_TITLE'] = $file; $entries = new ocp_tempcode(); $advanced_mode = get_param_integer('advanced_mode', 0); if ($advanced_mode == 1) { require_javascript('javascript_theme_colours'); global $CSS_MATCHES; $CSS_MATCHES = array(); $css = preg_replace_callback('#\\#[\\da-f][\\da-f][\\da-f][\\da-f][\\da-f][\\da-f]#i', 'css_preg', $css); foreach ($CSS_MATCHES as $id => $color) { $pos = strpos($css, '<color-' . $id . '>'); $section_start = $pos; do { $section_start = strrpos(substr($css, 0, $section_start), '{'); if ($section_start === false || $section_start < 5) { break; } } while ($css[$section_start - 2] == '*' || $css[$section_start - 1] != ' '); $section_line_start = strrpos(substr($css, 0, $section_start), chr(10)); $line_start = strrpos(substr($css, 0, $pos), chr(10)); $context1 = substr($css, $section_line_start, $section_start - $section_line_start); $context2 = substr($css, $line_start, $pos - $line_start); $context = $context1 . ' => ' . trim($context2); $entries->attach(do_template('THEME_COLOUR_CHOOSER', array('_GUID' => 'a42ef9daa06a95f5bb9d715aab1bd887', 'COLOR' => $color, 'NAME' => 'c' . strval($id), 'CONTEXT' => trim($context)))); // break; } } $switch_string = $advanced_mode == 1 ? do_lang_tempcode('SWITCH_TO_SIMPLE_MODE') : do_lang_tempcode('SWITCH_TO_ADVANCED_MODE'); $switch_icon = $advanced_mode == 1 ? 'page/simple' : 'page/advanced'; $switch_url = build_url(array('page' => '_SELF', 'type' => 'edit_css', 'file' => $file, 'theme' => $theme, 'advanced_mode' => 1 - $advanced_mode), '_SELF'); // Revision history $filesarray = $this->get_css_revisions($theme, get_param('file', 'global.css')); rsort($filesarray); $i = 0; $revision_history = new ocp_tempcode(); $max = intval(get_option('number_revisions_show')); $last_path = $path; foreach ($filesarray as $time) { // Find who did the revision $editor = $GLOBALS['SITE_DB']->query_value_null_ok('adminlogs', 'the_user', array('date_and_time' => $time, 'the_type' => 'EDIT_CSS', 'param_a' => $theme)); if (is_null($editor)) { $editor = do_lang('UNKNOWN'); } else { $editor = $GLOBALS['FORUM_DRIVER']->get_username($editor); if (is_null($editor)) { $editor = do_lang('UNKNOWN'); } } $date = is_null($time) ? do_lang('UNKNOWN') : get_timezoned_date(intval($time)); $url2 = get_custom_base_url() . '/themes/' . $theme . '/css_custom/' . $file . '.' . $time; $old_file = get_custom_file_base() . '/themes/' . $theme . '/css_custom/' . $file . '.' . $time; $size = filesize($old_file); $restore_url = build_url(array('page' => '_SELF', 'type' => 'edit_css', 'file' => $file, 'theme' => $theme, 'restore_from' => $time), '_SELF'); require_code('diff'); if (function_exists('diff_simple')) { $rendered_diff = diff_simple($old_file, $last_path); $last_path = $old_file; $revision_history->attach(do_template('REVISION_HISTORY_LINE', array('_GUID' => 'dba0110692775615152be1da850bc1d4', 'RENDERED_DIFF' => $rendered_diff, 'REFERENCE_POINT_EXACT' => true, 'EDITOR' => $editor, 'DATE' => $date, 'DATE_RAW' => $time, 'RESTORE_URL' => $restore_url, 'URL' => $url2, 'SIZE' => clean_file_size($size)))); $i++; } if ($i == $max) { break; } } if ($i != 0 && get_param('restore_from', '') == '') { $revision_history = do_template('REVISION_HISTORY_WRAP', array('_GUID' => '330a153101f131ff63445a694aa149c4', 'CONTENT' => $revision_history)); } elseif ($i != 0) { $revision_history = do_template('REVISION_RESTORE'); } require_code('form_templates'); list($warning_details, $ping_url) = handle_conflict_resolution($file); breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('MANAGE_THEMES')), array('_SELF:_SELF:choose_css:theme=' . $theme, do_lang_tempcode('CHOOSE')))); return do_template('THEME_EDIT_CSS_SCREEN', array('_GUID' => '3e34b2f44d7a73202f1bb475fd4ac593', 'PING_URL' => $ping_url, 'OLD_CONTENTS' => $old_contents, 'WARNING_DETAILS' => $warning_details, 'REVISION_HISTORY' => $revision_history, 'SWITCH_ICON' => $switch_icon, 'SWITCH_STRING' => $switch_string, 'SWITCH_URL' => $switch_url, 'TITLE' => $title, 'THEME' => $theme, 'CSS' => $css, 'URL' => $url, 'FILE' => $file, 'ENTRIES' => $entries)); }
/** * Convert the specified comcode (unknown format) into a tempcode tree. You shouldn't output the tempcode tree to the browser, as it looks really horrible. If you are in a rare case where you need to output directly (not through templates), you should call the evaluate method on the tempcode object, to convert it into a string. * * @param LONG_TEXT The comcode to convert * @param ?MEMBER The member the evaluation is running as. This is a security issue, and you should only run as an administrator if you have considered where the comcode came from carefully (NULL: current member) * @param boolean Whether to explicitly execute this with admin rights. There are a few rare situations where this should be done, for data you know didn't come from a member, but is being evaluated by one. * @param ?integer The position to conduct wordwrapping at (NULL: do not conduct word-wrapping) * @param ?string A special identifier that can identify this resource in a sea of our resources of this class; usually this can be ignored, but may be used to provide a binding between Javascript in evaluated comcode, and the surrounding environment (NULL: no explicit binding) * @param ?object The database connection to use (NULL: standard site connection) * @param boolean Whether to parse so as to create something that would fit inside a semihtml tag. It means we generate HTML, with Comcode written into it where the tag could never be reverse-converted (e.g. a block). * @param boolean Whether this is being pre-parsed, to pick up errors before row insertion. * @param boolean Whether to treat this whole thing as being wrapped in semihtml, but apply normal security otherwise. * @param boolean Whether we are only doing this parse to find the title structure * @param boolean Whether to only check the Comcode. It's best to use the check_comcode function which will in turn use this parameter. * @param ?array A list of words to highlight (NULL: none) * @param ?MEMBER The member we are running on behalf of, with respect to how attachments are handled; we may use this members attachments that are already within this post, and our new attachments will be handed to this member (NULL: member evaluating) * @return tempcode The tempcode generated */ function _comcode_to_tempcode($comcode, $source_member = NULL, $as_admin = false, $wrap_pos = 60, $pass_id = NULL, $connection = NULL, $semiparse_mode = false, $preparse_mode = false, $is_all_semihtml = false, $structure_sweep = false, $check_only = false, $highlight_bits = NULL, $on_behalf_of_member = NULL) { /*if (get_option('anti_leech',true)==='1') No, better to see it, even if custom settings are lost { unset($REVERSABLE_TAGS['attachment_safe']); unset($REVERSABLE_TAGS['attachment2']); }*/ if (count($_POST) != 0) { @header('X-XSS-Protection: 0'); } if (is_null($connection)) { $connection = $GLOBALS['SITE_DB']; } if (is_null($source_member)) { $source_member = function_exists('get_member') ? get_member() : 0; } if (!$structure_sweep) { $comcode = unixify_line_format($comcode); } // Done already if this is a structure sweep // Ensures the 'title' tags are incremental with their anchors global $STRUCTURE_LIST; $old_structure_list = $STRUCTURE_LIST; $STRUCTURE_LIST = array(); if (substr($comcode, 0, 8) == '<comcode') { require_code('comcode_xml'); if (!$as_admin) { check_specific_permission('comcode_dangerous', NULL, $source_member); } $parser = new comcode_xml_to_tempcode($comcode, $source_member, $wrap_pos, $pass_id, $connection, $semiparse_mode, $preparse_mode, $is_all_semihtml, $structure_sweep, $check_only, $on_behalf_of_member); $ret = $parser->tempcode; } else { require_code('comcode_text'); $ret = comcode_text_to_tempcode($comcode, $source_member, $as_admin, $wrap_pos, $pass_id, $connection, $semiparse_mode, $preparse_mode, $is_all_semihtml, $structure_sweep, $check_only, $highlight_bits, $on_behalf_of_member); } $STRUCTURE_LIST = $old_structure_list; // Restore, so that Comcode pages being loaded up in search results don't get skewed TOC's return $ret; }
/** * Standard actualiser to import catalogue entries * * @return tempcode The UI */ function _import_catalogue() { require_code('catalogues2'); check_specific_permission('mass_import'); $catalog_root = NULL; $title = get_page_title('CATALOGUE_IMPORT'); $catalogue_name = get_param('catalogue_name'); $categories = array(); $fields = $GLOBALS['SITE_DB']->query_select('catalogue_fields', array('*'), array('c_name' => $catalogue_name)); $catsrow = $GLOBALS['SITE_DB']->query("SELECT t1.id,t2.text_original,t1.cc_parent_id FROM " . $GLOBALS['SITE_DB']->get_table_prefix() . "catalogue_categories t1," . $GLOBALS['SITE_DB']->get_table_prefix() . "translate t2 WHERE t1.cc_title=t2.id AND t1.c_name='" . db_escape_string($catalogue_name) . "'"); foreach ($catsrow as $values) { $categories[$values['text_original']] = $values['id']; // Root category is 'default' category for catalogue importing (category with same name as catalogue) if (!array_key_exists($catalogue_name, $categories) && is_null($values['cc_parent_id'])) { $categories[$catalogue_name] = $values['id']; } } require_code('uploads'); $csv_name = NULL; if (is_swf_upload(true) && array_key_exists('file_novalidate', $_FILES) || array_key_exists('file_novalidate', $_FILES) && is_uploaded_file($_FILES['file_novalidate']['tmp_name'])) { $csv_name = $_FILES['file_novalidate']['tmp_name']; } if (is_null($csv_name)) { warn_exit(do_lang_tempcode('IMPROPERLY_FILLED_IN')); } $fixed_contents = unixify_line_format(file_get_contents($csv_name)); $myfile = @fopen($csv_name, 'wb'); if ($myfile !== false) { fwrite($myfile, $fixed_contents); fclose($myfile); } $handle = fopen($csv_name, 'rb'); $del = ','; $csv_field_titles = fgetcsv($handle, 1000, $del); if (count($csv_field_titles) == 1 && strpos($csv_field_titles[0], ';') !== false) { $del = ';'; rewind($handle); $csv_field_titles = fgetcsv($handle, 1000, $del); } $csv_field_titles = array_flip($csv_field_titles); //if(!array_key_exists('CATEGORY',$csv_field_titles)) //Checking the fields title contains 'CATEGORY'. // warn_exit(do_lang_tempcode('FIELDS_UNMATCH')); global $LAX_COMCODE; $temp2 = $LAX_COMCODE; $LAX_COMCODE = true; if (function_exists('set_time_limit')) { @set_time_limit(0); } //$count=0; $root_cat = $GLOBALS['SITE_DB']->query_value_null_ok('catalogue_categories', 'id', array('cc_parent_id' => NULL)); while (($data = fgetcsv($handle, 100000, $del)) !== false) { if ($data === array(NULL)) { continue; } // blank line $this->import_csv_lines($catalogue_name, $data, $root_cat, $fields, $categories, $csv_field_titles); //$count++; } $LAX_COMCODE = $temp2; $description = is_null($this->do_next_description) ? do_lang_tempcode('SUCCESS') : $this->do_next_description; $this->donext_catalogue_name = $catalogue_name; return $this->do_next_manager($title, $description, NULL); }
/** * Get the character set to use. We try and be clever to allow AJAX scripts to avoid loading up language * * @return string The character set */ function get_charset() { if (function_exists('do_lang')) { return do_lang('charset'); } global $SITE_INFO; $lang = array_key_exists('default_lang', $SITE_INFO) ? $SITE_INFO['default_lang'] : 'EN'; $path = get_file_base() . '/lang_custom/' . $lang . '/global.ini'; if (!file_exists($path)) { $path = get_file_base() . '/lang/' . $lang . '/global.ini'; } $file = fopen($path, 'rt'); $contents = unixify_line_format(fread($file, 100)); fclose($file); $matches = array(); if (preg_match('#charset=([\\w\\-]+)\\n#', $contents, $matches) != 0) { return strtolower($matches[1]); } return strtolower('ISO-8859-1'); }
/** * Extract code to execute the requested functions with the requested parameters from the module at the given path. * We used to actually load up the module, but it ate all our RAM when we did! * * @param PATH The path to the module * @param array Array of functions to be executing * @param ?array A list of parameters to pass to our functions (NULL: none) * @param boolean Whether to do this "properly" (via proper OOP), which will consume more memory * @return array A list of pieces of code to do the equivalent of executing the requested functions with the requested parameters */ function extract_module_functions($path, $functions, $params = NULL, $prefer_direct_code_call = false) { if ($params === NULL) { $params = array(); } global $SITE_INFO; $prefer_direct_code_call = $prefer_direct_code_call || isset($SITE_INFO['prefer_direct_code_call']) && $SITE_INFO['prefer_direct_code_call'] == '1'; $hphp = defined('HIPHOP_PHP'); if ($hphp && !function_exists('quercus_version') || $prefer_direct_code_call) { global $CLASS_CACHE; if (array_key_exists($path, $CLASS_CACHE)) { $new_classes = $CLASS_CACHE[$path]; } else { if (!$hphp) { $classes_before = get_declared_classes(); } require_code(preg_replace('#^' . preg_quote(get_file_base()) . '/#', '', preg_replace('#^' . preg_quote(get_file_base()) . '/((sources)|(sources\\_custom))/(.*)\\.php#', '${4}', $path))); if (!$hphp) { $classes_after = get_declared_classes(); } $new_classes = $hphp ? array() : array_values(array_diff($classes_after, $classes_before)); if (count($new_classes) == 0) { $matches = array(); if (preg_match('#^\\s*class (\\w+)#m', file_get_contents($path), $matches) != 0) { $new_classes = array($matches[1]); } } $CLASS_CACHE[$path] = $new_classes; } if (array_key_exists(0, $new_classes) && $new_classes[0] == 'standard_aed_module') { array_shift($new_classes); } if (array_key_exists(0, $new_classes)) { $c = $new_classes[0]; $new_ob = new $c(); } else { $new_ob = NULL; } $ret = array(); foreach ($functions as $function) { if (method_exists($new_ob, $function)) { $ret[] = array(array(&$new_ob, $function), $params); } else { $ret[] = NULL; } } return $ret; } if (!is_file($path)) { $ret = array(); foreach ($functions as $function) { $ret[] = NULL; } return $ret; } $file = unixify_line_format(file_get_contents($path), NULL, false, true); if (strpos($file, 'class Mx_') !== false) { return extract_module_functions($path, $functions, $params, true); } global $ARB_COUNTER; $r = preg_replace('#[^\\w]#', '', basename($path, '.php')) . strval(mt_rand(0, 100000)) . '_' . strval($ARB_COUNTER); $ARB_COUNTER++; $out = array(); $_params = ''; $pre = substr($file, 5, strpos($file, 'class ') - 5); // FUDGEFUDGE. We assume any functions we need to pre-load precede any classes in the file $pre = preg_replace('#(^|\\n)function (\\w+)\\(.*#s', 'if (!function_exists(\'${1}\')) { ${0} }', $pre); // In case we end up extracting from this file more than once across multiple calls to extract_module_functions if ($params !== NULL) { foreach ($params as $param) { if ($_params != '') { $_params .= ','; } if (is_string($param)) { $_params .= '\'' . str_replace('\'', '\\\'', $param) . '\''; } elseif ($param === NULL) { $_params .= 'NULL'; } elseif (is_bool($param)) { $_params .= $param ? 'true' : 'false'; } else { $_params .= strval($param); } } } foreach ($functions as $function) { $start = strpos($file, 'function ' . $function . '('); $spaces = 1; if ($start === false) { $out[] = NULL; } else { while ($file[$start - $spaces - 1] != chr(10)) { $spaces++; } $end1 = strpos($file, chr(10) . str_repeat(' ', $spaces) . '}' . chr(10), $start); $end2 = strpos($file, chr(10) . str_repeat("\t", $spaces) . '}' . chr(10), $start); if ($end1 === false) { $end1 = $end2; } if ($end2 === false) { $end2 = $end1; } $end = min($end1, $end2) + 2 + $spaces; $func = substr($file, $start, $end - $start); if (strpos($func, '$this->') !== false) { return extract_module_functions($path, $functions, $params, true); } /*if (strpos($func,'function '.$function.'()')===false) Fails for default parameters (e.g. $a=NULL in function definition) { $new_func=preg_replace('#function '.preg_quote($function).'\(([^\n]*)\)#','list(${1})=array('.$_params.');',$func); } else { $new_func=preg_replace('#function '.preg_quote($function).'\(\)#','',$func); }*/ $new_func = str_replace('function ' . $function . '(', 'function ' . $function . $r . '(', $func) . 'return ' . filter_naughty_harsh($function) . $r . '(' . $_params . '); '; $out[] = $pre . "\n\n" . $new_func; $pre = ''; // Can only load that bit once } } return $out; }
/** * The UI to view a security alert. * * @return tempcode The UI */ function alert_view() { $id = get_param_integer('id'); $rows = $GLOBALS['SITE_DB']->query_select('hackattack', array('*'), array('id' => $id)); $row = $rows[0]; $time = get_timezoned_date($row['date_and_time']); $title = get_page_title('VIEW_ALERT', true, array(escape_html($time))); $lookup_url = build_url(array('page' => 'admin_lookup', 'param' => $row['ip']), '_SELF'); $member_url = build_url(array('page' => 'admin_lookup', 'param' => $row['the_user']), '_SELF'); $reason = do_lang($row['reason'], $row['reason_param_a'], $row['reason_param_b']); $post = with_whitespace(unixify_line_format($row['data_post'])); $username = $GLOBALS['FORUM_DRIVER']->get_username($row['the_user']); if (is_null($username)) { $username = do_lang('UNKNOWN'); } breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('SECURITY_LOGGING')))); return do_template('SECURITY_ALERT_SCREEN', array('_GUID' => '6c5543151af09c79bf204bea5df61dde', 'TITLE' => $title, 'USER_AGENT' => $row['user_agent'], 'REFERER' => $row['referer'], 'USER_OS' => $row['user_os'], 'REASON' => $reason, 'IP' => hyperlink($lookup_url, $row['ip'], false, true), 'USERNAME' => hyperlink($member_url, escape_html($username)), 'POST' => $post, 'URL' => $row['url'])); }
/** * 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_rss($db, $table_prefix, $old_base_dir) { $rows = $db->query('SELECT * FROM ' . $table_prefix . 'rss ORDER BY position ASC'); $path = get_file_base() . '/pages/comcode_custom/' . get_site_default_lang() . '/panel_left.txt'; if (!file_exists($path)) { $source_path = get_file_base() . '/pages/comcode/' . get_site_default_lang() . '/panel_left.txt'; copy($source_path, $path); fix_permissions($path); sync_file($path); } $out = ''; foreach ($rows as $row) { if ($row['url'] != 'http://www.microsite.reuters.com/rss/worldNews') { $out .= chr(10) . '[block="' . $row['url'] . '"]side_rss[/block]'; } } $myfile = @fopen($path, 'at'); if ($myfile === false) { intelligent_write_error($path); } $out = unixify_line_format($out); fwrite($myfile, $out); fclose($myfile); fix_permissions($path); sync_file($path); }
/** * Get tempcode to tie in (to the HTML, in <head>) all the Javascript files that have been required. * * @param ?string Position to get Javascript for (NULL: all positions) * @set NULL header footer * @return tempcode The tempcode to tie in the Javascript files */ function javascript_tempcode($position = NULL) { global $JAVASCRIPTS, $JAVASCRIPT; $js = new ocp_tempcode(); $minify = get_param_integer('keep_no_minify', 0) == 0; $https = get_option('enable_https', true) == '1' && function_exists('is_page_https') && function_exists('get_zone_name') && (tacit_https() || is_page_https(get_zone_name(), get_page_name())); $mobile = is_mobile(); // Special merge operation for staff. In truth it's to get a better score on Google Page Speed ;) $to_merge = array('javascript_staff', 'javascript_button_occle', 'javascript_fractional_edit'); $good_to_merge = true; foreach ($to_merge as $j) { if (!array_key_exists($j, $JAVASCRIPTS)) { $good_to_merge = false; } } if ($good_to_merge) { $j = 'javascript_staff___merged'; if (!$minify) { $j .= '_non_minified'; } if ($https) { $j .= '_ssl'; } if ($mobile) { $j .= '_mobile'; } $theme = filter_naughty($GLOBALS['FORUM_DRIVER']->get_theme()); $dir = get_custom_file_base() . '/themes/' . $theme . '/templates_cached/' . filter_naughty(user_lang()); $write_path = $dir . '/' . filter_naughty_harsh($j); $write_path .= '.js'; /*$rebuild=false; Performance hit foreach ($to_merge as $j2) { $merge_from=javascript_enforce($j2); if (filemtime($merge_from)==time()) $rebuild=true; // Hmm, just recalculated }*/ if (!is_file($write_path)) { $data = ''; foreach ($to_merge as $j2) { $merge_from = javascript_enforce($j2); if (is_file($merge_from)) { $data .= unixify_line_format(file_get_contents($merge_from, FILE_TEXT)); } else { $good_to_merge = false; break; } } if ($good_to_merge) { $myfile = @fopen($write_path, 'wb') or intelligent_write_error($write_path); // Intentionally wb to stop line ending conversions on Windows fwrite($myfile, $data); fclose($myfile); fix_permissions($write_path, 0777); sync_file($write_path); } } if ($good_to_merge) { if ($position != 'header') { $js->attach(do_template('JAVASCRIPT_NEED', array('CODE' => $j))); } } } // Our main loop $bottom_ones = array('javascript_staff' => 1, 'javascript_button_occle' => 1, 'javascript_fractional_edit' => 1, 'javascript_thumbnails' => 1, 'javascript_button_realtime_rain' => 1); foreach (array_keys($JAVASCRIPTS) as $j) { if ($good_to_merge && in_array($j, $to_merge)) { continue; } if ($position !== NULL) { $bottom = isset($bottom_ones[$j]); // TODO: progmattic way of saying this at point of calls if ($position == 'header' && $bottom) { continue; } if ($position == 'footer' && !$bottom) { continue; } } $temp = javascript_enforce($j); if ($temp != '') { if (!$minify) { $j .= '_non_minified'; } if ($https) { $j .= '_ssl'; } if ($mobile) { $j .= '_mobile'; } $js->attach(do_template('JAVASCRIPT_NEED', array('_GUID' => 'b5886d9dfc4d528b7e1b0cd6f0eb1670', 'CODE' => $j))); } } if (!is_null($JAVASCRIPT)) { $js->attach($JAVASCRIPT); } return $js; }
/** * Parses input setup in constructor, and creates a parse tree. */ function parse_input() { /*We need to break the $this->parsed_input[SECTION_COMMAND] up into several distinct parts: - Command - Options - Parameters - Extras (e.g. I/O redirection / pipes) i.e. chmod -R 777 ./foobar >> output.txt COMMAND OPTION PARAMETER PARAMETER EXTRA */ /*Output redirection: 2&1> output.txt 2&1 > output.txt STREAM_IDENTIFIER ASSIGNMENT REDIRECT_IDENTIFIER */ $this->parse_runtime['command_length'] = strlen($this->current_input); $this->parse_runtime['parse_position'] = 0; $this->parse_runtime['current_mode'] = MODE_NORMAL; $this->parse_runtime['escape_used'] = false; $this->parse_runtime['occle_command'] = COMMAND_NATIVE; $this->parsed_input[SECTION_COMMAND] = NULL; $this->parsed_input[SECTION_OPTIONS] = array(); $this->parsed_input[SECTION_PARAMETERS] = array(); $this->parsed_input[SECTION_EXTRAS] = array(); $this->fs = object_factory('virtual_fs'); //Start parsing with the command $this->_extract_command(); if (trim($this->parsed_input[SECTION_COMMAND]) == '') { $this->output[STREAM_STDCOMMAND] = ''; $this->output[STREAM_STDHTML] = ''; $this->output[STREAM_STDOUT] = ''; $this->output[STREAM_STDERR] = do_lang('NON_COMMAND'); return; } if ($this->parse_runtime['occle_command'] == COMMAND_NATIVE) { //Options (it's an OcCLE command; not a PHP command) $this->_extract_options(); $this->_extract_parameters(); } //Extras $this->_extract_extras(); //Pre-processing: follow any extras provided $i = 0; foreach ($this->parsed_input[SECTION_EXTRAS] as $extra) { if ($extra[ASSIGNMENT] == REDIRECT_PIPE || $extra[ASSIGNMENT] == REDIRECT_INPUT) { $replacements = 0; if ($extra[ASSIGNMENT] == REDIRECT_PIPE) { if (!isset($extra[STREAM_IDENTIFIER][0])) { $extra[STREAM_IDENTIFIER] = array(STREAM_STDOUT); } $virtual_bash = new virtual_bash($extra[REDIRECT_IDENTIFIER]); $virtual_output = $virtual_bash->return_output(); $pertinant_output = $virtual_output[$extra[STREAM_IDENTIFIER][count($extra[STREAM_IDENTIFIER]) - 1]]; if ($virtual_output[STREAM_STDERR] != '') { $this->output[STREAM_STDERR] = $virtual_output[STREAM_STDERR]; } } else { $pertinant_output = $this->fs->read_file($this->fs->_pwd_to_array($extra[REDIRECT_IDENTIFIER])); if ($pertinant_output === false) { $pertinant_output = ''; } } foreach ($this->parsed_input[SECTION_PARAMETERS] as $param_no => $parameter) { //Do we have any "{".$i."}" parameters? if ($parameter == '{' . strval($i) . '}') { //NOTE: Might want to change this somehow so that other streams can be put through $this->parsed_input[SECTION_PARAMETERS][$param_no] = $pertinant_output; $replacements++; } } if ($replacements == 0) { //Just tag the input onto the end of the parameters array //NOTE: See above $this->parsed_input[SECTION_PARAMETERS][] = $pertinant_output; } $i++; } } //Handle the command: load up the relevant hook if ($this->parse_runtime['occle_command'] == COMMAND_NATIVE) { //See if it's a lone command first $hooks = find_all_hooks('modules', 'admin_occle_commands'); $hook_return = NULL; foreach (array_keys($hooks) as $hook) { if ($hook == $this->parsed_input[SECTION_COMMAND]) { require_code('hooks/modules/admin_occle_commands/' . filter_naughty_harsh($hook)); $object = object_factory('Hook_' . filter_naughty_harsh($hook)); $hook_return = $object->run($this->parsed_input[SECTION_OPTIONS], $this->parsed_input[SECTION_PARAMETERS], $this->fs); $this->parse_runtime['occle_command'] = COMMAND_LONE; break; } } if (!is_null($hook_return)) { $this->output[STREAM_STDCOMMAND] = $hook_return[0]; if (is_object($hook_return[1])) { $this->output[STREAM_STDHTML] = $hook_return[1]->evaluate(); } else { $this->output[STREAM_STDHTML] = $hook_return[1]; } $this->output[STREAM_STDOUT] = array_key_exists(2, $hook_return) ? $hook_return[2] : ''; $this->output[STREAM_STDERR] = array_key_exists(2, $hook_return) ? $hook_return[3] : ''; } else { //It's not a lone command; see if it's a script - check first in the main script dir if (file_exists(get_custom_file_base() . '/data/modules/admin_occle/' . filter_naughty_harsh($this->parsed_input[SECTION_COMMAND], true))) { $script_file = get_custom_file_base() . '/data/modules/admin_occle/' . filter_naughty_harsh($this->parsed_input[SECTION_COMMAND]); } else { $script_file = $this->_find_script_file($this->parsed_input[SECTION_COMMAND]); } //Exhaustive search if ($script_file !== false && is_readable($script_file)) { //It *is* a script, so let's run it :) $this->parse_runtime['occle_command'] = COMMAND_SCRIPT; $script_contents = unixify_line_format(file_get_contents($script_file, FILE_TEXT)); $script_lines = explode("\n", $script_contents); foreach ($script_lines as $script_line) { if (strlen($script_line) > 0) { $virtual_bash = new virtual_bash($script_line, $this->parsed_input[SECTION_PARAMETERS]); $script_output = $virtual_bash->return_output(); $this->output = $this->_combine_streams($this->output, $script_output); } } } else { //Give up: it's not a command $this->output[STREAM_STDCOMMAND] = ''; $this->output[STREAM_STDHTML] = ''; $this->output[STREAM_STDOUT] = ''; $this->output[STREAM_STDERR] = do_lang('NON_COMMAND'); return; } } } elseif ($this->parse_runtime['occle_command'] == COMMAND_PHP) { //NOTE: This is done in a separate function to limit variable interaction (due to the PHP memory implemented) $this->_handle_php_command(); } elseif ($this->parse_runtime['occle_command'] == COMMAND_SQL) { //SQL command $GLOBALS['NO_DB_SCOPE_CHECK'] = true; $occle_output = $GLOBALS['SITE_DB']->query($this->parsed_input[SECTION_COMMAND], NULL, NULL, true); $GLOBALS['NO_DB_SCOPE_CHECK'] = false; if (count($occle_output) > 100) { $occle_output = $GLOBALS['SITE_DB']->query($this->parsed_input[SECTION_COMMAND], 100, NULL, true); $occle_output[] = array('...' => '...'); } $this->output[STREAM_STDCOMMAND] = ''; $this->output[STREAM_STDHTML] = ''; $this->output[STREAM_STDOUT] = ''; $this->output[STREAM_STDERR] = ''; if (is_null($occle_output)) { $this->output[STREAM_STDERR] = do_lang('NO_RESULTS'); } else { $this->output[STREAM_STDHTML] = $this->_array_to_html($occle_output); } } //Post-processing: follow any extras provided $old_output = $this->output; foreach ($this->parsed_input[SECTION_EXTRAS] as $extra) { if (!isset($extra[STREAM_IDENTIFIER][0])) { $extra[STREAM_IDENTIFIER] = array(STREAM_STDOUT); } if (!isset($this->output[$extra[REDIRECT_IDENTIFIER]])) { // It's a file... so read in if it exists, else blank $this->output[$extra[REDIRECT_IDENTIFIER]] = $this->fs->read_file($this->fs->_pwd_to_array($extra[REDIRECT_IDENTIFIER])); if ($this->output[$extra[REDIRECT_IDENTIFIER]] === false) { $this->output[$extra[REDIRECT_IDENTIFIER]] = ''; } } $extra[ASSIGNMENT] = intval($extra[ASSIGNMENT]); foreach ($extra[STREAM_IDENTIFIER] as $stream_identifier) { if ($extra[ASSIGNMENT] == REDIRECT_OVERWRITE) { $this->output[$stream_identifier] = ''; // Because it's been taken away from here $this->output[$extra[REDIRECT_IDENTIFIER]] = $old_output[$stream_identifier]; } elseif ($extra[ASSIGNMENT] == REDIRECT_APPEND) { $this->output[$stream_identifier] = ''; // Because it's been taken away from here if (is_object($this->output[$extra[REDIRECT_IDENTIFIER]]) && is_object($old_output[$stream_identifier])) { $this->output[$extra[REDIRECT_IDENTIFIER]]->append($old_output[$stream_identifier]); } elseif (!is_object($this->output[$extra[REDIRECT_IDENTIFIER]]) && is_object($old_output[$stream_identifier])) { $this->output[$extra[REDIRECT_IDENTIFIER]] = make_string_tempcode($this->output[$extra[REDIRECT_IDENTIFIER]]); $this->output[$extra[REDIRECT_IDENTIFIER]]->append($old_output[$stream_identifier]); $this->output[$extra[REDIRECT_IDENTIFIER]] = $this->output[$extra[REDIRECT_IDENTIFIER]]->evaluate(); } elseif (is_object($this->output[$extra[REDIRECT_IDENTIFIER]]) && !is_object($old_output[$stream_identifier])) { $old_output[$stream_identifier] = make_string_tempcode($old_output[$stream_identifier]); $this->output[$extra[REDIRECT_IDENTIFIER]]->append($old_output[$stream_identifier]); } else { $this->output[$extra[REDIRECT_IDENTIFIER]] .= $old_output[$stream_identifier]; } } } if ($extra[ASSIGNMENT] == REDIRECT_OVERWRITE || $extra[ASSIGNMENT] == REDIRECT_APPEND) { if (is_object($this->output[$extra[REDIRECT_IDENTIFIER]])) { $this->output[$extra[REDIRECT_IDENTIFIER]] = $this->output[$extra[REDIRECT_IDENTIFIER]]->evaluate(); } $this->fs->write_file($this->fs->_pwd_to_array($extra[REDIRECT_IDENTIFIER]), $this->output[$extra[REDIRECT_IDENTIFIER]]); } } }
/** * Write a text file, using the _custom system * * @param string The file name (without .txt) * @param ?LANGUAGE_NAME The language to write for (NULL: none) (blank: search) * @param string The data to write */ function write_text_file($codename, $lang, $out) { $xpath = _find_text_file_path($codename, $lang); if ($xpath == '') { $xpath = get_file_base() . '/text/' . user_lang() . '/' . $codename . '.txt'; } $path = str_replace(get_file_base() . '/text/', get_custom_file_base() . '/text_custom/', $xpath); $myfile = @fopen($path, 'wt'); if ($myfile === false) { intelligent_write_error($path); } $out = unixify_line_format($out); if (fwrite($myfile, $out) < strlen($out)) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } fclose($myfile); fix_permissions($path); sync_file($path); }
/** * Rewrite some CSS code according to a CSS landscape. * * @param ID_TEXT CSS filename of source file. * @param array The colour expression landscape which we'll make substitutions using. * @param ID_TEXT The theme this is being generated from * @param ID_TEXT The algorithm to use * @set equations hsv * @param ID_TEXT The seed colour * @return string The sheet */ function theme_wizard_colours_to_sheet($sheet, $landscape, $source_theme, $algorithm, $seed) { $theme = filter_naughty($source_theme); if (file_exists(get_file_base() . '/themes/' . $theme . '/css_custom/' . filter_naughty($sheet))) { $contents = unixify_line_format(file_get_contents(get_file_base() . '/themes/' . $theme . '/css_custom/' . filter_naughty($sheet), FILE_TEXT)); } elseif (file_exists(get_file_base() . '/themes/' . $theme . '/css/' . filter_naughty($sheet))) { $contents = unixify_line_format(file_get_contents(get_file_base() . '/themes/' . $theme . '/css/' . filter_naughty($sheet), FILE_TEXT)); } elseif (file_exists(get_file_base() . '/themes/default/css_custom/' . filter_naughty($sheet))) { $contents = unixify_line_format(file_get_contents(get_file_base() . '/themes/default/css_custom/' . filter_naughty($sheet), FILE_TEXT)); } else { $contents = unixify_line_format(file_get_contents(get_file_base() . '/themes/default/css/' . filter_naughty($sheet), FILE_TEXT)); } return theme_wizard_colours_to_css($contents, $landscape, $source_theme, $algorithm, $seed); }
/** * Extend a language map from strings in a given language file. * * @param PATH The path to the language file * @param array The currently loaded language map * @param ?boolean Whether to get descriptions rather than strings (NULL: no, but we might pick up some descriptions accidently) * @param boolean Whether $b is infact not a path, but the actual file contents */ function _get_lang_file_map($b, &$entries, $descriptions = NULL, $given_whole_file = false) { if (!$given_whole_file) { if (!file_exists($b)) { return; } $lines = file($b); } else { $lines = explode(chr(10), unixify_line_format($b)); } if (!$given_whole_file && $b[strlen($b) - 1] == 'o') { // No description support btw (but shouldn't really be needed, once you save it will make a .ini and that does have description support) if ($descriptions === true) { return; } // Parse po file $matches = array(); $doing = NULL; $value = ''; $processing = false; foreach ($lines as $line) { if ($line == '') { continue; } if ($line[0] == '#' && preg_match('/#: \\[strings\\](.*)/', $line, $matches) != 0) { if (!is_null($doing) && $value != '') { $entries[$doing] = $value; } $doing = $matches[1]; $value = ''; $processing = false; } if ($processing) { if ($line[0] == '"') { $v = substr(rtrim($line, "\r\n"), 1); if (substr($v, -1) == '"') { $v = substr($v, 0, strlen($v) - 1); } $value .= stripslashes($v); } else { $processing = false; if (!is_null($doing) && $value != '') { if ($doing == 'en_left' && $value != 'left' && $value != 'right') { $value = 'left'; } if ($doing == 'en_right' && $value != 'left' && $value != 'right') { $value = 'right'; } $entries[$doing] = $value; } } } if (!$processing) { if (substr($line, 0, 8) == 'msgstr "') { $processing = true; $v = substr(rtrim($line, "\r\n"), 8); if (substr($v, -1) == '"') { $v = substr($v, 0, strlen($v) - 1); } $value .= stripslashes($v); } } } if (!is_null($doing) && $value != '') { $entries[$doing] = $value; } if (substr(basename($b), 0, 6) == 'global' || $given_whole_file) { $entries['charset'] = 'utf-8'; // Has to be } return; } // if (!is_null($descriptions)) // Full parsing needed for this then (this algorithm would support non-descriptions, but it's just slower) // { $in_lang = false; $nl = "\r\n"; foreach ($lines as $line) { $line = rtrim($line, $nl); if ($line == '') { continue; } if ($line[0] == '[') { if ($line == '[strings]') { $in_lang = $descriptions !== true; } elseif ($line == '[descriptions]') { $in_lang = $descriptions === true; } } if ($in_lang) { $parts = explode('=', $line, 2); if (isset($parts[1])) { $entries[$parts[0]] = rtrim($parts[1], $nl); /*str_replace('\n',"\n",$parts[1]);*/ } } } // } else // Efficient parsing possible // { // foreach ($lines as $line) // [descriptions] now comes before [strings], so we don't need to filter (it'll just overwrite correctly if there's a dupe between them) // { // $parts=explode('=',$line,2); // // if (isset($parts[1])) // $entries[$parts[0]]=rtrim($parts[1]);/*str_replace('\n',"\n",$parts[1]);*/ // } // } }
/** * Get a complex API information structure from a PHP file. It assumes the file has reasonably properly layed out class and function whitespace * The return structure is... * list of classes * each entry is a map containing 'functions' (list of functions) and 'name' * each functions entry is a map containing 'parameters' and 'name' and 'return' * each parameters entry is a map containing... * name * description * type * default * set * range * * @param ID_TEXT The PHP code module to get API information for * @param boolean Whether to include function source code * @return array The complex structure of API information */ function get_php_file_api($filename, $include_code = true) { require_code('type_validation'); $classes = array(); // Open up PHP file if ($filename == 'phpstub.php') { $full_path = $filename; } else { $full_path = (get_file_base() != '' ? get_file_base() . '/' : '') . filter_naughty($filename); } $lines = file($full_path); foreach ($lines as $i => $line) { $lines[$i] = str_replace("\t", ' ', $line); } // Go through all lines, keeping record of what current class we are looking at $current_class = '__global'; $current_class_level = 0; $functions = array(); global $LINE; for ($i = 0; array_key_exists($i, $lines); $i++) { $line = $lines[$i]; $LINE = $i + 1; if (strpos($line, '/' . '*NO_API_CHECK*/') !== false) { return array(); } // Sense class boundaries (hackerish: assumes whitespace laid out correctly) $ltrim = ltrim($line); if (substr($ltrim, 0, 6) == 'class ') { if (count($functions) != 0) { $classes[$current_class] = array('functions' => $functions, 'name' => $current_class); } $space_pos = strpos($ltrim, ' '); $space_pos_2 = strpos($ltrim, ' ', $space_pos + 1); if ($space_pos_2 === false) { $space_pos_2 = strpos($ltrim, chr(13), $space_pos + 1); } if ($space_pos_2 === false) { $space_pos_2 = strpos($ltrim, chr(10), $space_pos + 1); } $current_class = substr($ltrim, $space_pos + 1, $space_pos_2 - $space_pos - 1); $current_class_level = strlen($line) - strlen($ltrim); $functions = array(); } elseif ($current_class != '__global' && substr($line, 0, $current_class_level + 1) == str_repeat(' ', $current_class_level) . '}') { if (count($functions) != 0) { $classes[$current_class] = array('functions' => $functions, 'name' => $current_class); } $current_class = '__global'; $functions = array_key_exists('__global', $classes) ? $classes['__global']['functions'] : array(); } // Detect an API function if (substr($ltrim, 0, 3) == '/**') { $depth = strlen($line) - strlen($ltrim); // Find function line for ($j = $i + 1; array_key_exists($j, $lines); $j++) { $line2 = $lines[$j]; if (substr($line2, 0, $depth + 9) == str_repeat(' ', $depth) . 'function ') { // Parse function line $_line = substr($line2, $depth + 9); list($function_name, $parameters) = _read_php_function_line($_line); break; } if (substr(trim($line2), 0, 3) == '/**' || strpos($line2, '*/') !== false && array_key_exists($j + 1, $lines) && strpos($lines[$j + 1], 'function ') === false) { $i = $j - 1; continue 2; } } if (!array_key_exists($j, $lines)) { continue; } // No function: probably we commented it out // Parse comment block bits $description = ''; $flags = array(); $arg_counter = -1; $in_return = false; $return = NULL; for ($i++; $i < $j - 1; $i++) { $ltrim = ltrim($lines[$i]); $ltrim = substr($ltrim, 2); // Remove '* ' $ltrim = rtrim($ltrim); // Remove additional whitespace if ($ltrim == '') { continue; } if ($ltrim[0] == '@') { if (substr($ltrim, 0, 6) == '@param') { $arg_counter++; if (!array_key_exists($arg_counter, $parameters)) { fatal_exit(do_lang_tempcode('PARAMETER_MISMATCH', escape_html($function_name))); continue 2; } $parts = _cleanup_array(preg_split('/\\s/', substr($ltrim, 6))); if ($parts[0][0] != '?' && array_key_exists('default', $parameters[$arg_counter]) && is_null($parameters[$arg_counter]['default'])) { fatal_exit(do_lang_tempcode('UNALLOWED_NULL', escape_html($parameters[$arg_counter]['name']), escape_html($function_name), array(escape_html('NULL')))); continue 2; } if (!in_array($parts[0], array('~mixed', 'mixed', 'boolean')) && $parts[0][0] != '~' && array_key_exists('default', $parameters[$arg_counter]) && $parameters[$arg_counter]['default'] === false) { fatal_exit(do_lang_tempcode('UNALLOWED_NULL', escape_html($parameters[$arg_counter]['name']), escape_html($function_name), array(escape_html('false')))); continue 2; } $parameters[$arg_counter]['type'] = $parts[0]; unset($parts[0]); $parameters[$arg_counter]['description'] = implode(' ', $parts); } elseif (substr($ltrim, 0, 7) == '@return') { $return = array(); $parts = _cleanup_array(preg_split('/\\s/', substr($ltrim, 7))); $return['type'] = $parts[0]; unset($parts[0]); $return['description'] = implode(' ', $parts); $in_return = true; } elseif (substr($ltrim, 0, 4) == '@set') { $set = ltrim(substr($ltrim, 5)); if ($in_return) { $return['set'] = $set; } else { $parameters[$arg_counter]['set'] = $set; } } elseif (substr($ltrim, 0, 6) == '@range') { $range = ltrim(substr($ltrim, 6)); if ($in_return) { $return['range'] = $range; } else { $parameters[$arg_counter]['range'] = $range; } } } else { $description .= unixify_line_format($ltrim); } } $f_a = strpos($description, '{{'); if ($f_a !== false) { $f_b = strpos($description, '}}', $f_a); if ($f_b !== false) { $_flags = substr($description, $f_a + 2, $f_b - $f_a - 2); $flags = explode(' ', $_flags); $description = substr($description, $f_a) . substr($description, $f_b); } } if (array_key_exists($arg_counter + 1, $parameters)) { fatal_exit(do_lang_tempcode('PARAMETER_MISMATCH', escape_html($function_name))); continue; } // Do some checks foreach ($parameters as $parameter) { // Type check if (array_key_exists('default', $parameter)) { $default = $parameter['default']; if ($default === 'boolean-true') { $default = true; } if ($default === 'boolean-false') { $default = false; } } else { $default = NULL; } check_function_type($parameter['type'], $function_name, $parameter['name'], $default, array_key_exists('range', $parameter) ? $parameter['range'] : NULL, array_key_exists('set', $parameter) ? $parameter['set'] : NULL); // Check that null is fully specified if ($parameter['type'][0] == '?') { if (strpos($parameter['description'], '(NULL: ') === false) { fatal_exit(do_lang_tempcode('NULL_MEANING_NOT_SPECIFIED', escape_html($parameter['name']), escape_html($function_name), array(escape_html('NULL')))); } } if ($parameter['type'][0] == '~') { if (strpos($parameter['description'], '(false: ') === false) { fatal_exit(do_lang_tempcode('NULL_MEANING_NOT_SPECIFIED', escape_html($parameter['name']), escape_html($function_name), array(escape_html('false')))); } } } if (!is_null($return)) { $fret = $return; check_function_type($return['type'], $function_name, '(return)', NULL, array_key_exists('range', $return) ? $return['range'] : NULL, array_key_exists('set', $return) ? $return['set'] : NULL); // Check that null is fully specified if ($return['type'][0] == '?') { if (strpos($return['description'], '(NULL: ') === false) { fatal_exit(do_lang_tempcode('NULL_MEANING_NOT_SPECIFIED', escape_html('(return)'), escape_html($function_name), array(escape_html('NULL')))); } } if ($return['type'][0] == '~') { if (strpos($return['description'], '(false: ') === false) { fatal_exit(do_lang_tempcode('NULL_MEANING_NOT_SPECIFIED', escape_html('(return)'), escape_html($function_name), array(escape_html('false')))); } } } else { $fret = NULL; } // Now get source code $code = ''; for ($k = $j; array_key_exists($k, $lines); $k++) { $line2 = $lines[$k]; $code .= $line2; if (substr($line2, 0, $depth + 1) == str_repeat(' ', $depth) . '}') { break; } } $function = array('filename' => $filename, 'parameters' => $parameters, 'name' => $function_name, 'description' => $description, 'flags' => $flags); if ($include_code) { $function['code'] = $code; } if (!is_null($fret)) { $function['return'] = $fret; } $functions[$function_name] = $function; $i++; } } if (count($functions) != 0) { $classes[$current_class] = array('functions' => $functions, 'name' => $current_class); } // See if there are any functions with blank lines above them for ($i = 0; array_key_exists($i, $lines); $i++) { $line = ltrim($lines[$i]); if (substr($line, 0, 9) == 'function ' && (trim($lines[$i - 1]) == '' || trim($lines[$i - 1]) == '{')) { if (strpos($filename, '_custom') === false) { fatal_exit(do_lang_tempcode('MISSING_FUNCTION_COMMENT', rtrim($line))); } } } return $classes; }