Category Archives: PHP

Fix broken / overlapping Instagram embed for WordPress

At some point recently (February 2018), Instagram broke their oEmbed implementation which causes JavaScript errors and embeds that overlap each other. Use the snippet below to mitigate this issue and hopefully Instagram will fix it in the future. The snippet makes sure only one

/**
 * Remove Instagram embed.js script on each embed
 */
add_filter('embed_oembed_html', function($html, $url, $attr, $post_id) {
  $regex =    '/<script.*instagram\.com\/embed.js.*\s?script>/U';
  $regex_2 =  '/<script.*platform\.instagram\.com\/.*\/embeds\.js.*script>/U';

  if(preg_match($regex, $html) || preg_match($regex_2, $html)) {
    add_filter('kh_has_instagram_embed', '__return_true');

    $html = preg_replace($regex, '', $html);
    $html = preg_replace($regex_2, '', $html);

    return $html;
  }

  return $html;
}, 100, 4);

/**
 * Enqueue the embed.js script once at the bottom of the page, if at least one Instagram embed is enqueued
 */
add_filter('wp_footer', function() {
  if(apply_filters('kh_has_instagram_embed', false)) :
    ?>
      <script async defer src="//www.instagram.com/embed.js"></script>
    <?php
  endif;
}, 999);

Shorthand caching pattern in PHP

Here’s a short and simple caching pattern you can use to cache an expensive function call:

if(!$result = Cache::get('expensive-function-cache-key')) {
  $result = expensive_function();
  Cache::set('expensive-function-cache-key', $result);
}

//The result variable will always contain the proper value, whether the call was cached or not.
echo $result;

List authors by post count in WordPress using MySQL

A query to list authors / users by post count:

SELECT wp_users.ID, wp_users.user_nicename, COUNT(*) as count FROM wp_posts, wp_users WHERE wp_posts.post_type='post' AND wp_posts.post_status='publish' AND wp_posts.post_author = wp_users.ID GROUP BY post_author ORDER BY count DESC LIMIT 5 ;

Resulting table:

ID,user_nicename,count
29,"user-a",18
66,"user-b",16
26,"user-c",10
24,"user-f",9
48,"user-z",6

Setting the correct forwarded IP address in WordPress Stream plugin

If you are using the WordPress Stream plugin and have a reverse proxy like Varnish in front of it, you might be seeing the IP of your Varnish machines rather than the client IP. This snippet lets you set the proper IP address that Varnish or other reverse proxies forward.

This code only works for Apache. If you are running Nginx you will need the getallheaders polyfill.

//Add proper forwarded IP to log records
add_filter('wp_stream_record_array', function($record) {
   //Get proper IP
   if(function_exists('getallheaders')) {
      $headers = getallheaders();

      //Exchange IP if header set
      if(isset($headers['X-Forwarded-For'])) {
        $record['ip'] = filter_var($headers['X-Forwarded-For'], FILTER_VALIDATE_IP);
      }
    }

    return $record;
});

Upgrading from Deployer 3 to Deployer 4

If you are upgrading Deployer from version 3 to 4 you will see issues when trying to deploy, for example:

[ERROR] Error: Call to undefined function set() in /Users/stakhr/site/deploy.php:5    
       Stack trace:                                                                                
       #0 phar:///Users/stakhr/site/deployer.phar/bin/dep(114): require()            
       #1 phar:///Users/stakhr/site/deployer.phar/bin/dep(115): {closure}()          
       #2 /Users/stakhr/site/deployer.phar(4): require('phar:///Users/s...')         
       #3 {main}  

To fix these issues, you need to do a few things:

  • Add a Deployer namespace declaration at the top of your deploy.php file, like this: namespace Deployer;
  • The env() function has been deprecated. Replace it with set() when setting variables (two parameters) and get() when getting variables (one parameter)
  • The underlying SSH implementation will be changed in Deployer 5, so add set('ssh_type', 'native'); to fix the nag that shows up.

Here is a full example of deploying a WordPress site using Deployer 4

PS. I’ve also noted that running deployer self-update on version 3 does not upgrade to version 4.