Wordpress custom plugin shortcode wpdb unknown - wordpress

I'm writing a custom plugin in wordpress and I'm using a shortcode for the first time.
Until now my shortcode works but now I want to execute a query in the function of that shortcode to get all the employees from a specific employee group id
[employee_group_tag group_id=2]
This is the file that has my shortcode functionality:
<?php
/*
Plugin Name: Employees
Plugin URI: xxx
Description: xxx
Version: 1.0
Author: xxx
Author URI: http://www.blabla.com
*/
global $wpdb;
function employee_shortcode_func( $atts ) {
extract( shortcode_atts( array(
'group_id' => '0',
), $atts ) );
// Alle werknemers ophalen adhv van group_id
$sql = 'SELECT * FROM wp_werknemers_employees WHERE employee_employee_group_id = ' . $group_id;
$results = $wpdb->get_results($sql);
return 'test';
}
add_shortcode( 'employee_group_tag', 'employee_shortcode_func' );
But when I run this it gets stuck on $wpdb->get_results($sql) because when I leave this out it displays my page correctly but when I want to fill it with employee details I only get the half of my page. So it "breaks"
I tried to do (which works in all my other files)
require_once("../../../wp-config.php")
But it doesn't work...
Is it possible that it's not working because its in my "main" plugin file? Because in all my other files I can use wpdb when I use the require function...
any ideas?

From the PHP Manual:
For the most part all PHP variables only have a single scope. This single scope spans included and required files as well. For example:
$a = 1;
include 'b.inc';
Here the $a variable will be available within the included b.inc script. However, within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope. For example:
$a = 1; /* global scope */
function test()
{
echo $a; /* reference to local scope variable */
}
test();
The last example does not work, as $a is not defined inside the scope of the function.
Just like in your case, for it to work you have to use:
function employee_shortcode_func( $atts ) {
global $wpdb;
// etc
}

Related

Change custom postType properties from parent theme in Wordpress

I'm building a childtheme for an excisting Wordpress theme.
The parent theme creates a custom post type, that has a property "rewrite" property that I would like to get rid of.
'rewrite' => array(
'slug' => 'project'
)
I found that it is possible to alter / add taxonomies on excisting custom post types like this:
register_taxonomy_for_object_type( 'category', 'CUSTOM_POST_NAME' );
But is it posible to change this (and other) properties?
The key here is the call to register_post_type. This is what actually registers the post type within WordPress.
In the docs, we see that the function is defined in /wp-includes/post.php. We can also see the full source code of the function, which is very handy.
In the source code of the function, we can see that there's only a single do_action() and that's called after the post type is fully registered.
So, the next place to look at is in the WP_Post_Type class. We can again expand the full source code(or you can look through the source code in your favorite text/code editor). The first place to look at is the __construct() method of the class. This currently(WordPress 4.8) consists of the following:
public function __construct( $post_type, $args = array() ) {
$this->name = $post_type;
$this->set_props( $args );
}
So, as you can see, the name is assigned to $this->name and then the method set_props() is called with the passed $args(which is the array of parameters sent to register_post_type().
The next logical place to look at is inside of the set_props() method. And at pretty much the very top of that method is the following code:
/**
* Filters the arguments for registering a post type.
*
* #since 4.4.0
*
* #param array $args Array of arguments for registering a post type.
* #param string $post_type Post type key.
*/
$args = apply_filters( 'register_post_type_args', $args, $this->name );
Bingo! The passed $args are passed through the register_post_type_args filter before they're used in initializing the post type.
So now, the final piece of the puzzle is to create your own function, attach it to the register_post_type_args filter, make sure you're changing the correct post type and you're free to do whatever you want with that post type. Here's a sample code to help you out:
function my_filter_register_post_type_args( $args, $post_type ) {
// We only want to edit the 'CUSTOM_POST_NAME' post type - if that's not it, then bail
if ( 'CUSTOM_POST_NAME' != $post_type ) {
return $args;
}
$args['rewrite'] = false;
return $args;
}
add_filter( 'register_post_type_args', 'my_filter_register_post_type_args', 10, 2 );
I hope this will help you and anyone else out there see how easy it can be to dive into the source code of WordPress(you can even do it from your browser now :) ) in order to figure out something that might not always be just a search away. With some critical thinking, you can follow the breadcrumb trail in order to figure out what the best way to tweak something is.

wordpress remove post status count from cms

