function qa_length_validate(&$errors, $field, $input, $minlength, $maxlength) { if (isset($input)) { $length = qa_strlen($input); if ($length < $minlength) { $errors[$field] = $minlength == 1 ? qa_lang('main/field_required') : qa_lang_sub('main/min_length_x', $minlength); } elseif (isset($maxlength) && $length > $maxlength) { $errors[$field] = qa_lang_sub('main/max_length_x', $maxlength); } } }
/** * Check that a field meets the length requirements. If we're editing the post we can ignore missing fields. * * @param array $errors Array of errors, with keys matching $post * @param array $post The post containing the field we want to validate * @param string $key The element of $post to validate * @param int $minlength * @param int $maxlength */ private function validate_field_length(&$errors, &$post, $key, $minlength, $maxlength, $errorKey = null) { if (!$errorKey) { $errorKey = $key; } // skip the field is key not set (for example, 'title' when recategorizing questions) if (array_key_exists($key, $post)) { $length = qa_strlen($post[$key]); if ($length < $minlength) { $errors[$errorKey] = $minlength == 1 ? qa_lang('main/field_required') : qa_lang_sub('main/min_length_x', $minlength); } else { if (isset($maxlength) && $length > $maxlength) { $errors[$errorKey] = qa_lang_sub('main/max_length_x', $maxlength); } } } }
function qa_q_request($questionid, $title) { if (qa_to_override(__FUNCTION__)) { $args = func_get_args(); return qa_call_override(__FUNCTION__, $args); } require_once QA_INCLUDE_DIR . 'qa-app-options.php'; require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $title = qa_block_words_replace($title, qa_get_block_words_preg()); $words = qa_string_to_words($title, true, false, false); $wordlength = array(); foreach ($words as $index => $word) { $wordlength[$index] = qa_strlen($word); } $remaining = qa_opt('q_urls_title_length'); if (array_sum($wordlength) > $remaining) { arsort($wordlength, SORT_NUMERIC); // sort with longest words first foreach ($wordlength as $index => $length) { if ($remaining > 0) { $remaining -= $length; } else { unset($words[$index]); } } } $title = implode('-', $words); if (qa_opt('q_urls_remove_accents')) { $title = qa_string_remove_accents($title); } return (int) $questionid . '/' . $title; }
function qa_badge_plugin_user_form($userid) { $handles = qa_userids_to_handles(array($userid)); $handle = $handles[$userid]; // displays badge list in user profile $result = qa_db_read_all_assoc(qa_db_query_sub('SELECT badge_slug as slug, object_id AS oid FROM ^userbadges WHERE user_id=#', $userid)); $fields = array(); if (count($result) > 0) { // count badges $bin = qa_get_badge_list(); $badges = array(); foreach ($result as $info) { $slug = $info['slug']; $type = $bin[$slug]['type']; if (isset($badges[$type][$slug])) { $badges[$type][$slug]['count']++; } else { $badges[$type][$slug]['count'] = 1; } if ($info['oid']) { $badges[$type][$slug]['oid'][] = $info['oid']; } } foreach ($badges as $type => $badge) { $typea = qa_get_badge_type($type); $types = $typea['slug']; $typed = $typea['name']; $output = ' <table> <tr> <td class="qa-form-wide-label"> <h3 class="badge-title" title="' . qa_lang('badges/' . $types . '_desc') . '">' . $typed . '</h3> </td> </tr>'; foreach ($badge as $slug => $info) { $badge_name = qa_lang('badges/' . $slug); if (!qa_opt('badge_' . $slug . '_name')) { qa_opt('badge_' . $slug . '_name', $badge_name); } $name = qa_opt('badge_' . $slug . '_name'); $count = $info['count']; if (qa_opt('badge_show_source_posts')) { $oids = @$info['oid']; } else { $oids = null; } $var = qa_opt('badge_' . $slug . '_var'); $desc = qa_badge_desc_replace($slug, $var, $name); // badge row $output .= ' <tr> <td class="badge-container"> <div class="badge-container-badge"> <span class="badge-' . $types . '" title="' . $desc . ' (' . $typed . ')">' . qa_html($name) . '</span> <span onclick="jQuery(\'.badge-container-sources-' . $slug . '\').slideToggle()" class="badge-count' . (is_array($oids) ? ' badge-count-link" title="' . qa_lang('badges/badge_count_click') : '') . '">x ' . $count . '</span> </div>'; // source row(s) if any if (is_array($oids)) { $output .= ' <div class="badge-container-sources-' . $slug . '" style="display:none">'; foreach ($oids as $oid) { $post = qa_db_select_with_pending(qa_db_full_post_selectspec(null, $oid)); $title = $post['title']; $anchor = ''; if ($post['parentid']) { $anchor = urlencode(qa_anchor($post['type'], $oid)); $oid = $post['parentid']; $title = qa_db_read_one_value(qa_db_query_sub('SELECT BINARY title as title FROM ^posts WHERE postid=#', $oid), true); } $length = 30; $text = qa_strlen($title) > $length ? qa_substr($title, 0, $length) . '...' : $title; $output .= ' <div class="badge-source"><a href="' . qa_path_html(qa_q_request($oid, $title), NULL, qa_opt('site_url')) . ($anchor ? '#' . $anchor : '') . '">' . qa_html($text) . '</a></div>'; } } $output .= ' </td> </tr>'; } $output .= ' </table>'; $outa[] = $output; } $fields[] = array('value' => '<table class="badge-user-tables"><tr><td class="badge-user-table">' . implode('</td><td class="badge-user-table">', $outa) . '</td></tr></table>', 'type' => 'static'); } $ok = null; $tags = null; $buttons = array(); if ((bool) qa_opt('badge_email_notify') && qa_get_logged_in_handle() == $handle) { // add badge notify checkbox if (qa_clicked('badge_email_notify_save')) { qa_opt('badge_email_notify_id_' . $userid, (bool) qa_post_text('badge_notify_email_me')); $ok = qa_lang('badges/badge_notified_email_me'); } $select = (bool) qa_opt('badge_email_notify_id_' . $userid); $tags = 'id="badge-form" action="' . qa_self_html() . '#signature_text" method="POST"'; $fields[] = array('type' => 'blank'); $fields[] = array('label' => qa_lang('badges/badge_notify_email_me'), 'type' => 'checkbox', 'tags' => 'NAME="badge_notify_email_me"', 'value' => $select); $buttons[] = array('label' => qa_lang_html('main/save_button'), 'tags' => 'NAME="badge_email_notify_save"'); } return array('ok' => $ok && !isset($error) ? $ok : null, 'style' => 'tall', 'tags' => $tags, 'title' => qa_lang('badges/badges'), 'fields' => $fields, 'buttons' => $buttons); }
$inslug = qa_lang_sub('admin/category_default_slug', $inslug); break; default: $inslug = qa_lang_sub('admin/category_default_slug', $attempt - 1); break; } $matchcategoryid = qa_db_category_slug_to_id($inparentid, $inslug); // query against DB since MySQL ignores accents, etc... if (!isset($inparentid)) { $matchpage = qa_db_single_select(qa_db_page_full_selectspec($inslug, false)); } else { $matchpage = null; } if (empty($inslug)) { $errors['slug'] = qa_lang('main/field_required'); } elseif (qa_strlen($inslug) > QA_DB_MAX_CAT_PAGE_TAGS_LENGTH) { $errors['slug'] = qa_lang_sub('main/max_length_x', QA_DB_MAX_CAT_PAGE_TAGS_LENGTH); } elseif (preg_match('/[\\+\\/]/', $inslug)) { $errors['slug'] = qa_lang_sub('admin/slug_bad_chars', '+ /'); } elseif (!isset($inparentid) && qa_admin_is_slug_reserved($inslug)) { // only top level is a problem $errors['slug'] = qa_lang('admin/slug_reserved'); } elseif (isset($matchcategoryid) && strcmp($matchcategoryid, @$editcategory['categoryid'])) { $errors['slug'] = qa_lang('admin/category_already_used'); } elseif (isset($matchpage)) { $errors['slug'] = qa_lang('admin/page_already_used'); } else { unset($errors['slug']); } if (isset($editcategory['categoryid']) || !isset($errors['slug'])) { // don't try other options if editing existing category
function qa_block_words_replace($string, $wordspreg, $character = '*') { if (qa_to_override(__FUNCTION__)) { $args = func_get_args(); return qa_call_override(__FUNCTION__, $args); } if (strlen($wordspreg)) { $matches = qa_block_words_match_all($string, $wordspreg); krsort($matches, SORT_NUMERIC); foreach ($matches as $start => $length) { // get length again below to deal with multi-byte characters $string = substr_replace($string, str_repeat($character, qa_strlen(substr($string, $start, $length))), $start, $length); } } return $string; }
function qa_password_validate($password, $olduser = null) { $error = null; $filtermodules = qa_load_modules_with('filter', 'validate_password'); foreach ($filtermodules as $filtermodule) { $error = $filtermodule->validate_password($password, $olduser); if (isset($error)) { break; } } if (!isset($error)) { $minpasslen = max(QA_MIN_PASSWORD_LEN, 1); if (qa_strlen($password) < $minpasslen) { $error = qa_lang_sub('users/password_min', $minpasslen); } } if (isset($error)) { return array('password' => $error); } return array(); }
public function test__qa_strlen() { $test = qa_strlen($this->strAccents); $this->assertEquals($test, 43); }
function get_html($content, $format, $options) { if ($format == 'html') { $html = qa_sanitize_html($content, @$options['linksnewwindow'], false); // sanitize again for display, for extra safety, and due to new window setting if (isset($options['blockwordspreg'])) { // filtering out blocked words inline within HTML is pretty complex, e.g. p<B>oo</B>p must be caught require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $html = preg_replace('/<\\s*(' . $this->htmllineseparators . ')[^A-Za-z0-9]/i', "\n\\0", $html); // tags to single new line $html = preg_replace('/<\\s*(' . $this->htmlparagraphseparators . ')[^A-Za-z0-9]/i', "\n\n\\0", $html); // tags to double new line preg_match_all('/<[^>]*>/', $html, $pregmatches, PREG_OFFSET_CAPTURE); // find tag positions and lengths $tagmatches = $pregmatches[0]; $text = preg_replace('/<[^>]*>/', '', $html); // effectively strip_tags() but use same regexp as above to ensure consistency $blockmatches = qa_block_words_match_all($text, $options['blockwordspreg']); // search for blocked words within text $nexttagmatch = array_shift($tagmatches); $texttohtml = 0; $htmlshift = 0; foreach ($blockmatches as $textoffset => $textlength) { while (isset($nexttagmatch) && $nexttagmatch[1] <= $textoffset + $texttohtml) { // keep text and html in sync $texttohtml += strlen($nexttagmatch[0]); $nexttagmatch = array_shift($tagmatches); } while (1) { $replacepart = $textlength; if (isset($nexttagmatch)) { $replacepart = min($replacepart, $nexttagmatch[1] - ($textoffset + $texttohtml)); } // stop replacing early if we hit an HTML tag $replacelength = qa_strlen(substr($text, $textoffset, $replacepart)); // to work with multi-byte characters $html = substr_replace($html, str_repeat('*', $replacelength), $textoffset + $texttohtml + $htmlshift, $replacepart); $htmlshift += $replacelength - $replacepart; // HTML might have moved around if we replaced multi-byte characters if ($replacepart >= $textlength) { break; } // we have replaced everything expected, otherwise more left (due to hitting an HTML tag) $textlength -= $replacepart; $textoffset += $replacepart; $texttohtml += strlen($nexttagmatch[0]); $nexttagmatch = array_shift($tagmatches); } } } if (@$options['showurllinks']) { // we need to ensure here that we don't put new links inside existing ones require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $htmlunlinkeds = array_reverse(preg_split('|<[Aa]\\s+[^>]+>.*</[Aa]\\s*>|', $html, -1, PREG_SPLIT_OFFSET_CAPTURE)); // start from end so we substitute correctly foreach ($htmlunlinkeds as $htmlunlinked) { // and that we don't detect links inside HTML, e.g. <IMG SRC="http://..."> $thishtmluntaggeds = array_reverse(preg_split('/<[^>]*>/', $htmlunlinked[0], -1, PREG_SPLIT_OFFSET_CAPTURE)); // again, start from end foreach ($thishtmluntaggeds as $thishtmluntagged) { $innerhtml = $thishtmluntagged[0]; if (is_numeric(strpos($innerhtml, '://'))) { // quick test first $newhtml = qa_html_convert_urls($innerhtml, qa_opt('links_in_new_window')); $html = substr_replace($html, $newhtml, $htmlunlinked[1] + $thishtmluntagged[1], strlen($innerhtml)); } } } } } elseif ($format == '') { if (isset($options['blockwordspreg'])) { require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $content = qa_block_words_replace($content, $options['blockwordspreg']); } $html = qa_html($content, true); if (@$options['showurllinks']) { require_once QA_INCLUDE_DIR . 'qa-app-format.php'; $html = qa_html_convert_urls($html, qa_opt('links_in_new_window')); } } else { $html = '[no viewer found for format: ' . qa_html($format) . ']'; } // for unknown formats return $html; }
// Process saving an old or new user field if (qa_clicked('docancel')) { qa_redirect('admin/users'); } elseif (qa_clicked('dosavefield')) { require_once QA_INCLUDE_DIR . 'qa-db-admin.php'; require_once QA_INCLUDE_DIR . 'qa-util-string.php'; if (qa_post_text('dodelete')) { qa_db_userfield_delete($editfield['fieldid']); qa_redirect('admin/users'); } else { $inname = qa_post_text('name'); $inflags = qa_post_text('flags'); $inposition = qa_post_text('position'); $errors = array(); // Verify the name is legitimate if (qa_strlen($inname) > QA_DB_MAX_PROFILE_TITLE_LENGTH) { $errors['name'] = qa_lang_sub('main/max_length_x', QA_DB_MAX_PROFILE_TITLE_LENGTH); } // Perform appropriate database action if (isset($editfield['fieldid'])) { // changing existing user field qa_db_userfield_set_fields($editfield['fieldid'], isset($errors['name']) ? $editfield['content'] : $inname, $inflags); qa_db_userfield_move($editfield['fieldid'], $inposition); if (empty($errors)) { qa_redirect('admin/users'); } else { $userfields = qa_db_select_with_pending(qa_db_userfields_selectspec()); // reload after changes foreach ($userfields as $userfield) { if ($userfield['fieldid'] == $editfield['fieldid']) { $editfield = $userfield;
function qa_block_words_replace($string, $wordspreg, $character = '*') { if (strlen($wordspreg)) { $matches = qa_block_words_match_all($string, $wordspreg); krsort($matches, SORT_NUMERIC); foreach ($matches as $start => $length) { // get length again below to deal with multi-byte characters $string = substr_replace($string, str_repeat($character, qa_strlen(substr($string, $start, $length))), $start, $length); } } return $string; }
function qa_q_request($questionid, $title) { require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $words = qa_string_to_words($title, true, false, false); $wordlength = array(); foreach ($words as $index => $word) { $wordlength[$index] = qa_strlen($word); } $remaining = qa_opt('q_urls_title_length'); if (array_sum($wordlength) > $remaining) { arsort($wordlength, SORT_NUMERIC); // sort with longest words first foreach ($wordlength as $index => $length) { if ($remaining > 0) { $remaining -= $length; } else { unset($words[$index]); } } } $title = implode('-', $words); if (qa_opt('q_urls_remove_accents')) { $title = qa_string_remove_accents($title); } return (int) $questionid . '/' . $title; }
function qa_password_validate($password) { require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $errors = array(); $minpasslen = max(QA_MIN_PASSWORD_LEN, 1); if (qa_strlen($password) < $minpasslen) { $errors['password'] = qa_lang_sub('users/password_min', $minpasslen); } return $errors; }
function get_html($content, $format, $options) { if ($format == 'html') { $html = qa_sanitize_html($content, @$options['linksnewwindow']); // sanitize again for display, for extra safety, and due to new window setting if (isset($options['blockwordspreg'])) { // filtering out blocked words inline within HTML is pretty complex, e.g. p<B>oo</B>p must be caught require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $html = preg_replace('/<\\s*(' . $this->htmllineseparators . ')[^A-Za-z0-9]/i', "\n\\0", $html); // tags to single new line $html = preg_replace('/<\\s*(' . $this->htmlparagraphseparators . ')[^A-Za-z0-9]/i', "\n\n\\0", $html); // tags to double new line preg_match_all('/<[^>]*>/', $html, $pregmatches, PREG_OFFSET_CAPTURE); // find tag positions and lengths $tagmatches = $pregmatches[0]; $text = preg_replace('/<[^>]*>/', '', $html); // effectively strip_tags() but use same regexp as above to ensure consistency $blockmatches = qa_block_words_match_all($text, $options['blockwordspreg']); // search for blocked words within text $nexttagmatch = array_shift($tagmatches); $texttohtml = 0; $htmlshift = 0; foreach ($blockmatches as $textoffset => $textlength) { while (isset($nexttagmatch) && $nexttagmatch[1] <= $textoffset + $texttohtml) { // keep text and html in sync $texttohtml += strlen($nexttagmatch[0]); $nexttagmatch = array_shift($tagmatches); } while (1) { $replacepart = $textlength; if (isset($nexttagmatch)) { $replacepart = min($replacepart, $nexttagmatch[1] - ($textoffset + $texttohtml)); } // stop replacing early if we hit an HTML tag $replacelength = qa_strlen(substr($text, $textoffset, $replacepart)); // to work with multi-byte characters $html = substr_replace($html, str_repeat('*', $replacelength), $textoffset + $texttohtml + $htmlshift, $replacepart); $htmlshift += $replacelength - $replacepart; // HTML might have moved around if we replaced multi-byte characters if ($replacepart >= $textlength) { break; } // we have replaced everything expected, otherwise more left (due to hitting an HTML tag) $textlength -= $replacepart; $textoffset += $replacepart; $texttohtml += strlen($nexttagmatch[0]); $nexttagmatch = array_shift($tagmatches); } } } } else { if (isset($options['blockwordspreg'])) { require_once QA_INCLUDE_DIR . 'qa-util-string.php'; $content = qa_block_words_replace($content, $options['blockwordspreg']); } $html = qa_html($content, true); if (@$options['showurllinks']) { require_once QA_INCLUDE_DIR . 'qa-app-format.php'; $html = qa_html_convert_urls($html, qa_opt('links_in_new_window')); } } return $html; }