khepin/yaml-fixtures-bundle

此包已被放弃,不再维护。未建议替代包。

Symfony 扩展包,用于轻松加载基于 YAML 的数据固定文件。

安装: 147,801

依赖项: 2

建议者: 0

安全性: 0

星级: 58

关注者: 6

分支: 43

开放问题: 19

类型:symfony-bundle

1.0.2 2017-07-26 16:37 UTC

README

此扩展包为您提供了使用基于 YAML 的数据固定文件的方式,适用于 Symfony2 和 Doctrine2。它目前与 Doctrine ORM 或 Doctrine MongoDB ODM 一起工作。其他后端尚未实现,但可以很容易地实现。

Travic CI 状态: 构建状态 Scrutinizer CI: Scrutinizer 代码质量

安装

此扩展包依赖于 DoctrineFixturesBundle。如果您还没有用 Symfony2 配置它,请遵循设置说明

通过 Composer,添加到 composer.json

"require": {
    "khepin/yaml-fixtures-bundle": "~1.0.1"
}

然后在 AppKernel.php 中注册扩展包,最好只在开发环境中注册,因为它在其他地方可能不需要。

public function registerBundles()
{
    if (in_array($this->getEnvironment(), array('dev', 'test'))) {
        //...
        $bundles[] = new Khepin\YamlFixturesBundle\KhepinYamlFixturesBundle();
        //...
    }
}

配置

在您的 config.ymlconfig_dev.yml(推荐)中添加以下内容

khepin_yaml_fixtures:
    resources:
        - MyOtherBundle/load_this_first
        - MyBundle
        - MyOtherBundle

在 'resources' 下是一个您想要加载固定文件的扩展包列表。固定文件将按此顺序加载。

MyOtherBundle/load_this_first 语法意味着 load_this_first.yml 将在当前包中的其他文件之前加载。这允许为加载固定文件设置任何特定的顺序。

定义您的固定文件

设置

请注意,与 Symfony 1.x 不同,您加载固定文件的顺序很重要。您可以通过以下两种方式来操纵这个顺序

  • 通过 config.yml:指定哪些扩展包的固定文件首先加载
  • 通过文件名:固定文件在每个扩展包内部按字母顺序加载

默认情况下,固定文件使用扩展包层次结构:MyBundle/DataFixtures/somefixtures.yml

如果您想更改使用的层次结构固定文件,请在配置中指定它

khepin_yaml_fixtures:
    directory: Resources/fixtures

这将导致您的固定文件使用扩展包层次结构:MyBundle/Resources/fixtures/somefixtures.yml

定义

您只能在文件中定义一个类的固定文件。固定文件在顶级进行配置,并在 fixtures 键内定义。您可以通过在 fixtures 数组中提供名称来为固定文件命名,以便稍后引用。

model: Name\Space\MyBundle\Entity\User
tags: [ test, dev, prod ] # optional parameter
save_in_reverse: false # optional parameter
persistence: orm (default)| mongodb # lets you choose if these fixtures should be saved through the orm or through mongodb.
fixtures:
    michael:
        name: Michael
        phonenumber: 8765658
        birthday: "1989-12-12"

您可以通过提供名称来使用对先前创建的固定文件的引用

model: Name\Space\MyBundle\Entity\Car
fixtures:
    audi_a3:
        owner: michael
        since: "2010-12-12"

对于MongoDB的参考多,将您的引用作为列表放在相应的键下

model: Name\Space\Bundle\Document\Car
persistence: mongodb
fixtures:
    audi_a3:
        owners:
            - michael
            - paul
            - angella

您可以为同一实体定义尽可能多的文件。当与上下文标签(见下文)一起使用时,这会非常有用。

##处理日期和时间

日期需要在引号内设置。日期传递给DateTime,所以任何可以与DateTime一起工作的字符串都可以在这里使用。这包括相对格式,如"-1天"、"下个月"、"1周前"。

model: Name\Space\MyBundle\Entity\Statistics
fixtures:
    stat-1:
        product: example.org
        date: "2010-12-12" #dates NEED to be set inside quotes

Mongo嵌入式文档

在Mongo中可以使用嵌入式文档(目前只实现了embed_one)。只需像这样连续地保持yaml文件

model: Name\Space\Bundle\Document\Article
persistence: mongodb
fixtures:
    first_post:
        title: Ouelkom to my niew blog!
        content: I will update regularly!
        author: # This defines an embedded document
            name: khepin # this will be set on the embedded document

用法

从命令行

php app/console khepin:yamlfixtures:load <context>

关于上下文的更多内容将在以后介绍,除非你有理由,否则不需要添加上下文。

注意:目前命令行一次只能加载一个上下文。

从其他任何地方

