qa-filter-basic.php 6.44 KB
Newer Older
Scott committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
<?php
/*
	Question2Answer by Gideon Greenspan and contributors
	http://www.question2answer.org/

	Description: Basic module for validating form inputs


	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	More about this license: http://www.question2answer.org/license.php
*/

Scott committed
22
require_once QA_INCLUDE_DIR.'db/maxima.php';
Scott committed
23
require_once QA_INCLUDE_DIR.'util/string.php';
Scott committed
24

Scott committed
25 26 27 28
class qa_filter_basic
{
	public function filter_email(&$email, $olduser)
	{
Scott committed
29
		if (!strlen($email)) {
Scott committed
30
			return qa_lang('users/email_required');
Scott committed
31 32
		}
		if (!qa_email_validate($email)) {
Scott committed
33
			return qa_lang('users/email_invalid');
Scott committed
34 35
		}
		if (qa_strlen($email) > QA_DB_MAX_EMAIL_LENGTH) {
Scott committed
36
			return qa_lang_sub('main/max_length_x', QA_DB_MAX_EMAIL_LENGTH);
Scott committed
37
		}
Scott committed
38
	}
Scott committed
39

Scott committed
40 41
	public function filter_handle(&$handle, $olduser)
	{
Scott committed
42
		if (!strlen($handle)) {
Scott committed
43
			return qa_lang('users/handle_empty');
Scott committed
44
		}
Scott committed
45 46 47
		if (in_array($handle, array('.', '..'))) {
			return qa_lang_sub('users/handle_has_bad', '. ..');
		}
Scott committed
48
		if (preg_match('/[\\@\\+\\/]/', $handle)) {
Scott committed
49
			return qa_lang_sub('users/handle_has_bad', '@ + /');
Scott committed
50 51
		}
		if (qa_strlen($handle) > QA_DB_MAX_HANDLE_LENGTH) {
Scott committed
52
			return qa_lang_sub('main/max_length_x', QA_DB_MAX_HANDLE_LENGTH);
Scott committed
53
		}
54 55 56 57 58 59
		// check for banned usernames (e.g. "anonymous")
		$wordspreg = qa_block_words_to_preg(qa_opt('block_bad_usernames'));
		$blocked = qa_block_words_match_all($handle, $wordspreg);
		if (!empty($blocked)) {
			return qa_lang('users/handle_blocked');
		}
Scott committed
60
	}
Scott committed
61

Scott committed
62 63
	public function filter_question(&$question, &$errors, $oldquestion)
	{
64 65 66 67 68 69 70
		if ($oldquestion === null) {
			// a new post requires these fields be set
			$question['title'] = isset($question['title']) ? $question['title'] : '';
			$question['content'] = isset($question['content']) ? $question['content'] : '';
			$question['text'] = isset($question['text']) ? $question['text'] : '';
			$question['tags'] = isset($question['tags']) ? $question['tags'] : array();
		}
Scott committed
71

72 73 74
		$qminlength = qa_opt('min_len_q_title');
		$qmaxlength = max($qminlength, min(qa_opt('max_len_q_title'), QA_DB_MAX_TITLE_LENGTH));
		$this->validate_field_length($errors, $question, 'title', $qminlength, $qmaxlength);
Scott committed
75

76 77
		$this->validate_field_length($errors, $question, 'content', 0, QA_DB_MAX_CONTENT_LENGTH); // for storage
		$this->validate_field_length($errors, $question, 'text', qa_opt('min_len_q_content'), null); // for display
78 79 80 81
		// ensure content error is shown
		if (isset($errors['text'])) {
			$errors['content'] = $errors['text'];
		}
Scott committed
82

Scott committed
83
		if (isset($question['tags'])) {
84 85 86 87 88 89
			$counttags = count($question['tags']);
			$maxtags = qa_opt('max_num_q_tags');
			$mintags = min(qa_opt('min_num_q_tags'), $maxtags);

			if ($counttags < $mintags) {
				$errors['tags'] = qa_lang_sub('question/min_tags_x', $mintags);
Scott committed
90
			} elseif ($counttags > $maxtags) {
91
				$errors['tags'] = qa_lang_sub('question/max_tags_x', $maxtags);
Scott committed
92
			} else {
93 94
				$tagstring = qa_tags_to_tagstring($question['tags']);
				if (qa_strlen($tagstring) > QA_DB_MAX_TAGS_LENGTH) { // for storage
pupi1985 committed
95
					$errors['tags'] = qa_lang_sub('main/max_length_x', QA_DB_MAX_TAGS_LENGTH);
96 97
				}
			}
Scott committed
98 99
		}

Scott committed
100 101
		$this->validate_post_email($errors, $question);
	}
Scott committed
102

Scott committed
103 104
	public function filter_answer(&$answer, &$errors, $question, $oldanswer)
	{
105 106
		$this->validate_field_length($errors, $answer, 'content', 0, QA_DB_MAX_CONTENT_LENGTH); // for storage
		$this->validate_field_length($errors, $answer, 'text', qa_opt('min_len_a_content'), null, 'content'); // for display
Scott committed
107 108
		$this->validate_post_email($errors, $answer);
	}
Scott committed
109

Scott committed
110 111
	public function filter_comment(&$comment, &$errors, $question, $parent, $oldcomment)
	{
112
		$this->validate_field_length($errors, $comment, 'content', 0, QA_DB_MAX_CONTENT_LENGTH); // for storage
113
		$this->validate_field_length($errors, $comment, 'text', qa_opt('min_len_c_content'), null, 'content'); // for display
Scott committed
114 115
		$this->validate_post_email($errors, $comment);
	}
Scott committed
116

Scott committed
117 118
	public function filter_profile(&$profile, &$errors, $user, $oldprofile)
	{
119 120
		foreach (array_keys($profile) as $field) {
			// ensure fields are not NULL
Scott committed
121
			$profile[$field] = (string)$profile[$field];
122 123
			$this->validate_field_length($errors, $profile, $field, 0, QA_DB_MAX_CONTENT_LENGTH);
		}
Scott committed
124
	}
Scott committed
125 126


Scott committed
127
	// The definitions below are not part of a standard filter module, but just used within this one
Scott committed
128

Scott committed
129
	/**
130 131
	 * Add textual element $field to $errors if length of $input is not between $minlength and $maxlength.
	 *
Scott committed
132
	 * @deprecated This function is no longer used and will removed in the future.
Scott committed
133
	 */
134
	public function validate_length(&$errors, $field, $input, $minlength, $maxlength)
Scott committed
135 136
	{
		$length = isset($input) ? qa_strlen($input) : 0;
Scott committed
137

Scott committed
138 139 140 141 142
		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);
	}
