/** * test primitive variables */ function testPrimitiveVars() { // make an eptTest object $this->assertTrue($o = new eptTest("XXX", "YYY", "ZZZ")); // wrap it with epObject $this->assertTrue($w = new epObject($o)); // test new object is not dirty $this->assertFalse($w->epIsDirty()); // check vars $this->assertTrue($vars = $w->epGetVars()); // x, a, o are in vars $this->assertTrue(array_key_exists("x", $vars)); $this->assertTrue(array_key_exists("a", $vars)); $this->assertTrue(array_key_exists("o", $vars)); // y protected is not in vars $this->assertFalse(array_key_exists("y", $vars)); $this->assertFalse(array_key_exists("z", $vars)); /** * test primitive vars */ // test epGet('x') against direct object property access ($o->x) $this->assertTrue($w->epGet('x') === $o->x); // test epSet('x'), epGet('x'), and $w->x (overloading __get()) $value = md5($w->epGet('x')); $this->assertTrue($w->epSet('x', $value)); $this->assertTrue($o->x === $value); $this->assertTrue($w->epGet('x') === $o->x); $this->assertTrue($w->x === $o->x); $this->assertTrue($w->epIsDirty()); // check if 'x' is in modified list $this->assertTrue($modified = $w->epGetModifiedVars()); $this->assertTrue(array_key_exists('x', $modified)); $this->assertTrue($modified['x'] === $value); // test getter/setter (overloading __call()) $value = md5($w->epGet('x')); $this->assertTrue($w->setX($value)); $this->assertTrue($w->getX() === $o->x); $this->assertTrue($w->getX() === $value); // check which 'x' is in modified list $this->assertTrue($modified = $w->epGetModifiedVars()); $this->assertTrue(array_key_exists('x', $modified)); $this->assertTrue($modified['x'] === $value); // check magic method __get() and __set() $this->assertTrue($w->x === $value); $value = md5($w->x); $this->assertTrue($w->x = $value); $this->assertTrue($w->x === $value); // getting protected 'y' gets exception try { $this->assertTrue($w->epGet('y') === false); } catch (Exception $e) { // !!!simpletest seem to ignore assert in catch block $this->assertTrue($e instanceof epExceptionObject); } // setting protected 'y' gets exception try { $this->assertTrue($w->epSet('y', 'YYY|YYY') === false); } catch (Exception $e) { // !!!simpletest seem to ignore assert in catch block $this->assertTrue($e instanceof epExceptionObject); } // getting protected 'z' gets exception try { $this->assertTrue($w->epGet('z') === false); } catch (Exception $e) { // !!!simpletest seem to ignore assert in catch block $this->assertTrue($e instanceof epExceptionObject); } // setting protected 'z' gets exception try { $this->assertTrue($w->epSet('z', 'ZZZ|ZZZ') === false); } catch (Exception $e) { // !!!simpletest seem to ignore assert in catch block $this->assertTrue($e instanceof epExceptionObject); } }
/** * Make where part of a SQL select to get children values * @param epDbObject $db the db connection * @param epObject $o the child object for query * @param int $depth how many children down we are * @param string $parent the parent of this child * @return array('from', 'where') * @author Oak Nauhygon <*****@*****.**> * @author Trevan Richins <*****@*****.**> */ public static function sqlSelectChildren($db, $o, $depth, $parent) { // array to keep new tables in 'from' $from = array(); // array to keep new expression in 'where' $where = array(); // get the class map for the child object $cm = $o->epGetClassMap(); // get all vars in the object $vars = $o->epGetVars(); // if object has oid, select use oid if ($oid = $o->epGetObjectId()) { $where[] = $db->quoteId($cm->getOidColumn()) . ' = ' . $oid; return array('from' => $from, 'where' => $where); } // mark child object under search (to avoid loops) $o->epSetSearching(true); // total number of vars (primitive or non-primitive) collected $n = 0; // new depth $depth++; // number of non-primitive (relationship) fields collected $nprim_id = 0; // loop through vars while (list($var, $val) = each($vars)) { // get field map if (!($fm =& $cm->getField($var))) { // should not happen continue; } // exclude null values (including empty strings) if (is_null($val) || !$val && $fm->getType() == epFieldMap::DT_CHAR) { continue; } // is it a primitive var? if ($fm->isPrimitive()) { $where[] = $db->quoteId($parent) . '.' . $db->quoteId($fm->getColumnName()) . ' = ' . $db->quote($val, $fm); // done for this var $n++; continue; } // okay we are dealing with a non-primitive (relationship) var if ($val instanceof epArray) { foreach ($val as $obj) { // skip object that is under searching if (!$obj || $obj->epIsSearching()) { continue; } // get 'where' and 'from' from relationship $from_where = epObj2Sql::sqlSelectRelations($db, $fm, $cm, $obj->epGetClassMap()->getTable(), $depth . $nprim_id, $parent); $where = array_merge($where, $from_where['where']); $from = array_merge($from, $from_where['from']); // get 'where' and 'from' from relationship $from_where = epObj2Sql::sqlSelectChildren($db, $obj, $depth, '_' . $depth . $nprim_id); $where = array_merge($where, $from_where['where']); $from = array_merge($from, $from_where['from']); $nprim_id++; } } else { if ($val instanceof epObject && !$val->epIsSearching()) { // get 'where' and 'from' from relationship $from_where = epObj2Sql::sqlSelectRelations($db, $fm, $cm, $val->epGetClassMap()->getTable(), $depth . $nprim_id, $parent); $where = array_merge($where, $from_where['where']); $from = array_merge($from, $from_where['from']); // get 'where' and 'from' from relationship $from_where = epObj2Sql::sqlSelectChildren($db, $val, $depth, '_' . $depth . $nprim_id); $where = array_merge($where, $from_where['where']); $from = array_merge($from, $from_where['from']); $nprim_id++; } } $n++; } // reset search flag on child object $o->epSetSearching(false); return array('from' => $from, 'where' => $where); }
/** * 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; }
/** * 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; }