Here's a simple settings router. the createOrUpdate method lives in the model, and by default all models will return true on save or false if save went wrong.
175 lines
5.4 KiB
PHP
175 lines
5.4 KiB
PHP
<?php
|
|
namespace Sudzy;
|
|
|
|
abstract class ValidModel extends \Model
|
|
{
|
|
protected $_validator = null; // Reference to Sudzy validator object
|
|
protected $_validations = array(); // Array of validations
|
|
protected $_validationErrors = array(); // Array of error messages
|
|
protected $_validationOptions = array(
|
|
'indexedErrors' => false, // If True getValidationErrors will return an array with the index
|
|
// being the field name and the value the error. If multiple errors
|
|
// are triggered for a field only the first will be kept.
|
|
'throw' => self::ON_SAVE // One of self::ON_SET|ON_SAVE|NEVER.
|
|
// + ON_SET throws immediately when field is set()
|
|
// + ON_SAVE throws on save()
|
|
// + NEVER means an exception is never thrown; check for ->getValidaionErrors()
|
|
);
|
|
|
|
const ON_SET = 'set';
|
|
const ON_SAVE = 'save';
|
|
const NEVER = null;
|
|
|
|
public function __construct($validatorInstance = null) {
|
|
$this->_validator = $validatorInstance;
|
|
}
|
|
|
|
public function setValidationOptions($options)
|
|
{
|
|
$this->_validationOptions = array_merge($this->_validationOptions, $options);
|
|
}
|
|
|
|
public function addValidation($field, $validation, $message) {
|
|
if (!isset($this->_validations[$field])) {
|
|
$this->_validations[$field] = array();
|
|
}
|
|
$this->_validations[$field][] = array(
|
|
'validation' => $validation,
|
|
'message' => $message
|
|
);
|
|
}
|
|
|
|
public function addValidations($field, $validators) {
|
|
foreach ($validators as $validation => $message) {
|
|
$this->addValidation($field, $validation, $message);
|
|
}
|
|
}
|
|
|
|
// /**
|
|
// * Checks, without throwing exceptions, model fields with validations
|
|
// *
|
|
// * @return bool If false, running $this->doValidationError() will respond appropriately
|
|
// */
|
|
// public function validate()
|
|
// {
|
|
// $fields = array_keys($this->_validations);
|
|
// $success = true;
|
|
// foreach ($fields as $f) {
|
|
// $success = $success && $this->validateField($f, $this->$f);
|
|
// }
|
|
// return $success;
|
|
// }
|
|
|
|
/**
|
|
* @return bool Will set a message if returning false
|
|
**/
|
|
public function validateField($field, $value)
|
|
{
|
|
$this->setupValidationEngine();
|
|
|
|
if (!isset($this->_validations[$field])) {
|
|
return true; // No validations, return true by default
|
|
}
|
|
|
|
$success = true;
|
|
foreach ($this->_validations[$field] as $v) {
|
|
$checks = explode(' ', $v['validation']);
|
|
foreach ($checks as $check) {
|
|
$params = explode('|', $check);
|
|
$check = array_shift($params);
|
|
|
|
if ($this->_validator->executeOne($check, $value, $params)) {
|
|
$success = $success && true;
|
|
} else {
|
|
$this->addValidationError($v['message'], $field);
|
|
$success = false;
|
|
}
|
|
}
|
|
}
|
|
return $success;
|
|
}
|
|
|
|
public function getValidationErrors()
|
|
{
|
|
return $this->_validationErrors;
|
|
}
|
|
|
|
public function resetValidationErrors()
|
|
{
|
|
$this->_validationErrors = array();
|
|
}
|
|
|
|
///////////////////
|
|
// Overloaded methods
|
|
|
|
/**
|
|
* Overload __set to call validateAndSet
|
|
*/
|
|
public function __set($name, $value)
|
|
{
|
|
$this->validateAndSet($name, $value);
|
|
}
|
|
|
|
/**
|
|
* Overload save; checks if errors exist before saving
|
|
*/
|
|
public function save()
|
|
{
|
|
if ($this->isNew()) { //Fields populated by create() or hydrate() don't pass through set()
|
|
foreach( array_keys($this->_validations) as $field) {
|
|
$this->validateField($field, $this->$field);
|
|
}
|
|
}
|
|
|
|
$errs = $this->getValidationErrors();
|
|
if (!empty($errs))
|
|
$this->doValidationError(self::ON_SAVE);
|
|
|
|
parent::save();
|
|
}
|
|
|
|
/**
|
|
* Overload set; to call validateAndSet
|
|
* // TODO: handle multiple sets if $name is a field=>val array
|
|
*/
|
|
public function set($name, $value = null)
|
|
{
|
|
$this->validateAndSet($name, $value);
|
|
}
|
|
|
|
|
|
////////////////////
|
|
// Protected methods
|
|
protected function doValidationError($context)
|
|
{
|
|
if ($context == $this->_validationOptions['throw'])
|
|
throw new \Sudzy\ValidationException($this->_validationErrors);
|
|
}
|
|
|
|
protected function addValidationError($msg, $field = null)
|
|
{
|
|
if ($this->_validationOptions['indexedErrors'] && $field !== null) {
|
|
// Only keep the first error found on a field
|
|
if (!isset($this->_validationErrors[$field])) {
|
|
$this->_validationErrors[$field] = $msg;
|
|
}
|
|
} else {
|
|
$this->_validationErrors[] = $msg;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Overload set; to call validateAndSet
|
|
*/
|
|
protected function validateAndSet($name, $value)
|
|
{
|
|
if (!$this->validateField($name, $value)) $this->doValidationError(self::ON_SET);
|
|
parent::set($name, $value);
|
|
}
|
|
|
|
protected function setupValidationEngine()
|
|
{
|
|
if (null == $this->_validator) $this->_validator = new \Sudzy\Engine(); // Is lazy setup worth it?
|
|
}
|
|
}
|