BasicRelationsModel.php
Current file: /home/magister/git/yii-example/example/protected/models/BasicRelationsModel.php
Legend: executed not executed dead code

  Coverage
  Classes Functions / Methods Lines
Total
0.00% 0 / 1
28.57% 6 / 21 CRAP
56.71% 131 / 231
BasicRelationsModel
0.00% 0 / 1
28.57% 6 / 21 656.43
56.71% 131 / 231
 pivots()
0.00% 0 / 1 2
0.00% 0 / 1
 idPresent ($check_for_id)
100.00% 1 / 1 3
100.00% 10 / 10
 refresh ()
0.00% 0 / 1 2
0.00% 0 / 2
 magicRelationEligibleForDelete ($relation_name, $relation_object)
0.00% 0 / 1 6
0.00% 0 / 7
 magicRelationUpdated ($relation_name, $relation_object)
0.00% 0 / 1 4.03
88.24% 15 / 17
 setPost_Attributes($POST)
0.00% 0 / 1 87.84
48.57% 34 / 70
 magicRelationHasOneRead ($relation_name, $relation_column_name)
100.00% 1 / 1 2
100.00% 3 / 3
 magicRelationHasOneWrite ($relation_name, $relation_column_name, $new_value)
0.00% 0 / 1 7.61
52.94% 9 / 17
 magicRelationHasOneValidate ($relation_name, $relation_column_name, $magic_attribute_name, $params)
100.00% 1 / 1 3
100.00% 7 / 7
 magicRelationHasManyRead ($relation_name)
0.00% 0 / 1 20
0.00% 0 / 13
 magicRelationHasManyWrite ($new_values)
0.00% 0 / 1 2
0.00% 0 / 1
 magicRelationHasManyValidate ($relation_name)
0.00% 0 / 1 2
0.00% 0 / 1
 magicRelationManyManyAdd ()
0.00% 0 / 1 2
0.00% 0 / 1
 magicRelationManyManyDel ()
0.00% 0 / 1 2
0.00% 0 / 1
 magicRelationManyManySet ()
0.00% 0 / 1 2
0.00% 0 / 1
 getAllErrors ()
0.00% 0 / 1 110
0.00% 0 / 21
 beforeSave ()
0.00% 0 / 1 5.67
33.33% 2 / 6
 afterSave ()
0.00% 0 / 1 9
95.45% 21 / 22
 cascade ($cascade_setting)
100.00% 1 / 1 1
100.00% 2 / 2
 beforeDelete ()
100.00% 1 / 1 8
100.00% 27 / 27
 afterDelete ()
100.00% 1 / 1 1
100.00% 1 / 1


       1                 : <?php                                                                                                                    
       2                 :                                                                                                                          
       3                 : /**                                                                                                                      
       4                 :  * The BasicRelationsModel class implements some helper methods that will be                                             
       5                 :  * needed by several of the children classes.                                                                            
       6                 :  */                                                                                                                      
       7                 : class BasicRelationsModel extends CActiveRecord {                                                                        
       8                 :     // Used to cache the computed values of the magic attributes.                                                        
       9                 :     protected $_magic_attributes=array();                                                                                
      10                 :                                                                                                                          
      11                 :     // A list of AR's that are eligible for deletion. Updated with the                                                   
      12                 :     // magicRelation*Write methods. It is used when calling save() to delete                                             
      13                 :     // unused related AR records.                                                                                        
      14                 :     protected $_eligible_for_delete=array();                                                                             
      15                 :                                                                                                                          
      16                 :     // Track a list of relations that were updated with the                                                              
      17                 :     // magicRelation*Write methods. Used to cascade the save() operations only                                           
      18                 :     // to objects that have actually changed.                                                                            
      19                 :     protected $_relation_updated=array();                                                                                
      20                 :                                                                                                                          
      21                 :     // Issued in the afterSave() behavior. Must contain arrays with the following format:                                
      22                 :     // array (                                                                                                           
      23                 :     //   'conditions' => mixed,                                                                                          
      24                 :     //   'params' => array (),                                                                                           
      25                 :     // ),                                                                                                                
      26                 :     // conditions - the conditions that will be put in the WHERE part.                                                   
      27                 :     // params - the parameters to be bound to the query.                                                                 
      28                 :     protected $_delete_commands=array ();                                                                                
      29                 :                                                                                                                          
      30                 :     // Issued in the afterSave() behavior. Must contain arrays with the following format:                                
      31                 :     // array (                                                                                                           
      32                 :     //   'table' => string,                                                                                              
      33                 :     //   'columns' => array (),                                                                                          
      34                 :     // ),                                                                                                                
      35                 :     // table - The table that new rows will be inserted into.                                                            
      36                 :     // columns - The column data (name=>value) to be inserted into the table.                                            
      37                 :     protected $_insert_commands=array ();                                                                                
      38                 :                                                                                                                          
      39                 :     // Emulate cascade on delete if the DB does not support it.                                                          
      40                 :     protected $cascade_on_delete=false;                                                                                  
      41                 :                                                                                                                          
      42                 :     /**                                                                                                                  
      43                 :      * Maps the many to many relations pivot table to their respective AR                                                
      44                 :      * class. This attempts to reduce the number of delete's and inserts when                                            
      45                 :      * updateing many to many mappings. If not defined, the default behaviour                                            
      46                 :      * is to delete all and re-insert.                                                                                   
      47                 :      */                                                                                                                  
      48                 :     public function pivots() {                                                                                           
      49               0 :         return array();                                                                                                  
      50                 :     }                                                                                                                    
      51                 :                                                                                                                          
      52                 :     /**                                                                                                                  
      53                 :      * Runs a SQL statement to determine if the AR id specified exists in the                                            
      54                 :      * table for this class. Lighter than findByPk cause a new object is not                                             
      55                 :      * instantiated.                                                                                                     
      56                 :      * TODO: Implement support for composite primary keys.                                                               
      57                 :      */                                                                                                                  
      58                 :     public function idPresent ($check_for_id) {                                                                          
      59               3 :         if (empty ($check_for_id))                                                                                       
      60               3 :             return false;                                                                                                
      61               3 :         $primary_key=$this->tableSchema->primaryKey;                                                                     
      62               3 :         if (Yii::app()->db->createCommand()                                                                              
      63               3 :             ->select($primary_key)                                                                                       
      64               3 :             ->from($this->tableName())                                                                                   
      65               3 :             ->where($primary_key.'=:id', array (':id'=>$check_for_id))                                                   
      66               3 :             ->queryRow() )                                                                                               
      67               3 :             return true;                                                                                                 
      68               1 :         return false;                                                                                                    
      69                 :     }                                                                                                                    
      70                 :                                                                                                                          
      71                 :     /**                                                                                                                  
      72                 :      * Overload the refresh() method so the magic attributes cache can be                                                
      73                 :      * cleared.                                                                                                          
      74                 :      */                                                                                                                  
      75                 :     public function refresh () {                                                                                         
      76               0 :         $this->_magic_attributes=array();                                                                                
      77               0 :         return parent::refresh();                                                                                        
      78                 :     }                                                                                                                    
      79                 :                                                                                                                          
      80                 :     /************************************************************************/                                           
      81                 :                                                                                                                          
      82                 :     /**                                                                                                                  
      83                 :      * Marks a object a eligible for delete. Checks to see if the object is                                              
      84                 :      * already in the list of objects to be updated and removes it.                                                      
      85                 :      */                                                                                                                  
      86                 :     public function magicRelationEligibleForDelete ($relation_name, $relation_object) {                                  
      87               0 :         $relations=$this->relations();                                                                                   
      88               0 :         $relation_primary_key=$relation_object->tableSchema->primaryKey;                                                 
      89                 :         // TODO: add support for composite primary keys.                                                                 
      90               0 :         $pk=$relation_object->$relation_primary_key;                                                                     
      91               0 :         if (isset ($this->_relation_updated[$relation_name][$pk]))                                                       
      92               0 :             unset ($this->_relation_updated[$relation_name][$pk]);                                                       
      93               0 :         $this->_eligible_for_delete[]=$relation_object;                                                                  
      94               0 :     }                                                                                                                    
      95                 :                                                                                                                          
      96                 :     /**                                                                                                                  
      97                 :      * Mark a object as changed, and trigger a save() when the main object is                                            
      98                 :      * saved(). (Cascade Save). If the object's attributes are empty it marks                                            
      99                 :      * it as eligible for delete.                                                                                        
     100                 :      */                                                                                                                  
     101                 :     public function magicRelationUpdated ($relation_name, $relation_object) {                                            
     102                 :         // first check to see if the object's attributes are empty.                                                      
     103               4 :         $relations=$this->relations();                                                                                   
     104               4 :         $relation_settings=$relations[$relation_name];                                                                   
     105               4 :         $relation_primary_key=$relation_object->tableSchema->primaryKey;                                                 
     106               4 :         $attributes=$relation_object->attributes;                                                                        
     107                 :         // TODO: add support for composite primary keys.                                                                 
     108               4 :         unset ($attributes[$relation_primary_key]);                                                                      
     109                 :         // TODO: add support for composite foreign keys.                                                                 
     110               4 :         unset ($attributes[$relation_settings[2]]);                                                                      
     111               4 :         if (empty ($attributes)) {                                                                                       
     112                 :             // eligible for delete.                                                                                      
     113               0 :             $this->magicRelationEligibleForDelete ($relation_name, $relation_object);                                    
     114               0 :             return;                                                                                                      
     115                 :         }                                                                                                                
     116                 :         // tag for update.                                                                                               
     117               4 :         if (!isset ($this->_relation_updated[$relation_name]))                                                           
     118               4 :             $this->_relation_updated[$relation_name]=array ('new' => array());                                           
     119               4 :         if ($relation_object->isNewRecord) {                                                                             
     120               3 :             $this->_relation_updated[$relation_name]['new'][]=$relation_object;                                          
     121               3 :         } else {                                                                                                         
     122               1 :             $pk=$relation_object->$relation_primary_key;                                                                 
     123               1 :             $this->_relation_updated[$relation_name][$pk]=$relation_object;                                              
     124                 :         }                                                                                                                
     125               4 :     }                                                                                                                    
     126                 :                                                                                                                          
     127                 :     /**                                                                                                                  
     128                 :      * A magic setter used for processing the $_POST variable for this class                                             
     129                 :      * and all the related classes.                                                                                      
     130                 :      */                                                                                                                  
     131                 :     public function setPost_Attributes($POST) {                                                                          
     132               1 :         if (!isset ($POST[get_class ($this)]))                                                                           
     133               1 :             return;                                                                                                      
     134               1 :         $this->attributes=$POST[get_class ($this)];                                                                      
     135               1 :         foreach ($this->relations() as $relation_name => $relation_settings) {                                           
     136               1 :             $relation_type=$relation_settings[0];                                                                        
     137               1 :             $relation_class=$relation_settings[1];                                                                       
     138               1 :             $relation_fk=$relation_settings[2];                                                                          
     139                 :             switch ($relation_type) {                                                                                    
     140                 :                                                                                                                          
     141               1 :                 case 'CHasOneRelation':                                                                                  
     142               1 :                     if ($this->isNewRecord || empty ($this->$relation_name)) {                                           
     143               1 :                         if (!isset ($POST[$relation_class]))                                                             
     144               1 :                             continue;                                                                                    
     145                 :                         // Has One is new or not attached.                                                               
     146               1 :                         $this->$relation_name=new $relation_class;                                                       
     147               1 :                     } elseif (!isset ($POST[$relation_class])) {                                                         
     148               0 :                         $this->$relation_name->unsetAttributes();                                                        
     149               0 :                         $this->magicRelationUpdated ($relation_name, $this->$relation_name);                             
     150               0 :                         $this->$relation_name=null;                                                                      
     151               0 :                         continue;                                                                                        
     152                 :                     }                                                                                                    
     153               1 :                     $this->$relation_name->attributes=$POST[$relation_class];                                            
     154               1 :                     $this->magicRelationUpdated ($relation_name, $this->$relation_name);                                 
     155               1 :                     break;                                                                                               
     156                 :                                                                                                                          
     157               1 :                 case 'CHasManyRelation':                                                                                 
     158               1 :                     if ($this->isNewRecord || empty ($this->$relation_name)) {                                           
     159                 :                         // Has Many is new or none are attached.                                                         
     160               1 :                         $model_list=array ();                                                                            
     161               1 :                         foreach ($POST[$relation_class] as $post_attributes) {                                           
     162               1 :                             $model=new $relation_class;                                                                  
     163               1 :                             $model->attributes=$post_attributes;                                                         
     164               1 :                             $this->magicRelationUpdated ($relation_name, $model);                                        
     165               1 :                             $model_list[]=$model;                                                                        
     166               1 :                         }                                                                                                
     167               1 :                         $this->$relation_name=$model_list;                                                               
     168               1 :                     } else {                                                                                             
     169               0 :                         $model_list=array ();                                                                            
     170               0 :                         $delete_models=$this->$relation_name;                                                            
     171                 :                         // Has Many is present and needs to be merged with the incomming data.                           
     172               0 :                         $relation_pk=$relation_class::model()->tableSchema->primaryKey;                                  
     173               0 :                         if (!empty ($POST[$relation_class])) {                                                           
     174               0 :                             $post_attribute_list=$POST[$relation_class];                                                 
     175               0 :                             foreach ($delete_models as $delete_models_key => $model) {                                   
     176               0 :                                 foreach ($post_attribute_list as $post_attributes_key => $post_attributes) {             
     177                 :                                     // Check to see if any of the incoming entries match the PK of the current entry.    
     178               0 :                                     if ($post_attributes[$relation_pk] === $model->$relation_pk) {                       
     179                 :                                         // Match found.                                                                  
     180               0 :                                         $model->attributes=$post_attributes;                                             
     181               0 :                                         $this->magicRelationUpdated ($relation_name, $model);                            
     182               0 :                                         $model_list[]=$model;                                                            
     183                 :                                         // Pop the model off the delete list and off the incoming entries                
     184               0 :                                         unset ($delete_models[$delete_models_key]);                                      
     185               0 :                                         unset ($post_attribute_list[$post_attributes_key]);                              
     186               0 :                                         continue 2;                                                                      
     187                 :                                     }                                                                                    
     188               0 :                                 }                                                                                        
     189               0 :                             }                                                                                            
     190                 :                             // Matching complete.                                                                        
     191                 :                             // Create remaining new models.                                                              
     192               0 :                             if (!empty ($post_attribute_list)) {                                                         
     193               0 :                                 foreach ($post_attribute_list as $post_attributes) {                                     
     194               0 :                                     $model=new $relation_class;                                                          
     195               0 :                                     $model->attributes=$post_attributes;                                                 
     196               0 :                                     $this->magicRelationUpdated ($relation_name, $model);                                
     197               0 :                                     $model_list[]=$model;                                                                
     198               0 :                                 }                                                                                        
     199               0 :                             }                                                                                            
     200               0 :                             $this->$relation_name=$model_list;                                                           
     201                 : //                        } else {                                                                                       
     202                 : //                            $delete_models=$this->$relation_name;                                                      
     203                 : //                            $this->$relation_name=array ();                                                            
     204               0 :                         }                                                                                                
     205                 :                         // Delete left over models.                                                                      
     206               0 :                         if (!empty ($delete_models)) {                                                                   
     207               0 :                             foreach ($delete_models as $model) {                                                         
     208               0 :                                 $this->magicRelationEligibleForDelete ($relation_name, $model);                          
     209               0 :                             }                                                                                            
     210               0 :                         }                                                                                                
     211                 :                     }                                                                                                    
     212               1 :                     break;                                                                                               
     213                 :                                                                                                                          
     214               1 :                 case 'CManyManyRelation':                                                                                
     215               1 :                     $pivots=$this->pivots();                                                                             
     216               1 :                     if (isset ($pivots[$relation_name])) {                                                               
     217                 :                         // Use supplied pivot model                                                                      
     218               0 :                     } else {                                                                                             
     219                 :                         // Fall back to blanket delete/insert.                                                           
     220                 :                     }                                                                                                    
     221                 : /*                                                                                                                       
     222                 :                     $primary_key=$this->tableSchema->primaryKey;                                                         
     223                 :                     $pivot_table=$this->metaData->relations[$relation_name]->getJunctionTableName();                     
     224                 :                     $foreign_keys=$this->metaData->relations[$relation_name]->getJunctionForeignKeys();                  
     225                 :                     $primary_key_column=array_shift ($foreign_keys);                                                     
     226                 :                     $conditions="$primary_key_column = :id";                                                             
     227                 :                     $params=array (':id' => $this->$primary_key);                                                        
     228                 :                     $rows_affected=Yii::app()->db->createCommand()->delete ($pivot_table, $conditions, $params);         
     229                 : */                                                                                                                       
     230               1 :                     break;                                                                                               
     231                 :             }                                                                                                            
     232               1 :         }                                                                                                                
     233               1 :     }                                                                                                                    
     234                 :                                                                                                                          
     235                 :                                                                                                                          
     236                 :     /************************************************************************/                                           
     237                 :                                                                                                                          
     238                 :     /**                                                                                                                  
     239                 :      * Reader for a related colum with a Has One relationship.                                                           
     240                 :      */                                                                                                                  
     241                 :     public function magicRelationHasOneRead ($relation_name, $relation_column_name) {                                    
     242               1 :         if (empty ($this->$relation_name))                                                                               
     243               1 :             return null;                                                                                                 
     244               1 :         return $this->$relation_name->$relation_column_name;                                                             
     245                 :     }                                                                                                                    
     246                 :                                                                                                                          
     247                 :     /**                                                                                                                  
     248                 :      * Writer for a related column with a Has One relationship. If the object                                            
     249                 :      * does not exist a new one is created.                                                                              
     250                 :      */                                                                                                                  
     251                 :     public function magicRelationHasOneWrite ($relation_name, $relation_column_name, $new_value) {                       
     252               3 :         if (empty ($new_value)) {                                                                                        
     253               0 :             if (!empty ($this->$relation_name)) {                                                                        
     254                 :                 // Empty the column out.                                                                                 
     255               0 :                 $this->$relation_name->$relation_column_name=null;                                                       
     256               0 :                 $this->magicRelationUpdated ($relation_name, $this->$relation_name);                                     
     257               0 :             }                                                                                                            
     258               0 :             return;                                                                                                      
     259                 :         }                                                                                                                
     260               3 :         if (empty ($this->$relation_name)) {                                                                             
     261                 :             // New Record                                                                                                
     262               2 :             $relations=$this->relations();                                                                               
     263               2 :             $this->$relation_name=new $relations[$relation_name][1];                                                     
     264               2 :             if (!$this->isNewRecord) {                                                                                   
     265               0 :                 $primary_key=$this->tableSchema->primaryKey;                                                             
     266               0 :                 $this->$relation_name->$relations[$relation_name][2]=$this->$primary_key;                                
     267               0 :             }                                                                                                            
     268               2 :         }                                                                                                                
     269               3 :         $this->$relation_name->$relation_column_name=$new_value;                                                         
     270               3 :         $this->magicRelationUpdated ($relation_name, $this->$relation_name);                                             
     271               3 :     }                                                                                                                    
     272                 :                                                                                                                          
     273                 :     /**                                                                                                                  
     274                 :      * Validation check for a magic attribute that is emulating a related                                                
     275                 :      * column with a Has One relationship. Errors are bubbled up into the                                                
     276                 :      * magic attribute's name.                                                                                           
     277                 :      */                                                                                                                  
     278                 :     public function magicRelationHasOneValidate ($relation_name, $relation_column_name, $magic_attribute_name, $params) {
     279               5 :         if (empty ($this->$relation_name))                                                                               
     280               5 :             return;                                                                                                      
     281               3 :         if ($this->$relation_name->validate ($relation_column_name))                                                     
     282               3 :             return;                                                                                                      
     283               1 :         $errors=array ($magic_attribute_name => $this->$relation_name->getErrors ($relation_column_name));               
     284               1 :         $this->addErrors ($errors);                                                                                      
     285               1 :     }                                                                                                                    
     286                 :                                                                                                                          
     287                 :     /**                                                                                                                  
     288                 :      * Reads all the related object into an array of arrays containing the                                               
     289                 :      * attributes from each AR. The foreign key attribute is removed.                                                    
     290                 :      */                                                                                                                  
     291                 :     public function magicRelationHasManyRead ($relation_name) {                                                          
     292               0 :         if (empty ($this->$relation_name))                                                                               
     293               0 :             return array ();                                                                                             
     294               0 :         if (isset ($this->_magic_attributes[$relation_name]))                                                            
     295               0 :             return $this->_magic_attributes[$relation_name];                                                             
     296               0 :         $relations=$this->relations();                                                                                   
     297               0 :         $relation_settings=$relations[$relation_name];                                                                   
     298               0 :         $all_related_attributes=array ();                                                                                
     299               0 :         foreach ($this->$relation_name as $related_object) {                                                             
     300               0 :             $related_object_attributes=$related_object->attributes;                                                      
     301               0 :             unset ($related_object_attributes[$relation_settings[2]]);                                                   
     302                 : // probably need to change this to be more friendly with tabular input.                                                  
     303               0 :             $all_related_attributes[]=$related_object_attributes;                                                        
     304               0 :         }                                                                                                                
     305               0 :         return $this->_magic_attributes[$relation_name]=$all_related_attributes;                                         
     306                 :     }                                                                                                                    
     307                 :                                                                                                                          
     308                 :     /**                                                                                                                  
     309                 :      * Writes the related attributes to the AR's, creating new ones and                                                  
     310                 :      * marking unused ones as eligible for delete. The format must be a array                                            
     311                 :      * of arrays containing the attributes for the target model. The foreign                                             
     312                 :      * key attribute will be ignored if provided.                                                                        
     313                 :      */                                                                                                                  
     314                 :     public function magicRelationHasManyWrite ($new_values) {                                                            
     315               0 :     }                                                                                                                    
     316                 :                                                                                                                          
     317                 :     /**                                                                                                                  
     318                 :      * Cascades the validation to all the AR's that were marked as updated.                                              
     319                 :      * The resulting errors are bubbled up, the format of the errors is not                                              
     320                 :      * currently decided (they need to be compatiable with the CActiveForm                                               
     321                 :      * widget).                                                                                                          
     322                 :      */                                                                                                                  
     323                 :     public function magicRelationHasManyValidate ($relation_name) {                                                      
     324               0 :     }                                                                                                                    
     325                 :                                                                                                                          
     326                 :     /**                                                                                                                  
     327                 :      * Creates a new pivot table object for the many to many relation. The                                               
     328                 :      * resulting AR is added to the update list and will be saved when save()                                            
     329                 :      * is called on this AR.                                                                                             
     330                 :      */                                                                                                                  
     331                 :     public function magicRelationManyManyAdd () {                                                                        
     332               0 :     }                                                                                                                    
     333                 :                                                                                                                          
     334                 :     /**                                                                                                                  
     335                 :      * Finds the pivot table entry for the specified many to many relation and                                           
     336                 :      * marks it as eligible for delete.                                                                                  
     337                 :      */                                                                                                                  
     338                 :     public function magicRelationManyManyDel () {                                                                        
     339               0 :     }                                                                                                                    
     340                 :                                                                                                                          
     341                 :     /**                                                                                                                  
     342                 :      * Takes an array of PK's for the related model and attempts to determine                                            
     343                 :      * which records need to be add, removed or left alone.                                                              
     344                 :      */                                                                                                                  
     345                 :     public function magicRelationManyManySet () {                                                                        
     346               0 :     }                                                                                                                    
     347                 :                                                                                                                          
     348                 :     /************************************************************************/                                           
     349                 :                                                                                                                          
     350                 :     public function getAllErrors () {                                                                                    
     351               0 :         $errors=$this->getErrors();                                                                                      
     352               0 :         $relations=$this->relations();                                                                                   
     353               0 :         if (empty ($relations))                                                                                          
     354               0 :             return $errors;                                                                                              
     355               0 :         foreach ($relations as $relation_name => $relation_settings) {                                                   
     356               0 :             if (empty ($this->$relation_name))                                                                           
     357               0 :                 continue;                                                                                                
     358               0 :             if (is_object ($this->$relation_name)) {                                                                     
     359               0 :                 if (!empty ($this->$relation_name->errors))                                                              
     360               0 :                     $errors[$relation_name]=$this->$relation_name->getErrors ();                                         
     361               0 :             } elseif (is_array ($this->$relation_name)) {                                                                
     362               0 :                 $errors[$relation_name]=array ();                                                                        
     363               0 :                 foreach ($this->$relation_name as $related_key => $related_model) {                                      
     364               0 :                     if (!empty ($related_model->errors))                                                                 
     365               0 :                         $errors[$relation_name][$related_key]=$related_model->getErrors ();                              
     366               0 :                 }                                                                                                        
     367               0 :                 if (empty ($errors[$relation_name]))                                                                     
     368               0 :                     unset ($errors[$relation_name]);                                                                     
     369               0 :             }                                                                                                            
     370               0 :         }                                                                                                                
     371               0 :         return $errors;                                                                                                  
     372                 :     }                                                                                                                    
     373                 :                                                                                                                          
     374                 :     /************************************************************************/                                           
     375                 :                                                                                                                          
     376                 :     /**                                                                                                                  
     377                 :      * Start a DB transaction and cleans up all the objects that are eligible                                            
     378                 :      * for delete.                                                                                                       
     379                 :      */                                                                                                                  
     380                 :     public function beforeSave () {                                                                                      
     381                 :         // Start a transaction                                                                                           
     382                 :         // Issue the delete() on all eligible objects.                                                                   
     383               2 :         if (!empty ($this->_eligible_for_delete)) {                                                                      
     384               0 :             foreach ($this->_eligible_for_delete as $related_object) {                                                   
     385               0 :                 $related_object->delete();                                                                               
     386               0 :             }                                                                                                            
     387               0 :         }                                                                                                                
     388               2 :         return parent::beforeSave();                                                                                     
     389                 :     }                                                                                                                    
     390                 :                                                                                                                          
     391                 :     /**                                                                                                                  
     392                 :      * Cascaed the save() to all related objects that changed and commit the                                             
     393                 :      * transaction.                                                                                                      
     394                 :      */                                                                                                                  
     395                 :     protected function afterSave () {                                                                                    
     396                 :         // issue the save() on all changed objects.                                                                      
     397               2 :         if (!empty ($this->_relation_updated)) {                                                                         
     398               2 :             $primary_key=$this->primaryKey();                                                                            
     399               2 :             if (empty ($primary_key))                                                                                    
     400               2 :                 $primary_key=$this->tableSchema->primaryKey;                                                             
     401               2 :             $relations=$this->relations();                                                                               
     402               2 :             foreach ($this->_relation_updated as $relation_name => $related_objects) {                                   
     403               2 :                 if (empty ($related_objects))                                                                            
     404               2 :                     continue;                                                                                            
     405               2 :                 $relation_settings=$relations[$relation_name];                                                           
     406                 :                 // objects are seperated into 2 groups, new object and objects that                                      
     407                 :                 // already existed in the db, but were changed.                                                          
     408               2 :                 foreach ($related_objects as $pk_or_new => $r_object) {                                                  
     409               2 :                     if ($pk_or_new === 'new') {                                                                          
     410               2 :                         foreach ($r_object as $new_object) {                                                             
     411               2 :                             if (empty($new_object->$relation_settings[2]))                                               
     412               2 :                                 $new_object->$relation_settings[2]=$this->$primary_key;                                  
     413               2 :                             $new_object->save();                                                                         
     414               2 :                         }                                                                                                
     415               2 :                         continue;                                                                                        
     416                 :                     }                                                                                                    
     417               0 :                     $r_object->save();                                                                                   
     418               2 :                 }                                                                                                        
     419               2 :             }                                                                                                            
     420               2 :         }                                                                                                                
     421                 :         // end transaction/commit.                                                                                       
     422               2 :         return parent::afterSave();                                                                                      
     423                 :     }                                                                                                                    
     424                 :                                                                                                                          
     425                 :     public function cascade ($cascade_setting) {                                                                         
     426               1 :         $this->cascade_on_delete=$cascade_setting;                                                                       
     427               1 :     }                                                                                                                    
     428                 :                                                                                                                          
     429                 :     /**                                                                                                                  
     430                 :      * Emulates the cascade delete if the cascade variable is set to true.                                               
     431                 :      */                                                                                                                  
     432                 :     protected function beforeDelete () {                                                                                 
     433               1 :         if (!$this->cascade_on_delete)                                                                                   
     434               1 :             return parent::beforeDelete();                                                                               
     435                 :         // start transation.                                                                                             
     436                 :         // Itterate through the relations, issue deletes for Has One, Has                                                
     437                 :         // Manies, and the pivot table for the Many Manies.                                                              
     438               1 :         foreach ($this->relations () as $relation_name => $relation_settings) {                                          
     439               1 :             if (empty ($this->$relation_name))                                                                           
     440               1 :                 continue;                                                                                                
     441               1 :             switch ($relation_settings[0]) {                                                                             
     442               1 :                 case 'CHasOneRelation':                                                                                  
     443               1 :                     $this->$relation_name->delete();                                                                     
     444               1 :                     break;                                                                                               
     445               1 :                 case 'CHasManyRelation':                                                                                 
     446               1 :                     foreach ($this->$relation_name as $relation_entry)                                                   
     447               1 :                         $relation_entry->delete();                                                                       
     448               1 :                     break;                                                                                               
     449               1 :                 case 'CManyManyRelation':                                                                                
     450               1 :                     $primary_key=$this->tableSchema->primaryKey;                                                         
     451               1 :                     $pivot_table=$this->metaData->relations[$relation_name]->getJunctionTableName();                     
     452               1 :                     $foreign_keys=$this->metaData->relations[$relation_name]->getJunctionForeignKeys();                  
     453               1 :                     $primary_key_column=array_shift ($foreign_keys);                                                     
     454               1 :                     $conditions="$primary_key_column = :id";                                                             
     455               1 :                     $params=array (':id' => $this->$primary_key);                                                        
     456               1 :                     $rows_affected=Yii::app()->db->createCommand()->delete ($pivot_table, $conditions, $params);         
     457               1 :                     break;                                                                                               
     458               1 :                 default:                                                                                                 
     459               1 :                     continue;                                                                                            
     460               1 :             }                                                                                                            
     461               1 :         }                                                                                                                
     462               1 :         return parent::beforeDelete();                                                                                   
     463                 :     }                                                                                                                    
     464                 :                                                                                                                          
     465                 :     public function afterDelete () {                                                                                     
     466                 :         // end transaction                                                                                               
     467               1 :         return parent::afterDelete();                                                                                    
     468                 :     }                                                                                                                    
     469                 :                                                                                                                          
     470                 : }                                                                                                                        

Generated by PHP_CodeCoverage 1.1.2 using PHP 5.4.4-14+deb7u2 and PHPUnit 3.6.10 at Tue Aug 13 16:58:12 CDT 2013.