<commit_before>
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2014 Phalcon Team (http://www.phalconphp.com)       |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file docs/LICENSE.txt.                        |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to <EMAIL> so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: <NAME> <<EMAIL>>                      |
  |          <NAME> <<EMAIL>>                         |
  |          <NAME>                                                    |
  +------------------------------------------------------------------------+
*/

#include "mvc/model/validator/stringlength.h"
#include "mvc/model/validator.h"
#include "mvc/model/validatorinterface.h"
#include "mvc/model/exception.h"

#include "kernel/main.h"
#include "kernel/memory.h"
#include "kernel/fcall.h"
#include "kernel/exception.h"
#include "kernel/string.h"
#include "kernel/operators.h"
#include "kernel/concat.h"

#include "interned-strings.h"

/**
 * Phalcon\Mvc\Model\Validator\StringLength
 *
 * Simply validates specified string length constraints
 *
 *<code>
 *use Phalcon\Mvc\Model\Validator\StringLength as StringLengthValidator;
 *
 *class Subscriptors extends Phalcon\Mvc\Model
 *{
 *
 *	public function validation()
 *	{
 *		$this->validate(new StringLengthValidator(array(
 *			'field' => 'name_last',
 *			'max' => 50,
 *			'min' => 2,
 *			'messageMaximum' => 'We don\'t like really long names',
 *			'messageMinimum' => 'We want more than just their initials'
 *		)));
 *		if ($this->validationHasFailed() == true) {
 *			return false;
 *		}
 *	}
 *
 *}
 *</code>
 *
 */
zend_class_entry *phalcon_mvc_model_validator_stringlength_ce;

PHP_METHOD(Phalcon_Mvc_Model_Validator_StringLength, validate);

static const zend_function_entry phalcon_mvc_model_validator_stringlength_method_entry[] = {
	PHP_ME(Phalcon_Mvc_Model_Validator_StringLength, validate, arginfo_phalcon_mvc_model_validatorinterface_validate, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/**
 * Phalcon\Mvc\Model\Validator\StringLength initializer
 */
PHALCON_INIT_CLASS(Phalcon_Mvc_Model_Validator_StringLength){

	PHALCON_REGISTER_CLASS_EX(Phalcon\\Mvc\\Model\\Validator, StringLength, mvc_model_validator_stringlength, phalcon_mvc_model_validator_ce, phalcon_mvc_model_validator_stringlength_method_entry, 0);

	zend_class_implements(phalcon_mvc_model_validator_stringlength_ce TSRMLS_CC, 1, phalcon_mvc_model_validatorinterface_ce);

	return SUCCESS;
}

/**
 * Executes the validator
 *
 * @param Phalcon\Mvc\ModelInterface $record
 * @return boolean
 */
PHP_METHOD(Phalcon_Mvc_Model_Validator_StringLength, validate){

	zval *record, *option = NULL, *field, *is_set_min, *is_set_max;
	zval *value, *length = NULL, *invalid_maximum = NULL, *invalid_minimum = NULL;
	zval *maximum, *message = NULL, *type = NULL, *minimum, *is_set_code, *code;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 1, 0, &record);
	
	PHALCON_INIT_VAR(option);
	ZVAL_STRING(option, "field", 1);
	
	PHALCON_INIT_VAR(field);
	phalcon_call_method_p1(field, this_ptr, "getoption", option);
	if (Z_TYPE_P(field) != IS_STRING) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "Field name must be a string");
		return;
	}
	
	/** 
	 * At least one of 'min' or 'max' must be set
	 */
	PHALCON_INIT_NVAR(option);
	ZVAL_STRING(option, "min", 1);
	
	PHALCON_INIT_VAR(is_set_min);
	phalcon_call_method_p1(is_set_min, this_ptr, "issetoption", option);
	
	PHALCON_INIT_NVAR(option);
	ZVAL_STRING(option, "max", 1);
	
	PHALCON_INIT_VAR(is_set_max);
	phalcon_call_method_p1(is_set_max, this_ptr, "issetoption", option);
	if (!zend_is_true(is_set_min)) {
		if (!zend_is_true(is_set_max)) {
			PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "A minimum or maximum must be set");
			return;
		}
	}
	
	PHALCON_INIT_VAR(value);
	phalcon_call_method_p1(value, record, "readattribute", field);
	
	/** 
	 * Check if mbstring is available to calculate the correct length
	 */
	if (phalcon_function_exists_ex(SS("mb_strlen") TSRMLS_CC) == SUCCESS) {
		PHALCON_OBS_VAR(length);
		PHALCON_CALL_FUNCTION(&length, "mb_strlen", value);
	} else {
		PHALCON_INIT_VAR(length);
		phalcon_fast_strlen(length, value);
	}
	
	PHALCON_INIT_VAR(invalid_maximum);
	ZVAL_BOOL(invalid_maximum, 0);
	
	PHALCON_INIT_VAR(invalid_minimum);
	ZVAL_BOOL(invalid_minimum, 0);
	
	/** 
	 * Maximum length
	 */
	if (zend_is_true(is_set_max)) {
	
		PHALCON_INIT_NVAR(option);
		ZVAL_STRING(option, "max", 1);
	
		PHALCON_INIT_VAR(maximum);
		phalcon_call_method_p1(maximum, this_ptr, "getoption", option);
	
		is_smaller_function(invalid_maximum, maximum, length TSRMLS_CC);
		if (PHALCON_IS_TRUE(invalid_maximum)) {
	
			/** 
			 * Check if the developer has defined a custom message
			 */
			PHALCON_INIT_NVAR(option);
			ZVAL_STRING(option, "messageMaximum", 1);
	
			PHALCON_INIT_VAR(message);
			phalcon_call_method_p1(message, this_ptr, "getoption", option);
			if (!zend_is_true(message)) {
				PHALCON_INIT_NVAR(message);
				PHALCON_CONCAT_SVSVS(message, "Value of field '", field, "' exceeds the maximum ", maximum, " characters");
			}
	
			PHALCON_INIT_VAR(type);
			ZVAL_STRING(type, "TooLong", 1);

			/*
			 * Is code set
			 */
			PHALCON_INIT_NVAR(option);
			PHALCON_ZVAL_MAYBE_INTERNED_STRING(option, phalcon_interned_code);

			PHALCON_INIT_VAR(is_set_code);
			phalcon_call_method_p1(is_set_code, this_ptr, "issetoption", option);
			PHALCON_INIT_VAR(code);
			if (zend_is_true(is_set_code)) {
				phalcon_call_method_p1(code, this_ptr, "getoption", option);
			} else {
				ZVAL_LONG(code, 0);
			}

			phalcon_call_method_p3_noret(this_ptr, "appendmessage", message, field, type);
			RETURN_MM_FALSE;
		}
	}
	
	/** 
	 * Minimum length
	 */
	if (zend_is_true(is_set_min)) {
	
		PHALCON_INIT_NVAR(option);
		ZVAL_STRING(option, "min", 1);
	
		PHALCON_INIT_VAR(minimum);
		phalcon_call_method_p1(minimum, this_ptr, "getoption", option);
	
		is_smaller_function(invalid_minimum, length, minimum TSRMLS_CC);
		if (PHALCON_IS_TRUE(invalid_minimum)) {<commit_msg>StringLength validator to return code on Max error<commit_after>
/*
  +------------------------------------------------------------------------+
  | Phalcon Framework                                                      |
  +------------------------------------------------------------------------+
  | Copyright (c) 2011-2014 Phalcon Team (http://www.phalconphp.com)       |
  +------------------------------------------------------------------------+
  | This source file is subject to the New BSD License that is bundled     |
  | with this package in the file docs/LICENSE.txt.                        |
  |                                                                        |
  | If you did not receive a copy of the license and are unable to         |
  | obtain it through the world-wide-web, please send an email             |
  | to <EMAIL> so we can send you a copy immediately.       |
  +------------------------------------------------------------------------+
  | Authors: <NAME> <<EMAIL>>                      |
  |          <NAME> <<EMAIL>>                         |
  |          <NAME>                                                    |
  +------------------------------------------------------------------------+
*/

#include "mvc/model/validator/stringlength.h"
#include "mvc/model/validator.h"
#include "mvc/model/validatorinterface.h"
#include "mvc/model/exception.h"

#include "kernel/main.h"
#include "kernel/memory.h"
#include "kernel/fcall.h"
#include "kernel/exception.h"
#include "kernel/string.h"
#include "kernel/operators.h"
#include "kernel/concat.h"

#include "interned-strings.h"

/**
 * Phalcon\Mvc\Model\Validator\StringLength
 *
 * Simply validates specified string length constraints
 *
 *<code>
 *use Phalcon\Mvc\Model\Validator\StringLength as StringLengthValidator;
 *
 *class Subscriptors extends Phalcon\Mvc\Model
 *{
 *
 *	public function validation()
 *	{
 *		$this->validate(new StringLengthValidator(array(
 *			'field' => 'name_last',
 *			'max' => 50,
 *			'min' => 2,
 *			'messageMaximum' => 'We don\'t like really long names',
 *			'messageMinimum' => 'We want more than just their initials'
 *		)));
 *		if ($this->validationHasFailed() == true) {
 *			return false;
 *		}
 *	}
 *
 *}
 *</code>
 *
 */
zend_class_entry *phalcon_mvc_model_validator_stringlength_ce;

PHP_METHOD(Phalcon_Mvc_Model_Validator_StringLength, validate);

static const zend_function_entry phalcon_mvc_model_validator_stringlength_method_entry[] = {
	PHP_ME(Phalcon_Mvc_Model_Validator_StringLength, validate, arginfo_phalcon_mvc_model_validatorinterface_validate, ZEND_ACC_PUBLIC)
	PHP_FE_END
};

/**
 * Phalcon\Mvc\Model\Validator\StringLength initializer
 */
PHALCON_INIT_CLASS(Phalcon_Mvc_Model_Validator_StringLength){

	PHALCON_REGISTER_CLASS_EX(Phalcon\\Mvc\\Model\\Validator, StringLength, mvc_model_validator_stringlength, phalcon_mvc_model_validator_ce, phalcon_mvc_model_validator_stringlength_method_entry, 0);

	zend_class_implements(phalcon_mvc_model_validator_stringlength_ce TSRMLS_CC, 1, phalcon_mvc_model_validatorinterface_ce);

	return SUCCESS;
}

/**
 * Executes the validator
 *
 * @param Phalcon\Mvc\ModelInterface $record
 * @return boolean
 */
PHP_METHOD(Phalcon_Mvc_Model_Validator_StringLength, validate){

	zval *record, *option = NULL, *field, *is_set_min, *is_set_max;
	zval *value, *length = NULL, *invalid_maximum = NULL, *invalid_minimum = NULL;
	zval *maximum, *message = NULL, *type = NULL, *minimum, *is_set_code, *code;

	PHALCON_MM_GROW();

	phalcon_fetch_params(1, 1, 0, &record);
	
	PHALCON_INIT_VAR(option);
	ZVAL_STRING(option, "field", 1);
	
	PHALCON_INIT_VAR(field);
	phalcon_call_method_p1(field, this_ptr, "getoption", option);
	if (Z_TYPE_P(field) != IS_STRING) {
		PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "Field name must be a string");
		return;
	}
	
	/** 
	 * At least one of 'min' or 'max' must be set
	 */
	PHALCON_INIT_NVAR(option);
	ZVAL_STRING(option, "min", 1);
	
	PHALCON_INIT_VAR(is_set_min);
	phalcon_call_method_p1(is_set_min, this_ptr, "issetoption", option);
	
	PHALCON_INIT_NVAR(option);
	ZVAL_STRING(option, "max", 1);
	
	PHALCON_INIT_VAR(is_set_max);
	phalcon_call_method_p1(is_set_max, this_ptr, "issetoption", option);
	if (!zend_is_true(is_set_min)) {
		if (!zend_is_true(is_set_max)) {
			PHALCON_THROW_EXCEPTION_STR(phalcon_mvc_model_exception_ce, "A minimum or maximum must be set");
			return;
		}
	}
	
	PHALCON_INIT_VAR(value);
	phalcon_call_method_p1(value, record, "readattribute", field);
	
	/** 
	 * Check if mbstring is available to calculate the correct length
	 */
	if (phalcon_function_exists_ex(SS("mb_strlen") TSRMLS_CC) == SUCCESS) {
		PHALCON_OBS_VAR(length);
		PHALCON_CALL_FUNCTION(&length, "mb_strlen", value);
	} else {
		PHALCON_INIT_VAR(length);
		phalcon_fast_strlen(length, value);
	}
	
	PHALCON_INIT_VAR(invalid_maximum);
	ZVAL_BOOL(invalid_maximum, 0);
	
	PHALCON_INIT_VAR(invalid_minimum);
	ZVAL_BOOL(invalid_minimum, 0);
	
	/** 
	 * Maximum length
	 */
	if (zend_is_true(is_set_max)) {
	
		PHALCON_INIT_NVAR(option);
		ZVAL_STRING(option, "max", 1);
	
		PHALCON_INIT_VAR(maximum);
		phalcon_call_method_p1(maximum, this_ptr, "getoption", option);
	
		is_smaller_function(invalid_maximum, maximum, length TSRMLS_CC);
		if (PHALCON_IS_TRUE(invalid_maximum)) {
	
			/** 
			 * Check if the developer has defined a custom message
			 */
			PHALCON_INIT_NVAR(option);
			ZVAL_STRING(option, "messageMaximum", 1);
	
			PHALCON_INIT_VAR(message);
			phalcon_call_method_p1(message, this_ptr, "getoption", option);
			if (!zend_is_true(message)) {
				PHALCON_INIT_NVAR(message);
				PHALCON_CONCAT_SVSVS(message, "Value of field '", field, "' exceeds the maximum ", maximum, " characters");
			}
	
			PHALCON_INIT_VAR(type);
			ZVAL_STRING(type, "TooLong", 1);

			/*
			 * Is code set
			 */
			PHALCON_INIT_NVAR(option);
			PHALCON_ZVAL_MAYBE_INTERNED_STRING(option, phalcon_interned_code);

			PHALCON_INIT_VAR(is_set_code);
			phalcon_call_method_p1(is_set_code, this_ptr, "issetoption", option);
			PHALCON_INIT_VAR(code);
			if (zend_is_true(is_set_code)) {
				phalcon_call_method_p1(code, this_ptr, "getoption", option);
			} else {
				ZVAL_LONG(code, 0);
			}

			phalcon_call_method_p4_noret(this_ptr, "appendmessage", message, field, type, code);
			RETURN_MM_FALSE;
		}
	}
	
	/** 
	 * Minimum length
	 */
	if (zend_is_true(is_set_min)) {
	
		PHALCON_INIT_NVAR(option);
		ZVAL_STRING(option, "min", 1);
	
		PHALCON_INIT_VAR(minimum);
		phalcon_call_method_p1(minimum, this_ptr, "getoption", option);
	
		is_smaller_function(invalid_minimum, length, minimum TSRMLS_CC);
		if (PHALCON_IS_TRUE(invalid_minimum)) {
{'fraction_non_alphanumeric': 0.16539938266957765, 'fraction_numerical': 0.00542046224497478, 'mean_word_length': 3.0936825885978427, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6631208', 'n_tokens_mistral': 4964, 'n_tokens_neox': 4553, 'n_words': 810}