<?php
/*
Plugin Name: Stupid URIs
Plugin URI: http://rephrase.net/box/word/stupid/
Description: Hate clean, informative URIs? Make yours stupid.
Author: Sam Angove
Version: 1.0
Author URI: http://rephrase.net
*/ 



// Base class: intercepts query vars coming in, rewrites links going out.

class Stupid {
	function decode_callback($matches) {
		return $matches[1] . '=' . $this->decode($matches[2]) . $matches[3];
	}
	
	function encode_callback($matches) {
		return $matches[1] . '=' . $this->encode($matches[2]) . $matches[3];
	}
	
	function query($query) {
		return preg_replace_callback("#(.*?)=(.*?)(&|\z)#s", array($this, 'decode_callback'), $query);
	}
	function category_uri($uri) {
		global $wp_rewrite;
		return $this->uri($uri, $wp_rewrite->get_category_permastruct());	
	}
	
	function date_uri($uri) {
		global $wp_rewrite;
		return $this->uri($uri, $wp_rewrite->get_date_permastruct());	
	}
	function post_uri($uri) {
		return $this->uri($uri, get_settings('permalink_structure'));	
	}
	
	function pretty_uri($uri, $structure) {
		$uri = parse_url($uri);
		$path = $uri['path'];
			
		$home = parse_url(get_settings('home'));
		$home_path = $home['path'];
			
		$newuri = $uri['scheme'] . '://' . $uri['host']. trailingslashit($home_path);
		
		$path = str_replace($home_path, '', $path);
		$path = split('/', $path);
		$structure = split('/', $structure);
		
		$newpath = array();
		
		foreach ($path as $key => $segment) {
			if (trim($segment)) {
				if ($structure[$key] != $segment) {
					$segment = $this->encode($segment);
					$newpath[] = $segment;
				} else {
					$newpath[] = $segment;
				}
			}
		}
		$newuri .= implode('/', $newpath);
		return $newuri;
	}
	
	function uri($uri, $structure = false) {
		
		if ($structure) return $this->pretty_uri($uri, $structure);
		
		$uri = parse_url($uri);
		$query = preg_replace_callback("#(.*?)=(.*?)(&|\z)#s", array($this, 'encode_callback'), $uri['query']);
		
		$newuri = $uri['scheme'] . '://' . $uri['host'] . $uri['path'] . '?' . $query;
		
		return $newuri;
	}
	
	function rewrite($rewrite) {
		
		static $rewrote = false;
		
		// infinite loops just aren't cool, dig?
		if ($rewrote) return $rewrite;
			else $rewrote = true;
			
		if ($this->rules) {
			foreach ($this->rules as $tag => $what) {
				$rewrite->add_rewrite_tag($tag, $what[0], $what[1]);
			}
			$rules = $rewrite->rewrite_rules();
			$rewrite->rules = $rules;
		}
	}
}

// Classes providing the encode/decode functions to make those URIs useless.

class Backwards extends Stupid {
	
	function encode($str) {
		$newstr = '';
		for ($i=strlen($str)-1; $i>-1; $i--) {
			$newstr .= substr($str, $i, 1);
		}
		return $newstr;
	}	
	function decode($str) {
		return $this->encode($str);	
	}
	
}


class Banshee extends Stupid {
	
	var $encode_table = array();
	var $decode_table = array();
	var $rules = array();
	
	
	function Banshee() {
		$chars = "!0123456789abcdefghijklmnopqrstuvwxyz-_.";
		$count = strlen($chars);
		for ($i=1; $i < $count; $i++) {
			$char = substr($chars, $i, 1);
			$this->encode_table[$i] = $char;
			$this->decode_table[$char] = $i;
		}
		
		$this->rules['%year%'] 		= array('([iae]+)', "year=");
		$this->rules['%monthnum%']	= array('([iae]+)', "monthnum=");
		$this->rules['%day%'] 		= array('([iae]+)', "day=");
		$this->rules['%hour%']		= array('([iae]+)', "hour=");
		$this->rules['%minute%']	= array('([iae]+)', "minute=");
		$this->rules['%second%']	= array('([iae]+)', "second=");
		$this->rules['%post_id%']	= array('([iae]+)', "p=");
	}
	
	function encode($text) {
		$length = strlen($text);
		for ($i=0; $i < $length; $i++) {
			$letter = substr($text, $i, 1);
			$key = $this->decode_table[$letter];
			$t = array();
			$keylength = strlen($key);
			for ($j = 0; $j < $keylength; $j++) {
				$t[] = str_repeat('i', substr($key, $j, 1));	
			}
			$space[] = implode($t, 'a');
		}
		$text = implode($space, 'e');
							
		return $text;
	}
	
