CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • API v3: get activities by target contact and activity type
Pages: [1]

Author Topic: API v3: get activities by target contact and activity type  (Read 4910 times)

davej

  • Ask me questions
  • ****
  • Posts: 404
  • Karma: 21
API v3: get activities by target contact and activity type
September 26, 2011, 06:41:14 am
Hi API v3 people,

I'm trying to get activities of specified types for a specified target contact, using crmAPI() from a Smarty template. Problems I'm having:

(1) How to filter by target contact id.
 - If I specify contact_id, this retrieves activities where source OR target OR assignee is the specified contact. I've tried target_contact_id (which is what getfields suggests), target_id, target, targets.

(2) How to filter by both contact and activity type.
 - Testing on 4.0.5 and on d7.demo.civicrm.org, if I try this:
/civicrm/ajax/rest?json=1&debug=1&version=3&entity=Activity&action=get&contact_id=54&activity_type_id=9

- I get activities of all types, it seems to ignore the activity_type_id param. But if I don't specify a contact:
/civicrm/ajax/rest?json=1&debug=1&version=3&entity=Activity&action=get&activity_type_id=9

then it filters by activity type.

(3) How to filter by a set of activity types.
 - I've tried things like activity_type_id=3,4,5 or activity_type_id=3|4|5.

It would be handy to know which if any of 1-3 are expected current behaviour or intended but currently unimplemented.

[Edit 26 Sep 17:19 BST]
I also want to:

(4) Return assignee contact name as well as ID.
I'm guessing I'll need to define my own API function to do what I need. I've done this before in v2, implementing e.g.

function civicrm_myentity_myaction
in a file in a custom Drupal module, e.g.
modules/mymodule/api/v2/Myentity.php
and calling the function via jQuery crmAPI, e.g.
cj().crmAPI("myentity", "myaction", ...)

I'm trying to see if I can do something similar with API v3 but having no luck so far. I think the above approach made use of this from CRM/Utils/REST.php process() in Civi 3.3:

Code: [Select]
        } else {
            $fnGroup = ucfirst($args[1]);
            if ( strpos( $fnGroup, '_' ) ) {
                $fnGroup    = explode( '_', $fnGroup );
                $fnGroup[1] = ucfirst( $fnGroup[1] );
                $fnGroup    = implode( '', $fnGroup );
            }
            $apiFile = "api/v2/{$fnGroup}.php";
        }

This else clause isn't there in 4.0.5 . Is there a way to achieve the same thing in 4.0? I tried using a different entity name and implementing civicrm_api3_myentity_get in modules/mymodule/api/v3/Myentity.php, but that gives me:
API (myentity,get) does not exist (join the API team and implement civicrm_api3_myentity_get
 - because the file where I implemented civicrm_api3_myentity_get doesn't get loaded, because we don't have the above mechanism of $apiFile = "api/v2/{$fnGroup}.php / require_once $apiPath . $apiFile; as we did in 3.3 .

I tried implementing an api/v2 function as described above for 3.3 but got:
Fatal error: Call to undefined function civicrm_create_error() in .../sites/all/modules/civicrm/api/api.php on line 130, via:
7   0.6343   11781720   CRM_Utils_REST::ajax( )   ../Invoke.php:0
8   0.6344   11781720   CRM_Utils_REST::process( )   ../REST.php:494
9   0.6346   11781832   civicrm_api( )   ../REST.php:367

Not sure what to try next, advice gratefully appreciated. Perhaps one option might be forget the API and implement a function that I can call from Smarty, like crmAPI, but that returns the specific things I need.

Dave J
« Last Edit: September 26, 2011, 10:22:59 am by davej »

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: API v3: get activities by target contact and activity type
September 26, 2011, 12:30:31 pm
Hi Dave,

#1 The activity API & BAO is something we hope to improve in 4.1 - by restructuring the tables civicrm_activity_target & assignee & the source_contact id from the civicrm_activity table into a new table called activity_contact. The current structure presents a range of problems. I don't think it's worth fixing your first item in the API until the re-structure is done - I'd go with filtering the results in your code for now

At the moment IF you pass contact_id into the get function you interact with a fairly narrow prescriptive BAO function that creates temp tables to get around problems creating efficient queries with the current structure.

#2 IF you pass in source_contact_id you will get a different DAO based function called. This function will take activity_type_id as a filter as well - so your #2 question - if you pass in source contact id it should work.

#3 We don't yet have a format for 'IN' queries. I think I like the | as separator -  this isn't in place yet but could be applied in function _civicrm_api3_dao_set_filter function & it would be available to about 50% of the API. Not sure if '|' is adequately unique though? We could apply it only to fields of type 'integer'?

#4 as of 3.4.6 /4.0.6 you should be able to put custom api in your custom php directory. E.g. I now have a function in custom_php_dir/api/v3/Pledge/Related.php function civicrm_api3_pledge_related($params) which can be called from smarty

I also hit the situation here where I wanted contact_ids resolve to display names - I'm not sure if we should introduce an option for that or how best to do it.
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

totten

  • Administrator
  • Ask me questions
  • *****
  • Posts: 695
  • Karma: 64
Re: API v3: get activities by target contact and activity type
September 26, 2011, 05:58:18 pm
Just to expand a little bit on Eileen's comments about #4, i.e. implementing custom API functions:

One of the big changes in api/v3 was to better hide various file and function names from API consumers. As a result, CRM/Utils/REST.php and function.crmAPI.php don't need to do any string-magic with the file/function names -- they just hand off the request to civicrm_api() which takes care of the rest. This gives us some room to lookup files/functions in better ways. (CRM-8797 adds some more features to the API loader for 3.4.6/4.0.6.)

I don't think this is your problem, though. The approach of adding a new file "api/v3/Myentity.php" should still work. Digging into the error message:

"Call to undefined function civicrm_create_error() in .../sites/all/modules/civicrm/api/api.php on line 130"

"civicrm_create_error()" appears to be the helper function for API v2; but under API v3, the helper function is "civicrm_api3_create_error()". One or both of these may be the problem:

- The "version" parameter in your $params array doesn't match the version of your custom API.
- A bug in civicrm_api() causes it it to bomb badly when attempting to process an invalid APIv2 call (i.e. it neglects to load api/v2/utils.v2.php, so the civicrm_create_error function isn't available)

davej

  • Ask me questions
  • ****
  • Posts: 404
  • Karma: 21
Re: API v3: get activities by target contact and activity type
October 03, 2011, 07:21:40 am
Many thanks Eileen & Tim.

The suggestion of upgrading to 4.0.6 and implementing an API function under the custom PHP directory solved it for me. I like the structure implemented in CRM-8797, I used:

api/v3/Widget/Frobnicate.php

and have been happily frobnicating ever since.

Putting the API function in a custom Drupal module (as I'd done in Civi 3.3 with api v2) doesn't work for me in 4.0 / api v3. Is this an intended change? My 3.3 module used hook_civicrm_config to add itself to the PHP include path & template dir and used the directory structure described in my initial post. It's quite useful to be able to do it in this way, as it allows the code for a project to be packaged more neatly rather than having some code (for hooks etc) in a module & some in the custom PHP dir. But I have a working solution now and am grateful for your help with that.

Cheers,

Dave

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: API v3: get activities by target contact and activity type
October 03, 2011, 07:52:19 am
http://civicrm.org/blogs/totten/extending-apiv3

Did you try it as the second option example_civicrm_config ?

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

davej

  • Ask me questions
  • ****
  • Posts: 404
  • Karma: 21
Re: API v3: get activities by target contact and activity type
October 03, 2011, 09:25:37 am
Quote from: xavier on October 03, 2011, 07:52:19 am
http://civicrm.org/blogs/totten/extending-apiv3

Did you try it as the second option example_civicrm_config ?

Thanks for the link. Yes I did - but I've just found my mistake and it's now working. Sorry for the false alarm and thanks everyone for your help.

Dave J

davej

  • Ask me questions
  • ****
  • Posts: 404
  • Karma: 21
Re: API v3: get activities by target contact and activity type
November 24, 2011, 08:46:48 am
Hi,

I've run into a problem using the REST interface via civicrm/extern/rest.php with a custom API v3 function in 4.0.6. Although putting the API function in a custom Drupal module, which uses hook_civicrm_config to add itself to include_path, works when using /civicrm/ajax/rest, it doesn't work for civicrm/extern/rest.php, because the module doesn't get added to include_path. I've verified that these lines are present at the end of CRM/Utils/System/Drupal.php loadBootStrap():

Code: [Select]
        // CRM-8655: Drupal wasn't available during bootstrap, so hook_civicrm_config never executes
        require_once 'CRM/Utils/Hook.php';
        CRM_Utils_Hook::config( $config );

        return false;

Dave J

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: API v3: get activities by target contact and activity type
November 24, 2011, 09:20:53 am
Hi,

Bit of confusion it seems
1) the API from php is civicrm_api
2) the REST interface is an url /sites/all/modules....
3) the ajax interface is /civicrm/ajax/rest (or /civicrm/api/json )

Not sure what you are trying to do. Could you show the complete code?

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

davej

  • Ask me questions
  • ****
  • Posts: 404
  • Karma: 21
