我正在尝试在 Cake 中创建一个服装数据源。此服装数据源使用 HasOffers api(如果你们中的任何人熟悉它)。
该 API 的结构如下(取自 HasOffers API 文档):
$base = 'https://api.hasoffers.com/Api?';
$params = array(
'Format' => 'json'
,'Target' => 'Offer'
,'Method' => 'findAll'
,'Service' => 'HasOffers'
,'Version' => 2
,'NetworkId' => 'my-network-id'
,'NetworkToken' => 'my-api-key'
,'filters' => array(
'Offer.name' => array( 'LIKE' => 'My Offer' )
,'Offer.default_payout' => array( 'GREATER_THAN_OR_EQUAL_TO' => 10 )
)
);
$url = $base . http_build_query( $params );
$result = file_get_contents( $url );
现在你可以看到很多参数被用来确保你得到正确的数据,并且你实际上被“允许”拉取数据。
回到蛋糕:
现在我按照Cake Documentation 数据源示例的教程开始创建自己的数据源
目前,我只对读取数据源感兴趣(即我不关心更新、创建或删除)。
为此,我做了以下事情:
<?php
App::uses('HttpSocket', 'Network/Http');
class HasOffersStat extends DataSource {
/**
* An optional description of your datasource
*/
public $description = 'Has Offer stat';
public $base = 'http://bloglicsystem.api.hasoffers.com/Api?';
/**
* Our default config options. These options will be customized in our
* ``app/Config/database.php`` and will be merged in the ``__construct()``.
*/
public $config = array(
'Service' => 'HasOffers',
'Version' => 2,
'Format' => 'json',
'NetworkID' => "my-network-id",
'NetworkToken' => 'my-network-token',
'APIDomain' => 'http://bloglicsystem.api.hasoffers.com/Api?'
);
/**
* If we want to create() or update() we need to specify the fields
* available. We use the same array keys as we do with CakeSchema, eg.
* fixtures and schema migrations.
*/
protected $_schema = array(
'id' => array(
'type' => 'integer',
'null' => false,
'key' => 'primary',
'length' => 11,
),
'name' => array(
'type' => 'string',
'null' => true,
'length' => 255,
),
'message' => array(
'type' => 'text',
'null' => true,
),
);
/**
* Create our HttpSocket and handle any config tweaks.
*/
public function __construct($config) {
parent::__construct($config);
$this->Http = new HttpSocket();
}
public function makeApiCall($params)
{
$params = array_merge($this->params, (array)$params);
$api_response = json_decode(file_get_contents($this->base.$this->config. http_build_query($params) ), true);
return $api_response['response'];
}
/**
* Since datasources normally connect to a database there are a few things
* we must change to get them to work without a database.
*/
/**
* listSources() is for caching. You'll likely want to implement caching in
* your own way with a custom datasource. So just ``return null``.
*/
public function listSources($data = null) {
return null;
}
/**
* describe() tells the model your schema for ``Model::save()``.
*
* You may want a different schema for each model but still use a single
* datasource. If this is your case then set a ``schema`` property on your
* models and simply return ``$model->schema`` here instead.
*/
public function describe($model) {
return $this->_schema;
}
/**
* calculate() is for determining how we will count the records and is
* required to get ``update()`` and ``delete()`` to work.
*
* We don't count the records here but return a string to be passed to
* ``read()`` which will do the actual counting. The easiest way is to just
* return the string 'COUNT' and check for it in ``read()`` where
* ``$data['fields'] === 'COUNT'``.
*/
public function calculate(Model $model, $func, $params = array()) {
return 'COUNT';
}
/**
* Implement the R in CRUD. Calls to ``Model::find()`` arrive here.
*/
public function read(Model $model, $queryData = array(), $recursive = null) {
/**
* Now we get, decode and return the remote data.
*/
$params = array(
'Format' => 'json',
'Target' => 'Report'
);
$res = $this->makeApiCall($params);
return array($model->alias => $res);
}
}
然后在我的 app/config/database.php 我添加了以下几行:
public $HasOfferStat = array(
'datasource' => 'HasOffersStat',
'NetworkID' => "my-network-id",
'NetworkToken' => 'my-network-key',
'APIDomain' => 'http://bloglicsystem.api.hasoffers.com/Api?'
);
现在很有趣,这确实有效!我的模型和数据源之间的链接正在工作,但是我需要一些帮助!
有了蛋糕魔术,我应该能够从我的控制器执行以下操作:
$this->MyModel->find('all');
但是我不太明白这将如何工作?我需要在我的数据源中创建什么才能使魔术蛋糕方法起作用?