	function decode($bad) {
			
		$url = '';
		$parts = explode('e', $bad);
		
		foreach ($parts as $part) {
			if (strstr($part, 'a')) {
				$num = '';
				$real = explode('a', $part);
				foreach ($real as $r) {
					$num .= strlen($r);	
				}
			} else {
				$num = strlen($part);
			}
			$url .= $this->encode_table[$num];
		}
		return $url;
	}
}

class Morse extends Stupid {
	
	var $encode_table;
	var $decode_table = array();
	var $rules = array();
	
	function Morse() {
		$this->encode_table  = array('a' => '.-', 'b' => '-...', 'c' => '-.-.', 'd' => '-..', 'e' => '.', 
			'f' => '..-.', 'g' => '--.', 'h' => '....', 'i' => '..', 'j' => '.---', 
			'k' => '-.-', 'l' => '.-..', 'm' => '--', 'n' => '-.', 'o' => '---', 
			'p' => '.--.', 'q' => '--.-', 'r' => '.-.', 's' => '...', 't' => '-', 
			'u' => '..-', 'v' => '...-', 'w' => '.--', 'x' => '-..-', 'y' => '-.--', 
			'z' => '--..', '0' => '-----', '1' => '.----', '2' => '..---', '3' => '...--', 
			'4' => '....-', '5' => '.....', '6' => '-....', '7' => '--...', '8' => '---..', 
			'9' => '----.', '.' => '.-.-.-', ',' => '--..--', '?' => '..--..', '-' => '------',
			'%' => '.-----'); 
			//note: last few not actual Morse code
		
		foreach ($this->encode_table as $c => $m) {
			$this->decode_table[$m] = $c;
		}
		
		$this->rules['%year%'] 		= array('([.\-]{5}_[.\-]{5}_[.\-]{5}_[.\-]{5})_?', "year=");
		$this->rules['%monthnum%']	= array('([.\-]{5}_[.\-]{5})_?', "monthnum=");
		$this->rules['%day%'] 		= array('([.\-]{5}_[.\-]{5})_?', "day=");
		$this->rules['%hour%']		= array('([.\-]{5}_[.\-]{5})_?', "hour=");
		$this->rules['%minute%']	= array('([.\-]{5}_[.\-]{5})_?', "minute=");
		$this->rules['%second%']	= array('([.\-]{5}_[.\-]{5})_?', "second=");
		$this->rules['%post_id%']	= array('([.\-_]+)_?', "p=");
	}

	function encode($str) {
		
		$chars = array();
		for ($i=0;$i<strlen($str);$i++) {
			$char = substr($str, $i, 1);
			if ($this->encode_table[$char]) {
				$chars[] = $this->encode_table[$char];
			} else {
				$chars[] = $char;
			}
		}
		$str = implode('_', $chars);
		
		// can't let them end with a '.', or we get '.../' etc. in paths
		if (substr($str, strlen($uri)-1, 1) != '-') $str .= '_';
		return $str;
	}
	function decode($var) {
		
		if (!preg_match("#[^.\-_]#", $var)) {
			if (substr($var, strlen($var)-1, 1) == '_') $var = substr($var, 0, strlen($var)-1);
			$coded = explode('_', $var);
			$var = '';
			foreach ($coded as $c) {
				$var .= $this->decode_table[$c];	
			}
		}
		return $var;
	}
}


class Zxy extends Stupid {
	
	var $table;
	
	function Zxy() {
		$chars = "abcdefghijklmnopqrstuvwxyz";
		$back = strrev($chars);
		$count = strlen($chars);
		for ($i=0; $i < $count; $i++) {
			$char = substr($chars, $i, 1);
			$bchar = substr($back, $i, 1);
			$this->table[$char] = $bchar;
		}
	}
	
	function encode($str) {
		$length = strlen($str);
		for ($i=0; $i<$length; $i++) {
			$char = substr($str, $i, 1);
			
			$add = ($this->table[$char]) ? $this->table[$char] : $char;
			$newstr .= $add;
		}
		return $newstr;
	}	
	function decode($str) {
		return $this->encode($str);	
	}
	
}


$stupid = new Backwards();

add_filter('query_string', array($stupid, 'query'));
add_filter('year_link', array($stupid, 'date_uri'));
add_filter('month_link', array($stupid, 'date_uri'));
add_filter('day_link', array($stupid, 'date_uri'));
add_filter('post_link', array($stupid, 'post_uri'));
add_filter('category_link', array($stupid, 'category_uri'));
add_filter('generate_rewrite_rules', array($stupid, 'rewrite'));

?>