douzhigan1687 2013-09-02 12:22 采纳率: 0%
浏览 43
已采纳

CakePHP:如何在自定义数据源中实现查找类型?

I am trying to create a costum datasource in Cake. This costum datasource uses the HasOffers api (if any of you are familiar with it).

The structure of this API is as follow (taken from HasOffers API documentation):

$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 );

Now as you can see alot of parameters is used to make sure that you get the right data and that you are actually 'allowed' to pull the data.

Going back to cake:

Now i started out creating my own datasource by following the tutorial on Cake Documentation datasource example

For now, i am only interrested in reading from the datasource (i.e i dont care about update, create or delete).

For this purpose i did the following:

<?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);
    }
  }

Then in my app/config/database.php i added the following lines:

    public $HasOfferStat = array(
    'datasource' => 'HasOffersStat',
    'NetworkID' => "my-network-id",
    'NetworkToken' => 'my-network-key',
    'APIDomain' => 'http://bloglicsystem.api.hasoffers.com/Api?'
);

Now funny enough this actually works! the link between my model and the datasource is working however i need some help!

with cake magic i should be able to do the following line from my controller:

$this->MyModel->find('all');

However i don't quite understand how that would work? What do i need to create in my Datasource to make magic cake methods work?

  • 写回答

1条回答 默认 最新

  • douxianji6104 2013-09-02 13:11
    关注

    It depends whether you need to care about these "magic" find methods, the "magic" happens in the model (see Model::find(), Model::buildQuery(), Model::_readDataSource() and the Model::_find*() methods), where appropriate queries are generated based on the find type.

    The datasource receives these queries in the read method, and has to evaluate and make proper use of them, just like in the linked example.

    So it all depends on your specific needs, if you need to do something special based on the find type, then you can always check Model::$findQueryType in your read method and act appropriately.

    See also the CakePHP Datasources Plugin, it's for Cake 1.3, however you should get the point.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)
  • ¥65 抖音咸鱼付款链接转码支付宝
  • ¥15 ubuntu22.04上安装ursim-3.15.8.106339遇到的问题
  • ¥15 blast算法(相关搜索:数据库)
  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi