Should be simple, but I am really confused on how to make this work. Using this code:

function my_mod_services_resources() {
  return array(
   'my_resource' => array(
     
   'retrieve' => array( 
              'help'                    => 'Retrieves a book',
              'file' => array('file' => 'inc', 'module' => 'my_mod'),     
              'callback'                => '_my_mod_book_retrieve',
              'access callback'         => '_my_mod_map_access',
              'access arguments'        => array('view'),
              'access arguments append' => TRUE,
              'args' => array( 
                      array( 
                            'name' => 'id',
                            'type' => 'string',
                            'description' => 'The book Id',
                            'source' => array('path' => '0'),
                            'optional' => FALSE,
                         ),
      ),

I can have a GET using Poster firefox plugin to ask for the url: http://www.example.com/my_rec/12
This is working fine, and the argument is passed without any problem.

My issue is that I need to have two or more arguments in the above url.

I have tried this code:

              'args' => array( 
                      array( 
                            'name' => 'id',
                            'type' => 'string',
                            'description' => 'The book Id',
                            'source' => array('path' => '0'),
                            'optional' => FALSE,
                         ),
                      array( 
                            'name' => 'bookisbn',
                            'type' => 'string',
                            'description' => 'The book ISBN',
                            'source' => array('path' => '1'),
                            'optional' => FALSE,
                         ),                         
                       ),

Hoping that it would allow me to pass another argument in the GET (retrieve).

Is this correct? How should I form the URL call?
I have tried:
http://www.example.com/my_rec/12/DDFFF
http://www.example.com/my_rec/12/bookisbn/DDFFF
and
http://www.example.com/my_rec?id=12&bookisbn=DDFFF (but that only triggers the index, not retrieve...)

Do I need a relationship for that?
Any pointers? I couldn't find anything related in examples or documentation.

Comments

kylebrowning’s picture

its late but thought i would post a quick response maybe push you in the right direction.

You need to be setting the
'source' => array('path' => '1'),
to
'source' => array('param' => 'paramName'),

but only for any args that wont come from the path. so your URL would be
http://www.example.com/my_rec/12?bookisdn=ISDN

if that doesnt help you ican post a longer response tomorrow.

maria_zk’s picture

Thank you so much for your response, I really appreciate it and it was very helpful.
Using params I was able to pass the bookISDN :) Yay!

I was wondering about the proper structure of the url. For example:
Say I need to retrieve a book using id and ISDN.
The following url structure works: my_resource/12?bookisdn=ISDN
I can get id:12 and bookisdn:ISDN, so fine :)

Is it possible to have arguments directly from the path and without params like so:
my_resource/id/12/bookisdn/ISDN (where 12 and ISDN are the arguments)
does that make sense? If so, how should I build my resource?
(I am using REST server)

kylebrowning’s picture

Did you clear cache and save resources again? Since params have changed ctools needs the update cache.

konordo’s picture

kylebrowning #1 was really helpful, thank you :)

marcus178’s picture

Did you find out if you can have multiple arguments such as services/arg1/arg2 as I trying to do a similar thing

bmhaskar’s picture

Version: 6.x-3.x-dev » 7.x-3.1

marcus178 : Any luck?
I am trying to it in drupal 7. I got it working with param but it will be great if it could also be done in arg1/ag2 way.

marcus178’s picture

I ended up using using a combination of an argument and a parameter like this

 'args' => array( 
                      array( 
                            'name' => 'id',
                            'type' => 'string',
                            'description' => 'The book Id',
                            'source' => array('path' => '0'),
                            'optional' => FALSE,
                         ),
                      array( 
                            'name' => 'parameter',
                            'type' => 'string',
                            'description' => 'The book ISBN',
                            'source' => array('param' => 'parameter'),
                            'optional' => FALSE,
                         ),                         
                       ),
ygerasimov’s picture

Category: support » feature
Status: Active » Needs review
StatusFileSize
new9.15 KB

Here is a patch with test that allows multiple path arguments.

Status: Needs review » Needs work

The last submitted patch, services-1481586-multiple-path-arguments.patch, failed testing.

ygerasimov’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, services-1481586-multiple-path-arguments.patch, failed testing.

ygerasimov’s picture

Hm... patch can be applied locally without any problems and all tests pass. Can anyone manually test the patch?

kylebrowning’s picture

I got 3 fails on the argument handling tests. However i was able to apply the patch :/

ygerasimov’s picture

Status: Needs work » Needs review
StatusFileSize
new10.27 KB

Ah. My patch didn't contained all changes. Kyle, please review attached one.

Status: Needs review » Needs work

The last submitted patch, services-1481586-multiple-path-arguments-14.patch, failed testing.

kylebrowning’s picture

Status: Needs work » Needs review
StatusFileSize
new10.87 KB

Lets see if d.o likes this.

Status: Needs review » Needs work

The last submitted patch, 0001-Multiple-Arguments.patch, failed testing.

kylebrowning’s picture

Version: 7.x-3.1 » 7.x-3.x-dev
Status: Needs work » Needs review

DUH!

kylebrowning’s picture

#16: 0001-Multiple-Arguments.patch queued for re-testing.

kylebrowning’s picture

Status: Needs review » Reviewed & tested by the community

do a backport as well!

marcingy’s picture

Status: Reviewed & tested by the community » Needs work

The if statements could be refactored into elseif because in many case the test are mutually exclusive, and in other cases eg POST we can else if on POST and then check the individual POST conditions.

if (isset($argument['optional']) && $argument['optional']) {

This can simply be

if (!empty($argument['optional'])) {

This variable is not initialised

$required_args++;

And this code just seems strange

+    $args = array();
+    for ($i = 0; $i <= $not_required_args; $i++) {
+      $args[] = $required_args + $i;
+    }

What is this function actually seeking to achieve?

ygerasimov’s picture

Status: Needs work » Needs review
StatusFileSize
new11.57 KB

Here is updated patch.

I haven't left if statements on purpose for better readability.

Changed condition to use empty as per suggestion from #21.

$required_args is initialized via arguments.

I have changed countPathArgumentsNumbers() method so it is more logical. Also renamed it to checkNumberOfArguments().

Also test is enhanced.

kylebrowning’s picture

kylebrowning’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.