0

i am trying to make a dependend picklist set in a wordpress plugin. Within the plugin i have a javascript with the following method

             $('#am_organisation').change(function(){
            var val =  $(this).val();
            $.ajax({
                type: 'POST',
                url:  '/wp-content/plugins/harriecrm/admin/get-contacts.php',
                data:'organisation_id='+val,
                success: function(data){
                    $("#am_contact").html(data);
                    //$("#loader").hide();
                },
                error: function(xhr, status, error) {
                    alert(xhr.responseText);
                  }
                });
         });

the get-contacts.php file looks like

    <?php
       global $wpdb;
       global $xx;

       if(isset($_POST['organisation_id'])){

              $id = $_POST['organisation_id'];

              $listitems = $wpdb->prefix . 'am_contacts';
              $result = $wpdb->get_results ( "SELECT * FROM $listitems" );
              //foreach ( $result as $print ) {
               //      echo  '<option value="Maak een keuze">Maak een keuzesss-' . $id  . '</option>';

              //}

              //if($wpdb->query($sql)){
              //       $resp->uf_error = $wpdb->print_error();
              //       alert($resp);
              //};
              // $result = $wpdb->get_results ($strsql);
              //foreach ($result as $value) {                       
              // echo '  <option value='.$value->id.' '.$selected.'>'.$value->am_firstname. ", ".$value->am_firstname. '</option>    ';
              echo  '<option value="Maak een keuze">Maak een keuzesss-' . $id  . '</option>';     
              //}
       }
?>

i have tried a lot. I know the URL is good, and the page is being called. I have comment everything out except the echo line, i see that the pulldoen is being updated with that echo line.

BUt i want to use the $wpdb method to get rows from the database. But the moment i uncomment the line $result = $wpdb->get_results ( "SELECT * FROM $listitems" ); it does not work anymore. I get an empty errormessage. the alert(xhr.responseText); is being called but is empty. If i comment the $wpdb line out, then is works again.

I have really no clue what i am missing. The $wpdb I use very heavily and works like a charm except in the example here.

Any ideas? BR Marzel

1
  • 1
    I see you're using a standalone PHP file, this is dangerous, you should use a REST API endpoint for handling AJAX, or even WP Admin AJAX. By putting it in a standalone file you no longer have access out of the box to the WP APIs
    – Tom J Nowell
    Commented Jul 1, 2020 at 20:57

2 Answers 2

1

The reason your wpdb call fails is because there is no wpdb. You've taken the incorrect route of using a standalone PHP file, so there is no WordPress API. WordPress never gets loaded. That's not how you do AJAX in WordPress.

The solution is to do the AJAX call correctly and register a REST API endpoint.

E.g. in a plugin or a themes functions.php, register an endpoint:

add_action( 'rest_api_init', function () {
        register_rest_route( 'harriecrm/v1', '/contacts/', array(
                'methods' => 'GET',
                'callback' => 'get_contacts'
        ) );
} );

function get_contacts( $request ) {
    $id = $request['organisation_id'];
    .... your code goes here
    return "result";
}

Then make your AJAX request to yoursite.com/wp-json/harriecrm/v1/contacts and change it from a POST to a GET:

            $.ajax({
                type: 'GET',
                url:  '/wp-json/harriecrm/v1/contacts',

This gives you several advantages:

  1. You can expand the register_rest_route call to tell WP to expect an organisation ID, what format it takes, and it will do all the validating and sanitising for you!
  2. The endpoint goes away when you deactive the plugin, and it only appears on sites that have the plugin activated, closing a major security hole in your plugin
  3. You can put your code anywhere in your plugins codebase now
  4. The WordPress API, including wpdb is now loaded when your code runs
  5. The API is self documenting
  6. If you need to modify or add, you can register POST DELETE and other routes
  7. You can make register_rest_route handle authentication for you
  8. You can use tools such as Postman with this system
  9. If you redo your plugin you can do harriecrm/v2 so that things don't break for old code

And there are many other advantages. Using a standalone PHP file that you make direct requests to is extremely bad practice, and your question highlights one of the major issues.

1

Please add below lines on top of your php script

<?php

define( 'SHORTINIT', true );
$path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__);
require($path.'wp-load.php' );

and you are Done...

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Jun 24, 2022 at 14:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.