/** * Populates a data object from a key/value array * * @param array $data * @param \t41\Backend\Mapper $mapper * @return \t41\ObjectModel\DataObject */ public function populate(array $data, Backend\Mapper $mapper = null) { if ($mapper) { // @todo fix compatibility with metakeys in array $data = $mapper->toDataObject($data, $this->_class); } // then sent to data object properties foreach ($data as $key => $value) { // don't use empty() to check $value to avoid zero being ignored if (($property = $this->getProperty($key)) !== false && !is_null($value)) { if ($value == Property::EMPTY_VALUE) { $property->resetValue(); continue; } if ($property instanceof ObjectProperty || $property instanceof MediaProperty) { if ($property->getParameter('instanceof') == null) { throw new DataObject\Exception("Parameter 'instanceof' for '{$key}' in class should contain a class name"); } // Specific case of MediaObject() if ($property->getParameter('instanceof') == 't41\\ObjectModel\\MediaObject') { // new file case : value is a string prepended by 'tmp:' if ($value && substr($value, 0, strlen(MediaObject::TMP_PREFIX)) == MediaObject::TMP_PREFIX) { $parts = explode('|', substr($value, 4)); // 0 => hash, 1 => original file name $file = '/tmp/' . $parts[0]; if (file_exists($file)) { $media = new MediaObject(); $media->setUri(md5(rand() * microtime())); $media->setLabel($parts[1]); $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file); $media->setMedia($file); // blob property $media->setSize(filesize($file)); $media->setMime($mime); $media->save(); $property->setValue($media); // media property unlink($file); } continue; // don't go further in this case } } if ($value && $value != Property::EMPTY_VALUE) { if (is_object($value) && get_class($value) == $property->getParameter('instanceof')) { $property->setValue($value); } else { if (substr($value, 0, 4) == 'obj_') { // get object from cache $property->setValue(Core::cacheGet($value)); } else { if (substr($value, 0, 1) == Backend::PREFIX) { /* get & call object's backend to get a full configured object uri */ $backend = ObjectModel::getObjectBackend($property->getParameter('instanceof')); $value = $backend->buildObjectUri($value, $property->getParameter('instanceof')); $property->setValue($value instanceof ObjectUri ? $value : new ObjectUri($value)); } else { //$class = $property->getParameter('instanceof'); $backend = ObjectModel::getObjectBackend($property->getParameter('instanceof')); $value = $backend->buildObjectUri($value, $property->getParameter('instanceof')); $property->setValue($value); } } } } else { $property->resetValue(); } } else { if ($property instanceof Property\CollectionProperty) { // @todo handle collection populating here } else { // if value is an array, it is most likely a set of multiple options if (is_array($value)) { $value = implode('|', $value); } $property->setValue($value); } } } } return $this; }
/** * Return the number of distinct objects matching the given property * @param string $string * @param unknown_type $backend * @throws Backend\Exception * @return array */ public function returnsDistinct($string, $backend = null) { $prop = $this->_do->getProperty($string); if (!$prop instanceof Property\AbstractProperty) { throw new Backend\Exception(array("CONDITION_UNKNOWN_PROPERTY", $string)); } if (is_null($backend)) { $backend = ObjectModel::getObjectBackend($this->_do->getClass()); } return (array) Backend::returnsDistinct($this, $prop, $backend); }
public static function returnsDistinct(ObjectModel\Collection $co, Property\PropertyAbstract $property, Backend\Adapter\AbstractAdapter $backend) { if (is_null($backend)) { $backend = ObjectModel::getObjectBackend($co->getDataObject()->getClass()); if (is_null($backend)) { // get default backend $backend = self::getDefaultBackend(); } } if (!$backend) { throw new Backend\Exception("NO_AVAILABLE_BACKEND"); } return $backend->returnsDistinct($co, $property); }
/** * Perform the correct join from given object property and return the table alias * @todo test and implement in various places in find() method * @param Property\ObjectProperty $property * @param string $table * @return string */ protected function _join(Property\ObjectProperty $property, $table) { $join = array(); $class = $property->getParameter('instanceof'); $stable = $this->_getTableFromClass($class); $leftkey = $this->_mapper ? $this->_mapper->propertyToDatastoreName($property->getParent()->getDataObject()->getClass(), $property->getId()) : $property->getId(); $uniqext = $stable . '__joined_for__' . $leftkey; if (!isset($this->_alreadyJoined[$stable])) { $sbackend = ObjectModel::getObjectBackend($class); if ($sbackend->getAlias() != $this->getAlias()) { // @todo raise and exception if backends are not of same type // We presume that the current backend is allowed to connect to the remote one // Should we raise an exception instead ? $stable = $sbackend->getUri()->getDatabase() . '.' . $stable; } $field = $property->getId(); $rightkey = $this->_mapper ? $this->_mapper->getPrimaryKey($class) : Backend::DEFAULT_PKEY; if (is_array($rightkey)) { foreach ($rightkey as $rightkeyObj) { // @todo fix left key that should be provided by mapper $join[] = sprintf("%s.%s = %s.%s", $table, $leftkey, $uniqext, $rightkeyObj->getName()); } } else { $join[] = sprintf("%s.%s = %s.%s", $table, $leftkey, $uniqext, $rightkey); } $this->_select->joinLeft("{$stable} AS {$uniqext}", implode(' AND ', $join), array()); $this->_alreadyJoined[$stable] = $uniqext; } return $uniqext; }