[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:
---------------------------+-----------------------------
'''Background'''
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.
[[BR]]
----
'''Problem begins'''
I wrote my initial code:
{{{
add_action('wp_ajax_new_import', 'new_import_action_callback');
function new_import_action_callback() {
new_import();
}
}}}
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
function.
'''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') )
new_import();
}
}}}
----
''' ''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
try{
}catch($wp_error)
{
// 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);
}
}
}}}
[[BR]]
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