如果您需要从其他地方加载固定数据,比如...您的功能测试,以便为测试设置一个干净的数据库,您可以通过服务容器访问相同的内容,并且具有能够一起加载多个上下文的优势

$container->get('khepin.yaml_loader')->loadFixtures('prod', 'test', ...);

关于上下文

有时在设置测试用例的固定数据时,您需要不同的配置。这就是上下文旨在解决的问题。

上下文等同于在固定文件下设置在标签键中的标签。您可以在固定文件上设置尽可能多的标签。例如prodtest等...

如果您以这种方式定义固定数据,那么从命令行调用

php app/console khepin:yamlfixtures:load prod

将加载您设置的任何固定数据文件

tags: [ ..., prod, ... ]

这样,您可以定义在您使用测试或开发环境时加载的固定数据,但在例如生产环境中不加载。

没有任何标签的固定数据文件总是加载!这样,您可以在完全没有标签的文件中设置引导固定数据,然后为每个目的设置特定的固定数据。

那么这个“save_in_reverse”是什么东西?

这个参数通常可以省略。它目前只有在您有一个自引用表时才有用。例如,如果您有像这样的固定数据

fixtures:
    last_level:
        next_level: none
        name: Meet the boss
    middle_level:
        next_level: last_level
        name: complete the quest
    start_level:
        next_level: middle_level
        name: introduction

在这种情况下,我们需要在我们的固定数据中将last_level放在第一位,因为它是唯一一个没有引用其他任何东西的。我们无法首先创建start_level,因为它需要middle_level已经存在等...

问题是,当清除数据库时,ORMPurger()按id顺序逐行遍历。所以如果我们按这个顺序保存它们,last_level应该是第一个被移除的,这将因为它仍然被middle_level引用而导致外键问题。

以反向顺序保存将按此顺序创建对象,以便正确设置引用,然后以相反的顺序保存它们,这样在清除数据库时就没有异常。

处理 ORM 一对多或多对多关联

如果您想将已创建的对象数组传递给 *-To-Many 关联,您可以通过首先允许对象的 setter 接受一个简单的 PHP 数组(而不是仅接受 Doctrine\Common\ArrayCollection)来实现,然后按照以下方式定义您的 YAML 文件

fixtures:
    car:
        name: foo_bar
        parts:
            - part_one
            - part_two
            - part_three

当然,这假设 part_one、part_two 和 part_three 是您在先前加载的文件中已定义的对象。

YAML 加载器将创建一个包含三个对象的简单 PHP 数组,并将其传递给您在此文件中定义的模型上的 setParts() 方法。

构造函数

如果您想向构造函数传递参数

fixtures:
    car:
        __construct:
            - Ford
            - {type: reference , value: owner_ford}
            - {type: datetime, value: "2012-01-01"}
class Car
{
    /**
     * @param string $name
     * @param Owner $owner
     * @param DateTime $purchaseDate
     */
    public function __construct($name, Owner $owner, \DateTime $purchaseDate, )
    {
        ...
    }
}

服务调用

某些实体在持久化之前需要由特殊服务进行管理。例如,FOSUserBundle 就是这样,正确的密码是由 user_manager 设置的,而不是直接在用户类中设置。因此,我们需要请求此服务在我们将域对象设置为正确状态之前将其持久化。服务调用声明如下

model: My\NameSpace\User
service_calls:
    service_1:
        service: fos_user.user_manager # this is the service id in the container
        method: updateUser # the method to be called on the object
fixtures:
  dad:
    name: Francois
    plain_password: thisismypassword

现在,对于每个用户,在它被持久化之前,将发生类似于以下代码的操作

$container->get('fos_user.user_manager')->updateUser($user_francois);

使用 ACL

如果您需要在您的 fixtures 上设置 ACL 条目,这是可能的。ACL 是在所有 fixtures 已保存之后创建的,以确保没有可能的冲突。

要为 fixtures 设置 ACL,您需要使用 ProblematicAclManagerBundle

并按照以下方式更新您的配置

khepin_yaml_fixtures:
    acl_manager: ~
    resources:
        - MyBundle
        - MyOtherBundle

ACL 只能使用 Symfony MaskBuilder 中定义的标准掩码。示例

model: My\NameSpace\Car
tags: [ test ]
fixtures:
  dad_car:
    name: Mercedes
  mom_car:
    name: Mini Cooper

acl:
  dad_car:
    user_dad: MASK_OWNER
    user_mom: MASK_MASTER
  mom_car:
    user_mom: MASK_OWNER

请注意,Symfony 中的 ACL 不是通过 Doctrine 管理的,因此重新创建 fixtures 时不会清除。但是,如果有冲突,加载 ACL 将覆盖所有先前的 ACL 条目。