Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 220939b819996c103e45018b4b57137405a49bf9 @josegonzalez committed Nov 21, 2011
@@ -0,0 +1,99 @@
+h1. DynamicRoute Plugin (For CakePHP 1.3)
+
+Read routes from a database into @routes.php@ quickly and easily
+
+h2. Background
+
+As with the other route class I built, someone asked in IRC if it would be possible to read the routes from the database and load them into the @app/config/routes.php@ file on the fly. I decided this was true, and this is the result.
+
+h2. Requirements
+
+* PHP 5.2+
+* CakePHP 1.3
+
+h2. Installation
+
+_[Manual]_
+
+# Download this: http://github.com/josegonzalez/dynamic_route/zipball/master
+# Unzip that download.
+# Copy the resulting folder to app/plugins
+# Rename the folder you just copied to @dynamic_route@
+
+_[GIT Submodule]_
+
+In your app directory type:
+<pre><code>git submodule add git://github.com/josegonzalez/dynamic_route.git plugins/dynamic_route
+git submodule init
+git submodule update
+</code></pre>
+
+_[GIT Clone]_
+
+In your plugin directory type
+<pre><code>git clone git://github.com/josegonzalez/dynamic_route.git dynamic_route</code></pre>
+
+h2. Usage
+
+Way near the bottom of your @app/config/routes.php@ file, add the following:
+
+<pre><code>App::import('Lib', 'DynamicRoute.FancyRoute');
+FancyRoute::connectFancyRoutes();
+</code></pre>
+
+You can now remove all other **hacks** from your @app/config/routes.php@ file.
+
+What we've enabled is creating @spec|slug@ routes in the database. A @spec@ would be the internal CakePHP mapping, like @posts/view?id=45@ or @events/calendar?date=2011-11-01&category=lol@, while the corresponding @slug@s might be something like @/why-isnt-this-pup-asleep@ or @/manchester/cakephp-developers-dance-to-beyonce@.
+
+This @spec|slug@ system allows one to have a specialized table for routing - by default the @dynamic_routes@ table - which can be used across multiple models and controllers if necessary. It allows a developer to create a simple interface for building internal application routes that a non-developer can use at a later date. This is extremely useful when building content management systems that need a Joomla or Wordpress-like routing system.
+
+h2. Options
+
+@FancyRoute::connectFancyRoutes()@ takes an optional array for configuration the route loading:
+
+* @model@: String or Object referencing a CakePHP Model to use for loading records.
+** Default: (string) @DynamicRoute.DynamicRoute@
+** Note: Model being loaded must have a @load@ custom find method that returns specs mapping to slugs
+* @cacheKey@: Key used for caching the dynamic routes to disk
+** Default: (string) @dynamic_routes@
+* @cache@: Whether to cache the db queries
+** Default: (boolean) true
+
+h2. Notes
+
+Because of the way in which this class works, it is not necessary to call @Router::connect()@ on any of the dynamic routes, as this is called internally by the @FancyRoute@ class.
+
+The @DynamicRoute@ model contains methods for turning a given specification into an internal cakephp request, whether that be a string or array.
+
+You will currently have to create valid @spec|slug@ records yourself. Slugs should be prepended with a @/@ character, but should not be followed by one. Specs are regular web requests, @$_GET@ style.
+
+There is a helper method on the @DynamicRoute@ model called @saveNew()@; This method takes a @spec@ and @slug@, or an array of data, and returns whether or not the save is successful. It will also do it's best to ensure that the data is properly setup by normalizing specifications and ensuring there slug is in the correct format.
+
+h2. Todo
+
+* Unit Tests
+* Backend UI for creating new dynamic routes
+* -Helper Model method for creating new dynamic routes-
+* Port to 2.0
+
+h2. License
+
+Copyright (c) 2011 Jose Diaz-Gonzalez
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,62 @@
+<?php
+class M4eca1305e1ec49fa9291be82cbdd56cb extends CakeMigration {
+
+/**
+ * Migration description
+ *
+ * @var string
+ * @access public
+ */
+ public $description = '';
+
+/**
+ * Actions to be performed
+ *
+ * @var array $migration
+ * @access public
+ */
+ public $migration = array(
+ 'up' => array(
+ 'create_table' => array(
+ 'dynamic_routes' => array(
+ 'slug' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'spec' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'active' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
+ 'indexes' => array(
+ 'PRIMARY' => array('column' => 'slug', 'unique' => 1),
+ 'spec' => array('column' => 'spec', 'unique' => 0),
+ ),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB'),
+ ),
+ ),
+ ),
+ 'down' => array(
+ 'drop_table' => array(
+ 'dynamic_routes',
+ ),
+ ),
+ );
+
+/**
+ * Before migration callback
+ *
+ * @param string $direction, up or down direction of migration process
+ * @return boolean Should process continue
+ * @access public
+ */
+ public function before($direction) {
+ return true;
+ }
+
+/**
+ * After migration callback
+ *
+ * @param string $direction, up or down direction of migration process
+ * @return boolean Should process continue
+ * @access public
+ */
+ public function after($direction) {
+ return true;
+ }
+}
+?>
@@ -0,0 +1,6 @@
+<?php
+$map = array(
+ 1 => array(
+ '001_initial_migration' => 'M4eca1305e1ec49fa9291be82cbdd56cb'),
+);
+?>
@@ -0,0 +1,21 @@
+<?php
+/* dynamic_route schema generated on: 2011-11-21 08:44:09 : 1321865049*/
+class DynamicRouteSchema extends CakeSchema {
+ var $name = 'DynamicRoute';
+
+ function before($event = array()) {
+ return true;
+ }
+
+ function after($event = array()) {
+ }
+
+ var $dynamic_routes = array(
+ 'slug' => array('type' => 'string', 'null' => false, 'default' => NULL, 'key' => 'primary', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'spec' => array('type' => 'string', 'null' => false, 'default' => NULL,'key' => 'index', 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
+ 'active' => array('type' => 'boolean', 'null' => false, 'default' => '1'),
+ 'indexes' => array('PRIMARY' => array('column' => 'slug', 'unique' => 1), 'spec' => array('column' => 'spec', 'unique' => 0)),
+ 'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
+ );
+}
+?>
@@ -0,0 +1,4 @@
+<?php
+class DynamicRouteAppModel extends AppModel {
+
+}
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Custom Route class enables database-backed, dynamic routes
+ * Enables you to add new pages from the database without having to
+ * manually specify a shortcut route in your routes.php file
+ *
+ * To use, install the page_route plugin and add
+ * the following to the top of app/config/routes.php:
+ *
+ * App::import('Lib', 'FancyRoute.FancyRoute');
+ *
+ * To trigger it, simply call the connectFancyRoutes() static method:
+ *
+ * FancyRoute::connectFancyRoutes();
+ *
+ * Note that this hack works by calling Router::connect() on the actual
+ * DynamicRoute records.
+ *
+ * @author Jose Gonzalez (support@savant.be)
+ * @license http://www.opensource.org/licenses/mit-license.php MIT License
+ * @see CakeRoute
+ */
+class FancyRoute {
+
+/**
+ * An array of additional parameters for the Route.
+ *
+ * @var array
+ * @access public
+ */
+ static $options = array(
+ 'model' => 'DynamicRoute.DynamicRoute',
+ 'cacheKey' => 'dynamic_routes',
+ 'cache' => true,
+ );
+
+ static $_routes = array();
+
+ static $model = null;
+
+/**
+ * Constructor for a Route
+ *
+ * @param string $template Template string with parameter placeholders
+ * @param array $defaults Array of defaults for the route.
+ * @param string $params Array of parameters and additional options for the Route
+ * @return void
+ * @access public
+ */
+ public static function connectFancyRoutes($options = array()) {
+ static::$options = array_merge(static::$options, (array) $options);
+ Configure::write('DynamicRoute.cacheKey', static::$options['cacheKey']);
+
+ self::_loadDynamicRoutes();
+ }
+
+/**
+ * Loads routes in from the cache or database
+ *
+ * @return boolean
+ */
+ public static function _loadDynamicRoutes() {
+ if (static::$options['cache']) {
+ static::$_routes = Cache::read(static::$options['cacheKey']);
+ if (static::$_routes) {
+ return self::_loadRoutes();
+ }
+ }
+
+ if (is_object(static::$options['model'])) {
+ static::$model = static::$options['model'];
+ } else {
+ static::$model = ClassRegistry::init(static::$options['model']);
+ }
+
+ if (!is_object(static::$model)) {
+ if (!class_exists('CakeLog')) {
+ App::import('Core', 'CakeLog');
+ }
+ CakeLog::write('dynamic_route', 'Unable to load dynamic_route model');
+ return false;
+ }
+
+ static::$_routes = static::$model->find('load');
+ if (static::$_routes) {
+ if (static::$options['cache']) {
+ Cache::write(static::$options['cacheKey'], static::$_routes);
+ }
+ return self::_loadRoutes();
+ }
+
+ if (!class_exists('CakeLog')) {
+ App::import('Core', 'CakeLog');
+ }
+ CakeLog::write('dynamic_route', 'No routes available');
+ return false;
+ }
+
+ public static function _loadRoutes() {
+ foreach (static::$_routes as $slug => $spec) {
+ Router::connect($slug, $spec);
+ }
+ return true;
+ }
+
+}
Oops, something went wrong.

0 comments on commit 220939b

Please sign in to comment.