/** * Convert Comcode-Text to Comcode-XML. * * @param LONG_TEXT The comcode to convert * @param boolean Whether to not include a wrapper element (<comcode>) * @return LONG_TEXT The converted comcode */ function comcode_text__to__comcode_xml($comcode, $skip_wrapper = false) { require_code('comcode_xml'); require_code('comcode_text'); require_code('comcode_renderer'); if (substr($comcode, 0, 8) == '<comcode') { if ($skip_wrapper) { return str_replace('<comcode>', '', str_replace('</comcode>', '', $comcode)); } return $comcode; } $xml = ''; global $ALLOWED_ENTITIES, $CODE_TAGS, $DANGEROUS_TAGS, $VALID_COMCODE_TAGS, $BLOCK_TAGS, $POTENTIAL_JS_NAUGHTY_ARRAY, $TEXTUAL_TAGS, $LEET_FILTER, $IMPORTED_CUSTOM_COMCODE, $REPLACE_TARGETS; $len = strlen($comcode); require_lang('comcode'); require_code('type_validation'); if (function_exists('set_time_limit') && ini_get('max_execution_time') != '0') { @set_time_limit(300); } $comcode_dangerous = true; $comcode_dangerous_html = true; // Tag level $current_tag = ''; $attribute_map = array(); $continuation = ''; $close = mixed(); // Properties that come from our tag $white_space_area = true; $textual_area = true; $formatting_allowed = true; $in_html = false; $in_semihtml = false; $in_separate_parse_section = false; // Not escaped because it has to be passed to a secondary filter $in_code_tag = false; $lax = false; // Our state $status = CCP_NO_MANS_LAND; $tag_stack = array(); $pos = 0; $line_starting = true; $just_ended = false; $none_wrap_length = 0; $just_new_line = true; // So we can detect lists starting right away $just_title = false; global $NUM_LINES; $NUM_LINES = 0; $wrap_pos = 60; $preparse_mode = false; $is_all_semihtml = false; $smilies = $GLOBALS['FORUM_DRIVER']->find_emoticons(); // We'll be needing the smiley array $shortcuts = array('(c)' => '©', '(r)' => '®', '--' => '–', '---' => '—'); // Text syntax possibilities, that get maintained as our cursor moves through the text block $list_indent = 0; $list_type = 'ul'; while ($pos < $len) { $next = $comcode[$pos]; ++$pos; // State machine switch ($status) { case CCP_NO_MANS_LAND: if ($next == '[') { // Look ahead to make sure it's a valid tag. If it's not then it's considered normal user input, not a tag at all $dif = $pos < $len && $comcode[$pos] == '/' ? 1 : 0; $ahead = substr($comcode, $pos + $dif, 19); $equal_pos = strpos($ahead, '='); $space_pos = strpos($ahead, ' '); $end_pos = strpos($ahead, ']'); $cl_pos = strpos($ahead, chr(10)); if ($equal_pos === false) { $equal_pos = 22; } if ($space_pos === false) { $space_pos = 22; } if ($end_pos === false) { $end_pos = 22; } if ($cl_pos === false) { $cl_pos = 22; } $use_pos = min($equal_pos, $space_pos, $end_pos, $cl_pos); $potential_tag = strtolower(substr($ahead, 0, $use_pos)); if ($use_pos != 22 && (!$in_html || $potential_tag == 'html' || $potential_tag == 'semihtml') && (!$in_code_tag || isset($CODE_TAGS[$potential_tag]))) { if (!isset($VALID_COMCODE_TAGS[$potential_tag])) { if (!$IMPORTED_CUSTOM_COMCODE) { _custom_comcode_import($GLOBALS['SITE_DB']); } } if (isset($VALID_COMCODE_TAGS[$potential_tag]) && substr($ahead, 0, 2) != 'i ') { $close = false; $current_tag = ''; $xml .= $continuation; $continuation = ''; if ($potential_tag == 'html' || $potential_tag == 'semihtml') { list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; } $status = CCP_STARTING_TAG; continue; } } } if ($in_html || $in_semihtml && ($next == '<' || $next == '>')) { $ahead = substr($comcode, $pos - 1, 20); $ahead_lower = strtolower($ahead); if ($next == chr(10)) { ++$NUM_LINES; } $continuation .= $next; } else { // Text-format possibilities if ($just_new_line && $formatting_allowed) { $xml .= $continuation; $continuation = ''; // List $found_list = false; $old_list_indent = $list_indent; if ($pos + 1 < $len && is_numeric($next) && $comcode[$pos] == ')' && $comcode[$pos + 1] == ' ') { if ($list_indent != 0 && $list_type == 'ul') { list($temp_tpl, $old_list_indent) = _close_open_lists($list_indent, $list_type); $xml .= $temp_tpl; } $list_indent = 1; $found_list = true; $scan_pos = $pos; $list_type = '1'; } elseif ($pos + 1 < $len && ord($next) >= ord('a') && ord($next) <= ord('z') && $comcode[$pos] == ')' && $comcode[$pos + 1] == ' ') { if ($list_indent != 0 && $list_type == 'ul') { list($temp_tpl, $old_list_indent) = _close_open_lists($list_indent, $list_type); $xml .= $temp_tpl; } $list_indent = 1; $found_list = true; $scan_pos = $pos; $list_type = 'a'; } elseif ($next == ' ') { if ($old_list_indent != 0 && $list_type != 'ul') { list($temp_tpl, $old_list_indent) = _close_open_lists($list_indent, $list_type); $xml .= $temp_tpl; } $scan_pos = $pos - 1; $list_indent = 0; while ($scan_pos < $len) { $scan_next = $comcode[$scan_pos]; if ($scan_next == '-' && $comcode[$scan_pos + 1] == ' ') { $found_list = true; break; } else { if ($scan_next == ' ') { ++$list_indent; } else { break; } } ++$scan_pos; } if (!$found_list) { $list_indent = 0; } } else { list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; if ($next == '-' && !$just_title) { $scan_pos = $pos; $found_rule = true; while ($scan_pos < $len) { $scan_next = $comcode[$scan_pos]; if ($scan_next != '-') { if ($scan_next == chr(10)) { ++$NUM_LINES; break; } else { $found_rule = false; } } ++$scan_pos; } if ($found_rule) { $xml .= '<rule />'; $pos = $scan_pos + 1; $just_ended = true; $none_wrap_length = 0; continue; } } } // List handling if ($list_indent == $old_list_indent && $old_list_indent != 0) { $xml .= '</listElement>'; } for ($i = $list_indent; $i < $old_list_indent; ++$i) { $xml .= '</listElement>'; $xml .= '</list>'; } if ($list_indent < $old_list_indent && $list_indent != 0) { $xml .= '</listElement>'; } if ($found_list) { if ($list_indent - $old_list_indent > 1 && !$lax) { $error = comcode_parse_error($preparse_mode, array('CCP_LIST_JUMPYNESS'), $pos, $comcode); return $error->evaluate(); } for ($i = $old_list_indent; $i < $list_indent; ++$i) { switch ($list_type) { case 'ul': $xml .= '<list>'; break; case '1': $xml .= '<list type="1">'; break; case 'a': $xml .= '<list type="a">'; break; } if ($i < $list_indent - 1) { $xml .= '<listElement>'; } } $xml .= '<listElement>'; $just_ended = true; $none_wrap_length = 0; $next = ''; $pos = $scan_pos + 2; } } if ($next == chr(10) && $white_space_area && !$just_ended) { ++$NUM_LINES; $line_starting = true; $xml .= $continuation; $continuation = ''; $just_new_line = true; $none_wrap_length = 0; if ($list_indent == 0) { $xml .= '<br />' . chr(10); } } else { $just_new_line = false; if ($next == ' ' && $white_space_area) { if ($line_starting || $pos != 0 && $comcode[$pos - 2] == ' ') { $next = ' '; ++$none_wrap_length; } else { $none_wrap_length = 0; } $continuation .= $next; } elseif ($next == "\t" && $white_space_area) { $xml .= $continuation; $continuation = ''; $tab_tpl = do_template('COMCODE_TEXTCODE_TAB'); // $_tab_tpl = $tab_tpl->evaluate(); $none_wrap_length += strlen($_tab_tpl); $xml .= $tab_tpl->evaluate(); } else { if ($next == ' ' || $next == "\t" || $just_ended) { $none_wrap_length = 0; } else { if (!is_null($wrap_pos) && $none_wrap_length >= $wrap_pos && $textual_area && !$in_semihtml) { $xml .= $continuation; $continuation = ''; $xml .= '<br />' . chr(10); $none_wrap_length = 0; } elseif ($textual_area) { ++$none_wrap_length; } } $line_starting = false; $just_ended = false; $differented = false; // If somehow via lookahead we've changed this to HTML and thus won't use it in raw form // Symbol lookahead if (!$in_code_tag) { if ($next == '{' && ($comcode[$pos] == '$' || $comcode[$pos] == '+' || $comcode[$pos] == '!') && $comcode_dangerous) { $xml .= $continuation; $continuation = ''; if ($comcode[$pos] == '+') { $p_end = $pos + 5; while ($p_end < $len) { $p_portion = substr($comcode, $pos - 1, $p_end - ($pos - 1) + 5); if (substr_count($p_portion, '{+START') == substr_count($p_portion, '{+END')) { break; } $p_end++; } $p_len = 1; while ($pos + $p_len < $len) { $p_portion = substr($comcode, $pos - 1, $p_len); if (substr_count($p_portion, '{') == substr_count($p_portion, '}')) { break; } $p_len++; } $p_len--; $p_portion = substr($comcode, $pos + $p_len, $p_end - ($pos + $p_len)); $_ret = template_to_tempcode_static(substr($comcode, $pos - 1, $p_len + 1) . '!' . substr($comcode, $p_end, 6)); $ret = '<directive type="' . escape_html($_ret->bits[0][2]) . '">'; foreach ($_ret->bits[0][3] as $val) { $ret .= '<directiveParam>' . escape_html($val->evaluate()) . '</directiveParam>'; } $ret .= comcode_text__to__comcode_xml($p_portion, true); $ret .= '</directive>'; $pos = $p_end + 6; } else { $_ret = new ocp_tempcode(); $_ret->bits = array(read_single_uncompiled_variable($comcode, $pos, $len)); if ($_ret->bits[0][1] == TC_SYMBOL) { $ret = '<symbol>'; if (isset($_ret->bits[0][3])) { foreach ($_ret->bits[0][3] as $val) { $ret .= '<symbolParam>' . escape_html($val) . '</symbolParam>'; } } $ret .= $_ret->bits[0][2] . '</symbol>'; } else { $ret = '<language>'; if (isset($_ret->bits[0][3])) { foreach ($_ret->bits[0][3] as $val) { $ret .= '<languageParam>' . escape_html($val) . '</languageParam>'; } } $ret .= $_ret->bits[0][2] . '</language>'; } } $differented = true; $xml .= $ret; } } // Escaping of comcode tag starts lookahead if ($next == '\\' && !$in_code_tag) { if ($pos != $len && $comcode[$pos] == '"') { $continuation .= '"'; ++$pos; $differented = true; } elseif ($pos != $len && $comcode[$pos] == '[') { $continuation .= '['; ++$pos; $differented = true; } elseif ($pos != $len && $comcode[$pos] == '{') { $continuation .= '{'; ++$pos; $differented = true; } elseif ($pos == $len || $comcode[$pos] == '\\') { $continuation .= '\\'; ++$pos; $differented = true; } } // Smiley lookahead if (!$differented) { if (($textual_area || $in_semihtml) && trim($next) != '') { foreach ($smilies as $smiley => $imgcode) { if ($in_semihtml) { $smiley = ' ' . $smiley . ' '; } if ($next == $smiley[0]) { if (substr($comcode, $pos - 1, strlen($smiley)) == $smiley) { $xml .= $continuation; $continuation = ''; $pos += strlen($smiley) - 1; $differented = true; $xml .= '<emoticon>' . escape_html($imgcode) . '</emoticon>'; break; } } } } } if ($textual_area && trim($next) != '' && !$differented && addon_installed('cedi')) { // CEDI pages if ($pos < $len && $next == '[') { $matches = array(); if (preg_match('#^\\[([^\\[\\]]*)\\]\\]#', substr($comcode, $pos, 40), $matches) != 0) { $cedi_page_name = $matches[1]; $xml .= $continuation; $continuation = ''; $hash_pos = strpos($cedi_page_name, '#'); if ($hash_pos !== false) { $jump_to = substr($cedi_page_name, $hash_pos + 1); $cedi_page_name = substr($cedi_page_name, 0, $hash_pos); $xml .= '<cedi anchor="' . escape_html($jump_to) . '">' . escape_html($cedi_page_name) . '</cedi>'; } else { $xml .= '<cedi>' . escape_html($cedi_page_name) . '</cedi>'; } $pos += strlen($matches[1]) + 3; $differented = true; } } // Usernames if ($pos < $len && $next == '{') { $matches = array(); if (preg_match('#^\\{([^"{}&\'\\$<>]*)\\}\\}#', substr($comcode, $pos, 40), $matches) != 0) { $xml .= $continuation; $continuation = ''; $username = $matches[1]; if ($username[0] == '?') { $username = substr($username, 1); $xml .= '<member boxed="1">' . escape_html($username) . '</member>'; } else { $xml .= '<member>' . escape_html($username) . '</member>'; } $pos += strlen($matches[1]) + 3; $differented = true; } } if (!$in_code_tag && trim($next) != '' && !$differented) { // Shortcut lookahead if (!$differented) { foreach ($shortcuts as $code => $replacement) { if ($next == $code[0] && substr($comcode, $pos - 1, strlen($code)) == $code) { $xml .= $continuation; $continuation = ''; $pos += strlen($code) - 1; $differented = true; $xml .= $replacement; break; } } } } // Table syntax if (!$differented) { if ($pos < $len && $comcode[$pos] == '|') { $end_tbl = strpos($comcode, chr(10) . '|}', $pos); if ($end_tbl !== false) { $end_fst_line_pos = strpos($comcode, chr(10), $pos); $caption = substr($comcode, $pos + 2, max($end_fst_line_pos - $pos - 2, 0)); $pos += strlen($caption) + 1; $rows = preg_split('#(\\|-|\\|\\})#Um', substr($comcode, $pos, $end_tbl - $pos)); if (count($rows) == 1 && $caption == 'floats') { $cells = preg_split('/(\\n\\! | \\!\\! |\\n\\| | \\|\\| )/', $rows[0], -1, PREG_SPLIT_DELIM_CAPTURE); array_shift($cells); // First one is non-existant empty $spec = true; // Find which to float $to_float = NULL; foreach ($cells as $i => $cell) { if (!$spec) { if (strpos($cell, '!') !== false || is_null($to_float)) { $to_float = $i; } } $spec = !$spec; } $xml .= '<float>'; // Do floated one $xml .= '<fh>'; $xml .= comcode_text__to__comcode_xml(rtrim($cells[$to_float]), true); $xml .= '</fh>'; // Do non-floated ones foreach ($cells as $i => $cell) { if ($i % 2 == 1 && $i != $to_float) { $xml .= '<fd>'; $xml .= comcode_text__to__comcode_xml(rtrim($cells[$to_float]), true); $xml .= '</fd>'; } } $xml .= '</float>'; } else { $xml .= '<table summary="' . escape_html($caption) . '">'; foreach ($rows as $table_row) { $xml .= '<tr>'; $cells = preg_split('/(\\n\\! | \\!\\! |\\n\\| | \\|\\| )/', $table_row, -1, PREG_SPLIT_DELIM_CAPTURE); array_shift($cells); // First one is non-existant empty $spec = true; $c_type = ''; foreach ($cells as $cell) { if ($spec) { $c_type = strpos($cell, '!') !== false ? 'th' : 'td'; } else { $xml .= '<' . $c_type . '>'; $xml .= comcode_text__to__comcode_xml(rtrim($cell), true); $xml .= '</' . $c_type . '>'; } $spec = !$spec; } $xml .= '</tr>'; } $xml .= '</table>'; } $pos = $end_tbl + 3; $differented = true; } } } // Link lookahead if (!$differented) { if (!$in_semihtml && $next == 'h' && (substr($comcode, $pos - 1, strlen('http://')) == 'http://' || substr($comcode, $pos - 1, strlen('https://')) == 'https://' || substr($comcode, $pos - 1, strlen('ftp://')) == 'ftp://')) { list($link_end_pos, $auto_link) = detect_link($comcode, $pos); $xml .= $continuation; $continuation = ''; $downloaded_at_link = http_download_file($auto_link, 3000, false); $link_captions_title = ''; if (is_string($downloaded_at_link)) { $matches = array(); if (preg_match('#<title>\\s*(.*)\\s*</title>#', $downloaded_at_link, $matches) != 0) { require_code('character_sets'); $link_captions_title = @html_entity_decode(convert_to_internal_encoding($matches[1]), ENT_QUOTES, get_charset()); } } $xml .= '<url param="' . escape_html($auto_link) . '">' . escape_html($link_captions_title) . '</url>'; $pos += $link_end_pos - $pos; $differented = true; break; } } } if (!$differented) { if (!$in_separate_parse_section && (!$in_semihtml || !$comcode_dangerous && !$is_all_semihtml)) { if ($next == '&') { $ahead = substr($comcode, $pos, 20); $ahead_lower = strtolower($ahead); $matches = array(); $entity = preg_match('#(\\#)?([\\w]*);#', $ahead_lower, $matches) != 0; // If it is a SAFE entity, use it if ($entity) { if ($matches[1] == '' && isset($ALLOWED_ENTITIES[$matches[2]])) { $pos += strlen($matches[2]) + 1; $continuation .= '&' . $matches[2] . ';'; } elseif (is_numeric($matches[2]) && $matches[1] == '#') { $matched_entity = intval(base_convert($matches[1], 16, 10)); if ($matched_entity < 127 && array_key_exists(chr($matched_entity), $POTENTIAL_JS_NAUGHTY_ARRAY)) { $continuation .= escape_html($next); } else { $pos += strlen($matches[2]) + 2; $continuation .= '&#' . $matches[2] . ';'; } } else { $continuation .= '&'; } } else { $continuation .= '&'; } } else { $continuation .= escape_html($next); } } else { $continuation .= $next; } } } } } break; case CCP_IN_TAG_NAME: if ($next == '=') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT; $current_attribute_name = 'param'; } elseif (trim($next) == '') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTES; } elseif ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { if ($close) { if ($formatting_allowed) { list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; } if (count($tag_stack) == 0) { warn_exit(do_lang_tempcode('CCP_NO_CLOSE', escape_html($current_tag))); } $_last = array_pop($tag_stack); if ($_last[0] != $current_tag) { warn_exit(do_lang_tempcode('CCP_NO_CLOSE_MATCH', escape_html($current_tag), escape_html($_last))); } // Do the comcode for this tag if ($in_semihtml) { foreach ($_last[1] as $index => $conv) { $_last[1][$index] = @html_entity_decode(str_replace('<br />', chr(10), $conv), ENT_QUOTES, get_charset()); } } $attributes = $_last[1]; if ($current_tag == 'html') { $in_html = false; $_last[0] = 'htmlWrap'; } elseif ($current_tag == 'semihtml') { $in_semihtml = false; $_last[0] = 'htmlWrap'; } elseif ($current_tag == 'external_table' || $current_tag == 'internal_table') { $_last[0] = 'box'; } elseif ($current_tag == 'php') { $_last[0] = 'code'; $attributes['param'] = 'php'; } elseif ($current_tag == 'codebox') { $_last[0] = 'code'; $attributes['scroll'] = '1'; } elseif ($current_tag == 'sql') { $_last[0] = 'code'; $attributes['param'] = 'sql'; } elseif ($current_tag == 'snapback') { $_last[0] = 'post'; } elseif ($current_tag == 'thread') { $_last[0] = 'topic'; } elseif ($current_tag == 'list') { $sub_elements = explode('[*]', str_replace('[/*]', '', $xml)); $xml = ''; foreach ($sub_elements as $sub_element) { $xml .= '<listElement>' . $sub_element . '</listElement>'; } } if ($_last[0] == 'box' && isset($attributes['breadth']) && !isset($attributes['dimensions'])) { $attributes['dimensions'] = $attributes['breadth']; unset($attributes['breadth']); } if ($_last[0] == 'page' && array_keys($attributes) != array('param')) { $zone = isset($attributes['param']) ? $attributes['param'] : '_SEARCH'; $page = $xml; $xml = $attributes['caption']; unset($attributes['param']); unset($attributes['caption']); $pagelink = $zone . ':' . $page; foreach ($attributes as $key => $val) { $pagelink .= ':' . $key . '=' . $val; } $attributes = array('pageLink' => $pagelink); } if ($_last[0] == 'block') { foreach ($attributes as $key => $val) { $xml .= '<blockParam key="' . escape_html($key) . '" value="' . escape_html($val) . '" />'; } $attributes = array(); } if ($_last[0] == 'random') { foreach ($attributes as $key => $val) { $xml .= '<randomTarget pickIfAbove="' . escape_html($key) . '">' . comcode_text__to__comcode_xml($val, true) . '</randomTarget>'; } $attributes = array(); } if ($_last[0] == 'jumping') { foreach ($attributes as $key => $val) { $xml .= '<jumpingTarget>' . comcode_text__to__comcode_xml($val, true) . '</jumpingTarget>'; } $attributes = array(); } if ($_last[0] == 'concepts') { foreach ($attributes as $_key => $_value) { if (substr($_key, -4) == '_key') { $key = $_value; $cid = substr($_key, 0, strlen($_key) - 4); $value = $attributes[$cid . '_value']; $xml .= '<showConcept key="' . escape_html($key) . '" value="' . escape_html($value) . '" />'; } } $attributes = array(); } if (($_last[0] == 'attachment' || $_last[0] == 'attachment_safe') && isset($attributes['description'])) { $xml .= '<attachmentDescription>' . comcode_text__to__comcode_xml($attributes['description'], true) . '</attachmentDescription>'; unset($attributes['description']); } if ($_last[0] == 'hide' && isset($attributes['param'])) { $xml .= '<hideTitle>' . comcode_text__to__comcode_xml($attributes['param'], true) . '</hideTitle>'; unset($attributes['param']); } if ($_last[0] == 'tooltip' && isset($attributes['param'])) { $xml .= '<tooltipMessage>' . comcode_text__to__comcode_xml($attributes['param'], true) . '</tooltipMessage>'; unset($attributes['param']); } global $COMCODE_XML_PARAM_RENAMING, $COMCODE_XML_SWITCH_AROUND; if (isset($attributes['param']) && isset($COMCODE_XML_PARAM_RENAMING[$_last[0]])) { $attributes[$COMCODE_XML_PARAM_RENAMING[$_last[0]]] = $attributes['param']; unset($attributes['param']); } $comcode_xml_switch_around = $COMCODE_XML_SWITCH_AROUND; if ($_last[0] == 'email' && (!isset($attributes['param']) || !is_valid_email_address($attributes['param'])) && is_valid_email_address($xml)) { $comcode_xml_switch_around[] = 'email'; } if ($_last[0] == 'url' && (!isset($attributes['param']) || !looks_like_url($attributes['param'])) && looks_like_url($xml)) { $comcode_xml_switch_around[] = 'url'; } if (in_array($_last[0], $comcode_xml_switch_around)) { $x = 'param'; if ($_last[0] == 'reference') { $x = 'title'; } if (isset($attributes[$x])) { $temp = $attributes[$x]; $attributes[$x] = $xml; $xml = comcode_text__to__comcode_xml($temp, true); } else { $attributes[$x] = $xml; } } $in_code_tag = false; $white_space_area = $_last[3]; $in_separate_parse_section = $_last[4]; $formatting_allowed = $_last[5]; $textual_area = $_last[6]; if ($_last[0] == 'htmlWrap') { $embed_output = '<htmlWrap xmlns="http://www.w3.org/1999/xhtml">'; } else { $embed_output = '<' . to_camelCase($_last[0]); foreach ($attributes as $key => $val) { $embed_output .= ' ' . to_camelCase($key) . '="' . escape_html($val) . '"'; } $embed_output .= '>'; } $embed_output .= $xml . '</' . to_camelCase($_last[0]) . '>'; $just_ended = isset($BLOCK_TAGS[$current_tag]); $xml = $_last[2] . $embed_output; if ($current_tag == 'title') { if (strlen($comcode) > $pos + 1 && $comcode[$pos] == chr(10) && $comcode[$pos + 1] == chr(10)) { $NUM_LINES += 2; $pos += 2; $just_new_line = true; list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; } } $status = CCP_NO_MANS_LAND; } else { array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } } else { $current_tag .= strtolower($next); } break; case CCP_STARTING_TAG: if ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { warn_exit(do_lang_tempcode('CCP_TAG_CLOSE_ANOMALY')); } elseif ($next == '/') { $close = true; } else { $current_tag .= strtolower($next); $status = CCP_IN_TAG_NAME; } break; case CCP_IN_TAG_BETWEEN_ATTRIBUTES: if ($next == ']') { array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } elseif ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif (trim($next) != '') { $status = CCP_IN_TAG_ATTRIBUTE_NAME; $current_attribute_name = $next; } break; case CCP_IN_TAG_ATTRIBUTE_NAME: if ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { $at_map_keys = array_keys($attribute_map); $old_attribute_name = $at_map_keys[count($at_map_keys) - 1]; $attribute_map[$old_attribute_name] .= ' ' . $current_attribute_name; array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } elseif ($next == '=') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT; } elseif ($next != ' ') { $current_attribute_name .= strtolower($next); } else { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_LEFT; } break; case CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_LEFT: if ($next == '=') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT; } elseif (trim($next) != '') { warn_exit(do_lang_tempcode('CCP_ATTRIBUTE_ERROR', escape_html($current_attribute_name), escape_html($current_tag))); } break; case CCP_IN_TAG_BETWEEN_ATTRIBUTE_NAME_VALUE_RIGHT: if ($next == '[') { warn_exit(do_lang_tempcode('CCP_TAG_OPEN_ANOMALY')); } elseif ($next == ']') { warn_exit(do_lang_tempcode('CCP_TAG_CLOSE_ANOMALY')); } elseif ($next == '"' || $in_semihtml && substr($comcode, $pos - 1, 6) == '"') { if ($next != '"') { $pos += 5; } $status = CCP_IN_TAG_ATTRIBUTE_VALUE; $current_attribute_value = ''; } elseif ($next != '') { $status = CCP_IN_TAG_ATTRIBUTE_VALUE_NO_QUOTE; $current_attribute_value = $next; } break; case CCP_IN_TAG_ATTRIBUTE_VALUE_NO_QUOTE: if ($next == ' ') { $status = CCP_IN_TAG_BETWEEN_ATTRIBUTES; if (isset($attribute_map[$current_attribute_name])) { warn_exit(do_lang_tempcode('CCP_DUPLICATE_ATTRIBUTES', escape_html($current_attribute_name), escape_html($current_tag))); } $attribute_map[$current_attribute_name] = $current_attribute_value; } elseif ($next == ']') { if (isset($attribute_map[$current_attribute_name])) { warn_exit(do_lang_tempcode('CCP_DUPLICATE_ATTRIBUTES', escape_html($current_attribute_name), escape_html($current_tag))); } $attribute_map[$current_attribute_name] = $current_attribute_value; array_push($tag_stack, array($current_tag, $attribute_map, $xml, $white_space_area, $in_separate_parse_section, $formatting_allowed, $textual_area)); list(, , , $white_space_area, $formatting_allowed, $in_separate_parse_section, $textual_area, $attribute_map, $status, $in_html, $in_semihtml, $pos, $in_code_tag) = _opened_tag(false, false, get_member(), $attribute_map, $current_tag, $pos, $comcode_dangerous, $comcode_dangerous_html, $in_separate_parse_section, $in_html, $in_semihtml, $close, $len, $comcode); $xml = ''; } else { $current_attribute_value .= $next; } break; case CCP_IN_TAG_ATTRIBUTE_VALUE: if ($next == '"' || $in_semihtml && substr($comcode, $pos - 1, 6) == '"') { if ($next != '"') { $pos += 5; } $status = CCP_IN_TAG_BETWEEN_ATTRIBUTES; if (isset($attribute_map[$current_attribute_name])) { warn_exit(do_lang_tempcode('CCP_DUPLICATE_ATTRIBUTES', escape_html($current_attribute_name), escape_html($current_tag))); } $attribute_map[$current_attribute_name] = $current_attribute_value; } else { if ($next == '\\') { if ($comcode[$pos] == '"') { $current_attribute_value .= '"'; ++$pos; } elseif ($comcode[$pos] == '\\') { $current_attribute_value .= '\\'; ++$pos; } else { $current_attribute_value .= $next; } } else { $current_attribute_value .= $next; } } break; } } $xml .= $continuation; $continuation = ''; list($close_list, $list_indent) = _convert_close_open_lists($list_indent); $xml .= $close_list; if ($status != CCP_NO_MANS_LAND || count($tag_stack) != 0) { $stack_top = array_pop($tag_stack); warn_exit(do_lang_tempcode('CCP_BROKEN_END', escape_html($stack_top[0]))); } if (!$skip_wrapper) { $xml = '<comcode>' . $xml . '</comcode>'; } return $xml; }
/** * Get an array containing new comcode, and tempcode. The function wraps the normal comcode_to_tempcode function. The function will do attachment management, including deleting of attachments that have become unused due to editing of some comcode and removing of the reference. * * @param LONG_TEXT The unparsed comcode that references the attachments * @param ID_TEXT The type the attachment will be used for (e.g. download) * @param ID_TEXT The ID the attachment will be used for * @param boolean Whether we are only previewing the attachments (i.e. don't store them!) * @param ?object The database connection to use (NULL: standard site connection) * @param ?boolean Whether to insert it as an admin (any comcode parsing will be carried out with admin privileges) (NULL: autodetect) * @param ?MEMBER The member to use for ownership permissions (NULL: current member) * @return array A map containing 'comcode' (after substitution for tying down the new attachments) and 'tempcode' */ function do_comcode_attachments($original_comcode, $type, $id, $previewing_only = false, $connection = NULL, $insert_as_admin = NULL, $for_member = NULL) { require_lang('comcode'); global $COMCODE_ATTACHMENTS; unset($COMCODE_ATTACHMENTS[$id]); // In case we have some kind of conflict if (is_null($connection)) { $connection = $GLOBALS['SITE_DB']; } if ($for_member !== NULL) { $member = $for_member; if (is_null($insert_as_admin)) { $insert_as_admin = false; } } else { if (function_exists('get_member')) { $member = get_member(); if (is_null($insert_as_admin)) { $insert_as_admin = false; } } else { $member = 0; if (is_null($insert_as_admin)) { $insert_as_admin = true; } } } $comcode_text = substr($original_comcode, 0, 8) != '<comcode'; // Handle data URLs for attachment embedding if (function_exists('imagecreatefromstring')) { $matches = array(); $matches2 = array(); $num_matches = preg_match_all('#<img[^<>]*src="data:image/\\w+;base64,([^"]*)"[^<>]*>#', $original_comcode, $matches); $num_matches2 = preg_match_all('#\\[img[^\\[\\]]*\\]data:image/\\w+;base64,([^"]*)\\[/img\\]#', $original_comcode, $matches2); for ($i = 0; $i < $num_matches2; $i++) { $matches[0][$num_matches] = $matches2[0][$i]; $matches[1][$num_matches] = $matches2[1][$i]; $num_matches++; } for ($i = 0; $i < $num_matches; $i++) { if (strpos($original_comcode, $matches[0][$i]) !== false) { $data = @base64_decode($matches[1][$i]); if ($data !== false && function_exists('imagepng')) { $image = @imagecreatefromstring($data); if ($image !== false) { do { $new_filename = uniqid('', true) . '.png'; $new_path = get_custom_file_base() . '/uploads/attachments/' . $new_filename; } while (file_exists($new_path)); imagepng($image, $new_path); $attachment_id = $GLOBALS['SITE_DB']->query_insert('attachments', array('a_member_id' => get_member(), 'a_file_size' => strlen($data), 'a_url' => 'uploads/attachments/' . $new_filename, 'a_thumb_url' => '', 'a_original_filename' => basename($new_filename), 'a_num_downloads' => 0, 'a_last_downloaded_time' => time(), 'a_description' => '', 'a_add_time' => time()), true); $GLOBALS['SITE_DB']->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment_id)); $original_comcode = str_replace($matches[0][$i], '[attachment type="inline" thumb="0"]' . strval($attachment_id) . '[/attachment]', $original_comcode); } } } } } global $ATTACHMENTS_ALREADY_REFERENCED; $old_already = $ATTACHMENTS_ALREADY_REFERENCED; $ATTACHMENTS_ALREADY_REFERENCED = array(); $before = $connection->query_select('attachment_refs', array('a_id', 'id'), array('r_referer_type' => $type, 'r_referer_id' => $id)); foreach ($before as $ref) { $ATTACHMENTS_ALREADY_REFERENCED[$ref['a_id']] = 1; } $has_one = false; $may_have_one = false; foreach ($_POST as $key => $value) { if (preg_match('#^hidFileID\\_#i', $key) != 0) { require_code('uploads'); $may_have_one = is_swf_upload(); } } if ($may_have_one) { require_code('uploads'); is_swf_upload(true); require_code('comcode_from_html'); $original_comcode = preg_replace_callback('#<input [^>]*class="ocp_keep_ui_controlled" [^>]*title="([^"]*)" [^>]*type="text" [^>]*value="[^"]*"[^>]*/?' . '>#siU', 'debuttonise', $original_comcode); } $myfile = mixed(); foreach ($_FILES as $key => $file) { $matches = array(); if (($may_have_one && is_swf_upload() || is_uploaded_file($file['tmp_name'])) && preg_match('#file(\\d+)#', $key, $matches) != 0) { $has_one = true; $atype = post_param('attachmenttype' . $matches[1], ''); $is_extract = preg_match('#\\[attachment [^\\]]*type="\\w+_extract"[^\\]]*\\]new_' . $matches[1] . '\\[/#', $original_comcode) != 0 || preg_match('#<attachment [^>]*type="\\w+_extract"[^>]*>new_' . $matches[1] . '</#', $original_comcode) != 0; if (substr($atype, -8) == '_extract' || $is_extract) { require_code('uploads'); require_code('files'); require_code('files2'); $thumb = preg_match('#\\[(attachment|attachment_safe) [^\\]]*thumb="1"[^\\]]*\\]new_' . $matches[1] . '\\[/#', $original_comcode) != 0 || preg_match('#<(attachment|attachment_safe) [^>]*thumb="1"[^>]*>new_' . $matches[1] . '</#', $original_comcode) != 0; $arcext = get_file_extension($_FILES[$key]['name']); if ($arcext == 'tar' || $arcext == 'zip') { if ($arcext == 'tar') { require_code('tar'); $myfile = tar_open($file['tmp_name'], 'rb'); $dir = tar_get_directory($myfile, true); } elseif ($arcext == 'zip') { if (!function_exists('zip_open') && get_option('unzip_cmd') == '') { warn_exit(do_lang_tempcode('ZIP_NOT_ENABLED')); } if (!function_exists('zip_open')) { require_code('m_zip'); $mzip = true; } else { $mzip = false; } $myfile = zip_open($file['tmp_name']); if (is_integer($myfile)) { require_code('failure'); warn_exit(zip_error($myfile, $mzip)); } $dir = array(); while (($zip_entry = zip_read($myfile)) !== false) { $dir[] = array('zip_entry' => $zip_entry, 'path' => zip_entry_name($zip_entry), 'size' => zip_entry_filesize($zip_entry)); } } if (count($dir) > 100) { require_code('site'); attach_message(do_lang_tempcode('TOO_MANY_FILES_TO_EXTRACT'), 'warn'); } else { foreach ($dir as $entry) { if (substr($entry['path'], -1) == '/') { continue; } // Ignore folders $_file = preg_replace('#\\..*\\.#', '.', basename($entry['path'])); if (!check_extension($_file, false, NULL, true)) { continue; } if (should_ignore_file($entry['path'], IGNORE_ACCESS_CONTROLLERS | IGNORE_HIDDEN_FILES)) { continue; } $place = get_custom_file_base() . '/uploads/attachments/' . $_file; $i = 2; // Hunt with sensible names until we don't get a conflict while (file_exists($place)) { $_file = strval($i) . basename($entry['path']); $place = get_custom_file_base() . '/uploads/attachments/' . $_file; $i++; } $i = 2; $_file_thumb = basename($entry['path']); $place_thumb = get_custom_file_base() . '/uploads/attachments_thumbs/' . $_file_thumb; // Hunt with sensible names until we don't get a conflict while (file_exists($place_thumb)) { $_file_thumb = strval($i) . basename($entry['path']); $place_thumb = get_custom_file_base() . '/uploads/attachments_thumbs/' . $_file_thumb; $i++; } if ($arcext == 'tar') { $file_details = tar_get_file($myfile, $entry['path'], false, $place); } elseif ($arcext == 'zip') { zip_entry_open($myfile, $entry['zip_entry']); $file_details = array('size' => $entry['size']); $out_file = @fopen($place, 'wb') or intelligent_write_error($place); $more = mixed(); do { $more = zip_entry_read($entry['zip_entry']); if ($more !== false) { if (fwrite($out_file, $more) < strlen($more)) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } } } while ($more !== false && $more != ''); fclose($out_file); zip_entry_close($entry['zip_entry']); } $description = do_lang('EXTRACTED_FILE'); if (strpos($entry['path'], '/') !== false) { $description = do_lang('EXTRACTED_FILE_PATH', dirname($entry['path'])); } // Thumbnail $thumb_url = ''; require_code('images'); if (is_image($_file)) { $gd = get_option('is_on_gd') == '1' && function_exists('imagetypes'); if ($gd) { require_code('images'); if (!is_saveable_image($_file)) { $ext = '.png'; } else { $ext = '.' . get_file_extension($_file); } $thumb_url = 'uploads/attachments_thumbs/' . $_file_thumb; convert_image(get_custom_base_url() . '/uploads/attachments/' . $_file, $place_thumb, -1, -1, intval(get_option('thumb_width')), true, NULL, false, true); if ($connection->connection_write != $GLOBALS['SITE_DB']->connection_write) { $thumb_url = get_custom_base_url() . '/' . $thumb_url; } } else { $thumb_url = 'uploads/attachments/' . $_file; } } $url = 'uploads/attachments/' . $_file; if (addon_installed('galleries')) { require_code('images'); if (is_video($url) && $connection->connection_read == $GLOBALS['SITE_DB']->connection_read) { require_code('transcoding'); $url = transcode_video($url, 'attachments', 'a_url', 'a_original_filename', NULL, NULL); } } $attachment_id = $connection->query_insert('attachments', array('a_member_id' => get_member(), 'a_file_size' => $file_details['size'], 'a_url' => $url, 'a_thumb_url' => $thumb_url, 'a_original_filename' => basename($entry['path']), 'a_num_downloads' => 0, 'a_last_downloaded_time' => time(), 'a_description' => $description, 'a_add_time' => time()), true); $connection->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment_id)); if ($comcode_text) { $original_comcode .= chr(10) . chr(10) . '[attachment type="' . comcode_escape(str_replace('_extract', '', $atype)) . '" description="' . comcode_escape($description) . '" thumb="' . ($thumb ? '1' : '0') . '"]' . strval($attachment_id) . '[/attachment]'; } else { require_code('comcode_xml'); //$original_comcode.=chr(10).chr(10).'<attachment type="'.comcode_escape(str_replace('_extract','',$atype)).'" thumb="'.($thumb?'1':'0').'"><attachmentDescription>'.comcode_text__to__comcode_xml($description).'</attachmentDescription>'.strval($attachment_id).'</attachment>'; Would go in bad spot } } } if ($arcext == 'tar') { tar_close($myfile); } elseif ($arcext == 'zip') { zip_close($myfile); } } } else { if (strpos($original_comcode, ']new_' . $matches[1] . '[/attachment]') === false && strpos($original_comcode, '>new_' . $matches[1] . '</attachment>') === false && strpos($original_comcode, ']new_' . $matches[1] . '[/attachment_safe]') === false && strpos($original_comcode, '>new_' . $matches[1] . '</attachment_safe>') === false) { if (preg_match('#\\]\\d+\\[/attachment\\]#', $original_comcode) == 0 && preg_match('#>\\d+</attachment>#', $original_comcode) == 0) { if ($comcode_text) { $original_comcode .= chr(10) . chr(10) . '[attachment]new_' . $matches[1] . '[/attachment]'; } else { //$original_comcode.=chr(10).chr(10).'<attachment>new_'.$matches[1].'</attachment>'; Would go in bad spot } } } } } } global $LAX_COMCODE; $temp = $LAX_COMCODE; if ($has_one) { $LAX_COMCODE = true; } // We don't want a simple syntax error to cause us to lose our attachments $tempcode = comcode_to_tempcode($original_comcode, $member, $insert_as_admin, 60, $id, $connection, false, false, false, false, false, NULL, $for_member); $LAX_COMCODE = $temp; $ATTACHMENTS_ALREADY_REFERENCED = $old_already; /*if ((array_key_exists($id,$COMCODE_ATTACHMENTS)) && (array_key_exists(0,$COMCODE_ATTACHMENTS[$id]))) { $original_comcode=$COMCODE_ATTACHMENTS[$id][0]['comcode']; }*/ $new_comcode = $original_comcode; if (array_key_exists($id, $COMCODE_ATTACHMENTS)) { $ids_present = array(); for ($i = 0; $i < count($COMCODE_ATTACHMENTS[$id]); $i++) { $attachment = $COMCODE_ATTACHMENTS[$id][$i]; // If it's a new one, we need to change the comcode to reference the ID we made for it if ($attachment['type'] == 'new') { $marker = $attachment['marker']; // echo $marker.'!'.$new_comcode; $a_id = $attachment['id']; $old_length = strlen($new_comcode); // Search backwards from $marker $tag_end_start = $marker - strlen('[/' . $attachment['tag_type'] . ']'); // </attachment> would be correct if it is Comcode-XML, but they have the same length, so it's irrelevant $tag_start_end = $tag_end_start; while ($tag_start_end > 1 && (!isset($new_comcode[$tag_start_end - 1]) || $new_comcode[$tag_start_end - 1] != ']' && $new_comcode[$tag_start_end - 1] != '>')) { $tag_start_end--; } $param_keep = substr($new_comcode, 0, $tag_start_end - 1); $end_keep = substr($new_comcode, $tag_end_start); if ($comcode_text) { $new_comcode = $param_keep; if (strpos(substr($param_keep, strrpos($param_keep, '[')), ' type=') === false) { $new_comcode .= ' type="' . comcode_escape($attachment['attachmenttype']) . '"'; } if (strpos(substr($param_keep, strrpos($param_keep, '[')), ' description=') === false) { $new_comcode .= ' description="' . comcode_escape($attachment['description']) . '"'; } $new_comcode .= ']' . strval($a_id) . $end_keep; } else { require_code('comcode_xml'); $new_comcode = $param_keep; if (strpos(substr($param_keep, strrpos($param_keep, '<')), ' type=') === false) { $new_comcode .= ' type="' . comcode_escape($attachment['attachmenttype']); } $new_comcode .= '">'; if (strpos(substr($param_keep, strrpos($param_keep, '<')), ' description=') === false) { require_code('comcode_xml'); $new_comcode .= '<attachmentDescription>' . comcode_text__to__comcode_xml($attachment['description'], true) . '</attachmentDescription>'; } $new_comcode .= strval($a_id) . $end_keep; } // echo $new_comcode.'<br />!<br />'; // Update other attachment markers $dif = strlen($new_comcode) - $old_length; for ($j = $i + 1; $j < count($COMCODE_ATTACHMENTS[$id]); $j++) { // echo $COMCODE_ATTACHMENTS[$id][$i]['marker'].'!'; $COMCODE_ATTACHMENTS[$id][$j]['marker'] += $dif; } if (!is_null($type)) { $connection->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $a_id)); } } else { // (Re-)Reference it $connection->query_delete('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment['id']), '', 1); $connection->query_insert('attachment_refs', array('r_referer_type' => $type, 'r_referer_id' => $id, 'a_id' => $attachment['id'])); } $ids_present[] = $attachment['id']; } if (!$previewing_only && get_value('disable_attachment_cleanup') !== '1') { // Clear any de-referenced attachments foreach ($before as $ref) { if (!in_array($ref['a_id'], $ids_present) && strpos($new_comcode, 'attachment.php?id=') === false && !multi_lang()) { // Delete reference (as it's not actually in the new comcode!) $connection->query_delete('attachment_refs', array('id' => $ref['id']), '', 1); // Was that the last reference to this attachment? (if so -- delete attachment) $test = $connection->query_value_null_ok('attachment_refs', 'id', array('a_id' => $ref['a_id'])); if (is_null($test)) { require_code('attachments3'); _delete_attachment($ref['a_id'], $connection); } } } } } return array('comcode' => $new_comcode, 'tempcode' => $tempcode); }
/** * Export an ocPortal database row to an equivalent XML format. * * @param ID_TEXT Table to export * @param array DB row * @param array List of field definitions for the row * @param ?ID_TEXT SEO type code (NULL: N/A) * @param ?ID_TEXT Permission type code (NULL: N/A) * @param ?ID_TEXT ID field name (NULL: N/A) * @param boolean Whether to export Comcode as Comcode XML * @param boolean Whether to include the end tag for the row * @return string Exported data in XML format */ function _export_xml_row($table, $row, $db_fields, $seo_type_code, $permissions_type_code, $id_field, $comcode_xml, $include_end = true) { $xml_data = ''; $inner = ''; $fields = ''; $auto_key_id = NULL; foreach ($db_fields as $field) { if ($field['m_table'] != $table) { continue; } $name = $field['m_name']; $value = ''; if (strpos($field['m_type'], 'TRANS') !== false || $table == 'config' && $name == 'config_value' && $row[$name] != '' && strpos($row['the_type'], 'trans') !== false) { $translate_rows = $GLOBALS['SITE_DB']->query_select('translate', array('*'), array('id' => $row[$name])); foreach ($translate_rows as $t) { if ($comcode_xml && $t['text_parsed'] != '' && $t['text_original'] != '') { $value = chr(10) . _tab(comcode_text__to__comcode_xml($t['text_original'])) . chr(10); } else { $value = xmlentities($t['text_original']); } $inner .= _tab('<' . $name . ' language="' . xmlentities($t['language']) . '" importance_level="' . xmlentities(strval($t['importance_level'])) . '" source_user="******">' . $value . '</' . $name . '>') . chr(10); } if (strpos($field['m_type'], '*') !== false) { if ($field['m_type'] == '*AUTO') { $auto_key_id = $field['m_name']; } $fields .= ' ' . $name . '="' . xmlentities(strval($row[$name])) . '"'; } } else { if (!array_key_exists($name, $row)) { continue; } // Shouldn't happen, but corruption could lead to this switch (gettype($row[$name])) { case 'integer': switch (str_replace('?', '', str_replace('*', '', $field['m_type']))) { case 'TIME': $value = strftime('%a, %d %b %Y %H:%M:%S %z', $row[$name]); break; default: $value = strval($row[$name]); break; } break; case 'double': // float $value = float_to_raw_string($row[$name]); break; case 'NULL': $value = ''; break; default: $value = $row[$name]; break; } // Place data if (strpos($field['m_type'], '*') !== false) { if ($field['m_type'] == '*AUTO') { $auto_key_id = $field['m_name']; } $fields .= ' ' . $name . '="' . xmlentities($value) . '"'; } else { $inner .= _tab('<' . $name . '>' . xmlentities($value) . '</' . $name . '>') . chr(10); } } } // Assemble full row in XML format $xml_data .= chr(10) . chr(10); if (!is_null($auto_key_id)) { $xml_data .= '<!-- If copying to another site you may wish to remove the ' . $auto_key_id . ' attribute/value-pair so that an appropriate new key is chosen (otherwise could update the wrong record) -->' . chr(10); } $xml_data .= '<' . $table . $fields . '>' . chr(10); $xml_data .= $inner; // SEO if (!is_null($seo_type_code)) { $rows = $GLOBALS['SITE_DB']->query_select('seo_meta', array('*'), array('meta_for_type' => $seo_type_code, 'meta_for_id' => is_integer($row[$id_field]) ? strval($row[$id_field]) : $row[$id_field]), '', 1); if (array_key_exists(0, $rows)) { if (is_integer($rows[0]['meta_for_id'])) { $export_row = array('meta_for_id' => 'LAST_INSERT_ID_' . $table) + $rows[0]; } else { $export_row = $rows[0]; } $xml_data .= _tab(_export_xml_row('seo_meta', $export_row, $db_fields, NULL, NULL, NULL, $comcode_xml)); } } // Permissions if (!is_null($permissions_type_code)) { $rows = $GLOBALS['SITE_DB']->query_select('group_category_access', array('*'), array('module_the_name' => $permissions_type_code, 'category_name' => is_integer($row[$id_field]) ? strval($row[$id_field]) : $row[$id_field])); foreach ($rows as $_row) { if (is_integer($_row['category_name'])) { $export_row = array('category_name' => 'LAST_INSERT_ID_' . $table) + $_row; } else { $export_row = $_row; } $xml_data .= _tab(_export_xml_row('group_category_access', $export_row, $db_fields, NULL, NULL, NULL, $comcode_xml)); } $rows = $GLOBALS['SITE_DB']->query_select('gsp', array('*'), array('module_the_name' => $permissions_type_code, 'category_name' => is_integer($row[$id_field]) ? strval($row[$id_field]) : $row[$id_field])); foreach ($rows as $_row) { if (is_integer($_row['category_name'])) { $export_row = array('category_name' => 'LAST_INSERT_ID_' . $table) + $_row; } else { $export_row = $_row; } $xml_data .= _tab(_export_xml_row('gsp', $export_row, $db_fields, NULL, NULL, NULL, $comcode_xml)); } } if ($include_end) { $xml_data .= '</' . $table . '>'; } return $xml_data; }
/** * AJAX script for HTML<>Comcode conversion (and Comcode-Text>Comcode-XML). */ function comcode_convert_script() { header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past global $EXTRA_HEAD; if (!isset($EXTRA_HEAD)) { $EXTRA_HEAD = new ocp_tempcode(); } $EXTRA_HEAD->attach('<meta name="robots" content="noindex" />'); // XHTMLXHTML require_lang('comcode'); convert_data_encodings(true); $data = post_param('data', NULL, false, false); if (is_null($data)) { $title = get_page_title('_COMCODE'); $fields = new ocp_tempcode(); require_code('form_templates'); $fields->attach(form_input_huge(do_lang_tempcode('TEXT'), '', 'data', '', true)); $fields->attach(form_input_tick('Convert HTML to Comcode', '', 'from_html', false)); $fields->attach(form_input_tick('Convert to semihtml', '', 'semihtml', false)); $fields->attach(form_input_tick('Lax mode (less parse rules)', '', 'lax', false)); $hidden = new ocp_tempcode(); $hidden->attach(form_input_hidden('to_comcode_xml', strval(either_param_integer('to_comcode_xml', 0)))); $out2 = globalise(do_template('FORM_SCREEN', array('_GUID' => 'dd82970fa1196132e07049871c51aab7', 'TITLE' => $title, 'SUBMIT_NAME' => do_lang_tempcode('VIEW'), 'TEXT' => '', 'HIDDEN' => $hidden, 'URL' => find_script('comcode_convert', true), 'FIELDS' => $fields)), NULL, '', true); $out2->evaluate_echo(); return; } $panel = either_param_integer('panel', NULL); if (!is_null($panel)) { global $TEMPCODE_SETGET; if ($panel == 0) { $TEMPCODE_SETGET['in_panel'] = '0'; } else { $TEMPCODE_SETGET['in_panel'] = '1'; } } if (either_param_integer('to_comcode_xml', 0) == 1) { require_code('comcode_conversion'); $out = comcode_text__to__comcode_xml($data); } elseif (either_param_integer('from_html', 0) == 1) { require_code('comcode_from_html'); $out = trim(semihtml_to_comcode($data)); } else { if (either_param_integer('lax', 0) == 1) { $GLOBALS['LAX_COMCODE'] = true; } if (either_param_integer('is_semihtml', 0) == 1) { require_code('comcode_from_html'); $data = semihtml_to_comcode($data); } $db = $GLOBALS['SITE_DB']; if (get_param_integer('forum_db', 0) == 1) { $db = $GLOBALS['FORUM_DB']; } $tpl = comcode_to_tempcode($data, get_member(), false, 60, NULL, $db, either_param_integer('semihtml', 0) == 1, false, false, false); $evaluated = $tpl->evaluate(); $out = ''; if ($evaluated != '') { if (get_param_integer('css', 0) == 1) { global $CSSS; unset($CSSS['global']); unset($CSSS['no_cache']); $out .= static_evaluate_tempcode(css_tempcode()); } if (get_param_integer('javascript', 0) == 1) { global $JAVASCRIPTS; unset($JAVASCRIPTS['javascript']); unset($JAVASCRIPTS['javascript_staff']); $out .= static_evaluate_tempcode(javascript_tempcode()); } } $out .= trim(trim($evaluated)); } if (either_param_integer('fix_bad_html', 0) == 1) { require_code('xhtml'); $new = xhtmlise_html($out, true); if (preg_replace('#<!--.*-->#Us', '', preg_replace('#\\s+#', '', $new)) != preg_replace('#<!--.*-->#Us', '', preg_replace('#\\s+#', '', $out))) { /*$myfile=fopen(get_file_base().'/a','wb'); fwrite($myfile,preg_replace('#<!--.*-->#Us','',preg_replace('#\s+#',chr(10),$new))); fclose($myfile); $myfile=fopen(get_file_base().'/b','wb'); fwrite($myfile,preg_replace('#<!--.*-->#Us','',preg_replace('#\s+#',chr(10),$out))); fclose($myfile);*/ $out = $new . do_lang('BROKEN_XHTML_FIXED'); } } if (either_param_integer('keep_skip_rubbish', 0) == 0) { @ini_set('ocproducts.xss_detect', '0'); $box_title = get_param('box_title', ''); if (is_object($out)) { $out = $out->evaluate(); } if ($box_title != '' && $out != '') { $out = static_evaluate_tempcode(put_in_standard_box(make_string_tempcode($out), $box_title)); } header('Content-Type: text/xml'); echo '<?xml version="1.0" encoding="' . get_charset() . '"?' . '>'; echo '<request><result>'; echo xmlentities($out); echo '</result></request>'; } else { header('Content-type: text/plain; charset=' . get_charset()); echo $out; } }