Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

query translated children #409

Merged
merged 1 commit into from
Feb 28, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions lib/Doctrine/ODM/PHPCR/Query/Builder/AbstractNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ abstract public function getCardinalityMap();
* @see addChild
*
* @param AbstractNode $node
*
* @return AbstractNode
*/
public function setChild(AbstractNode $node)
Expand Down Expand Up @@ -196,7 +197,7 @@ public function getNext()
* Note that this will returned a flattened version
* of the classes type => children map.
*
* @return array AbstractNode[]
* @return AbstractNode[]
*/
public function getChildren()
{
Expand All @@ -213,7 +214,7 @@ public function getChildren()
/**
* Return children of specified type.
*
* @return array AbstractNode[]
* @return AbstractNode[]
*/
public function getChildrenOfType($type)
{
Expand All @@ -232,8 +233,9 @@ public function removeChildrenOfType($type)
/**
* Return child of node, there must be exactly one child of any type.
*
* @return AbstractNode[]
*
* @throws OutOfBoundsException if there are more than one or none
* @return array AbstractNode[]
*/
public function getChild()
{
Expand Down Expand Up @@ -261,8 +263,9 @@ public function getChild()
*
* Note: This does not take inheritance into account.
*
* @return AbstractNode[]
*
* @throws OutOfBoundsException if there are more than one or none
* @return array AbstractNode[]
*/
public function getChildOfType($type)
{
Expand Down Expand Up @@ -296,7 +299,6 @@ public function getChildOfType($type)
* types.
*
* @throws OutOfBoundsException
* @return void
*/
public function validate()
{
Expand Down
89 changes: 58 additions & 31 deletions lib/Doctrine/ODM/PHPCR/Query/Builder/BuilderConverterPhpcr.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ class BuilderConverterPhpcr
*/
protected $sourceDocumentNodes;

/**
* Used to keep track of which sources are used with translated fields, to
* tell the translation strategy to update if needed.
*
* @var array keys are the alias, value is true
*/
protected $aliasWithTranslatedFields;

/**
* @var string|null
*/
Expand Down Expand Up @@ -100,23 +108,34 @@ protected function getMetadata($alias)
}

/**
* Return the PHPCR property name for the given ODM document property name
* Return the PHPCR property name and alias for the given ODM document
* property name and query alias.
*
* The alias might change if this is a translated field and the strategy
* needs to do a join to get in the translation.
*
* @param string $alias - Name of alias (corresponds to document source)
* @param string $odmField - Name of ODM document property
* @param string $originalAlias As specified in the query source.
* @param string $odmField Name of ODM document property.
*
* @return string
* @return array first element is the real alias to use, second element is
* the property name
*/
protected function getPhpcrProperty($alias, $odmField)
protected function getPhpcrProperty($originalAlias, $odmField)
{
$fieldMeta = $this->getMetadata($alias)->getField($odmField);
$property = $fieldMeta['property'];
$fieldMeta = $this->getMetadata($originalAlias)->getField($odmField);
$propertyName = $fieldMeta['property'];

if (!empty($this->translator[$alias]) && !empty($fieldMeta['translated'])) {
$property = $this->translator[$alias]->getTranslatedPropertyName($this->locale, $fieldMeta['property']);
if (empty($fieldMeta['translated'])
|| empty($this->translator[$originalAlias])
) {
return array($originalAlias, $propertyName);
}

return $property;
$propertyPath = $this->translator[$originalAlias]->getTranslatedPropertyPath($originalAlias, $fieldMeta['property'], $this->locale);

$this->aliasWithTranslatedFields[$originalAlias] = true;

return $propertyPath;
}

/**
Expand All @@ -133,6 +152,7 @@ protected function getPhpcrProperty($alias, $odmField)
*/
public function getQuery(QueryBuilder $builder)
{
$this->aliasWithTranslatedFields = array();
$this->locale = $builder->getLocale();
if (null === $this->locale && $this->dm->hasLocaleChooserStrategy()) {
$this->locale = $this->dm->getLocaleChooserStrategy()->getLocale();
Expand Down Expand Up @@ -199,6 +219,10 @@ public function getQuery(QueryBuilder $builder)
}
}

foreach (array_keys($this->aliasWithTranslatedFields) as $alias) {
$this->translator[$alias]->alterQueryForTranslation($this->qomf, $this->from, $this->constraint, $alias, $this->locale);
}

$phpcrQuery = $this->qomf->createQuery(
$this->from,
$this->constraint,
Expand Down Expand Up @@ -258,21 +282,21 @@ public function dispatch(AbstractNode $node)
return $res;
}

public function walkSelect($node)
public function walkSelect(AbstractNode $node)
{
$columns = array();

/** @var $property Field */
foreach ($node->getChildren() as $property) {
$phpcrName = $this->getPhpcrProperty(
list($alias, $phpcrName) = $this->getPhpcrProperty(
$property->getAlias(),
$property->getField()
);

$column = $this->qomf->column(
$property->getAlias(),
// do we want to support custom column names in ODM?
// what do columns get used for in an ODM in anycase?
$alias,
$phpcrName,
// do we want to support custom column names in ODM?
$phpcrName
);

Expand Down Expand Up @@ -359,7 +383,8 @@ protected function walkSourceDocument(SourceDocument $node)
// constraints.
$this->sourceDocumentNodes[$alias] = $node;

// index the metadata for this document
// cache the metadata for this document
/** @var $meta ClassMetadata */
$meta = $this->mdf->getMetadataFor($documentFqn);

if (null === $meta->getName()) {
Expand All @@ -369,14 +394,15 @@ protected function walkSourceDocument(SourceDocument $node)
}

$this->aliasMetadata[$alias] = $meta;
if ($this->locale && 'attribute' === $meta->translator) {
if ($this->locale && $meta->translator) {
$this->translator[$alias] = $this->dm->getTranslationStrategy($meta->translator);
}
$nodeType = $meta->getNodeType();

// get the PHPCR Alias
$alias = $this->qomf->selector(
$alias,
$meta->getNodeType()
$nodeType
);

return $alias;
Expand Down Expand Up @@ -419,16 +445,16 @@ protected function walkSourceJoinConditionFactory(SourceJoinConditionFactory $no
*/
protected function walkSourceJoinConditionEqui(SourceJoinConditionEqui $node)
{
$phpcrProperty1 = $this->getPhpcrProperty(
list($alias1, $phpcrProperty1) = $this->getPhpcrProperty(
$node->getAlias1(), $node->getProperty1()
);
$phpcrProperty2 = $this->getPhpcrProperty(
list($alias2, $phpcrProperty2) = $this->getPhpcrProperty(
$node->getAlias2(), $node->getProperty2()
);

$equi = $this->qomf->equiJoinCondition(
$node->getAlias1(), $phpcrProperty1,
$node->getAlias2(), $phpcrProperty2
$alias1, $phpcrProperty1,
$alias2, $phpcrProperty2
);

return $equi;
Expand Down Expand Up @@ -463,7 +489,7 @@ protected function walkSourceJoinConditionSameDocument(SourceJoinConditionSameDo
return $joinCon;
}

protected function doWalkConstraintComposite($node, $method)
protected function doWalkConstraintComposite(AbstractNode $node, $method)
{
$children = $node->getChildren();

Expand Down Expand Up @@ -497,12 +523,12 @@ protected function walkConstraintOrX(ConstraintOrX $node)

protected function walkConstraintFieldIsset(ConstraintFieldIsset $node)
{
$phpcrProperty = $this->getPhpcrProperty(
list($alias, $phpcrProperty) = $this->getPhpcrProperty(
$node->getAlias(), $node->getField()
);

$con = $this->qomf->propertyExistence(
$node->getAlias(),
$alias,
$phpcrProperty
);

Expand All @@ -511,12 +537,12 @@ protected function walkConstraintFieldIsset(ConstraintFieldIsset $node)

protected function walkConstraintFullTextSearch(ConstraintFullTextSearch $node)
{
$phpcrProperty = $this->getPhpcrProperty(
list($alias, $phpcrProperty) = $this->getPhpcrProperty(
$node->getAlias(), $node->getField()
);

$con = $this->qomf->fullTextSearch(
$node->getAlias(),
$alias,
$phpcrProperty,
$node->getFullTextSearchExpression()
);
Expand Down Expand Up @@ -590,13 +616,13 @@ protected function walkConstraintNot(ConstraintNot $node)

protected function walkOperandDynamicField(OperandDynamicField $node)
{
$phpcrProperty = $this->getPhpcrProperty(
list($alias, $phpcrProperty) = $this->getPhpcrProperty(
$node->getAlias(),
$node->getField()
);

$op = $this->qomf->propertyValue(
$node->getAlias(),
$alias,
$phpcrProperty
);

Expand All @@ -623,13 +649,13 @@ protected function walkOperandDynamicFullTextSearchScore(OperandDynamicFullTextS

protected function walkOperandDynamicLength(OperandDynamicLength $node)
{
$phpcrProperty = $this->getPhpcrProperty(
list($alias, $phpcrProperty) = $this->getPhpcrProperty(
$node->getAlias(),
$node->getField()
);

$propertyValue = $this->qomf->propertyValue(
$node->getAlias(),
$alias,
$phpcrProperty
);

Expand Down Expand Up @@ -698,6 +724,7 @@ protected function walkOrderBy(OrderBy $node)

$orderings = $node->getChildren();

/** @var $ordering Ordering */
foreach ($orderings as $ordering) {
$dynOp = $ordering->getChildOfType(
QBConstants::NT_OPERAND_DYNAMIC
Expand Down
2 changes: 0 additions & 2 deletions lib/Doctrine/ODM/PHPCR/Query/Builder/SourceJoin.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

namespace Doctrine\ODM\PHPCR\Query\Builder;

use Doctrine\ODM\PHPCR\Query\Builder\Source;

/**
* $from->joinInner()->left()->document()->
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ public function setPrefix($prefix)
}

/**
* Get the name of the property where to store the translations of a given property in a given language
* Determine the locale specific property name.
*
* @param string $locale The language to store
* @param string $fieldName The name of the field to translate
* @param string $locale
* @param string $propertyName the untranslated property name
*
* @return string The name of the property where to store the translation
* @return string the property name with the translation namespace.
*/
public function getTranslatedPropertyName($locale, $fieldName)
public function getTranslatedPropertyName($locale, $propertyName)
{
return sprintf('%s:%s-%s', $this->prefix, $locale, $fieldName);
return sprintf('%s:%s-%s', $this->prefix, $locale, $propertyName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@
use Doctrine\ODM\PHPCR\Mapping\ClassMetadata,
PHPCR\NodeInterface;

use Doctrine\ODM\PHPCR\Query\Builder\SourceFactory;
use Doctrine\ODM\PHPCR\Translation\Translation;
use PHPCR\Query\QOM\ConstraintInterface;
use PHPCR\Query\QOM\QueryObjectModelFactoryInterface;
use PHPCR\Query\QOM\SelectorInterface;

/**
* Translation strategy that stores the translations in attributes of the same node.
Expand Down Expand Up @@ -158,4 +162,29 @@ public function getLocalesFor($document, NodeInterface $node, ClassMetadata $met

return $locales;
}

/**
* {@inheritDoc}
*
* Translated properties are on the same node, but have a different name.
*/
public function getTranslatedPropertyPath($alias, $propertyName, $locale)
{
return array($alias, $this->getTranslatedPropertyName($locale, $propertyName));
}

/**
* {@inheritDoc}
*
* Nothing to do, the properties are on the same node.
*/
public function alterQueryForTranslation(
QueryObjectModelFactoryInterface $qomf,
SelectorInterface &$selector,
ConstraintInterface &$constraint = null,
$alias,
$locale
) {
// do nothing
}
}
Loading