/** * Convert a string to an array, with utf-8 awareness where possible/required. * * @param string Input * @param boolean Whether to force unicode as on. * @return array Output */ function ocp_mb_str_split($str, $force = false) { $len = ocp_mb_strlen($str, $force); $array = array(); for ($i = 0; $i < $len; $i++) { $array[] = ocp_mb_substr($str, $i, 1, $force); } return $array; }
/** * Return part of a string, with utf-8 awareness where possible/required. * * @param string The subject. * @param integer The start position. * @param ?integer The length to extract (NULL: all remaining). * @param boolean Whether to force unicode as on. * @return ~string String part (false: $start was over the end of the string). */ function ocp_mb_substr($in, $from, $amount = NULL, $force = false) { if (is_null($amount)) { $amount = ocp_mb_strlen($in, $force) - $from; } if (!$force && strtolower(get_charset()) != 'utf-8') { return substr($in, $from, $amount); } if (function_exists('iconv_substr')) { return @iconv_substr($in, $from, $amount, $force ? 'utf-8' : get_charset()); } if (function_exists('mb_substr')) { return @mb_substr($in, $from, $amount, $force ? 'utf-8' : get_charset()); } $ret = substr($in, $from, $amount); $end = ord(substr($ret, -1)); if ($end >= 192 && $end <= 223) { $ret .= substr($in, $from + $amount, 1); } if ($from != 0) { $start = ord(substr($ret, 0, 1)); if ($start >= 192 && $start <= 223) { $ret = substr($in, $from - 1, 1) . $ret; } } return $ret; }
/** * Handle truncation symbols in all their complexity * * @param array Parameters passed to the symbol (0=text, 1=amount, 2=tooltip?, 3=is_html?, 4=use as grammatical length rather than HTML byte length, 5=fractional-deviation-tolerance for grammar-preservation) * @param string The type of truncation to do * @set left right spread * @param ?mixed Tooltip to add on, but only if we end up creating our own tooltip (NULL: none) * @return string The result. */ function symbol_truncator($param, $type, $tooltip_if_truncated = NULL) { $value = ''; if (is_object($param[0])) { $param[0] = $param[0]->evaluate(); if (!isset($param[2])) { $param[2] = '0'; } $param[3] = '1'; } if ($GLOBALS['XSS_DETECT']) { $is_escaped = ocp_is_escaped($param[0]); } $amount = intval(isset($param[1]) ? $param[1] : '60'); $is_html = isset($param[3]) && $param[3] == '1'; if ($is_html) { $not_html = @html_entity_decode(strip_tags($param[0]), ENT_QUOTES, get_charset()); // In case it contains HTML. This is imperfect, but having to cut something up is imperfect from the offset. $html = $param[0]; if ($GLOBALS['XSS_DETECT']) { ocp_mark_as_escaped($html); } if ($html == $not_html && strpos($html, '&') === false && strpos($html, '<') === false) { $is_html = false; } // Conserve memory } else { $not_html = $param[0]; $html = escape_html($param[0]); } if (ocp_mb_strlen($not_html) > $amount) { $tooltip = isset($param[2]) && $param[2] == '1'; $literal_pos = isset($param[4]) ? $param[4] == '1' : false; $grammar_completeness_tolerance = isset($param[5]) ? floatval($param[5]) : 0.0; if ($is_html || $grammar_completeness_tolerance != 0.0) { require_code('xhtml'); } $truncated = $not_html; switch ($type) { case 'left': $temp = $is_html || $grammar_completeness_tolerance != 0.0 ? xhtml_substr($html, 0, $amount - 3, $literal_pos, false, $grammar_completeness_tolerance) : escape_html(ocp_mb_substr($not_html, 0, $amount - 3)); if ($temp != $html && in_array(substr($temp, -1), array('.', '?', '!'))) { $temp .= '<br />'; } // so the "..." does not go right after the sentence terminator $truncated = $temp == $html ? $temp : str_replace(array('</p>…', '</div>…'), array('…</p>', '…</div>'), rtrim($temp) . '…'); break; case 'expand': $temp = $is_html || $grammar_completeness_tolerance != 0.0 ? xhtml_substr($html, 0, $amount - 3, $literal_pos, false, $grammar_completeness_tolerance) : escape_html(ocp_mb_substr($not_html, 0, $amount - 3)); if ($temp != $html && in_array(substr($temp, -1), array('.', '?', '!'))) { $temp .= '<br />'; } // so the "..." does not go right after the sentence terminator $_truncated = do_template('COMCODE_HIDE', array('TEXT' => protect_from_escaping($temp), 'CONTENT' => protect_from_escaping($html))); $truncated = $_truncated->evaluate(); break; case 'right': $truncated = str_replace(array('</p>…', '</div>…'), array('…</p>', '…</div>'), '…' . ltrim($is_html || $grammar_completeness_tolerance != 0.0 ? xhtml_substr($html, -$amount - 3, NULL, $literal_pos, false, $grammar_completeness_tolerance) : escape_html(ocp_mb_substr($not_html, -$amount - 3)))); break; case 'spread': $pos = intval(floor(floatval($amount) / 2.0)) - 1; $truncated = str_replace(array('</p>…', '</div>…'), array('…</p>', '…</div>'), rtrim(($is_html || $grammar_completeness_tolerance != 0.0 ? xhtml_substr($html, 0, $pos, $literal_pos, false, $grammar_completeness_tolerance) : escape_html(ocp_mb_substr($not_html, 0, $pos))) . '…' . ltrim($is_html || $grammar_completeness_tolerance != 0.0 ? xhtml_substr($html, -$pos - 1) : escape_html(ocp_mb_substr($not_html, -$pos - 1))))); break; } if ($tooltip) { if (!is_null($tooltip_if_truncated)) { $tif = is_object($tooltip_if_truncated) ? $tooltip_if_truncated->evaluate() : $tooltip_if_truncated; if (strpos($tif, $html) !== false) { $html = $tif; } else { $html .= ' – ' . $tif; } } $tpl = strpos($truncated, '<div') !== false || strpos($truncated, '<p') !== false || strpos($truncated, '<table') !== false ? 'CROP_TEXT_MOUSE_OVER' : 'CROP_TEXT_MOUSE_OVER_INLINE'; $value_tempcode = do_template($tpl, array('_GUID' => '36ae945ed864633cfa0d67e5c3f2d1c8', 'TEXT_SMALL' => $truncated, 'TEXT_LARGE' => $html)); $value = $value_tempcode->evaluate(); if ($GLOBALS['XSS_DETECT']) { ocp_mark_as_escaped($value); } } else { $value = $truncated; } } else { $value = $html; } if ($GLOBALS['XSS_DETECT']) { if ($is_escaped || !$is_html) { ocp_mark_as_escaped($value); } } return $value; }
/** * Edit a member's signature, and check validity. * * @param LONG_TEXT The new signature. * @param ?MEMBER The member (NULL: the current member). */ function ocf_member_choose_signature($new_signature, $member_id = NULL) { if (is_null($member_id)) { $member_id = get_member(); } $max_sig_length = ocf_get_member_best_group_property($member_id, 'max_sig_length_comcode'); if (ocp_mb_strlen($new_signature) > $max_sig_length) { warn_exit(make_string_tempcode(escape_html(do_lang('SIGNATURE_TOO_BIG')))); } $_signature = $GLOBALS['OCF_DRIVER']->get_member_row_field($member_id, 'm_signature'); if (get_translated_text($_signature) == $new_signature) { return; } require_code('attachments2'); require_code('attachments3'); $GLOBALS['FORUM_DB']->query_update('f_members', array('m_signature' => update_lang_comcode_attachments($_signature, $new_signature, 'ocf_signature', strval($member_id), $GLOBALS['FORUM_DB'], false, $member_id)), array('id' => $member_id), '', 1); require_code('notifications'); dispatch_notification('ocf_choose_signature', NULL, do_lang('CHOOSE_SIGNATURE_SUBJECT', $GLOBALS['FORUM_DRIVER']->get_username($member_id), NULL, NULL, get_lang($member_id)), do_lang('CHOOSE_SIGNATURE_BODY', $new_signature, $GLOBALS['FORUM_DRIVER']->get_username($member_id), NULL, get_lang($member_id))); // Decache from run-time cache unset($GLOBALS['FORUM_DRIVER']->MEMBER_ROWS_CACHED[$member_id]); unset($GLOBALS['MEMBER_CACHE_FIELD_MAPPINGS'][$member_id]); }