/jar.php
PHP | 2804 lines | 1242 code | 304 blank | 1258 comment | 227 complexity | e158d778c2f12e09fc370bfdb9b6e80c MD5 | raw file
Possible License(s): MIT
- <?php
- /**
- * Common API Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Common API Interface
- *
- * Parent class that our API interface classes should be extending. Contains
- * execution of parental functions but may contain more down the road.
- */
- abstract class API_Common extends Object
- {
- /**
- * Constructor
- */
- public function __construct()
- {
- parent::__construct();
- }
- /**
- * Destructor
- */
- public function __destruct()
- {
- parent::__destruct();
- }
- }
- /**
- * Google Profanity Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Google Profanity API Interface
- */
- class API_Google_Profanity extends API_Common
- {
- /**
- * Check
- *
- * Checks if a word is considered profanity.
- *
- * @usage API_Google_Profanity::check('fuck'); // returns true
- * @param string $word word to check
- * @return boolean whether or not the word is profanity
- */
- public static function check($word)
- {
- $response = json_decode(file_get_contents('http://www.wdyl.com/profanity?q=' . $word), true);
- if ($response == null || !isset($response['response']) || !in_array($response['response'], array('true', 'false')))
- {
- throw new Exception('Invalid response from API.');
- }
- else
- {
- return $response['response'] == 'true';
- }
- }
- }
- /**
- * Tinychat Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Tinychat API Interface
- *
- * @link http://tinychat.com/developer/docs
- */
- class API_Tinychat extends API_Common
- {
- /**
- * Public Key
- *
- * @access private
- * @var string
- */
- private $public_key = null;
-
- /**
- * Secret Key
- *
- * @access private
- * @var string
- */
- private $secret_key = null;
- /**
- * Constructor
- *
- * Assigns our public and secret keys from the configuration.
- */
- public function __construct()
- {
- parent::__construct();
- if (isset($this->config->api['tinychat'], $this->config->api['tinychat']['public_key'], $this->config->api['tinychat']['secret_key']))
- {
- $this->public_key = $this->config->api['tinychat']['public_key'];
- $this->secret_key = $this->config->api['tinychat']['secret_key'];
- }
- else
- {
- throw new Exception('Unable to load TinyChat configuration.');
- }
- }
- /**
- * Execute
- *
- * Constructs a valid API call, executes it and returns the results.
- *
- * @param string $codephrase name of the API call being called
- * @param string $authentication post-codephrase portion of the auth string
- * @param array $parameters key / value pairs for additional data
- * @return array results of the API call
- */
- private function execute($codephrase, $authentication, $parameters = null)
- {
- // Assembles and hashes the authentication token
- $authentication = md5($this->secret_key . ':' . $authentication);
-
- // Assembles any additional parameters
- $additional = '';
- if ($parameters && is_array($parameters))
- {
- foreach ($parameters as $key => $value)
- {
- $additional .= '&' . $key . '=' . $value;
- }
- }
- // Executes the API call
- $results = file_get_contents('http://tinychat.apigee.com/' . $codephrase . '?result=json&key=' . $this->public_key . '&auth=' . $authentication . $additional);
- return json_decode($results, true);
- }
- /**
- * List Rooms
- *
- * Pulls all rooms for the API application.
- *
- * @return array API results
- */
- public function listRooms()
- {
- return $this->execute('roomlist', 'roomlist');
- }
- /**
- * Room Info
- *
- * Pulls the information for a room.
- *
- * @param string $room name of the room
- * @param boolean $with_ip whether or not to include users IP addresses
- * @return array API results
- */
- public function roomInfo($room, $with_ip = false)
- {
- return $this->execute('roominfo', $room . ':roominfo', array('room' => $room, 'with_ip' => ($with_ip ? 1 : 0)));
- }
- /**
- * Set Room Password
- *
- * Sets the password for the room, only users with the correct password
- * will be able to enter.
- *
- * @param string $room name of the room
- * @param string $password password to use, blank for no password
- * @return array API results
- */
- public function setRoomPassword($room, $password = '')
- {
- return $this->execute('setroompassword', $room . ':setroompassword', array('room' => $room, 'password' => $password));
- }
- /**
- * Set Broadcast Password
- *
- * Sets the password to allow broadcasting in the room. Only users with the
- * correct password will be able to broadcast.
- *
- * @param string $room name of the room
- * @param string $password password to use, blank for no password
- * @return array API results
- */
- public function setBroadcastPassword($room, $password = '')
- {
- return $this->execute('setbroadcastpassword', $room . ':setbroadcastpassword', array('room' => $room, 'password' => $password));
- }
- /**
- * Generate HTML
- *
- * Creates the HTML to place a chat on a site.
- *
- * @todo List params...
- * @return array API results
- */
- public function generateHTML($room, $join = false, $nick = false, $change = false, $login = false, $oper = false, $owner = false, $bcast = false, $api = false, $colorbk = false, $tcdisplay = false, $autoop = false, $urlsuper = false, $langdefault = false)
- {
- return '
- <script type="text/javascript">
- var tinychat = {'
- . 'room: "' . $room . '",'
- . ($join ? 'join: "auto",' : '')
- . ($nick ? 'nick: "' . $nick . '",' : '')
- . ($change ? 'change: "none",' : '')
- . ($login ? 'login: "' . $login . '",' : '')
- . ($oper ? 'oper: "none",' : '')
- . ($owner ? 'owner: "none",' : '')
- . ($bcast ? 'bcast: "restrict",' : '')
- . ($api ? 'api: "' . $api . '",' : '')
- . ($colorbk ? 'colorbk: "' . $colorbk . '",' : '')
- . ($tcdisplay ? 'tcdisplay: "vidonly",' : '')
- /* @todo Implement $autoop, it's an array and needs validated */
- . ($urlsuper ? 'urlsuper: "' . $urlsuper . '",' : '')
- . ($langdefault ? 'langdefault: "' . $langdefault . '",' : '')
- . 'key: "' . $this->public_key . '"'
- . '};
- </script>
- <script src="http://tinychat.com/js/embed.js"></script>
- <div id="client"></div>
- ';
- }
- }
- /**
- * Caching System for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Cache Class
- *
- * Wrapper class for Memcache() to allow for better error handling when the
- * Memcached server is unavailable. Designed around the syntax for Memcached()
- * to allow for an easier transistion to the aforementioned in the future. I
- * don't entirely remember specifics, but the reason for not using Memcached()
- * was due to an unexplainable bug in the version in the repository for Ubuntu
- * 10.04 LTS. Memcached() does support more of the memcached protocol and will
- * eventually be what PICKLES uses.
- *
- * Requires php5-memcache
- *
- * @link http://us.php.net/manual/en/book.memcache.php
- * @link http://packages.ubuntu.com/lucid/php5-memcache
- * @link http://www.memcached.org/
- */
- class Cache extends Object
- {
- /**
- * Hostname for the Memcached Server
- *
- * @access private
- * @var string
- */
- private $hostname = null;
- /**
- * Port to use to connect
- *
- * @access private
- * @var integer
- */
- private $port = null;
- /**
- * Connection resource to Memcached
- *
- * @access private
- * @var object
- */
- private $connection = null;
- /**
- * Constructor
- *
- * Sets up our connection variables.
- *
- * @param string $hostname optional hostname to connect to
- * @param string $database optional port to use
- */
- public function __construct($hostname = null, $port = null)
- {
- parent::__construct();
- if ($this->config->pickles['cache'])
- {
- if (isset($this->config->datasources[$this->config->pickles['cache']]))
- {
- $datasource = $this->config->datasources[$this->config->pickles['cache']];
- if (isset($datasource['hostname'], $datasource['port']))
- {
- $this->hostname = $datasource['hostname'];
- $this->port = $datasource['port'];
- }
- }
- }
- }
- /**
- * Destructor
- *
- * Closes the connection when the object dies.
- */
- public function __destruct()
- {
- if ($this->connection)
- {
- $this->connection->close();
- }
- }
- /**
- * Get Instance
- *
- * Let's the parent class do all the work.
- *
- * @static
- * @param string $class name of the class to instantiate
- * @return object self::$instance instance of the Cache class
- */
- public static function getInstance($class = 'Cache')
- {
- return parent::getInstance($class);
- }
- /**
- * Opens Connection
- *
- * Establishes a connection to the memcached server.
- */
- public function open()
- {
- if ($this->connection === null)
- {
- $this->connection = new Memcache();
- $this->connection->connect($this->hostname, $this->port);
- }
- return true;
- }
- /**
- * Get Key
- *
- * Gets the value of the key and returns it.
- *
- * @param string $key key to retrieve
- * @return mixed value of the requested key, false if not set
- */
- public function get($key)
- {
- if ($this->open())
- {
- return $this->connection->get($key);
- }
- return false;
- }
- /**
- * Set Key
- *
- * Sets key to the specified value. I've found that compression can lead to
- * issues with integers and can slow down the storage and retrieval of data
- * (defeats the purpose of caching if you ask me) and isn't supported. I've
- * also been burned by data inadvertantly being cached for infinity, hence
- * the 5 minute default.
- *
- * @param string $key key to set
- * @param mixed $value value to set
- * @param integer $expiration optional expiration, defaults to 5 minutes
- * @return boolean status of writing the data to the key
- */
- public function set($key, $value, $expire = 300)
- {
- if ($this->open())
- {
- return $this->connection->set($key, $value, 0, $expire);
- }
- return false;
- }
- /**
- * Delete Key
- *
- * Deletes the specified key.
- *
- * @param string $key key to delete
- * @return boolean status of deleting the key
- */
- public function delete($key)
- {
- if ($this->open())
- {
- return $this->connection->delete($key);
- }
- return false;
- }
- /**
- * Increment Key
- *
- * Increments the value of an existing key.
- *
- * @param string $key key to increment
- * @return boolean status of incrementing the key
- * @todo Wondering if I should check the key and set to 1 if it's new
- */
- public function increment($key)
- {
- if ($this->open())
- {
- return $this->connection->increment($key);
- }
- return false;
- }
- }
- /**
- * Configuration Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Config Class
- *
- * Handles loading the site's configuration file (if available). At the moment
- * this class is a very skewed Singleton. The plan is to eventually extend this
- * out to support multiple configuration files, and the ability to load in
- * custom config files on the fly as well. The core of PICKLES uses the class
- * as a Singleton so we're not loading the configuration multiple times per
- * page load.
- *
- * @usage <code>$config = new Config($filename);</code>
- */
- class Config extends Object
- {
- /**
- * Config data
- *
- * @access private
- * @var array
- */
- private $data = array();
- /**
- * Constructor
- *
- * Calls the parent constructor and loads the passed file.
- *
- * @param string $filename optional Filename of the config
- */
- public function __construct($filename = null)
- {
- parent::__construct();
- // Try to fine the configuration
- if ($filename == null)
- {
- $filename = 'config.php';
- $loaded = false;
- $cwd = getcwd();
- while ($loaded == false)
- {
- chdir(dirname($filename));
- if (getcwd() == '/')
- {
- throw new Exception('Unable to load configuration.');
- }
- chdir($cwd);
- $filename = '../' . $filename;
- $loaded = $this->load($filename);
- }
- }
- else
- {
- $this->load($filename);
- }
- }
- /**
- * Loads a configuration file
- *
- * @param string $filename filename of the config file
- * @return boolean success of the load process
- */
- public function load($filename)
- {
- $environments = false;
- $environment = false;
- // Sanity checks the config file
- if (file_exists($filename) && is_file($filename) && is_readable($filename))
- {
- require_once $filename;
- // Determines the environment
- if (isset($config['environment']))
- {
- $environment = $config['environment'];
- }
- else
- {
- if (isset($config['environments']) && is_array($config['environments']))
- {
- $environments = $config['environments'];
- // If we're on the CLI, check an environment was even passed in
- if (IS_CLI == true && $_SERVER['argc'] < 2)
- {
- throw new Exception('You must pass an environment (e.g. php script.php <environment>)');
- }
- // Loops through the environments and tries to match on IP or name
- foreach ($config['environments'] as $name => $hosts)
- {
- if (!is_array($hosts))
- {
- $hosts = array($hosts);
- }
- // Tries to determine the environment name
- foreach ($hosts as $host)
- {
- if (IS_CLI == true)
- {
- // Checks the first argument on the command line
- if ($_SERVER['argv'][1] == $name)
- {
- $environment = $name;
- break;
- }
- }
- else
- {
- if ((preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $host)
- && $_SERVER['SERVER_ADDR'] == $host)
- || $_SERVER['HTTP_HOST'] == $host)
- {
- // Sets the environment and makes a run for it
- $environment = $name;
- break;
- }
- }
- }
- }
- }
- }
- // Flattens the array based on the environment
- $this->data = $this->flatten($environment, $config);
- // Restore environments value
- if ($environments != false)
- {
- $this->data['environments'] = $environments;
- }
- // Sets the environment if it's not set already
- if (!isset($this->data['environment']))
- {
- $this->data['environment'] = $environment;
- }
- // Defaults profiler to true if it doesn't match an option exactly
- if (isset($this->data['pickles']['profiler']))
- {
- if ($this->data['pickles']['profiler'] !== true)
- {
- // If we have an array convert to a string
- if (is_array($this->data['pickles']['profiler']))
- {
- $this->data['pickles']['profiler'] = implode(',', $this->data['pickles']['profiler']);
- }
- // Checks that one of our known values exists, if not, force true
- if (preg_match('/(objects|timers|queries|explains)/', $this->data['pickles']['profiler'] == false))
- {
- $this->data['pickles']['profiler'] = true;
- }
- }
- }
- else
- {
- $this->data['pickles']['profiler'] = false;
- }
- // Defaults expected PICKLES options to false
- foreach (array('cache', 'logging') as $variable)
- {
- if (!isset($this->data['pickles'][$variable]))
- {
- $this->data['pickles'][$variable] = false;
- }
- }
- // Creates constants for the security levels
- if (isset($this->data['security']['levels']) && is_array($this->data['security']['levels']))
- {
- foreach ($this->data['security']['levels'] as $value => $name)
- {
- $constant = 'SECURITY_LEVEL_' . strtoupper($name);
- // Checks if constant is already defined, and throws an error
- if (defined($constant))
- {
- throw new Exception('The constant ' . $constant . ' is already defined');
- }
- else
- {
- define($constant, $value);
- }
- }
- }
- return true;
- }
- return false;
- }
- /**
- * Flatten
- *
- * Flattens the configuration array around the specified environment.
- *
- * @param string $environment selected environment
- * @param array $array configuration error to flatten
- * @return array flattened configuration array
- */
- private function flatten($environment, $array)
- {
- if (is_array($array))
- {
- foreach ($array as $key => $value)
- {
- if (is_array($value))
- {
- if (isset($value[$environment]))
- {
- $value = $value[$environment];
- }
- else
- {
- $value = $this->flatten($environment, $value);
- }
- }
- $array[$key] = $value;
- }
- }
- return $array;
- }
- /**
- * Get instance of the object
- *
- * Let's the parent class do all the work
- *
- * @static
- * @param string $class name of the class to instantiate
- * @return object self::$instance instance of the Config class
- */
- public static function getInstance($class = 'Config')
- {
- return parent::getInstance($class);
- }
- /**
- * Magic Setter Method
- *
- * Prohibits the direct modification of module variables.
- *
- * @param string $name name of the variable to be set
- * @param mixed $value value of the variable to be set
- */
- public function __set($name, $value)
- {
- throw new Exception('Cannot set config variables directly', E_USER_ERROR);
- }
- /**
- * Magic Getter Method
- *
- * Attempts to load the config variable. If it's not set, will override
- * the variable with boolean false.
- *
- * @param string $name name of the variable requested
- * @return mixed value of the variable or boolean false
- */
- public function __get($name)
- {
- if (!isset($this->data[$name]))
- {
- $this->data[$name] = false;
- }
- return $this->data[$name];
- }
- }
- /**
- * Single Entry Controller
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Controller Class
- *
- * The heavy lifter of PICKLES, makes the calls to get the session and
- * configuration loaded. Loads modules, serves up user authentication when the
- * module asks for it, and loads the viewer that the module requested. Default
- * values are present to make things easier on the user.
- *
- * @usage <code>new Controller($config);</code>
- */
- class Controller extends Object
- {
- /**
- * Pass Thru
- *
- * Whether or not the page being loaded is simple a pass thru for an
- * internal PICKLES file. The point of this variable is to suppress the
- * profiler report in the destructor.
- *
- * @access private
- * @var boolean
- */
- private $passthru = false;
- /**
- * Constructor
- *
- * To make life a bit easier when using PICKLES, the Controller logic is
- * executed automatically via use of a constructor.
- */
- public function __construct()
- {
- parent::__construct();
- if (isset($_REQUEST['request']))
- {
- // Catches requests that aren't lowercase
- $lowercase_reqest = strtolower($_REQUEST['request']);
- if ($_REQUEST['request'] != $lowercase_reqest)
- {
- header('Location: ' . substr_replace($_SERVER['REQUEST_URI'], $lowercase_reqest, 1, strlen($lowercase_reqest)));
- exit;
- }
- // Catches requests to the __shared directory
- if (preg_match('/^__shared/', $_REQUEST['request']))
- {
- header('Location: /');
- exit;
- }
- }
- // Generate a generic "site down" message if the site is set to be disabled
- if (isset($this->config->pickles['disabled']) && $this->config->pickles['disabled'] == true)
- {
- Error::fatal($_SERVER['SERVER_NAME'] . ' is currently<br />down for maintenance');
- }
- // Checks the passed request for validity
- if (isset($_REQUEST['request']) && trim($_REQUEST['request']) != '')
- {
- $request = $_REQUEST['request'];
- }
- // Loads the default module information if we don't have a valid request
- else
- {
- $request = isset($this->config->pickles['module']) ? $this->config->pickles['module'] : 'home';
- }
- // Loads the module's information
- list($module_class, $module_filename, $template_basename, $css_class, $js_basename) = $this->prepareVariables($request);
- unset($request);
- $module_exists = (isset($module_filename) && $module_filename != null && file_exists($module_filename));
- // Instantiates an instance of the module
- if ($module_exists)
- {
- require_once $module_filename;
- // Checks that our class exists
- if (class_exists($module_class))
- {
- $module = new $module_class;
- }
- else
- {
- if ($this->config->pickles['logging'] === true)
- {
- Log::warning('Class named ' . $module_class . ' was not found in ' . $module_filename);
- }
- }
- }
- // If a new module object wasn't created, create a generic one
- if (!isset($module))
- {
- $module = new Module();
- }
- // Determines if the module is private and should be, well, private
- if ($module->private == true)
- {
- header('Location: /');
- exit;
- }
- // Determines if we need to serve over HTTP or HTTPS
- if ($module->secure == false && isset($_SERVER['HTTPS']))
- {
- header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
- exit;
- }
- elseif ($module->secure == true && !isset($_SERVER['HTTPS']))
- {
- header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
- exit;
- }
- // Establishes the session
- if (ini_get('session.auto_start') == 0)
- {
- if ($module->session)
- {
- if (session_id() == '')
- {
- session_start();
- }
- }
- }
- // Validates security level
- if ($module->security !== false)
- {
- $is_authenticated = false;
- if (is_array($module->security))
- {
- $module_security = $module->security;
- $security_check_class = 'isLevel';
- // Checks the type and validates it
- if (isset($module_security['type']))
- {
- $security_check_type = strtoupper($module_security['type']);
- if (in_array($security_check_type, array('IS', 'HAS', 'BETWEEN')))
- {
- $security_check_class = $security_check_type;
- }
- unset($security_check_type, $module_security['type']);
- }
- $module_security_levels = array();
- // If there's a level(s) key use it
- foreach (array('level', 'levels') as $security_level_key)
- {
- if (isset($module_security[$security_level_key]))
- {
- if (is_array($module_security[$security_level_key]))
- {
- array_merge($module_security_levels, $module_security[$security_level_key]);
- }
- else
- {
- $module_security_levels[] = $module_security[$security_level_key];
- }
- unset($module_security[$security_level_key]);
- }
- }
- // Assume everything left in the array is a level and add it to the array
- array_merge($module_security_levels, $module_security);
- $security_level_count = count($module_security_levels);
- switch ($security_check_class)
- {
- case 'BETWEEN':
- if ($security_level_count >= 2)
- {
- $is_authenticated = Security::betweenLevel($module_security_levels[0], array_pop($module_security_levels));
- }
- break;
- case 'HAS':
- if ($security_level_count > 0)
- {
- $is_authenticated = Security::hasLevel($module_security_levels);
- }
- break;
- case 'IS':
- if ($security_level_count > 0)
- {
- $is_authenticated = Security::isLevel($module_security_levels);
- }
- break;
- }
- }
- else
- {
- $is_authenticated = Security::isLevel($module->security);
- }
- if ($is_authenticated == false)
- {
- if ($_SERVER['REQUEST_METHOD'] == 'POST')
- {
- exit('{ "status": "error", "message": "You are not properly authenticated" }');
- }
- else
- {
- // Sets variable for the destination
- $_SESSION['__pickles']['login']['destination'] = isset($_REQUEST['request']) ? $_REQUEST['request'] : '/';
- // Redirect to login page, potentially configured in the config, else /login
- header('Location: /' . (isset($this->config->security['login']) ? $this->config->security['login'] : 'login'));
- exit;
- }
- }
- }
- // Validates the rendering engine
- $engines = is_array($module->engine) ? array_values($module->engine) : array($module->engine);
- $engines = array_combine($engines, $engines);
- $engine = current($engines);
- // Possibly overrides the engine with the passed return type
- if (isset($return_type))
- {
- $return_type = strtoupper($return_type);
- // Validates the return type against the module
- if (in_array($return_type, array('JSON', 'RSS', 'XML')) && in_array($return_type, $engines))
- {
- $engine = $return_type;
- }
- unset($return_type);
- }
- // Starts up the display engine
- $display_class = 'Display_' . $engine;
- $display = new $display_class();
- // Assigns the template / template variables
- $display->setTemplateVariables($module->template, $template_basename, $css_class, $js_basename);
- // Checks the templates
- $template_exists = $display->templateExists();
- // If there is no valid module or template, then redirect
- if (!$module_exists && !$template_exists)
- {
- if (!isset($_REQUEST['request']))
- {
- Error::fatal('Way to go, you\'ve successfully created an infinite redirect loop. Good thing I was here or you would have been served with a pretty ugly browser error.<br /><br />So here\'s the deal, no templates were able to be loaded. Make sure your parent and child templates actually exist and if you\'re using non-default values, make sure they\'re defined correctly in your config.');
- }
- else
- {
- $redirect_url = '/';
- if (isset($this->config->pickles['404']) && $_REQUEST['request'] != $this->config->pickles['404'])
- {
- $redirect_url .= $this->config->pickles['404'];
- }
- header('Location: ' . $redirect_url, 404);
- exit;
- }
- }
- // Gets the profiler status
- $profiler = $this->config->pickles['profiler'];
- // Attempts to execute the default method
- if (method_exists($module, '__default'))
- {
- if (isset($requested_id))
- {
- $module->setRequest(array('id' => $requested_id));
- }
- // Sets meta data from the module
- $display->setMetaData(array(
- 'title' => $module->title,
- 'description' => $module->description,
- 'keywords' => $module->keywords
- ));
- // Starts a timer before the module is executed
- if ($profiler === true || stripos($profiler, 'timers') !== false)
- {
- Profiler::timer('module __default');
- }
- $valid_request = false;
- $valid_security_hash = false;
- $error_message = 'An unexpected error has occurred';
- // Determines if the request method is valid for this request
- if ($module->method != false)
- {
- $methods = (is_array($module->method) ? $module->method : array($module->method));
- $request_method = $_SERVER['REQUEST_METHOD'];
- foreach ($methods as $method)
- {
- if ($request_method == strtoupper($method))
- {
- $valid_request = true;
- break;
- }
- }
- if ($valid_request == false)
- {
- $error_message = 'There was a problem with your request method';
- }
- unset($methods, $request_method, $method);
- }
- else
- {
- $valid_request = true;
- }
- // Validates the hash if applicable
- if ($module->hash != false)
- {
- if (isset($_REQUEST['security_hash']))
- {
- $hash_value = ($module->hash === true ? get_class($module) : $module->hash);
- if (Security::generateHash($hash_value) == $_REQUEST['security_hash'])
- {
- $valid_security_hash = true;
- }
- else
- {
- $error_message = 'Invalid security hash';
- }
- unset($hash_value);
- }
- else
- {
- $error_message = 'Missing security hash';
- }
- }
- else
- {
- $valid_security_hash = true;
- }
- /**
- * Note to Self: When building in caching will need to let the
- * module know to use the cache, either passing in a variable
- * or setting it on the object
- */
- $display->setModuleReturn($valid_request && $valid_security_hash ? $module->__default() : array('status' => 'error', 'message' => $error_message));
- unset($error_message);
- // Stops the module timer
- if ($profiler === true || stripos($profiler, 'timers') !== false)
- {
- Profiler::timer('module __default');
- }
- }
- // Starts a timer for the display rendering
- if ($profiler === true || stripos($profiler, 'timers') !== false)
- {
- Profiler::timer('display render');
- }
- // Renders the content
- $display->render();
- // Steps the display timer
- if ($profiler === true || stripos($profiler, 'timers') !== false)
- {
- Profiler::timer('display render');
- }
- }
- /**
- * Destructor
- *
- * Dumps out the Profiler's report if applicable.
- */
- public function __destruct()
- {
- parent::__destruct();
- // Display the Profiler's report is the stars are aligned
- if ($this->config->pickles['profiler'] != false && $this->passthru == false)
- {
- Profiler::report();
- }
- }
- /**
- * Prepare Variables
- *
- * Processes the request variable and creates all the variables that the
- * Controller needs to load the page.
- *
- * @param string $basename the requested page
- * @return array the resulting variables
- */
- public function prepareVariables($basename)
- {
- // Sets up all of our variables
- $module_class = strtr($basename, '/', '_');
- $module_filename = SITE_MODULE_PATH . $basename . '.php';
- $template_basename = $basename;
- $css_class = $module_class;
- $js_basename = $basename;
- // Scrubs class names with hyphens
- if (strpos($module_class, '-') !== false)
- {
- $module_class = preg_replace('/(-(.{1}))/e', 'strtoupper("$2")', $module_class);
- }
- return array($module_class, $module_filename, $template_basename, $css_class, $js_basename);
- }
- }
- /**
- * Converter
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Convert Class
- *
- * Collection of statically called methods to help aid in converting formats.
- */
- class Convert
- {
- /**
- * To JSON
- *
- * Encodes passed variable as JSON.
- *
- * Requires PHP 5 >= 5.2.0 or PECL json >= 1.2.0
- * Note: PECL json 1.2.1 is included /vendors
- *
- * @link http://json.org/
- * @link http://us.php.net/json_encode
- * @link http://pecl.php.net/package/json
- *
- * @static
- * @param mixed $variable variable to convert
- * @return JSON encoded string
- */
- public static function toJSON($variable)
- {
- if (JSON_AVAILABLE)
- {
- return json_encode($variable);
- }
- else
- {
- return '{ "status": "error", "message": "json_encode() not found" }';
- }
- }
- /**
- * Array to XML
- *
- * Converts an array into XML tags (recursive). This method expects the
- * passed array to be formatted very specifically to accomodate the fact
- * that an array's format isn't quite the same as well-formed XML.
- *
- * Input Array =
- * array('children' => array(
- * 'child' => array(
- * array('name' => 'Wendy Darling'),
- * array('name' => 'John Darling'),
- * array('name' => 'Michael Darling')
- * )
- * ))
- *
- * Output XML =
- * <children>
- * <child><name>Wendy Darling</name></child>
- * <child><name>John Darling</name></child>
- * <child><name>Michael Darling</name></child>
- * </children>
- *
- * @static
- * @param array $array array to convert into XML
- * @return string generated XML
- */
- public static function arrayToXML($array, $format = false, $level = 0)
- {
- $xml = '';
- if (is_array($array))
- {
- foreach ($array as $node => $value)
- {
- // Checks if the value is an array
- if (is_array($value))
- {
- foreach ($value as $node2 => $value2)
- {
- if (is_array($value2))
- {
- // Nest the value if the node is an integer
- $new_value = (is_int($node2) ? $value2 : array($node2 => $value2));
- $xml .= ($format ? str_repeat("\t", $level) : '');
- $xml .= '<' . $node . '>' . ($format ? "\n" : '');
- $xml .= self::arrayToXML($new_value, $format, $level + 1);
- $xml .= ($format ? str_repeat("\t", $level) : '');
- $xml .= '</' . $node . '>' . ($format ? "\n" : '');
- }
- else
- {
- if (is_int($node2))
- {
- $node2 = $node;
- }
- // Checks for special characters
- if (htmlspecialchars($value2) != $value2)
- {
- $xml .= ($format ? str_repeat("\t", $level) : '');
- $xml .= '<' . $node2 . '><![CDATA[' . $value2 . ']]></' . $node2 . '>' . ($format ? "\n" : '');
- }
- else
- {
- $xml .= ($format ? str_repeat("\t", $level) : '');
- $xml .= '<' . $node2 . '>' . $value2 . '</' . $node2 . '>' . ($format ? "\n" : '');
- }
- }
- }
- }
- else
- {
- // Checks for special characters
- if (htmlspecialchars($value) != $value)
- {
- $xml .= ($format ? str_repeat("\t", $level) : '');
- $xml .= '<' . $node . '><![CDATA[' . $value . ']]></' . $node . '>' . ($format ? "\n" : '');
- }
- else
- {
- $xml .= ($format ? str_repeat("\t", $level) : '');
- $xml .= '<' . $node . '>' . $value . '</' . $node . '>' . ($format ? "\n" : '');
- }
- }
- }
- }
- return $xml;
- }
- }
- /**
- * Common Database Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Common Database Abstraction Layer
- *
- * Parent class that our database driver classes should be extending. Contains
- * basic functionality for instantiation and interfacing.
- */
- abstract class Database_Common extends Object
- {
- /**
- * Driver
- *
- * @access protected
- * @var string
- */
- protected $driver = null;
- /**
- * Hostname for the server
- *
- * @access protected
- * @var string
- */
- protected $hostname = 'localhost';
- /**
- * Port number for the server
- *
- * @access protected
- * @var integer
- */
- protected $port = null;
- /**
- * UNIX socket for the server
- *
- * @access protected
- * @var integer
- */
- protected $socket = null;
- /**
- * Username for the server
- *
- * @access protected
- * @var string
- */
- protected $username = null;
- /**
- * Password for the server
- *
- * @access protected
- * @var string
- */
- protected $password = null;
- /**
- * Database name for the server
- *
- * @access protected
- * @var string
- */
- protected $database = null;
- /**
- * Whether or not to use caching
- *
- * @access protected
- * @var boolean
- */
- protected $cache = false;
- /**
- * Connection resource
- *
- * @access protected
- * @var object
- */
- protected $connection = null;
- /**
- * Results object for the executed statement
- *
- * @access protected
- * @var object
- */
- protected $results = null;
- /**
- * Constructor
- */
- public function __construct()
- {
- parent::__construct();
- // Checks the driver is set and available
- if ($this->driver == null)
- {
- throw new Exception('Driver name is not set');
- }
- else
- {
- if (extension_loaded($this->driver) == false)
- {
- throw new Exception('Driver "' . $this->driver . '" is not loaded');
- }
- }
- }
- /**
- * Set Hostname
- *
- * @param string $hostname hostname for the database
- */
- public function setHostname($hostname)
- {
- return $this->hostname = $hostname;
- }
- /**
- * Set Port
- *
- * @param integer $port port for the database
- */
- public function setPort($port)
- {
- return $this->port = $port;
- }
- /**
- * Set Socket
- *
- * @param string $socket name of the UNIX socket
- */
- public function setSocket($socket)
- {
- return $this->socket = $socket;
- }
- /**
- * Set Username
- *
- * @param string $username username for the database
- */
- public function setUsername($username)
- {
- return $this->username = $username;
- }
- /**
- * Set Password
- *
- * @param string $password password for the database
- */
- public function setPassword($password)
- {
- return $this->password = $password;
- }
- /**
- * Set Database
- *
- * @param string $database database for the database
- */
- public function setDatabase($database)
- {
- return $this->database = $database;
- }
- /**
- * Set Cache
- *
- * @param boolean whether or not to use cache
- */
- public function setCache($cache)
- {
- return $this->cache = $cache;
- }
- /**
- * Get Driver
- *
- * Returns the name of the driver in use. Used by the Model class to
- * determine which path to take when interfacing with the Database object.
- *
- * @return string name of the driver in use
- */
- public function getDriver()
- {
- return $this->driver;
- }
- /**
- * Get Cache
- *
- * Returns the status of caching for this datasource.
- *
- * @return string whether or not to use the cache
- */
- public function getCache()
- {
- return $this->cache;
- }
- /**
- * Opens database connection
- *
- * Establishes a connection to the MySQL database based on the
- * configuration options that are available in the Config object.
- *
- * @abstract
- * @return boolean true on success, throws an exception overwise
- */
- abstract public function open();
- /**
- * Closes database connection
- *
- * Sets the connection to null regardless of state.
- *
- * @return boolean always true
- */
- abstract public function close();
- }
- /**
- * PDO Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * PDO Abstraction Layer
- *
- * Parent class for any of our database classes that use PDO.
- */
- class Database_PDO_Common extends Database_Common
- {
- /**
- * DSN format
- *
- * @access protected
- * @var string
- */
- protected $dsn;
- /**
- * PDO Attributes
- *
- * @access protected
- * @var string
- */
- protected $attributes = array(
- PDO::ATTR_PERSISTENT => true,
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::NULL_EMPTY_STRING => true
- );
- /**
- * Constructor
- */
- public function __construct()
- {
- parent::__construct();
- // Checks that the prefix is set
- if ($this->dsn == null)
- {
- throw new Exception('Data source name is not defined');
- }
- }
- /**
- * Opens database connection
- *
- * Establishes a connection to the database based on the set configuration
- * options.
- *
- * @return boolean true on success, throws an exception overwise
- */
- public function open()
- {
- if ($this->connection === null)
- {
- if (isset($this->username, $this->password, $this->database))
- {
- // Creates a new PDO database object (persistent)
- try
- {
- // Swaps out any variables with values in the DSN
- $this->dsn = str_replace(
- array('[[hostname]]', '[[port]]', '[[socket]]', '[[username]]', '[[password]]', '[[database]]'),
- array($this->hostname, $this->port, $this->socket, $this->username, $this->password, $this->database),
- $this->dsn
- );
- // Strips any empty parameters in the DSN
- $this->dsn = str_replace(array('host=;', 'port=;', 'unix_socket=;'), '', $this->dsn);
- // Attempts to establish a connection
- $this->connection = new PDO($this->dsn, $this->username, $this->password, $this->attributes);
- }
- catch (PDOException $e)
- {
- throw new Exception($e);
- }
- }
- else
- {
- throw new Exception('There was an error loading the database configuration');
- }
- }
- return true;
- }
- /**
- * Closes database connection
- *
- * Sets the connection to null regardless of state.
- *
- * @return boolean always true
- */
- public function close()
- {
- $this->connection = null;
- return true;
- }
- /**
- * Executes an SQL Statement
- *
- * Executes a standard or prepared query based on passed parameters. All
- * queries are logged to a file as well as timed and logged in the
- * execution time is over 1 second.
- *
- * @param string $sql statement to execute
- * @param array $input_parameters optional key/values to be bound
- * @return integer ID of the last inserted row or sequence number
- */
- public function execute($sql, $input_parameters = null)
- {
- $this->open();
- if ($this->config->pickles['logging'] === true)
- {
- $loggable_query = $sql;
- if ($input_parameters != null)
- {
- $loggable_query .= ' -- ' . (JSON_AVAILABLE ? json_encode($input_parameters) : serialize($input_parameters));
- }
- Log::query($loggable_query);
- }
- $sql = trim($sql);
- // Checks if the query is blank
- if ($sql != '')
- {
- try
- {
- // Establishes if we're working on an EXPLAIN
- if (Profiler::enabled('explains') == true)
- {
- $explaining = preg_match('/^EXPLAIN /i', $sql);
- $selecting = preg_match('/^SELECT /i', $sql);
- }
- else
- {
- $explaining = null;
- $selecting = null;
- }
- // Executes a standard query
- if ($input_parameters === null)
- {
- // Explains the query
- if ($selecting == true && $explaining == false)
- {
- $explain = $this->fetch('EXPLAIN ' . $sql);
- }
- $start_time = microtime(true);
- $this->results = $this->connection->query($sql);
- }
- // Executes a prepared statement
- else
- {
- // Explains the query
- if ($selecting == true && $explaining == false)
- {
- $explain = $this->fetch('EXPLAIN ' . $sql, $input_parameters);
- }
- $start_time = microtime(true);
- $this->results = $this->connection->prepare($sql);
- $this->results->execute($input_parameters);
- }
- $end_time = microtime(true);
- $duration = $end_time - $start_time;
- if ($this->config->pickles['logging'] === true && $duration >= 1)
- {
- Log::slowQuery($duration . ' seconds: ' . $loggable_query);
- }
- // Logs the information to the profiler
- if ($explaining == false && Profiler::enabled('explains', 'queries'))
- {
- Profiler::logQuery($sql, $input_parameters, (isset($explain) ? $explain : false), $duration);
- }
- }
- catch (PDOException $e)
- {
- throw new Exception($e);
- }
- }
- else
- {
- throw new Exception('No query to execute');
- }
- return $this->connection->lastInsertId();
- }
- /**
- * Fetch records from the database
- *
- * @param string $sql statement to be executed
- * @param array $input_parameters optional key/values to be bound
- * @param string $return_type optional type of return set
- * @return mixed based on return type
- */
- public function fetch($sql = null, $input_parameters = null)
- {
- $this->open();
- if ($sql !== null)
- {
- $this->execute($sql, $input_parameters);
- }
- // Pulls the results based on the type
- $results = $this->results->fetchAll(PDO::FETCH_ASSOC);
- return $results;
- }
- }
- /**
- * MySQL Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * MySQL Database Abstraction Layer
- */
- class Database_PDO_MySQL extends Database_PDO_Common
- {
- /**
- * Driver
- *
- * @access protected
- * @var string
- */
- protected $driver = 'pdo_mysql';
- /**
- * DSN format
- *
- * @access protected
- * @var string
- */
- protected $dsn = 'mysql:host=[[hostname]];port=[[port]];unix_socket=[[socket]];dbname=[[database]]';
- /**
- * Default port
- *
- * @access proceted
- * @var integer
- */
- protected $port = 3306;
- }
- /**
- * PostgreSQL Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * PostgreSQL Database Abstraction Layer
- */
- class Database_PDO_PostgreSQL extends Database_PDO_Common
- {
- /**
- * Driver
- *
- * @access protected
- * @var string
- */
- protected $driver = 'pdo_pgsql';
- /**
- * DSN format
- *
- * @access protected
- * @var string
- */
- protected $dsn = 'pgsql:host=[[hostname]];port=[[port]];dbname=[[database]];user=[[username]];password=[[password]]';
- /**
- * Default port
- *
- * @access proceted
- * @var integer
- */
- protected $port = 5432;
- }
- /**
- * SQLite Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * SQLite Database Abstraction Layer
- */
- class Database_PDO_SQLite extends Database_PDO_Common
- {
- /**
- * Driver
- *
- * @access protected
- * @var string
- */
- protected $driver = 'pdo_sqlite';
- /**
- * DSN format
- *
- * @access protected
- * @var string
- */
- protected $dsn = 'sqlite:[[hostname]]';
- }
- /**
- * Database Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Database Factory
- *
- * Generic class to simplify connecting to a database. All database objects
- * should be created by this class to future proof against any internal changes
- * to PICKLES.
- */
- class Database extends Object
- {
- /**
- * Constructor
- *
- * Attempts to get an instance of the passed database type or attempts to
- * use a default specified in the config.
- *
- * @param string $name optional name of the connection to use
- */
- public function __construct(String $name = null)
- {
- parent::__construct();
- return Database::getInstance($name);
- }
- /**
- * Get instance
- *
- * Looks up the datasource using the passed name and gets an instance of
- * it. Allows for easy sharing of certain classes within the system to
- * avoid the extra overhead of creating new objects each time. Also avoids
- * the hassle of passing around variables (yeah I know, very global-ish)
- *
- * @static
- * @param string $name name of the datasource
- * @return object instance of the class
- */
- public static function getInstance($name = null)
- {
- $config = Config::getInstance();
- // Checks if we have a default
- if ($name == null)
- {
- // Checks the config for a default
- if (isset($config->pickles['datasource']))
- {
- $name = $config->pickles['datasource'];
- }
- // Tries to use the first defined datasource
- elseif (is_array($config->datasources))
- {
- $datasources = $config->datasources;
- $name = key($datasources);
- }
- }
- // If we have a name try to set up a connection
- if ($name != null)
- {
- if (isset($config->datasources[$name]))
- {
- $datasource = $config->datasources[$name];
- $datasource['driver'] = strtolower($datasource['driver']);
- if (!isset(self::$instances['Database'][$name]))
- {
- // Checks the driver is legit and scrubs the name
- switch ($datasource['driver'])
- {
- case 'pdo_mysql': $class = 'PDO_MySQL'; break;
- case 'pdo_pgsql': $class = 'PDO_PostgreSQL'; break;
- case 'pdo_sqlite': $class = 'PDO_SQLite'; break;
- default:
- throw new Exception('Datasource driver "' . $datasource['driver'] . '" is invalid');
- break;
- }
- // Instantiates our database class
- $class = 'Database_' . $class;
- $instance = new $class();
- // Sets our database parameters
- if (isset($datasource['hostname']))
- {
- $instance->setHostname($datasource['hostname']);
- }
- if (isset($datasource['port']))
- {
- $instance->setPort($datasource['port']);
- }
- if (isset($datasource['socket']))
- {
- $instance->setSocket($datasource['socket']);
- }
- if (isset($datasource['username']))
- {
- $instance->setUsername($datasource['username']);
- }
- if (isset($datasource['password']))
- {
- $instance->setPassword($datasource['password']);
- }
- if (isset($datasource['database']))
- {
- $instance->setDatabase($datasource['database']);
- }
- if (isset($datasource['cache']))
- {
- $instance->setCache($datasource['cache']);
- }
- }
- // Caches the instance for possible reuse later
- if (isset($instance))
- {
- self::$instances['Database'][$name] = $instance;
- }
- // Returns the instance
- return self::$instances['Database'][$name];
- }
- }
- return false;
- }
- }
- /**
- * Date Utility Collection
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Date Class
- *
- * Just a simple collection of static functions to accomplish some of the more
- * redundant date related manipulation.
- */
- class Date
- {
- // {{{ Age
- /**
- * Age
- *
- * Calculates age based on the passed date.
- *
- * @static
- * @param string $date birth / inception date
- * @return integer $age number of years old
- */
- public static function age($date)
- {
- if (!preg_match('/\d{4}-\d{2}-\d{2}/', $date))
- {
- $date = date('Y-m-d', strtotime($date));
- }
- list($year, $month, $day) = explode('-', $date, 3);
- $age = date('Y') - $year;
- if (date('md') < $month . $day)
- {
- $age--;
- }
- return $age;
- }
- // }}}
- }
- /**
- * Common Display Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Common Display Class
- *
- * This is the parent class class that each display class should be
- * extending and executing parent::render()
- */
- abstract class Display_Common extends Object
- {
- /**
- * Template Extension
- *
- * @access protected
- * @var string $extension file extension for the template files
- */
- protected $extension = null;
- /**
- * Parent Template
- *
- * @access protected
- * @var string
- */
- protected $parent_template = null;
- /**
- * Child (sub) Template
- *
- * @access protected
- * @var string
- */
- protected $child_template = null;
- /**
- * CSS Class Name
- *
- * @access protected
- * @var string
- */
- protected $css_class = '';
- /**
- * Javascript [Path and] Basename
- *
- * @access protected
- * @var array
- */
- protected $js_basename = '';
- /**
- * Meta Data
- *
- * @access protected
- * @var array
- */
- protected $meta_data = null;
- /**
- * Module Return Data
- *
- * @access protected
- * @var array
- */
- protected $module_return = null;
- /**
- * Constructor
- *
- * Gets those headers working
- */
- public function __construct()
- {
- parent::__construct();
- // Obliterates any passed in PHPSESSID (thanks Google)
- if (stripos($_SERVER['REQUEST_URI'], '?PHPSESSID=') !== false)
- {
- list($request_uri, $phpsessid) = explode('?PHPSESSID=', $_SERVER['REQUEST_URI'], 2);
- header('HTTP/1.1 301 Moved Permanently');
- header('Location: ' . $request_uri);
- exit;
- }
- else
- {
- // XHTML compliancy stuff
- ini_set('arg_separator.output', '&');
- ini_set('url_rewriter.tags', 'a=href,area=href,frame=src,input=src,fieldset=');
- header('Content-type: text/html; charset=UTF-8');
- }
- }
- /**
- * Set Template
- *
- * Sets the template file based on passed template type. Adds path and
- * extension if applicable.
- *
- * @param string $template template file's basename
- * @param string $type template file's type (either parent or child)
- */
- private function setTemplate($template, $type)
- {
- if ($template != null)
- {
- $template_name = $type . '_template';
- $template_path = SITE_TEMPLATE_PATH . ($type == 'parent' ? '__shared/' : '');
- $template_file = $template_path . $template . ($this->extension != false ? '.' . $this->extension : '');
- if (file_exists($template_file))
- {
- $this->$template_name = $template_file;
- }
- }
- }
- /**
- * Set Template Variables
- *
- * Sets the variables used by the templates
- *
- * @param string $parent_template parent template
- * @param string $child_template child (sub) template
- * @param string $css_class name of the CSS class for the module
- * @param string $js_basename basename for the javascript file for the module
- */
- public function setTemplateVariables($parent_template, $child_template, $css_class, $js_basename)
- {
- $this->setTemplate($parent_template, 'parent');
- $this->setTemplate($child_template, 'child');
- $this->css_class = $css_class;
- $this->js_basename = $js_basename;
- }
- /**
- * Set Meta Data
- *
- * Sets the meta data from the module so the display class can use it
- *
- * @param array $meta_data key/value array of data
- */
- public function setMetaData($meta_data)
- {
- $this->meta_data = $meta_data;
- }
- /**
- * Set Module Return
- *
- * Sets the return data from the module so the display class can display it
- *
- * @param array $module_return key / value pairs for the data
- */
- public function setModuleReturn($module_return)
- {
- $this->module_return = $module_return;
- }
- /**
- * Template Exists
- *
- * Checks the templates for validity, not required by every display type so
- * the return defaults to true.
- *
- * @return boolean whether or not the template exists
- */
- public function templateExists()
- {
- return true;
- }
- /**
- * Rendering Method
- *
- * @abstract
- */
- abstract public function render();
- }
- /**
- * JSON Display Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * JSON Display
- *
- * Displays data in JavaScript Object Notation.
- */
- class Display_JSON extends Display_Common
- {
- /**
- * Renders the data in JSON format
- */
- public function render()
- {
- echo Convert::toJSON($this->module_return);
- }
- }
- /**
- * PHP Display Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * PHP Display
- *
- * Displays the associated PHP templates for the Model.
- */
- class Display_PHP extends Display_Common
- {
- /**
- * Template Extension
- *
- * I know there's some controversy amoungst my peers concerning the
- * usage of the .phtml extension for these PHP template files. If you
- * would prefer .php or .tpl extensions, feel free to void your
- * warranty and change it here.
- *
- * @access protected
- * @var string $extension file extension for the template files
- */
- protected $extension = 'phtml';
- /**
- * Template Exists
- *
- * @return integer the number of templates defined
- */
- public function templateExists()
- {
- if ($this->parent_template != null)
- {
- return file_exists($this->parent_template) && file_exists($this->child_template);
- }
- else
- {
- return file_exists($this->child_template);
- }
- }
- /**
- * Renders the PHP templated pages
- */
- public function render()
- {
- if ($this->templateExists())
- {
- // Starts up the buffer
- ob_start();
- // Puts the class variables in local scope of the template
- $__config = $this->config;
- $__meta = $this->meta_data;
- $__module = $this->module_return;
- $__css_class = $this->css_class;
- $__js_file = $this->js_basename;
- // Creates (possibly overwritten) objects
- $form_class = (class_exists('CustomForm') ? 'CustomForm' : 'Form');
- $dynamic_class = (class_exists('CustomDynamic') ? 'CustomDynamic' : 'Dynamic');
- $__form = new $form_class();
- $__dynamic = new $dynamic_class();
- // Loads the template
- if ($this->parent_template != null)
- {
- if ($this->child_template == null)
- {
- $__template = $this->parent_template;
- }
- else
- {
- $__template = $this->child_template;
- }
- require_once $this->parent_template;
- }
- elseif ($this->child_template != null)
- {
- $__template = $this->child_template;
- require_once $__template;
- }
- // Grabs the buffer contents and clears it out
- $buffer = ob_get_clean();
- // Kills any whitespace and HTML comments
- $buffer = preg_replace(array('/^[\s]+/m', '/<!--.*-->/U'), '', $buffer);
- // Note, this doesn't exit in case you want to run code after the display of the page
- echo $buffer;
- }
- else
- {
- echo Convert::toJSON($this->module_return);
- }
- }
- }
- /**
- * RSS Display Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * RSS Display
- *
- * Displays data as an RSS formatted XML string.
- */
- class Display_RSS extends Display_Common
- {
- // {{{ Feed Defaults
- /**
- * RSS Version
- *
- * @access private
- * @var string
- */
- private $version = '2.0';
- /**
- * Date Format
- *
- * @access private
- * @var string
- */
- private $date_format = 'r';
- // }}}
- // {{{ Channel Defaults
- /**
- * Title
- *
- * @access private
- * @var string
- */
- private $title = '';
- /**
- * Link
- *
- * @access private
- * @var string
- */
- private $link = '';
- /**
- * Description
- *
- * @access private
- * @var string
- */
- private $description = '';
- /**
- * Language
- *
- * @access private
- * @var string
- */
- private $language = 'en-us';
- /**
- * Generator
- *
- * @access private
- * @var string
- */
- private $generator = 'http://p.ickl.es';
- // }}}
- /**
- * Renders the data in RSS format
- */
- public function render()
- {
- // Throws off the syntax highlighter otherwise
- echo '<' . '?xml version="1.0" ?' . '><rss version="' . $this->version . '"><channel>';
- // Loops through the passable channel variables
- $channel = array();
- foreach (array('title', 'link', 'description', 'language') as $variable)
- {
- if (isset($this->module_return[$variable]))
- {
- $this->$variable = $this->module_return[$variable];
- }
- $channel[$variable] = $this->$variable;
- }
- $channel['generator'] = $this->generator;
- // Loops through the items
- $items = '';
- $build_date = '';
- if (isset($this->module_return['items']) && is_array($this->module_return['items']))
- {
- foreach ($this->module_return['items'] as $item)
- {
- // Note: time is the equivalent to pubDate, I just don't like camel case variables
- $publish_date = date($this->date_format, is_numeric($item['time']) ? $item['time'] : strtotime($item['time']));
- if ($build_date == '')
- {
- $build_date = $publish_date;
- }
- if (isset($item['link']))
- {
- $item['guid'] = $item['link'];
- }
- $item['pubDate'] = $publish_date;
- unset($item['time']);
- $items .= Convert::arrayToXML($item);
- }
- }
- $channel['pubDate'] = $build_date;
- $channel['lastBuildDate'] = $build_date;
- echo Convert::arrayToXML($channel) . $items . '</channel></rss>';
- }
- }
- /**
- * XML Display Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * XML Display
- *
- * Displays data in XML format.
- */
- class Display_XML extends Display_Common
- {
- /**
- * Renders the data in XML format
- */
- public function render()
- {
- echo Convert::arrayToXML($this->module_return);
- }
- }
- /**
- * Dynamic Content Class File for PICKLES
- *
- * PHP version 5
- *
- * Licensed under The MIT License
- * Redistribution of these files must retain the above copyright notice.
- *
- * @author Josh Sherman <josh@gravityblvd.com>
- * @copyright Copyright 2007-2011, Josh Sherman
- * @license http://www.opensource.org/licenses/mit-license.html
- * @package PICKLES
- * @link http://p.ickl.es
- */
- /**
- * Dynamic Class
- *
- * Handles generating links to static content that are a timestamp injected as
- * to avoid hard caching. Also minifies content where applicable.
- *
- * Note: you will want to add a mod_rewrite line to your .htaccess to support
- * the routing to the filenames with the timestamp injected:
- *
- * RewriteRule ^(.+)\.([\d]+)\.(css|js|gif|png|jpg|jpeg)$ /$1.$3 [NC,QSA]
- */
- class Dynamic extends Object
- {
- /**
- * Generate Reference
- *
- * Appends a dynamic piece of information to the passed reference in the
- * form of a UNIX timestamp added to the query string.
- *
- * @param string $reference URI reference of the file
- * @param string $failover URI reference to use if the reference can't be found
- * @return string URI reference reference with dynamic content
- */
- public function reference($reference, $failover = false)
- {
- // Checks if the URI reference is absolute, and not relative
- if (substr($reference, 0, 1) == '/')
- {
- $query_string = '';
- // Checks for ? and extracts query string
- if (strstr($reference, '?'))
- {
- list($reference, $query_string) = explode('?', $reference);
- }
- // Adds the dot so the file functions can find the file
- $file = '.' . $reference;
- if (file_exists($file))
- {
- // Replaces the extension with time().extension
- $parts = explode('.', $reference);
- if (count($parts) == 1)
- {
- throw new Exception('Filename must have an extension (e.g. /path/to/file.png)');
- }
- else
- {
- end($parts);
- $parts[key($parts)] = filemtime($file) . '.' . current($parts);
- $reference = implode('.', $parts);
- }
- // Adds the query string back
- if ($query_string != '')
- {
- $reference .= '?' . $query_string;
- }
- }
- else
- {
- if ($failover != false)
- {
- $reference = $failover;
- }
- else
- {
- throw new Exception('Supplied reference does not exist (' . $reference . ')');
- }
- }
- }
- else
- {
- throw new Exception('Reference value must be absolute (e.g. /path/to/file.png)');
- }
- return $reference;
- }
- /**
- * Generate Stylesheet Reference
- *
- * Attempts to minify the stylesheet and then returns the reference URI
- * for the file, minified or not.
- *
- * @param string $reference URI reference of the Stylesheet
- * @return string URI reference reference with dynamic content
- */
- public function css($original_reference)
- {
- // Injects .min into the filename
- $parts = explode('.', $original_reference);
- if (count($parts) == 1)
- {
- throw new Exception('Filename must have an extension (e.g. /path/to/file.css)');