Example #1
0
 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();
     }
 }
Example #2
0
 /**
  * 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;
 }
Example #3
0
 /**
  * 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';
     }
 }
Example #4
0
 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();
 }
Example #5
0
 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;
 }
Example #6
0
 /**
  * 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);
 }
Example #7
0
 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;
 }
Example #8
0
 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);
 }
Example #9
0
 /**
  * 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);
 }
Example #10
0
 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);
 }
Example #11
0
 /**
  * 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;
 }
Example #12
0
 /**
  * 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;
 }
Example #13
0
 /**
  * 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();
 }
Example #14
0
 public function __construct($do = null, array $params = null)
 {
     parent::__construct('t41\\ObjectModel\\Collection\\StatsObject', $params);
 }