WordPress Shortcode: “Show If” for conditional content display

Here’s the code for a simple WordPress shortcode to conditionally display content within pages based on supplied usernames or roles.

 

Example Usage

Display to a specified user:


Display to a specified role:


Display to both a user and a role:


Display to multiple roles (comma separated list. “username” works the same):


 

Code

It’s in a GitHub gist at https://gist.github.com/vylesk/64ca3e6d3da77fb853ca7af181165e6b and below:

<?php
/**
* Plugin Name: "Show If" Shortcode
* Plugin URI: https://jsnelders.com/
* Description: Shortcode to conditionally display content if the user is in a specified role or has a specified username.
* Author: Jason Snelders
* Author URI: http://jsnelders.com
* Version: 190529.1
**/

namespace JasonSnelders\Shortcodes;

/*
*	Show the content only if the current user is one of the specified username(s) or in one ofthe role(s).
*
*	Attributes:
*		role: comma separated list of allowed roles to view the content.
*		username: comma separated list of allowed usernames to view the content.
*
*	Attrubtes combine as an OR expressess - content is displayed if they user is in the "role" list OR the "username" list.
*/
add_shortcode('show_if', 'JasonSnelders\Shortcodes\show_if_handler');

function show_if_handler($atts = [], $content = null)
{
	
	// Get supplied shortcode attributes.
	$show_if_role = "";
	$show_if_username = "";
	if(isset($atts["role"])) $show_if_role = $atts["role"];
	if(isset($atts["username"])) $show_if_username = $atts["username"];
	$show_if_role = explode(',', $show_if_role);
	$show_if_username = explode(',', $show_if_username);
	
	
	// Get the current user.
	$wp_user = \wp_get_current_user();
	$wp_user_roles = $wp_user->roles;
	$wp_user_username = $wp_user->user_login;
	
	// Check if current user can view content/
	$show_to_user = false;
	
	foreach ($wp_user_roles as $role_slug)
	{
		if ($role_slug != "" && in_array_case_insensitive($atts, $role_slug))
		{
			$show_to_user = true;
			break;
		}
	}
	
	if ($show_to_user == false)
	{
		foreach ($show_if_username as $show_username)
		{
			if ($show_username != "" && strtolower($show_username) == strtolower($wp_user_username))
			{
				$show_to_user = true;
				break;
			}
		}
	}
	
    
	ob_start();

	if ($show_to_user == true)
	{
		// Show the content
		$content = do_shortcode($content);
		echo $content;
	}
	else
	{
		// Hide the content
		echo "";
	}

	return ob_get_clean();
}


/*
*	Case-insensitive check if a value is in the array.
*	(Source: https://gist.github.com/sepehr/6351397)
*/
function in_array_case_insensitive($array, $check_value)
{
	return in_array(strtolower($check_value), array_map('strtolower', $array));
}
?>

WordPress: Changing File Upload and Processing Sizes

[This is a post for self-reference]

Up front I’m going to say I got exactly the help I need from here: https://www.wpbeginner.com/wp-tutorials/how-to-increase-the-maximum-file-upload-size-in-wordpress/.
The author of that post deserves all my credit.

I’m creating this post to summarise it in my own words and to give it a little educational context.


When allowing file uploads on a website there are 3 big things you need to think about:

  • The size of each file.
  • The total size of all files in an upload.
  • The time it takes to process the upload.

Actually, there are a couple of things to consider that are worthy of mention but I won’t cover in this post:

  • Asynchronous uploads (AJAX as we used to call them) can change the figure of an upload, because instead of uploading multiple files at one, you upload one file at a time (even if they are in parallel) so the “total size of all files” number will be different.
  • Tell users about the limits they face before they upload. Also, when uploading images a bit of guidance around things like “27MB images are a stupid side for most sites because 27MB isn’t going to be better than 7MB, and the site will trim the size down to a couple of hundred KB at most anyway.”
  • Trap, log and respond to any errors. This is on my mind because WordPress/PHP seems to like gobbling errors and not telling anyone about it (I’m in the process of hunting down how to handle this and will be a topic of another post).

 

There are 3 main ways in PHP to affect file upload sizes and times:

  • @set_init() in a PHP script itself.
  • php.ini file
  • .hataccess file.

