views:

45

answers:

1

I am using CakePHP 1.3. I have successfully created an Indeed DataSource and am looking to create more complicated ones. I am looking into creating a Yahoo Answers DataSource and was wondering about a few best practices. The API exposes a few functions:

1) Ability to search for questions

2) Ability to get questions in a category

3) Ability to get details on a specific question

4) Ability to get details on a specific user

As is, I might only use the question and user search functions. Here are my questions:

  1. Do I created 1 DataSource that can perform both tasks or separate ones (i.e. one to find users and another to find questions?

  2. If i create 1 DataSource then how do I identify if the model is $this->YahooUser->find() (find users) vs $this->YahooQuestion->find() (find questions) so that I may create the right URL for the request.

+1  A: 

Think of a datasource as a Database. For example, CakePHP is distributed with several database-specific datasources (ie. MySql, Oracle, etc.) What you will want to do is create a YahooAnswers datasource.

Here is an example in the docs to show you how to create a Twitter datasource for example: http://book.cakephp.org/view/849/An-Example

This should help you implement the YahooAnswers API as a datasource.

UPDATE: Here is an example:

<?php 
pp::import('Core', 'HttpSocket');
class YahooAnswersSource extends DataSource {
    protected $_schema = array(
        'users' => array(
            'id' => array(
                'type' => 'integer',
                'null' => true,
                'key' => 'primary',
                'length' => 11,
            ),
            'name' => array(
                'type' => 'string',
                'null' => true,
                'key' => 'primary',
                'length' => 60
            ),
        ),
                'questions' => array(
            'id' => array(
                'type' => 'integer',
                'null' => true,
                'key' => 'primary',
                'length' => 11,
            ),
            'text' => array(
                'type' => 'string',
                'null' => true,
                'key' => 'primary',
                'length' => 140
            ),
        )
    );
    public function __construct($config) {
        $auth = "{$config['login']}:{$config['password']}";
        $this->connection = new HttpSocket(
            "http://{$auth}@yahooanswers.com/"
        );
        parent::__construct($config);
    }
    public function listSources() {
        return array('users','questions');
    }
...
?>
cdburgess
Ive seen the example and it really does not cover how to develop a DataSource where you could retrieve multiple sources. I mentioned I've already created DataSoources in the past. My specific question was about how to go about my specific situation.
Angel S. Moreno
You are not pulling from multiple sources are you? You are pulling from one source... YahooAnswers. This datasource would have multiple schemas (tables) that reference users and questions. I made an edit so you can see what I mean. So think of the API(YahooAnswers) as the DATABASE and the data (users and questions) as the TABLES within the database.
cdburgess
I see, I see! ok, so then I want to create a YahooUsers model and a YahooQuestion model to query data from YahooAnswers. How would I know with in my DataSource to pull from a particular ListSource (aka table) ? ie $this->YahooUser->find('all') vs $this->YahooQuestion->find('all')Looks to me like I will have to pass a parameter from the model object to the DataSource object to let it know which source to access. I looked at the manual and there is no mention of this.
Angel S. Moreno
It would be more like: `$this->YahooAnswers->get_users();` or `$this->YahooAnswers->get_questions();`
cdburgess
and where would these methods live? in the DataSource or in the model? I was under the impression that with data sources you would have to do a $model->find() at the model level in order to trigger the read() method in the data source. I appreciate you assisting me on this. There are a few data sources missing from the CakePHP community and I play to give back by contributing my code.
Angel S. Moreno
I was wrong. You are correct. You would use $MODEL->find();. The way you differentiate between user and question is the name of the model. So you would create two models (user and question). Cake will 'automagically' pass the model name to the datasource so it knows what is coming in. Then in the read method of the datasource, you create a switch (or by some other method) to accommodate for the variation. Does that make sense? So you could do something like `switch ($model) { case 'user': find_user()...`
cdburgess
geez, so then i was right. I could create all my methods in the one datasource and then from the model let the datasource know the type of data to query. This is great! thanks so much Chuck!
Angel S. Moreno
No worries Angel. Good luck and happy coding!
cdburgess