I want to remove the post status count from WordPress edit.php.
My WordPress CMS have more than 500,000 posts. The publish count is loaded every time you open the page. The following query is fired every time.
This makes my Wordpress CMS loading very slow.
SELECT post_status, COUNT( * ) AS num_posts FROM wp_posts WHERE post_type = 'post' GROUP BY post_status
By tracing the code, I've worked up the only solution that I can see.
The filter bulk_post_updated_messages is ONLY called on the edit.php screen.
The counts are not calculated (in class-wp-posts-list-table.php, get_views method) if the global variable $locked_post_status is not empty.
By gluing these two pieces of information together, I've got a solution that you can use by dropping it into your theme's functions.php file:
// Hook this filter, only called on the `edit.php` screen.
// It's not the "correct" filter, but it's the only one we can leverage
// so we're hijacking it a bit.
add_filter('bulk_post_updated_messages', 'suppress_counts', 10, 2);
// We need to let the function "pass through" the intended filter content, so accept the variable $bulk_messages
function suppress_counts($bulk_messages) {
// If the GET "post_type" is not set, then it's the "posts" type
$post_type = (isset($_GET['post_type'])) ? $_GET['post_type'] : 'post';
// List any post types you would like to KEEP counts for in this array
$exclude_post_types = array('page');
// Global in the variable so we can modify it
global $locked_post_status;
// If the post type is not in the "Exclude" list, then set the $locked variable
if ( ! in_array($post_type, $exclude_post_types)) {
$locked_post_status = TRUE;
}
// Don't forget to return this so the filtered content still displays!
return $bulk_messages;
}
i came up with this solution.
//Disable Article Counter - query runs for about 1-2 seconds
add_filter('admin_init', function () {
foreach (get_post_types() as $type) {
$cache_key = _count_posts_cache_key($type, "readable");
$counts = array_fill_keys(get_post_stati(), 1);
wp_cache_set($cache_key, (object)$counts, 'counts');
}
}, -1);
add_action('admin_head', function () {
$css = '<style>';
$css .= '.subsubsub a .count { display: none; }';
$css .= '</style>';
echo $css;
});
the post counter uses the wp-cache, the idea behind this approach is, to prefill the cache with the "correct" object containing 1's (0 would skip the status from being clickable) - at the earliest moment.
it results in all stati being displayed - with 1's and the query is not run et-all
in addition it returns a css snippet to hide the (1)

Wordpress PHP warning: Creating default object from empty value in wp-admin\includes\post.php on line 627

I am using Wordpress 4.2.2, Xampp installation in windows with PHP 5.6.8
I have added the following function to my theme's functions.php to automatically set the title of the post type 'departure':
function custom_title() {
if ($_POST['post_type'] == 'departure') :
$post_title = 'Departure-'.$_POST['post_ID'];
return $post_title;
endif;
}
add_filter ( 'title_save_pre', 'custom_title' );
Title setting for the custom post type "departure" works fine. But when I try to add a new wordpress standard post (i.e. post_type = post) I get the following error:
Warning: Creating default object from empty value in wp-admin\includes\post.php on line 627
Line 627 is as follows:
/**
* Filter the default post content initially used in the "Write Post" form.
*
* #since 1.5.0
*
* #param string $post_content Default post content.
* #param WP_Post $post Post object.
*/
$post->post_content = apply_filters( 'default_content', $post_content, $post );
All the other post types (i.e. custom types and wordpress standard page) work fine. By dumping $_POST data in a logfile I have seen, that for all the working post-types an empty array (i.e. array()) is passed as $_POST data. This does not happen with the "post" post type.
If I comment the function in functions.php, an empty array is sent as $_POST data when adding a new "post" post type, and the problem disappears.
Any ideas?
Thanks
You need to return a value, even if the post type isn't departure. The function should take an argument, and return something:
function custom_title($post_title) {
if ($_POST['post_type'] == 'departure') {
$post_title = 'Departure-'.$_POST['post_ID'];
}
return $post_title;
}
add_filter ( 'title_save_pre', 'custom_title' );

Using $wpdb object in Wordpress functions.php file