Scott committed
143

144 145 146
	/**
	 * Check that a field meets the length requirements. If we're editing the post we can ignore missing fields.
	 *
Scott committed
147 148 149
	 * @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
150 151 152
	 * @param int $minlength
	 * @param int $maxlength
	 */
Scott committed
153
	private function validate_field_length(&$errors, &$post, $key, $minlength, $maxlength, $errorKey = null)
154
	{
155 156 157 158
		if (!$errorKey) {
			$errorKey = $key;
		}

159
		// skip the field if key not set (for example, 'title' when recategorizing questions)
160 161 162 163
		if (array_key_exists($key, $post)) {
			$length = qa_strlen($post[$key]);

			if ($length < $minlength) {
164
				$errors[$errorKey] = $minlength == 1 ? qa_lang('main/field_required') : qa_lang_sub('main/min_length_x', $minlength);
165
			} elseif (isset($maxlength) && ($length > $maxlength)) {
166
				$errors[$errorKey] = qa_lang_sub('main/max_length_x', $maxlength);
167 168 169 170
			}
		}
	}

171 172 173
	/**
	 * Wrapper function for validating a post's email address.
	 */
174
	private function validate_post_email(&$errors, $post)
Scott committed
175 176
	{
		if (@$post['notify'] && strlen(@$post['email'])) {
Scott committed
177 178 179 180
			$error = $this->filter_email($post['email'], null);
			if (isset($error)) {
				$errors['email'] = $error;
			}
Scott committed
181 182
		}
	}
Scott committed
183
}