4

I've mainly used the php apis in the past but I would like to use the REST API. I added an api key to the contact record, and I attempted to use the really simple example in the documentation. Yet I just keep getting

{"is_error":0,"version":3,"count":0,"values":[]}"

I'm using really simple examples like

entity=Contact&action=get (of course with the base url and rest.php? and then the keys at the end). I'm pretty sure the url is right since it says there is no error (and if I change things I definitely get an error response). If I use the php api I get data, so it's not that there is no data.

Update 2

Actually I think I was wrong about at least where the problem is because clearly the checking for a valid CMS user record is happening. If I use a url like this:

http://example.com/administrator/components/com_civicrm/civicrm/extern/rest.php?entity=Contact&action=get&group_id=6&options[limit]=25&options[offset]=50&json=1&key=4d0b3527f437210aa4479ca8fa4936eb&api_key=654321'

I get (along with a good apache response) {"is_error":0,"version":3,"count":0,"values":[]}

However if I add a var_dump($apiResponse); right before the return in run() in Civi\API\kernel.php I definitely get the data and count is not 0. And that array comes through just fine to \api\api.php. So whatever is going wrong is happening somewhere after that.

12
  • Can you try constructing it with a "frontend" url instead of a "backend" url?
    – Coleman
    Commented Mar 31, 2015 at 14:06
  • I actually thought about that as a possibility, but it didn't work in an obvious way. I think that something is going wrong with bootAndRun(). However the documentation is a bit tricky too; it really says to give the full path to the rest.php class which is in /administrator.
    – Elin
    Commented Apr 1, 2015 at 0:19
  • Just wondering.... what if you specify the values to be returned in your REST call?
    – DaveD
    Commented Apr 3, 2015 at 17:51
  • I'm not sure what you mean. The api specifically requests a set of values based on the query. In this case all the contact data on contacts who are in group 6.
    – Elin
    Commented Apr 3, 2015 at 18:11
  • Instead of asking for 'all the contact data', specify just a few fields to be returned. Using the super-nice api explorer in the new v4.6 (now officially out!!) I specified to return just last name and birthdate: /sites/all/modules/civicrm/extern/rest.php?entity=Contact&action=get&json={"sequential":1,"return":"last_name,birth_date"}&api_key=yourkey&key=sitekey
    – DaveD
    Commented Apr 3, 2015 at 18:20

2 Answers 2

5

This is going to be a fuller answer eventually but for right now it is a partial answer that addresses how to get publicly available data via REST.

The REST API works differently than the PHP or other versions of the API. Some of this is documented and some is not.

The most important difference between the rest API and the others is that the REST API does not instantiate an authenticated user as the current user in a Joomla! environment. Therefore it cannot use any of the Joomla access controls when determining what data to provide or what actions to allow. Also because the current user is not an authenticated user, CiviCRM roles (such as the default Authenticated User and Administrator) are not available. Therefore the only role that is available is Everyone.

However this does not literally mean that everyone (in the sense of the unregistered public) can see. This is because there must be a contact record with an api_key value and a registered Joomla user associated with that contact.

This also does not mean that Everyone can see everything. An ACL record still must be created. That is you must create ACL for each kind of data that you want to have accessible to the REST interface.

For GET the basic approach should be to create a group that contains the records you want to return. Call this, for example, MyGroup. To reiterate: This is not the group of users who have access to the interface, it is the group of users about whom data will be returned.

In the ACL interface click on Manage ACL.

  • For Role: Everyone
  • Action:View
  • Type of Data: A group of contacts
  • Group: MyGroup

These settings will allow you to use the REST interface to return data on one or more users in the MyGroup group, with data based on the URL you craft.

If you have a Joomla front end and you want to access a list of contacts via the rest interface you need to include a number of steps. This includes reading the keys, crafting the URL, and creating the request.

  1. If you have a civicrm.settings.php file you can obtain the site key with the following code:

    require_once JPATH_ROOT . '/administrator/components/com_civicrm/helpers/api.php'; 
    CivicrmHelperApi::civiInit();
    echo CIVICRM_SITE_KEY;
    

However, if you don't have access to the helper you can just require_once the settings file and that will define the site key constant.

  1. You also need to to access the individual user level API key. Most likely it would make the most sense to to store that in a file locally and read it in. Call that CIVICRM_API_KEY.

  2. Then you can craft a request url, which will have three parts, the base, the api parameters, and the keys.

    // Of course this should be https if possible.
    $restbase  = 'http://example.com/jooomla-cms/administrator/components/com_civicrm/civicrm/extern/rest.php?';
    $restkeys = '&key='. CIVICRM_SITE_KEY .  '&api_key=' . CIVICRM_API_KEY;
    $restvars = 'entity=contact&action=get&json={"sequential":1,"return":"first_name"}';
    
    // Make the request
    $http = new JHttp();
    $return = $http->get($restbase2 . $restvars  . $restkeys);
    
    // Do something with the data
    $body = $return->body;
    $values = json_decode($body)->values;
    
    foreach ($values as $value)
    {
        echo '<div>' . htmlspecialchars($value->first_name) . ' </div>';
    }
    

Some notes

There are many combinations of actions and entities which cannot be created in the ACL settings.

Depending on what you are envisioning you may want to create a Joomla user to be the one that provides access or you could register a user for each application that will be allowed to access publicly available data via the REST API.

These include most post and delete actions. In these cases there is sometimes checking of specific Joomla permissions such as access Civicrm but it does not work as expected. At least at this point the authorization process always returns false unless you have given the public permission to do these things via Joomla ACL. Not a good idea.

Update

I sent a pull request for a fix for this so that now permissions will be checked. You can apply this as a patch and it will work the way the documentation says (or at least it has been for me -- would love a few people to test it).

3
  • Great, glad to know it's getting solved. I have been tripped up on more than one occasion with permissions, especially with joomla. I hope you can write a good summary of what you found so that we can all find it next time we run into the same or similar problem.
    – DaveD
    Commented Apr 5, 2015 at 20:17
  • I think I found the bug that is causing the problem with authentication.
    – Elin
    Commented Apr 14, 2015 at 11:47
  • This report contains a link to a gist with code to force permissions checks to be done using the userid rather than an empty user. The empty user is why it worked when you made the data public.
    – Elin
    Commented Apr 18, 2015 at 13:35
0

It sounds like mod_rewrite is overzealously configured. You can edit your Apache(?) redirect, either in your .htaccess and/or your .conf files. You can add a command like:

RewriteCond %{REQUEST_FILENAME} !-f

And that says not to do rewrites below it if the exact path you're requesting resolves to a file that exists. That way, your request is never redirected to Joomla. See here for further documentation.

1
  • I think if that were the case I would not be getting a 200 response. The Apache response is just fine, headers are great etc, it is just the data that are empty. Edited the question to show the relevant code.
    – Elin
    Commented Mar 30, 2015 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.