Undefined index when setting WordPress custom options variables? - wordpress

I have my custom options set like this...
function my_options_init(){
register_setting(
'myoptions',
'myoptions',
'myoptions_validate'
);
}
add_action( 'admin_init', 'my_options_init' );
...and I'm used to setting variables on my custom settings page in this manner...
$myoptions = get_option( 'myoptions' );
$foo = $myoptions['foo'];
But when debugging is enabled I get an error:
Notice: Undefined index: foo
The solution as I understand it is to do this...
if(isset($myoptions['foo'])) {
$foo = $myoptions['foo'];
}
..which makes the error go away.
The problem is that I have many variables I want to use in my plugin, and it seems like a lot of unnecessary work to do this every time I need to use a variable.
Then I stumbled on this in another topic:
"...to avoid having to include this check everytime you are getting a
setting from $myoptions - would be to review your
myoptions() function and make sure it returns an
array that includes every setting, including default values for those
settings that are not saved in the database yet."
My question is, how would I go about doing that?

You can setup a function for default values. Then when you fetch plugin option, you can fetch options with defaults. After that even if there is no options in the database, function will get value from default. So no PHP notice. Please check following example.
function wpso_get_default_options() {
// Default plugin options.
$default = array(
'foo' => 1,
'bar' => 'left',
);
return $default;
}
function wpso_get_plugin_option( $key ) {
$defaults = wpso_get_default_options();
$plugin_options = get_option( 'myoptions' );
$plugin_options = wp_parse_args( $plugin_options, $defaults );
$value = null;
if ( isset( $plugin_options[ $key ] ) ) {
$value = $plugin_options[ $key ];
}
return $value;
}

Related

How to extends a TimberPost

Probably it is something obvious and has escaped under my nose.
I did not understand how to hook my extended class to timber.
Let's take the example of the issues. How can I get an object like MySitePost when I call Timber::query_post()?
So now I’ve got an easy way to refer to the {{ post.issue }} in our twig templates.
Looks like an automatic process... but I'm not so sure about this!
For reference:
https://timber.github.io/docs/guides/extending-timber/
I think this is a good question that might not be so obvious.
To use your custom post, you’ll often find a parameter when fetching posts where you can pass the name of your custom class. The returned object will then be instances of your custom class.
$posts = Timber::get_posts( $your_args, 'MySitePost' );
$posts = new Timber\PostQuery( $your_args, 'MySitePost' );
When you want to fetch a single post, it works quite similar. You can either directly instantiate your post or pass your post class to the function.
$post = new MySitePost();
$post = Timber::get_post( $post_id, 'MySitePost' );
If you want to set a default class to be used for your posts, you can use the Timber\PostClassMap filter:
// Use one class for all Timber posts.
add_filter( 'Timber\PostClassMap', function( $post_class, $post_type ) {
return 'MySitePost';
}, 10, 2 );
// Use default class for all post types, except for pages.
add_filter( 'Timber\PostClassMap', function( $post_class, $post_type ) {
// Bailout if not a page
if ( 'page' !== $post_type ) {
return $post_class;
}
return 'MySitePost';
}, 10, 2 );
// Use a class map for different post types
add_filter( 'Timber\PostClassMap', function( $post_class, $post_type ) {
return array(
'post' => 'MySitePost',
'apartment' => 'MyApartmentPost',
'city' => 'MyCityPost',
);
}, 10, 2 );

Use Wordpress shortcode function to render Gutenberg block, sending the attributes as parameters

