PDA

View Full Version : استفاده از ولیدیتورهای دستی



tux-world
جمعه 06 دی 1392, 11:25 صبح
سلام. در مورد ولیدیتورهایی که خود Yii داره و کادر خالی باشه خطا میده در صورتی که ما نخواییم به این شکل باشه باید یه کلاسی که از Cvalidator مشتق میشه استفاده کرد یا فانکشن جدید بنویسیم ؟ نحوه کارش چطوریه وقتی فیلدی خالی هستش یا اشتباهه؟ عملیاتی مانند safe و یا max و یا حتی خود required رو چطور میشه با اونها تطبیق داد؟

MMSHFE
جمعه 06 دی 1392, 11:35 صبح
فرض کنید میخواین یک Validator بگذارین که اجازه نمیده کاربران رمز ساده انتخاب کنن. برای این کار دو روش وجود داره که توی پستهای بعدی جداگانه توضیح میدم.

MMSHFE
جمعه 06 دی 1392, 11:41 صبح
روش ساده - اضافه کردن یک rule داخل مدل:
ابتدا دو تا ثابت توی کلاس مدلتون اضافه کنید:


const WEAK = 0;
const STRONG = 1;

حالا با کد زیر در قسمت rules میتونید Validator خودتون به اسم passwordStrength رو به فیلد password فرم اضافه کنید:


/**
* @return array validation rules for model attributes.
*/
public function rules()
{
return array(
// ...
array('password', 'passwordStrength', 'strength'=>self::STRONG),
// ...
);
}

این هم متد passwordStrength که نقش Validator رو داره:


/**
* check if the user password is strong enough
* check the password against the pattern requested
* by the strength parameter
* This is the 'passwordStrength' validator as declared in rules().
*/
public function passwordStrength($attribute,$params)
{
if ($params['strength'] === self::WEAK)
$pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/';
elseif ($params['strength'] === self::STRONG)
$pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/';

if(!preg_match($pattern, $this->$attribute))
$this->addError($attribute, 'your password is not strong enough!');
}

همونطور که میبینید، برحسب اینکه درجه امنیت رو توی rules چی تعیین کنید، اگه الگوی رمز واردشده با pattern$ نخونه، یک خطا به فیلد فرم اضافه میشه و نمیگذاره فرم ثبت بشه. البته به شرطی که قبل از صدا زدن ;()model->save$ با بررسی ()model->hasErrors$ چک کنید که خطایی وجود نداشته باشه.

tux-world
جمعه 06 دی 1392, 11:49 صبح
ممنون دوست عزیز. انگار خوب منظورم رو نتونستم برسونم. ببینید وقتی فیلدی ولیدیشن میشه و خطایی رخ میده هسته خود فریم ورک دست به کار میشه میگه مثلا خالیه. ما اگه بخاییم این کار رو هسته انجام نده چیکار کنیم؟ مثلا بنویسیم نام کاربری وارد نشده. مثل همون سیستم شاپرک که لینک داده بودید

MMSHFE
جمعه 06 دی 1392, 11:51 صبح
روش کامل - توسعه کلاس CValidator فریمورک:
این روش از اون جهت بهتره که میتونید به راحتی کلاس Validator خودتون رو در پروژه های دیگه هم بکار ببرین. برای اینکار، ابتدا توی پوشه protected یک پوشه به اسم MyValidators بسازین. بعد داخلش یک فایل به اسم passwordStrength.php ایجاد کنید. حالا داخلش ابتدا کدهای زیر رو بنویسید:


class passwordStrength extends CValidator
{

public $strength;

private $weak_pattern = '/^(?=.*[a-zA-Z0-9]).{5,}$/';
private $strong_pattern = '/^(?=.*\d(?=.*\d))(?=.*[a-zA-Z](?=.*[a-zA-Z])).{5,}$/';

/**
* Validates the attribute of the object.
* If there is any error, the error message is added to the object.
* @param CModel $object the object being validated
* @param string $attribute the attribute being validated
*/
protected function validateAttribute($object,$attribute)
{
// check the strength parameter used in the validation rule of our model
if ($this->strength == 'weak')
$pattern = $this->weak_pattern;
elseif ($this->strength == 'strong')
$pattern = $this->strong_pattern;

// extract the attribute value from it's model object
$value=$object->$attribute;
if(!preg_match($pattern, $value))
{
$this->addError($object,$attribute,'your password is too weak!');
}
}
}

حالا توی متد rules توی مدلتون باید اینطوری بنویسید:


/**
* @return array validation rules for model attributes.
*/
public function rules()
{
return array(
// ...
array('password', 'passwordStrength', 'strength'=>'strong'),
// ...
);
}

نکته: علت اینکه گفته شد یک پوشه به اسم MyValidators بسازین و فایل رو به اسم کلاس و با پسوند php. داخلش ذخیره کنید اینه که از قابلیت LazyLoading موجود در Yii استفاده بشه وگرنه میشد هرجایی بگذارین و توی فایل تنظیمات main.php تو قسمت import فایلهاش رو فراخوانی کنید.
نکته بعدی: اگه میخواین Validation سمت کلاینت رو هم بازنویسی کنید، باید یک متد دیگه به کلاستون اضافه کنید:


/**
* Returns the JavaScript needed for performing client-side validation.
* @param CModel $object the data object being validated
* @param string $attribute the name of the attribute to be validated.
* @return string the client-side validation script.
* @see CActiveForm::enableClientValidation
*/
public function clientValidateAttribute($object,$attribute)
{

// check the strength parameter used in the validation rule of our model
if ($this->strength == 'weak')
$pattern = $this->weak_pattern;
elseif ($this->strength == 'strong')
$pattern = $this->strong_pattern;

$condition="!value.match({$pattern})";

return 'if(' . $condition . ') { messages.push(' . CJSON::encode('your password is too weak!') . '); }';
}

MMSHFE
جمعه 06 دی 1392, 11:56 صبح
خوب شما باید تو متد rules (داخل مدل) از Validatorهای خود Yii استفاده نکنید و Validator خودتون رو سر راه فیلد موردنظر بگذارین.