0

PHPCR-ODM を既存の Symfony プロジェクトに統合しようとしていますが、(おそらく) マップされた Document クラスを検出するのに問題があります。具体的には、クラス MyDocument の Document を永続化しようとすると、次のようなエラーが発生します。

[Doctrine\Common\Persistence\Mapping\MappingException]                                                                            
The class 'Example\Common\ORM\Document\MyDocument' was not found in the chain configured namespaces Doctrine\ODM\PHPCR\Document

このプロジェクトはDoctrine ORMも使用しているため、私のクラスは奇妙な名前空間にある可能性があります.

ドキュメントに従って、app/autoload.php に追加しました。

 AnnotationRegistry::registerFile(__DIR__.'/../vendor/doctrine/phpcr-odm/lib/Doctrine/ODM/PHPCR/Mapping/Annotations/DoctrineAnnotations.php');

私の app/config/config.yml には以下が含まれています (parameters.yml でパラメーターが設定されています):

 doctrine_phpcr:
     session:
         backend:
             type: jackrabbit
             url: %jackrabbit_url%
         workspace: %jackrabbit_workspace%
         username: %jackrabbit_user%
         password: %jackrabbit_password%
     odm:
         auto_mapping: true

私のドキュメント クラスは src/Example/Common/ORM/Document/MyDocument.php にあり、次のようになります。

<?php

namespace Example\Common\ORM\Document;

use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;

/**
 * @PHPCRODM\Document
 */
class MyDocument
{
  /**
   * @PHPCRODM\Id
   */
  private $id;

  /**
   * @PHPCRODM\ParentDocument
   */
  private $parent;

  /**
   * @PHPCRODM\Nodename
   */
  private $name;

  // .. etc

最後に、統合をテストするために使用しているコードは、単純なコンソール コマンド内にあり、次のようになります。

use Example\Common\ORM\Document\MyDocument;

// ...

$documentManager = $this->container->get('doctrine_phpcr.odm.default_document_manager');

$document = new MyDocument();
$document->setParent($documentManager->find(null, '/'));
$document->setName('ExampleName');

$documentManager->persist($document);
$documentManager->flush();

MyDocument クラスが正しくロードされていることを確認しましたが、マップされた Document クラスであることを DocumentManager に認識させるような方法で注釈が処理されていないようです。

私の推測では、簡単な設定手順を見落としていると思いますが、PHPCR、PHPCR-ODM、さらには Symfony CMF のドキュメントを繰り返し徹底的に調べても、何も見つからないようです。そこにある例のほとんどは、Symfony CMF を介して PHPCR を使用することを含んでおり、PHPCR-ODM が通常の Symfony プロジェクトに統合されている実際の例を多く (すべて?) 見つけることができませんでした。


編集:最終的な解決策

@WouterJ が以下に示したアドバイスに従い、問題を解決しました。さらに、Symfony バンドルにコンパイラ パスを追加して、これを非標準の名前空間 (つまり、 以外のものYourBundle\Document) で機能させるという彼の提案に従いました。私の場合、これはバンドルではなく別の場所で再利用されるライブラリに入るので、適切でした。

src/Example/Bundle/ExampleBundle/ExampleBundle.phpこれを行うには、次のようにファイルにメソッドを追加しました。

<?php

namespace Example\Bundle\ExampleBundle;

use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class ExampleBundle extends Bundle
{
  public function build(ContainerBuilder $container)
  {
    parent::build($container);

    $mappedDirectories = array(
      realpath(__DIR__ . '/../../Common/ODM/Document')
    );

    $mappedNamespaces = array(
        'Example\Common\ODM\Document'
    );

    $phpcrCompilerClass = 'Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass';
    if (class_exists($phpcrCompilerClass)) {
        $container->addCompilerPass(
            DoctrinePhpcrMappingsPass::createAnnotationMappingDriver(
              $mappedNamespaces,
              $mappedDirectories
        ));
    }
  }
}

このコードは、マッピングされたドキュメント クラスを Example\Common\ODM\Document 名前空間に配置できるようにし、それらを取得します。この例では注釈を使用していますが、同じパターンを XML または YAML マッピングに使用できます (Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPassメソッド シグネチャについてはクラスを参照してください)。

doctrine_phpcr.odm.metadata.annotation_readerこれを機能させるには、サービスを定義する必要があることもわかりましたapp/config.yml

services:
    doctrine_phpcr.odm.metadata.annotation_reader:
        class: Doctrine\Common\Annotations\AnnotationReader

それを行うためのより良い方法があるかもしれませんが、それは私にとってそれを機能させるのに十分でした.

4

1 に答える 1

1

ドキュメントは、ORM\Document 名前空間ではなく、バンドルの Document 名前空間に配置する必要があります。

本当に ORM\Document 名前空間に配置したい場合 (ORM ではなく ODM について話しているため、これは非常に奇妙です)、ドクトリン マッピング コンパイラ パスを使用できます: http://symfony.com/doc/ current/cookbook/doctrine/mapping_model_classes.html

于 2013-10-20T07:13:05.773 に答える