public function query(Query $query)
{
// TODO handle bind variables
$querystring = $query->getStatement();
$limit = $query->getLimit();
$offset = $query->getOffset();
$language = $query->getLanguage();
switch ($language) {
case QueryInterface::JCR_JQOM:
// for JQOM, fall through to SQL2
// for JQOM, fall through to SQL2
case QueryInterface::JCR_SQL2:
$ns = '';
$langElement = 'JCR-SQL2';
break;
case QueryInterface::XPATH:
$langElement = 'dcr:xpath';
$ns = 'xmlns:dcr="http://www.day.com/jcr/webdav/1.0"';
break;
case QueryInterface::SQL:
$langElement = 'dcr:sql';
$ns = 'xmlns:dcr="http://www.day.com/jcr/webdav/1.0"';
break;
default:
// this should be impossible as we check on creation already
throw new InvalidQueryException("Unsupported query language: {$language}");
}
$body = '<D:searchrequest ' . $ns . ' xmlns:D="DAV:"><' . $langElement . '><![CDATA[' . $querystring . ']]></' . $langElement . '>';
if (null !== $limit || null !== $offset) {
$body .= '<D:limit>';
if (null !== $limit) {
$body .= '<D:nresults>' . (int) $limit . '</D:nresults>';
}
if (null !== $offset) {
$body .= '<offset>' . (int) $offset . '</offset>';
}
$body .= '</D:limit>';
}
$body .= '</D:searchrequest>';
$path = $this->addWorkspacePathToUri('/');
$request = $this->getRequest(Request::SEARCH, $path);
$request->setBody($body);
$rawData = $request->execute();
$dom = new DOMDocument();
$dom->loadXML($rawData);
$rows = array();
foreach ($dom->getElementsByTagName('response') as $row) {
$columns = array();
foreach ($row->getElementsByTagName('column') as $column) {
$sets = array();
foreach ($column->childNodes as $childNode) {
if ('dcr:value' == $childNode->tagName) {
$value = $this->getDcrValue($childNode);
// TODO if this bug is fixed, spaces may be urlencoded instead of the escape sequence: https://issues.apache.org/jira/browse/JCR-2997
// the following line fails for nodes with "_x0020 " in their name, changing that part to " x0020_"
// other characters like < and > are urlencoded, which seems to be handled by dom already.
if (is_string($value)) {
$value = str_replace('_x0020_', ' ', $value);
}
} else {
$value = $childNode->nodeValue;
}
$sets[$childNode->tagName] = $value;
}
if (!isset($sets['dcr:value'])) {
$sets['dcr:value'] = null;
}
$columns[] = $sets;
}
$rows[] = $columns;
}
return $rows;
}