Ahmed Nuaman


builder of internets ~ developer of dreams ~ tamer of Dachshunds

WordPress, Mutli-site And Files

I’ve been working on a big web site that’s built on the superb WordPress. Now I *love* WordPress, it’s just amazing, but then it does some crap stuff.

I was having some issues looking at cache control and gzipping on the site’s server and came across just how WordPress multi-site handles files from the different of sites: it points them through PHP.

Now this isn’t fun, nor is it clever; here’s the file: http://core.trac.wordpress.org/browser/trunk/wp-includes/ms-files.php (look at line 82, it says readfile(), that’s magic!)

Now me being me, I didn’t like this. So I’ve written a simple little WordPress plugin that’ll do a better job, or at least I hope: https://github.com/ahmednuaman/WordPress-Filer.

It’s pretty simple, here’s the (latest) code (but don’t trust it, get it off Github).

<?php
/*
Plugin Name: WordPress Multi-site Filer
Plugin URI: https://github.com/ahmednuaman/WordPress-Filer
Description: It's a plugin that handles files that much better
Version: 1
Author: Ahmed Nuaman
Author URI: http://www.ahmednuaman.com
*/


/**
 * @author          Ahmed Nuaman (http://www.ahmednuaman.com)
 * @langversion     5
 *
 * This work is licenced under the Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License.
 * To view a copy of this licence, visit http://creativecommons.org/licenses/by-sa/2.0/uk/ or send a letter
 * to Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
*/


/*
So, how do you use this? Well, in your .htaccess (or whatever rewrite program you use) will be a directive like so:
    RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
   
You need to rewrite it to:
    RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-admin/admin-ajax.php?file=$2&origin=$1&action=get_blog_file [L]
   
This simply rewrites it to this bad ass plugin
*/


error_reporting( E_ALL ^ E_NOTICE );

add_action( 'wp_ajax_get_blog_file',                'filer_get_blog_file' );

add_action( 'wp_ajax_nopriv_get_blog_file',         'filer_get_blog_file' );

$files      = '/wp-content/blogs.dir/';

function filer_get_blog_file()
{
    global $files;
   
    $path   = _to_word( $_REQUEST[ 'origin' ] );

    $b_id   = _filer_get_blog_id( $path );

    $dir    = $files . $b_id . '/files/' . $_REQUEST[ 'file' ];
   
    header( 'Location: ' . $dir );
   
    die();
}

if ( !function_exists( '_filer_get_blog_id' ) )
{
    function _filer_get_blog_id($blog_path)
    {
        global $wpdb;

        $blog_path  = _to_safe_var( $blog_path );

        $blog       = $wpdb->get_row( 'SELECT blog_id FROM wp_blogs WHERE path = "/' . $blog_path . '/"' );

        return $blog->blog_id;
    }
}

if ( !function_exists( '_to_safe_var' ) )
{
    function _to_safe_var($v)
    {
        return str_replace( '"', '', mysql_real_escape_string( $v ) );
    }
}

if ( !function_exists( '_to_word' ) )
{
    function _to_word($v)
    {
        return _to_safe_var( preg_replace( '/[^A-z]/', '', $v ) );
    }
}
?>

It’s pretty simple to use: just download and install and update your .htaccess (or whatever rewrite program you use) to do the following:

# uploaded files
#RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-admin/admin-ajax.php?file=$2&origin=$1&action=get_blog_file [L]

And you’re laughing! Let me know if it’s useful and if you like it. I really wanna look at getting caching in here somewhere, so that’ll be the next update.

Where have comments gone?

Good question my old fruity. I'm now sticking any post discussions on Google+. Why? Well simply it's better. WordPress's comment system isn't very elegant and nor are ones like Disqus or Livefyre, so to save hassle I've just shipped them off to a social network, like a real boss.

Search

My social skills

Latest blog posts

  • Loading posts...

Subscribe in a reader

Latest tweets

  • Loading tweets...