fsi/datasource

FSi DataSource 组件

2.1.1 2021-02-11 16:41 UTC

README

DataSource 允许通过不同的驱动从各种来源获取数据。它支持分页,并通过字段(驱动程序或其扩展必须提供)允许提供各种条件,所获取的数据必须满足这些条件。

用于获取特定类型数据(从数据库、xml、json等)的 DataSource 必须使用正确配置的驱动程序创建,该驱动程序将实现获取该类型数据的方法。

可用驱动程序

基本用法

假设我们想要创建一个使用 DoctrineDriver 的 DataSource(您可以在 doc 文件夹中找到特定驱动程序的文档),它允许我们通过 Doctrine ORM 获取一些数据。为了我们的示例,假设我们有一个 News 对象(实体),包含 id、标题、作者、创建日期、简短内容和内容。我们只需要一个 $managerRegistry 实例。然后我们可以创建 $datasource 实例。

<?php

use FSi\Component\DataSource\Driver\DriverFactoryManager;
use FSi\Component\DataSource\Driver\Doctrine\ORM\DoctrineFactory;
use FSi\Component\DataSource\Driver\Doctrine\ORM\Extension\Core\CoreExtension;
use FSi\Component\DataSource\DataSourceFactory;

$managerRegistry = $this->getDoctrine()->getManager();

$driverExtensions = array(new CoreExtension());

$driverFactoryManager = new DriverFactoryManager(array(
    new DoctrineFactory($managerRegistry, $driverExtensions);
));

$extensions = array(
    //(...) Extensions that have to be loaded to DataSource after creation.
);

$factory = new DataSourceFactory($driverFactoryManager, $extensions);

$driverOptions = array(
    'entity' => 'FSiDemoBundle:News'
);
$datasource = $factory->createDataSource('doctrine-orm',  $driverOptions, 'datasource_name');

然后,如果我们想要为返回的数据指定某些条件,我们需要指定字段、它们的类型和比较方式。

<?php

$datasource
    ->addField('id', 'number', 'eq')
    ->addField('title', 'text', 'like')
    ->addField('author', 'text', 'eq')
    ->addField('create_date', 'datetime', 'between', array(
        'someoption' => 'somevalue', //Specific options that this field allows.
    ))
    ->addField('content', 'text', 'like')
;

如果我们已经配置了 DataSource,我们可以将其绑定到一些参数。

<?php

$parameters = array(
    'datasource_name' => array(
        'fields' => array( // In fact this key always equals to constant \FSi\Component\DataSource\DataSourceInterface::PARAMETER_FIELDS.
            'title' => 'part of searched title',
            'author' => 'author@example.com',
            'create_date' => array( // Input data doesn't have to be scalar, but it must in form that fields expects it.
                'from' => '2012-04-04',
                'to' => '2012-12-12',
            ),
        ),
    ),
);

$datasource->bindParameters($parameters);

我们还可以设置适当的分页。

<?php

$datasource->setMaxResults(20);
$datasource->setFirstResult(0);

最后,我们可以获取我们的数据

<?php

$result = $datasource->getResult();

或在视图渲染期间创建有用的视图(见下文了解更多信息)。

<?php

$view = $datasource->createView();

返回的结果始终实现 Traversable 接口。

注意:实际上,您要执行的所有操作只是创建 DataSource 并调用 getResult 方法,其他步骤都是可选的。

视图

在视图渲染时,您应使用 DataSourceView。其主要目的是保留由扩展提供的某些属性,这些属性对于渲染各种链接、分页等是必需的。有关更多详细信息,请参阅 doc 文件夹中扩展的文档。

要获取这些属性,您可以使用以下方法:hasAttributesetAttributegetAttributegetAttributesremoveAttribute

视图还具有三种获取当前数据源参数、页面上的其他参数或所有参数(如果页面上有多个 DataSource)的方法:这些方法分别是 getParametersgetAllParametersgetOtherParameters。您获得的参数允许您重新生成 DataSource 的当前状态(这意味着如果从 getParameters 绑定参数,DataSource 将处于绑定前的相同状态)。

这些方法返回多维数组,因此您需要将其转换为适合作为 GET 参数发送的状态(如 name[param1][param2])。

视图还包含 FieldViews(每个字段一个,见下文)。您可以通过多种方式访问它们,因为 View 实现了 ArrayAccessCountableSeekableIterator

<?php

$view = $datasource->createView(); //Main view.

foreach ($view as $fieldView) {
    // (...)
}

count($view);

$view['fieldname1'].hasAttribute('foo');

注意:请记住,您不能使用 ArrayAccess 接口设置任何内容,如 unset($view['field1'])$view['field2'] = 'sth' 这样的结构将不起作用。

