Completed updates to MVC approach and completed base functionality.
authorChuck Scott <cscott@gaslightmedia.com>
Tue, 11 Nov 2014 02:18:13 +0000 (21:18 -0500)
committerChuck Scott <cscott@gaslightmedia.com>
Tue, 11 Nov 2014 02:18:13 +0000 (21:18 -0500)
Should all be working now. Still needs more documentation updates.

29 files changed:
controllers/admin.php
controllers/front.php
css/index.css
index.php
lib/smartyTemplateSupport.php
models/activate.php
models/admin/add.php [deleted file]
models/admin/add/index.php [new file with mode: 0644]
models/admin/display.php [deleted file]
models/admin/error/badAction.php [new file with mode: 0644]
models/admin/error/index.php [new file with mode: 0644]
models/admin/list.php [deleted file]
models/admin/prototypes/delete.php [new file with mode: 0644]
models/admin/prototypes/display.php [new file with mode: 0644]
models/admin/prototypes/edit.php [new file with mode: 0644]
models/admin/prototypes/index.php [new file with mode: 0644]
models/deactivate.php
models/uninstall.php
views/admin/add/index.html [new file with mode: 0644]
views/admin/add/submitted.html [new file with mode: 0644]
views/admin/error/badAction.html [new file with mode: 0644]
views/admin/prototype_add.html [deleted file]
views/admin/prototype_display.html [deleted file]
views/admin/prototype_list.html [deleted file]
views/admin/prototype_submitted.html [deleted file]
views/admin/prototypes/display.html [new file with mode: 0644]
views/admin/prototypes/edit.html [new file with mode: 0644]
views/admin/prototypes/index.html [new file with mode: 0644]
views/admin/prototypes/updated.html [new file with mode: 0644]

index d1c6101..ca0deb7 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Gaslight Media Prototype Management and Display 
+ * Gaslight Media Prototype Management and Display
  * Admin Controller
  *
  * PHP version 5.5
  * @link     http://dev.gaslightmedia.com/
  */
 
-/*
- * This class sets up WordPress admin menus and controls which models are use for
- * admin functionality of this plugin. 
- * 
+/**
+ * Array of valid menu items and actions.
+ *
+ *
+ * The higher level elements are valid menu items. These correlate to
+ * actual menu or sub menu items that are hooks back to this controller
+ * class.
+ *
+ * The lower level items below each menu item are actions that may be specified
+ * by a "glmProtoAction" form field.
+ */
+$GLOBALS['glmProtoAdminValidActions'] = array(
+
+        'prototypes' => array(
+                'index',
+                'display',
+                'edit',
+                'delete'
+        ),
+        'add' => array(
+                'index'
+        ),
+        'error' => array(
+                'badAction'
+        )
+);
+
+/**
+ * Admin Controller Class
+ *
+ * This is one of perhaps multiple controller classes that provide
+ * controller services for a major portion of this plugin. Typically
+ * there are such classes for Admin and Front-End functionality, but
+ * there could be others.
+ *
+ * This controller class performs all admin related operations for
+ * this plugin by calling the appropriate model and merging the resulting
+ * data with the appropriate view to produce any output.
+ *
+ * All requests for this controller class come through WordPress admin
+ * menus via hooks that "call back" methods in this class for each admin
+ * menu item in this plugin. Form submissions from an admin page selected
+ * by a particular menu item are directed to WordPress using the page
+ * reference of that menu item. Because of this, the callback for a form
+ * submission is also handled by the callback target method used by that
+ * menu item.
+ *
+ * Admin form submissions must use the URI for one of this plugin's
+ * menu items. The form post parameters may also provide an "action" name
+ * in the case where the default menu item behavior is not desired. A
+ * pathname for the model to execute is then complied using the menu
+ * item name as the name of a directory under models/admin and the
+ * requested action as the file name of the model to execute. The name
+ * "index" would be the default menu item action model. In essence the
+ * controller locates the model by menu item name and action name. for
+ * example...
+ *
+ * models/admin/prototypes/index.php
+ * models/admin/prototypes/display.php
+ *
+ * Similarly, the view associated with the action would be in a directory
+ * named the same as the model, and the view file would be named "index"
+ * or the name of the action.
+ *
+ * These hooks are established using the WordPress add_action()
+ * function and the configureMenus() method below. Other methods in this
+ * class then recieve any request from a menu item selection or form
+ *
+ * submission associated with a menu item by WordPress calling one of the
+ * "callback" methods below.
+ *
+ * The callback methods do nothing other than to call the controller()
+ * method and passing it the name of the menu item assocaiated with the
+ * callback.
+ *
+ * The controller() method determines which model to execute, executes
+ * that model, determines which view to merge with the data returned by
+ * the model, creates output from the result of that merge, and sends
+ * that output to the user.
+ *
+ * In situations where it may be desired to output directly to the browser
+ * without being contained in the admin Dashboard, the contructor can be
+ * directed
+ * to bypass setting up the admin hooks and execute the controller() method
+ * directly then exit. This results in output from the model/view withing being
+ * contained in the normal WordPress dashboard context. To trigger this use the
+ * following two form fields.
+ *
+ * glm_display_direct = 'true'
+ * glm_menu_item = (menu item name associated with the desired model)
+ *
+ * (no prameters)
+ *
+ * @return void
+ * @access public
  */
 class glmProtoAdmin
 {
-       
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-
-       /**
-        * Admin Controller Constructor
-        *
-        * This contructor is executed by the main plugin index file when the site 
-        * Dashboard is displayed. It's responsible for setting up any needed hooks
-        * into WordPress and setting up any support classes required to do admin
-        * work.
-        *
-        * (no prameters)
-        *
-        * @return void
-        * @access public
-        */
-       public function __construct($wpdb)
-       {
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-               
-               // Add hooks to WordPress
-               add_action( 'admin_menu', array($this, 'configureMenus'));
-               
-               /*
-                * Check for Requested Actions
-                */
-               if (isset($_REQUEST['glm_proto_action'])) {
-               
-                       switch ($_REQUEST['glm_proto_action']) {
-                                       
-                               // Display a prototype
-                               case 'display':
-                                       require_once(GLM_PROTO_PLUGIN_DIR.'/models/admin/display.php');
-                                       return new glmProtoAdminDisplayModel($this->wpdb);
-                                       break;
-                                       
-                               default:
-                                       break;
-                                               
-                       }
-               }
-               
-       }
-       
-       /**
-        * Configure Additional WordPress Menus
-        *
-        * This method is called by an add_action() hook setup in the contructor. We do it
-        * this way so that the menu related functions of WordPress are in scope when creating
-        * the additional menu items. WordPress will execute this call-back method when building
-        * its Dashboard menus.
-        * 
-        * (no prameters)
-        *
-        * @return void
-        * @access public
-        */
-       public function configureMenus() {
-               
-               // Add a new main menu item for management and display of customer prototypes.
-               add_menu_page('Site Prototypes', 'Prototypes', 'manage_options', 'glm-proto-admin-list', array($this, 'glmProtoAdminList'));
-               
-               // Add sub-menu for adding a new prototype under the Prototypes main menu item.
-               add_submenu_page('glm-proto-admin-list', 'Site Prototypes', 'Add', 'manage_options', 'glm-proto-admin-add', array($this, 'glmProtoAdminAdd'));
-               
-       }
-
-       /*
-        * Menu action methods
-        * 
-        * These methods are called by WordPress when specific menu items are selected by the user. 
-        * They should only include and execute the appropriate model for that menu action. 
-        * 
-        */
-
-       // Main GLM Prototypes Menu Item - Lists current prototypes
-       public function glmProtoAdminList()
-       {
-               require_once(GLM_PROTO_PLUGIN_DIR.'/models/admin/list.php');
-               new glmProtoAdminListModel($this->wpdb);
-       }
-       
-       // Add Prototype Sub Menu Item - Displays a form to add a new prototype
-       public function glmProtoAdminAdd()
-       {
-               require_once(GLM_PROTO_PLUGIN_DIR.'/models/admin/add.php');
-               return new glmProtoAdminAddModel($this->wpdb);
-       }
-               
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /**
+     * Admin Controller Constructor
+     *
+     * This contructor is executed by the main plugin index file when the site
+     * Dashboard is displayed. It's responsible for setting up any needed hooks
+     * into WordPress and setting up any support classes required to do admin
+     * work.
+     *
+     * (no prameters)
+     *
+     * @return void
+     * @access public
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        /*
+         * Check if there's a request to bypass the WordPress Dashboard and
+         * display
+         * directly to the browser using a specified menuItem/action.
+         *
+         */
+        if (isset($_REQUEST['glm_display_direct']) &&
+                 $_REQUEST['glm_menu_item'] != '') {
+
+            // Get the desired menu item name and call controller() with that.
+            $menuItem = sanitize_text_field($_REQUEST['glm_menu_item']);
+            $this->controller($menuItem);
+
+            // Exit at this point to stop all WordPress Dashboard output
+            exit();
+        }
+
+        // Add hooks to WordPress
+        add_action('admin_menu',
+                array(
+                        $this,
+                        'configureMenus'
+                ));
+    }
+
+    /**
+     * Configure WordPress Menus for this Plugin
+     *
+     * This method is called by an add_action() hook setup in the contructor. We
+     * do it
+     * this way so that the menu related functions of WordPress are in scope
+     * when creating
+     * the additional menu items. WordPress will execute this call-back method
+     * when building
+     * its Dashboard menus.
+     *
+     * (no prameters)
+     *
+     * @return void
+     * @access public
+     */
+    public function configureMenus ()
+    {
+
+        // Add a new main menu item for management and display of customer
+        // prototypes.
+        add_menu_page('Site Prototypes', 'Prototypes', 'manage_options',
+                'glm-proto-admin-menu-prototypes',
+                array(
+                        $this,
+                        'glmProtoAdminMenuPrototypes'
+                ));
+
+        // Add sub-menu for adding a new prototype under the Prototypes main
+        // menu item.
+
+        add_submenu_page('glm-proto-admin-menu-prototypes', 'Site Prototypes',
+                'Add', 'manage_options', 'glm-proto-admin-menu-add',
+                array(
+                        $this,
+                        'glmProtoAdminMenuAdd'
+                ));
+    }
+
+    /*
+     * Menu item specific "Callback" methods
+     *
+     * These methods are called by WordPress when specific menu items are
+     * selected by the
+     * user or a form action is submitted associated with the menu item.
+     *
+     * These methods call the controller and pass it the menu item that was
+     * called
+     * but perform no other work.
+     *
+     */
+
+    // Main GLM Prototypes Menu Item - Default (list and other operations)
+    public function glmProtoAdminMenuPrototypes ()
+    {
+        $this->controller('prototypes');
+    }
+
+    // Add Prototype Sub Menu Item - Displays a form to add a new prototype
+    public function glmProtoAdminMenuAdd ()
+    {
+        $this->controller('add');
+    }
+
+    /**
+     * Admin controller
+     *
+     * This method is called by a plugin menu method. It is responsible for
+     * executing the approriate model, combining model data with a view, and
+     * outputing the result. It is therefore the core of the controller.
+     *
+     * This controller is supplied a menu item name and then determines if
+     * there is an additional action related to that menu item that needs to be
+     * executed rather than the default menu action.
+     *
+     * All models should return an array containing the following.
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     * For a better explanation of how this all works, see the description for
+     * this class.
+     *
+     * Controller parameters
+     *
+     * @menuItem string Name of the menu item that is being processed
+     *
+     * @return void
+     * @access public
+     */
+    public function controller ($menuItem)
+    {
+
+        /*
+         * Determine model to execute
+         */
+
+        // Default action is "index"
+        $action = 'index';
+
+        // Get any requested "action" from a form submission modify path/name
+        // accordingly
+        if (isset($_REQUEST['glm_action']) && $_REQUEST['glm_action'] != '') {
+            $a = sanitize_text_field($_REQUEST['glm_action']);
+            if ($a != '') {
+                $action = $a;
+            }
+        }
+
+        // Loop as long as there's a model redirect.
+        do {
+
+            // Verify Menu item and action using array at top of this file
+            if (! in_array($action,
+                    $GLOBALS['glmProtoAdminValidActions'][$menuItem])) {
+                $menuItem = 'error';
+                $action = 'badAction';
+            }
+
+            /*
+             * Execute the selected model
+             */
+            // Build model and path and class names and load the model
+            $modelName = GLM_PROTO_PLUGIN_DIR . '/models/admin/' . $menuItem .
+                     '/' . $action . '.php';
+            $className = 'glmProtoAdmin_' . $menuItem . '_' . $action;
+            require_once ($modelName);
+
+            // Instantiate the model and ask it to perform the work
+            $model = new $className($this->wpdb);
+            $results = $model->modelAction();
+
+            // Check if there's been a model redirect request
+            $modelRedirect = false;
+            if ($results['modelRedirect']) {
+
+                // Set the new model action
+                $action = $results['modelRedirect'];
+
+                // Check if there's also a menu item change
+                if ($results['menuItemRedirect']) {
+                    $menuItem = $results['menuItemRedirect'];
+                }
+
+                $modelRedirect = true;
+            }
+
+            // Loop again if there's a model redirect
+        } while ($modelRedirect);
+
+        /*
+         * Check model results
+         */
+
+        // Get suggested view
+        $view = $results['view'];
+
+        // If there's a general model failure use the error view
+        if (! $results['status']) {
+            $view = 'admin/error/index.html';
+        }
+
+        /*
+         * Merge data returned from the model with the selected view
+         */
+
+        // Load Smarty Template support
+        require (GLM_PROTO_PLUGIN_DIR . '/lib/smartyTemplateSupport.php');
+        $smarty = new smartyTemplateSupport();
+
+        // Add some standard parameters
+        $smarty->templateAssign(
+                array(
+                        'request_uri' => $_SERVER['REQUEST_URI']
+                ));
+
+        // Add data from model to Smarty template
+        $haveData = false;
+        if (is_array($results['data']) && count($results['data']) > 0) {
+            $haveData = true;
+            $smarty->templateAssign('data', $results['data']);
+        }
+        $smarty->templateAssign('haveData', $haveData);
+
+        // $x = $smarty->template->getTemplateVars();
+        // echo "<pre>".print_r($x,1)."</pre>";
+
+        // Generate output from model data and view
+        $smarty->template->display($view);
+    }
 }
 
 
