我有以下情况:
我想要实现的目标是根据"后端内部应用&#34中的活动自动创建,更新和删除"前端内部应用" -pages的方法;
例如,当在"后端房屋应用程序"中添加新房子时,我希望它通知"前端房屋应用程序"所以"前端的房子应用"将自动为新添加的房屋创建整个节点树。含义:a" house" -page填写所需的数据," room" -pages for each rooms等,以便"前端的内容管理员应用"可以在工作区中看到新添加的房屋的整个树,并可以开始操作已有模板中的内容。除了自动创建这些页面之外,我还想预先设置更新和创建的权限,因为"前端内部应用程序的内容管理器"例如,不得能够创建新房间或更改房屋名称。
我无法让它发挥作用,我只是添加我已经完成的工作来展示我遇到的问题。
我开始使用以下代码,在一个控制器中扩展了Sulu自己的WebsiteController:
$documentManager = $this->get('sulu_document_manager.document_manager');
$nodeManager = $this->get('sulu_document_manager.node_manager');
$parentHousesDocument = $documentManager->find('/cmf/immo/routes/nl/huizen', 'nl');
$newHouseDocument = $documentManager->create('page');
// The backendApi just gives a House object with data from the backend
// In this case we get an existing House with id 1
$house = $backendApi->getHouseWithId(1);
$newHouseDocument->setTitle($house->getName()); // For instance 'Smurfhouse'
$newHouseDocument->setLocale('nl'); // Nl is the only locale we have
$newHouseDocument->setParent($parentHouseDocument); // A default page where all the houses are listed
$newHouseDocument->setStructureType('house'); // Since we have a house.xml template
// I need to grab the structure to fill it with values from the House object
$structure = $newHouseDocument->getStructure();
$structure->bind([
'title' => $house->getName(),
'houseId' => $house->getId(),
]);
$newHouseDocument->setWorkflowStage(WorkflowStage::PUBLISHED); // You would expect this to automatically publish the document, but apparently it doesn't... I took it from a test I reverse-engineered in trying to create a page, I have no clue what it is supposed to change.
$nodeManager->createPath('/cmf/immo/routes/nl/huizen/' . $house->getId());
$documentManager->persist(
$newHouseDocument,
'nl',
[
'path' => '/cmf/immo/contents/huizen/' . Slugifier::slugify($house->getName()), // Assume for argument's sake that the Slugifier just slugifies the name...
'auto_create' => true, // Took this value from a test that creates pages, don't know whether it is necessary
'load_ghost_content' => false, // Idem
]
);
$documentManager->flush();
现在,当我触发控制器动作时,我首先得到异常
财产" url"在结构"房子"是必需的,但没有给出任何价值。
我尝试通过手动将属性'url'
与值'/huizen/' . $house->getId()
绑定到$structure
来解决此问题,我绑定了其他值。但这并没有解决它,显然url值在persist事件链的某处被覆盖了,而我还没有找到的位置。
但是,出于测试目的,我可以手动覆盖处理此特定持久性事件映射的StructureSubscriber
中的URL。如果我这样做,会在Sulu-app-database中创建一些东西 - 欢呼!
我的phpcr_nodes
表列出了两个额外的记录,一个用于引用/cmf/immo/routes/nl/huizen/1
的RouteDocument,另一个用于引用/cmf/immo/contents/huizen/smurfhouse
的PageDocument。两者都在workspace_name
列中填充了值default_live
。但是,只要不存在与这两个记录完全重复的记录,除了default
列中的值workspace_name
,这些页面将不会出现在Sulu管理CMS环境中。毋庸置疑,他们也不会出现在公共网站上。
此外,当我让控制器操作中的DocumentManager尝试->find
我新创建的文档时,我会得到类UnknownDocument
的文档。因此,我不能让DocumentManager对其进行->publish
;随之而来的是一个例外。如果我访问Sulu管理环境中的页面,则它们未被发布;一旦我在那里发布它们,它们可以通过DocumentManager在控制器动作中找到 - 即使我稍后取消发布它们。由于某种原因,它们不再是UnknownDocument
。但是,即使可以找到它们,我也不能让DocumentManager转到->unpublish
或->publish
- 这对实际文档没有任何影响。
我希望有一份苏禄食谱 - 食谱或其他文件广泛描述如何动态创建完整发布的页面,因此无需通过“手工劳动”#39;实际的CMS环境,但到目前为止我还没有找到一个...所有的帮助非常感谢:)
PS:为了完成目的:我们在PHP 7.1的Windows服务器环境中运行Sulu; dbase是PostgreSQL,Sulu是发布标签1.4.7的本地分叉版本,因为我必须对Sulu处理上传文件的方式进行一些更改,以使其在Windows环境中工作。
编辑:如果不存在新房子页面,则制作新房屋页面的部分解决方案(未明确使用AdminKernel,但当然应该在AdminKernel处于活动状态的上下文中运行):
public function getOrCreateHuisPagina(Huis $huis)
{
$parent = $this->documentManager->find('/cmf/immo/routes/nl/huizen', 'nl'); // This is indeed the route document for the "collector page" of all the houses, but this doesn't seem to give any problems (see below)
try {
$document = $this->documentManager->find('/cmf/immo/routes/nl/huizen/' . $huis->id(), 'nl'); // Here I'm checking whether the page already exists
} catch(DocumentNotFoundException $e) {
$document = $this->setupPublishedPage();
$document->setTitle($huis->naam());
$document->setStructureType('huis_detail');
$document->setResourceSegment('/huizen');
$document->setParent($parent);
$document->getStructure()->bind([
'title' => $huis->naam(), // Not sure if this is required seeing as I already set the title
'huis_id' => $huis->id(),
]);
$this->documentManager->persist(
$document,
'nl',
[
'parent_path' => '/cmf/immo/contents/huizen', // Explicit path to the content document of the parnt
]
);
}
$this->documentManager->publish($document, 'nl');
return $document;
}
答案 0 :(得分:0)
首先,我认为以下行不会加载您要加载的内容:
$parentHousesDocument = $documentManager->find('/cmf/immo/routes/nl/huizen', 'nl');
它加载路径而不是页面文档,因此它应如下所示:
$parentHousesDocument = $documentManager->find('/cmf/immo/contents/nl/huizen', 'nl');
关于您使用网址的错误,而不是覆盖StructureSubscriber
,您应该简单地使用文档的setResourceSegment
方法,这正是您所需要的: - )
default_live
工作空间错误,您是否有可能在网站内核上运行这些命令?问题是WebsiteKernel默认使用default_live
工作空间,因此将内容写入此工作空间。如果您运行带有AdminKernel
的命令,它应该落在default
工作区中,您应该能够使用default_live
方法将其复制到publish
工作区中DocumentManager。
我希望有帮助: - )