FieldView

FieldView 允许设置与特定字段相关的某些特定属性。您可以通过与 View 中相同的方法访问它们:hasAttributesetAttributegetAttributegetAttributesremoveAttribute

要了解在哪些情况下设置了哪些属性,请参阅扩展文档。

扩展

您可以在 doc 文件夹中找到可用扩展的文档。

通常有三种类型的扩展:DataSource 扩展、Driver 扩展和 Field 扩展。

本组件的所有部分都使用 Symfony 的 EventDispatcher (Symfony\Component\EventDispatcher\EventDispatcher) 来管理事件。

数据源扩展

每个扩展必须实现接口 FSi\Component\DataSource\DataSourceExtensionInterface。方法 loadSubscribers 必须返回对象数组(如果有的话),这些对象必须实现 Symfony\Component\EventDispatcher\EventSubscriberInterface。方法 loadDriverExtensions 必须返回对象数组(如果有的话),这些对象必须是有效的驱动扩展(见下文)。

每个订阅者可以订阅以下事件之一:(列表包含键,即 FSi\Component\DataSource\Event\DataSourceEvents 中的常量,以及事件方法参数,该参数定义在 FSi\Component\DataSource\Event\DataSourceEvent 命名空间中)

  • PRE_BIND_PARAMETERS - ParametersEventArgs
  • POST_BIND_PARAMETERS - DataSourceEventArgs
  • PRE_GET_RESULT - DataSourceEventArgs
  • POST_GET_RESULT - ResultEventArgs
  • PRE_BUILD_VIEW - ViewEventArgs
  • POST_BUILD_VIEW - ViewEventArgs
  • PRE_GET_PARAMETERS - ParametersEventArgs
  • POST_GET_PARAMETERS - ParametersEventArgs

所有参数都允许通过 getDataSource 方法访问 DataSource

参数

  • DataSourceEventArgs - 只提供访问 DataSource 的权限(见上文)
  • ParametersEventArgs - 允许通过 getParameterssetParameters 方法获取和设置参数
  • ViewEventArgs - 允许通过 getView 方法获取视图
  • ResultEventArgs - 允许通过 getResultsetResult 方法获取和设置结果

驱动扩展

每个扩展必须实现接口 FSi\Component\DataSource\Driver\DriverExtensionInterface。方法 loadSubscribers 必须返回对象数组(如果有的话),这些对象必须实现 Symfony\Component\EventDispatcher\EventSubscriberInterface

驱动扩展必须实现方法 getExtendedDriverTypes(),该方法返回适合此扩展的驱动类型。

驱动扩展通过 hasFieldTypegetFieldType 方法提供字段类型,其中 getFieldType 必须返回给定类型的字段对象,该对象实现了 FSi\Component\DataSource\Field\FieldTypeInterface,并且已经加载了所有其扩展。

每个订阅者可以订阅以下事件之一:(列表包含键,即 FSi\Component\DataSource\Event\DriverEvents 中的常量,以及事件方法参数,该参数定义在 FSi\Component\DataSource\Event\DriverEvent 命名空间中)

  • PRE_GET_RESULT - DriverEventArgs
  • POST_GET_RESULT - ResultEventArgs

参数

  • DriverEventArgs - 允许通过 getDriver 方法访问驱动
  • ResultEventArgs - 允许通过 DriverEventArgs 访问驱动,并通过 getResultsetResult 方法设置和获取结果

字段扩展

每个扩展必须实现接口 FSi\Component\DataSource\Field\FieldExtensionInterface。方法 loadSubscribers 必须返回对象数组(如果有的话),这些对象必须实现 Symfony\Component\EventDispatcher\EventSubscriberInterface

字段扩展必须实现方法 getExtendedFieldTypes(),该方法返回适合此扩展的字段类型。

每个订阅者可以订阅以下事件之一:(列表包含键,即 FSi\Component\DataSource\Event\FieldEvents 中的常量,以及事件方法参数,该参数定义在 FSi\Component\DataSource\Event\FieldEvent 命名空间中)

  • PRE_BIND_PARAMETER - ParameterEventArgs
  • POST_BIND_PARAMETER - FieldEventArgs
  • POST_BUILD_VIEW - ViewEventArgs
  • POST_GET_PARAMETER - ParameterEventArgs

所有参数都允许通过 getField 方法访问 Field

参数

  • FieldEventArgs - 只提供访问字段(见上文)
  • ParameterEventArgs - 允许通过 getParametersetParameter 方法获取和设置参数
  • ViewEventArgs - 允许通过 getView 方法获取字段视图