/** * {@inheritDoc} */ protected function walkSourceDocument(SourceDocument $node) { $alias = $node->getAlias(); $documentFqn = $node->getDocumentFqn(); // cache the metadata for this document /** @var $meta ClassMetadata */ $meta = $this->mdf->getMetadataFor($documentFqn); if (null === $meta->getName()) { throw new \RuntimeException(sprintf('%s is not a mapped document', $documentFqn)); } $this->aliasMetadata[$alias] = $meta; if ($this->locale && $meta->translator) { $this->translator[$alias] = $this->dm->getTranslationStrategy($meta->translator); } $nodeType = $meta->getNodeType(); // make sure we add the phpcr:{class,classparents} constraints // unless the document has a unique type; From is dispatched first, // so these will always be the primary constraints. if (!$meta->hasUniqueNodeType()) { $this->sourceDocumentNodes[$alias] = $node; } // get the PHPCR Alias $alias = $this->qomf->selector($alias, $nodeType); return $alias; }
/** * @param object $document * @param ClassMetadata $metadata * @throws PHPCRException */ private function doRemoveAllTranslations($document, ClassMetadata $metadata) { if (!$this->isDocumentTranslatable($metadata)) { return; } $node = $this->session->getNode($this->getDocumentId($document)); $strategy = $this->dm->getTranslationStrategy($metadata->translator); $strategy->removeAllTranslations($document, $node, $metadata); }
/** * {@inheritDoc} */ public function getTranslationStrategy($key) { return $this->wrapped->getTranslationStrategy($key); }
/** * Migrate content into the new translation format and remove the old properties. * * This does not commit the changes to the repository. Call save on the * PHPCR session *after each batch*. Calling flush on the document manager * *is not enough*. * * When translating, the new properties are copied into the languages * specified in $locales. When un-translating, the current locale and * language fallback is used, and $locales is ignored. * * To convert all fields into a translation, you can pass an empty array * for $fields and the information is read from the metadata. The fields * are mandatory when converting fields back to non-translated. * * To convert a single field from translated to non-translated, simply * specify that field. * * If you convert an existing translation, you need to specify the name of * the strategy that was previously used. The name is the one you would use * for DocumentManagerInterface::getTranslationStrategy, so "attribute" or * "child". * * The current strategy is read from the document metadata. * * Only documents that match $class exactly are converted, but not * descendants. You can query whether there where documents encountered * that could not be converted by calling getLastNotices() after each call * to convert(). * * @param string $class FQN of the document class * @param array $locales Locales to copy previously untranslated fields into. * Ignored when untranslating a document. * @param array $fields List of fields to convert. Required when making a * field not translated anymore * @param string $previousStrategyName Name of previous strategy or "none" if field was not * previously translated * * @return boolean true if there are more documents to convert and this method needs to be * called again. * * @throws PHPCRExceptionInterface if the document can not be found. * * @see getLastNotices() */ public function convert($class, $locales, array $fields = array(), $previousStrategyName = NonTranslatedStrategy::NAME) { /** @var ClassMetadata $currentMeta */ $currentMeta = $this->dm->getClassMetadata($class); $currentStrategyName = $currentMeta->translator ?: NonTranslatedStrategy::NAME; // sanity check strategies if ($currentStrategyName === $previousStrategyName) { $message = 'Previous and current strategy are the same.'; if (NonTranslatedStrategy::NAME === $currentStrategyName) { $message .= ' To untranslate a document, you need to specify the previous translation strategy'; } else { $message .= sprintf(' Document is currently at %s', $currentStrategyName); } throw new InvalidArgumentException($message); } if (!count($locales) && NonTranslatedStrategy::NAME !== $currentStrategyName) { throw new InvalidArgumentException('When converting to translated content, the locales must be specified.'); } $this->notices = array(); $translated = null; foreach ($fields as $field) { $current = !empty($currentMeta->mappings[$field]['translated']); if (null !== $translated && $current !== $translated) { throw new InvalidArgumentException(sprintf('The list of specified fields %s contained both translated and untranslated fields. If you want to move back to untranslated, specify only the untranslated fields.', implode(', ', $fields))); } $translated = $current; } $partialUntranslate = false; if (false === $translated && NonTranslatedStrategy::NAME !== $currentStrategyName) { // special case, convert fields back to untranslated $partialUntranslate = true; $previousStrategyName = $currentStrategyName; $currentStrategyName = NonTranslatedStrategy::NAME; $currentMeta->translator = null; } $currentStrategy = NonTranslatedStrategy::NAME === $currentStrategyName ? new NonTranslatedStrategy($this->dm) : $this->dm->getTranslationStrategy($currentMeta->translator); if (NonTranslatedStrategy::NAME === $previousStrategyName) { $previousStrategy = new NonTranslatedStrategy($this->dm); } else { $previousStrategy = $this->dm->getTranslationStrategy($previousStrategyName); } if (!$fields) { if (NonTranslatedStrategy::NAME === $currentStrategyName) { throw new InvalidArgumentException('To untranslate a document, you need to specify the fields that where previously translated'); } $fields = $currentMeta->translatableFields; } // trick query into using the previous strategy $currentMeta->translator = NonTranslatedStrategy::NAME === $previousStrategyName ? null : $previousStrategyName; if (NonTranslatedStrategy::NAME === $currentStrategyName) { $currentMeta->translatableFields = $fields; foreach ($fields as $field) { $currentMeta->mappings[$field]['translated'] = true; } } $qb = $this->dm->createQueryBuilder(); $or = $qb->fromDocument($class, 'd')->where()->orX(); foreach ($fields as $field) { $or->fieldIsset('d.' . $field); } $qb->setMaxResults($this->batchSize); $documents = $qb->getQuery()->execute(); // restore meta data to the real thing $currentMeta->translator = NonTranslatedStrategy::NAME === $currentStrategyName ? null : $currentStrategyName; if (NonTranslatedStrategy::NAME === $currentStrategyName) { $currentMeta->translatableFields = array(); foreach ($fields as $field) { unset($currentMeta->mappings[$field]['translated']); } } // fake metadata for previous $previousMeta = clone $currentMeta; $previousMeta->translator = NonTranslatedStrategy::NAME === $previousStrategyName ? null : $previousStrategyName; // even when previously not translated, we use translatableFields for the NonTranslatedStrategy $previousMeta->translatableFields = $fields; foreach ($documents as $document) { if (ClassUtils::getClass($document) !== $class) { $path = $this->dm->getUnitOfWork()->getDocumentId($document); $this->notices[$path] = ClassUtils::getClass($document); continue; } $this->convertDocument($document, $previousStrategy, $previousMeta, $currentStrategy, $currentMeta, $fields, $locales, $partialUntranslate); } return count($documents) === $this->batchSize; }