I have an issue with not being able to call the get_results() function on the $wpdb object inside the Wordpress functions.php file.
Exact error: Call to a member function get_results() on a non-object in [...]
This is my function;
global $wpdb;
function query_students($year){
$wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}usermeta WHERE meta_key ='foobar' AND meta_value = '{$year}'"
)
);
$wpdb->flush();
}
As you can see I've globalised the $wpdb variable, and this function works great in the page template file. I would just prefer it if my functions weren't dotted around the place, and in some kind of centralised file.
Thanks in anticipation! :)
"Globalizing" a variable that's already in global scope does nothing. Case and point:
global $a; //does nothing
$a = 'foo';
global $a; //does nothing
foo();
echo $a; //'foo'
bar();
echo $a; //'bar'
function foo()
{
$a = 'bar';
}
function bar()
{
global $a;
$a = 'bar';
}
The global keyword does not permanently make the defined variable global in scope. Think of it as a way to define a variable in a function and set its value to whatever a variable with the same name is outside of the function.
You need to move your global declaration INTO the function to make the $wpdb object in the Global scope available within the function's scope:
function query_students($year){
global $wpdb;
$wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}usermeta WHERE meta_key ='foobar' AND meta_value = '{$year}'"
));
$wpdb->flush();
}
I was running following query in functions.php
SELECT `id`, `user`, `width`, `type`, `source`, `link`, `expire`, `impressions`, `clicks` FROM adds WHERE `width`=728 and `impressions` < (SELECT max(`impressions`) FROM adds WHERE `width`=728 ) or `width`=728 and `clicks` < (SELECT max(`clicks`) FROM adds WHERE `width`=728 ) ORDER BY RAND() LIMIT 3
it was not working but after adding the line
global $wpdb in the begining of the function helped me and query is running fine.
Thanks

setting variable in header.php but not seen in footer.php

in wordpress ,
i set a variable in header.php
<?php
$var= 'anything'
?>
but in footer.php when I echo it
<?php
echo $var;
?>
I got no thing printed ... why !>
You're not in the same scope, as the header and footer files are included in a function's body. So you are declaring a local variable, and referring to another local variable (from another function).
So just declare your variable as global:
$GLOBALS[ 'var' ] = '...';
Then:
echo $GLOBALS[ 'var' ];
I know you've already accepted the answer to this question; however, I think there's a much better approach to the variable scope problem than passing vars into the $GLOBALS array.
Take the functions.php file in your theme for example. This file is included outside the scope of the get_header() and get_footer() functions. In fact it supersedes anything else you might be doing in your theme (and I believe in the plugin scope as well--though I'd have to check that.)
If you want to set a variable that you'd like to use in your header/footer files, you should do it in your functions.php file rather than polluting $GLOBALS array. If you have more variables that you want to sure, consider using a basic Registry object with getters/setters. This way your variables will be better encapsulated in a scope you can control.
Registry
Here's a sample Registry class to get you started if:
<?php
/**
* Registry
*
* #author Made By Me
* #version v0.0.1
*/
class Registry
{
# +------------------------------------------------------------------------+
# MEMBERS
# +------------------------------------------------------------------------+
private $properties = array();
# +------------------------------------------------------------------------+
# ACCESSORS
# +------------------------------------------------------------------------+
/**
* #set mixed Objects
* #param string $index A unique index
* #param mixed $value Objects to be stored in the registry
* #return void
*/
public function __set($index, $value)
{
$this->properties[ $index ] = $value;
}
/**
* #get mixed Objects stored in the registry
* #param string $index A unique ID for the object
* #return object Returns a object used by the core application.
*/
public function __get($index)
{
return $this->properties[ $index ];
}
# +------------------------------------------------------------------------+
# CONSTRUCTOR
# +------------------------------------------------------------------------+
public function __construct()
{
}
}
Save this class in your theme somewhere, e.g. /classes/registry.class.php Include the file at the top of your functions.php file: include( get_template_directory() . '/classes/registry.class.php');
Example Usage
Storing variables:
$registry = new Registry();
$registry->my_variable_name = "hello world";
Retrieving variables:
echo '<h1>' . $registry->my_variable_name . '</h1>'
The registry will accept any variable type.
Note: I normally use SplObjectStorage as the internal datastore, but I've swapped it out for a regular ole array for this case.
I know this is a bit old question and with a solution voted but I though I should share another option and just found a better solution (that works) without using Globals
function fn_your_var_storage( $var = NULL )
{
static $internal;
if ( NULL !== $var )
{
$internal = $var;
}
return $internal;
}
// store the value
fn_your_var_storage( 'my_value' );
// retrieve value
echo fn_your_var_storage(); // print my_value
try this code
first define your initial variable
$var="something";
then use the $_GLOBALS
$_GLOBALS['myvar']=$var;
and finally use the global variable in anywhere you want
global $myvar;
define string inside the $_GLOBALS as taken as global variable name or use the $_GLOBALS['myvar'] direct into the code without using the global
In wordpress Header, any template, Footer is different functions so you have to declare any varible as a global variable then you can access it .
/** header.php **/
<?php
global $xyz;
$xyz="123456"; ?>
/** Template.php or Footer.php **/
<?php
echo $xyz; ///return 123456
?>

Resources