exporter API(导出、输出器api)moodel3.3

Moodle【导出器】是接收数据并将其序列化为一个简单的预定义结构的类。它们确保输出的数据格式统一,易于维护。它们也用于生成外部函数的签名(参数和返回值)

外部函数定义在moodle/lib/externallib.php

在处理外部函数(Ajax,Web服务,...)和渲染方法时,我们经常遇到同一个对象被使用并从多个位置输出的情况。当这种情况出现时,我们的对象的代码会被重复序列化,或者变得不一致我们用【导出器】来解决这个问题,它清楚地定义了它输出的数据,并包含将输入数据转换成输出数据的逻辑,它可以自动生成外部函数所需的结构,如果需要导出新属性,则只需将其添加到导出器类中,并且【导出器】的所有用法都会自动继承此添加的属性

基类被定义在:moodle33\lib\classes\external\exporter.php

protected $related   用于避免DB查询的相关对象的列表

protected $data     这个输出器的数据 (值:stdClass|array//保存持久对象和相关对象

public function __construct($data, $related = array())   

//函数以适合于mustache模板的格式导出渲染器数据。这意味着原始记录是在to_record中生成的,但是,所有的字符串都是通过外部格式文本(或外部格式字符串)正确地传递的

final public function export(renderer_base $output)   

//函数猜测正确的上下文,返回到系统上下文

protected function get_context()    

//在导出时获得附加的值

protected function get_other_values(renderer_base $output)

//获取此导出器的读取属性定义。 Read属性将模型(persistent或stdClass)的默认属性与{@link self :: define_other_properties()}定义的属性相结合

final public static function read_properties_definition()

//获取用于创建和更新结构的导出器的属性定义,读取结构由以下方式返回:{@link self :: read_properties_definition()}

final public static function properties_definition()

//返回仅用于显示的附加属性列表

protected static function define_other_properties()

//返回属性列表。返回实例化导出器时所需的属性列表,以及它将同时导出的属性列表

protected static function define_properties()

//返回与此持久性相关的对象列表,只有在这里列出的对象可以缓存在这个对象中

protected static function define_related()

//获取上下文结构

final protected static function get_context_structure()

//获取格式字段名

final protected static function get_format_field($definitions, $property)

//得到结构格式

final protected static function get_format_structure($property, $definition, $required = VALUE_REQUIRED)

//返回创建的结构

final public static function get_create_structure()

//返回读取的结构
final public static function get_read_structure()

//从一组属性(递归)返回读取结构
final protected static function get_read_structure_from_properties($properties, $required = VALUE_REQUIRED, $default = null)

//返回更新的结构
final public static function get_update_structure()

定义属性

define_properties()方法返回实例化导出器时所需的属性列表,以及它将同时导出的属性列表

protected static function define_properties() {
    return array(
        'id' => array(
            'type' => PARAM_INT
        ),
        'username' => array(
            'type' => PARAM_ALPHANUMEXT
        ),
    );
}

这些属性将允许我们为外部函数生成一个创建更新结构,稍后再介绍

哦,如果你使用持久性,你不需要这样做:瞧瞧这个-导出和持久。

如果你有一个持续的,你想要导出输出,所有的工作已经完成了。如果扩展class core\external\persistent_exporter,并添加方法define_class(),则所有持久性属性将自动添加到导出器

class status_exporter extends \core\external\persistent_exporter {
 
    /**
     * Returns the specific class the persistent should be an instance of.
     *
     * @return string
     */
    protected static function define_class() {
        return \some\namespace\status::class; // PHP 5.5+ only
    }
 
}

 

属性特性

每个属性都使用以下属性进行配置:

type
唯一的强制性属性。它必须是许多PARAM_ *常量之一,或者是一组属性。
default
未提供值时的默认值。未指定时,需要一个值。
null
无论是常量NULL_ALLOWED还是NULL_NOT_ALLOWED,都会告知是否接受空值。这个默认为NULL_NOT_ALLOWED。
optional
该财产是否可以完全省略。默认为false。
multiple
这个属性是否会有更多的条目。默认为false。

尽管这不是一个规则,但建议标准属性(通过与附加属性相反)仅使用上面的type属性,并且只使用PARAM_ *常量。

附加属性

附加属性的列表被视为额外的属性,不需要给导出器输出它们。它们是从提供的数据(以及相关的对象,后面会详细介绍)中动态生成的。例如,如果我们希望我们的导出器将URL提供给用户的配置文件,我们不需要开发者事先传递它,我们可以基于已经提供的ID生成它。

 
 

附加属性只包含在对象的读取结构(get_read_structureread_properties_definition)中,因为它们是动态生成的。不需要也不需要创建更新对象


/*
* * Return the list of additional properties. * @return array */ protected static function define_other_properties() { return array( 'profileurl' => array( 'type' => PARAM_URL ), 'statuses' => array( 'type' => status_exporter::read_properties_definition(), 'multiple' => true, 'optional' => true ), ); }

 

 

上面的代码片段定义了我们将始终在属性profileurl下导出一个URL ,并且我们将导出或不导出status_exporters的列表。正如你所看到的,这个类型可以使用另一个导出器的读取属性,它允许导出器被嵌套。

如果您定义了其他属性,则还必须添加逻辑来导出它们。这是通过将get_other_values(renderer_base $ output)方法添加到导出器来完成的。这是一个我们忽略状态的例子,因为它们是可选的

/**
 * Get the additional values to inject while exporting.
 *
 * @param renderer_base $output The renderer.
 * @return array Keys are the property names, values are their values.
 */
protected function get_other_values(renderer_base $output) {
    $profileurl = new moodle_url('/user/profile.php', ['id' => $this->data->id]);
    return [
        'profileurl' => $profileurl->out(false)
    ];
}

重要说明:其他属性不能覆盖标准属性,所以请确保名称不冲突。

相关的对象

 

有时我们需要出口商内部的更多信息来导出。这可能与上下文一样简单,但在导出其他属性时也可以使用其他对象。尽可能避免调用API,或者在导出时查询数据库。出口商可以在循环中使用,因此后续查询可能会显着影响性能,因此需要相关的对象。

 

相关对象需要在出口商内部进行定义,即确保它们总是被提供并且是正确的类型。在一些情况下,通常当相关对象不存在时,它们可以被标记为可选的。例如,如果我们有一个问题导出器,可选的相关对象可能是同行评审者,因为我们并不总是有同行评审者。

 

使用方法protected static define_related(),如下所示。键是相关对象的任意名称,值是该类的完全限定名称。班级名称后面可以跟[]和/或分别表示这些对象的列表,以及一个可选的相关内容

/**
 * Returns a list of objects that are related.
 *
 * @return array
 */
protected static function define_related() {
    return array(
        'context' => 'context',                     // Must be an instance of context.
        'statuses' => 'some\\namespace\\status[]',  // Must be an array of status instances.
        'mother' => 'family\\mother?',              // Can be a mother instance, or null.
        'brothers' => 'family\\brother[]?',         // Can be null, or an array of brother instances.
    );
}

实例化时,我们将相关的对象给导出者,如下所示:

$data = (object) ['id' => 123, 'username' => 'batman'];
$relateds = [
    'context' => context_system::instance(),
    'statuses' => [
        new some\namespace\status('Hello'),
        new some\namespace\status('World!'),
    ],
    'mother' => null,
    'brothers' => null
];
$ue = new user_exporter($data, $relateds);

 

 

使用导出器

一旦我们有一个简约的出口商设置,这里是如何使用它。

class user_exporter extends core\external\exporter {
 
    /**
     * Return the list of properties.
     *
     * @return array
     */
    protected static function define_properties() {
        return array(
            'id' => array(
                'type' => PARAM_INT
            ),
            'username' => array(
                'type' => PARAM_ALPHANUMEXT
            ),
        );
    }
 
}

 

导出数据

$data = (object) ['id' => 123, 'username' => 'batman'];
 
// The only time we can give data to our exporter is when instantiating it.
$ue = new user_exporter($data);
 
// To export, we must pass the reference to a renderer.
$data = $ue->export($OUTPUT);

如果我们打印$data的内容,我们将获得这个:

stdClass对象
(
    [id] => 123
    [username] =>蝙蝠侠
)

现在,我同意这并不令人印象深刻。但是等到你阅读了关于自动格式化文本①,以及在外部函数中的使用②。

 

①遵守文本格式规则:  如果我们在导出过程中必须通过$OUTPUT,那是因为我们正在为您自动处理文本格式。记住函数format_text()format_string()?它们被用来对用户通常提交的内容应用过滤器,还可以将其从一些给定的格式转换为HTML。

导出时,导出器会查看所有属性的类型。当它找到PARAM_TEXT类型的属性时,它将使用format_string()。但是,如果使用PARAM_RAW找到一个属性,并且存在另一个同名的属性,但以format结尾,则将使用format_text()。如果您不熟悉在Moodle中输出文本的规则,请参阅输出函数最常用的PARAM_ *类型

 

'description' => array(
    'type' => PARAM_RAW,
),
'descriptionformat' => array(
    'type' => PARAM_INT,
),

添加上面的两个属性,让我们看看当用户的描述是以Markdown格式,然后导出它时会发生什么

$data = (object) [
    'id' => 123,
    'username' => 'batman',
    'description' => 'Hello __world__!',
    'descriptionformat' => FORMAT_MARKDOWN
];
$ue = new user_exporter($data, ['context' => context_user::instance(123)]);
$data = $ue->export($OUTPUT);

不出所料,这就是它出来的结果:

stdClass Object
(
    [id] => 123
    [username] => 蝙蝠侠
    [description] => <p>Hello <strong>world</strong>!</p>
    [descriptionformat] => 1   // Corresponds to FORMAT_HTML.
)

Psst ...我们已经在上面作弊了。你有没有注意到我们已经通过了导出器的上下文?我们通过了一个相关的对象

 

外部函数里

假设我们有一个外部函数get_users,它返回一个用户列表。现在我们只想导出用户ID和他们的用户名,所以我们将使用我们的导出器。我们要求我们的导出器为我们创造外部结构:

public static function get_users_returns() {
    return external_multiple_structure(
        user_exporter::get_read_structure()
    );
}

现在这样做了,我们必须使用我们的导出器来导出我们用户的数据

public static function get_users() {
    global $DB, $PAGE;
    $output = $PAGE->get_renderer('core');
    $users = $DB->get_records('user', null, '', 'id, username', 0, 10); // Get 10 users.
    $result = [];
    foreach ($users as $userdata) {
        $exporter = new user_exporter($userdata);
        $result[] = $exporter->export($output);
    }
    return $result;
}

最后,如果您有另一个外部函数来创建用户,则可以使用导出器来获取传入数据的结构。如果你希望你的外部函数需要更多的信息来创建你的用户,这将有助于你的需求的增长。以下表示外部函数需要字段“username”在通过键“user”中传递。在创建更新结构,包括所有的标准性能,而不是其他的附加属性。请注意,创建结构不包括id属性。使用user_exporter :: get_update_structure()是否更新用户,从而接收ID。

public static function create_user_parameters() {
    return new external_function_parameters([
        'user' => user_exporter::get_create_structure()
    ]);
}
 
public static function create_user($user) {
    // Mandatory parameters validation.
    $params = self::validate_parameters(self::create_user_parameters(), ['user' => $user]);
    $user = $params['user'];
    ...
}

重要提示:在参数中使用时,导出器的结构必须总是被包含在另一个关键字的下方,高于我们所使用的用户。否则这将不会灵活,并且可能不会为某些Web服务协议生成有效的结构

转载于:https://www.cnblogs.com/lichihua/p/8396847.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值