Advertisement
Guest User

unzend.com_306

a guest
Jul 28th, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 20.09 KB | None | 0 0
  1. <?php
  2. // Ioncube Decoder Unzend.Com Email unzend@gmail.com
  3. // http://www.unzend.com
  4. /**
  5.  * CModel class file.
  6.  *
  7.  * @author Qiang Xue <qiang.xue@gmail.com>
  8.  * @link http://www.yiiframework.com/
  9.  * @copyright 2008-2013 Yii Software LLC
  10.  * @license http://www.yiiframework.com/license/
  11.  */
  12.  
  13.  
  14. /**
  15.  * CModel is the base class providing the common features needed by data model objects.
  16.  *
  17.  * CModel defines the basic framework for data models that need to be validated.
  18.  *
  19.  * @property CList $validatorList All the validators declared in the model.
  20.  * @property array $validators The validators applicable to the current {@link scenario}.
  21.  * @property array $errors Errors for all attributes or the specified attribute. Empty array is returned if no error.
  22.  * @property array $attributes Attribute values (name=>value).
  23.  * @property string $scenario The scenario that this model is in.
  24.  * @property array $safeAttributeNames Safe attribute names.
  25.  * @property CMapIterator $iterator An iterator for traversing the items in the list.
  26.  *
  27.  * @author Qiang Xue <qiang.xue@gmail.com>
  28.  * @package system.base
  29.  * @since 1.0
  30.  */
  31. abstract class CModel extends CComponent implements IteratorAggregate, ArrayAccess
  32. {
  33.     private $_errors=array();   // attribute name => array of errors
  34.     private $_validators;       // validators
  35.     private $_scenario='';      // scenario
  36.  
  37.     /**
  38.      * Returns the list of attribute names of the model.
  39.      * @return array list of attribute names.
  40.      */
  41.     abstract public function attributeNames();
  42.  
  43.     /**
  44.      * Returns the validation rules for attributes.
  45.      *
  46.      * This method should be overridden to declare validation rules.
  47.      * Each rule is an array with the following structure:
  48.      * <pre>
  49.      * array('attribute list', 'validator name', 'on'=>'scenario name', ...validation parameters...)
  50.      * </pre>
  51.      * where
  52.      * <ul>
  53.      * <li>attribute list: specifies the attributes (separated by commas) to be validated;</li>
  54.      * <li>validator name: specifies the validator to be used. It can be the name of a model class
  55.      *   method, the name of a built-in validator, or a validator class (or its path alias).
  56.      *   A validation method must have the following signature:
  57.      * <pre>
  58.      * // $params refers to validation parameters given in the rule
  59.      * function validatorName($attribute,$params)
  60.      * </pre>
  61.      *   A built-in validator refers to one of the validators declared in {@link CValidator::builtInValidators}.
  62.      *   And a validator class is a class extending {@link CValidator}.</li>
  63.      * <li>on: this specifies the scenarios when the validation rule should be performed.
  64.      *   Separate different scenarios with commas. If this option is not set, the rule
  65.      *   will be applied in any scenario that is not listed in "except". Please see {@link scenario} for more details about this option.</li>
  66.      * <li>except: this specifies the scenarios when the validation rule should not be performed.
  67.      *   Separate different scenarios with commas. Please see {@link scenario} for more details about this option.</li>
  68.      * <li>additional parameters are used to initialize the corresponding validator properties.
  69.      *   Please refer to individal validator class API for possible properties.</li>
  70.      * </ul>
  71.      *
  72.      * The following are some examples:
  73.      * <pre>
  74.      * array(
  75.      *     array('username', 'required'),
  76.      *     array('username', 'length', 'min'=>3, 'max'=>12),
  77.      *     array('password', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'),
  78.      *     array('password', 'authenticate', 'on'=>'login'),
  79.      * );
  80.      * </pre>
  81.      *
  82.      * Note, in order to inherit rules defined in the parent class, a child class needs to
  83.      * merge the parent rules with child rules using functions like array_merge().
  84.      *
  85.      * @return array validation rules to be applied when {@link validate()} is called.
  86.      * @see scenario
  87.      */
  88.     public function rules()
  89.     {
  90.         return array();
  91.     }
  92.  
  93.     /**
  94.      * Returns a list of behaviors that this model should behave as.
  95.      * The return value should be an array of behavior configurations indexed by
  96.      * behavior names. Each behavior configuration can be either a string specifying
  97.      * the behavior class or an array of the following structure:
  98.      * <pre>
  99.      * 'behaviorName'=>array(
  100.      *     'class'=>'path.to.BehaviorClass',
  101.      *     'property1'=>'value1',
  102.      *     'property2'=>'value2',
  103.      * )
  104.      * </pre>
  105.      *
  106.      * Note, the behavior classes must implement {@link IBehavior} or extend from
  107.      * {@link CBehavior}. Behaviors declared in this method will be attached
  108.      * to the model when it is instantiated.
  109.      *
  110.      * For more details about behaviors, see {@link CComponent}.
  111.      * @return array the behavior configurations (behavior name=>behavior configuration)
  112.      */
  113.     public function behaviors()
  114.     {
  115.         return array();
  116.     }
  117.  
  118.     /**
  119.      * Returns the attribute labels.
  120.      * Attribute labels are mainly used in error messages of validation.
  121.      * By default an attribute label is generated using {@link generateAttributeLabel}.
  122.      * This method allows you to explicitly specify attribute labels.
  123.      *
  124.      * Note, in order to inherit labels defined in the parent class, a child class needs to
  125.      * merge the parent labels with child labels using functions like array_merge().
  126.      *
  127.      * @return array attribute labels (name=>label)
  128.      * @see generateAttributeLabel
  129.      */
  130.     public function attributeLabels()
  131.     {
  132.         return array();
  133.     }
  134.  
  135.     /**
  136.      * Performs the validation.
  137.      *
  138.      * This method executes the validation rules as declared in {@link rules}.
  139.      * Only the rules applicable to the current {@link scenario} will be executed.
  140.      * A rule is considered applicable to a scenario if its 'on' option is not set
  141.      * or contains the scenario.
  142.      *
  143.      * Errors found during the validation can be retrieved via {@link getErrors}.
  144.      *
  145.      * @param array $attributes list of attributes that should be validated. Defaults to null,
  146.      * meaning any attribute listed in the applicable validation rules should be
  147.      * validated. If this parameter is given as a list of attributes, only
  148.      * the listed attributes will be validated.
  149.      * @param boolean $clearErrors whether to call {@link clearErrors} before performing validation
  150.      * @return boolean whether the validation is successful without any error.
  151.      * @see beforeValidate
  152.      * @see afterValidate
  153.      */
  154.     public function validate($attributes=null, $clearErrors=true)
  155.     {
  156.         if($clearErrors)
  157.             $this->clearErrors();
  158.         if($this->beforeValidate())
  159.         {
  160.             foreach($this->getValidators() as $validator)
  161.                 $validator->validate($this,$attributes);
  162.             $this->afterValidate();
  163.             return !$this->hasErrors();
  164.         }
  165.         else
  166.             return false;
  167.     }
  168.  
  169.     /**
  170.      * This method is invoked after a model instance is created by new operator.
  171.      * The default implementation raises the {@link onAfterConstruct} event.
  172.      * You may override this method to do postprocessing after model creation.
  173.      * Make sure you call the parent implementation so that the event is raised properly.
  174.      */
  175.     protected function afterConstruct()
  176.     {
  177.         if($this->hasEventHandler('onAfterConstruct'))
  178.             $this->onAfterConstruct(new CEvent($this));
  179.     }
  180.  
  181.     /**
  182.      * This method is invoked before validation starts.
  183.      * The default implementation calls {@link onBeforeValidate} to raise an event.
  184.      * You may override this method to do preliminary checks before validation.
  185.      * Make sure the parent implementation is invoked so that the event can be raised.
  186.      * @return boolean whether validation should be executed. Defaults to true.
  187.      * If false is returned, the validation will stop and the model is considered invalid.
  188.      */
  189.     protected function beforeValidate()
  190.     {
  191.         $event=new CModelEvent($this);
  192.         $this->onBeforeValidate($event);
  193.         return $event->isValid;
  194.     }
  195.  
  196.     /**
  197.      * This method is invoked after validation ends.
  198.      * The default implementation calls {@link onAfterValidate} to raise an event.
  199.      * You may override this method to do postprocessing after validation.
  200.      * Make sure the parent implementation is invoked so that the event can be raised.
  201.      */
  202.     protected function afterValidate()
  203.     {
  204.         $this->onAfterValidate(new CEvent($this));
  205.     }
  206.  
  207.     /**
  208.      * This event is raised after the model instance is created by new operator.
  209.      * @param CEvent $event the event parameter
  210.      */
  211.     public function onAfterConstruct($event)
  212.     {
  213.         $this->raiseEvent('onAfterConstruct',$event);
  214.     }
  215.  
  216.     /**
  217.      * This event is raised before the validation is performed.
  218.      * @param CModelEvent $event the event parameter
  219.      */
  220.     public function onBeforeValidate($event)
  221.     {
  222.         $this->raiseEvent('onBeforeValidate',$event);
  223.     }
  224.  
  225.     /**
  226.      * This event is raised after the validation is performed.
  227.      * @param CEvent $event the event parameter
  228.      */
  229.     public function onAfterValidate($event)
  230.     {
  231.         $this->raiseEvent('onAfterValidate',$event);
  232.     }
  233.  
  234.     /**
  235.      * Returns all the validators declared in the model.
  236.      * This method differs from {@link getValidators} in that the latter
  237.      * would only return the validators applicable to the current {@link scenario}.
  238.      * Also, since this method return a {@link CList} object, you may
  239.      * manipulate it by inserting or removing validators (useful in behaviors).
  240.      * For example, <code>$model->validatorList->add($newValidator)</code>.
  241.      * The change made to the {@link CList} object will persist and reflect
  242.      * in the result of the next call of {@link getValidators}.
  243.      * @return CList all the validators declared in the model.
  244.      * @since 1.1.2
  245.      */
  246.     public function getValidatorList()
  247.     {
  248.         if($this->_validators===null)
  249.             $this->_validators=$this->createValidators();
  250.         return $this->_validators;
  251.     }
  252.  
  253.     /**
  254.      * Returns the validators applicable to the current {@link scenario}.
  255.      * @param string $attribute the name of the attribute whose validators should be returned.
  256.      * If this is null, the validators for ALL attributes in the model will be returned.
  257.      * @return array the validators applicable to the current {@link scenario}.
  258.      */
  259.     public function getValidators($attribute=null)
  260.     {
  261.         if($this->_validators===null)
  262.             $this->_validators=$this->createValidators();
  263.  
  264.         $validators=array();
  265.         $scenario=$this->getScenario();
  266.         foreach($this->_validators as $validator)
  267.         {
  268.             if($validator->applyTo($scenario))
  269.             {
  270.                 if($attribute===null || in_array($attribute,$validator->attributes,true))
  271.                     $validators[]=$validator;
  272.             }
  273.         }
  274.         return $validators;
  275.     }
  276.  
  277.     /**
  278.      * Creates validator objects based on the specification in {@link rules}.
  279.      * This method is mainly used internally.
  280.      * @throws CException if current class has an invalid validation rule
  281.      * @return CList validators built based on {@link rules()}.
  282.      */
  283.     public function createValidators()
  284.     {
  285.         $validators=new CList;
  286.         foreach($this->rules() as $rule)
  287.         {
  288.             if(isset($rule[0],$rule[1]))  // attributes, validator name
  289.                 $validators->add(CValidator::createValidator($rule[1],$this,$rule[0],array_slice($rule,2)));
  290.             else
  291.                 throw new CException(Yii::t('yii','{class} has an invalid validation rule. The rule must specify attributes to be validated and the validator name.',
  292.                     array('{class}'=>get_class($this))));
  293.         }
  294.         return $validators;
  295.     }
  296.  
  297.     /**
  298.      * Returns a value indicating whether the attribute is required.
  299.      * This is determined by checking if the attribute is associated with a
  300.      * {@link CRequiredValidator} validation rule in the current {@link scenario}.
  301.      * @param string $attribute attribute name
  302.      * @return boolean whether the attribute is required
  303.      */
  304.     public function isAttributeRequired($attribute)
  305.     {
  306.         foreach($this->getValidators($attribute) as $validator)
  307.         {
  308.             if($validator instanceof CRequiredValidator)
  309.                 return true;
  310.         }
  311.         return false;
  312.     }
  313.  
  314.     /**
  315.      * Returns a value indicating whether the attribute is safe for massive assignments.
  316.      * @param string $attribute attribute name
  317.      * @return boolean whether the attribute is safe for massive assignments
  318.      * @since 1.1
  319.      */
  320.     public function isAttributeSafe($attribute)
  321.     {
  322.         $attributes=$this->getSafeAttributeNames();
  323.         return in_array($attribute,$attributes);
  324.     }
  325.  
  326.     /**
  327.      * Returns the text label for the specified attribute.
  328.      * @param string $attribute the attribute name
  329.      * @return string the attribute label
  330.      * @see generateAttributeLabel
  331.      * @see attributeLabels
  332.      */
  333.     public function getAttributeLabel($attribute)
  334.     {
  335.         $labels=$this->attributeLabels();
  336.         if(isset($labels[$attribute]))
  337.             return $labels[$attribute];
  338.         else
  339.             return $this->generateAttributeLabel($attribute);
  340.     }
  341.  
  342.     /**
  343.      * Returns a value indicating whether there is any validation error.
  344.      * @param string $attribute attribute name. Use null to check all attributes.
  345.      * @return boolean whether there is any error.
  346.      */
  347.     public function hasErrors($attribute=null)
  348.     {
  349.         if($attribute===null)
  350.             return $this->_errors!==array();
  351.         else
  352.             return isset($this->_errors[$attribute]);
  353.     }
  354.  
  355.     /**
  356.      * Returns the errors for all attribute or a single attribute.
  357.      * @param string $attribute attribute name. Use null to retrieve errors for all attributes.
  358.      * @return array errors for all attributes or the specified attribute. Empty array is returned if no error.
  359.      */
  360.     public function getErrors($attribute=null)
  361.     {
  362.         if($attribute===null)
  363.             return $this->_errors;
  364.         else
  365.             return isset($this->_errors[$attribute]) ? $this->_errors[$attribute] : array();
  366.     }
  367.  
  368.     /**
  369.      * Returns the first error of the specified attribute.
  370.      * @param string $attribute attribute name.
  371.      * @return string the error message. Null is returned if no error.
  372.      */
  373.     public function getError($attribute)
  374.     {
  375.         return isset($this->_errors[$attribute]) ? reset($this->_errors[$attribute]) : null;
  376.     }
  377.  
  378.     /**
  379.      * Adds a new error to the specified attribute.
  380.      * @param string $attribute attribute name
  381.      * @param string $error new error message
  382.      */
  383.     public function addError($attribute,$error)
  384.     {
  385.         $this->_errors[$attribute][]=$error;
  386.     }
  387.  
  388.     /**
  389.      * Adds a list of errors.
  390.      * @param array $errors a list of errors. The array keys must be attribute names.
  391.      * The array values should be error messages. If an attribute has multiple errors,
  392.      * these errors must be given in terms of an array.
  393.      * You may use the result of {@link getErrors} as the value for this parameter.
  394.      */
  395.     public function addErrors($errors)
  396.     {
  397.         foreach($errors as $attribute=>$error)
  398.         {
  399.             if(is_array($error))
  400.             {
  401.                 foreach($error as $e)
  402.                     $this->addError($attribute, $e);
  403.             }
  404.             else
  405.                 $this->addError($attribute, $error);
  406.         }
  407.     }
  408.  
  409.     /**
  410.      * Removes errors for all attributes or a single attribute.
  411.      * @param string $attribute attribute name. Use null to remove errors for all attribute.
  412.      */
  413.     public function clearErrors($attribute=null)
  414.     {
  415.         if($attribute===null)
  416.             $this->_errors=array();
  417.         else
  418.             unset($this->_errors[$attribute]);
  419.     }
  420.  
  421.     /**
  422.      * Generates a user friendly attribute label.
  423.      * This is done by replacing underscores or dashes with blanks and
  424.      * changing the first letter of each word to upper case.
  425.      * For example, 'department_name' or 'DepartmentName' becomes 'Department Name'.
  426.      * @param string $name the column name
  427.      * @return string the attribute label
  428.      */
  429.     public function generateAttributeLabel($name)
  430.     {
  431.         return ucwords(trim(strtolower(str_replace(array('-','_','.'),' ',preg_replace('/(?<![A-Z])[A-Z]/', ' \0', $name)))));
  432.     }
  433.  
  434.     /**
  435.      * Returns all attribute values.
  436.      * @param array $names list of attributes whose value needs to be returned.
  437.      * Defaults to null, meaning all attributes as listed in {@link attributeNames} will be returned.
  438.      * If it is an array, only the attributes in the array will be returned.
  439.      * @return array attribute values (name=>value).
  440.      */
  441.     public function getAttributes($names=null)
  442.     {
  443.         $values=array();
  444.         foreach($this->attributeNames() as $name)
  445.             $values[$name]=$this->$name;
  446.  
  447.         if(is_array($names))
  448.         {
  449.             $values2=array();
  450.             foreach($names as $name)
  451.                 $values2[$name]=isset($values[$name]) ? $values[$name] : null;
  452.             return $values2;
  453.         }
  454.         else
  455.             return $values;
  456.     }
  457.  
  458.     /**
  459.      * Sets the attribute values in a massive way.
  460.      * @param array $values attribute values (name=>value) to be set.
  461.      * @param boolean $safeOnly whether the assignments should only be done to the safe attributes.
  462.      * A safe attribute is one that is associated with a validation rule in the current {@link scenario}.
  463.      * @see getSafeAttributeNames
  464.      * @see attributeNames
  465.      */
  466.     public function setAttributes($values,$safeOnly=true)
  467.     {
  468.         if(!is_array($values))
  469.             return;
  470.         $attributes=array_flip($safeOnly ? $this->getSafeAttributeNames() : $this->attributeNames());
  471.         foreach($values as $name=>$value)
  472.         {
  473.             if(isset($attributes[$name]))
  474.                 $this->$name=$value;
  475.             elseif($safeOnly)
  476.                 $this->onUnsafeAttribute($name,$value);
  477.         }
  478.     }
  479.  
  480.     /**
  481.      * Sets the attributes to be null.
  482.      * @param array $names list of attributes to be set null. If this parameter is not given,
  483.      * all attributes as specified by {@link attributeNames} will have their values unset.
  484.      * @since 1.1.3
  485.      */
  486.     public function unsetAttributes($names=null)
  487.     {
  488.         if($names===null)
  489.             $names=$this->attributeNames();
  490.         foreach($names as $name)
  491.             $this->$name=null;
  492.     }
  493.  
  494.     /**
  495.      * This method is invoked when an unsafe attribute is being massively assigned.
  496.      * The default implementation will log a warning message if YII_DEBUG is on.
  497.      * It does nothing otherwise.
  498.      * @param string $name the unsafe attribute name
  499.      * @param mixed $value the attribute value
  500.      * @since 1.1.1
  501.      */
  502.     public function onUnsafeAttribute($name,$value)
  503.     {
  504.         if(YII_DEBUG)
  505.             Yii::log(Yii::t('yii','Failed to set unsafe attribute "{attribute}" of "{class}".',array('{attribute}'=>$name, '{class}'=>get_class($this))),CLogger::LEVEL_WARNING);
  506.     }
  507.  
  508.     /**
  509.      * Returns the scenario that this model is used in.
  510.      *
  511.      * Scenario affects how validation is performed and which attributes can
  512.      * be massively assigned.
  513.      *
  514.      * A validation rule will be performed when calling {@link validate()}
  515.      * if its 'except' value does not contain current scenario value while
  516.      * 'on' option is not set or contains the current scenario value.
  517.      *
  518.      * And an attribute can be massively assigned if it is associated with
  519.      * a validation rule for the current scenario. Note that an exception is
  520.      * the {@link CUnsafeValidator unsafe} validator which marks the associated
  521.      * attributes as unsafe and not allowed to be massively assigned.
  522.      *
  523.      * @return string the scenario that this model is in.
  524.      */
  525.     public function getScenario()
  526.     {
  527.         return $this->_scenario;
  528.     }
  529.  
  530.     /**
  531.      * Sets the scenario for the model.
  532.      * @param string $value the scenario that this model is in.
  533.      * @see getScenario
  534.      */
  535.     public function setScenario($value)
  536.     {
  537.         $this->_scenario=$value;
  538.     }
  539.  
  540.     /**
  541.      * Returns the attribute names that are safe to be massively assigned.
  542.      * A safe attribute is one that is associated with a validation rule in the current {@link scenario}.
  543.      * @return array safe attribute names
  544.      */
  545.     public function getSafeAttributeNames()
  546.     {
  547.         $attributes=array();
  548.         $unsafe=array();
  549.         foreach($this->getValidators() as $validator)
  550.         {
  551.             if(!$validator->safe)
  552.             {
  553.                 foreach($validator->attributes as $name)
  554.                     $unsafe[]=$name;
  555.             }
  556.             else
  557.             {
  558.                 foreach($validator->attributes as $name)
  559.                     $attributes[$name]=true;
  560.             }
  561.         }
  562.  
  563.         foreach($unsafe as $name)
  564.             unset($attributes[$name]);
  565.         return array_keys($attributes);
  566.     }
  567.  
  568.     /**
  569.      * Returns an iterator for traversing the attributes in the model.
  570.      * This method is required by the interface IteratorAggregate.
  571.      * @return CMapIterator an iterator for traversing the items in the list.
  572.      */
  573.     public function getIterator()
  574.     {
  575.         $attributes=$this->getAttributes();
  576.         return new CMapIterator($attributes);
  577.     }
  578.  
  579.     /**
  580.      * Returns whether there is an element at the specified offset.
  581.      * This method is required by the interface ArrayAccess.
  582.      * @param mixed $offset the offset to check on
  583.      * @return boolean
  584.      */
  585.     public function offsetExists($offset)
  586.     {
  587.         return property_exists($this,$offset);
  588.     }
  589.  
  590.     /**
  591.      * Returns the element at the specified offset.
  592.      * This method is required by the interface ArrayAccess.
  593.      * @param integer $offset the offset to retrieve element.
  594.      * @return mixed the element at the offset, null if no element is found at the offset
  595.      */
  596.     public function offsetGet($offset)
  597.     {
  598.         return $this->$offset;
  599.     }
  600.  
  601.     /**
  602.      * Sets the element at the specified offset.
  603.      * This method is required by the interface ArrayAccess.
  604.      * @param integer $offset the offset to set element
  605.      * @param mixed $item the element value
  606.      */
  607.     public function offsetSet($offset,$item)
  608.     {
  609.         $this->$offset=$item;
  610.     }
  611.  
  612.     /**
  613.      * Unsets the element at the specified offset.
  614.      * This method is required by the interface ArrayAccess.
  615.      * @param mixed $offset the offset to unset element
  616.      */
  617.     public function offsetUnset($offset)
  618.     {
  619.         unset($this->$offset);
  620.     }
  621. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement