/** * Returns the last node on a path. If the path does not exist * in the the tree, creates the nodes if $create is set to true. * Path is given in an array. * @param array $path * @return false|epQueryPathNode * @throws epExceptionQueryPath */ protected function &_obtainNodeByPath(&$path, $create = true) { // get the first non-empty piece in path while (!($piece = array_shift($path)) && $path) { } // this is the end if piece is empty if (!$piece) { return $this; } // check if piece is a child if ($child =& $this->getChild($piece)) { // if so, recursion on child return $child->_obtainNodeByPath($path, $create); } // check if we need to create path if it does not exist if (!$create) { return self::$false; } // get the class and field map for this node $fm = null; if ($this->isRoot()) { $cm = $this->getMap(); } else { $fm = $this->getMap(); $cm = $this->_em()->getClassMap($fm->getClass()); } // // 1. if the node is a many-valued relationship, then create an contained root node // if ($fm && !$fm->isPrimitive() && $fm->isMany()) { // create a child - an alias root if (!($child =& new epQueryPathRoot($cm, $piece, epQueryPathRoot::CONTAINED))) { throw new epExceptionQueryPath("cannot create a node for '{$piece}'"); return false; } // add child into this node $this->addChild($child); // recursion on child return $child->_obtainNodeByPath($path, $create); } // // 2. otherwise, create a field node // // get field map for the piece if ($piece == 'oid') { $fm = new epFieldMapPrimitive('oid', epFieldMap::DT_INTEGER, array(), $cm); $fm->setColumnName($cm->getOidColumn()); } else { // get field map if (!($fm =& $cm->getField($piece))) { throw new epExceptionQueryPath("no field map for '{$piece}'"); return self::$false; } } // create a child if (!($child =& new epQueryPathField($fm))) { throw new epExceptionQueryPath("cannot create a node for '{$piece}'"); return self::$false; } // add it into parent $this->addChild($child); // recursion on child return $child->_obtainNodeByPath($path, $create); }
/** * Actually processes a variable by consulting epManager * @param string $alias the starting alias for a variable * @param array $parts the array of attributes for the variable * @return false|array * @throws epExceptionQueryBuilder */ protected function _processVariable($node, $alias, $parts) { // get class name for alias if (!($class = $this->aliases[$alias])) { throw new epExceptionQueryBuilder($this->_e('Class for alias [' . $alias . '] not found', $node)); return false; } // get class map if (!($cm = $this->em->getMap($class))) { throw new epExceptionQueryBuilder($this->_e('Class [' . $class . '] not found', $node)); return false; } // go through each var $fms = array(); foreach ($parts as $part) { // make sure we have class map if (!$cm) { throw new epExceptionQueryBuilder($this->_e('Variable [' . $class . '::' . $part . '] not existing', $node)); return false; } // fake a fieldmap if part is 'oid' if ($part == 'oid') { $fm = new epFieldMapPrimitive('oid', epFieldMap::DT_INTEGER, array(), $cm); $fm->setColumnName($cm->getOidColumn()); } else { if (!($fm = $cm->getField($part))) { throw new epExceptionQueryBuilder($this->_e('Variable [' . $class . '::' . $part . '] not existing', $node)); return false; } } // collect this field map $fms[] = $fm; // must be a relationship field map $cm = null; if ($fm instanceof epFieldMapRelationship) { $cm = $this->em->getClassMap($fm->getClass()); $class = $cm->getName(); } } return $fms; }