Wordpress wpdb undefined variable - wordpress

I'm writing a plugin and trying to request some data from a custom table in my database using:
$current_text = $wpdb->get_results("SELECT text FROM addtext ORDER BY id DESC LIMIT 1");
but just get the error Undefined variable: wpdb
Any idea why this isn't working? I've followed the docs and scoured Google, with no luck. Still pretty new to WP plugins so probably something obvious.
Thanks!

I needed to use global $wpdb; in my function.

One note to add: You cannot use global inside a class, and of course you have to use global in order to get your objects to work using $wpdb.
While you can't use global immediately inside a class, you must declare $wpdb as global inside a function inside the class, and this does work.
e.g. This gives you an error:
class wpdb_test {
global $wpdb; // can't use global as a direct 'child' of a class
public function __construct () {
...
}
}
Because global can't be used directly inside a class. Likewise, simply referencing $wpdb inside the class also gives you an error because the object doesn't know what $wpdb is. You have to declare $wpdb as global from inside a function that is inside your class.
e.g. This works just fine:
class wpdb_test {
public $variable_name;
public function __construct () {
global $wpdb; // safe to use because it's inside a function
...
}
}
...and because $wpdb has been declared global inside a function inside a class you are able to use it.

Related

Custom function error to produce a shortcode resulted in white screen of death

