/**
  * Add one object into objects and its associated db to watch
  * @param epObject $o 
  * @param epDbObject $db
  * @return bool
  */
 public function addObject($o, $db)
 {
     // validate input
     if (!$o instanceof epObject) {
         return false;
     }
     // has object been kept?
     $uid = $o->epGetUId();
     if (!isset($this->objects[$uid])) {
         // check if object is in transaction. start if not
         if (!$o->epInTransaction()) {
             $o->epStartTransaction();
         }
         // add the associated db to watch
         $this->addDb($db);
         // add if not
         $this->objects[$uid] = $o;
     }
     return true;
 }
 /**
  * Checks if the variables of this object matches all the 
  * non-null variables in another object
  * 
  * <b>
  * Note: for now we only match primitive fields. For relational 
  * fields, things can get complicated as we may be dealing with 
  * very "deep" comparisons and recursions.
  * </b>
  * 
  * @param epObject $o the example object
  * @param bool $deep should this be a deep search
  * @return bool 
  */
 public function epMatches($o, $deep = false)
 {
     // make sure param is epObject
     if (!$o instanceof epObject) {
         return false;
     }
     // same object if same object uid
     if ($this->ep_uid == $o->epGetUId()) {
         return true;
     }
     // matches if the example object does not have any non-null variable
     if (!($vars_o = $o->epGetVars())) {
         return true;
     }
     // get vars of this object
     $vars = $this->epGetVars();
     // set 'matching' flag to avoid endless loop
     $this->epSetMatching(true);
     $o->epSetMatching(true);
     // go through each var from the example object
     foreach ($vars_o as $var => $value) {
         // skip 'oid'
         if ($var == 'oid') {
             continue;
         }
         // ignore null values (including empty string)
         if (is_null($value) || is_string($value) && !$value) {
             continue;
         }
         // for primitive var, mismatch if var is not in object or two vars unequal
         if ($this->epIsPrimitive($var)) {
             if (!isset($vars[$var]) || $vars[$var] != $value) {
                 $this->epSetMatching(false);
                 $o->epSetMatching(false);
                 return false;
             }
             continue;
         }
         // done if no deep matching (see method comments)
         if (!$deep) {
             continue;
         }
         // deep matching for relationship fields
         // many-valued relationship var
         if ($value instanceof epArray) {
             // the epArray can have different order between the
             // two objects, so we have to do an n^2 loop to see
             // if they are the same (ugly)
             // oak: shall we match array count? strict mode? //
             foreach ($value as $obj) {
                 if (!$obj) {
                     continue;
                 }
                 // skip object already under matching
                 if ($obj->epIsMatching()) {
                     continue;
                 }
                 // flag indicates object being matched
                 $matched = false;
                 // go through each var in array
                 foreach ($vars[$var] as $tmp) {
                     if (!$tmp->epIsMatching() && !$obj->epIsMatching()) {
                         if ($tmp->epMatches($obj, true)) {
                             $matched = true;
                             break;
                         }
                     }
                 }
                 // no match to $obj. done.
                 if (!$matched) {
                     $this->epSetMatching(false);
                     $o->epSetMatching(false);
                     return false;
                 }
             }
         } else {
             if ($value instanceof epObject && !$value->epIsMatching()) {
                 // we need to check this
                 if (!isset($vars[$var])) {
                     $vars[$var] = $this->epGet($var);
                 }
                 // match only when vars are not flagged 'matching'
                 if (!$value->epIsMatching() && !$vars[$var]->epIsMatching()) {
                     if (!$vars[$var]->epMatches($value, true)) {
                         $this->epSetMatching(false);
                         $o->epSetMatching(false);
                         return false;
                     }
                 } else {
                     $this->epSetMatching(false);
                     $o->epSetMatching(false);
                     return false;
                 }
             }
         }
     }
     // reset matching flags
     $this->epSetMatching(false);
     $o->epSetMatching(false);
     return true;
 }
