public function readAction() { $collection = new Collection($this->_class); if ($this->_getParam('id')) { $collection->having(ObjectUri::IDENTIFIER)->equals($this->_getParam('id')); $collection->setBoundaryBatch(1)->find(); if ($collection->getTotalMembers() == 1) { $form = new FormComponent($collection->getMember(Collection::POS_FIRST)); $form->register(); } } else { $list = new ListComponent($collection); $list->addRowAction($_SERVER['REQUEST_URI'], 'Read', array('icon' => 'tool-blue')); $list->register(); } }
/** * Populate the given collection from the array of identifiers and the uri base * * @param array $ids * @param \t41\ObjectModel\Collection $collection * @param \t41\ObjectModel\ObjectUri $uriBase */ protected function _populateCollection(array $ids, ObjectModel\Collection $collection, ObjectModel\ObjectUri $uriBase) { if (count($ids) == 0) { return array(); } if (count($ids[0]) > 1) { $do = clone $collection->getDataObject(); } $class = $collection->getDataObject()->getClass(); // populate array with relevant objects type $array = array(); /** * If data object has been modified (meta property added) we need to use it to populate objects */ if ($collection->getParameter('memberType') != ObjectModel::URI && $collection->getDataObject()->getDna('custom')) { $do = clone $collection->getDataObject(); } foreach ($ids as $key => $id) { $uri = clone $uriBase; if (is_array($id)) { $uri->setUrl($uri->getUrl() . $id['id'])->setIdentifier($id['id']); unset($id['id']); } else { $uri->setUrl($uri->getUrl() . $id)->setIdentifier($id); } if (isset($do)) { $obj = clone $do; $obj->setUri($uri); } else { unset($obj); } switch ($collection->getParameter('memberType')) { case ObjectModel::URI: $obj = $uri; break; case ObjectModel::MODEL: if (isset($obj) || is_array($ids)) { Backend::read($obj, null, $id); } else { $obj = Core::_($uri, $class); } break; case ObjectModel::DATA: default: if (isset($obj) || is_array($ids)) { Backend::read($obj, null, $id); } else { $obj = Core::_($uri, $class); } $obj = $obj->getDataObject(); break; } $array[$key] = $obj; } return $array; }
/** * returns a collection of objects matching the dependency parameter */ public function dependAction() { if (($property = $this->_obj->getProperty($this->_post['destProperty']['id'])) !== false) { // @todo implement cache mechanism for the following collection $collection = new Collection($property->getParameter('instanceof')); foreach ($this->_post['srcProperty'] as $key => $val) { $collection->having($key)->equals($val); } $collection->setBoundaryBatch(50000); $collection->find(ObjectModel::MODEL); $data = array(); foreach ($collection->getMembers() as $member) { $reduced = $member->reduce(); $data[$member->getUri()->getIdentifier()] = $reduced; if ($property->getValue() && $property->getValue()->getIdentifier() == $member->getIdentifier()) { $this->_data['value'] = $reduced['uuid']; } } $this->_data['total'] = $collection->getTotalMembers(); $this->_data['collection'] = $data; } else { $this->_status = 'NOK'; } }
public function returnsDistinct(ObjectModel\Collection $collection, ObjectModel\Property\PropertyAbstract $property) { $class = $collection->getDataObject()->getClass(); $mode = $collection->getParameter('memberType'); // set database to use $this->_selectDatabase(); // get collection to use, from mapper if available, else from data object $collec = $this->_mapper instanceof Backend\Mapper ? $this->_mapper->getDatastore($class) : $class; //$collec = $this->_db->selectCollection($collec); $conditions = array(); /* @var $condition t41_Condition */ foreach ($collection->getConditions() as $conditionArray) { $condition = $conditionArray[0]; // map property to field if ($this->_mapper) { $field = $this->_mapper->propertyToDatastoreName($class, $condition->getProperty()->getId()); } else { $field = $condition->getProperty()->getId(); } $conditions += $this->_buildConditionStatement($field, $condition->getClauses(), $conditions); switch ($conditionArray[1]) { case 'OR': //$select->orWhere($statement); break; case 'AND': default: //$select->where($statement); break; } } $params = array(); $params['distinct'] = $collec; $params['key'] = $property->getId(); $params['query'] = $conditions; $this->_setLastQuery('command', $params); $ids = $this->_db->command($params); /* @todo if property is an object, we should get all values from the list of ids */ return isset($ids['values']) ? $ids['values'] : array(); }
public function find(array $conditions = null, array $sortings = null, $offset = 0, $batch = 10) { $co = new Collection(clone $this->_dataObject); if (is_array($conditions)) { $co->setConditions($conditions); } if (is_array($sortings)) { $co->setSortings($sortings); } $co->setBoundaryOffset($offset); $co->setBoundaryBatch($batch); $co->find(); return $co; }
/** * Returns an array of objects queried from the given t41_Object_Collection instance parameters * * The given collection is populated if it comes empty of members. * * In any other case, this method doesn't directly populate the collection. This action is under the responsability of * the caller. For example, the t41_Object_Collection::find() method takes care of it. * * @param t41\ObjectModel\Collection $collection * @param boolean|array $returnCount true = counting, array = stats on listed properties * @param string $subOp complex operation like SUM or AVG * @return array */ public function find(ObjectModel\Collection $collection, $returnCount = false, $subOp = null) { $this->_class = $class = $collection->getDataObject()->getClass(); $table = $this->_getTableFromClass($class); if (!$table) { throw new Exception('MISSING_DBTABLE_PARAM'); } // primary key is either part of the mapper configuration or 'id' $pkey = $this->_mapper ? $this->_mapper->getPrimaryKey($class) : \t41\Backend::DEFAULT_PKEY; if (is_array($pkey)) { $composite = array(); /* @var $obj t41\Backend\Key */ foreach ($pkey as $obj) { $composite[] = sprintf('TRIM(%s)', $table . '.' . $obj->getName()); $composite[] = Backend\Mapper::VALUES_SEPARATOR; } $pkey = sprintf("CONCAT(%s) AS %s", implode(',', $composite), Backend::DEFAULT_PKEY); } else { $pkey = $table . '.' . $pkey; } $this->_connect(); /* @var $select \Zend_Db_Select */ $this->_select = $this->_ressource->select(); // detect if query is of stat-kind if ($returnCount) { switch ($subOp) { case ObjectModel::CALC_SUM: $expressions = array(); foreach ($returnCount as $propKey => $property) { $prop = $this->_mapper ? $this->_mapper->propertyToDatastoreName($class, $propKey) : $propKey; $expressions[] = sprintf('SUM(%s.%s)', $table, $prop); } $subOpExpr = implode('+', $expressions); break; case ObjectModel::CALC_AVG: $subOpExpr = sprintf('AVG(%s)', $returnCount); break; default: $subOpExpr = 'COUNT(*)'; break; } $this->_select->from($table, new \Zend_Db_Expr($subOpExpr . " AS " . \t41\Backend::MAX_ROWS_IDENTIFIER)); } else { $this->_select->distinct(); $this->_select->from($table, $pkey); } $this->_alreadyJoined = array(); /* @var $condition t41\Backend\Condition */ foreach ($collection->getConditions() as $conditionArray) { // combo conditions if ($conditionArray[0] instanceof Condition\Combo) { $statement = array(); foreach ($conditionArray[0]->getConditions() as $condition) { $statement[] = $this->_parseCondition($condition[0], $this->_select, $table); } $statement = implode(' OR ', $statement); switch ($conditionArray[1]) { case Condition::MODE_OR: $this->_select->orWhere($statement); break; case Condition::MODE_AND: default: $this->_select->where($statement); break; } continue; } // optional table where the column may be $jtable = ''; // condition object is in the first key $condition = $conditionArray[0]; /* does condition contain another condition object ? */ if ($condition->isRecursive()) { while ($condition->isRecursive()) { $property = $condition->getProperty(); $parent = $property->getParent() ? $property->getParent()->getId() : $table; $condition = $condition->getCondition(); if ($jtable) { $parentTable = $jtable; } else { if ($parent) { $parentTable = $this->_mapper ? $this->_mapper->getDatastore($parent) : $parent; } else { $parentTable = $table; } } $jtable = $this->_mapper ? $this->_mapper->getDatastore($property->getParameter('instanceof')) : $this->_getTableFromClass($property->getParameter('instanceof')); /* column name in left table */ $jlkey = $this->_mapper ? $this->_mapper->propertyToDatastoreName($class, $property->getId()) : $property->getId(); $uniqext = $jtable . '__joined_for__' . $jlkey; if (in_array($uniqext, $this->_alreadyJoined)) { $class = $property->getParameter('instanceof'); $jtable = $uniqext; continue; } /* pkey name in joined table */ $jpkey = $this->_mapper ? $this->_mapper->getPrimaryKey($property->getParameter('instanceof')) : Backend::DEFAULT_PKEY; $join = sprintf("%s.%s = %s.%s", $parentTable, $jlkey, $uniqext, $jpkey); $this->_select->joinLeft($jtable . " AS {$uniqext}", $join, array()); $this->_alreadyJoined[$jtable] = $uniqext; //$jtable; $jtable = $uniqext; $class = $property->getParameter('instanceof'); } } $property = $condition->getProperty(); if ($property instanceof Property\ObjectProperty) { // no join if object is stored in a different backend ! // @todo improve this part if (ObjectModel::getObjectBackend($property->getParameter('instanceof'))->getAlias() != $this->_uri->getAlias()) { $clauses = $condition->getClauses(); if ($clauses[0]['value'] != Condition::NO_VALUE) { $clauses[0]['operator'] = Condition::OPERATOR_ENDSWITH | Condition::OPERATOR_EQUAL; $condition->setClauses($clauses); } $field = $this->_mapper ? $this->_mapper->propertyToDatastoreName($this->_class, $property->getId()) : $property->getId(); } else { // which table to join with ? (in case of condition is last element of a recursion) $jtable2 = $jtable ? $jtable : $table; $jtable = $this->_mapper ? $this->_mapper->getDatastore($property->getParameter('instanceof')) : $this->_getTableFromClass($property->getParameter('instanceof')); $leftkey = $this->_mapper ? $this->_mapper->propertyToDatastoreName($class, $property->getId()) : $property->getId(); $field = $rightkey = $this->_mapper ? $this->_mapper->getPrimaryKey($property->getParameter('instanceof')) : Backend::DEFAULT_PKEY; $uniqext = $jtable . '__joined_for__' . $leftkey; if (!in_array($uniqext, $this->_alreadyJoined)) { $join = sprintf("%s.%s = %s.%s", $jtable2, $leftkey, $uniqext, is_array($rightkey) ? $rightkey[0] : $rightkey); $this->_select->joinLeft($jtable . " AS {$uniqext}", $join, array()); $this->_alreadyJoined[$jtable] = $uniqext; } $jtable = $uniqext; } } else { if ($property instanceof Property\CollectionProperty) { // handling of conditions based on collection limited to withMembers() and withoutMembers() $leftkey = $property->getParameter('keyprop'); $field = $property->getId(); $subSelect = $this->_ressource->select(); $subseltbl = $this->_mapper ? $this->_mapper->getDatastore($property->getParameter('instanceof')) : $this->_getTableFromClass($property->getParameter('instanceof')); $subSelect->from($subseltbl, new \Zend_Db_Expr(sprintf("COUNT(%s)", $leftkey))); $join = sprintf("%s.%s = %s", $subseltbl, $leftkey, $pkey); $subSelect->where($join); $statement = $this->_buildConditionStatement(new \Zend_Db_Expr(sprintf("(%s)", $subSelect)), $condition->getClauses(), $conditionArray[1]); $this->_select->where($statement); continue; } else { $field = $property->getId(); if ($this->_mapper) { $field = $this->_mapper->propertyToDatastoreName($class, $field); } } } /* convert identifier tag to the valid primary key */ if ($field == ObjectUri::IDENTIFIER) { // @todo handle multiple keys from mapper $field = $table . '.'; $key = $this->_mapper ? $this->_mapper->getPrimaryKey($class) : Backend::DEFAULT_PKEY; $field .= is_array($key) ? $key[0] : $key; } else { if ($jtable) { if (array_key_exists($jtable, $this->_alreadyJoined)) { $field = $this->_alreadyJoined[$jtable] . '.' . $field; } else { $tmp = $jtable . '.'; $tmp .= is_array($field) ? $field[0] : $field; $field = $tmp; } } else { if (array_key_exists($table, $this->_alreadyJoined)) { $field = $this->_alreadyJoined[$table] . '.' . $field; } else { $field = $table . '.' . $field; } } } if ($field instanceof Key) { $field = $table . '.' . $field->getName(); } // protect DateProperty() with setted timepart parameter from misuse if ($property instanceof DateProperty && $property->getParameter('timepart') == true) { $field = "DATE({$field})"; } $statement = $this->_buildConditionStatement($field, $condition->getClauses(), $conditionArray[1]); switch ($conditionArray[1]) { case Condition::MODE_OR: $this->_select->orWhere($statement); break; case Condition::MODE_AND: default: $this->_select->where($statement); break; } } // Adjust query based on returnCount if ($returnCount) { if (is_array($returnCount)) { if ($subOp) { } else { // return count on grouped columns foreach ($returnCount as $key => $property) { $fieldmodifier = null; if ($this->_mapper) { $class = $property->getParent() ? $property->getParent()->getId() : $collection->getDataObject()->getClass(); $field = $this->_mapper->propertyToDatastoreName($class, $property->getId()); } else { $field = $property->getId(); } if ($property instanceof ObjectProperty) { // join with $key if necessary if (strstr($key, '.') !== false) { $leftPart = substr($key, 0, strpos($key, '.')); $intermediateProp = $collection->getDataObject()->getProperty($leftPart); $fieldmodifier = $this->_join($intermediateProp, $table) . '.' . $field; } } // limit date grouping to date part, omitting possible hour part if ($property instanceof DateProperty) { $fieldmodifier = "DATE({$field})"; } $this->_select->group($fieldmodifier ? $fieldmodifier : $field); $this->_select->columns(array($field => $fieldmodifier ? $fieldmodifier : $field)); } } } else { $this->_select->reset('group'); } } else { $this->_select->limit($collection->getBoundaryBatch() != -1 ? $collection->getBoundaryBatch() : null, $collection->getBoundaryOffset()); /** * Sorting part */ foreach ($collection->getSortings() as $sorting) { $slUniqext = $slTable = null; // Specific cases first // @todo find a better way to sort on meta properties if ($sorting[0]->getId() == ObjectUri::IDENTIFIER || $sorting[0] instanceof MetaProperty) { $id = Backend::DEFAULT_PKEY; $this->_select->order(new \Zend_Db_Expr($table . '.' . $id . ' ' . $sorting[1])); continue; } else { if ($sorting[0] instanceof Property\CollectionProperty) { // handling of conditions based on collection limited to withMembers() and withoutMembers() $leftkey = $sorting[0]->getParameter('keyprop'); //$field = $property->getId(); $subSelect = $this->_ressource->select(); $subseltbl = $this->_mapper ? $this->_mapper->getDatastore($sorting[0]->getParameter('instanceof')) : $this->_getTableFromClass($sorting[0]->getParameter('instanceof')); $subSelect->from($subseltbl, new \Zend_Db_Expr(sprintf("COUNT(%s)", $leftkey))); $join = sprintf("%s.%s = %s", $subseltbl, $leftkey, $pkey); $subSelect->where($join); // $statement = $this->_buildConditionStatement(new \Zend_Db_Expr(sprintf("(%s)", $subSelect)), $condition->getClauses(), $conditionArray[1]); $this->_select->order(new \Zend_Db_Expr('(' . $subSelect->__toString() . ') ' . $sorting[1])); continue; } else { if ($sorting[0] instanceof Property\ObjectProperty) { // find which property to sort by if ($sorting[0]->getParameter('sorting')) { $sprops = array_keys($sorting[0]->getParameter('sorting')); } else { // try to sort with properties used to display value if (substr($sorting[0]->getParameter('display'), 0, 1) == '[') { // @todo extract elements of pattern to order from them ? $sprops = array('id'); } else { $sprops = explode(',', $sorting[0]->getParameter('display')); } } // sorting property belongs to a second-level join if ($sorting[0]->getParent()->getClass() != $collection->getClass()) { $leftkey = 'commande'; //$this->_mapper ? $this->_mapper->propertyToDatastoreName($collection->getDataObject()->getClass(), $sorting[0]->getParent()getId()) : $sorting[0]->getId(); $class = $sorting[0]->getParent()->getClass(); $stable = $this->_getTableFromClass($class); $sbackend = ObjectModel::getObjectBackend($class); // Property to sort from is in a different backend from current one if ($sbackend->getAlias() != $this->getAlias()) { // 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 = $sorting[0]->getId(); $rightkey = $this->_mapper ? $this->_mapper->getPrimaryKey($class) : Backend::DEFAULT_PKEY; $uniqext = $stable . '__joined_for__' . $leftkey; if (!in_array($uniqext, $this->_alreadyJoined)) { if (is_array($rightkey)) { foreach ($rightkey as $rightkeyObj) { $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}", $join, array()); $this->_alreadyJoined[$stable] = $uniqext; } $slTable = $this->_getTableFromClass($sorting[0]->getParameter('instanceof')); $slUniqext = $uniqext; } $leftkey = $this->_mapper ? $this->_mapper->propertyToDatastoreName($collection->getDataObject()->getClass(), $sorting[0]->getId()) : $sorting[0]->getId(); $class = $sorting[0]->getParameter('instanceof'); $stable = isset($slTable) ? $slTable : $this->_getTableFromClass($class); $sbackend = ObjectModel::getObjectBackend($class); // Property to sort from is in a different backend from current one if ($sbackend->getAlias() != $this->getAlias()) { // 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 = $sorting[0]->getId(); $rightkey = $this->_mapper ? $this->_mapper->getPrimaryKey($class) : Backend::DEFAULT_PKEY; $uniqext = $stable . '__joined_for__' . $leftkey; if (!in_array($uniqext, $this->_alreadyJoined)) { if (is_array($rightkey)) { foreach ($rightkey as $rightkeyObj) { $join = sprintf("%s.%s = %s.%s", $table, $leftkey, $uniqext, $rightkeyObj->getName()); } } else { $join = sprintf("%s.%s = %s.%s", isset($slUniqext) ? $slUniqext : $table, $leftkey, $uniqext, $rightkey); } $this->_select->joinLeft("{$stable} AS {$uniqext}", $join, array()); $this->_alreadyJoined[$stable] = $uniqext; } foreach ($sprops as $sprop) { if ($this->_mapper) { $sfield = $this->_mapper->propertyToDatastoreName($class, $sprop); } else { $sfield = $sprop; } $sortingExpr = $this->_alreadyJoined[$stable] . '.' . $sfield; if (isset($sorting[2]) && !empty($sorting[2])) { $sortingExpr = sprintf('%s(%s)', $sorting[2], $sortingExpr); } $this->_select->order(new \Zend_Db_Expr($sortingExpr . ' ' . $sorting[1])); } continue; } } } // default sorting on a different table $class = $sorting[0]->getParent() ? $sorting[0]->getParent()->getClass() : $collection->getDataObject()->getClass(); $stable = $this->_getTableFromClass($class); if ($this->_mapper) { $sfield = $this->_mapper->propertyToDatastoreName($class, $sorting[0]->getId()); } else { $field = $sorting[0]; $sfield = $field->getId(); } // add a left join if the sorting field belongs to a table not yet part of the query if ($stable != $table) { // get the property id from the class name $tfield = isset($sorting[3]) ? $sorting[3] : $collection->getDataObject()->getObjectPropertyId($class); $leftkey = $this->_mapper ? $this->_mapper->propertyToDatastoreName($class, $tfield) : $tfield; $rightkey = $this->_mapper ? $this->_mapper->getPrimaryKey($field->getParameter('instanceof')) : Backend::DEFAULT_PKEY; $uniqext = $stable . '__joined_for__' . $leftkey; if (!in_array($uniqext, $this->_alreadyJoined)) { $join = sprintf("%s.%s = %s.%s", $table, $leftkey, $uniqext, $rightkey); $this->_select->joinLeft("{$stable} AS {$uniqext}", $join, array()); $this->_alreadyJoined[$stable] = $uniqext; } $sortingExpr = $this->_alreadyJoined[$stable] . '.' . $sfield; } else { $sortingExpr = $stable . '.' . $sfield; } if (isset($sorting[2]) && !empty($sorting[2])) { $sortingExpr = sprintf('%s(%s)', $sorting[2], $sortingExpr); } $this->_select->order(new \Zend_Db_Expr('TRIM(' . $sortingExpr . ') ' . $sorting[1])); } } $result = array(); $context = array('table' => $table); try { if (true && $returnCount == false) { $this->_select->columns($this->_getColumns($collection->getDataObject())); } $result = $this->_ressource->fetchAll($this->_select); } catch (\Zend_Db_Exception $e) { $context['error'] = $e->getMessage(); $this->_setLastQuery($this->_select->__toString(), $this->_select->getPart('where'), $context); return false; } $this->_setLastQuery($this->_select->__toString(), $this->_select->getPart('where'), $context); if ($returnCount !== false) { return is_array($returnCount) ? $result : $result[0][Backend::MAX_ROWS_IDENTIFIER]; } // convert array of primary keys to strings foreach ($result as $key => $val) { // $result[$key] = implode(Backend\Mapper::VALUES_SEPARATOR, $val); } /* prepare base of object uri */ $uri = new ObjectModel\ObjectUri(); $uri->setBackendUri($this->_uri); $uri->setClass($collection->getDataObject()->getClass()); $uri->setUrl($this->_database . '/' . $table . '/'); return $collection->populate($result, $uri); //return $this->_populateCollection($result, $collection, $uri); }
public function find(ObjectModel\Collection $collection) { $class = $collection->getDataObject()->getClass(); $mode = $collection->getParameter('memberType'); $expr = ''; $this->_setRessource($class); /* @var $condition t41_Condition */ foreach ($collection->getConditions() as $conditionArray) { $condition = $conditionArray[0]; // map property to field if ($this->_mapper) { $field = $this->_mapper->propertyToDatastoreName($class, $condition->getProperty()->getId()); } else { $field = $condition->getProperty()->getId(); } if ($expr) { switch ($conditionArray[1]) { case 'OR': $expr .= ' or '; break; case 'AND': default: $expr .= ' and '; break; } } $expr .= sprintf("%s %s '%s'", $field, is_numeric($condition->getOperator()) ? $this->_operators[$condition->getOperator()] : $condition->getOperator(), $condition->getValue()); } // get all nodes id $result = $this->_findNodes($expr, '@id'); $dataSet = array(); foreach ($result as $node) { $dataSet[] = $node->nodeValue; } if (count($collection->getSortings()) > 0) { $sort = array(); foreach ($collection->getSortings() as $key => $sorting) { if ($this->_mapper) { $field = $this->_mapper->propertyToDatastoreName($class, $sorting[0]->getId()); } else { $field = $sorting[0]->getId(); } $sort = $this->_sortNodes($sort, $field, $sorting[1], $key == 0 ? $dataSet : null); } } // Flatten array $sort = $this->_arrayflat($sort); //Zend_Debug::dump($sort); $array = array(); $uri = new ObjectModel\ObjectUri(); $uri->setBackendUri($this->_uri); $uri->setClass($class); if ($mode != 'uri') { $do = new ObjectModel\DataObject($class); } $count = $collection->getBoundaryOffset(); $limit = $count + $collection->getBoundaryBatch(); /* iterate over result set as long as requested */ while ($count < $limit) { if (!isset($dataSet[$count])) { // if end of result data set has been reached, return array return $array; } $id = $dataSet[$count]; $uri->setUrl($this->_alias . '/' . $id); switch ($mode) { case 'uri': $data = clone $uri; break; case 'data': $do->setUri(clone $uri); $do->populate(); $data = clone $do; break; case 'model': $do->setUri(clone $uri); $do->populate(); /* @var $obj t41_Object_Model */ $data = new $class(null, null, clone $do); break; } $array[] = $data; $count++; } return $array; }
public function addElementFromProperty(AbstractProperty $property, $fname, $position = null) { $class = get_class($property); $class = substr($class, strrpos($class, '\\') + 1); switch ($class) { case 'EnumProperty': if ($property->getParameter('constraints.multiple') !== false) { $element = new Element\MultipleElement(); } else { $element = new Element\EnumElement(); } $element->setEnumValues($property->getValues()); break; case 'DateProperty': $element = new Element\DateElement(); break; case 'TimeProperty': $element = new Element\TimeElement(); break; case 'CurrencyProperty': $element = new Element\CurrencyElement(); break; case 'StringProperty': if ($property->getParameter('multilines')) { $element = new Element\TextElement(); } else { $element = new Element\FieldElement(); } break; case 'ObjectProperty': // @todo join this code and the one in CollectionProperty::getValue if ($property->getParameter('instanceof') == 't41\\ObjectModel\\MediaObject') { $element = new Element\MediaElement(); } else { $element = new Element\ListElement(); $element->setParameter('display', $property->getParameter('display')); $collection = new ObjectModel\Collection($property->getParameter('instanceof')); /* inject the condition that allows to find collection members */ if ($property->getParameter('keyprop')) { $collection->having($property->getParameter('keyprop'))->equals($property->getParent()); } if ($property->getParameter('depends')) { $element->setParameter('dependency', $property->getParameter('depends')); } if ($property->getParameter('morekeyprop')) { foreach ($property->getParameter('morekeyprop') as $value) { if (strstr($value, ' ') !== false) { // if value contains spaces, it's a pattern $parts = explode(' ', $value); if (count($parts) == 3) { if (strstr($parts[2], ',') !== false) { $parts[2] = explode(',', $parts[2]); } $collection->having($parts[0])->{$parts}[1]($parts[2]); } else { if (strstr($parts[1], ',') !== false) { $parts[1] = explode(',', $parts[1]); } $collection->having($parts[0])->equals($parts[1]); } } else { // default case, we expect the member to hold a property // with the same name and value as the current object $collection->having($value)->equals($property->getParent()->getProperty($value)->getValue()); } } } if ($property->getParameter('sorting')) { $element->setParameter('sorting', $property->getParameter('sorting')); } if ($property->getParameter('search')) { $element->setParameter('search', $property->getParameter('search')); } if ($property->getParameter('sdisplay')) { $element->setParameter('sdisplay', $property->getParameter('sdisplay')); } $element->setCollection($collection); } break; case 'CollectionProperty': $element = new Element\GridElement(); $element->setCollection($property->getValue()); break; case 'MediaProperty': $element = new Element\MediaElement(); break; default: $element = new Element\FieldElement(); break; } $element->setId(str_replace('.', '-', $fname)); $element->setTitle($property->getLabel()); $element->setDefaultValue($property->getDefaultValue()); $element->setHelp($property->getParameter('help')); if ($property instanceof MetaProperty) { $value = $property->getDisplayValue(); } else { $value = $property->getValue(); if ($value instanceof ObjectModel\ObjectUri) { $value = $value->__toString(); } else { if ($value instanceof ObjectModel\BaseObject) { $value = $value->getUri() ? $value->getUri()->__toString() : null; } } } $element->setValue($value); $constraints = $property->getParameter('constraints'); foreach (self::$constraintsList as $key) { if (isset($constraints[$key])) { $element->setConstraint($key, $constraints[$key] != '0' && empty($constraints[$key]) ? true : $constraints[$key]); } } // property uses a special format for which we should have a decorator if (isset($constraints['format'])) { $element->setDecorator($constraints['format']); } return $this->addElement($element, $position); }
/** * Returns an array of objects queried from the given t41_Object_Collection instance parameters * * The given collection is populated if it comes empty of members. * * In any other case, this method doesn't directly populate the collection. This action is under the responsability of * the caller. For example, the t41_Object_Collection::find() method takes care of it. * * @param \t41\ObjectModel\Collection $collection * @return array */ public function find(ObjectModel\Collection $collection, $returnCount = false) { $class = $collection->getDataObject()->getClass(); $table = $this->_getTableFromClass($class); if (!$table) { throw new Exception('BACKEND_MISSING_DBTABLE_PARAM'); } // primary key is either part of the mapper configuration or 'id' $pkey = $this->_mapper ? $this->_mapper->getPrimaryKey($class) : Backend::DEFAULT_PKEY; if (is_array($pkey)) { $composite = array(); /* @var $obj t41_Backend_Key */ foreach ($pkey as $obj) { $composite[] = sprintf('TRIM(%s)', $table . '.' . $obj->getName()); } $pkey = sprintf("%s", implode(',', $composite)); } else { $pkey = $table . '.' . $pkey; } $this->_connect(); /* @var $select Zend_Db_Select */ $select = $this->_ressource->select(); $select->from($table, $returnCount ? new \Zend_Db_Expr("COUNT(*) AS " . Backend::MAX_ROWS_IDENTIFIER) : $pkey); /* @var $condition t41_Condition */ foreach ($collection->getConditions() as $conditionArray) { $jtable = ''; $class = $collection->getDataObject()->getClass(); $condition = $conditionArray[0]; /* does condition contain another condition object ? */ if ($condition->isRecursive()) { while ($condition->isRecursive()) { $property = $condition->getProperty(); $parent = $property->getParent() ? $property->getParent()->getId() : $table; $condition = $condition->getCondition(); $jtable = $this->_mapper ? $this->_mapper->getDatastore($property->getParameter('instanceof')) : $property->getParameter('instanceof'); $jpkey = $this->_mapper ? $this->_mapper->getPrimaryKey($property->getParameter('instanceof')) : 'id'; $parentTable = $this->_mapper ? $this->_mapper->getDatastore($parent) : $parent; $join = sprintf("%s.%s = %s.%s", $parentTable, $jpkey, $jtable, $jpkey); $select->joinLeft($jtable, $join, array()); $class = $property->getParameter('instanceof'); } } $property = $condition->getProperty(); if ($property instanceof Property\ObjectProperty) { $jtable = $this->_mapper ? $this->_mapper->getDatastore($property->getParameter('instanceof')) : $property->getParameter('instanceof'); $leftkey = $this->_mapper ? $this->_mapper->propertyToDatastoreName($class, $property->getId()) : $property->getId(); $field = $rightkey = $this->_mapper ? $this->_mapper->getPrimaryKey($property->getParameter('instanceof')) : 'id'; $join = sprintf("%s.%s = %s.%s", $table, $leftkey, $jtable, $rightkey); $select->joinLeft($jtable, $join, array()); } else { $field = $property->getId(); if ($this->_mapper) { $field = $this->_mapper->propertyToDatastoreName($class, $field); } } /* if a join was performed, prefix current field with table name */ if ($jtable) { $field = $jtable . '.' . $field; } $statement = $this->_buildConditionStatement($field, $condition->getClauses()); switch ($conditionArray[1]) { case 'OR': $select->orWhere($statement); break; case 'AND': default: $select->where($statement); break; } } if ($returnCount != true) { foreach ($collection->getSortings() as $sorting) { if ($this->_mapper) { $class = $sorting[0]->getParent() ? $sorting[0]->getParent()->getId() : $collection->getDataObject()->getClass(); $field = $this->_mapper->propertyToDatastoreName($class, $sorting[0]->getId()); } else { $field = $sorting[0]->getId(); } $select->order($field, $sorting[1]); } $select->limit($collection->getBoundaryBatch(), $collection->getBoundaryOffset()); } //echo $select; $result = array(); $context = array('_table' => $table); try { $this->_connect(); $result = $this->_ressource->fetchAll($select); } catch (\Zend_Db_Exception $e) { $context['error'] = $e->getMessage(); } $this->_setLastQuery($select->__toString(), $select->getPart('where'), $context); if ($returnCount == true) { return $result[0][Backend::MAX_ROWS_IDENTIFIER]; } // convert array of primary keys to strings foreach ($result as $key => $val) { $result[$key] = implode(\t41\Mapper::VALUES_SEPARATOR, $val); } /* prepare base of object uri */ $uri = new ObjectModel\ObjectUri(); $uri->setBackendUri($this->_uri); $uri->setClass($collection->getDataObject()->getClass()); $uri->setUrl($this->_database . '/' . $table . '/'); return $this->_populateCollection($result, $collection, $uri); }
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); }
/** * Convert an array of t41_Condition instances into an array of preg_match patterns * AND is the only supported mode bewteen conditions right now * AND & OR mode are supported within the clauses of the same condition * * @todo implement AND mode between conditions * @param t41_Object_Collection $collection */ protected function _prepareConditionBlock(Collection $collection) { $array = array(); /* @var $condition t41_Condition */ foreach ($collection->getConditions() as $condition) { /* get property id in backend */ $key = $this->_mapper->propertyToDatastoreName($collection->getClass(), $condition[0]->getProperty()->getId()); $array[$key] = array(); $clauses = $condition[0]->getClauses(); $value = array(); foreach ($clauses as $clause) { if (!isset($mode)) { $mode = isset($clause['mode']) ? $clause['mode'] : Backend\Condition::MODE_AND; } $ops = $this->_matchOperator($clause['operator']); $prefix = $suffix = null; foreach ($ops as $op) { switch ($op) { case Backend\Condition::OPERATOR_BEGINSWITH: $prefix = '^'; break; case Backend\Condition::OPERATOR_ENDSWITH: $suffix = '$'; break; default: break; } } if (is_array($clause['value'])) { $value[] = $prefix . '[' . implode(",", $clause['value']) . ']' . $suffix; } else { $value[] = $prefix . $clause['value'] . $suffix; } } $array[$key][$mode] = $value; $mode = null; } $this->_conditionsBlock = $array; }
/** * Populate the given collection from the array of identifiers and the uri base * * @param array $ids * @param \t41\ObjectModel\Collection $collection * @param \t41\ObjectModel\ObjectUri $uriBase */ protected function _populateCollection(array $ids, ObjectModel\Collection $collection, ObjectModel\ObjectUri $uriBase) { $class = $collection->getDataObject()->getClass(); // populate array with relevant objects type $array = array(); if ($collection->getParameter('memberType') != ObjectModel::URI) { $do = clone $collection->getDataObject(); } foreach ($ids as $id) { $uri = clone $uriBase; $uri->setUrl($uri->getUrl() . $id)->setIdentifier($id); switch ($collection->getParameter('memberType')) { case ObjectModel::URI: $obj = $uri; break; case ObjectModel::MODEL: $obj = clone $do; $obj->setUri($uri); $this->read($obj); $obj = new $class(null, null, $obj); break; case ObjectModel::DATA: default: $obj = clone $do; $obj->setUri($uri); $this->read($obj); break; } $array[] = $obj; } return $array; }
/** * Return current ObjecModel\Collection instance handled by current instance * instant instanciation is performed if $_value is null or $force is true * * @param boolean $force * @return t41\ObjectModel\Collection */ public function getValue($force = false) { if (is_null($this->_value) || $force === true) { /* set a new Collection based on instanceof parameter value */ $this->_value = new ObjectModel\Collection($this->getParameter('instanceof')); $this->_value->setBoundaryBatch(-1); $this->_value->setParent($this->_parent); /* inject the condition that allows to find collection members */ if ($this->getParameter('keyprop')) { $this->_value->having($this->getParameter('keyprop'))->equals($this->_parent); } /* inject any other defined condition */ if ($this->getParameter('morekeyprop')) { foreach ($this->getParameter('morekeyprop') as $value) { if (strstr(trim($value), ' ') !== false) { // if value contains spaces, it's a pattern $parts = explode(' ', $value); if (count($parts) == 3) { if ($parts[2] == 'novalue') { $parts[2] = Condition::NO_VALUE; } if ($parts[2] == ObjectUri::IDENTIFIER) { $parts[2] = $this->_parent->getUri(); } if (substr($parts[2], 0, 1) == '%' && substr($parts[2], -1) == '%') { $prop = substr($parts[2], 1, strlen($parts[2]) - 2); if (($prop = $this->_parent->getProperty($prop)) !== false) { $parts[2] = $prop->getValue(); } } if (strstr($parts[2], ',') !== false) { $parts[2] = explode(',', $parts[2]); } $this->_value->having($parts[0])->{$parts}[1]($parts[2]); } else { if ($parts[1] == 'novalue') { $parts[1] = Condition::NO_VALUE; } if (substr($parts[1], 0, 1) == '%' && substr($parts[1], -1) == '%') { $prop = substr($parts[1], 1, strlen($parts[1]) - 2); if (($prop = $this->_parent->getProperty($prop)) !== false) { $parts[1] = $prop->getValue(); } } if (strstr($parts[1], ',') !== false) { $parts[1] = explode(',', $parts[1]); } $this->_value->having($parts[0])->equals($parts[1]); } } else { // default case, we expect the member to hold a property // with the same name and value as the current object if (($property = $this->_parent->getProperty($value)) === false) { throw new Exception(sprintf("keyprop value '%s' doesn't match any property of class '%s'", $value, $this->_parent->getClass())); } $this->_value->having($value)->equals($property->getValue()); } } } // set sorting if ($this->getParameter('sorting')) { foreach ($this->getParameter('sorting') as $key => $val) { if ($this->_value->getDataObject()->getRecursiveProperty($key) !== false) { $this->_value->setSorting(array($key, $val)); } else { Core::log(sprintf("Can't sort %s property with unknown property %s", $this->_id, $key), \Zend_Log::WARN); } } } // DON'T POPULATE THERE, IT IS DONE IMPLICITELY IN Collection::getMembers() //$this->_value->debug(); } return parent::getValue(); }
public function __construct($do = null, array $params = null) { parent::__construct('t41\\ObjectModel\\Collection\\StatsObject', $params); }