public function search(NodeQuery $dto) { $searchSafe = $dto->getParameter('SearchKeywords'); $searchRaw = $dto->getParameter('SearchKeywordsRaw') == null ? preg_replace("/[\\(\\)\\/\\*\\[\\]\\?]+/", '', $searchSafe) : $dto->getParameter('SearchKeywordsRaw'); $searchThreshold = $dto->getParameter('SearchThreshold'); $maxresults = $dto->getParameter('SearchMaxResults') != null ? $dto->getParameter('SearchMaxResults') : 500; $sortCol = $dto->getParameter('SearchSort') != null ? $dto->getParameter('SearchSort') : 'relevance'; $sortDir = $dto->getParameter('SearchSortDirection') != null ? $dto->getParameter('SearchSortDirection') : 'desc'; // $stopwords = array ('/\bof\b/','/\ba\b/','/\band\b/','/\bthe\b/'); // $s = str_replace('+','\+',$searchRaw); // $s = preg_replace($stopwords,' ',$s); //$s = preg_replace("/\s+/",' ',$s); $s = preg_replace("/\\s+/", ' ', $searchRaw); // execute query $rows = $this->executeIndexQuery($this->getReadConnection(), $dto, $s, $searchSafe, $maxresults); if (sizeof($rows) == 0) { return $dto; } $datascore = $this->columnScores(); $words = StringUtils::wordsTokenized($s); $scores = array(); $sorts = array(); $resultingNodeRefs = array(); $preg_s = preg_quote(str_replace(array('*', '+', '-'), '', $s), '/'); $ct = 0; foreach ($rows as $row) { $negative_match = FALSE; $found = array(); if ($ct++ > $maxresults) { break; } $score = $row['Score']; if (preg_match("/^{$preg_s}/i", $row['Title'])) { $score += 10; } elseif (sizeof($words) == 1 && preg_match("/\\b" . $preg_s . "/i", $row['Title'])) { $score += 5; } foreach ($datascore as $param => $val) { if (!empty($s) && !empty($row[$param]) && preg_match("/\\b" . $preg_s . "\\b/si", " " . $row[$param] . " ")) { $score += $val; } $m[$param] = 0; foreach ($words as $word) { if (preg_match("/^-(.{2,})/", $word, $m) && preg_match("/\\b{$m['1']}\\b/is", $row[$param])) { $negative_match = TRUE; } $preg_word = preg_quote($word, '/'); if (!empty($word) && preg_match("/\\b{$preg_word}\\b/si", " " . $row[$param] . " ")) { if (!isset($m[$param])) { $m[$param] = 0; } $m[$param]++; $found[$word] = 1; $score += $val / 2; } } if (isset($m[$param]) && $m[$param] == sizeof($words)) { $score += $val * 3; } } if (sizeof($found) > 0) { $score = $score * (sizeof($found) / sizeof($words)); } $rowElement = $this->ElementService->getByID($row['ElementID']); $rowSlug = $row['Slug']; $rowNodeRef = new NodeRef($rowElement, $rowSlug); $rawscores['' . $rowNodeRef] = $score; if (!$negative_match) { if (empty($searchThreshold) || $score > $searchThreshold) { $resultingNodeRefs['' . $rowNodeRef] = $rowNodeRef; $scores['' . $rowNodeRef] = $score; $sorts['' . $rowNodeRef] = $sortCol != 'relevance' ? $row[$sortCol] : $score; } } } reset($scores); if (sizeof($sorts) == 0) { return $dto; } if (strtolower($sortDir) == 'asc') { asort($sorts); } else { arsort($sorts); } // $this->Logger->debug($resultingNodeRefs); // $this->Logger->debug($sorts); $results = ArrayUtils::arraySortUsingKeys($resultingNodeRefs, array_keys($sorts)); $dto->setParameter('NodeRefs.in', $results); $dto->setParameter('NodeRefs.fullyQualified', true); $dto->setOrderBy('NodeRefs'); $results = $this->NodeService->findAll($dto)->getResults(); foreach ($results as $key => &$node) { $nodeRef = $node['NodeRef']; $node['SearchScore'] = $scores['' . $nodeRef]; // error_log($node['Title'].' ('.$node['SearchScore'].')'); } // $keys = array_map('strval', $sorts); $dto->setResults($results); return $dto; }
public function buildMySQLQuery(DatabaseInterface $db, $tableNodeRef, $table, $tableid, NodeQuery $nodeQuery, $orderObjects, $slugs, $ids = null) { $table = $db->quoteIdentifier($table); $element = $tableNodeRef->getElement(); $schema = $element->getSchema(); $q = new Query(); $q->SELECT('DISTINCT ' . $table . '.' . $tableid . ' as ID', true); $q->SELECT($table . '.Slug'); $mTableC = 1; if ($nodeQuery->hasParameter('OrderByInTag')) { $inParts = explode(' ', $nodeQuery->getParameter('OrderByInTag'), 2); $partials = PartialUtils::unserializeInPartials($inParts[0]); foreach ($partials as $partial) { if ($partial->getTagElement() && $partial->getTagSlug() && $partial->getTagRole()) { $tTable = $db->quoteIdentifier($this->NodeDBMeta->getInTagsTable($tableNodeRef)); $tClause = $this->NodeTagsDAO->getOutTagPartialClause($partial, $db, $tTable); $q->SELECT("OCondTable" . $mTableC . ".SortOrder as OSortOrder{$mTableC}"); $q->JOIN("INNER JOIN {$tTable} as OCondTable{$mTableC} " . str_replace($tTable, 'OCondTable' . $mTableC, " ON {$table}.{$tableid} = {$tTable}.{$tableid} AND {$tClause}")); $direction = array_key_exists(1, $inParts) ? $inParts[1] : 'ASC'; $q->ORDERBY('OCondTable' . $mTableC . '.SortOrder ' . $direction); $mTableC++; } else { throw new NodeException('Invalid OrderByInTag parameter, must be fully qualified TagPartial with element:slug#role'); } } } if ($nodeQuery->hasParameter('OrderByOutTag')) { $outParts = explode(' ', $nodeQuery->getParameter('OrderByOutTag'), 2); $partials = PartialUtils::unserializeOutPartials($outParts[0]); foreach ($partials as $partial) { if ($partial->getTagElement() && $partial->getTagSlug() && $partial->getTagRole()) { $tTable = $db->quoteIdentifier($this->NodeDBMeta->getOutTagsTable($tableNodeRef)); $tClause = $this->NodeTagsDAO->getOutTagPartialClause($partial, $db, $tTable); $q->SELECT("OCondTable" . $mTableC . ".SortOrder as OSortOrder{$mTableC}"); $q->JOIN("INNER JOIN {$tTable} as OCondTable{$mTableC} " . str_replace($tTable, 'OCondTable' . $mTableC, " ON {$table}.{$tableid} = {$tTable}.{$tableid} AND {$tClause}")); $direction = array_key_exists(1, $outParts) ? $outParts[1] : 'ASC'; $q->ORDERBY('OCondTable' . $mTableC . '.SortOrder ' . $direction); $mTableC++; } else { throw new NodeException('Invalid OrderByOutTag parameter, must be fully qualified TagPartial with element:slug#role'); } } } $mTableC = 1; foreach ($orderObjects as $orderObject) { $column = $orderObject->getColumn(); $direction = $orderObject->getDirection(); //if(!in_array($column, array('ID', 'Slug'))) //{ if ($orderObject->isMeta()) { $partial = $orderObject->getOrderByMetaPartial(); $datatype = $orderObject->getOrderByMetaDataType(); $mTable = $this->NodeDBMeta->getMetaTable($tableNodeRef, $datatype); $mTableAlias = $db->quoteIdentifier($mTable . $mTableC++); $mTable = $db->quoteIdentifier($mTable); $mClause = $this->NodeMetaDAO->getMetaPartialClause(new MetaPartial($partial), $datatype, $db, $mTableAlias); $q->SELECT($mTableAlias . '.' . $datatype . 'Value as ' . $column); $q->JOIN('LEFT JOIN ' . $mTable . ' as ' . $mTableAlias . ' ON ' . $table . '.' . $tableid . ' = ' . $mTableAlias . '.' . $tableid . ' AND ' . $mClause); $q->ORDERBY("{$column} {$direction}"); } else { if ($orderObject->isDirectional()) { if (!in_array($orderObject->getColumn(), array('Title', 'Slug', 'SortOrder', 'ActiveDate', 'CreationDate', 'ModifiedDate', 'TreeID'))) { throw new NodeException('Invalid ordering column [' . $orderObject->getColumn() . '], must be Title, Slug, SortOrder, ActiveDate, CreationDate, ModifiedDate, TreeID, or #meta-id'); } if ($orderObject->getColumn() != 'Slug') { $q->SELECT($table . '.' . $orderObject->getColumn()); } $q->ORDERBY("{$table}.{$column} {$direction}"); } } //} } // Add if clause 2/1/2010 by Craig .. Mysql seems to be doing it's job without this secondary sort. if (empty($orderObjects)) { $q->ORDERBY('ID DESC'); } $q->FROM($table); // ID if (!empty($ids)) { if (count($ids) > 1) { $q->WHERE("{$table}.{$tableid} IN (" . $db->joinQuote($ids) . ")"); } else { if (isset($ids[0])) { $q->WHERE("{$table}.{$tableid} = {$db->quote($ids[0])}"); } } } // Slug if (!empty($slugs)) { if (count($slugs) > 1) { $q->WHERE("{$table}.Slug IN (" . $db->joinQuote($slugs) . ")"); } else { if (isset($slugs[0])) { $q->WHERE("{$table}.Slug = {$db->quote($slugs[0])}"); } } } // AlphaIndex if (($alpha = $nodeQuery->getParameter('Title.firstChar')) != null) { if (strtolower($alpha) == '#') { $q->WHERE("(ASCII(LOWER(LEFT({$table}.Title, 1))) < 65) OR (ASCII(LOWER(LEFT({$table}.Title, 1))) BETWEEN 90 AND 97) OR (ASCII(LOWER(LEFT({$table}.Title, 1))) > 122)"); } else { $q->WHERE("LOWER(LEFT({$table}.Title, 1)) = {$db->quote(strtolower($alpha))}"); } } // Title $this->DTOHelper->buildEqualsFilter($db, $q, $nodeQuery, 'Title.ieq', "{$table}.Title"); $this->DTOHelper->buildReplaceFilter($db, $q, $nodeQuery, 'Title.eq', "BINARY {$table}.Title = ?"); // TitleSearch $this->DTOHelper->buildReplaceFilter($db, $q, $nodeQuery, 'Title.like', "{$table}.Title LIKE ?", '%#s%'); // ParentTreeID $this->DTOHelper->buildReplaceFilter($db, $q, $nodeQuery, 'TreeID.childOf', "{$table}.TreeID LIKE ?", "#s%"); // TreeID $this->DTOHelper->buildEqualsFilter($db, $q, $nodeQuery, 'TreeID.eq', "{$table}.TreeID"); // select node by Tree depth (or limit existing selection) if (($treeDepth = $nodeQuery->getParameter('TreeID.depth')) !== null) { $actualDepth = $treeDepth * 4; $q->orWhere("LENGTH({$table}.TreeID) = {$db->quote($actualDepth)}"); } if (($treeid = $nodeQuery->getParameter('TreeID.parentOf')) != null) { $depth = strlen($treeid) / 4; if ($depth == 1) { $q->WHERE('1 = 0'); } else { for ($i = 1; $i < $depth; ++$i) { $ptreeid = substr($treeid, 0, $i * 4); $q->ORWHERE("{$table}.TreeID = {$db->quote($ptreeid)}"); } } } // ActiveAfter // ActiveBefore $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'ActiveDate.after', "{$table}.ActiveDate > ?"); $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'ActiveDate.before', "{$table}.ActiveDate <= ?"); $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'ActiveDate.start', "{$table}.ActiveDate >= ?", 0, 0, 0); $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'ActiveDate.end', "{$table}.ActiveDate <= ?", 23, 59, 59); // CreatedAfter // CreatedBefore $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'CreationDate.after', "{$table}.CreationDate > ?"); $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'CreationDate.before', "{$table}.CreationDate <= ?"); $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'CreationDate.start', "{$table}.CreationDate >= ?", 0, 0, 0); $this->DTOHelper->buildDateReplaceFilter($db, $q, $nodeQuery, 'CreationDate.end', "{$table}.CreationDate <= ?", 23, 59, 59); // Status if (($status = $nodeQuery->getParameter('Status.eq')) != null) { switch ($status) { case 'published': $q->WHERE("{$table}.Status = 'published'"); break; case 'draft': $q->WHERE("{$table}.Status = 'draft'"); break; case 'deleted': $q->WHERE("{$table}.Status = 'deleted'"); break; default: $q->WHERE("{$table}.Status != 'deleted'"); break; } } else { if ($nodeQuery->getParameter('Status.isActive') !== null && StringUtils::strToBool($nodeQuery->getParameter('Status.isActive')) == true) { $now = $this->DateFactory->newStorageDate(); $q->WHERE("{$table}.Status = 'published' AND {$table}.ActiveDate < {$db->quote($now)}"); } else { if ($nodeQuery->getParameter('Status.all') == null || StringUtils::strToBool($nodeQuery->getParameter('Status.all')) == false) { $q->WHERE("{$table}.Status != 'deleted'"); } } } $metaParams = $this->NodesHelper->getMetaFilters($nodeQuery); $tablect = 0; foreach ($metaParams as $mArgs) { list($full, $name, $operator, $value) = $mArgs; $def = $schema->getMetaDef($name); $datatype = $def->Datatype; $mTable = $db->quoteIdentifier($this->NodeDBMeta->getMetaTable($tableNodeRef, $datatype)); $clause = ' ' . $db->quoteIdentifier($mTable) . '.Name = ' . $db->quote($name) . " AND "; if ($datatype == 'flag') { throw new NodeException('Unable to run meta clause on flag datatype'); } if (in_array($datatype, array('text', 'blob', 'mediumtext', 'mediumblob'))) { throw new NodeException('Query arguments with #' . $name . ' are not supported'); } switch ($operator) { case 'eq': if ($datatype == 'varchar') { $clause .= " BINARY {$db->quoteIdentifier($mTable)}.{$datatype}Value = {$db->quote($value)}"; } else { $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value = {$db->quote($value)}"; } break; case 'ieq': $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value = {$db->quote($value)}"; break; case 'like': $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value LIKE " . $db->quote('%' . $value . '%'); break; case 'before': $d = $this->DateFactory->newLocalDate($value); $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value <= {$db->quote($d)}"; break; case 'after': $d = $this->DateFactory->newLocalDate($value); $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value > {$db->quote($d)}"; break; case 'start': $d = $this->DateFactory->newLocalDate($value); $d->setTime(0, 0, 0); $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value >= {$db->quote($d)}"; break; case 'end': $d = $this->DateFactory->newLocalDate($value); $d->setTime(23, 59, 59); $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value <= {$db->quote($d)}"; break; case 'notEq': if ($datatype == 'varchar') { $clause .= " BINARY {$db->quoteIdentifier($mTable)}.{$datatype}Value != {$db->quote($value)}"; } else { $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value != {$db->quote($value)}"; } break; case 'lessThan': $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value < {$db->quote($value)}"; break; case 'lessThanEq': $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value <= {$db->quote($value)}"; break; case 'greaterThan': $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value > {$db->quote($value)}"; break; case 'greaterThanEq': $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value >= {$db->quote($value)}"; break; /* * case insensitive comparison for #meta.in filtering. */ /* * case insensitive comparison for #meta.in filtering. */ case 'in': $inValues = explode(',', $value); if (count($inValues) > 1) { $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value IN ({$db->joinQuote($inValues)})"; } else { if ($datatype == 'varchar') { $clause .= " BINARY {$db->quoteIdentifier($mTable)}.{$datatype}Value = {$db->quote($value)}"; } else { $clause .= " {$db->quoteIdentifier($mTable)}.{$datatype}Value = {$db->quote($value)}"; } } break; } $tablect++; $q->JOIN("INNER JOIN {$mTable} as CondTable{$tablect} " . str_replace($mTable, 'CondTable' . $tablect, " ON {$table}.{$tableid} = {$mTable}.{$tableid} AND {$clause}")); } // IncludesMeta // if(($im = $nodeQuery->getParameter('Meta.exist')) != NULL ) { // $metas = PartialUtils::unserializeMetaPartials($im); // $conditions = array(); // foreach($metas as $partial) { // $s = $schema->getMetaDef($partial->getMetaName()); // // $datatype = $s->Datatype; // // $mTable = $db->quoteIdentifier($this->NodeDBMeta->getMetaTable($tableNodeRef, $datatype)); // $mClause = $this->NodeMetaDAO->getMetaPartialClause($partial, $datatype, $db, $mTable); // // $conditions[] = "{$table}.{$tableid} IN // (SELECT {$mTable}.{$tableid} // FROM {$mTable} // WHERE ".$mClause.")"; //// $conditions[] = "EXISTS (SELECT 1 FROM {$this->model->getMetaTable()} //// WHERE {$this->model->getMetaTable()}.{$this->model->getTableID()} = {$table}.{$this->model->getTableID()} //// AND ".$partial->getTagClause($this->model->getMetaTable()).")"; // } // if (!empty($conditions)) { // $q->WHERE(join(' OR ', $conditions)); // } // // } // IncludesAllMeta if (($iam = $nodeQuery->getParameter('Meta.exist')) != NULL) { $metas = PartialUtils::unserializeMetaPartials($iam); foreach ($metas as $partial) { $s = $schema->getMetaDef($partial->getMetaName()); $datatype = $s->Datatype; $mTable = $db->quoteIdentifier($this->NodeDBMeta->getMetaTable($tableNodeRef, $datatype)); $mClause = $this->NodeMetaDAO->getMetaPartialClause($partial, $datatype, $db, $mTable); $tablect++; $q->JOIN("INNER JOIN {$mTable} as CondTable{$tablect} " . str_replace($mTable, 'CondTable' . $tablect, " ON {$table}.{$tableid} = {$mTable}.{$tableid} AND {$mClause}")); // $q->WHERE("{$table}.{$tableid} IN // (SELECT {$mTable}.{$tableid} // FROM {$mTable} // WHERE ".$mClause.")"); // $this->db->WHERE("EXISTS (SELECT 1 FROM {$this->model->getMetaTable()} // WHERE {$this->model->getMetaTable()}.{$this->model->getTableID()} = {$table}.{$this->model->getTableID()} // AND ".$partial->getTagClause($this->model->getMetaTable()).")"); } } // IncludesOutTags // if(($iot = $nodeQuery->getParameter('IncludesOutTags')) != NULL ) { // $tags = PartialUtils::unserializeOutPartials($iot); // $conditions = array(); // foreach($tags as $partial) { // $tTable = $db->quoteIdentifier($this->NodeDBMeta->getOutTagsTable($tableNodeRef)); // // // TODO: need to support aspects // // TODO: convert OR clauses into multiple unions // // $tClause = $this->NodeTagsDAO->getOutTagPartialClause($partial, $tableNodeRef->getSite(), $db, $tTable); // // $conditions[] = "{$table}.{$tableid} IN // (SELECT {$tTable}.{$tableid} // FROM {$tTable} // WHERE {$tClause})"; //// $conditions[] = "EXISTS (SELECT 1 FROM {$this->model->getTagsTable()} t2 //// INNER JOIN tags2 ON t2.tagid = tags2.tagid //// WHERE {$table}.{$this->model->getTableID()} = t2.{$this->model->getTableID()} AND //// ".$partial->getTagClause("tags2").")"; // } // if (!empty($conditions)) { // $q->WHERE(join(' OR ', $conditions)); // } // // } // IncludesAllOutTags if (($iaot = $nodeQuery->getParameter('OutTags.exist')) != NULL) { $tags = PartialUtils::unserializeOutPartials($iaot); foreach ($tags as $partial) { $tTable = $db->quoteIdentifier($this->NodeDBMeta->getOutTagsTable($tableNodeRef)); $tClause = $this->NodeTagsDAO->getOutTagPartialClause($partial, $db, $tTable); $tablect++; $q->JOIN("INNER JOIN {$tTable} as CondTable{$tablect} " . str_replace($tTable, 'CondTable' . $tablect, " ON {$table}.{$tableid} = {$tTable}.{$tableid} AND {$tClause}")); // $q->WHERE( "{$table}.{$tableid} IN // (SELECT {$tTable}.{$tableid} // FROM {$tTable} // WHERE {$tClause})" ); // $this->db->WHERE("EXISTS (SELECT 1 FROM {$this->model->getTagsTable()} t2 // INNER JOIN tags2 ON t2.tagid = tags2.tagid // WHERE {$table}.{$this->model->getTableID()} = t2.{$this->model->getTableID()} AND // ".$partial->getTagClause("tags2").")"); } } // IncludesInTags // if(($iit = $nodeQuery->getParameter('IncludesInTags')) != NULL ) { // $tags = PartialUtils::unserializeInPartials($iit); // $conditions = array(); // foreach($tags as $partial) { // $tTable = $db->quoteIdentifier($this->NodeDBMeta->getInTagsTable($tableNodeRef)); // $tClause = $this->NodeTagsDAO->getInTagPartialClause($partial, $tableNodeRef->getElement(), $tableNodeRef->getSite(), $db, $tTable); // // $conditions[] = "{$table}.{$tableid} IN // (SELECT {$tTable}.{$tableid} // FROM {$tTable} // WHERE {$tClause})"; //// $conditions[] = "EXISTS (SELECT 1 FROM {$this->model->getTagsTable()} t2 //// INNER JOIN tags2 ON t2.tagid = tags2.tagid //// WHERE {$table}.{$this->model->getTableID()} = t2.{$this->model->getTableID()} AND //// ".$partial->getTagClause("tags2").")"; // } // if (!empty($conditions)) { // $q->WHERE(join(' OR ', $conditions)); // } // // } // IncludesAllInTags if (($iait = $nodeQuery->getParameter('InTags.exist')) != NULL) { $tags = PartialUtils::unserializeInPartials($iait); foreach ($tags as $partial) { $tTable = $db->quoteIdentifier($this->NodeDBMeta->getInTagsTable($tableNodeRef)); $tClause = $this->NodeTagsDAO->getInTagPartialClause($partial, $tableNodeRef->getElement(), $db, $tTable); $tablect++; $q->JOIN("INNER JOIN {$tTable} as CondTable{$tablect} " . str_replace($tTable, 'CondTable' . $tablect, " ON {$table}.{$tableid} = {$tTable}.{$tableid} AND {$tClause}")); // // $q->WHERE( "{$table}.{$tableid} IN // (SELECT {$tTable}.{$tableid} // FROM {$tTable} // WHERE {$tClause})" ); // $this->db->WHERE("EXISTS (SELECT 1 FROM {$this->model->getTagsTable()} t2 // INNER JOIN tags2 ON t2.tagid = tags2.tagid // WHERE {$table}.{$this->model->getTableID()} = t2.{$this->model->getTableID()} AND // ".$partial->getTagClause("tags2").")"); } } return $q; }
public function getOrderObjects(NodeQuery $nodeQuery, $ignoreNone = false) { $nodeRefs = $nodeQuery->getParameter('NodeRefs.normalized'); $firstElement = current($nodeRefs)->getElement(); $offset = $nodeQuery->getOffset() != null ? $nodeQuery->getOffset() : 0; $limit = $nodeQuery->getLimit(); // ORDER BYS $arr = array('Title', 'ActiveDate', 'CreationDate', 'SortOrder', 'TreeID'); $default = $firstElement->getDefaultOrder(); if (empty($default)) { $default = 'ActiveDate DESC'; } if (count($order = explode(' ', $default)) == 2) { $field = $order[0]; $direction = $order[1]; $defaultSorts = array($field => $direction); } $dtoSorts = $nodeQuery->getOrderBys(); if ($dtoSorts == null && !$ignoreNone) { $dtoSorts = $defaultSorts; } $diff = array_diff(array_keys($dtoSorts), array_keys($arr)); $merged = array_merge($diff, $arr); $sorts = array_unique($merged); $orderObjects = array(); $metaCount = 1; foreach ($sorts as $name => $column) { if (is_int($name)) { $name = $column; } if (isset($dtoSorts[$name])) { $direction = $dtoSorts[$name]; if (strcasecmp($name, 'NodeRefs') === 0) { //$dtoParameterToSortBy = $direction; $nodeRefs = array_slice($nodeRefs, 0, $limit + $offset); $orderObjects[] = new NodeOrderBy('NodeRef', $nodeRefs); } else { if (strpos($name, '#') !== false) { //$orderByMeta = new MetaPartial($name); $name = substr($name, strpos($name, '#') + 1); if ($firstElement->getSchema()->hasMetaDef($name)) { $s = $firstElement->getSchema()->getMetaDef($name); $datatype = $s->Datatype; $column = "{$datatype}Value{$metaCount}"; $metaCount++; $orderObjects[] = new NodeOrderBy($column, $direction, $name, $datatype); } } else { $orderObjects[] = new NodeOrderBy($column, $direction); } } } } return $orderObjects; }
public function normalizeNodeQuery(NodeQuery $nodeQuery) { if ($nodeQuery->getParameter('NodeQuery.normalized') == null) { $this->Events->trigger('Node.normalizeQuery', $nodeQuery); $nodeQuery->setParameter('NodeQuery.normalized', true); } // // if($nodeQuery->hasParameter('NodePartials.eq') && $nodeQuery->hasParameter('NodeRefs.normalized') && $nodeQuery->hasParameter('NodeRefs.fullyQualified')) // return $nodeQuery; if (!$nodeQuery->hasParameter('NodePartials.eq')) { $nodeQuery->setParameter('NodePartials.eq', new NodePartials($nodeQuery->getParameter('Meta.select'), $nodeQuery->getParameter('OutTags.select'), $nodeQuery->getParameter('InTags.select'))); } // NODEREFS if ($nodeQuery->hasParameter('NodeRefs.in')) { $noderefsin = $nodeQuery->getParameter('NodeRefs.in'); if (is_string($noderefsin)) { $nodeRefsIn = array(); $noderefsin = explode(',', $noderefsin); foreach ($noderefsin as $noderefstr) { $noderef = $this->parseFromString(trim($noderefstr)); if (!empty($noderef)) { $nodeRefsIn[] = $noderef; } } } else { $nodeRefsIn = $noderefsin; } $nodeQuery->setParameter('NodeRefs.normalized', $nodeRefsIn); if (!$nodeQuery->hasParameter('NodeRefs.fullyQualified')) { $nodeQuery->setParameter('NodeRefs.fullyQualified', true); } return $nodeQuery; // return array($nodeRefsIn, $nodePartials, // $nodeQuery->hasParameter('NodeRefs.fullyQualified')?$nodeQuery->getParameter('NodeRefs.fullyQualified'):true); } $nodeRefs = array(); if (!$nodeQuery->hasParameter('Elements.in')) { throw new NodeException('Unable to query nodes without Elements.in specified'); } $elementSlugs = $nodeQuery->getParameter('Elements.in'); if (!is_array($elementSlugs)) { $elementSlugs = StringUtils::smartExplode($elementSlugs); } // $firstElement = null; $sites = array(); if ($nodeQuery->hasParameter('Sites.in')) { $siteSlugs = $nodeQuery->getParameter('Sites.in'); if (!is_array($siteSlugs)) { $siteSlugs = StringUtils::smartExplode($siteSlugs); } $sites = $this->SiteService->multiGetBySlug($siteSlugs); } $elements = array(); foreach ($elementSlugs as $ek => $elementSlug) { if (substr($elementSlug, 0, 1) == '@') { $aspectSlug = substr($elementSlug, 1); $aspect = $this->AspectService->getBySlug($aspectSlug); if ($aspect->ElementMode == 'one' || $aspect->ElementMode == 'anchored') { $elements = array_merge($elements, (array) $this->ElementService->findAllWithAspect($aspectSlug)); unset($elementSlugs[$ek]); } else { if (!empty($sites)) { foreach ((array) $sites as $site) { $elements = array_merge($elements, (array) $this->ElementService->findAllWithAspect($aspectSlug, $site->getSlug())); } } else { $elements = array_merge($elements, (array) $this->ElementService->findAllWithAspect($aspectSlug)); } } } else { $elements[] = $this->ElementService->getBySlug($elementSlug); } } if (empty($elements)) { throw new NoElementsException('No elements found for expression [' . $nodeQuery->getParameter('Elements.in') . '].'); } $allFullyQualified = false; // $allSites = array(); // if($nodeQuery->hasParameter('Sites.in')) { // $siteSlugs = $nodeQuery->getParameter('Sites.in'); // if(!is_array($siteSlugs)) // $siteSlugs = StringUtils::smartExplode($siteSlugs); // // $allSites = $this->SiteService->multiGetBySlug($siteSlugs); // } else if ($nodeQuery->hasParameter('SiteIDs.in')) { // $siteIDs = $nodeQuery->getParameter('SiteIDs.in'); // if(!is_array($siteIDs)) // $siteIDs = StringUtils::smartExplode($siteIDs); // // foreach($siteIDs as $siteID) // $allSites[] = $this->SiteService->getByID($siteID); // // } else { // $allSites = $this->SiteService->findAll()->getResults(); // } foreach ($elements as $element) { // if($element->isAnchored() && $nodeQuery->getParameter('Elements.ignoreAnchoredSite') == null){ // $sites = array($element->getAnchoredSite()); // } else { // $sites = $allSites; // } // foreach($sites as $site) // { if (($slugs = $nodeQuery->getParameter('Slugs.in')) != null) { if (!is_array($slugs)) { $slugs = StringUtils::smartExplode($slugs); } $allFullyQualified = true; foreach ($slugs as $slug) { $nodeRefs[] = new NodeRef($element, SlugUtils::createSlug($slug, true)); } } else { $nodeRefs[] = new NodeRef($element); } // } } $nodeQuery->setParameter('NodeRefs.normalized', $nodeRefs); //if(!$nodeQuery->hasParameter('NodeRefs.fullyQualified')) $nodeQuery->setParameter('NodeRefs.fullyQualified', $allFullyQualified); //return array($nodeRefs, $nodePartials, $allFullyQualified); return $nodeQuery; }