0

Cake で costum データソースを作成しようとしています。この costum データソースは、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 datasource exampleのチュートリアルに従って、独自のデータソースの作成を開始しました

今のところ、私はデータソースからの読み取りにのみ関心があります (つまり、更新、作成、または削除は気にしません)。

この目的のために、私は次のことを行いました:

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

面白いことに、これは実際に機能します。モデルとデータソース間のリンクは機能していますが、助けが必要です!

Cake Magic を使用すると、コントローラーから次の行を実行できるはずです。

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

しかし、それがどのように機能するのかよくわかりませんか?マジック ケーキ メソッドを機能させるには、データソースに何を作成する必要がありますか?

4

1 に答える 1