/**
  * Similar to ensure_is_obj(), this method makes sure $base_class_obj_or_id
  * is a value of the this model's primary key. If it's an EE_Base_Class child,
  * returns it ID.
  * @param EE_Base_Class|int|string $base_class_obj_or_id
  * @return int|string depending on the type of this model object's ID
  * @throws EE_Error
  */
 public function ensure_is_ID($base_class_obj_or_id)
 {
     $className = $this->_get_class_name();
     if ($base_class_obj_or_id instanceof $className) {
         /** @var $base_class_obj_or_id EE_Base_Class */
         $id = $base_class_obj_or_id->ID();
     } elseif (is_int($base_class_obj_or_id)) {
         //assume it's an ID
         $id = $base_class_obj_or_id;
     } elseif (is_string($base_class_obj_or_id)) {
         //assume its a string representation of the object
         $id = $base_class_obj_or_id;
     } else {
         throw new EE_Error(sprintf(__("'%s' is neither an object of type %s, nor an ID! Its full value is '%s'", 'event_espresso'), $base_class_obj_or_id, $this->_get_class_name(), print_r($base_class_obj_or_id, true)));
     }
     return $id;
 }
 /**
  * update_cache_after_object_save
  * Allows a cached item to have it's cache ID (within the array of cached items) reset using the new ID it has obtained after being saved to the db
  *
  * @param string                $relationName       - the type of object that is cached
  * @param \EE_Base_Class $newly_saved_object - the newly saved object to be re-cached
  * @param string                $current_cache_id   - the ID that was used when originally caching the object
  * @return boolean TRUE on success, FALSE on fail
  */
 public function update_cache_after_object_save($relationName, EE_Base_Class $newly_saved_object, $current_cache_id = '')
 {
     // verify that incoming object is of the correct type
     $obj_class = 'EE_' . $relationName;
     if ($newly_saved_object instanceof $obj_class) {
         /* @type EE_Base_Class $newly_saved_object*/
         // now get the type of relation
         $relationship_to_model = $this->get_model()->related_settings_for($relationName);
         // if this is a 1:1 relationship
         if ($relationship_to_model instanceof EE_Belongs_To_Relation) {
             // then just replace the cached object with the newly saved object
             $this->_model_relations[$relationName] = $newly_saved_object;
             return TRUE;
             // or if it's some kind of sordid feral polyamorous relationship...
         } elseif (is_array($this->_model_relations[$relationName]) && isset($this->_model_relations[$relationName][$current_cache_id])) {
             // then remove the current cached item
             unset($this->_model_relations[$relationName][$current_cache_id]);
             // and cache the newly saved object using it's new ID
             $this->_model_relations[$relationName][$newly_saved_object->ID()] = $newly_saved_object;
             return TRUE;
         }
     }
     return FALSE;
 }
 /**
  * Basically this method gets called to verify if the incoming object needs to be manipulated somewhat because it is a revision save.  If so, then we change things before sending back.  We also do verifications when this IS NOT an revision because we always need to make sure that the autosave/revision has parent recorded (which is sometime delayed if the object is created/saved first by the autosave)
  *
  * @param  EE_Base_Class $this_model_obj
  * @param  EE_Base_Class $other_obj
  * @param  boolean       $remove_relation Indicates whether we're doing a remove_relation or add_relation.
  * @return EE_Base_Class. ($other_obj);
  */
 protected function _check_for_revision($this_obj, $other_obj, $remove_relation = FALSE)
 {
     $pk_on_related_model = $this->get_other_model()->get_primary_key_field()->get_name();
     //now we need to determine if we're in a WP revision save cause if we are we need to do some special handling
     if ($this_obj->post_type() == 'revision') {
         //first if $other_obj fk = this_obj pk then we know that this is a pk object, let's make sure there is a matching set for the autosave if there is then we save over it, if there isn't then we need to create a new one.
         $parent_evt_id = $this_obj->parent();
         /*var_dump($parent_evt_id);
         		var_dump($this_obj);
         		var_dump($other_obj);/**/
         if (!empty($parent_evt_id) && $parent_evt_id == $other_obj->get($this->_primary_cpt_field)) {
             //let's do query on this objects model to see if the incoming pk value on the obj matches any parents in this objects table.
             $has_parent_obj = $this->get_other_model()->get_one(array(array($this->_parent_pk_relation_field => $other_obj->ID(), $this->_primary_cpt_field => $this_obj->ID())));
             if ($has_parent_obj) {
                 //this makes sure the update on the current obj happens to the revision's row NOT the parent row.
                 $other_obj->set($this->_parent_pk_relation_field, $other_obj->ID());
                 $other_obj->set($pk_on_related_model, $has_parent_obj->ID());
                 $other_obj->set($this->_primary_cpt_field, $this_obj->ID());
                 if (!$remove_relation) {
                     $other_obj->save();
                     return array($other_obj);
                 } elseif ($remove_relation && !$this->_blocking_delete) {
                     $other_obj->delete();
                     $other_obj->set($this->_parent_pk_relation_field, NULL, true);
                     return array($other_obj);
                 }
             } else {
                 $other_obj->set($this->_parent_pk_relation_field, $other_obj->ID());
                 $other_obj->set($this->_primary_cpt_field, $this_obj->ID());
                 $other_obj->set($pk_on_related_model, NULL, true);
                 //ensure we create a new row for the autosave with parent id the same as the incoming ID.
                 $other_obj->save();
                 //make sure we insert.
                 return array($other_obj);
             }
         }
         //var_dump('what makes it here');
         //var_dump($other_obj);
         //the next possible condition is that the incoming other_model obj has a NULL pk which means it just gets saved (which in turn creates it)
         //the last possible condition on a revision is that the incoming other_model object has a fk that == $this_obj pk which means we just return the $other obj and let it save as normal so we see the return at the bottom of this method.
     } else {
         //we only need to do the below IF this is not a remove relation
         if (!$remove_relation) {
             //okay this is is a normal update/save/remove so, let's make sure the other object is not a revision of the current object.
             //the other object will likely NOT have the correct fk on it (which is the primary_cpt_field_mame) so we must retrieve from the db to get that first.
             $existing_other_obj = $this->get_other_model()->get_one_by_ID($other_obj->ID());
             $potential_revision_id = is_object($existing_other_obj) ? $existing_other_obj->get($this->_primary_cpt_field) : NULL;
             if ($parent_this_obj_id = wp_is_post_revision($potential_revision_id)) {
                 //yes the OTHER object is linked to the revision of the parent, not the parent itself. That means we need to make the other_object an attachment of this_obj and then duplicate other_obj for the revision.
                 $other_obj->set($this->_primary_cpt_field, $this_obj->ID());
                 $other_obj->save();
                 //now create a new other_obj and fill with details from existing object
                 $new_obj = $other_obj;
                 $new_obj->set($this->_primary_cpt_field, $potential_revision_id);
                 $new_obj->set($this->_parent_pk_relation_field, $other_obj->ID());
                 $new_obj->set($pk_on_related_model, NULL);
                 $new_obj->save();
                 return array($new_obj);
             }
         }
     }
     return $other_obj;
 }
 /**
  * Shorthand for setting the OBJ_ID and OBJ_type. Slightly handier than using
  * _add_relation_to because you don't have to specify what type of model you're
  * associating it with
  * @param EE_Base_Class $object
  * @param boolean $save
  * @return boolean if $save=true, NULL is $save=false
  */
 function set_object($object, $save = TRUE)
 {
     if ($object instanceof EE_Base_Class) {
         $this->set_OBJ_type($object->get_model()->get_this_model_name());
         $this->set_OBJ_ID($object->ID());
     } else {
         $this->set_OBJ_type(NULL);
         $this->set_OBJ_ID(NULL);
     }
     if ($save) {
         return $this->save();
     } else {
         return NULL;
     }
 }
 /**
  * this just returns a model_object_id for incoming item that could be an object or id.
  * @param  EE_Base_Class|int $model_object_or_id model object or the primary key of this model
  * @throws EE_Error
  * @return int
  */
 protected function _get_model_object_id($model_object_or_id)
 {
     if ($model_object_or_id instanceof EE_Base_Class) {
         $model_object_id = $model_object_or_id->ID();
     } else {
         $model_object_id = $model_object_or_id;
     }
     if (!$model_object_id) {
         throw new EE_Error(sprintf(__("Sorry, we cant get the related %s model objects to %s model object before it has an ID. You can solve that by just saving it before trying to get its related model objects", "event_espresso"), $this->get_other_model()->get_this_model_name(), $this->get_this_model()->get_this_model_name()));
     }
     return $model_object_id;
 }
 /**
  * This is used to set the model object on the $_model_objects property
  *
  * @since 1.0.0
  *
  * @param  EE_Base_Class $obj
  * @return  void
  */
 protected function _set_model_object(EE_Base_Class $obj)
 {
     $this->_model_objects[$obj->ID()] = $obj;
 }
 private static function _compare_objects(EE_Base_Class $obj_a, EE_Base_Class $obj_b)
 {
     return $obj_a->ID() - $obj_b->ID();
 }
 /**
  *
  * @param string $log_type !see the acceptable values of LOG_type in EEM__Change_Log::__construct
  * @param mixed $message array|string of the message you want to record
  * @param EE_Base_Class $related_model_obj
  * @return EE_Change_Log
  */
 public function log($log_type, $message, $related_model_obj)
 {
     if ($related_model_obj instanceof EE_Base_Class) {
         $obj_id = $related_model_obj->ID();
         $obj_type = $related_model_obj->get_model()->get_this_model_name();
     } else {
         $obj_id = NULL;
         $obj_type = NULL;
     }
     $log = EE_Change_Log::new_instance(array('LOG_type' => $log_type, 'LOG_message' => $message, 'OBJ_ID' => $obj_id, 'OBJ_type' => $obj_type));
     $log->save();
     return $log;
 }
 /**
  * Callback for AHEE__EE_Base_Class__delete_before hook so we can ensure any person relationships for an item being deleted
  * are also handled.
  *
  * @param EE_Base_Class $model_object
  */
 public function delete_people_relations_on_related_delete(EE_Base_Class $model_object)
 {
     if ($model_object instanceof EE_Event) {
         $remove_where = array('OBJ_ID' => $model_object->ID(), 'OBJ_type' => 'Event');
         EEM_Person_Post::instance()->delete(array($remove_where));
     }
 }