/** * Combines the same functionality that {@link createFromArray()} and * {@link updateFromArray} have. * * @param epObject $o * @param array $array * @param boolean $dispatch_event whether to dispatch events * @param boolean $clean * @return null|epObject|string (error message if string) * @throws epExceptionManagerBase */ protected function &_fromArray(&$o, $array, $dispatch_event, $clean = true) { // get class from object $class = $o->epGetClass(); // copy array values to object foreach ($array as $var => $val) { // skip oid if ($var == 'oid') { $o->epSetObjectId($val); continue; } // check if var exists in class if (!$o->epIsVar($var)) { // unrecognized var throw new epExceptionManagerBase('Variable [' . $var . '] does not exist in class [' . $class . ']'); return self::$null; } // // a primitive var? // if ($o->epIsPrimitive($var)) { // primitive must be a scalar if (!is_scalar($val)) { throw new epExceptionManagerBase('Value is not scalar for primitive var [' . $class . '::' . $var . ']'); return self::$null; } // assign value to var in object $o[$var] = $val; continue; } // // a relationship var // // get class of var $class = $o->epGetClassOfVar($var); // // a single-valued var // if ($o->epIsSingle($var)) { // recursion if value is an array if (is_array($val)) { // recursion: object to var in object $o->epSet($var, $this->createFromArray($class, $val, $dispatch_event, $clean)); continue; } // if value is int, it might be an oid of an existing object if (is_integer($val) || ctype_digit($val)) { // get the corresponding object if ($sub =& $this->get($class, $val)) { // yep, it exists $o->epSet($var, $sub); continue; } } // if it is an object, it might be an existing object if ($val instanceof epObject) { $o->epSet($var, $val); continue; } throw new epExceptionManagerBase('Value is not array or object id for relationship var [' . $class . '::' . $var . ']'); continue; } // // a many-valued var // // value should be either an integer (oid) or an array. $vals = is_array($val) ? $val : array($val); // check if value is multiple. arrayize it if not. $vals = isset($val[0]) ? $val : array($val); // create objects for many-valued field $os = array(); foreach ($vals as $val) { // recursion: object to var in object if (is_array($val)) { $os[] =& $this->createFromArray($class, $val, $dispatch_event, $clean); continue; } // if value is int, it might be an oid of an existing object if (is_integer($val) || ctype_digit($val)) { if ($sub =& $this->get($class, $val)) { // yep, it exists $os[] =& $sub; continue; } } // if it is an object, it might be an existing object if ($val instanceof epObject) { $os[] =& $val; continue; } throw new epExceptionManagerBase('Value is not array or object id for relationship var [' . $class . '::' . $var . ']'); continue; } $o->epSet($var, $os); } return $o; }
/** * Cache an object * @param epObject $o The object to be added into cache * @param boolean $force Whether to force replace object in cache * @return boolean */ public function add(epObject &$o, $force = false) { // don't cache objects that haven't been committed if (!($oid = $o->epGetObjectId())) { return false; } // get class if (!($class = $o->epGetClass())) { return false; } // generate key $key = $this->_key($class); // get all objects for the class if (!($os = $this->cache->get($key))) { $os = array(); } // done if not forced -and- oid already in cache if (!$force && in_array($o->oid, array_keys($os))) { return true; } // put object into array $os[$o->oid] = $o; // is class write locked? if ($this->isLocked($class, self::LOCK_WRITE)) { return false; } // lock write $this->_lock($class, self::LOCK_WRITE); // cache array $status = $this->cache->set($key, $os); // unlock write $this->_unlock($class, self::LOCK_WRITE); return $status; }
/** * Generate a string that can be used to uniquely identify an object. * False is returned if invalid object or object does not have oid yet. * @param epObject $o * @return false|string */ public function encodeUoid(epObject $o) { if (!$o || !($oid = $o->epGetObjectId())) { return false; } // put class name and id into simple format: "<class>:<id>" return $this->_encodeUoid($o->epGetClass(), $oid); }