index e7a39b1..6ba764c 100644 (file)
@@ -1,6 +1,7 @@
 <?php
+
 /**
- * Gaslight Media Prototype Management and Display 
+ * Gaslight Media Prototype Management and Display
  * Front-End Controller
  *
  * PHP version 5.5
  */
 class glmProtoFront
 {
-               
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-       
-       public function __construct()
-       {
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-               
-               /*
-                * This plugin does not currently have front-end functionality
-                */
 
-       }
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    public function __construct ()
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
 
+        /*
+         * This plugin does not currently have front-end functionality
+         */
+    }
 }
 
 ?>
\ No newline at end of file
index b523bb6..c0bd6e9 100644 (file)
@@ -1,6 +1,7 @@
 .glm-proto-required {
-       color: red;
+    color: red;
 }
+
 .glm-proto-error {
-       color: red;     
+    color: red;
 }
\ No newline at end of file
index b1fae7b..85e9752 100644 (file)
--- a/index.php
+++ b/index.php
 
 /**
  * Gaslight Media Prototype Management and Display
- * Index 
+ * Index
  *
  * PHP version 5.5
  *
  * @category glmWordPressPlugin
- * @package  glmPrototypeManagement
- * @author   Chuck Scott <cscott@gaslightmedia.com>
- * @license  http://www.gaslightmedia.com Gaslightmedia
- * @version  1.0
+ * @package glmPrototypeManagement
+ * @author Chuck Scott <cscott@gaslightmedia.com>
+ * @license http://www.gaslightmedia.com Gaslightmedia
+ * @version 1.0
  */
 
-/*  Copyright 2014 Charles Scott  (email : cscott@gaslightmedia.com)
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License, version 2, as
-published by the Free Software Foundation.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-/*********************************************************************************
-
-Directory and File Structure
-
-       index.php                       Index file for this plugin. All plugin processing starts 
-                                               here. (See "Process Flow" below.)
-
-       controllers                     Directory containing any controllers. Typically there
-                                               would be admin and front controllers in this directory. 
-                                               These controllers do the general setup for the plugin, 
-                                               determine and call the appropriate model, determine the 
-                                               appropriate view, then merge any data returned by the model 
-                                               with the view and output the result as appropriate. 
-                                               
-                                               When executed, a model may determine that it cannot handle 
-                                               the current request and return such a notice to the controller 
-                                               possibly with a suggested model to execute. Models may also 
-                                               return a desired view back to the controller based on the 
-                                               result of processing, but should do so in a generic way so 
-                                               as to permit multi-lingual output and use of multiple "skins"
-                                               (but not to the exception of appropriate use of WordPress
-                                               Themes).        
-       
-       css                                     Directory containing any css files specific to this plugin.
-                                               The use of additional styling should be kept to a minimum
-                                               so as to not interfere with the application of WordPress
-                                               default styling and Themes.
-        
-       js                                      Directory containing any JAVAscript files specific to this
-                                               Plugin. This directory should be reserved for general script
-                                               files that provide functionality that can be used in various
-                                               views. Any JAVAscript that is specific to a view should be
-                                               located along with the associated view as it is logically
-                                               part of the view.
-       
-       lib                                     Directory containing any class or function libraries that 
-                                               are used generally by this plugin. Any class or other code
-                                               that is specific to a particular model should be located
-                                               in, or along with, that model since it is logically 
-                                               associated only with that model. 
-        
-       misc                            Directory containing ancillary directories and files. This
-                                               might be used for things like cach directories. An example
-                                               might be the "smarty" directory for Smaarty Templates.
-                                               
-       models                          Directory containing model files that execute a specific
-                                               process in this plugin. If this is a simple plugin, then 
-                                               the model files can be placed directly in this directory.
-                                               If it's a more complex plugin, then there should be sub-
-                                               directories for various groupings of related model files. 
-
-                                               An individual model may consist of a grouping of files, 
-                                               such as additional class files, that are specific only to
-                                               that model. In that case, these should be located in a 
-                                               subdirectory under where the model file called by the 
-                                               controller is located and that directory should be named
-                                               so as to be obviously associated with that model. 
-                                               
-                                               There are three special files in the models directory. These
-                                               are activate.php, deactivate.php, and uninstall.php. These
-                                               are called via hooks setup in this file and should always
-                                               be here. If they do not provide any real functionality, they
-                                               should at least be a shell that can be called for those 
-                                               situations.
-                                               
-       views                           Directory containing view files for producing output upon
-                                               request of a model file in the models directory. If this
-                                               is a simply plugin, then the view files can be placed 
-                                               directly in this directory. If it's a more complex plugin,
-                                               then there should be sub-directories for the various 
-                                               groupings of related view files. If using sub-directories,
-                                               those should generally match the associated model directories.
-                                               It may also be wise to use separate front and admin
-                                               directories under views to keep things organized.
-                                               
-                                               Additionally, views may be grouped in such a way that they
-                                               support the selection of various "skins" that output in
-                                               different ways, although any styling should be provided by
-                                               WordPress Themes or use default WordPress styling.
-                                               
-Process Flow
-
-       * WordPress calls the plugin index file. All plugin processing starts here.
-       
-       * The plugin index file performs the following operations ...
-               - Sets-up any required plugin-wide defines and data
-               - Instatiates any plugin-wide classes and objects
-               - Sets-up any plugin-wide WordPress hooks
-               - Determines which controller is to be executed
-               - Executes the selected controller 
-               
-       * The selected controller performs the following operations ... 
-               - Sets-up any controller specific defines and data
-               - Instatiates any controller specific classes and objects
-               - Sets-up any controller specific WordPress hooks
-               - Determines which model process is to be executed
-               - Executes the selected model
-               
-       * The selected model performs the following operations ...
-               - Sets-up any model specific defines and data
-               - Instatiates any model specific classes and objects
-               - Sets-up any model specific WordPress hooks
-               - Performs any specific processing required of the model 
-               - Determines which view is to be used to generate output
-               - Generates output based on model data and the selected view
-
-       * WordPress wraps everything up         
-               
-**********************************************************************************/
+/*
+ * Copyright 2014 Charles Scott (email : cscott@gaslightmedia.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
 
+/**
+ * *******************************************************************************
+ *
+ * *** Directory and File Structure ***
+ *
+ * index.php
+ *
+ * Index file for this plugin. All plugin processing starts here. (See
+ * "Process Flow" below.)
+ *
+ * controllers
+ *
+ * Directory containing any controllers. Typically there
+ * would be admin and front controllers in this directory.
+ * These controllers do the general setup for the plugin,
+ * determine and call the appropriate model, determine the
+ * appropriate view, then merge any data returned by the model
+ * with the view and output the result as appropriate.
+ *
+ * When executed, a model may determine that it cannot handle
+ * the current request and return such a notice to the controller
+ * possibly with a suggested model to execute. Models may also
+ * return a desired view back to the controller based on the
+ * result of processing, but should do so in a generic way so
+ * as to permit multi-lingual output and use of multiple "skins"
+ * (but not to the exception of appropriate use of WordPress
+ * Themes).
+ *
+ * css
+ *
+ * Directory containing any css files specific to this plugin.
+ * The use of additional styling should be kept to a minimum
+ * so as to not interfere with the application of WordPress
+ * default styling and Themes.
+ *
+ * js
+ *
+ * Directory containing any JAVAscript files specific to this
+ * Plugin. This directory should be reserved for general script
+ * files that provide functionality that can be used in various
+ * views. Any JAVAscript that is specific to a view should be
+ * located along with the associated view as it is logically
+ * part of the view.
+ *
+ * lib
+ *
+ * Directory containing any class or function libraries that
+ * are used generally by this plugin. Any class or other code
+ * that is specific to a particular model should be located
+ * in, or along with, that model since it is logically
+ * associated only with that model.
+ *
+ * misc
+ *
+ * Directory containing ancillary directories and files. This
+ * might be used for things like cach directories. An example
+ * might be the "smarty" directory for Smaarty Templates.
+ *
+ * models
+ *
+ * Directory containing model files that execute a specific
+ * process in this plugin. If this is a simple plugin, then
+ * the model files can be placed directly in this directory.
+ * If it's a more complex plugin, then there should be sub-
+ * directories for various groupings of related model files.
+ *
+ * An individual model may consist of a grouping of files,
+ * such as additional class files, that are specific only to
+ * that model. In that case, these should be located in a
+ * subdirectory under where the model file called by the
+ * controller is located and that directory should be named
+ * so as to be obviously associated with that model.
+ *
+ * There are three special files in the models directory. These
+ * are activate.php, deactivate.php, and uninstall.php. These
+ * are called via hooks setup in this file and should always
+ * be here. If they do not provide any real functionality, they
+ * should at least be a shell that can be called for those
+ * situations.
+ *
+ * views
+ *
+ * Directory containing view files for producing output upon
+ * request of a model file in the models directory. If this
+ * is a simply plugin, then the view files can be placed
+ * directly in this directory. If it's a more complex plugin,
+ * then there should be sub-directories for the various
+ * groupings of related view files. If using sub-directories,
+ * those should generally match the associated model directories.
+ * It may also be wise to use separate front and admin
+ * directories under views to keep things organized.
+ *
+ * Additionally, views may be grouped in such a way that they
+ * support the selection of various "skins" that output in
+ * different ways, although any styling should be provided by
+ * WordPress Themes or use default WordPress styling.
+ *
+ * *** Process Flow ***
+ *
+ * WordPress calls the plugin index file. All plugin processing starts here.
+ *
+ * The plugin index file performs the following operations ...
+ * - Sets-up any required plugin-wide defines and data
+ * - Instatiates any plugin-wide classes and objects
+ * - Sets-up any plugin-wide WordPress hooks
+ * - Determines which controller is to be executed
+ * - Executes the selected controller
+ *
+ * The selected controller performs the following operations ...
+ * - Sets-up any controller specific defines and data
+ * - Instatiates any controller specific classes and objects
+ * - Sets-up any controller specific WordPress hooks
+ * - Determines which model process is to be executed
+ * - Executes the selected model
+ *
+ * The selected model performs the following operations ...
+ * - Sets-up any model specific defines and data
+ * - Instatiates any model specific classes and objects
+ * - Sets-up any model specific WordPress hooks
+ * - Performs any specific processing required of the model
+ * - Determines which view is to be used to generate output
+ * - Generates output based on model data and the selected view
+ *
+ * WordPress wraps everything up
+ *
+ * ********************************************************************************
+ */
 
 /*
- *  Set some parameters
+ *
+ * Set standard parameters
+ *
  */
 
 // WordPress Debugging