Be aware, as a PHP/Linux novice I reckon there are other defaults and hierarchies that come into play.
This article is spawned by a situation where I was changing php.ini without realising .htaccess had a value overriding it.

 

How do you implement these values?

This is where I rip from the wpbeginner site I mentioned above for quick reference:

1. PHP script file (e.g. functions.php in WordPress themes)

@ini_set( 'upload_max_size' , '64M' );
@ini_set( 'post_max_size', '64M');
@ini_set( 'max_execution_time', '300' );

(I haven’t tried this approach yet, but I have used @ini_set() in other instances (e.g. ‘memory_limit’) and it’s worked well.

2. php.ini

upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300

I’ve used this approach in development and it did the trick.

3 .htaccess

php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300

Before writing this post I had to fix a production issue and after trying php.ini I got lucky and discovered .htaccess was where the value was coming from.
So the moral: .htaccess overrides php.ini.

Also, I did not need to restart apache for this change to take affect.

 

DISCLAIMER: I haven’t actually read in-depth how all this works. I’m a typical developer who expects other people’s shit to work, and when it doesn’t I’m usually in the middle of my own concerns so it’s a case of “search and scan by keyword until someone else’s solution works for me”.
Such is this age of software development.

 

Need to know what your current settings are?

It’s helpful in debugging and verification to know what your actual PHP settings are so you know what your starting point is (and  you have a number to search your files for).

A good way is to call phpinfo();.

For example, create a file in your site (I call mine info.php) and add the following PHP code:

<?php
phpinfo();
?>

You should see something like the following when you run it. This screenshot shows some output from the section titled “Core”, and the 3 columns are (from left to right): “Directive”, “Local Value” and “Master Value”. I can say from experience the “Local Value” is the one that matters.

phpinfo() output

Change a WordPress site URL (when copying or migrating a WordPress site)

This is a post for quick reference. But given 25% (or more) of the Interwebs run on WordPress I want to give it some love too.

Background

Moving (migrating) or copying a WordPress site has some hidden complexity.

While it is easy, there are 3 things you need to do:

  1. Copy the whole website structure, starting with the folder than contains the wp-config.php and other files (it also contains the  “wp-admin”, “wp-content” and “wp-includes” folders).
  2. Change the URL of the site as defined in WordPress (ordinarily set during setup, or within the Settings area).
  3. Update all the saved URLs within the database.

Step 3 is the real gotacha. When you add a link to another page within your site, or insert media, or set a navigation item, it saves the full URL of that item in the database.

For example, if you have a site “https://MySite.com” but want to change it to “https://MySite.com” (or as a software developer, you may want to create a copy of the production site at “https://test.MySite.com”) then after you change the actual URL of the site, all the internal links and images will still be pointing to the original MySite.com.

 

Solution

Many sites have covered how to change a WordPress site URL before, including the official Codex at https://codex.wordpress.org/Changing_The_Site_URL.

I like to keep things simple, so this post is my process:

  1. Backup your site database if you can (I connect directly to the database and run backup scripts, or use phpmyadmin and export).
  2. Update your site URLs by adding the following lines to the top of your active theme’s functions.php file:
    update_option( 'siteurl', 'https://MyNewSite.com' );
    update_option( 'home', 'https://MyNewSite.com' );
    
    1. Browser to your new site (via the IP or URL).
    2. Browse to it again and make sure it’s OK.
    3. Remove the lines from functions.php
    4. Browser to the site again one more time to make sure you can access it now you’ve removed the lines from functions.php.
  3. Upload the interconnect/it “Database Search and Replace Script” script to our site, found at https://interconnectit.com/products/search-and-replace-for-wordpress-databases/.
    1. Install it in a “not easily guessed” sub-directory of the site. This is for security reasons (so other people can’t scan and execute the scripts).
    2. Most fields are filled in. In the “search for…” enter your old URL or IP address, including “http” or “https” (e.g. “https://MySite.com” – you should be using https by now). I don’t end with a trailing forward slash.
      In the “replace with…” field enter the new URL or IP Address (e.g. “https://MyNewSite.com”). Again, not trailing forward slash.
    3. Make sure you do “dry run” to start. This should tell you if you have any problems.
    4. If all is good, do a “live run” and update your database.
    5. At the end, delete the “Database Search and Replace Script” from your site. This is important. If you leave it there bad people may find it and execute it and break your site.

WordPress – Adding post category requires page refresh to show up

I’m developing a plug-in and today, after a bunch of refactoring, found myself not able to add a category or tag to a Post and have it show in the list (as in this sort of screen):

 

If found the guiding answer at on StackOver at https://stackoverflow.com/a/50656747/115704 and while I also provided the following as an answer on that post I find the moderators on StackOverflow to overzealous pricks and likely to screw with my contributions, so I’m recording it here as well.

The cause

The ultimate cause is white space in PHP files appearing before the opening and closing of PHP code.

Finding the culprit is the hard part and that where I might be able to help.

 

What I said

I experienced this issue today, and white space in PHP files was the problem.

However, I want to share the steps I took to resolve the issue:

  1. I tried opening every PHP file and checking for blank lines at the start and end of the file. I picked up a few problems but the issue persisted.
  2. I was also able to do a regex search in my IDE for problems. I used Textmate/Regex: Strip whitespace from beginning/end of file as a reference point and [without quotation marks] the following regex searches “https://regex101.com/r/5EExaF/1” to find space/blank lines at the end of a file, and “https://regex101.com/r/qs17J9/1” for the start of a file.
  3. There were still problems so I narrowed down the scope by disabling plug-ins (I also knew it was one of my own plug-ins in the site I’m developing, so that made it easier).
  4. Re-activating a plug-in give a warning “The plugin generated X characters of unexpected output during activation”. This helped me in the trial-and-error process of narrowing down the source.
  5. Once I had the plug-in identified, I started commenting out require_once() calls in PHP files until the “The plugin generated X characters of unexpected output” warning disappeared.
  6. Eventually, I realised I’d broken the plug-in during refactoring and was doing a require_once() on a PHP file that was pure HTML (to inject favicon tags into a page header) rather than the appropriate add_action() call on the file as I originally intended.

Hopefully, these debug steps provide some inspiration to other people suffering the same problem. As far as I know, WordPress does not offer any easy way to identify the cause of this problem (i.e. it does not identify which file has bad spaces in it).

NOTE: I had to link to regex101 to shoe the actual values because WordPress or WordFence seems to not like regex in posts.

WordPress: An embedded page at widgets.wp.com says – Request failed. Returned status of 404

Key Stats:

  • Publication Date: 06 May 2016
  • WordPress Core Version: 4.9.5–en_AU
  • JetPack Version: 6.1

My WordPress-based Knowledge Base site has started displaying an unwanted JavaScript dialogue box on post pages saying:

An embedded page at widgets.wp.com says
Request failed. Returned status of 404

 

It turns out I’m not the only one with this issue (as this WordPress Support page indicates) and the problem looks to be coming from the JetPack plug-in.

After finding a few keywords on that support and testing on my own site, it turns out the problem is being caused by the “Show Likes.” feature on the post:

 

Untick the “Show Likes.” option and save the post again and the problem goes away.

 

Now we just need to wait for a fix from JetPack (which seems a bit slow coming).

Note for developers: This type of error should never be logged in the UI via a JavaScript dialogue box. Why? It’s truly bad user experience for non-technical end users (who in the case of WordPress websites are most likely to see it). Log it to the console instead.

Developing WordPress: What You Need to Learn

  • Download and install WordPress on a development PC.
    • LAMP/WAMP/XAMP stack (Apache, MySQL, PHP)
    • Database table naming. Default is “wp_”. Change the name in config.php so multiple installations in the one DB.
  • Training:
  • Official WordPress sites:
  • Terms and Concepts (and how they work)
    • Users
    • Roles
    • Taxonomies
    • Posts (this the core of WordPress) and Post Types
    • Custom Post Types
    • Database structure
  • Custom Development
    • Themes
    • Plug-ins
    • Shortcodes
    • Page Templates
    • ‘Meta’ fields
    • Custom Roles
    • Extending user information/fields
    • WordPress API
    • Actions, Hooks, Filters
  • Achieving specific ends
    • Creating forms for users in the front-end
  • Good Themes and plug-ins to know
    • Themeco ‘X’ or ‘Pro’ themes
    • Advanced Custom Fields (ACF)
  • Other things to think about
    • Form validation for custom forms
    • Data sanitisation
    • Security
    • Exception handling (500 & 404)
    • Unit test and general testing
      • https://codex.wordpress.org/Theme_Unit_Test
    • Logging
    • User analytics (tracking user behaviour)
    • Different plug-ins (and theme) loading the same javascript resources (e.g. jQuery). Think about version conflicts.
    • Updating themes and plug-ins
    • Debugging (e.g. debug(‘WP_DEBUG’, true);)

Thinking about DevOps:

  • The database stores a lot of configuration data.
  • Plug-in development
  • Theme development
  • Creating dev/test environments from prod.
    • Renaming domains in the .database
  • Can we push dev/test (including config via DB) to prod? Investigate.
  • Deploying themes and plug-ins (is built-in WP the best, even for us?)

Look at:

wordpress.org/extend/plugins/monster-widget/
../theme-check/
../developer/
../debogger/
../log-deprecated-notices/

http://wptest.io/

WordPress Themes & Plugins

Themes

‘X’ Theme or ‘Pro’ Theme
Themeco
https://theme.co/x/
US$55

Divi
Elegant Themes
https://www.elegantthemes.com/
US$89

General

Jetpack
https://jetpack.com/
US$39/99/299/year
– Themes
– Backups
– Monitoring

 

Canonical

Yoast SEO
Free/US$89/year

https://wordpress.org/plugins/tags/canonical/

 

Forms

Contact Form 7
https://contactform7.com/
Free
Comes with X Theme

Gravity Forms
http://www.gravityforms.com/
US$39

Ninja Forms
https://ninjaforms.com/
US$99 (Personal)

 

Security

WordFence
https://www.wordfence.com/
Free or US$99/year

 

Favicon

Built-in with WordPress

Favicon by RealFaviconGenerator
https://wordpress.org/plugins/favicon-by-realfavicongenerator/
Free

 

Schema, Rich Snippets & Social Sharing

  • Schema.org
  • Twitter Cards
  • Open Graph Protocol
  • Microformats

https://wordpress.org/plugins/schema/
https://wordpress.org/plugins/all-in-one-schemaorg-rich-snippets/

Social Sharing
http://www.wpbeginner.com/plugins/best-social-media-plugins-for-wordpress/
https://wordpress.org/plugins/ultimate-social-media-icons/
https://wordpress.org/plugins/ultimate-social-media-plus/

Google Maps

 

e-Commerce

http://www.wpbeginner.com/plugins/best-wordpress-ecommerce-plugins-compared/

WooCommerce
Free

 

Galleries, Sliders and Carousels

Envira Gallery (with X theme)
http://enviragallery.com/
UD$29 (Basic)

Soliloquy (with X theme)
http://soliloquywp.com/
UD$19 (Personal)

 

Spam and Comments

(TBC)

 

Backups, DR, & Monitoring

VaultPress (with JetPack)

BackupBuddy
https://ithemes.com/purchase/backupbuddy/
US$80/year

Uptime

 

Site Usage, Analytics, and Mapping

Sitemap
SEO plug-ins

Google XML Sitemaps
https://en-au.wordpress.org/plugins/google-sitemap-generator/

Google Sitemap by BestWebSoft
https://wordpress.org/plugins/google-sitemap-plugin/

Google Analytics
X Theme

MonsterInsights [for full dashboard]
https://wordpress.org/plugins/google-analytics-for-wordpress/
US$39/year

Robots.txt
(TBC)

Meta and keyword tags (per page)
Yoast SEO

 

SEO

Yoast SEO
https://en-au.wordpress.org/plugins/wordpress-seo/
Free or US$89/year

All in One SEO Pack
https://wordpress.org/plugins/all-in-one-seo-pack/
US$136/year

 

SSL

Migrate or Change website domain
https://wordpress.org/plugins/tags/migrate/
https://wordpress.org/plugins/duplicator/
https://wordpress.org/plugins/all-in-one-wp-migration/

 

Email and Contact Lists

MailChimp
https://mailchimp.com/

https://mc4wp.com/ (MailChimp plug-in)

 

Membership & Subscription

https://wordpress.org/plugins/wp-members/
Untested

 

Active Directory Integration