我有一個網站記錄,可以包含任何數量的具有不同信息的AdProvider配置字段。不幸的是,fieldNames(提供商的名稱)是獨一無二的,而且還會有更多。我可以在文檔中將它們中的每一個硬編碼爲散列類型,但每次添加新的提供程序時都必須更新文檔。在Symfony2中與Doctrine ODM如何在文檔中動態創建字段?
我想動態修改尋找供應商,我可以從另一個蒙戈收集得到的列表中選擇文檔本身,但我無法弄清楚如何做到這一點。
我第一次嘗試是建立在loadClassMetaData事件偵聽器和映射新的領域。我看到了字段映射,但它們沒有反映在文檔中。顯然,這些字段沒有任何getter和setter,所以我嘗試使用magic __get和__set方法訪問它們,但是我得到的錯誤不存在。
也許我會對此錯誤的方法嗎?
例蒙戈記錄:
{
"_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'));
}
}
}
}
我不認爲你想要做的是可能與教條。 Doctrine文檔是「靜態的」,所以你想加載的字段必須存在於文檔中,否則將不會被加載。如果你能解釋更多關於你想達到的目標,我想有一個更好的方法來做到這一點。 – Sgoettschkes
我希望能夠使我的應用程序適用於新輸入的廣告提供商(在創建或編輯網站記錄時生成所需的正確表單字段。 –
我玩過更多的東西,如果我在檢索記錄之前修改classMetadata,就能使它工作。但是,我需要在Document中定義屬性並使用魔術方法,因此看起來這樣做沒有任何優勢。我想我只需要添加屬性,生成getter和setter,並在新的AdProvider添加到數據庫時重新部署。 –