ajax and $wpdb

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

ajax and $wpdb

Adam Taylor-7
Hi All,

I'm using AJAX to call my plugin script to process data and update what is
displayed (essentially a thumbs up/thumbs down voting plugin).  This is
fine, I can update the text but I need to also interact with the database.

As I understand, because I am calling my script directly not from within
wordpress $wpdb is not available.

I read that you can include wp-blog-header.php and everything should be
available and have added - require_once('../../../wp-blog-header.php');  -
to the function requiring it, however, I get the following error:

PHP Fatal error:  Call to a member function set_prefix() on a non-object in
/dev/site/wp-settings.php on line 255

Firstly: what's going on here and how can I fix it?

Secondly: is this the best way of doing this? I can't find any tutorials or
documents about writing an ajaxy plugin for wordpress that interacts with
the database. This topic http://wordpress.org/support/topic/184095 suggests
that it is not but I don't understand the suggested solutions.

Thanks in advance,
Adam

--
[hidden email]
http://www.twitter.com/adamtaylor
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Adam Taylor-7
Ok I've resolved my first question but my second question still stands.

Adam

--
[hidden email]
http://www.twitter.com/adamtaylor
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

scribu
On Wed, Jul 29, 2009 at 1:41 PM, Adam Taylor <[hidden email]> wrote:

> Secondly: is this the best way of doing this? I can't find any tutorials or
> documents about writing an ajaxy plugin for wordpress that interacts with
> the database.


Definetly not the best way. I would send you to this page, but it's
outdated, unfortunately: http://codex.wordpress.org/AJAX_in_Plugins

Basically, instead of calling a script directly, you should do this:

For logged-in users:

add_action('wp_ajax_my_action', 'my_ajax_handler');

For the public:

add_action('wp_ajax_nopriv_my_action', 'my_ajax_handler');


The js should look something like this:

jQuery.post(<?php echo admin_url('admin_ajax.php'); ?>, {action:
'my_action', foo: 'bar'});


And the php:

function my_ajax_handler() {
  var_dump($_POST);
}


That's about it.


--
http://scribu.net
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Jennifer Hodgdon
scribu wrote:

> On Wed, Jul 29, 2009 at 1:41 PM, Adam Taylor <[hidden email]> wrote:
>
>> Secondly: is this the best way of doing this? I can't find any tutorials or
>> documents about writing an ajaxy plugin for wordpress that interacts with
>> the database.
>
>
> Definetly not the best way. I would send you to this page, but it's
> outdated, unfortunately: http://codex.wordpress.org/AJAX_in_Plugins
>
> Basically, instead of calling a script directly, you should do this:
>
> For logged-in users:
>
> add_action('wp_ajax_my_action', 'my_ajax_handler');
>
> For the public:
>
> add_action('wp_ajax_nopriv_my_action', 'my_ajax_handler');

When did this come in to WordPress? That Codex page was written in an
era when you couldn't do AJAX in a standardized way outside of the
admin screens.

     --Jennifer

--
Jennifer Hodgdon * Poplar ProductivityWare
www.poplarware.com
Drupal, WordPress, and custom Web programming

_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Otto-19
On Wed, Jul 29, 2009 at 9:32 AM, Jennifer Hodgdon<[hidden email]> wrote:
> When did this come in to WordPress? That Codex page was written in an era
> when you couldn't do AJAX in a standardized way outside of the admin
> screens.

The nopriv stuff got added 5 months ago, here:
http://core.trac.wordpress.org/changeset/10720

-Otto
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Jess Planck-2
That sure does beat doing a template_redirect or trying to point to  
some custom php thing in a plugin or theme url "http://nasty-something/ 
wp-content/where??/".

It is worthwhile to note that the _nopriv_ will only run for logged  
out visitors. For some cases you may need to perform ajax for  
authenticated visitors as well.

If the intertubes don't mangle it, this is a small experiment added to  
a theme's function.php where the theme had a proper wp_footer() call  
and I just threw the jquery enqueue into init:

function my_jquery_enqueue() {
        wp_enqueue_script( 'jquery' );
}
add_action( 'init', 'my_jquery_enqueue' );

function my_ajax_handler() {
        var_export( $_POST );
}

if ( defined( 'DOING_AJAX' ) ) {
        if ( is_user_logged_in() )
                add_action('wp_ajax_my_action', 'my_ajax_handler');
        else
                add_action('wp_ajax_nopriv_my_action', 'my_ajax_handler');
}

