Hello I am trying to get lowest priority number from all the functions that hook into wp_head.
My code is this.
function wpcrown_wpcss_loaded() {
global $wp_filter;
$lowest_priority = max(array_keys($wp_filter['wp_head']));
add_action('wp_head', 'wpcrown_wpcss_head', $lowest_priority + 1);
$arr = $wp_filter['wp_head'];
}
add_action('wp_head', "wpcrown_wpcss_loaded");
But its shown error like this.
Warning: array_keys() expects parameter 1 to be array
Warning: max() [<a href='function.max'>function.max</a>]: When only one parameter is given, it must be an array in
Please help to solve this.
Thanks
As Benoti said $wp_filter is no longer an array so array_keys is throwing these warnings because expects an array.
If you want to add scripts / styles / whatever you have in wpcrown_wpcss_head at the end of the head (to give priority) this should work:
1) Comment this action:
// add_action('wp_head', "wpcrown_wpcss_loaded");
2) Use this one instead:
add_action('wp_head', "wpcrown_wpcss_head");
Hope it helps.
Be carefull on the use of $wp_filters as an array since WordPress 4.7,
Here is the guidelines for wp .4.,7
Make.wordpress that explain:
If your plugin directly accesses the $wp_filter global rather than using the public hooks API, you might run into compatibility issues.
Case 1: Directly setting callbacks in the $wp_filter array
$wp_filter['save_post'][10]['my_special_key'] = array( 'function' => 'my_callback_function', 'accepted_args' => 2 );
This will no longer work, and will cause a fatal error. $wp_filter['save_post'] is no longer a simple array. Rather, it is an object that implements the ArrayAccess interface.
You have two options to work around. The first (and preferred) method is to use the add_filter() or add_action() functions.
add_action( 'save_post', 'my_callback_function', 10, 2 );
If, for some reason, you absolutely cannot, you can still work around this.
if ( ! isset( $wp_filter['save_post'] ) ) {
$wp_filter['save_post'] = new WP_Hook();
}
$wp_filter[ 'save_post' ]->callbacks[10]['my_special_key'] = array( 'function' => 'my_callback_function', 'accepted_args' => 2 );
Case 2: Directly unsetting callbacks in the $wp_filter array
unset( $wp_filter['save_post'][10][ $my_callback_id ] );
This will fail for the same reason as case one. To work around, you can use the standard remove_filter() / remove_action() functions.
remove_action( 'save_post', 'my_callback_function', 10, 2 );
Or, if you absolutely must access the array directly:
if ( isset( $wp_filter[ 'save_post' ] ) ) {
unset( $wp_filter['save_post']->callbacks[10][ $my_callback_id ] );
}
Case 3: Checking if a hook is an array
if ( isset( $wp_filter['save_post'] ) && is_array( $wp_filter['save_post'] ) ) {
// do something
}
This will always return false. $wp_filter['save_post'] is a WP_Hook object. To check if a hook has callbacks, use has_action() or has_filter()
if ( has_action( 'save_post' ) ) {
// do something
}
Case 4: Moving the $wp_filter array pointer manually
If you’re calling next() or prev() on the $wp_filter array pointer to manually manage the order that callbacks are called in (or if you’re doing it to work around #17817), you will likely be unsuccessful. Use callback priorities, add_action() / add_filter(), and remove_action() / remove_filter() appropriately and let WordPress manage execution order.
Related
I have posts with slugs with special characters. One of them is the following:
http://localhost/wp-json/wp/v2/posts?slug=my-post!
Unfortunately, WP REST API not showing the content since it has (!) within the slug.
Is there any solution you guys would recommend?
I have found the solution (at least for my case), not sure if it'll work for you but may indicate you the way to go. We need to tap into the function used to sanitize the slugs, as I said in my comment, by default is wp_parse_slug_list. Looking at the code the function that actually sanitizes the slug is sanitize_title.
Looking at the source code, wp_parse_slug_list calls sanitize_title with only one argument, which means that the context used is save. This means that, for posts that were already saved without being sanitized by this function, the slug won't match and the post will be inaccessible through the API. The solution is to change the sanitizing function slightly by adding a filter:
add_filter('rest_post_collection_params', function($query_params) {
$query_params['slug']['sanitize_callback'] = 'sanitize_rest_api_slug';
return $query_params;
}, 20, 1);
function sanitize_rest_api_slug( $list ) {
if ( ! is_array( $list ) ) {
$list = preg_split( '/[\s,]+/', $list );
}
foreach ( $list as $key => $value ) {
$list[ $key ] = sanitize_title( $value, '', 'query' );
}
return array_unique( $list );
}
The filter is actually being applied on the function get_collection_params() on the class-wp-rest-posts-controller class, but if you look at the source code, the filter has a variable depending on the post_type, so if you have another special kind of posts defined (besides post) you need to add/change a filter for that kind as well.
I hope this helps somebody else like me, even if it's too late for your issue.
Can Wordpress shortcodes have attributes without values like this?
[foo some_att]
I know it can be like this:
[foo some_att=""]
Can I have shortcode values like this (with curly braces)?
[foo path="{'quality': '720p', 'mp4': 'PATH_TO_MP4_VIDEO'}"]
You sure can! RichJenks has a short yet informative article on implementing this functionality, which boils down to defining a new function that can tell you if a flag (argument with no associated value) is present in your $atts array:
function is_flag( $flag, $atts ) {
foreach ( $atts as $key => $value )
if ( $value === $flag && is_int( $key ) ) return true;
return false;
}
After defining this function, you can reference is_flag() in your shortcode function to tell if the flag has been provided as part of the shortcode invocation:
if is_flag( 'some_att', $atts )
// flag is present
else
// flag is not present
Unfortunately, the example you've provided wouldn't work as an argument value with the Wordpress shortcode parser. According to the official Wordpress documentation on the Shortcode API:
Attribute values must never contain the following characters:
Square braces: [ ]
Quotes: " '
Since your example makes use of the single-quote character ('), it is officially unsupported by the shortcode parsing engine.
You can use this for first question.
is_int( array_search( 'some_att', $atts ?: [] ) )
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.
I use the_posts filter to add an object to each queried post. When access the added object, I get different result by using $post or get_post.
This is the code to attach the object to posts:
add_filter( 'the_posts', 'populate_posts_obj', 10,2 );
function populate_posts_obj( $posts, $query ){
if ( !count( $posts ) || !isset($query->query['post_type']) )
return $posts;
if( in_array( $query->query['post_type'], get_valid_grade_types())){
foreach ( $posts as $post ) {
if ( $obj = new Gradebook( $post->ID ) )
$post->gradebook = $obj;
}
}
return $posts;
}
Then, access the obj via $post, sometimes get the obj, sometimes not (even when it's the same post):
function get_the_gradebook(){
global $post;
return isset($post->gradebook) ? $post->gradebook : null;
}
Access the obj via get_post(), always get the obj:
function get_the_gradebook(){
global $post;
$p = get_post($post->ID);
return isset($p->gradebook) ? $p->gradebook : null;
}
I can just use the get_post() version, but it would be useful if I know why the difference.
Additional info:
If you ask the reason I attach an obj to each post, I think WordPress may take care of the caching process at the first place. Then, other caching plugins can work on my obj as if working on standard WP posts.
Lets explain you with a little bit pseudo code. I am trying to be broad with my approach so that my answer is relevant to StackOverflow however I still don't know how many down votes I may be receiving for this.
The simple difference is $post is a variable and get_post() is a method that means you can expect a different output from get_post() due to several dependencies however $post will only change when you explicitly do that.
Lets assume something like this
function get_post() {
return rand(0, 5);
}
$post = get_post(); /* lets assume random
value that was generated
this time was "2" */
Now each time you call get_post() its value be keep changing however the value of $post is always 2.
Coming back to the context of wordpress, $post is set using get_post() within the Loop and corresponds to the object referring to default post ID for current URL where as get_post() will take post ID as an input and return the post object.
$post is what WordPress considers to be the current "post" (post/page/custom post type) and can quite often end up giving you data you didn't quite expect. This is especially true if you perform WP_Query's in your template or have a template that uses data from several "posts".
By using get_post() with the ID you want the data from, you can be assured that you are getting the data you really want.
I keep getting this error when I put PHP error reporting on in my WordPress setup.
Notice: Only variable references should be returned by reference in /Users/admin/Sites/wp-includes/post.php on line 3394
I have a feeling it has to do with the taxonomies and their hierarchal setup.
Been trying to track it down for a while now in the plugin I'm writing.
These are the actual lines of code in the WP Core, the return being on the excact line.
// Make sure the post type is hierarchical
$hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
if ( !in_array( $post_type, $hierarchical_post_types ) )
return false;
I'll keep debugging it till I find the issue, but any input would be great seeing that i've not tracked down the issue in my plugin.
return false; - that's not a variable
Try something like
if ( !in_array( $post_type, $hierarchical_post_types ) ) {
$rv = false;
return $rv;
}
(side-note: I have no idea what wordpress and/or a mod you're using there is doing, but maybe/probably "return by reference" is a) unnecessary in the first place and b) a relict from a php4 implementation)