[wp-trac] [WordPress Trac] #25255: Extend admin-ajax to detect multiple user capability and admin-ajax.php does not return 0

WordPress Trac noreply at wordpress.org
Sun Sep 8 13:04:06 UTC 2013

#25255: Extend admin-ajax to detect multiple user capability and admin-ajax.php
does not return 0
 Reporter:  godhulii_1985  |      Owner:
     Type:  enhancement    |     Status:  new
 Priority:  normal         |  Milestone:  Awaiting Review
Component:  General        |    Version:  3.6
 Severity:  normal         |   Keywords:
 I was developing an ajax plugin and faced some problem. I wanted to write
 a code that will allow users to import some data as wordpress post.[[BR]]
 However, I do not want every user to give this capability (say, only
 >=author can access this). So, I included the GUI as a submenu page and
 via POST request to the same page processed the imported data. Next, I
 wanted to extend the functionality and provided ajax post support so that
 users need not to refresh/wait their page to submit data, only a submit
 button beside each datarow will do the job.


 '''Problem begins'''
 I wrote my initial code:

 add_action('wp_ajax_new_import', 'new_import_action_callback');

 function new_import_action_callback() {

 desired output: ''abc''
 constantly got: ''abc0''

 After lots of checking, I became sure that my code inside {{{ new_import()
 }}} has no issue but the extra 0 is appearing after code flow leaves my
 code. So, I looked into admin-ajax.php and found this line at the end:
 {{{die( '0' );}}}

 '''Things I understood from documentation'''
 From execution flow, it is correct to kill/die/exit execution at this line
 since above this line the original {{{ wp_ajax_example }}} action was
 called. However,
 * As a plugin+theme developer I never used die/exit in the codes written
 by me because I always transfer the control to wordpress to complete code
 flow (say, it has to close connection to database or other things that I
 don't know but necessary in core class destructors). I assumed the same
 for wp-ajax.
 * When I read the documentattion on
 [http://codex.wordpress.org/AJAX_in_Plugins] page, in '''Error Return
 Values''' section I read:
  *  ''the response will be -1 or 0, depending on the reason for the
 failure'' => So, not clear what will happen if it succeed and I assumed
 nothing will be output by wp.
  *  ''if the request succeeds, but the Ajax action does not match a
 Wordpress hook then admin-ajax.php will respond 0. '' => So, getting zero
 means request failed somehow.
  *  One sample code mention that: {{{ // this is required to return a
 proper result }}} . But this is in comment and do not reflect its vital
 significance. This die is necessary to end code forcefully (something
 unusual in plugin/theme development) but I didn't find anything (or maybe
 I missed) that mention that wp-ajax must be killed via ajax handling

 '''Final problem: cannot restrict my function to subset of all user'''
 It can be summarized as:
 * Submenu page or menu pages can be restricted to users via mentioning
 {{{manage_example}}} options. However, wp-ajax is common for all logged in
 user regardless of their capability.
 * In my original code, I do not want each user to import data so it is
 necessary for me to get a confirmation that logged in user has permission
 to import data. Currently I have modified my code as:
 add_action('wp_ajax_new_import', 'new_import_action_callback');

 function new_import_action_callback() {
         if( current_user_can('manage_example') )


 ''' ''Suggestion:'' To remove confusion'''
 The main reason for my hard time was that I didn't realize wp-ajax must be
 killed by me (code author). Moreover the return value was confusing and
 misleading also (same return value for 2 different condition which are
 mutually exclusive). Following things can be done:

 * Update codex to mention about the importance of killing/exiting code in
 wp-ajax function.
 * Update admin-ajax.php file's 77 line (wp-3.6) as: {{{ die(); }}}. This
 die is unconditional and if code reached here then plugin execution is
 completed and wp should not echo something voluntarily that ajax-receiver
 end do not expect.
 * If an error happens then it is more precise to echo via http-404 header
 because almost every ajax plugin/libraray rely on success or error via
 http status code.


 ''' ''Enhancement:'' Wordpress-ajax registration function '''

 In my opinion, some functionality should be provided for ajax
 functionality that give same level of control like menupage or submenu
 page. For example,

 // restrict to only editors
 add_ajax('handle_example', 'example_function', 'manage_categories');

 function example_function(){
         // code goes here

                 // WP_AJAX_HEADER = a function that takes a HTTP status
 code and print response lines from 2nd argument
                 WP_AJAX_HEADER(404, serialize($wp_error);


 Lastly, my thinking is that wordpress is like a blackbox to someone who
 uses this. So, access capability should be handled by wp (as done in page
 management) and wp should not output something extra (as it does in
 {{{die('0');}}} even though the ajax function might have succeeded.

Ticket URL: <http://core.trac.wordpress.org/ticket/25255>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software

More information about the wp-trac mailing list