模型
您决定继续阅读关于 Symfony CMF 的内容 10 分钟?真是好消息!在这一部分,您将更多地了解 CMF 的默认数据库层。
注意
再次声明,本章讨论的是 PHPCR 存储层。但是 CMF 是以存储不可知的方式编写的,这意味着它不与特定的存储系统绑定。
熟悉 PHPCR
PHPCR 将所有数据存储到一个大的树结构中。您可以将其比作文件系统,其中每个文件和目录都包含数据。这意味着使用 PHPCR 存储的所有数据都与至少另一个数据(其父数据)存在关系。反向关系也存在,您也可以获取数据元素的子元素。
让我们看一下您在前一章中下载的 CMF Sandbox 的树的转储。转到您的目录并执行以下命令
1
$ php bin/console doctrine:phpcr:node:dump
结果将是 PHPCR 树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
ROOT:
cms:
menu:
main:
admin-item:
projects-item:
cmf-item:
company-item:
team-item:
...
content:
home:
phpcr_locale:en:
phpcr_locale:fr:
phpcr_locale:de:
seoMetadata:
additionalInfoBlock:
child1:
...
routes:
en:
company:
team:
more:
about:
...
每个数据在 PHPCR 中都称为节点。所有内容都附加在 ROOT 节点下(由 PHPCR 本身创建)。
每个节点都有属性,其中包含数据。您为页面设置的内容、标题和标签都保存在 home
节点的此类属性中。您可以通过将 --props
开关添加到 dump 命令来查看这些属性
1
$ php bin/console doctrine:phpcr:node:dump --props /cms/content/home
注意
之前,PHPCR 树被比作文件系统。虽然这让您对发生的事情有一个很好的了解,但这并不是唯一的真相。您可以将其比作 XML 文件,其中每个节点都是一个元素,其属性是属性。
Doctrine PHPCR-ODM
Symfony CMF 使用 Doctrine PHPCR-ODM 与 PHPCR 交互。Doctrine 允许用户创建对象(称为文档),这些对象直接持久化到 PHPCR 树并从中检索。这类似于 Symfony 标准版中默认提供的 Doctrine ORM,但用于 PHPCR 而不是 SQL 数据库。
从代码创建内容
现在您对 PHPCR 有了更多了解,并且您了解了与之交互的工具,您可以开始自己使用它了。在前一章中,您通过使用 Yaml 文件编辑页面,该文件由沙盒的 fixture 加载器解析。这一次,您将使用 PHP 代码创建一个页面。
首先,您必须创建一个新的 DataFixture 以添加您的新页面。您可以通过在 AppBundle 中创建一个新类来完成此操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// src/AppBundle/DataFixtures/PHPCR/LoadQuickTourData.php
namespace AppBundle\DataFixtures\PHPCR;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
class LoadQuickTourData implements FixtureInterface, OrderedFixtureInterface
{
public function getOrder()
{
// refers to the order in which the class' load function is called
// (lower return values are called first)
return 100;
}
public function load(ObjectManager $documentManager)
{
// you will add code to this method in the next steps
}
}
$documentManager
是将文档持久化到 PHPCR 的对象。但首先,您必须创建一个新的 Page 文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
use Doctrine\ODM\PHPCR\DocumentManager;
use Symfony\Cmf\Bundle\ContentBundle\Doctrine\Phpcr\StaticContent;
// ...
public function load(ObjectManager $documentManager)
{
if (!$documentManager instanceof DocumentManager) {
throw new \RuntimeException(sprintf(
'Fixture requires a PHPCR ODM DocumentManager instance, instance of "%s" given.',
get_class($documentManager)
));
}
$content = new StaticContent();
$content->setName('quick-tour'); // the name of the node
$content->setTitle('Quick tour new Page');
$content->setBody('I have added this page myself!');
}
每个文档都需要一个父文档。在本例中,父文档应该是内容根节点。为此,我们首先从 PHPCR 检索根文档,然后将其设置为其父文档
1 2 3 4 5 6 7
public function load(ObjectManager $documentManager)
{
// ...
// get the root document
$contentRoot = $documentManager->find(null, '/cms/content');
$content->setParentDocument($contentRoot); // set the parent to the root
}
最后,我们必须告诉 Document Manager 使用 Doctrine API 持久化我们的内容文档
1 2 3 4 5 6
public function load(ObjectManager $documentManager)
{
// ...
$documentManager->persist($content); // tell the document manager to track the content
$documentManager->flush(); // doctrine is like a toilet: never forget to flush
}
现在您需要再次执行 doctrine:phpcr:fixtures:load
命令。再次转储节点时,您的新页面应显示在 /cms/content/quick-tour
下!
另请参阅
如果您想了解更多关于在 Symfony 应用程序中使用 PHPCR 的信息,请参阅 Doctrine PHPCR-ODM。