-if (!defined( 'WP_DEBUG' )) {
-       define( 'WP_DEBUG', true );
+if (! defined('WP_DEBUG')) {
+    define('WP_DEBUG', true);
 }
 // Plugin URL
-if (!defined( 'GLM_PROTO_PLUGIN_URL' )) {
-       define( 'GLM_PROTO_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
+if (! defined('GLM_PROTO_PLUGIN_URL')) {
+    define('GLM_PROTO_PLUGIN_URL', plugin_dir_url(__FILE__));
 }
 
 // Plugin Directory
-if (!defined( 'GLM_PROTO_PLUGIN_DIR' )) {
-       define( 'GLM_PROTO_PLUGIN_DIR', dirname( __FILE__ ) );
+if (! defined('GLM_PROTO_PLUGIN_DIR')) {
+    define('GLM_PROTO_PLUGIN_DIR', dirname(__FILE__));
 }
 // Custom plugin post type (for wp_post entries)
-define( 'GLM_PROTO_PLUGIN_POST_TYPE', 'glm_proto');
+define('GLM_PROTO_PLUGIN_POST_TYPE', 'glm_proto');
 
 /*
+ *
  * Activate, Deactivate, Uninstall hooks
+ *
  */
 
 // Activate
-function glmProtoPluginActivate() 
+function glmProtoPluginActivate ()
 {
-       global $wpdb;
-       require_once(GLM_PROTO_PLUGIN_DIR.'/models/activate.php');
-       new glmProtoPluginActivate($wpdb);
+    global $wpdb;
+    require_once (GLM_PROTO_PLUGIN_DIR . '/models/activate.php');
+    new glmProtoPluginActivate($wpdb);
 }
-register_activation_hook( __FILE__, 'glmProtoPluginActivate' );
+register_activation_hook(__FILE__, 'glmProtoPluginActivate');
 
 // Deactivate
-function glmProtoPluginDeactivate()
+function glmProtoPluginDeactivate ()
 {
-       global $wpdb;
-       require_once(GLM_PROTO_PLUGIN_DIR.'/models/deactivate.php');
-       new glmProtoPluginDectivate($wpdb);
+    global $wpdb;
+    require_once (GLM_PROTO_PLUGIN_DIR . '/models/deactivate.php');
+    new glmProtoPluginDectivate($wpdb);
 }
-register_deactivation_hook( __FILE__, 'glmProtoPluginDeativate' );
+register_deactivation_hook(__FILE__, 'glmProtoPluginDeativate');
 
 // Uninstall
-function glmProtoPluginUninstall()
+function glmProtoPluginUninstall ()
 {
-       global $wpdb;
-       require_once(GLM_PROTO_PLUGIN_DIR.'/models/uninstall.php');
-       new glmProtoPluginUninstall($wpdb);
+    global $wpdb;
+    require_once (GLM_PROTO_PLUGIN_DIR . '/models/uninstall.php');
+    new glmProtoPluginUninstall($wpdb);
 }
-register_uninstall_hook( __FILE__, 'glmProtoPluginUninstall' );
+register_uninstall_hook(__FILE__, 'glmProtoPluginUninstall');
 
 /*
+ *
  * Style Sheets
+ *
  */
-wp_register_style('glmProtoIndexStyle', GLM_PROTO_PLUGIN_URL.'css/index.css');
-wp_enqueue_style( 'glmProtoIndexStyle' );
+
+// A simple set of styles for things I haven't found as a WordPress default yet
+wp_register_style('glmProtoIndexStyle', GLM_PROTO_PLUGIN_URL . 'css/index.css');
+wp_enqueue_style('glmProtoIndexStyle');
 
 /*
- * Scripts
+ *
+ * JAVAscript files that need to be enqueued.
+ *
  */
+
 add_action('admin_enqueue_scripts', 'glmProtoScripts');
-function glmProtoScripts() {
-       wp_enqueue_media();
-       wp_register_script('glm-proto-index-js', GLM_PROTO_PLUGIN_URL.'js/index.js', array('jquery'));
-       wp_enqueue_script('glm-proto-index-js');
-}
 
+function glmProtoScripts ()
+{
+    wp_enqueue_media();
+    wp_register_script('glm-proto-index-js',
+            GLM_PROTO_PLUGIN_URL . 'js/index.js',
+            array(
+                    'jquery'
+            ));
+    wp_enqueue_script('glm-proto-index-js');
+}
 
 /*
- *     Standard includes
+ *
+ * Standard includes and classes
+ *
  */
-require_once(GLM_PROTO_PLUGIN_DIR.'/lib/smartyTemplateSupport.php');
 
 /*
- *     Determine which controller to load
+ * Determine which controller to load
  */
 if (is_admin()) {
-       
-       require_once(GLM_PROTO_PLUGIN_DIR.'/controllers/admin.php');
-       new glmProtoAdmin($wpdb);
 
+    require_once (GLM_PROTO_PLUGIN_DIR . '/controllers/admin.php');
+    new glmProtoAdmin($wpdb);
 } else {
-       
-       require_once(GLM_PROTO_PLUGIN_DIR.'/controllers/front.php');    
-       new glmProtoFront($wpdb);
-       
-}
 
+    require_once (GLM_PROTO_PLUGIN_DIR . '/controllers/front.php');
+    new glmProtoFront($wpdb);
+}
 
 ?>
\ No newline at end of file
index 5efb8d4..39244a3 100644 (file)
@@ -1,6 +1,7 @@
 <?php
+
 /**
- * Gaslight Media Prototype Management and Display 
+ * Gaslight Media Prototype Management and Display
  * Smarty Templates Support Class
  *
  * PHP version 5.5
  */
 
 /*
- * This class loads, instatiates, and configures Smarty Templates for this plugin.
- * 
- * This class should be extended with the class that will need to use Smarty. This
- * will make the $template object available to the class extending this one as 
- * $this->template. 
- * 
+ * This class loads, instatiates, and configures Smarty Templates for this
+ * plugin.
+ *
+ * This class should be extended with the class that will need to use Smarty.
+ * This
+ * will make the $template object available to the class extending this one as
+ * $this->template.
+ *
  * The templateAssign() method simplifies adding parameters to the template.
- * 
- * To use this class you must execute the following. No need to assign the result.
- * 
- *             new smartyTemplateSupport();
- * 
+ *
+ * To use this class you must execute the following. No need to assign the
+ * result.
+ *
+ * new smartyTemplateSupport();
+ *
  */
-abstract class smartyTemplateSupport
+class smartyTemplateSupport
 {
 
-       /**
-        * Smarty Template Object
-        * @var    $template
-        * @access public
-        */
-       public $template;
-       
     /**
-     * Setup Smarty Templates
-     *
-     * Initializes Smarty Templates and assigns the Smarty object to $this->template
-     * for use in any classes that extend this class.
-     * 
-     * To initialize Smarty Templates use the following call in the contructor of the
-     * extended class.
-     * 
-     *                 $this->setupSmarty();
-     * 
-     * (no prameters)
+     * Smarty Template Object
      *
-     * @return void
+     * @var $template
      * @access public
      */
-       public function setupSmarty()
-       {
-               
-               /*
-                *      Load and instatiate Smarty Templates
-                */
-               require(GLM_PROTO_PLUGIN_DIR.'/lib/Smarty-3.1.21/libs/Smarty.class.php');
+    public $template;
 
-               $this->template = new Smarty();
-               
-               /*
-                *  Configure Smarty Templates for this site
-                */
-               $this->template->setTemplateDir(GLM_PROTO_PLUGIN_DIR.'/views');
-               $this->template->setCompileDir(GLM_PROTO_PLUGIN_DIR.'/misc/smarty/templates_c');
-               $this->template->setCacheDir(GLM_PROTO_PLUGIN_DIR.'/misc/smarty/cache');
-               $this->template->setConfigDir(GLM_PROTO_PLUGIN_DIR.'/misc/smarty/configs');
+    /*
+     * Smarty Template Support Constructor
+     *
+     * This constructor loads and instatiates smarty templates, then adds some
+     * standard template parameters.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ()
+    {
 
-       }
-       
-       /*
-        * Assign parameters to the template
-        * 
-        * This method assigns either one parameter to the template object in this class
-        * or an array of parameters. 
-        * 
-        * Submit an array of parameters to the template.
-        * 
-        * @param array Array of arrays with parameter name (key), value pairs
-        * 
-        *   or
-        * 
-        * Submit one parameter to the template
-        * 
-        * @param text parameter name
-        * @param {whatever} parameter value
-        *
-        * @return void
-        */
-       public function templateAssign($param, $value = null)
-       {
-       
-               // If this is a single assignment
-               if ($value !== null) {
+        /*
+         * Load and instatiate Smarty Templates
+         */
+        require (GLM_PROTO_PLUGIN_DIR .
+                 '/lib/Smarty-3.1.21/libs/Smarty.class.php');
 
-                       $this->template->assign($param, $value);
+        $this->template = new Smarty();
 
-               // Otherwise it's an array of parameter/value pairs
-               } elseif (is_array($param)) {
-       
-                       while (list($key, $value) = each($param)) {
-                               $this->template->assign($key, $value);
-                       }
-       
-               }
-       
-       }
-       
+        /*
+         * Configure Smarty Templates for this site
+         */
+        $this->template->setTemplateDir(GLM_PROTO_PLUGIN_DIR . '/views');
+        $this->template->setCompileDir(
+                GLM_PROTO_PLUGIN_DIR . '/misc/smarty/templates_c');
+        $this->template->setCacheDir(
+                GLM_PROTO_PLUGIN_DIR . '/misc/smarty/cache');
+        $this->template->setConfigDir(
+                GLM_PROTO_PLUGIN_DIR . '/misc/smarty/configs');
+    }
 
-}
+    /*
+     * Assign parameters to the template
+     *
+     * This method assigns either one parameter to the template object in this
+     * class
+     * or an array of parameters.
+     *
+     * Submit an array of parameters to the template.
+     *
+     * @param array Array of arrays with parameter name (key), value pairs
+     *
+     * or
+     *
+     * Submit one parameter to the template
+     *
+     * @param text parameter name
+     * @param {whatever} parameter value
+     *
+     * @return void
+     */
+    public function templateAssign ($param, $value = null)
+    {
 
+        // If this is a single assignment
+        if ($value !== null) {
 
+            $this->template->assign($param, $value);
+
+            // Otherwise it's an array of parameter/value pairs
+        } elseif (is_array($param)) {
+
+            while (list ($key, $value) = each($param)) {
+                $this->template->assign($key, $value);
+            }
+        }
+    }
+}
 
 ?>
\ No newline at end of file
index eee198e..4d6b5cd 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Gaslight Media Prototype Management and Display
  * Activate Plugin Tasks
  */
 class glmProtoPluginActivate
 {
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-
-       /*
-        * Constructor
-        *
-        * Performs all the work for this model
-        */
-       public function __construct($wpdb)
-       {
-               
-               // Make sure the current user has this capability
-               if ( !current_user_can('activate_plugins') ) {
-                       return;
-               }
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-
-               // Perform any activation tasks here
-       }
 
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * Performs all the work for this model
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Make sure the current user has this capability
+        if (! current_user_can('activate_plugins')) {
+            return;
+        }
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Perform any activation tasks here
+    }
 }
 
 ?>
\ No newline at end of file
diff --git a/models/admin/add.php b/models/admin/add.php
deleted file mode 100644 (file)
index 373e246..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-/**
- * Gaslight Media Prototype Management and Display
- * Admin Add Prototype Model
- *
- * PHP version 5.5
- *
- * @category glmWordPressPlugin
- * @package  glmPrototypeManagement
- * @author   Chuck Scott <cscott@gaslightmedia.com>
- * @license  http://www.gaslightmedia.com Gaslightmedia
- * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
- * @link     http://dev.gaslightmedia.com/
- */
-
-/*
- * This class performs the work needed to add a new prototype.
- * 
- * If a prototype is properly submitted, it is stored in the wp_posts table
- * using the following fields.
- * 
- *             post_date               Current date
- *             post_date_gmt   Current date in GMT
- *             post_content    Serialized array with 'title', 'background', and 'prototype'
- *             post_title              Title of prototype
- *             post_type               'glm_proto'
- *
- */
-class glmProtoAdminAddModel extends smartyTemplateSupport
-{
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-       /**
-        * Selected Template File
-        * @var    $templateFile
-        * @access public
-        */
-       public $templateFile;
-       
-       /*
-        * Constructor
-        * 
-        * Performs all the work for this model
-        */
-       public function __construct($wpdb)
-       {
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-
-               // Start Smarty Templates - creates $this->template object
-               $this->setupSmarty();
-
-               $templateData = array(
-                       'glm_proto_title' => '',
-                       'glm_proto_title_error' => '',
-                       'glm_proto_width' => '1500',
-                       'glm_proto_width_error' => '',
-                       'glm_proto_height' => '1200',
-                       'glm_proto_height_error' => '',
-                       'glm_proto_background' => '',
-                       'glm_proto_background_error' => '',
-                       'glm_proto_prototype' => '',
-                       'glm_proto_prototype_error' => ''
-               );
-               
-               /*
-                * If a protototype is being submitted 
-                */
-               $submitError = false;
-               $submitted = false;
-               if ($_REQUEST['glm_proto_action'] == 'add_submit') {
-
-                       // Clean up all input
-                       $templateData['glm_proto_title'] = sanitize_text_field($_REQUEST['glm_proto_title']);
-                       $templateData['glm_proto_width'] = sanitize_text_field($_REQUEST['glm_proto_width']);
-                       $templateData['glm_proto_height'] = sanitize_text_field($_REQUEST['glm_proto_height']);
-                       $templateData['glm_proto_background'] = sanitize_text_field($_REQUEST['glm_proto_background']);
-                       $templateData['glm_proto_prototype'] =  sanitize_text_field($_REQUEST['glm_proto_prototype']);
-                               
-                       // Check title field
-                       if ($templateData['glm_proto_title'] == '') {
-                               $templateData['glm_proto_title_error'] = 'Required title not supplied';
-                               $submitError = true;
-                       }
-                       
-                       // Check width field
-                       if ($templateData['glm_proto_width'] == '') {
-                               $templateData['glm_proto_width_error'] = 'Required width not supplied';
-                               $submitError = true;
-                       }
-                       
-                       // Check height field
-                       if ($templateData['glm_proto_height'] == '') {
-                               $templateData['glm_proto_height_error'] = 'Required height not supplied';
-                               $submitError = true;
-                       }
-                       
-                       // Check background image - Not required but must exist if provided
-                       if ($templateData['glm_proto_background'] != '' &&
-                               !$this->glmProtoIsUploaded($templateData['glm_proto_background']) ) 
-                       {
-                               $templateData['glm_proto_background_error'] = 'Supplied background image does not exists';
-                               $submitError = true;
-                       }
-                       
-                       // Check prototype image 
-                       if ($templateData['glm_proto_prototype'] == '') {
-                               $templateData['glm_proto_prototype_error'] = 'Required prototype image not supplied ';
-                               $submitError = true;
-                       } else {
-                               $exists = $this->glmProtoIsUploaded($templateData['glm_proto_prototype']);                              
-                               if (!$exists) {
-                                       $templateData['glm_proto_prototype_error'] .= 'Supplied prototype image does not exists';
-                                       $submitError = true;
-                               }
-                       }
-
-                       if (!$submitError) {
-
-                               // Prepair data for storage
-                               $date = date('Y-m-d', time());
-                               $timezoneBackup = date_default_timezone_get();
-                               date_default_timezone_set("GMT");
-                               $gmtDate = date('Y-m-d', time()); 
-                               date_default_timezone_set($timezoneBackup);
-                               
-                               $content = serialize(
-                                       array(
-                                               'title' => $templateData['glm_proto_title'],
-                                               'width' => $templateData['glm_proto_width'],
-                                               'height' => $templateData['glm_proto_height'],
-                                               'background' => $templateData['glm_proto_background'],
-                                               'prototype' => $templateData['glm_proto_prototype']
-                                       )
-                               );
-                               
-                               // Store into wp_posts table
-                               $result = $this->wpdb->insert(
-                                       'wp_posts',
-                                       array(
-                                               'post_date' => $date,
-                                               'post_date_gmt' => $gmtDate,
-                                               'post_content' => $content,
-                                               'post_title' => $templateData['glm_proto_title'],
-                                               'post_type' => 'glm_proto'
-                                       )
-                               );
-
-                               // If there was a problem storing the prototype, pass that to the template
-                               if (!$result) {                                 
-                                       $templateData['glm_proto_title_error'] = 'There was an unknown problem storing this prototype.';
-                               }
-                               
-                               // Select view
-                               $this->templateFile = 'admin/prototype_submitted.html';
-                               
-                               // Add template parameters
-                               $this->templateAssign($templateData);
-                               
-                               $prototypeSubmitted = true;
-                       }
-                       
-               }
-
-               /*
-                * 
-                */
-               if ($prototypeSubmitted) {
-
-               // No prototype was submitted so display the form.
-               } else {
-                       
-                       // Select view
-                       $this->templateFile = 'admin/prototype_add.html';
-       
-                       // Add template parameters
-                       $this->templateAssign('request_uri', $_SERVER['REQUEST_URI']);
-                       $this->templateAssign($templateData);
-                       
-               }
-                                               
-               // Output our template results
-               $this->template->display($this->templateFile);
-       
-       }
-
-       /*
-        * Check if a file supposedly uploaded to WordPress exists
-        * 
-        * This method accepts a URL to a WordPress file or image, strips the
-        * WordPress base file URL to get the remaining path and file name for
-        * the file, then adds the base path for WordPress files and checks to
-        * see if the file exists.
-        * 
-        * @param string URL of uploaded WordPress file or image 
-        * 
-        * @return bool True if it exists, false if not
-        */
-       private function glmProtoIsUploaded($url) {
-               
-               // Get current WordPress upload directory/url information
-               $paths = wp_upload_dir();
-               $base = $paths['baseurl'];
-               $path = $paths['basedir'];
-               
-               // Strip base directory from supplied URL
-               $file = substr($url, strlen($base));
-               
-               // Check if file exists
-               $exists = file_exists($path.$file);
-               return $exists;
-
-       }
-}
-
-?>
\ No newline at end of file
diff --git a/models/admin/add/index.php b/models/admin/add/index.php
new file mode 100644 (file)
index 0000000..6bc1ae7
--- /dev/null
@@ -0,0 +1,260 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin Add Prototype Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This class performs the work needed to add a new prototype.
+ *
+ * If a prototype is properly submitted, it is stored in the wp_posts table
+ * using the following fields.
+ *
+ * post_date           Current date
+ * post_date_gmt       Current date in GMT
+ * post_content        Serialized array with 'title', 'background', and 'prototype'
+ * post_title          Title of prototype
+ * post_type           'glm_proto'
+ *
+ */
+class glmProtoAdmin_add_index
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This method does the work for this model and returns any resulting data
+     *
+     * @return array Status and data array
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     */
+    public function modelAction ()
+    {
+        $data = array(
+                'glm_proto_title' => '',
+                'glm_proto_title_error' => '',
+                'glm_proto_width' => '1500',
+                'glm_proto_width_error' => '',
+                'glm_proto_height' => '1200',
+                'glm_proto_height_error' => '',
+                'glm_proto_background' => '',
+                'glm_proto_background_error' => '',
+                'glm_proto_prototype' => '',
+                'glm_proto_prototype_error' => ''
+        );
+
+        /*
+         * If a protototype is being submitted
+         */
+        $submitError = false;
+        $submitted = false;
+        if (isset($_REQUEST['glm_proto_title'])) {
+
+            // Clean up all input
+            $data['glm_proto_title'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_title']);
+            $data['glm_proto_width'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_width']);
+            $data['glm_proto_height'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_height']);
+            $data['glm_proto_background'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_background']);
+            $data['glm_proto_prototype'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_prototype']);
+
+            // Check title field
+            if ($data['glm_proto_title'] == '') {
+                $data['glm_proto_title_error'] = 'Required title not supplied';
+                $submitError = true;
+            }
+
+            // Check width field
+            if ($data['glm_proto_width'] == '') {
+                $data['glm_proto_width_error'] = 'Required width not supplied';
+                $submitError = true;
+            }
+
+            // Check height field
+            if ($data['glm_proto_height'] == '') {
+                $data['glm_proto_height_error'] = 'Required height not supplied';
+                $submitError = true;
+            }
+
+            // Check background image - Not required but must exist if provided
+            if ($data['glm_proto_background'] != '' && ! $this->glmProtoIsUploaded(
+                    $data['glm_proto_background'])) {
+                $data['glm_proto_background_error'] = 'Supplied background image does not exists';
+                $submitError = true;
+            }
+
+            // Check prototype image
+            if ($data['glm_proto_prototype'] == '') {
+                $data['glm_proto_prototype_error'] = 'Required prototype image not supplied ';
+                $submitError = true;
+            } else {
+                $exists = $this->glmProtoIsUploaded(
+                        $data['glm_proto_prototype']);
+                if (! $exists) {
+                    $data['glm_proto_prototype_error'] .= 'Supplied prototype image does not exists';
+                    $submitError = true;
+                }
+            }
+
+            if (! $submitError) {
+
+                // Prepair data for storage
+                $date = date('Y-m-d', time());
+                $timezoneBackup = date_default_timezone_get();
+                date_default_timezone_set("GMT");
+                $gmtDate = date('Y-m-d', time());
+                date_default_timezone_set($timezoneBackup);
+
+                $content = serialize(
+                        array(
+                                'title' => $data['glm_proto_title'],
+                                'width' => $data['glm_proto_width'],
+                                'height' => $data['glm_proto_height'],
+                                'background' => $data['glm_proto_background'],
+                                'prototype' => $data['glm_proto_prototype']
+                        ));
+
+                // Store into wp_posts table
+                $result = $this->wpdb->insert('wp_posts',
+                        array(
+                                'post_date' => $date,
+                                'post_date_gmt' => $gmtDate,
+                                'post_content' => $content,
+                                'post_title' => $data['glm_proto_title'],
+                                'post_type' => 'glm_proto'
+                        ));
+
+                // If there was a problem storing the prototype, pass that to
+                // the template
+                if (! $result) {
+                    $data['glm_proto_title_error'] = 'There was an unknown problem storing this prototype.';
+                }
+
+                $prototypeSubmitted = true;
+            }
+        }
+
+        // If submitted OK then display success page
+        $menuItemRedirect = false;
+        $modelRedirect = false;
+        if ($prototypeSubmitted) {
+
+            $view = 'admin/add/submitted.html';
+
+            // Prototype was not successfully submitted so redisplay the form.
+        } else {
+
+            // Select view
+            $view = 'admin/add/index.html';
+        }
+
+        // Return status, suggested view, and data to controller
+        return array(
+                'status' => true,
+                'menuItemRedirect' => false,
+                'modelRedirect' => false,
+                'view' => $view,
+                'data' => $data
+        );
+    }
+
+    /*
+     * Check if a file supposedly uploaded to WordPress exists
+     *
+     * This method accepts a URL to a WordPress file or image, strips the
+     * WordPress base file URL to get the remaining path and file name for
+     * the file, then adds the base path for WordPress files and checks to
+     * see if the file exists.
+     *
+     * @param string URL of uploaded WordPress file or image
+     *
+     * @return bool True if it exists, false if not
+     */
+    private function glmProtoIsUploaded ($url)
+    {
+
+        // Get current WordPress upload directory/url information
+        $paths = wp_upload_dir();
+        $base = $paths['baseurl'];
+        $path = $paths['basedir'];
+
+        // Strip base directory from supplied URL
+        $file = substr($url, strlen($base));
+
+        // If there's now no file name
+        if (trim($file) == '') {
+            return false;
+        }
+
+        // Check if file exists
+        $exists = file_exists($path . $file);
+
+        return $exists;
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/display.php b/models/admin/display.php
deleted file mode 100644 (file)
index d9a050b..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-/**
- * Gaslight Media Prototype Management and Display
- * Admin Display Selected Prototype Model
- *
- * PHP version 5.5
- *
- * @category glmWordPressPlugin
- * @package  glmPrototypeManagement
- * @author   Chuck Scott <cscott@gaslightmedia.com>
- * @license  http://www.gaslightmedia.com Gaslightmedia
- * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
- * @link     http://dev.gaslightmedia.com/
- */
-
-/*
- * This class performs the work needed to list existing prototypes.
- */
-class glmProtoAdminDisplayModel extends smartyTemplateSupport
-{
-       
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-       /**
-        * Selected Template File
-        * @var    $templateFile
-        * @access public
-        */
-       public $templateFile;
-       
-       /*
-        * Constructor
-        * 
-        * Performs all the work for this model
-        */
-       public function __construct($wpdb)
-       {
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-               
-               // Start Smarty Templates - creates $this->template object
-               $this->setupSmarty();
-
-               // Check if we recieved a prototype ID
-               $id = $_REQUEST['proto_id'] - 0;
-               if ($id > 0) {
-                       
-                       // Get the prototype data
-                       $res = $this->wpdb->get_row("
-                               SELECT id,
-                                          DATE_FORMAT(post_date, '%Y-%m-%d') p_date,
-                                          post_title,
-                                          post_content
-                                 FROM wp_posts
-                                WHERE post_type = 'glm_proto'
-                                  AND id = $id
-                       ", ARRAY_A );
-
-                       // If we have results
-
-                       if ($res['post_content']) {
-
-                               // Break out the prototype file data
-                               $d = unserialize($res['post_content']);
-                               $res['content'] = $d;
-                                                               
-                       }
-
-                       $this->templateAssign($res);
-                               
-                               
-               }
-               
-               // Select view
-               $this->templateFile = 'admin/prototype_display.html';
-
-               // Output our template results
-               $this->template->display($this->templateFile);
-               exit;
-               
-       }
-
-}
-
-?>
\ No newline at end of file
diff --git a/models/admin/error/badAction.php b/models/admin/error/badAction.php
new file mode 100644 (file)
index 0000000..bc2c689
--- /dev/null
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin Bad Action Error Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This model is called if a bad action has been requested.
+ *
+ */
+class glmProtoAdmin_error_badAction
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor performs the work for this model. This model returns
+     * an array containing the following.
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     * @wpdb object WordPress database object
+     *
+     * @return array Array containing status, suggested view, and any data
+     */
+    public function __construct ($wpdb)
+    {
+        $this->wpdb = $wpdb;
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This method does the work for this model and returns any resulting data
+     *
+     * @return array Status and data array
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     */
+    public function modelAction ()
+    {
+
+        // No work to perform here so just return status
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => true,
+                'menuItemRedirect' => false,
+                'modelRedirect' => false,
+                'view' => 'admin/error/badAction.html',
+                'data' => false
+        );
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/error/index.php b/models/admin/error/index.php
new file mode 100644 (file)
index 0000000..43437c9
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin Generic Error Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This model is called if there is a generic/unknown error
+ *
+ */
+class glmProtoAdminError
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor performs the work for this model. This model returns
+     * an array containing the following.
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     * @wpdb object WordPress database object
+     *
+     * @return array Array containing status, suggested view, and any data
+     */
+    public function __construct ($wpdb)
+    {
+        // No work to perform here so just return status
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => true,
+                'view' => false,
+                'data' => false
+        );
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/list.php b/models/admin/list.php
deleted file mode 100644 (file)
index 9ea18c1..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-/**
- * Gaslight Media Prototype Management and Display
- * Admin List Prototypes Model
- *
- * PHP version 5.5
- *
- * @category glmWordPressPlugin
- * @package  glmPrototypeManagement
- * @author   Chuck Scott <cscott@gaslightmedia.com>
- * @license  http://www.gaslightmedia.com Gaslightmedia
- * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
- * @link     http://dev.gaslightmedia.com/
- */
-
-/*
- * This class performs the work needed to list existing prototypes.
- */
-class glmProtoAdminListModel extends smartyTemplateSupport
-{
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-       /**
-        * Selected Template File
-        * @var    $templateFile
-        * @access public
-        */
-       public $templateFile;
-       
-       /*
-        * Constructor
-        * 
-        * Performs all the work for this model
-        */
-       public function __construct($wpdb)
-       {
-               
-               // If there's any other display operation requested, don't do this one.
-               if (isset($_REQUEST['glm_proto_action'])) {
-                       return;
-               }
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-               
-               // Start Smarty Templates - creates $this->template object
-               $this->setupSmarty();
-               
-               // Get a current list of prototypes
-               $list = $this->getList();
-                               
-               // If we have list entries
-               if ($list) {
-                       
-                       // Expand content array in case we need it
-                       while (list($key, $value) = each($list)) {
-                               $list[$key]['content'] = unserialize($value['post_content']);
-                       }
-
-                       // Add data to templates
-                       $this->templateAssign('haveList', true);
-                       $this->templateAssign('prototypes', $list);
-                       
-               } else {
-                       $this->templateAssign('haveList', false);
-               }                               
-               
-               // Also add the current request URI to use for links back for display
-               $this->templateAssign('request_uri', $_SERVER['REQUEST_URI']);
-               
-               // Select view
-               $this->templateFile = 'admin/prototype_list.html';
-               
-               // Output our template results
-               $this->template->display($this->templateFile);
-
-       }
-       
-       /*
-        * Constructor
-        *
-        * Performs all the work for this model
-        */
-       public function getList()
-       {
-
-               // Get all prototypes
-               $res = $this->wpdb->get_results( "
-                       SELECT id,
-                                  DATE_FORMAT(post_date, '%Y-%m-%d') p_date,
-                                  post_title,
-                                  post_content
-                         FROM wp_posts
-                        WHERE post_type = 'glm_proto'
-                 ORDER BY post_date, post_title
-                       ", ARRAY_A
-               );
-               
-               // If we have results
-               if (is_array($res) && count($res) > 0) {
-                       return $res;
-               }
-
-               return false;
-       }
-       
-}
-
-?>
\ No newline at end of file
diff --git a/models/admin/prototypes/delete.php b/models/admin/prototypes/delete.php
new file mode 100644 (file)
index 0000000..0e0db90
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin Delete Selected Prototype Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This class performs the work needed to delete an existing prototype.
+ */
+class glmProtoAdmin_prototypes_delete
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This method does the work for this model and returns any resulting data
+     *
+     * @return array Status and data array
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     */
+    public function modelAction ()
+    {
+
+        // Check if we recieved a prototype ID
+        $id = $_REQUEST['proto_id'] - 0;
+        if ($id > 0) {
+
+            // Delete the prototype data
+            $res = $this->wpdb->get_row(
+                    "
+                               DELETE
+                                 FROM wp_posts
+                                WHERE post_type = 'glm_proto'
+                                  AND id = $id
+                       ", ARRAY_A);
+        }
+
+        // Return status - in this case we always redirect to the prototypes
+        // index model (list)
+        return array(
+                'status' => true,
+                'menuItemRedirect' => 'prototypes',
+                'modelRedirect' => 'index',
+                'view' => false,
+                'data' => false
+        );
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/prototypes/display.php b/models/admin/prototypes/display.php
new file mode 100644 (file)
index 0000000..49d59e1
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin Display Selected Prototype Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This class performs the work needed to display an existing prototype.
+ */
+class glmProtoAdmin_prototypes_display
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This method does the work for this model and returns any resulting data
+     *
+     * @return array Status and data array
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     */
+    public function modelAction ()
+    {
+
+        // Check if we recieved a prototype ID
+        $id = $_REQUEST['proto_id'] - 0;
+        if ($id > 0) {
+
+            // Get the prototype data
+            $res = $this->wpdb->get_row(
+                    "
+                               SELECT id,
+                                          DATE_FORMAT(post_date, '%Y-%m-%d') p_date,
+                                          post_title,
+                                          post_content
+                                 FROM wp_posts
+                                WHERE post_type = 'glm_proto'
+                                  AND id = $id
+                       ", ARRAY_A);
+
+            // If we have results
+            $success = false;
+            if ($res['post_content']) {
+
+                $success = true;
+
+                // Break out the prototype file data
+                $d = unserialize($res['post_content']);
+                $res['content'] = $d;
+            }
+
+        }
+
+        // Return status, any suggested view, and any data to controller
+        return array(
+                'status' => $success,
+                'menuItemRedirect' => false,
+                'modelRedirect' => false,
+                'view' => 'admin/prototypes/display.html',
+                'data' => $res['content']
+        );
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/prototypes/edit.php b/models/admin/prototypes/edit.php
new file mode 100644 (file)
index 0000000..39f5533
--- /dev/null
@@ -0,0 +1,291 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin Edit Prototype Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This class performs the work needed to add a new prototype.
+ *
+ */
+class glmProtoAdmin_prototypes_edit
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This method does the work for this model and returns any resulting data
+     *
+     * @return array Status and data array
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     */
+    public function modelAction ()
+    {
+
+        // Check that we have a prototype ID
+        $id = 0;
+        if (isset($_REQUEST['proto_id'])) {
+            // Make sure it's an integer
+            $id = $_REQUEST['proto_id'] - 0;
+        }
+        if (! $id) {
+            echo "FAILURE";
+            exit();
+        }
+
+        // Get the current data for the selected prototype
+        // Get the prototype data
+        $res = $this->wpdb->get_row(
+                "
+                SELECT id,
+                DATE_FORMAT(post_date, '%Y-%m-%d') p_date,
+                post_title,
+                post_content
+                FROM wp_posts
+                WHERE post_type = 'glm_proto'
+                AND id = $id
+                ", ARRAY_A);
+
+        // If we have results
+        $success = false;
+        if ($res['post_content']) {
+
+            $success = true;
+
+            // Break out the prototype file data
+            $content = unserialize($res['post_content']);
+        }
+
+        // Setup input data array
+        $data = array(
+                'glm_proto_title' => $content['title'],
+                'glm_proto_title_error' => '',
+                'glm_proto_width' => $content['width'],
+                'glm_proto_width_error' => '',
+                'glm_proto_height' => $content['height'],
+                'glm_proto_height_error' => '',
+                'glm_proto_background' => $content['background'],
+                'glm_proto_background_error' => '',
+                'glm_proto_prototype' => $content['prototype'],
+                'glm_proto_prototype_error' => ''
+        );
+
+        /*
+         * If a protototype update is being submitted
+         */
+        $submitError = false;
+        $submitted = false;
+        if (isset($_REQUEST['glm_proto_title'])) {
+
+            // Clean up all input
+            $data['glm_proto_title'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_title']);
+            $data['glm_proto_width'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_width']);
+            $data['glm_proto_height'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_height']);
+            $data['glm_proto_background'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_background']);
+            $data['glm_proto_prototype'] = sanitize_text_field(
+                    $_REQUEST['glm_proto_prototype']);
+
+            // Check title field
+            if ($data['glm_proto_title'] == '') {
+                $data['glm_proto_title_error'] = 'Required title not supplied';
+                $submitError = true;
+            }
+
+            // Check width field
+            if ($data['glm_proto_width'] == '') {
+                $data['glm_proto_width_error'] = 'Required width not supplied';
+                $submitError = true;
+            }
+
+            // Check height field
+            if ($data['glm_proto_height'] == '') {
+                $data['glm_proto_height_error'] = 'Required height not supplied';
+                $submitError = true;
+            }
+
+            // Check background image - Not required but must exist if provided
+            if ($data['glm_proto_background'] != '' && ! $this->glmProtoIsUploaded(
+                    $data['glm_proto_background'])) {
+                $data['glm_proto_background_error'] = 'Supplied background image does not exists';
+                $submitError = true;
+            }
+
+            // Check prototype image
+            if ($data['glm_proto_prototype'] == '') {
+                $data['glm_proto_prototype_error'] = 'Required prototype image not supplied ';
+                $submitError = true;
+            } else {
+                $exists = $this->glmProtoIsUploaded(
+                        $data['glm_proto_prototype']);
+                if (! $exists) {
+                    $data['glm_proto_prototype_error'] .= 'Supplied prototype image does not exists';
+                    $submitError = true;
+                }
+            }
+
+            if (! $submitError) {
+
+                // Prepair data for storage
+                $date = date('Y-m-d', time());
+                $timezoneBackup = date_default_timezone_get();
+                date_default_timezone_set("GMT");
+                $gmtDate = date('Y-m-d', time());
+                date_default_timezone_set($timezoneBackup);
+
+                $content = serialize(
+                        array(
+                                'title' => $data['glm_proto_title'],
+                                'width' => $data['glm_proto_width'],
+                                'height' => $data['glm_proto_height'],
+                                'background' => $data['glm_proto_background'],
+                                'prototype' => $data['glm_proto_prototype']
+                        ));
+
+                // Store into wp_posts table
+                $result = $this->wpdb->update(
+                        'wp_posts',
+                        array(
+                                'post_date' => $date,
+                                'post_date_gmt' => $gmtDate,
+                                'post_content' => $content,
+                                'post_title' => $data['glm_proto_title'],
+                                'post_type' => 'glm_proto'
+                        ),
+                        array(
+                                'id' => $id
+                        ));
+
+                // If there was a problem storing the prototype, pass that to
+                // the template
+                if (! $result) {
+                    $data['glm_proto_title_error'] = 'There was an unknown problem updating this prototype.';
+                }
+
+                $prototypeSubmitted = true;
+            }
+        }
+
+        // If submitted OK then display success page
+        $menuItemRedirect = false;
+        $modelRedirect = false;
+        if ($prototypeSubmitted) {
+
+            $view = 'admin/prototypes/updated.html';
+
+            // Prototype was not successfully submitted so redisplay the form.
+        } else {
+
+            // Select view
+            $view = 'admin/prototypes/edit.html';
+        }
+
+        // Return status, suggested view, and data to controller
+        return array(
+                'status' => true,
+                'menuItemRedirect' => false,
+                'modelRedirect' => false,
+                'view' => $view,
+                'data' => $data
+        );
+    }
+
+    /*
+     * Check if a file supposedly uploaded to WordPress exists
+     *
+     * This method accepts a URL to a WordPress file or image, strips the
+     * WordPress base file URL to get the remaining path and file name for
+     * the file, then adds the base path for WordPress files and checks to
+     * see if the file exists.
+     *
+     * @param string URL of uploaded WordPress file or image
+     *
+     * @return bool True if it exists, false if not
+     */
+    private function glmProtoIsUploaded ($url)
+    {
+
+        // Get current WordPress upload directory/url information
+        $paths = wp_upload_dir();
+        $base = $paths['baseurl'];
+        $path = $paths['basedir'];
+
+        // Strip base directory from supplied URL
+        $file = substr($url, strlen($base));
+
+        // If there's now no file name
+        if (trim($file) == '') {
+            return false;
+        }
+
+        // Check if file exists
+        $exists = file_exists($path . $file);
+
+        return $exists;
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/models/admin/prototypes/index.php b/models/admin/prototypes/index.php
new file mode 100644 (file)
index 0000000..8c8bc71
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+
+/**
+ * Gaslight Media Prototype Management and Display
+ * Admin List Prototypes Model
+ *
+ * PHP version 5.5
+ *
+ * @category glmWordPressPlugin
+ * @package  glmPrototypeManagement
+ * @author   Chuck Scott <cscott@gaslightmedia.com>
+ * @license  http://www.gaslightmedia.com Gaslightmedia
+ * @release  admin.php,v 1.0 2014/10/31 19:31:47 cscott Exp $
+ * @link     http://dev.gaslightmedia.com/
+ */
+
+/*
+ * This class performs the work for the default action of the "Prototypes" menu
+ * option.
+ *
+ * The default action is to list existing prototypes.
+ */
+class glmProtoAdmin_prototypes_index
+{
+
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * This contructor sets up this model. At this time that only includes
+     * storing away the WordPress data object.
+     *
+     * @return object Class object
+     *
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+    }
+
+    /*
+     * Perform Model Action
+     *
+     * This method does the work for this model and returns any resulting data
+     *
+     * @return array Status and data array
+     *
+     * 'status'
+     *
+     * True if successfull and false if there was a fatal failure.
+     *
+     * 'menuItemRedirect'
+     *
+     * If not false, provides a menu item the controller should
+     * execute after this one. Normally if this is used, there would also be a
+     * modelRedirect value supplied as well.
+     *
+     * 'modelRedirect'
+     *
+     * If not false, provides an action the controller should execute after
+     * this one.
+     *
+     * 'view'
+     *
+     * A suggested view name that the contoller should use instead of the
+     * default view for this model or false to indicate that the default view
+     * should be used.
+     *
+     * 'data'
+     *
+     * Data that the model is returning for use in merging with the view to
+     * produce output.
+     *
+     */
+    public function modelAction ()
+    {
+        // Get a current list of prototypes
+        $list = $this->getList();
+
+        // If we have list entries - even if it's an empty list
+        $success = false;
+        if ($list !== false) {
+
+            $success = true;
+
+            // If we have any prototypes listed
+            if (count($list) > 0) {
+
+                // Expand content array in case we need it
+                while (list ($key, $value) = each($list)) {
+                    $list[$key]['content'] = unserialize($value['post_content']);
+                }
+            }
+        }
+
+        // Return status, suggested view, and data to controller
+        return array(
+                'status' => $success,
+                'menuItemRedirect' => false,
+                'modelRedirect' => false,
+                'view' => 'admin/prototypes/index.html',
+                'data' => $list
+        );
+    }
+
+    /*
+     * Get List of Prototypes from Database
+     *
+     * @return array Array of prototypes data
+     */
+    public function getList ()
+    {
+
+        // Get all prototypes
+        $res = $this->wpdb->get_results(
+                "
+                       SELECT id,
+                                  DATE_FORMAT(post_date, '%Y-%m-%d') p_date,
+                                  post_title,
+                                  post_content
+                         FROM wp_posts
+                        WHERE post_type = 'glm_proto'
+                 ORDER BY post_date, post_title
+                       ", ARRAY_A);
+
+        // If we have results - even an empty array
+        if (is_array($res)) {
+            return $res;
+        }
+
+        return false;
+    }
+}
+
+?>
\ No newline at end of file
index a5b29c6..7022c29 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Gaslight Media Prototype Management and Display
  * Deactivate Plugin Tasks
  */
 class glmProtoPluginDeactivate
 {
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-
-       /*
-        * Constructor
-        *
-        * Performs all the work for this model
-        */
-       public function __construct($wpdb)
-       {
-               
-               // Make sure the current user has this capability
-               if ( !current_user_can('activate_plugins') ) {
-                       return;
-               }
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-
-               // Perform any deactivation tasks here
-
-       }
 
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * Performs all the work for this model
+     */
+    public function __construct ($wpdb)
+    {
+
+        // Make sure the current user has this capability
+        if (! current_user_can('activate_plugins')) {
+            return;
+        }
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Perform any deactivation tasks here
+    }
 }
 
 ?>
\ No newline at end of file
index 1641802..b0337f0 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * Gaslight Media Prototype Management and Display
  * Uninstall Plugin Tasks
@@ -16,7 +17,7 @@
 /*
  * This class performs all necessary additional work when this
  * plugin is activated.
- * 
+ *
  * Should probably add an option for this plugin that indicates
  * whether the user wants to delete all data when uninstalling
  * the plugin. Not sure how to do that yet. Could be an option
  */
 class glmProtoPluginUninstall
 {
-       /**
-        * WordPress Database Object
-        * @var    $wpdb
-        * @access public
-        */
-       public $wpdb;
-
-       /*
-        * Constructor
-        *
-        * Performs all the work for this model
-        */
-       public function __construct($wpdb)
-       {
-               // Verify that uninstall is called from WordPress
-               if ( !defined( 'WP_UNINSTALL_PLUGIN' ) ) {
-                       return;
-               }
-               
-               // Make sure the current user has this capability
-               if ( !current_user_can('delete_plugins') ) {
-                       return;
-               }
-               
-               // Save WordPress Database object
-               $this->wpdb = $wpdb;
-
-               // Perform any uninstall tasks here
-
-       }
 
+    /**
+     * WordPress Database Object
+     *
+     * @var $wpdb
+     * @access public
+     */
+    public $wpdb;
+
+    /*
+     * Constructor
+     *
+     * Performs all the work for this model
+     */
+    public function __construct ($wpdb)
+    {
+        // Verify that uninstall is called from WordPress
+        if (! defined('WP_UNINSTALL_PLUGIN')) {
+            return;
+        }
+
+        // Make sure the current user has this capability
+        if (! current_user_can('delete_plugins')) {
+            return;
+        }
+
+        // Save WordPress Database object
+        $this->wpdb = $wpdb;
+
+        // Perform any uninstall tasks here
+    }
 }
 
 ?>
\ No newline at end of file
diff --git a/views/admin/add/index.html b/views/admin/add/index.html
new file mode 100644 (file)
index 0000000..f7270a4
--- /dev/null
@@ -0,0 +1,56 @@
+<div class="wrap">
+    
+    <h2>Add a New Prototype</h2>
+
+    <form action="{$data.request_uri}" method="post" enctype="multipart/form-data">
+        <input type="hidden" name="glm_proto_action" value="add_submit">
+        <table class="form-table">
+            <tr>
+                <th scope="row"><label for="glm_proto_title">Title for this Prototype <span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input name="glm_proto_title" type="text" id="glm_proto_title" value="{$data.glm_proto_title}" class="regular-text" />
+                    {if $data.glm_proto_title_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_title_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_width">Desired initial display width<span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input name="glm_proto_width" type="text" id="glm_proto_width" value="{$data.glm_proto_width}" class="regular-text" style="width: 4em;" />
+                    {if $data.glm_proto_width_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_width_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_height">Desired initial display height<span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input name="glm_proto_height" type="text" id="glm_proto_height" value="{$data.glm_proto_height}" class="regular-text" style="width: 4em;" />
+                    {if $data.glm_proto_height_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_height_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_background">Prototype Background</label></th>
+                <td>
+                    <input id="glm-proto-background" class="glm-proto-media-uploader" type="text" size="36" name="glm_proto_background" value="{$data.glm_proto_background}" />
+                    <input class="glm-protp-upload-button button" data-id="glm-proto-background" type="button" value="Upload Image" />
+                    {if $data.glm_proto_background_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_background_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_prototype">Prototype Image <span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input id="glm-proto-prototype" class="glm-proto-media-uploader" type="text" size="36" name="glm_proto_prototype" value="{$data.glm_proto_prototype}" />
+                    <input class="glm-protp-upload-button button" data-id="glm-proto-prototype" type="button" value="Upload Image" />
+                    {if $data.glm_proto_prototype_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_prototype_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th>&nbsp;</th>
+                <td><input type="submit" name="Submit" value="Add this template" class="button-primary"></td>
+            </tr>
+        </table>
+        <p><span class="glm-proto-required">*</span> Required</p>
+    </form>
+    
+</div>
+
+
+
diff --git a/views/admin/add/submitted.html b/views/admin/add/submitted.html
new file mode 100644 (file)
index 0000000..14a0ca7
--- /dev/null
@@ -0,0 +1,16 @@
+<div class="wrap">
+
+  {if $glm_proto_title_error != ''}
+
+    <h2>Error Adding Prototype</h2>
+    <p><b class="glm-proto-error">{$data.glm_proto_title_error}</b>
+
+  {else}
+    
+    <h2>New Prototype Added</h2>
+
+    <p><b>Prototype Title:</b> {$data.glm_proto_title}</p>
+  
+  {/if}
+    
+</div>
diff --git a/views/admin/error/badAction.html b/views/admin/error/badAction.html
new file mode 100644 (file)
index 0000000..9d31e46
--- /dev/null
@@ -0,0 +1,8 @@
+<div class="wrap">
+    
+    <h2>Sorry, we've had an error.</h2>
+
+    <p>There's been some kind of error and we're not able to do what you requested.</p>
+    <p>Please try again. If you still get the same error, contact Gaslight Media at 231-487-0692 for assistance.</p>
+      
+</div>
diff --git a/views/admin/prototype_add.html b/views/admin/prototype_add.html
deleted file mode 100644 (file)
index a9e990b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-<div class="wrap">
-       
-       <h2>Add a New Prototype</h2>
-
-       <form action="{$request_uri}" method="post" enctype="multipart/form-data">
-               <input type="hidden" name="glm_proto_action" value="add_submit">
-               <table class="form-table">
-                       <tr>
-                               <th scope="row"><label for="glm_proto_title">Title for this Prototype <span class="glm-proto-required">*</span></label></th>
-                               <td>
-                                       <input name="glm_proto_title" type="text" id="glm_proto_title" value="{$glm_proto_title}" class="regular-text" />
-                                       {if $glm_proto_title_error != ''}<br><span class="glm-proto-error">{$glm_proto_title_error}</span>{/if}
-                               </td>
-                       </tr>
-                       <tr>
-                               <th scope="row"><label for="glm_proto_width">Desired initial display width<span class="glm-proto-required">*</span></label></th>
-                               <td>
-                                       <input name="glm_proto_width" type="text" id="glm_proto_width" value="{$glm_proto_width}" class="regular-text" style="width: 4em;" />
-                                       {if $glm_proto_width_error != ''}<br><span class="glm-proto-error">{$glm_proto_width_error}</span>{/if}
-                               </td>
-                       </tr>
-                       <tr>
-                               <th scope="row"><label for="glm_proto_height">Desired initial display height<span class="glm-proto-required">*</span></label></th>
-                               <td>
-                                       <input name="glm_proto_height" type="text" id="glm_proto_height" value="{$glm_proto_height}" class="regular-text" style="width: 4em;" />
-                                       {if $glm_proto_height_error != ''}<br><span class="glm-proto-error">{$glm_proto_height_error}</span>{/if}
-                               </td>
-                       </tr>
-                       <tr>
-                               <th scope="row"><label for="glm_proto_background">Prototype Background</label></th>
-                               <td>
-                                       <input id="glm-proto-background" class="glm-proto-media-uploader" type="text" size="36" name="glm_proto_background" value="{$glm_proto_background}" />
-                               <input class="glm-protp-upload-button button" data-id="glm-proto-background" type="button" value="Upload Image" />
-                                       {if $glm_proto_background_error != ''}<br><span class="glm-proto-error">{$glm_proto_background_error}</span>{/if}
-                               </td>
-                       </tr>
-                       <tr>
-                               <th scope="row"><label for="glm_proto_prototype">Prototype Image <span class="glm-proto-required">*</span></label></th>
-                               <td>
-                                       <input id="glm-proto-prototype" class="glm-proto-media-uploader" type="text" size="36" name="glm_proto_prototype" value="{$glm_proto_prototype}" />
-                               <input class="glm-protp-upload-button button" data-id="glm-proto-prototype" type="button" value="Upload Image" />
-                                       {if $glm_proto_prototype_error != ''}<br><span class="glm-proto-error">{$glm_proto_prototype_error}</span>{/if}
-                               </td>
-                       </tr>
-                       <tr>
-                               <th>&nbsp;</th>
-                               <td><input type="submit" name="Submit" value="Add this template" class="button-primary"></td>
-                       </tr>
-               </table>
-               <p><span class="glm-proto-required">*</span> Required</p>
-       </form>
-       
-</div>
-
-
-
diff --git a/views/admin/prototype_display.html b/views/admin/prototype_display.html
deleted file mode 100644 (file)
index 273a109..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-       <head>
-               <title>Prototype: {$content.title}</title>
-               <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-       </head>
-       <body style="margin:0;padding:0; background: #e7e7df;">      
-               <div style="min-width:1400px;min-height:2500px; background: url({$content.prototype}) top center no-repeat; z-index: 10;"></div>
-               <div style="min-width:100%;min-height:784px; background: url($content.background) top left repeat-x; position: absolute; top: 0; z-index: -1;"></div>
-       </body>
-</html>
diff --git a/views/admin/prototype_list.html b/views/admin/prototype_list.html
deleted file mode 100644 (file)
index 60ed29e..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-<script type="text/javascript">
-       function dispProtoWindow(url, w, h)
-       {
-               var disp_setting="toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,width=" + w + ", height=" + h + ", left=100, top=25";
-               window.open(url,"emDebugWindowFront",disp_setting);
-               return false;
-       }
-</script>
-<div class="wrap">
-       
-       <h2>List of Prototypes</h2>
-       
-       <table class="widefat">
-               <thead>
-               <tr>
-                       <th>Date</th>
-                       <th>Prototype Name</th>
-                       <th>&nbsp;</th>
-               </tr>
-               </thead>
-               <tbody>
-{if $haveList}
-       {foreach $prototypes as $p}
-                       <tr>
-                       <td>{$p.p_date}</td>
-                       <td>{$p.post_title}</td>
-                       <td>
-                               <a href="{$request_uri}&glm_proto_action=display&proto_id={$p.id}" name="Edit" class="button-primary"
-                                       onClick="dispProtoWindow('{$request_uri}&glm_proto_action=display&proto_id={$p.id}', {$p.content.width}, {$p.content.height}); return false;"
-                               >View</a>
-                               <a href="{$request_uri}&glm_proto_action=edit&proto_id={$p.id}" name="Edit" class="button-primary">Edit</a>
-                               <a href="{$request_uri}&glm_proto_action=delete&proto_id={$p.id}" name="Edit" class="button-primary">Delete</a>
-                       </td>
-                       </tr>
-       {/foreach}
-{else}
-                       <tr><td colspan="2">(no prototypes listed)</td></tr>
-{/if}
-               </tbody>
-       </table>
-
-</div>
-
diff --git a/views/admin/prototype_submitted.html b/views/admin/prototype_submitted.html
deleted file mode 100644 (file)
index 26add73..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<div class="wrap">
-
-  {if $glm_proto_title_error != ''}
-
-       <h2>Error Adding Prototype</h2>
-       <p><b class="glm-proto-error">{$glm_proto_title_error}</b>
-
-  {else}
-       
-       <h2>New Prototype Added</h2>
-
-       <p><b>Prototype Title:</b> {$glm_proto_title}</p>
-  
-  {/if}
-       
-</div>
diff --git a/views/admin/prototypes/display.html b/views/admin/prototypes/display.html
new file mode 100644 (file)
index 0000000..8c27573
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>Prototype: {$data.title}</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    </head>
+    <body style="margin:0;padding:0; background: #e7e7df;">      
+        <div style="min-width:1400px;min-height:2500px; background: url({$data.prototype}) top center no-repeat; z-index: 10;"></div>
+        <div style="min-width:100%;min-height:784px; background: url({$data.background}) top left repeat-x; position: absolute; top: 0; z-index: -1;"></div>
+    </body>
+</html>
diff --git a/views/admin/prototypes/edit.html b/views/admin/prototypes/edit.html
new file mode 100644 (file)
index 0000000..79739ed
--- /dev/null
@@ -0,0 +1,56 @@
+<div class="wrap">
+    
+    <h2>Edit a Prototype</h2>
+
+    <form action="{$data.request_uri}" method="post" enctype="multipart/form-data">
+        <input type="hidden" name="glm_action" value="edit">
+        <table class="form-table">
+            <tr>
+                <th scope="row"><label for="glm_proto_title">Title for this Prototype <span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input name="glm_proto_title" type="text" id="glm_proto_title" value="{$data.glm_proto_title}" class="regular-text" />
+                    {if $data.glm_proto_title_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_title_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_width">Desired initial display width<span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input name="glm_proto_width" type="text" id="glm_proto_width" value="{$data.glm_proto_width}" class="regular-text" style="width: 4em;" />
+                    {if $data.glm_proto_width_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_width_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_height">Desired initial display height<span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input name="glm_proto_height" type="text" id="glm_proto_height" value="{$data.glm_proto_height}" class="regular-text" style="width: 4em;" />
+                    {if $data.glm_proto_height_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_height_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_background">Prototype Background</label></th>
+                <td>
+                    <input id="glm-proto-background" class="glm-proto-media-uploader" type="text" size="36" name="glm_proto_background" value="{$data.glm_proto_background}" />
+                    <input class="glm-protp-upload-button button" data-id="glm-proto-background" type="button" value="Upload Image" />
+                    {if $data.glm_proto_background_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_background_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th scope="row"><label for="glm_proto_prototype">Prototype Image <span class="glm-proto-required">*</span></label></th>
+                <td>
+                    <input id="glm-proto-prototype" class="glm-proto-media-uploader" type="text" size="36" name="glm_proto_prototype" value="{$data.glm_proto_prototype}" />
+                    <input class="glm-protp-upload-button button" data-id="glm-proto-prototype" type="button" value="Upload Image" />
+                    {if $data.glm_proto_prototype_error != ''}<br><span class="glm-proto-error">{$data.glm_proto_prototype_error}</span>{/if}
+                </td>
+            </tr>
+            <tr>
+                <th>&nbsp;</th>
+                <td><input type="submit" name="Submit" value="Update this template" class="button-primary"></td>
+            </tr>
+        </table>
+        <p><span class="glm-proto-required">*</span> Required</p>
+    </form>
+    
+</div>
+
+
+
diff --git a/views/admin/prototypes/index.html b/views/admin/prototypes/index.html
new file mode 100644 (file)
index 0000000..26d81dc
--- /dev/null
@@ -0,0 +1,43 @@
+<script type="text/javascript">
+    function dispProtoWindow(url, w, h)
+    {
+        var disp_setting="toolbar=no,location=no,directories=no,menubar=no,scrollbars=yes,width=" + w + ", height=" + h + ", left=100, top=25";
+        window.open(url,"emDebugWindowFront",disp_setting);
+        return false;
+    }
+</script>
+<div class="wrap">
+    
+    <h2>List of Prototypes</h2>
+    
+    <table class="widefat">
+        <thead>
+            <tr>
+                <th>Date</th>
+                <th>Prototype Name</th>
+                <th>&nbsp;</th>
+            </tr>
+        </thead>
+        <tbody>
+{if $haveData}
+    {foreach $data as $d}
+            <tr>
+                <td>{$d.p_date}</td>
+                <td>{$d.post_title}</td>
+                <td>
+                    <a href="{$request_uri}&glm_action=display&proto_id={$d.id}&glm_display_direct=true&glm_menu_item=prototypes" name="Edit" class="button-primary"
+                        onClick="dispProtoWindow('{$request_uri}&glm_action=display&proto_id={$d.id}&glm_display_direct=true&glm_menu_item=prototypes', {$d.content.width}, {$d.content.height}); return false;"
+                    >View</a>
+                    <a href="{$request_uri}&glm_action=edit&proto_id={$d.id}" name="Edit" class="button-primary">Edit</a>
+                    <a href="{$request_uri}&glm_action=delete&proto_id={$d.id}" name="Edit" class="button-primary">Delete</a>
+                </td>
+            </tr>
+    {/foreach}
+{else}
+            <tr><td colspan="2">(no prototypes listed)</td></tr>
+{/if}
+        </tbody>
+    </table>
+
+</div>
+
diff --git a/views/admin/prototypes/updated.html b/views/admin/prototypes/updated.html
new file mode 100644 (file)
index 0000000..f08ffd4
--- /dev/null
@@ -0,0 +1,7 @@
+<div class="wrap">
+
+    <h2>Prototype Updated</h2>
+
+    <p><b>Prototype Title:</b> {$data.glm_proto_title}</p>
+  
+</div>