I followed the syntax the best I could to create a shortcode on execution, I got the wsod. Once removed, all was well. But I don't know what is wrong with my code. This code sits inside 'My Custom Functions', a plugin for wp.
In researching how to write a custom shortcode, I discovered instructions here: https://torquemag.io/2017/06/custom-shortcode/ My expertise is in mysql and use mostly plugins in our wordpress website. I am very limited with coding.
function last_updated_shortcode {
$last_updated = $wpdb->get_results( "SELECT MAX(process_time) FROM
qgotv.last_updated");
return $last_updated;
}
add_shortcode( 'last_updated', 'last_updated_shortcode' );
This shortcode should retrieve a max(datetime value) from a db table so it can be displayed on a page. The query works. The qgotv db is separate from the wordpress db but can be accessed through wp.
Two issues I can see, one is that you have a syntax error in your function. When defining a function in PHP, you need to include the arguments parenthesis: function my_function(){ /* Do Stuff */ }. Also, you probably need to reference the $wpdb with the global keyword.
You can read up a bit on the $wpdb class as well as creating your own functions.
This should get you sorted out:
add_shortcode( 'last_updated', 'last_updated_shortcode' );
function last_updated_shortcode(){
global $wpdb;
$last_updated = $wpdb->get_results( "SELECT MAX(process_time) FROM qgotv.last_updated");
return $last_updated;
}

Silverstripe has_one CMS dropdown filter before dropdown_field_threshold

I have a has_one in one of my models. But it exceeds the dropdown_field_threshold.
But in the getCMSFields method I have changed the query for that dropdown. But since it already exceeds the threshold before this method is called, the dropdown is converted to NumericDropdown or something like that.
Is there a way to alter the query before the threshold gets checked?
By the way, I know I can make a custom dropdown with my own query. But Silverstripe already handles a lot, so it would be better to just alter the query.
Edit: Example code
public function getCMSFields() {
$fields = parent::getCMSFields();
$questionnaire = $this->QuestionnaireSection()->Questionnaire();
$nextQuestionOptions = $questionnaire->Sections();
/** #var DropdownField $dropdownField */
$dropdownField = $fields->dataFieldByName("NextQuestionID");
$dropdownField->setSource($nextQuestionOptions->map()->toArray());
return $fields;
}
Unfortunately it is not possible to alter this query within the context of the class. An alternative may be to write your own scaffold function instead of calling parent::getCMSFields, but that is not really advised in this case.
If you have some way to obtain the current Questionnaire object globally, you could add an augmentDataQueryCreation function like below to QuestionnaireSection to add a where clause to the query that is being executed. Be aware however that this function is called in every case that QuestionnaireSection::get() is executed.
public function augmentDataQueryCreation(SQLSelect $query, DataQuery $dataQuery){
$baseTable = $this->baseTable();
$filter = 1; //Your global param here
$dataQuery->where("\"$baseTable\".\"QuestionnaireID\" = $filter");
}
An alternative to prevent the DropdownField from being replaced by a NumericField is to change the threshold of this switch by adding the following code to your mysite.yml. This does not solve your problem entirely, but is a good workaround.
SilverStripe\ORM\FieldType\DBForeignKey:
dropdown_field_threshold: 100000

WP Shortcodes not being added

I was creating a wordpress plugin where the user enters in some information, and is able to generate shortcodes. I was not quite sure where the shortcodes are supposed to go - my current setup is class-based, and I want to be able to create a shortcode when an AJAX request is being made, and is successful. The following two methods are in the same file in the class.
This method gets called via the admin-ajax.php file:
public static function processAjax()
{
global $wpdb;
$event_data = $_POST['obj'];
$event_title = $event_data[0];
$event_subdomain = $event_data[1];
$result_events = $wpdb->get_results("SELECT * FROM wp_shortcode_plugin WHERE subdomain = '{$event_subdomain}'", OBJECT);
if (sizeof($result_events)>0) {
echo "duplicate";
} else {
add_shortcode($event_subdomain, 'getEmbed');
$results = $wpdb->insert('wp_shortcode_plugin', array("event_name"=>$event_title, "subdomain"=>$event_subdomain));
echo json_encode($_POST['obj']);
}
die();
}
And here is my getEmbed() method that I would like to call.
public static function getEmbed()
{
return 'test';
}
It seems that the shortcodes are not being created, however. Am I missing something here? Also, is it possible to pass a value to the getEmbed function from the add_shortcode() method?
Instead of adding shortcode directly from AJAX, you should use update_option to store in the information for the shortcode to be loaded. If option doesn't exist, it will be created.
Than you will simple use wp_init hook to load up all of the shortcodes you need to load in the function.php file for the theme or plugin php file.
You should use get_option within the wp_init hook and check the values in there. You will need to have function(s) associated with the shortcodes, which can be autogenerated in php using create_function or you can route them through 1 function (defined in your php file) that will have the $atts and $content parameters defined and do whatever depending on the value of your get_option that you send to that function.
add_shortcode function should be defined within the wp_init hook, after checking the value of the get_option function. You will need to give your option a name and add to it via the ajax function. the option will most likely want to be an array, that wordpress will automatically serialize. Than you use that array returned from get_option to loop through the array of shortcodes, and call add_shortcode as many times as you need there. This requires setting up your option array so that it has a shortcode tag defined in each index of the array. I would, personally, make the shortcode tag the key of the array and all attributes of the shortcode, imo, would than be an array of that array.
Hope this helps you to get started on this.

Drupal 7 global $user variable

Would appreciate it, if anyone can let me know how we can set the global $user variable, so that we don't have to keep re-declaring it in each function, to access its contents. How can we declare it so that all the functions in a module can use it?
The type of global you're looking for (available always, in every scope) is called a superglobal in PHP. You cannot declare new superglobals, but you can access all globals directly because they are part of the $GLOBAL superglobal. In other words, you can use $GLOBALS['user'] to access the $user global directly.
See also create superglobal variables in php? for more info and alternative methods.
You can't...that's how globals work in PHP. If you want to import the global variable into your local function then you have to use the global keyword, there's no way round it. This is a 'feature' of the PHP language, it has nothing to do with Drupal.
An alternative method might be to implement a helper function:
function get_current_user() {
global $user;
return $user;
}
And call it like this:
$user = &get_current_user();
In your function if you want to use the $user variable, you just required to use/instantiate 'global' keyword before $user it. So that you can access all the data for that current user of the website.
For example
function myGenericFunc(){
global $user;
$user_id = $user->uid;
}
Note that you cannot redeclare it.
I hope it helps.

Include Wordpress Core into own Scripts

I'm trying to "Import" the Wordpress core into an own script to use the functionality such as wp_query etc. I've created an script in a subdirectory (own framework) and want to extend it by wordpress, but everytime the script throws an error:
Fatal error: Call to a member function add_rewrite_tag() on a non-object in .../wordpress/wp-includes/taxonomy.php on line 333
such as (when I remove the add_action( 'init', 'create_initial_taxonomies', 0 )):
Fatal error: Call to a member function add_rewrite_tag() on a non-object in .../wordpress/wp-includes/post.php on line 1006
The non-object is the $wp_rewrite-object. I've echo'ed something and figured out that first $wp_rewrite is valid and at the next call not. I've changed nothing at the WP core files.
I try to include the core by calling:
require_once(BASE_PATH . 'wp-load.php');
Has anybody some ideas for me?
thanks
Short answer, do this:
define('WP_USE_THEMES', false);
global $wp, $wp_query, $wp_the_query, $wp_rewrite, $wp_did_header;
require(BASE_PATH . 'wp-load.php');
Long answer, it's a subtle gotcha around importing scripts with PHP.
If you define a local variable, outside of all functions, then it can be retrieved inside a function using 'global'. If you have a local variable inside a function, it cannot be retrieved later using global, unless it is defined as being global there and then.
The script 'wp-settings.php' is where the issue lies. It is included via your call to include 'wp-load.php'.
The variables defined there are not stated as being global; instead this is presumed because the script is always run outside of any functions, and so are automatically global. i.e.
$wordpress = 'foo';
function wordpressFunction() {
global $wordpress;
}
Because you are importing the script within a function, they now become local variables. You are essentially doing:
function myFramework() {
$wordpress = 'foo';
function wordpressFunction() {
global $wordpress;
}
}
So the fix is to define them as global yourself before importing the script. Now $wp_query, and the others defined as global, are correctly found.
The easiest way to access everything wordpress has programmed in is to use the following:
require_once('/../../../wp-blog-header.php'); // Use actual root path to wp-blog-header.php
header("HTTP/1.0 200 OK");
Using the above code you'll get all functions you would normally get using a template with in WordPress. I've tried all the other methods listed above and this one is by far the best.
I had the same error. I wanted to get some articles along with permalinks. This helped:
global $wpdb, $wp_rewrite;
require '/(...)/wp-config.php';
$result = $wpdb->get_results( $wpdb->prepare( ... ) );
foreach( $result as &$item )
$item->link = get_permalink( $item->ID );
I also found this useful in another case:
http://www.stormyfrog.com/using-wpdb-outside-wordpress/

Resources