function my_ajax_handler_js() {
?>

        <div id="wp-ajax-debug">Ajax Debug</div>
       
        <script type="text/javascript" charset="utf-8">
        /* <![CDATA[ */
       
        jQuery.post(
                '<?php echo admin_url('admin-ajax.php'); ?>',
                {
                        action: 'my_action',
                        foo: 'bar'
                },
                function( data ) {
                        jQuery( '#wp-ajax-debug' ).html( '::DONE:: ' + data );
                }
        );
       
        /* ]]> */
        </script>

<?php
}
add_action( 'wp_footer', 'my_ajax_handler_js' );

Have fun, I am!

Jess

[  :P  ]  jess planck  -  http://funroe.net

On Jul 29, 2009, at 9:54 AM, Otto wrote:

> The nopriv stuff got added 5 months ago, here:
> http://core.trac.wordpress.org/changeset/10720

_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Simon Wheatley-3
In reply to this post by Adam Taylor-7
Others have answered the AJAX question, but for completeness
wp-load.php is what you wanted rather tha wp-blog-header.php.

However to add my tuppenny-worth, and this is why the AJAX solutions
mentioned are more cleverer, you can't guarantee the relative location
of wp-load.php to your plugin files (they might have moved wp-content
outside the main WP files, etc, etc)... so to get that to work you'd
have to have someone edit the plugin files to specify the location...
and then when someone uses the nifty cool "update plugin" feature all
the edits would be overwritten and the plugin breaks. This last point
is why we all need to drill "never edit plugin files" into people as
thoroughly as we've been drilling "never hack core".

S


On Wed, Jul 29, 2009 at 11:26 AM, Adam Taylor<[hidden email]> wrote:

> Hi All,
>
> I'm using AJAX to call my plugin script to process data and update what is
> displayed (essentially a thumbs up/thumbs down voting plugin).  This is
> fine, I can update the text but I need to also interact with the database.
>
> As I understand, because I am calling my script directly not from within
> wordpress $wpdb is not available.
>
> I read that you can include wp-blog-header.php and everything should be
> available and have added - require_once('../../../wp-blog-header.php');  -
> to the function requiring it, however, I get the following error:
>
> PHP Fatal error:  Call to a member function set_prefix() on a non-object in
> /dev/site/wp-settings.php on line 255
>
> Firstly: what's going on here and how can I fix it?
>
> Secondly: is this the best way of doing this? I can't find any tutorials or
> documents about writing an ajaxy plugin for wordpress that interacts with
> the database. This topic http://wordpress.org/support/topic/184095 suggests
> that it is not but I don't understand the suggested solutions.
>
> Thanks in advance,
> Adam
>


---
Sweet Interaction Ltd is Registered in England/Wales, no. 6610741
Registered office: 7 Malton Av, Manchester, M21 8AT
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Silverstein, Jesse
Re: Simon's problem of plugin directory location & editing plugin files:

I think if your plugin file has loaded, it's safe to assume that ABSPATH has been defined, and you can go from there.
For example:
require_once ABSPATH . WPINC . "/functions.php";
or something along those lines. Dynamically reference the core files you need based on the global definitions already available to you. That way there is no plugin editing required, and your plugin can work regardless of where the content directory is or where the plugins directory is, etc.

When referencing other files in your plugin directory, (and please correct me if I'm wrong here,) it's best to use WP_PLUGIN_URL or WP_PLUGIN_DIR, depending on the use case (URL for anything that gets printed to the browser or for redirects, DIR for includes and requires). For backward compatibility to 2.5ish,

if ( !defined( 'WP_CONTENT_URL' ) )
        define( 'WP_CONTENT_URL', get_option( 'site_url' ) . '/wp-content' );
if ( !defined( 'WP_CONTENT_DIR' ) )
        define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
if ( !defined( 'WP_PLUGIN_URL' ) )
        define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' );
if ( !defined( 'WP_PLUGIN_DIR' ) )
        define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );

I can't take credit for that code because I think I found in on the codex somewhere. Regardless, I hope it helps someone out there.

-Jesse

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Simon Wheatley
Sent: Wednesday, July 29, 2009 2:05 PM
To: [hidden email]
Subject: Re: [wp-hackers] ajax and $wpdb

Others have answered the AJAX question, but for completeness
wp-load.php is what you wanted rather tha wp-blog-header.php.

However to add my tuppenny-worth, and this is why the AJAX solutions
mentioned are more cleverer, you can't guarantee the relative location
of wp-load.php to your plugin files (they might have moved wp-content
outside the main WP files, etc, etc)... so to get that to work you'd
have to have someone edit the plugin files to specify the location...
and then when someone uses the nifty cool "update plugin" feature all
the edits would be overwritten and the plugin breaks. This last point
is why we all need to drill "never edit plugin files" into people as
thoroughly as we've been drilling "never hack core".

S


On Wed, Jul 29, 2009 at 11:26 AM, Adam Taylor<[hidden email]> wrote:

> Hi All,
>
> I'm using AJAX to call my plugin script to process data and update what is
> displayed (essentially a thumbs up/thumbs down voting plugin).  This is
> fine, I can update the text but I need to also interact with the database.
>
> As I understand, because I am calling my script directly not from within
> wordpress $wpdb is not available.
>
> I read that you can include wp-blog-header.php and everything should be
> available and have added - require_once('../../../wp-blog-header.php');  -
> to the function requiring it, however, I get the following error:
>
> PHP Fatal error:  Call to a member function set_prefix() on a non-object in
> /dev/site/wp-settings.php on line 255
>
> Firstly: what's going on here and how can I fix it?
>
> Secondly: is this the best way of doing this? I can't find any tutorials or
> documents about writing an ajaxy plugin for wordpress that interacts with
> the database. This topic http://wordpress.org/support/topic/184095 suggests
> that it is not but I don't understand the suggested solutions.
>
> Thanks in advance,
> Adam
>


---
Sweet Interaction Ltd is Registered in England/Wales, no. 6610741
Registered office: 7 Malton Av, Manchester, M21 8AT
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers

No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.392 / Virus Database: 270.13.35/2270 - Release Date: 07/29/09 06:12:00
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Eric Marden-2
> you can't guarantee the relative location
> of wp-load.php to your plugin files (they might have moved wp-content
> outside the main WP files, etc, etc)...

On Jul 29, 2009, at 2:45 PM, Silverstein, Jesse wrote:
> Re: Simon's problem of plugin directory location & editing plugin  
> files:
>
> I think if your plugin file has loaded, it's safe to assume that  
> ABSPATH has been defined, and you can go from there.


ABSPATH is only created for you if wp-load.php is called. If you're  
sending some processing out to userland, you may need to carry that  
path around with you. Like Simon noted if you move your WP files  
around to nonstandard places, you can't be sure where wp-load.php is,  
and hence will not have any CONSTANTS defined when you need them. One  
(sort of) inelegant solution is to wrap your JS file in a PHP script  
and pass the path into to dynamically write your ajax URLs therein.

I've been bitten by this since I put WP in its own folder via  
svn:externals, move my wp-content folder elsewhere and do other custom  
stuff in my set-up. If for some reason wp-load.php needs to be  
included directly into another script (in a plugin, ajax endpoint,  
etc) and the code depends on wp-load.php to be relative to wp-content,  
then you run into troubles.

There is more than one plugin that won't work with my custom set-up  
because of this very issue. I haven't found a good work around to this  
yet.



- Eric Marden
__________________________________
http://xentek.net/code/wordpress/





_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

Otto-19
The short of it is that there is never really a need for your plugin
to directly include the WordPress code, via wp-load or wp-config or
anything else.

The cases where people try to do this are multiple, but end up being
resolvable through different means.

Case 1: AJAX.
You have your plugin calling some file in the plugin via script tags
or ajax or something, and you think "hey, since I need access to the
DB, this ajax file I'm making needs to include wp-load". False, your
plugin needs to hook into the wp_ajax_* actions and you need to make
the page make a call to admin_url('admin-ajax.php'); with a proper
?action=whatever parameter.

Case 2: You need to get some kind of output from a separate call to a
file in your plugin.
You have your plugin calling some other file in the plugin, which
produces some special kind of output (image, text, whatever), and it
needs access to WordPress functions and such, so you want to include
wp-load. Again, false. Your plugin needs to hook into
template_redirect and add a query variable so it can recognize when
it's being called. Example:

add_filter('query_vars', 'add_my_var');
function add_my_var($public_query_vars) {
        $public_query_vars[] = 'some_unique_identifier';
        return $public_query_vars;
}

add_action('template_redirect', 'my_var_output');
function my_var_output() {
        $myvalue=get_query_var('some_unique_identifier');
        if ($myvalue) {
                // do whatever output you like here
                // you can even use $myvalue to see what the request is for
                exit; // this stops WordPress entirely
        }
}

Any call to the main WP url with ?=some_unique_identifier=whatever
will now cause your output to run and WordPress to stop execution
afterwards. So you can override the output with anything you like.
Want an image output? Throw out a header() call to set the mime type
and output the image data. And since you're in a plugin context, you
have WP functions available to you.

So, never include wp-load (or blog-header or config, etc) from a
plugin, even a separate file. It's simply not necessary.

-Otto
_______________________________________________
wp-hackers mailing list
[hidden email]
http://lists.automattic.com/mailman/listinfo/wp-hackers
Reply | Threaded
Open this post in threaded view
|

Re: ajax and $wpdb

idavidson
This post has NOT been accepted by the mailing list yet.
In reply to this post by Jennifer Hodgdon
Thank you, Scribu! I never would have guessed that the "nopriv" addition was required.