I have a shortcode that generates a gallery, given the gallery ID.
function rb_scroll_gallery_shortcode( $atts, $content ) {
$a = shortcode_atts( array(
'id' => -1,
), $atts );
$gallery_ID = $a['id'];
$output = '';
if($gallery_ID != -1){
ob_start();
$gallery = new RB_Scroll_Gallery($gallery_ID);
$gallery->render();
$output = ob_get_clean();
}
return $output;
}
add_shortcode( 'rb_scroll_gallery', 'rb_scroll_gallery_shortcode' );
Now, I've made a Gutenberg block that works perfectly in the editor. You can select a gallery and it will save. However, I dont want to repeat code and have the html in the save property and in the php code.
So I was wondering if there is a way to use that same rb_scroll_gallery_shortcode function to render the block in the front end.
I've seen that you can use register_block_type and set the render_callback to rb_scroll_gallery_shortcode, but I need the ID selected in the block to send it to the function in the $atts array
//This uses the shortcode funtion, but doesn't gives the gallery ID
register_block_type( 'cgb/block-rb-scroll-gallery-block', array(
'render_callback' => 'rb_scroll_gallery_shortcode',
) );
You can try to Convert a Shortcode to a Gutenberg Block and after use in your theme,
Registering the Dynamic Block Callback in PHP
/**
* Register the GitHub Gist shortcode
*/
function gggb_init() {
add_shortcode( 'github-gist', 'gggb_render_shortcode' );
register_block_type( 'github-gist-gutenberg-block/github-gist', array(
'render_callback' => 'gggb_render_shortcode',
) );
}
add_action( 'init', 'gggb_init' );
When your block is rendered on the frontend, it will be processed by your render callback:
function gggb_render_shortcode( $atts ) {
if ( empty( $atts['url'] )
|| 'gist.github.com' !== parse_url( $atts['url'], PHP_URL_HOST ) ) {
return '';
}
return sprintf(
'<script src="%s"></script>',
esc_url( rtrim( $atts['url'], '/' ) . '.js' )
);
}
**Note:** this render callback is intentionally different than the Gutenberg block’s edit callback. Our preference is to use GitHub’s provided JavaScript embed code because this lets GitHub change the embed’s behavior at a future date without requiring a developer to make changes.
Refer link for get more information, https://pantheon.io/blog/how-convert-shortcode-gutenberg-block
I've found out the little thing that messed up my code. The problem wasn't that the render_callback() wasn't getting any attributes (though it wasn't), but it was that the editor wasn't saving them because I forgot to remove some testing data from the attribute galleryID
In the registerBlockType:
The save() method should return null.
The attribute should not have a selector data, since it is used to find the value on the markup return by the save(), wich in this case returns null. I've forgot to remove this data, thats why the attribute wasn't being saved.
attributes: {
galleryID: {
type: 'string',
//This data should only be set if the value can be found in the markup return by save().
//Since save() returns null, we let it out
/*source: 'attribute',
/*attribute: 'data-gallery-id',
/*selector: '.rb-scroll-gallery-holder',*/
},
}

WooCommerce Undefined Property stdClass::$url

When i am installing woocommerce and logged out from my site then on home page woocommerce causes this problem.My wp-config.php is turned true , that is why its showing this error. but i need to know what is happening
Notice: Undefined property: stdClass::$url in /home/......./wp-content/plugins/woocommerce/includes/wc-page-functions.php on line 123
Line 123 of that file is within the following piece of code:
function wc_nav_menu_items( $items ) {
if ( ! is_user_logged_in() ) {
$customer_logout = get_option( 'woocommerce_logout_endpoint', 'customer-logout' );
if ( ! empty( $customer_logout ) ) {
foreach ( $items as $key => $item ) {
$path = parse_url( $item->url, PHP_URL_PATH );
$query = parse_url( $item->url, PHP_URL_QUERY );
if ( strstr( $path, $customer_logout ) || strstr( $query, $customer_logout ) ) {
unset( $items[ $key ] );
}
}
}
}
return $items;
}
add_filter( 'wp_nav_menu_objects', 'wc_nav_menu_items', 10 );
Notice on the last line there is a filter hook for wp_nav_menu_objects. So this function is used to filter the nav menu, and specifically looks like it is there solely so that WooCommerce can hide a logout menu object when the user is not logged in.
Now to the reason why the error is being thrown. I believe it stems back to the wordpress hook wp_nav_menu_objects. When looking at the function again it looks like the argument getting filtered named $items is expected to be a keyed array of stdClass instances, however on line 123 PHP is discovering that the url property is not available. This leads me to believe that another filter that occurs before this one is incorrectly modifying the $items array so that this filter can not correctly read the property.
Looking further in the file wc-page-functions.php on line 185 there is another hook for this filter:
add_filter( 'wp_nav_menu_objects', 'wc_nav_menu_item_classes', 2 );
However checking wc_nav_menu_item_classes reveals that it does not do anything special either. So here are my suggestions based on what has been presented:
Make sure that WordPress is up to date, the version of WooCommerce you are running maybe incompatible.
If you have code that filters wp_nav_menu_objects, make sure that you have not introduced a bug that changes the $items array to no longer contain instances of stdClass.
Try disabling/enabling 3rd party plugins that are not WooCommerce, you may find that one of these if out of date or just bugged.
Best of luck!
Koda

How can I make a WordPress custom function available in a Timber index page?

