menu

CakePHP Custom Rules

CakePHP Custom Rules

چهارشنبه 17 شهریور 1395

یکی از وظایف اصلی Model توی CakePHP، تعیین ویژگی ها و خصیصه های مربوط به هر Column مربوط به اون Table در دیتابیس هست و به همین دلیل، توی Cake میشه برای هر Column یه قانون یا Rule تعریف کرد. مثلا میشه گفت که این Column خالی نباشه، توی Table یکتا باشه، فقط عدد باشه، فقط متن باشه، حداکثر و حداقل چند کاراکتر باشه، عدد و متن قاطی باشه یا چیزای دیگه

توی یکی از پروژه هام، نیاز بود که یه قانون خاص بنویسم

یه Column بود که قرار بود از کاربر، کد ملی بگیره و میخواستم که یه قانون توی Model خودم بنویسم، که بیاد و بررسی کنه که آیا این کد ملی معتبر هست یا نه

همونطور که میدونید، کد ملی یه ساختار معین داره که میتونید اینجا ببینید

اول از همه، توی Table مورد نظر خودتون فرض کنید یه Column دارید به اسم codemelli

میریم سراغ کدهای مورد نیاز

Model ما قبل از هر تغییراتی اینجوری بوده:

<?php
	class MyModel extends AppModel{
		
	}
?>

حالا کافیه یه property برای validate کردن Column خودمون ایجاد کنیم

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				
			)
		);
	}
?>

حالا بیاید Rules خودمون را براش وارد کنیم. اسمش را میزاریم codemellivalidate

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				'rule' => 'codemellivalidate',
				'message' => 'کدملی نامعتبر است. لطفا یک کدملی معتبر وارد کنید'
			)
		);
	}
?>

قسمت مربوط به Validate تموم شد. الان موقع اون هست که خود ما یه تابع بنویسیم به اسم codemellivalidate. ورودی این تابع، همون مقداری هست که کاربر وارد میکنه و قراره توی دیتابیس ذخیره بشه. اگه خروجی تابع return true بود، مقدار ذخیره میشه و اگه return false بود، ارور میده و ذخیره نمیشه

بیاید تابع را بنویسیم

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				'rule' => 'codemellivalidate',
				'message' => 'کدملی نامعتبر است. لطفا یک کدملی معتبر وارد کنید'
			)
		);
		public function codemellivalidate($check){			
			
		}
	}
?>

این هم از تابع ما. دقت کنید که آرگومان ورودی تابع که من اسمش را گذاشتم $check، همون مقداری هست که قراره توی دیتابیس ذخیره بشه. البته به صورت آرایه. 

یه آرایه که key اون، اسم Column هست که ما میخواهیم ذخیره کنیم. که توی این نمونه از اونجایی که اسم Column ما codemelli هست، پس به عبارت دقیق تر اونی که ما میخواهیم ذخیره کنیم و روش پردازش انجام بدیم و بررسیش کنیم

$check['codemelli']

هست. اولین کار ما این هست که بیایم ببینیم اصلا این مقداری که میخواهیم ذخیره کنیم توی دیتابیس، ده رقمی هست یا نه

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				'rule' => 'codemellivalidate',
				'message' => 'کدملی نامعتبر است. لطفا یک کدملی معتبر وارد کنید'
			)
		);
		public function codemellivalidate($check){
			//$check['codemelli']	is the variable that we want to check	
			$data = $check['codemelli'];
			if(strlen($data) == 10){
				
			}else{
				return false;
			}
		}
	}
?>

حالا که مطمئن شدیم ده رقمی هست، موقع اون هست که طبق اینجا عمل کنیم.

برای این کار اول متغیر خودمون را split میکنیم و به صورت آرایه درش میاریم. بعد هم هر کدوم از خونه های آرایه را، بستگی به موقعیت مکانیش، در عدد مناسب ضرب میکنیم و در نهایت همشون را باهم جمع میکنیم

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				'rule' => 'codemellivalidate',
				'message' => 'کدملی نامعتبر است. لطفا یک کدملی معتبر وارد کنید'
			)
		);
		public function codemellivalidate($check){
			//$check['codemelli']	is the variable that we want to check	
			$data = $check['codemelli'];
			if(strlen($data) == 10){
				$code = str_split($data);
				$total = $code[0] * 10 + $code[1] * 9 + $code[2] * 8 + $code[3] * 7 + $code[4] * 6 + $code[5] * 5 + $code[6] * 4 + $code[7] * 3 + $code[8] * 2;
				
			}else{
				return false;
			}
		}
	}
?>

حالا کافیه باقی مانده ی اون را بر عدد 11 به دست بیاریم

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				'rule' => 'codemellivalidate',
				'message' => 'کدملی نامعتبر است. لطفا یک کدملی معتبر وارد کنید'
			)
		);
		public function codemellivalidate($check){
			//$check['codemelli']	is the variable that we want to check	
			$data = $check['codemelli'];
			if(strlen($data) == 10){
				$code = str_split($data);
				$total = $code[0] * 10 + $code[1] * 9 + $code[2] * 8 + $code[3] * 7 + $code[4] * 6 + $code[5] * 5 + $code[6] * 4 + $code[7] * 3 + $code[8] * 2;
				$division = (int)($total / 11);
				$remainder = $total - ($division * 11);
				
			}else{
				return false;
			}
		}
	}
?>

و در نهایت باید شرط نهایی را اعمال کنیم. اگر باقی مانده کمتر از 2 بود، باقی مانده باید با آخرین عدد سمت راست کدملی یکسان باشد و اگر باقی مانده بیشتر از 2 بود، آخرین عدد سمت راست کدملی باید با حاصل تفریق 11 منهای باقی مانده برابر باشد

<?php
	class MyModel extends AppModel{
		public $validate= array(			
			'codemelli' => array(
				'rule' => 'codemellivalidate',
				'message' => 'کدملی نامعتبر است. لطفا یک کدملی معتبر وارد کنید'
			)
		);
		public function codemellivalidate($check){
			//$check['codemelli']	is the variable that we want to check	
			$data = $check['codemelli'];
			if(strlen($data) == 10){
				$code = str_split($data);
				$total = $code[0] * 10 + $code[1] * 9 + $code[2] * 8 + $code[3] * 7 + $code[4] * 6 + $code[5] * 5 + $code[6] * 4 + $code[7] * 3 + $code[8] * 2;
				$division = (int)($total / 11);
				$remainder = $total - ($division * 11);
				if($remainder < 2){
					if($code[9] == $remainder){
						return true;
					}else{
						return false;
					}
				}else{
					if((11 - $remainder) == $code[9]){
						return true;
					}else{
						return false;
					}
				}
			}else{
				return false;
			}
		}
	}
?>

به همین سادگی

البته اگه میخواستم خود CakePHP Custom Rules را توضیح بدم، کار خیلی ساده ای بود!

کافیه اسم تابع ما با اسم rules ما برابر باشه و توی اون تابع، اگه return true بود مقدار ذخیره میشه و اگه return false بود ذخیره نمیشه!

ولی سعی کردم که با مثال و تجربه ای باشه که داشتم، و خود مثال از خود مسئله کمی سخت تر بود!

منتشر شده در:

    ارسال نظر
    خوانا نیست؟تعویض کد