異なる情報を持つ任意の数のAdProvider構成フィールドを含むことができるサイトレコードがあります。残念ながら、fieldNames(プロバイダーの名前)は一意であり、今後さらに増える予定です。ドキュメント内のそれぞれをハッシュタイプとしてハードコーディングすることもできますが、新しいプロバイダーが追加されるたびにドキュメントを更新する必要があります。
別のMongoコレクションから取得できるプロバイダーのリストを見てドキュメント自体を動的に変更したいのですが、これを行う方法がわかりません。
私の最初の試みは、loadClassMetaDataイベントでリスナーを作成し、新しいフィールドをマップすることでした。フィールドマッピングが表示されていますが、ドキュメントに反映されていません。明らかに、これらのフィールドにはゲッターとセッターがないので、魔法の__getメソッドと__setメソッドを使用してアクセスしようとしましたが、存在しないというエラーが発生します。
多分私はこれについて間違った方法で行っているのですか?
Mongoレコードの例:
{
"_id" : ObjectId("4ff1d29d99c6667722000000"),
"_type" : [
"Models_Site"
],
"enabledAdProviders" : [
"provider1",
"provider2",
"provider3",
"provider4"
],
"provider1" : {
"id" : "4028cbff38e2d7c00666fd2fdc770208"
},
"provider2" : {
"placements" : {
"Top_300x50" : "477",
"Btm_300x50" : "478",
"Top_320x50" : "477",
"Btm_320x50" : "478"
}
},
"provider3" : {
"id" : "8a809449013331fdcdc6662708532b20"
},
"siteId" : "PsTl",
"siteName" : "Publisher Site",
"provider4" : {
"placements" : {
"Top_300x50" : "430",
"Btm_300x50" : "430"
}
}
}
私のリスナー:
<?php
namespace BIM\DataBundle\Listener;
use BIM\DataBundle\Document\AdPublisherRecord;
use BIM\DataBundle\Document\AdProviderRecord;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
class AdPublisherSiteSetup
{
private $serviceContainer;
/**
* This service is called every time Ads doctrine odm loads a document.
* We are dynamically creating the ad provider setting nodes on the AdPublisher Record
*
*/
public function __construct($serv){
$this->serviceContainer = $serv;
}
public function loadClassMetadata(\Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs $args)
{
$metaData = $args->getClassMetadata();
$document = (string)$metaData->getName();
if($document == "BIM\DataBundle\Document\AdPublisherRecord"){
//query for ad providers
//create as a hash type to store each providers settings.
$providerList = $this->serviceContainer->get('ads.publisher.factory')->getProviderList();
foreach ($providerList as $name => $value) {
$metaData->mapField(array('fieldName' => $name, 'type' => 'hash'));
}
}
}
}