Lithium:如何手动填充DocumentSet?

时间:2013-07-12 11:14:36

标签: php lithium

如何将外部源中的数据作为DocumentSet返回?

我设置了一个自定义数据源,以便与亚马逊的Product Advertising API进行交互。为此,我将lithium\data\source\Http子类化,并重新定义了read方法以满足我的需求,如文档(http://li3.me/docs/manual/working-with-data/creating-data-sources.wiki)中所述。

但是,我的锂版本(0.11,最后一个版本)似乎没有像示例中那样的强制转换方法,如果我创建了一个,当我执行return $this->item($model, $data, $options)时它将不会被调用。

因此,我通过调用item创建了一个自定义parent::item函数来创建文档,就像文档示例对cast所做的那样。 然后,在递归调用之后,我最终得到一个 Document对象数组,最后调用parent::item然后给我一个空的DocumentSet对象。 我应该如何传递数据以创建正确的DocumentSet?

以下是我的代码的最小示例:

// Within class Amazon extends \lithium\data\source\Http

protected function _init() {
    // Define entity classes.
    $this->_classes += array(
        'entity' => 'lithium\data\entity\Document',
        'set' => 'lithium\data\collection\DocumentSet'
    );

    parent::_init();
}

public function read($query, array $options = array()) {
    // Extract from query object.
    $parameters = $query->export($this, array('keys' => array('conditions')));
    $conditions = $parameters['conditions'];

    // Code stripped to validate conditions and prepare Amazon request (that part works).
    // results in a $queryString variable.

    // Get response from Server.
    $xml = simplexml_load_string($this->connection->get($this->_config['basePath'], $queryString));

    // Stripped response validation and reformatting -> $items contains an array of SimpleXMLElement objects.

    return $this->item($query->model(), $items, array('class' => 'set'));
}

public function item($model, array $data = array(), array $options = array()) {
    // Recursively create Documents for arrays.
    foreach($data as $key => $value) {
        if(is_array($value)) {
            $data[$key] = $this->item($model, $value, array('class' => 'entity'));
        }
        else if(is_object($value) && get_class($value) == "SimpleXMLElement") {
            // Stripped code to extract data from XML object and put it in array $docData.

            $data[$key] = $this->item($model, $docData, array('class' => 'entity'));
        }
    }
    // Works perfectly for every (recursive) call with $options['class'] == 'entity' but fails for the final call with $options['class'] == 'set' (for this final call $data contains an array of Document objects).
    return parent::item($model, $data, $options);
}

1 个答案:

答案 0 :(得分:1)

我会跟踪主分支而不是发布版本。

在你的情况下,由于你手动装箱,我会做类似的事情:

return $this->_instance('set', compact('data'));