Re: API v3: get activities by target contact and activity type
November 24, 2011, 09:44:16 am
Hi Xavier,

Thanks for responding. Sorry for not being clear.

I've written a custom API v3 function and packaged it into a module, as in http://civicrm.org/blogs/totten/extending-apiv3 "Put the new files in a Drupal module and add the module to the include path".

When I call the custom API function via /civicrm/ajax/rest, the function works.

When I call the custom API function via /sites/all/modules/civicrm/extern/rest.php, the function doesn't work. (I carelessly abbreviated the path to /civicrm/extern/rest.php in my previous post, which was the source of the confusion I think.) - I get is_error = 1, error_message = "API (contact,mymethod) does not exist (join the API team and implement it!)"

I can work around the problem by putting the code into my custom PHP  directory instead of into a module. I suspect the problem is to do with the order in which Drupal bootstrapping and Civi config hook invocation occur. CRM-8655 seems relevant.

Dave J

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: API v3: get activities by target contact and activity type
November 24, 2011, 09:59:53 am
Quote from: davej on November 24, 2011, 09:44:16 am
When I call the custom API function via /sites/all/modules/civicrm/extern/rest.php, the function doesn't work. (I carelessly abbreviated the path to /civicrm/extern/rest.php in my previous post, which was the source of the confusion I think.) - I get is_error = 1, error_message = "API (contact,mymethod) does not exist (join the API team and implement it!)"


By using sites/all/modules... you are calling the api on a remote server, I'm assuming that's the goal? In that case, your code doesn't have to bootstrap anything.

What civi version are you using? the rest interface has received some love recently.

I would like to promote the new api/class.api.php you can use it either

$api = new civicrm_api3 ();
$api->Contact->get (array(...))

or (what you want for the rest)
  $api = new civicrm_api3 (array ('server' => 'http://example.org','api_key'=>'theusersecretkey','key'=>'thesitesecretkey'));


and then that's the same $api->Entity->Action ();


check out the comments at the start of class.api should give you some examples

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

davej

  • Ask me questions
  • ****
  • Posts: 404
  • Karma: 21
Re: API v3: get activities by target contact and activity type
November 24, 2011, 10:54:01 am
Hi Xavier,

Quote from: xavier on November 24, 2011, 09:59:53 am
By using sites/all/modules... you are calling the api on a remote server, I'm assuming that's the goal? In that case, your code doesn't have to bootstrap anything.

Yes, the custom API function will be called remotely. I am testing it in a browser, using a URL like blah.tld/sites/all/modules/civicrm/extern/rest.php?q=civicrm/contact/mymethod&key=blah&api_key=blah&...

I determined that the reason for the custom function not loading was that in civicrm_api (which the file civicrm/extern/rest.php invokes via CRM_Utils_REST::run/handle/process), the call to _civicrm_api_resolve was failing to find the custom function, because the custom module that contains the function was not in include_path. Whereas if I access the custom function using /civicrm/ajax/rest, the module is in include_path. So I speculated that the problem was that when using /sites/all/modules/civicrm/extern/rest.php, Drupal was not being properly bootstrapped, hence modules not being available and/or Civi hooks (specifically config hook) not running, which would account for the problem.

However I found that civicrm/extern/rest.php runs $rest->loadCMSBootstrap(),
which calls CRM_Utils_System::loadBootStrap(),
which calls CRM_Utils_System_Drupal::loadBootStrap(),
which contains the code I mentioned earlier:

Code: [Select]
        // CRM-8655: Drupal wasn't available during bootstrap, so hook_civicrm_config never executes
        require_once 'CRM/Utils/Hook.php';
        CRM_Utils_Hook::config( $config );

This code looks as though it's intended to fix the very problem that I'm experiencing.

Anyway, I can put the custom API function under my custom PHP directory instead and it then works.

Quote from: xavier on November 24, 2011, 09:59:53 am
What civi version are you using? the rest interface has received some love recently.
4.0.6.

Quote from: xavier on November 24, 2011, 09:59:53 am
I would like to promote the new api/class.api.php you can use it either

$api = new civicrm_api3 ();
$api->Contact->get (array(...))

or (what you want for the rest)
  $api = new civicrm_api3 (array ('server' => 'http://example.org','api_key'=>'theusersecretkey','key'=>'thesitesecretkey'));


and then that's the same $api->Entity->Action ();

Thanks, this looks cool. I don't think it's relevant to what I'm doing on the current project, as the REST call will be made from somebody's FileMaker server.

Cheers,

Dave J

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • API v3: get activities by target contact and activity type

This forum was archived on 2017-11-26.