Exemple #3
0
 /**
  * Low level create (called by {@link create()})
  * Create a new instance of a class
  * 
  * Although this method is made public for {@link epDbObject} to be able 
  * to call in assembling objects from database rows, it is <b>not</b> 
  * recommended to be used. Please use {@epManager::create()} instead. 
  * 
  * @param string|object $class_or_obj class name or an object
  * @param boolean $caching whether to cache the newly created object
  * @param boolean $dispatch_event whether to dispatch event
  * @return null|epObject
  * @access public 
  * @throws epExceptionManagerBase
  */
 public function &_create($class_or_obj, $caching = true, $dispatch_event = true, $args = array())
 {
     // check if the argument is a string (class name)
     $class = '';
     $o = false;
     if (is_string($class_or_obj)) {
         $class = $class_or_obj;
     } else {
         if (is_object($class_or_obj)) {
             $o =& $class_or_obj;
             $class = get_class($o);
         } else {
             throw new epExceptionManagerBase('Argument unrecognized. It should be either object or class name (string)');
             return self::$null;
         }
     }
     // check if class has been compiled
     if (!($cm =& $this->_getMap($class))) {
         // if not, check if auto_compile is enabled
         if (!$this->getConfigOption('auto_compile')) {
             // if not (auto_compile off), throw
             throw new epExceptionManagerBase('Class ' . $class . ' has not been compiled. ' . 'It cannot be made persistable. Either enable ' . 'auto_compile or compile manually');
             return self::$null;
         }
         // otherwise (auto compile enabled)
         if (!($cm =& $this->_compileClass($class))) {
             // return false if auto-compile fails
             return self::$null;
         }
     }
     // event: onPreCreate
     if ($dispatch_event) {
         $this->_dispatchEvent(array('onPreCreate'), $class, $args);
     }
     // in case the argument is not object, create it
     if (!$o) {
         // make a new instance
         if (!($o =& epNewObject($class, $args))) {
             // throw if failed to create an object
             throw new epExceptionManagerBase('Cannot create object for class [' . $class . ']');
             return self::$null;
         }
     }
     // wrap object if it doesn't have epObject ifc
     if (!$o instanceof epObject) {
         if (!($o = new epObject($o, $cm))) {
             throw new epExceptionManagerBase('Cannot wrap object of [' . $class . ']');
             return self::$null;
         }
     }
     // cache it in the array of uncommited objects (only when auto_flush is on)
     if ($caching) {
         $this->objects_uc[$o->epGetUId()] =& $o;
     }
     // event: onCreate, onPostCreate
     if ($dispatch_event) {
         $this->_dispatchEvent(array('onCreate', 'onPostCreate'), $o);
     }
     return $o;
 }
 /**
  * Checks if the variables of this object matches all the 
  * non-null variables in another object
  * 
  * <b>
  * Note: for now we only match primitive fields. For relational 
  * fields, things can get complicated as we may be dealing with 
  * very "deep" comparisons and recursions.
  * </b>
  * 
  * @param epObject $o the example object
  * @param bool $deep should this be a deep search
  * @return bool 
  */
 public function epMatches($o, $deep = false)
 {
     if (!$o instanceof epObject) {
         return false;
     }
     // same object if same object uid
     if ($this->ep_uid == $o->epGetUId()) {
         return true;
     }
     // matches if the example object does not have any non-null variable
     if (!($vars_o = $o->epGetVars())) {
         return true;
     }
     $this->epSetMatching(true);
     $o->epSetMatching(true);
     // get vars of this object
     $vars = $this->epGetVars();
     // go through each var from the example object
     foreach ($vars_o as $var => $value) {
         if ($var == 'oid') {
             continue;
         }
         // ignore null values (including empty string)
         if (is_null($value) || is_string($value) && !$value) {
             continue;
         }
         // skip non-primitive fields (see note in method comment above)
         // unless we are doing a deep search
         if (!$this->epIsPrimitive($var)) {
             if ($deep) {
                 if ($value instanceof epArray) {
                     // the epArray can have different order between the
                     // two objects, so we have to do an n^2 loop to see
                     // if they are the same (ugly)
                     foreach ($value->getIterator() as $obj) {
                         if (!$obj) {
                             continue;
                         }
                         $matches = array();
                         $matched = false;
                         // we are working on this one already, don't mess with it
                         if ($obj->epIsMatching()) {
                             continue;
                         }
                         foreach ($vars[$var]->getIterator() as $temp) {
                             if (in_array($temp->epGetUId(), $matches)) {
                                 continue;
                             }
                             if (!$temp->epIsMatching() && !$obj->epIsMatching()) {
                                 if ($temp->epMatches($obj, true)) {
                                     // we have matched this temp object
                                     // we don't want to check it again
                                     $matches[] = $temp->epGetUId();
                                     $matched = true;
                                     break;
                                 }
                             }
                         }
                         if (!$matched) {
                             $this->epSetMatching(false);
                             $o->epSetMatching(false);
                             return false;
                         }
                     }
                 } elseif ($value instanceof epObjectWrapper && !$value->epIsMatching()) {
                     if (!isset($vars[$var])) {
                         // we need to check this
                         $vars[$var] = $this->epGet($var);
                     }
                     if (!$value->epIsMatching() && !$vars[$var]->epIsMatching()) {
                         if (!$vars[$var]->epMatches($value, true)) {
                             $this->epSetMatching(false);
                             $o->epSetMatching(false);
                             return false;
                         }
                     } elseif ($value->epIsMatching() && !$vars[$var]->epIsMatching()) {
                         // if one is matching and the other is not, they are not equal
                         $this->epSetMatching(false);
                         $o->epSetMatching(false);
                         return false;
                     } elseif (!$value->epIsMatching() && $vars[$var]->epIsMatching()) {
                         $this->epSetMatching(false);
                         $o->epSetMatching(false);
                         return false;
                     }
                 }
             }
             continue;
         }
         // is var in the objects's vars?
         if (!isset($vars[$var])) {
             $this->epSetMatching(false);
             $o->epSetMatching(false);
             return false;
         }
         // are the values same?
         if ($vars[$var] != $value) {
             $this->epSetMatching(false);
             $o->epSetMatching(false);
             return false;
         }
     }
     $this->epSetMatching(false);
     $o->epSetMatching(false);
     return true;
 }