I'm trying to convert my standard PHP WordPress theme to Timber/Twig and am having trouble getting any output from custom functions. This one in particular looks to see if the post has a Yoast Primary Term set, which allows you to specify a primary category for a post that has multiple categories.
I need to do this in within The Loop and most of the documentation talks about how to do it in a single page. I have a function like this in my functions.php:
function my_theme_get_post_category() {
// regular list of categories set in WP
list( $wp_category ) = get_the_category();
// primary category set with Yoast plugin
$primary_category = new WPSEO_Primary_Term( 'category', get_the_ID() );
$primary_category = $primary_category->get_primary_term();
$primary_category = get_category( $primary_category );
// use only one or the other
if ( is_wp_error( $primary_category ) || $primary_category == null ) {
$category = $wp_category;
} else {
$category = $primary_category;
}
return $category;
}
Based on what I've read in the "Functions" section here (https://github.com/timber/timber/wiki/WP-Integration#functions), I should be able to call this in my template with {{ function('my_theme_get_post_category', post.ID) }}, but that does not work.
I tried making $postID a required parameter of the function, but that also didn't help anything.
I also tried using the TimberHelper::function_wrapper and then calling it in the template with {{ my_theme_get_post_category }} but, again, that didn't accomplish anything.
If you use {{ function('my_theme_get_post_category', post.ID) }}, then the function that you call needs to accept the argument that you pass. When you use…
function my_theme_get_post_category() {
// Your function code
}
… then your post ID won’t be passed to the function. As you mentioned, you probably already tried to add the post id as a parameter:
function my_theme_get_post_category( $post_id ) {
// Your function code
}
And nothing happened. That’s because your function uses functions that depend on The Loop, like get_the_category() or get_the_ID(). These functions get the current post id from global variables, which are not always set when you loop through posts in Timber.
When using Timber, you need to tell these functions to use a certain post id. If you look at the documentation for get_the_category(), you see that there’s one optional argument that you can pass: the post id.
For the other function, get_the_ID(), you can simply replace it with the parameter $post_id that you pass to your function.
function my_theme_get_post_category( $post_id ) {
// regular list of categories set in WP
list( $wp_category ) = get_the_category( $post_id );
// primary category set with Yoast plugin
$primary_category = new WPSEO_Primary_Term( 'category', $post_id );
$primary_category = $primary_category->get_primary_term();
$primary_category = get_category( $primary_category );
// use only one or the other
if ( is_wp_error( $primary_category ) || $primary_category == null ) {
$category = $wp_category;
} else {
$category = $primary_category;
}
return $category;
}

changing the wordpress gallery image size default

I was wondering if any could help on my problem
I have this code from someone that runs fine except that the size does not function, default is always on "thumbnail"
function my_gallery_default_type_set_link( $settings ) {
$settings['galleryDefaults']['link'] = 'file';
$settings['galleryDefaults']['columns'] = '4';
$settings['galleryDefaults']['size'] = 'large';
return $settings;
}
add_filter( 'media_view_settings', 'my_gallery_default_type_set_link');
how can I make this always in large as a default?
This piece of code is actually working, the size of the gallery will be "large" by default if an other size is not manually selected. The real problem come from the dropdown itself that is not correctly set on initialisation, still in WP 4.8.2.
There is a ticket open with more details about this display error.
In the meantime, I found a workaround using the print_media_templates hook :
Step 1 - Define your gallery default image size
function my_gallery_default_settings( $settings ) {
$settings['galleryDefaults']['size'] = 'large';
return $settings;
}
add_filter( 'media_view_settings', 'my_gallery_default_settings');
Step 2 - Debug the dropdown image size default value
function debug_gallery_image_size_default_value() {
?>
<script>
jQuery(document).ready(function(){
wp.media.view.Settings.Gallery = wp.media.view.Settings.Gallery.extend({
template: function(view){
var base_view = wp.media.template('gallery-settings')(view);
var size_option_search = '<option value="'+wp.media.gallery.defaults.size+'">';
var size_option_replace = '<option value="'+wp.media.gallery.defaults.size+'" selected="selected">';
base_view = base_view.replace(size_option_search, size_option_replace);
return base_view;
}
});
});
</script>
<?php
}
add_action('print_media_templates', 'debug_gallery_image_size_default_value');
Why are you using someone else's custom code? There is already a Gallery shortcode with size option in it:
https://codex.wordpress.org/Gallery_Shortcode
Just call it with [gallery size="thumbnail"].
Actually, other code in other answers replaces default settings for existing galleries. Here's the code to apply default settings only to the new gallery:
add_filter( 'media_view_settings', 'theme_gallery_defaults', 10, 2 );
function theme_gallery_defaults( $settings, $post ) {
$defaults = ! empty( $settings['galleryDefaults'] ) && is_array( $settings['galleryDefaults'] ) ? $settings['galleryDefaults'] : array();
$settings['galleryDefaults'] = array_merge( $defaults, array(
'columns' => 5,
'size' => 'large',
'link' => 'file'
) );
return $settings;
}

Resources