Add the GLM-Blocks
authorSteve Sutton <steve@gaslightmedia.com>
Thu, 24 Apr 2014 14:52:41 +0000 (14:52 +0000)
committerSteve Sutton <steve@gaslightmedia.com>
Thu, 24 Apr 2014 14:52:41 +0000 (14:52 +0000)
For headlines

30 files changed:
Toolkit/Blocks/Admin/EditPage.php [new file with mode: 0644]
Toolkit/Blocks/Admin/ListPages.php [new file with mode: 0644]
Toolkit/Blocks/Admin/PageTree.php [new file with mode: 0644]
Toolkit/Blocks/Block.php [new file with mode: 0644]
Toolkit/Blocks/Database/application.sql [new file with mode: 0644]
Toolkit/Blocks/Database/removeApplication.sql [new file with mode: 0644]
Toolkit/Blocks/Database/tables/blocks.sql [new file with mode: 0644]
Toolkit/Blocks/Database/upgrade.sql [new file with mode: 0644]
Toolkit/Blocks/Display.php [new file with mode: 0644]
Toolkit/Blocks/IndexController.php [new file with mode: 0644]
Toolkit/Blocks/application.ini [new file with mode: 0644]
Toolkit/Blocks/assets/btn_add.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_add_sm.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_back.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_delete.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_edit.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_link.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_update.gif [new file with mode: 0755]
Toolkit/Blocks/assets/btn_upload.gif [new file with mode: 0755]
Toolkit/Blocks/assets/left_circle.gif [new file with mode: 0755]
Toolkit/Blocks/assets/right_circle.gif [new file with mode: 0755]
Toolkit/Blocks/css/style.css [new file with mode: 0644]
Toolkit/Blocks/js/column.js [new file with mode: 0644]
Toolkit/Blocks/js/editPage.js [new file with mode: 0644]
Toolkit/Blocks/js/jquery.columnview.js [new file with mode: 0644]
Toolkit/Blocks/js/listPages.js [new file with mode: 0644]
Toolkit/Blocks/positionBlock.php [new file with mode: 0644]
Toolkit/Blocks/templates/editPage.html [new file with mode: 0644]
Toolkit/Blocks/templates/listPages.html [new file with mode: 0644]
admin/blocks.php [new file with mode: 0644]

diff --git a/Toolkit/Blocks/Admin/EditPage.php b/Toolkit/Blocks/Admin/EditPage.php
new file mode 100644 (file)
index 0000000..e8f7271
--- /dev/null
@@ -0,0 +1,254 @@
+<?php
+
+/**
+ * EditPage.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Blocks_Admin_EditPage
+ *
+ * Handles the Edit page for the Block page
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blocks_Admin_EditPage
+{
+    private $_adminPath;
+    private $_dbh;
+    private $_flexyOptions;
+    private $_template;
+    private $_pageId;
+    private $_routerPath;
+    private $_canCreateOnAnyPage;
+
+    /**
+     * Creates a edit page for blocks
+     *
+     * @param Toolkit_Registry $registry Registry Object
+     */
+    public function __construct(
+        Toolkit_Registry $registry,
+        $pageId = null
+    ) {
+        $config = $registry->appConfig;
+        $this->_dbh          = $registry->dbh;
+        $this->_flexyOptions = $GLOBALS['flexyOptions'];
+        $this->_adminPath    = $config->application->path;
+        $this->_routerPath
+            = MEDIA_BASE_URL . $config->application->setPath;
+        $this->_flexyOptions['templateDir']
+            = BASE . $config->flexy->options->templateDir;
+        $this->_flexyOptions['compileDir']
+            = BASE . $config->flexy->options->compileDir;
+        $this->_template
+            = $config->flexy->templates->editPage;
+        $this->_pageId = $pageId;
+        $this->_canCreateOnAnyPage = $config->canCreateOnAnyPage;
+    }
+
+    private function _getPageName()
+    {
+        try {
+            $sql = "
+            SELECT navigation_name
+              FROM pages
+             WHERE id = :id";
+            $stmt = $this->_dbh->prepare($sql);
+            $stmt->bindParam(':id', $this->_pageId, PDO::PARAM_INT);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * returns the featured pages table data
+     *
+     * @return array features
+     */
+    public function _getBlocks()
+    {
+        $blocks = array();
+        try {
+            $sql = "
+              SELECT b.*, p.navigation_name
+                FROM blocks b LEFT OUTER JOIN pages p
+                     ON (b.page_to = p.id)
+               WHERE page_on = :page
+            ORDER BY pos";
+            $stmt = $this->_dbh->prepare($sql);
+            $stmt->bindParam(':page', $this->_pageId, PDO::PARAM_INT);
+            $stmt->execute();
+            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if ($row['image']) {
+                    $row['imageUrl'] = HEADLINE_THUMB . $row['image'];
+                }
+                $row['deleteUrl']
+                    = 'blocks.php?ac=Edit&Command=Delete&blockId=' .
+                    $row['id'];
+                $blocks[] = $row;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return $blocks;
+    }
+
+    /**
+     * Returns the string of html used to generate the edit page
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        $GLOBALS['bottomScripts'][]
+            = CKEDITOR_JS . '';
+        $GLOBALS['bottomScripts'][]
+            = $this->_routerPath . '/js/editPage.js';
+        if ($_GET['blockId'] && $_REQUEST['Command'] == 'Delete') {
+            $blockId = filter_input(
+                INPUT_GET,
+                'blockId',
+                FILTER_SANITIZE_NUMBER_INT
+            );
+            if ($blockId) {
+                $block = Toolkit_Blocks_Block::fetchById(
+                    $this->_dbh,
+                    $blockId
+                );
+                if ($block) {
+                    $pageOn = $block->getPageOn();
+                    // remove this cache file for the block
+                    $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+                    $cache->remove($pageOn, 'Block');
+                    $block->delete($this->_dbh);
+                }
+                header('Location: blocks.php?ac=Edit&page_on=' . $pageOn);
+            }
+        } else if ($_POST) {
+            if ($_FILES['image']['size'] > 0) {
+                $is = new Toolkit_FileServer_ImageAdapter();
+                $imageUploaded = $is->upload('image');
+            }
+            $pageOn = filter_input(
+                INPUT_POST,
+                'page_on',
+                FILTER_SANITIZE_NUMBER_INT
+            );
+            $pageTo = filter_input(
+                INPUT_POST,
+                'page_to',
+                FILTER_SANITIZE_NUMBER_INT
+            );
+            $blockId = filter_input(
+                INPUT_POST,
+                'blockId',
+                FILTER_SANITIZE_NUMBER_INT
+            );
+            $title = filter_input(
+                INPUT_POST,
+                'title',
+                FILTER_SANITIZE_STRING
+            );
+            $url = filter_input(
+                INPUT_POST,
+                'url',
+                FILTER_SANITIZE_STRING
+            );
+            $external = filter_input(
+                INPUT_POST,
+                'external',
+                FILTER_VALIDATE_BOOLEAN
+            );
+            $description = filter_var(
+                $_REQUEST['description'],
+                FILTER_UNSAFE_RAW
+            );
+            if (get_magic_quotes_gpc()) {
+                $description = stripslashes($description);
+            }
+            $pos = filter_input(
+                INPUT_POST,
+                'pos',
+                FILTER_SANITIZE_NUMBER_INT
+            );
+            $oldImage = filter_input(
+                INPUT_POST,
+                'oldImage',
+                FILTER_SANITIZE_STRING
+            );
+
+            $values = array(
+                'title'       => $title,
+                'description' => $description,
+                'image'       => (($imageUploaded['name'])
+                    ? $imageUploaded['name']
+                    :$oldImage),
+                'pageOn'      => $pageOn,
+                'pageTo'      => $pageTo,
+                'url'         => Toolkit_Common::filterURI($url),
+                'external'    => $external
+            );
+            if ($blockId) {
+                $values['id'] = $blockId;
+                $oldBlock = Toolkit_Blocks_Block::fetchById
+                    ($this->_dbh,
+                    $blockId
+                );
+                if ($oldBlock) {
+                    $values['pos'] = $oldBlock->getPos();
+                    $pageOn = $oldBlock->getPageOn();
+                    // remove this cache file for the oldblock
+                    $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+                    $cache->remove($pageOn, 'Block');
+                }
+            }
+            $block = Toolkit_Blocks_Block::createByValues(
+                $values
+            );
+            if ($block) {
+                $pageOn = $block->getPageOn();
+                // remove this cache file for the block
+                $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+                $cache->remove($pageOn, 'Block');
+                $block->save($this->_dbh);
+            }
+            header('Location: blocks.php?ac=Edit&page_on=' . $pageOn);
+            return false;
+        } else {
+            $tpl = new HTML_Template_Flexy($this->_flexyOptions);
+            $tpl->compile($this->_template);
+
+            $page = new stdClass();
+            if (is_numeric($this->_pageId)) {
+                $page->pageName = $this->_getPageName();
+            }
+            $page->baseUrl = MEDIA_BASE_URL;
+            $page->pageOn = $this->_pageId;
+            $page->blocks
+                = ($this->_pageId)
+                ? $this->_getBlocks()
+                : false;
+            $page->canCreateOnAnyPage = $this->_canCreateOnAnyPage;
+            return $tpl->bufferedOutputObject($page);
+        }
+    }
+}
+
diff --git a/Toolkit/Blocks/Admin/ListPages.php b/Toolkit/Blocks/Admin/ListPages.php
new file mode 100644 (file)
index 0000000..e6e9989
--- /dev/null
@@ -0,0 +1,140 @@
+<?php
+
+/**
+ * ListFeatures.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Tags_Admin_ListFeatures
+ *
+ * Handles the listing of the Pages that have the blocks on them.
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blocks_Admin_ListPages
+{
+    private $_adminPath;
+    private $_dbh;
+    private $_flexyOptions;
+    private $_template;
+    private $_routerPath;
+
+    /**
+     * Creates a list of the featured pages
+     *
+     * @param Toolkit_Registry $registry Registry Object
+     */
+    public function __construct(Toolkit_Registry $registry)
+    {
+        $config = $registry->appConfig;
+        $this->_dbh          = $registry->dbh;
+        $this->_flexyOptions = $GLOBALS['flexyOptions'];
+        $this->_adminPath    = $config->application->path;
+        $this->_routerPath
+            = MEDIA_BASE_URL . $config->application->setPath;
+        $this->_flexyOptions['templateDir']
+            = BASE . $config->flexy->options->templateDir;
+        $this->_flexyOptions['compileDir']
+            = BASE . $config->flexy->options->compileDir;
+        $this->_template
+            = $config->flexy->templates->listPages;
+    }
+
+    /**
+     * returns the featured pages table data
+     *
+     * @return array features
+     */
+    private function _getPages()
+    {
+        $breadCrumbsFactory = new Toolkit_BreadCrumbsFactory(
+            new Toolkit_Toolbox_PageGatewayPublishFactory(
+                $this->_dbh
+            )
+        );
+        $breadCrumbHelper = $breadCrumbsFactory->createBreadCrumbsHelper();
+        $pages = array();
+        try {
+            $sql = "
+            SELECT count(b.id) as count,b.page_on,p.navigation_name
+              FROM blocks.blocks b
+                   LEFT OUTER JOIN pages p ON (b.page_on = p.id)
+            GROUP BY navigation_name,page_on";
+            $stmt = $this->_dbh->query($sql);
+            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $row['editUrl']
+                    = $this->_adminPath . '?ac=Edit&page_on=' .
+                    $row['page_on'];
+                $row['breadCrumbs']
+                    = $breadCrumbHelper->toHtml($row['page_on']);
+                $row['pageUrl'] = Toolkit_Template_Page::getSeoUrl(
+                    new Toolkit_Toolbox_PageGatewayPublish($this->_dbh),
+                    $row['page_on']
+                );
+                $row['deleteUrl']
+                    = 'blocks.php?Command=Delete&pageId=' .
+                    $row['page_on'];
+                $pages[$row['page_on']] = $row;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return $pages;
+    }
+
+    /**
+     * Returns the string of html used to generate the list of Pages.
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        if ($_REQUEST['Command'] == 'Delete') {
+            $pageId = filter_input(
+                INPUT_GET,
+                'pageId',
+                FILTER_SANITIZE_NUMBER_INT
+            );
+            if ($pageId) {
+                try {
+                    $sql = "
+                    DELETE
+                      FROM blocks
+                     WHERE page_on = :page_on";
+                    $stmt = $this->_dbh->prepare($sql);
+                    $stmt->bindParam(':page_on', $pageId, PDO::PARAM_INT);
+                    $stmt->execute();
+                } catch(PDOException $e) {
+                    Toolkit_Common::handleError($e);
+                }
+            }
+        }
+        $GLOBALS['bottomScripts'][]
+            = $this->_routerPath . '/js/listPages.js';
+        $tpl = new HTML_Template_Flexy($this->_flexyOptions);
+        $tpl->compile($this->_template);
+
+        $page = new stdClass();
+        $page->baseUrl = MEDIA_BASE_URL;
+        $page->addUrl  = $this->_adminPath . '?ac=Edit';
+        $page->pages   = $this->_getPages();
+
+        return $tpl->bufferedOutputObject($page);
+    }
+}
diff --git a/Toolkit/Blocks/Admin/PageTree.php b/Toolkit/Blocks/Admin/PageTree.php
new file mode 100644 (file)
index 0000000..a5e2b32
--- /dev/null
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * PageTree.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Package_PageTree
+ *
+ * Display the toolbox page as ul lil list for jQuery-Column viewer
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blocks_Admin_PageTree
+{
+    private $_dbh;
+    private $_rootNodeStart = "<ul class=\"menu\" id=\"demo1\">\n";
+    private $_leafStartExpanded = "\n\t<li class=\"expanded\" %s>\n";
+    private $_leafStartLeaf = "\n\t<li class=\"leaf\" %s>\n";
+    private $_subTreeStart = "\n<ul class=\"menu\">\n";
+    private $_treeEnd = "\n</ul>\n";
+    private $_leafEnd = "\n\t</li>\n";
+    private $_tree;
+
+    public function __construct(PDO $dbh)
+    {
+        $this->_dbh = $dbh;
+    }
+
+    /**
+     * creates and executes the sql query for getting the pages
+     *
+     * @return array | null
+     */
+    private function _findAll()
+    {
+        try {
+            if (defined('MEMBERS_CATEGORY') && MEMBERS_CATEGORY) {
+                $sql = "
+                SELECT id,parent,navigation_name
+                  FROM pages
+                 WHERE id NOT IN (".MEMBERS_CATEGORY.")
+                   AND parent NOT IN (".MEMBERS_CATEGORY.")
+                 ORDER by parent, pos";
+            } else {
+                $sql = "
+                SELECT id,parent,navigation_name
+                  FROM pages
+                 ORDER by parent, pos";
+            }
+
+
+            return $this->_dbh
+                ->query($sql)
+                ->fetchAll(PDO::FETCH_ASSOC);
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * Get all pages for the tree
+     *
+     * @return array
+     */
+    private function _fetchPages()
+    {
+        $pages = $this->_findAll();
+        if (is_array($pages)) {
+            $threads = array();
+            foreach ($pages as $page) {
+                $page['children'] = array();
+                $threads[] = $page;
+            }
+
+            $children = array();
+            while (list($key, $value) = each ($threads)) {
+                $children[$value['parent']][$value['id']] = $value;
+            }
+
+            $this->_tree = $children;
+        } else {
+            $this->_tree = array();
+        }
+    }
+
+    /**
+     * Create html of the pages tree for jqueyr.columnview
+     *
+     * @return string
+     */
+    public function toHtml()
+    {
+        $this->_fetchPages();
+        if (is_array($this->_tree)) {
+            $html = $this->createTree($this->_tree, reset($this->_tree));
+        }
+        return $html;
+    }
+
+    /**
+     * Creates the tree structure for the pages jquery column view
+     *
+     * @param array $tree  Array for tree
+     * @param type  $leaf  Array for leaf
+     * @param type  $level tree level
+     *
+     * @return string
+     */
+    protected function createTree(array $tree, $leaf, $level = 0)
+    {
+        $html = !$level ? $this->_rootNodeStart : $this->_subTreeStart;
+        if (is_array($leaf) && !empty($leaf)) {
+            while (list($parent, $branch) = each($leaf)) {
+                if ($tree[$parent]) {
+                    $html .= sprintf($this->_leafStartExpanded, null);
+                    $html .= "<a href=\"#\" rel=\"{$branch['id']}\">{$branch['navigation_name']} </a> ";
+                    $html .= $this->createTree($tree, $tree[$parent], $level + 1);
+                } else {
+                    $html .= sprintf($this->_leafStartLeaf, null);
+                    $html .= "<a href=\"#\" rel=\"{$branch['id']}\">{$branch['navigation_name']} </a> ";
+                    $html .= $this->_leafEnd;
+                }
+            }
+        }
+        $html .= $this->_treeEnd;
+        if ($level) {
+            $html .= $this->_leafEnd;
+        }
+        return $html;
+    }
+}
diff --git a/Toolkit/Blocks/Block.php b/Toolkit/Blocks/Block.php
new file mode 100644 (file)
index 0000000..4ff43ff
--- /dev/null
@@ -0,0 +1,529 @@
+<?php
+
+/**
+ * Block.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Package_Block
+ *
+ * Class constructs an object for the Block table of the GLM BLock
+ * Application. Handles the insert and update by way of the save method.
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blocks_Block
+{
+    protected $tableName = "blocks";
+    protected $primaryKey = "id";
+    private $_id;
+    private $_title;
+    private $_description;
+    private $_image;
+    private $_pageOn;
+    private $_pageTo;
+    private $_url;
+    private $_external;
+    private $_pos;
+
+    /**
+     * Creates objects of type Block
+     *
+     * @param array $values values to use for the Block
+     */
+    public function __construct($values)
+    {
+        extract($values);
+        $this->setTitle($title)
+            ->setImage($image)
+            ->setDescription($description)
+            ->setPageOn($pageOn)
+            ->setPageTo($pageTo)
+            ->setPos($pos)
+            ->setUrl($url)
+            ->setExternal($external);
+        if ($id) {
+            $this->setId($id);
+        }
+    }
+
+    /**
+     * Static method to create Block objects from an array of values
+     *
+     * @param array $values values to create block with
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public static function createByValues($values)
+    {
+        return new Toolkit_Blocks_Block($values);
+    }
+
+    /**
+     * Fetch a block by id if not found return false
+     *
+     * @param PDO  $dbh Database Connection
+     * @param type $id  id of block to fetch
+     *
+     * @return false | Toolkit_Blocks_Block
+     */
+    public static function fetchById(PDO $dbh, $id)
+    {
+        try {
+            $sql = "
+            SELECT *
+              FROM blocks
+             WHERE id = :id";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':id', $id, PDO::PARAM_INT);
+            $stmt->execute();
+            $values = $stmt->fetch(PDO::FETCH_ASSOC);
+            if ($values) {
+                $values['pageOn'] = $values['page_on'];
+                $values['pageTo'] = $values['page_to'];
+                return Toolkit_Blocks_Block::createByValues($values);
+            } else {
+                return false;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * Fetch a block by id if not found return false
+     *
+     * @param PDO  $dbh Database Connection
+     * @param type $pageOn  id of block to fetch
+     *
+     * @return false | Toolkit_Blocks_Block
+     */
+    public static function fetchByPageOn(PDO $dbh, $pageOn)
+    {
+        $blocks = array();
+        try {
+            $sql = "
+              SELECT *
+                FROM blocks
+               WHERE page_on = :id
+            ORDER BY pos";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':id', $pageOn, PDO::PARAM_INT);
+            $stmt->execute();
+            while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $values['pageOn'] = $values['page_on'];
+                $values['pageTo'] = $values['page_to'];
+                $blocks[] = Toolkit_Blocks_Block::createByValues($values);
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return $blocks;
+    }
+
+    /**
+     * Returns the Blocks id
+     *
+     * @return id
+     */
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    /**
+     * Sets the Blocks id
+     *
+     * @param type $id Id to set (must be numeric)
+     *
+     * @return Toolkit_Blocks_Block
+     * @throws Exception
+     */
+    public function setId($id)
+    {
+        if (!is_numeric($id)) {
+            throw new Exception('id must be an integer');
+        }
+        if (!$this->_id) {
+            $this->_id = $id;
+        }
+        return $this;
+    }
+
+    /**
+     * Returns Blocks title
+     *
+     * @return title
+     */
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    /**
+     * Sets the Blocks title
+     *
+     * @param string $title Title to set for Block
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setTitle($title)
+    {
+        $this->_title = $title;
+        return $this;
+    }
+
+    /**
+     * Returns Blocks url
+     *
+     * @return url
+     */
+    public function getUrl()
+    {
+        return $this->_url;
+    }
+
+    /**
+     * Sets the Blocks url
+     *
+     * @param string $url Url to set for Block
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setUrl($url)
+    {
+        $this->_url = $url;
+        return $this;
+    }
+
+    /**
+     * Returns if External
+     *
+     * @return external
+     */
+    public function getExternal()
+    {
+        return $this->_external;
+    }
+
+    /**
+     * Sets if Url is external
+     *
+     * @param string $external Boolean if external url
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setExternal($external)
+    {
+        $this->_external = $external;
+        return $this;
+    }
+
+    /**
+     * Returns the Blocks description
+     *
+     * @return description
+     */
+    public function getDescription()
+    {
+        return $this->_description;
+    }
+
+    /**
+     * Sets the Blocks desciption
+     *
+     * @param type $description The description for Block
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setDescription($description)
+    {
+        $this->_description = $description;
+        return $this;
+    }
+
+    /**
+     * Returns the Blocks image
+     *
+     * @return image
+     */
+    public function getImage()
+    {
+        return $this->_image;
+    }
+
+    /**
+     * Sets the Blocks image
+     *
+     * @param string $image
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setImage($image)
+    {
+        $this->_image = $image;
+        return $this;
+    }
+
+    /**
+     * Returns the Blocks Page id to display the block on
+     *
+     * @return page_on
+     */
+    public function getPageOn()
+    {
+        return $this->_pageOn;
+    }
+
+    /**
+     * Sets the Blocks page on
+     *
+     * @param type $pageOn The page to display the Block on
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setPageOn($pageOn)
+    {
+        $this->_pageOn = $pageOn;
+        return $this;
+    }
+
+    /**
+     * Returns the Page To display Block on
+     *
+     * @return page_to
+     */
+    public function getPageTo()
+    {
+        return $this->_pageTo;
+    }
+
+    /**
+     * Sets the Page to display the Block on
+     *
+     * @param type $pageTo The page id to display the Block on
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setPageTo($pageTo)
+    {
+        $this->_pageTo = $pageTo;
+        return $this;
+    }
+
+    /**
+     * Return the Blocks position on the page
+     *
+     * @return pos
+     */
+    public function getPos()
+    {
+        return $this->_pos;
+    }
+
+    /**
+     * Sets the Position of the Block
+     *
+     * @param type $pos Position of the Block on the Page
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function setPos($pos)
+    {
+        $this->_pos = $pos;
+        return $this;
+    }
+
+    /**
+     * Checks the id of the object if it is set then calls update othervise
+     * calls insert function
+     *
+     * @param PDO     $dbh            Database connection
+     * @param boolean $saveNullFields To save nul fields or not
+     *
+     * @return viod
+     */
+    public function save(PDO $dbh)
+    {
+        if ($this->_id) {
+            $this->update($dbh);
+        } else {
+            $this->insert($dbh);
+        }
+    }
+
+    /**
+     * Inserts the object into the $this->tableName and returns the object
+     * being created
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function insert(PDO $dbh)
+    {
+        try {
+            $methods = get_class_methods(get_class($this));
+            $values = array();
+            if ($methods) {
+                $pattern = '/get(.*)/';
+                foreach ($methods as $mName) {
+                    if (preg_match($pattern, $mName, $matches)) {
+                        $func = create_function(
+                            '$c',
+                            'return "_" . strtolower($c[1]);'
+                        );
+                        $fieldName = preg_replace_callback(
+                            '/([A-Z])/',
+                            $func,
+                            $matches[1]
+                        );
+                        $fieldName = preg_replace('/^_/', '', $fieldName);
+                        $values[$fieldName] = $this->$matches[0]();
+                    }
+                }
+            }
+            $defaultVars = get_class_vars(get_class($this));
+            $primaryKey  = $defaultVars['primaryKey'];
+            $tableName   = $defaultVars['tableName'];
+            unset($values[$primaryKey]);
+            // get the position for this insert
+            $values['pos'] = $this->_returnNextPos($dbh, $values['page_on']);
+            $sql = Toolkit_Common::createSQLInsert(
+                $tableName,
+                array_keys($values)
+            );
+            $sql .= " RETURNING $primaryKey";
+            $stmt = Toolkit_Common::prepareQuery(
+                $dbh,
+                $tableName,
+                $sql,
+                $values
+            );
+            $stmt->execute();
+            $setter = 'set'.ucfirst($primaryKey);
+            $this->$setter($stmt->fetchColumn());
+            return $this;
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * returs the next positition for the given page_on
+     *
+     * @param PDO $dbh    Database Connection
+     * @param int $pageOn page to display block on
+     *
+     * @return int
+     */
+    private function _returnNextPos(PDO $dbh, $pageOn)
+    {
+        try {
+            $sql = "
+            SELECT count(id)
+              FROM blocks
+             WHERE page_on = :page_on";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':page_on', $pageOn, PDO::PARAM_INT);
+            $stmt->execute();
+            $nextPos = $stmt->fetchColumn();
+            return ($nextPos) ? ++$nextPos : 1;
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * Updates the object
+     *
+     * @param PDO $dbh Database Connection
+     *
+     * @return Toolkit_Blocks_Block
+     */
+    public function update(PDO $dbh)
+    {
+        try {
+            $methods = get_class_methods(get_class($this));
+            $values = array();
+            if ($methods) {
+                $pattern = '/get(.*)/';
+                foreach ($methods as $mName) {
+                    if (preg_match($pattern, $mName, $matches)) {
+                        $func = create_function(
+                            '$c',
+                            'return "_" . strtolower($c[1]);'
+                        );
+                        $fieldName = preg_replace_callback(
+                            '/([A-Z])/',
+                            $func,
+                            $matches[1]
+                        );
+                        $fieldName = preg_replace('/^_/', '', $fieldName);
+                        $fieldValue = $this->$matches[0]();
+                        $values[$fieldName] = $fieldValue;
+                    }
+                }
+            }
+            $defaultVars = get_class_vars(get_class($this));
+            $primaryKey  = $defaultVars['primaryKey'];
+            $tableName   = $defaultVars['tableName'];
+            $sql = Toolkit_Common::createSQLUpdate(
+                $tableName,
+                array_keys($values),
+                array("$primaryKey = :$primaryKey")
+            );
+            $stmt = Toolkit_Common::prepareQuery(
+                $dbh,
+                $tableName,
+                $sql,
+                $values
+            );
+            $stmt->execute();
+            return $this;
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    /**
+     * Removes a object from the database by the id
+     * if id is not set then it throws an error
+     *
+     * @param PDO $dbh
+     */
+    public function delete(PDO $dbh)
+    {
+        if (!$this->getId()) {
+            throw new Exception('id is not set');
+        }
+        try {
+            $sql = "
+            DELETE
+              FROM {$this->tableName}
+             WHERE id = :id";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':id', $this->getId(), PDO::PARAM_INT);
+            $stmt->execute();
+        } catch(PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+}
+
diff --git a/Toolkit/Blocks/Database/application.sql b/Toolkit/Blocks/Database/application.sql
new file mode 100644 (file)
index 0000000..349392a
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- setup schema
+--
+
+CREATE SCHEMA blocks;
+GRANT ALL ON SCHEMA blocks TO nobody;
+
+--
+-- Tables
+--
+
+\i ./tables/blocks.sql
\ No newline at end of file
diff --git a/Toolkit/Blocks/Database/removeApplication.sql b/Toolkit/Blocks/Database/removeApplication.sql
new file mode 100644 (file)
index 0000000..c08046a
--- /dev/null
@@ -0,0 +1,6 @@
+--
+-- Drops schema
+-- WARNING: CANNOT BE UNDONE
+--
+
+DROP SCHEMA IF EXISTS blocks CASCADE;
\ No newline at end of file
diff --git a/Toolkit/Blocks/Database/tables/blocks.sql b/Toolkit/Blocks/Database/tables/blocks.sql
new file mode 100644 (file)
index 0000000..8139346
--- /dev/null
@@ -0,0 +1,19 @@
+DROP TABLE IF EXISTS blocks.blocks;
+
+CREATE TABLE blocks.blocks (
+    id SERIAL,
+    title TEXT,
+    description TEXT,
+    image TEXT,
+       url TEXT,
+    external BOOLEAN,
+    page_on INTEGER NOT NULL
+        REFERENCES toolbox.pages(id)
+        ON DELETE CASCADE,
+    page_to INTEGER,
+    pos INTEGER NOT NULL DEFAULT 1,
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON blocks.blocks TO nobody;
+GRANT ALL ON blocks.blocks_id_seq TO nobody;
\ No newline at end of file
diff --git a/Toolkit/Blocks/Database/upgrade.sql b/Toolkit/Blocks/Database/upgrade.sql
new file mode 100644 (file)
index 0000000..ca1c8f3
--- /dev/null
@@ -0,0 +1,8 @@
+--
+-- Upgrade block to have url and external option
+--
+
+ALTER TABLE blocks.blocks drop CONSTRAINT blocks_page_to_fkey;
+ALTER TABLE blocks.blocks ALTER page_to DROP NOT NULL;
+ALTER TABLE blocks.blocks ADD url TEXT;
+ALTER TABLE blocks.blocks ADD external BOOLEAN;
\ No newline at end of file
diff --git a/Toolkit/Blocks/Display.php b/Toolkit/Blocks/Display.php
new file mode 100644 (file)
index 0000000..028f7c2
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * Display.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Package_Display
+ *
+ * Creates an array
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_BLocks_Display
+{
+    private $_dbh;
+
+    public function __construct(PDO $dbh)
+    {
+        $this->_dbh = $dbh;
+    }
+
+    public function getPageBlocksAsArray($pageId)
+    {
+        $pageBlocks = array();
+        $blocks = Toolkit_Blocks_Block::fetchByPageOn($this->_dbh, $pageId);
+        if (!empty($blocks)) {
+            foreach ($blocks as $block) {
+                if ($block->getUrl()) {
+                    $url = $block->getUrl();
+                } else {
+                    $url = Toolkit_Template_Page::getSeoUrl(
+                        new Toolkit_Toolbox_PageGatewayPublish($this->_dbh),
+                        $block->getPageTo()
+                    );
+                }
+                $pageBlocks[] = array(
+                    'external' => $block->getExternal(),
+                    'href'     => $url,
+                    'img'      => ($block->getImage())
+                        ? HEADLINE_THUMB . $block->getImage()
+                        : '',
+                    'header'   => $block->getTitle(),
+                    'descr'    => $block->getDescription()
+                );
+            }
+        }
+        return $pageBlocks;
+    }
+}
+
diff --git a/Toolkit/Blocks/IndexController.php b/Toolkit/Blocks/IndexController.php
new file mode 100644 (file)
index 0000000..927db89
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+/**
+ * IndexController.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Tags_IndexController
+ *
+ * Controller for admin side of the Featured pages
+ *
+ * @category  Toolkit
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_Blocks_IndexController
+    extends Toolkit_BaseControllerAbstract
+    implements Toolkit_IController
+{
+
+    public function __construct(Toolkit_Registry $registry)
+    {
+        parent::__construct($registry);
+        $GLOBALS['styleSheets'][] = MEDIA_BASE_URL .
+            $registry->appConfig->application->setPath . '/css/style.css';
+    }
+    /**
+     * default action used
+     *
+     * @return string html
+     */
+    public function indexAction()
+    {
+        $GLOBALS['bottomScripts'][] = MEDIA_BASE_URL .
+                $this->registry->appConfig->application->setPath .
+                '/js/jquery.columnview.js';
+        // look at canCreateOnAnyPage
+        $canCreateOnAnyPage = $this->registry->appConfig->canCreateOnAnyPage;
+        if ($canCreateOnAnyPage) {
+
+            $list = new Toolkit_Blocks_Admin_ListPages($this->registry);
+            $html = $list->toHtml();
+        } else {
+            $edit = new Toolkit_Blocks_Admin_EditPage(
+                $this->registry,
+                HOME_ID
+            );
+            $html = $edit->toHtml();
+        }
+        return $html;
+    }
+
+    /**
+     * Add/Edit Page Action
+     *
+     * @return string html
+     */
+    public function EditAction()
+    {
+        $GLOBALS['bottomScripts'][] = MEDIA_BASE_URL .
+            $this->registry->appConfig->application->setPath .
+            '/js/jquery.columnview.js';
+        $pageId = filter_input(
+            INPUT_GET,
+            'page_on',
+            FILTER_SANITIZE_NUMBER_INT
+        );
+        $edit = new Toolkit_Blocks_Admin_EditPage(
+            $this->registry,
+            $pageId
+        );
+        return $edit->toHtml();
+    }
+
+    /**
+     * Used to create the page selector Column View
+     * this method will call exit to stop it from creating any more html
+     * from top and fotter methods
+     */
+    public function AddAction()
+    {
+        $pageTree = new Toolkit_Blocks_Admin_PageTree($this->registry->dbh);
+        echo $pageTree->toHtml();
+        exit;
+    }
+
+}
diff --git a/Toolkit/Blocks/application.ini b/Toolkit/Blocks/application.ini
new file mode 100644 (file)
index 0000000..d9471c6
--- /dev/null
@@ -0,0 +1,38 @@
+; Production server configuration data
+[production]
+application.name    = "GLM Blocks"
+application.path    = MEDIA_BASE_URL "admin/blocks.php"
+application.setPath = "Toolkit/Blocks"
+
+; router config
+router.path        = BASE "Toolkit/Blocks"
+router.application = "Blocks"
+
+; PEAR HTML_Template_Flexy Options and settings
+flexy.options.templateDir    = "Toolkit/Blocks/templates"
+flexy.options.compileDir     = "Toolkit/Blocks/templates/compiled"
+flexy.templates.listPages    = "listPages.html"
+flexy.templates.editPage     = "editPage.html"
+
+; jQuery settings
+jqueryui.version = "1.8.13"
+; jQuery themes {"base", "cupertino", "smoothness", "start"}
+jqueryui.theme = "base"
+
+canCreateOnAnyPage = Off
+
+; development server configuration data inherits from production and
+; overrides values as necessary
+[development : production]
+
+; chuck's server configuration data inherits from development
+; and overrides values as necessary
+[chuck : development]
+
+; john's server configuration data inherits from development
+; and overrides values as necessary
+[john : development]
+
+; steve's server configuration data inherits from development
+; and overrides values as necessary
+[steve : development]
diff --git a/Toolkit/Blocks/assets/btn_add.gif b/Toolkit/Blocks/assets/btn_add.gif
new file mode 100755 (executable)
index 0000000..7ca35fb
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_add.gif differ
diff --git a/Toolkit/Blocks/assets/btn_add_sm.gif b/Toolkit/Blocks/assets/btn_add_sm.gif
new file mode 100755 (executable)
index 0000000..50994dc
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_add_sm.gif differ
diff --git a/Toolkit/Blocks/assets/btn_back.gif b/Toolkit/Blocks/assets/btn_back.gif
new file mode 100755 (executable)
index 0000000..31ae1f4
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_back.gif differ
diff --git a/Toolkit/Blocks/assets/btn_delete.gif b/Toolkit/Blocks/assets/btn_delete.gif
new file mode 100755 (executable)
index 0000000..b320511
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_delete.gif differ
diff --git a/Toolkit/Blocks/assets/btn_edit.gif b/Toolkit/Blocks/assets/btn_edit.gif
new file mode 100755 (executable)
index 0000000..0630f07
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_edit.gif differ
diff --git a/Toolkit/Blocks/assets/btn_link.gif b/Toolkit/Blocks/assets/btn_link.gif
new file mode 100755 (executable)
index 0000000..155c6c8
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_link.gif differ
diff --git a/Toolkit/Blocks/assets/btn_update.gif b/Toolkit/Blocks/assets/btn_update.gif
new file mode 100755 (executable)
index 0000000..91838e0
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_update.gif differ
diff --git a/Toolkit/Blocks/assets/btn_upload.gif b/Toolkit/Blocks/assets/btn_upload.gif
new file mode 100755 (executable)
index 0000000..121f0b3
Binary files /dev/null and b/Toolkit/Blocks/assets/btn_upload.gif differ
diff --git a/Toolkit/Blocks/assets/left_circle.gif b/Toolkit/Blocks/assets/left_circle.gif
new file mode 100755 (executable)
index 0000000..075391b
Binary files /dev/null and b/Toolkit/Blocks/assets/left_circle.gif differ
diff --git a/Toolkit/Blocks/assets/right_circle.gif b/Toolkit/Blocks/assets/right_circle.gif
new file mode 100755 (executable)
index 0000000..08cfbad
Binary files /dev/null and b/Toolkit/Blocks/assets/right_circle.gif differ
diff --git a/Toolkit/Blocks/css/style.css b/Toolkit/Blocks/css/style.css
new file mode 100644 (file)
index 0000000..72e5f36
--- /dev/null
@@ -0,0 +1,485 @@
+html {
+    font-size: 62.5%;
+    }
+#blocksEditWrapper, #blocksListWrapper {
+    font-size: 12px;
+    font-size: 1.2rem;
+    }
+h2 {
+    font-size: 18px;
+    font-size: 1.8rem;
+    color: #777;
+    }
+.containerobj .widget {
+    background-color: white;
+    }
+.containerobj .active .widget {
+    color: white;
+    background-color: #3671cf;
+    }
+.containerobj .inpath .widget {
+    background-color: #d0d0d0;
+    }
+#demo1 {
+    height: 200px;
+    }
+#demo1 a {
+    padding: 0 3px;
+    }
+.ui-dialog-buttonpane {
+    padding: 0 10px 0 20px !important;
+    }
+#dialog-modal {
+    height: auto !important;
+    }
+.imageBlock {
+    width: 210px;
+    float: left;
+    padding: 0 5px 0 5px;
+}
+.textBlock {
+    float: left;
+    width: 536px;
+    padding: 5px 5px 0 5px;
+}
+.textBlockTextArea {
+    width: 436px;
+    max-width: 436px;
+    min-width: 436px;
+    min-height: 160px;
+    margin: 3px 0 0 0;
+    padding: 3px;
+    font-family: Verdana, Geneva, sans-serif;
+    font-size: 12px;
+    font-size: 1.2rem;
+    border: 1px solid #999;
+}
+#sortable {
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+    width: 800px;
+    float: left;
+    overflow: hidden;
+}
+#sortable li {
+    margin: 3px;
+    position: relative;
+    padding: 0 0 3px 25px;
+    overflow: hidden;
+}
+#sortable li span.ui-icon {
+    position: absolute;
+    margin-left: -25px;
+}
+#newBlockForm {
+    float: left;
+    clear: both;
+    list-style-type: none;
+    margin: 0;
+    padding: 0;
+    width: 800px;
+    float: left;
+    overflow: hidden;
+}
+#newBlockForm li {
+    margin: 3px;
+    position: relative;
+    padding: 0 0 3px 25px;
+    overflow: hidden;
+}
+#notsortable {
+    list-style-type: none;
+    margin: 10px 0 10px 0;
+    padding: 0;
+    width: 800px;
+    overflow: hidden;
+}
+#notsortable li {
+    overflow: hidden;
+}
+#notsortable li span {
+    margin-left: 20px;
+}
+#blocksListWrapper {
+    width: 800px;
+    border: 1px solid #777;
+    padding: 10px;
+    background: #E1E1E1;
+    }
+#blocksListWrapper h2 {
+    width: 600px;
+    float: left;
+    overflow: hidden;
+    margin: 5px 0 5px 3px;
+    }
+#editPane {
+    float: left;
+    width: 99px;
+    }
+#deletePane {
+    float: right;
+    width: 100px;
+    }
+#mainPane {
+    float: left;
+    width: 500px;
+    overflow: hidden;
+    }
+#infoPane {
+    float: left;
+    display: block;
+    width: 500px;
+    margin: 9px 0 0 8px;
+    border-bottom: 1px solid #B1B1B1;
+    overflow: hidden;
+    font-size: 30px;
+    font-size: 3.0rem;
+    line-height: 28px;
+    color: #777;
+    text-decoration: none;
+    }
+#breadcrumbs {
+    float:left;
+    color: #777;
+    margin: 3px 0 10px 9px;
+    }
+#numberPane {
+    float: right;
+    width: 90px;
+    margin: 20px 0 0 0;
+    }
+a#editBtn, a#deleteBtn {
+    display: block;
+    height: 28px;
+    width: 82px;
+    line-height: 28px;
+    margin: 20px 0 20px 8px;
+    padding: 0 0 0 30px;
+    color: #555;
+    font-family: Verdana, Geneva, sans-serif;
+    text-decoration: none;
+    }
+a#editBtn {
+    background: url(../assets/btn_edit.gif) no-repeat;
+    }
+a#editBtn:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    }
+a#deleteBtn {
+    background: url(../assets/btn_delete.gif) no-repeat;
+    }
+a#deleteBtn:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    }
+#titletext {
+    float: left;
+    display: block;
+    font-size: 30px;
+    font-size: 3.0rem;
+    line-height: 28px;
+    color: #777;
+    text-decoration: none;
+    overflow: hidden;
+    width: 500px;
+    margin: 9px 0 0 8px;
+    border-bottom: 1px solid #B1B1B1;
+    overflow: hidden;
+    font-size: 26px;
+    font-size: 2.6rem;
+    }
+#titletext:hover {
+    color: #09F;
+    }
+#linktext {
+    float: right;
+    padding: 8px 5px 0 0;
+    }
+#numLeft {
+    float: right;
+    display: inline-block;
+    width: 15px;
+    height: 30px;
+    background: url(../assets/left_circle.gif) no-repeat;
+    }
+#numRight {
+    float: right;
+    display: inline-block;
+    width: 15px;
+    height: 30px;
+    background: url(../assets/right_circle.gif) no-repeat;
+    }
+#numMain {
+    float: right;
+    display: inline-block;
+    overflow: hidden;
+    color: #777;
+    font-size: 20px;
+    font-size: 2.0rem;
+    font-weight: bold;
+    line-height: 28px;
+    border-top: 1px solid #B1B1B1;
+    border-bottom: 1px solid #B1B1B1;
+    margin: 0 -3px;
+    }
+a#addPageUrl {
+    display: block;
+    width: 222px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0 0 0 36px;
+    margin: 0 0 10px 0;
+    background: url(../assets/btn_add.gif) no-repeat;
+    color: #555;
+    font-family: Verdana, Geneva, sans-serif;
+    text-decoration: none;
+    }
+a#addPageUrl:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    }
+#blocksEditWrapper {
+    border: 1px solid #777;
+    padding: 10px;
+    margin: 10px 0 0 0;
+    background: #E1E1E1;
+    width: 800px;
+    overflow: hidden;
+    }
+#blocksEditWrapper h2 {
+    width: 600px;
+    float: left;
+    overflow: hidden;
+    margin: 5px 0 5px 3px;
+    }
+#backBtn {
+    display:block;
+    height: 28px;
+    width: 139px;
+    line-height: 28px;
+    margin: 0 3px 0 0;
+    padding: 0 0 0 30px;
+    background: url(../assets/btn_back.gif) no-repeat;
+    color: #555;
+    font-family: Verdana, Geneva, sans-serif;
+    text-decoration: none;
+    }
+#backBtn:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    }
+.title {
+    float: left;
+    display: inline;
+    height: 26px;
+    padding: 0 5px 0 0;
+    margin: 0;
+    }
+.titleLabel {
+    display: inline;
+    font-size: 12px;
+    font-size: 1.2rem;
+    line-height: 26px;
+    margin: 0;
+}
+.urlField {
+    clear: left;
+}
+.editPageTo {
+    display: inline;
+    font-size: 12px;
+    font-size: 1.2rem;
+    line-height: 26px;
+    margin: 0 5px 0 0;
+    }
+#page_to_name {
+    display: inline;
+    font-size: 12px;
+    line-height: 26px;
+    margin: 0 5px 0 0;
+    }
+#addPageTo {
+    display: inline;
+    width: 82px;
+    height: 28px;
+    background: url(../assets/btn_link.gif) no-repeat;
+    border: none;
+    text-align: left;
+    padding: 0 0 0 24px;
+}
+#addPageTo:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    cursor: pointer;
+    }
+#addBtn {
+    display: block;
+    position:absolute;
+    bottom: 5px;
+    right: 5px;
+    width: 82px;
+    height: 28px;
+    background: url(../assets/btn_add_sm.gif) no-repeat;
+    border: none;
+}
+#addBtn:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    cursor: pointer;
+    }
+#updateBtn {
+    display: block;
+    position:absolute;
+    bottom: 5px;
+    right: 5px;
+    width: 82px;
+    height: 28px;
+    background: url(../assets/btn_update.gif) no-repeat;
+    border: none;
+    padding: 0 0px 0 16px;
+    }
+#updateBtn:hover {
+    color: #09F;
+    background-position: 0px -28px;
+    cursor: pointer;
+    }
+#deleteBtn2 {
+    display: block;
+    position:absolute;
+    bottom: 36px;
+    right: 5px;
+    width: 55px;
+    height: 28px;
+    background: url(../assets/btn_delete.gif) no-repeat;
+    border: none;
+    padding: 0 0 0 27px;
+    font-size: 14px;
+    font-size: 1.4rem;
+    line-height: 28px;
+    text-decoration: none;
+    margin: 0px;
+    }
+#deleteBtn2:hover {
+    color: #F00;
+    background-position: 0px -28px;
+    cursor: pointer;
+    }
+.ui-state-highlight {
+    color: #09F;
+    border-color: #09F;
+    background: #09F;
+    }
+.ui-widget-content {
+    margin: 0;
+    padding: 0;
+    }
+.upload {
+    position: relative;
+    width: 210px;
+    height:2 8px;
+    background: url(../assets/btn_upload.gif) no-repeat;
+    line-height: 28px;
+    padding: 0;
+    margin: 5px 0 3px 0;
+    font-size: 12px;
+    font-size: 1.2rem;
+    color: #555;
+    font-family: Verdana, Geneva, sans-serif;
+    text-decoration: none;
+    }
+.upload:hover {
+    color: #09F;
+    background-position: 0px -28px;
+}
+.upload, .image {
+    width: 210px;
+    height: 28px;
+    }
+.image {
+    opacity: 0.01;
+    filter: alpha(opacity=0.01);
+    position: absolute;
+    right: 0px;
+    }
+#upload_text {
+    width: 210px;
+    height: 28px;
+    display: block;
+    cursor: pointer;
+    }
+.upload:hover #upload_text {
+    color: #09F;
+    }
+.file-wrapper {
+    cursor: pointer;
+    display: inline-block;
+    overflow: hidden;
+    position: relative;
+    margin: 5px 0 0 0;
+}
+.file-wrapper input {
+    cursor: pointer;
+    font-size: 100px;
+    height: 100%;
+    filter: alpha(opacity=1);
+    -moz-opacity: 0.01;
+    opacity: 0.01;
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 210px;
+    height: 28px;
+}
+.file-wrapper .button {
+    width: 180px;
+    height: 28px;
+    background: url(../assets/btn_upload.gif) no-repeat;
+    color: #fff;
+    cursor: pointer;
+    font-size: 12px;
+    font-size: 1.2rem;
+    color: #555;
+    font-family: Verdana, Geneva, sans-serif;
+    text-decoration: none;
+    display: inline-block;
+    line-height: 28px;
+    padding: 0 0 0 30px;
+}
+
+.file-wrapper:hover .button {
+    color: #09F;
+    background-position: 0px -28px;
+    }
+#sideImage {
+    display: block;
+    width: 210px;
+    height: auto;
+}
+.internal_link, .external_link {
+    display: block;
+    float: left;
+    clear: left;
+    overflow: hidden;
+    background: #F5F5F5;
+    border: 1px solid #CCC;
+    width: 290px;
+    margin-top: 5px;
+    padding: 5px;
+}
+.internal_link h3, .external_link h3 {
+    display: block;
+    width: 100%;
+    overflow: hidden;
+    font-size: 14px;
+    font-weight: bold;
+    margin: 0;
+    padding: 0 0 5px 0;
+    color: #777;
+}
+.cke_chrome {
+    float: left;
+    clear: left;
+    margin-top: 5px !important;
+}
diff --git a/Toolkit/Blocks/js/column.js b/Toolkit/Blocks/js/column.js
new file mode 100644 (file)
index 0000000..f1d6d09
--- /dev/null
@@ -0,0 +1,10 @@
+$(document).ready(function(){
+    $("#dialog-modal").load('blocks.php?ac=Add', function(){
+        $('#demo1').columnview({
+            preview:false,
+            onchange: function(element) {
+                $("#page_on").text($(element).text());
+            }
+        });
+    });
+});
diff --git a/Toolkit/Blocks/js/editPage.js b/Toolkit/Blocks/js/editPage.js
new file mode 100644 (file)
index 0000000..dd1cc0a
--- /dev/null
@@ -0,0 +1,149 @@
+var SITE = SITE || {};
+
+SITE.fileInputs = function() {
+  var $this = $(this),
+      $val = $this.val(),
+      valArray = $val.split('\\'),
+      newVal = valArray[valArray.length-1],
+      $button = $this.siblings('.button'),
+      $fakeFile = $this.siblings('.file-holder');
+  if(newVal !== '') {
+    $button.text('Image Chosen');
+    if($fakeFile.length === 0) {
+      $button.after('<span class="file-holder">' + newVal + '</span>');
+    } else {
+      $fakeFile.text(newVal);
+    }
+  }
+};
+
+$(function(){
+    $('.file-wrapper input[type=file]').bind('change focus click', SITE.fileInputs);
+
+    $('.deleteBlock > a').click(function(){
+        return confirm('This Delete cannot be undone!\n Are You Sure?');
+    });
+    $('#sortable').live('mousedown', function(e) {
+        e.stopPropagation();
+    });
+    if (CKEDITOR.env.isCompatible) {
+        $("textarea.textBlockTextArea").each(function() {
+            CKEDITOR.replace(
+                $(this).attr('id'),
+                {
+                    toolbar : 'LimitedToolset',
+                    width : 300,
+                    height : 200
+                }
+            );
+        });
+    }
+    $("#sortable").sortable({
+        update: function (event, ui) {
+
+            var url = '../block-pos/?' + $(this).sortable('serialize');
+            $.get(url, function(data){
+                $('.movable').effect('hightlight', {}, 700);
+            });
+        },
+        placeholder: "ui-state-highlight"
+    });
+    //$("#sortable").disableSelection();
+
+    $("#addPageTo").click(function(){
+        $("#dialog-modal").dialog({
+            height: 240,
+            width: 800,
+            modal: true,
+            buttons: {
+                "Select Page": function() {
+                    if ($("#page_to").val() != '') {
+                        $(this).dialog("close");
+                    } else {
+                        alert("Select a Page");
+                    }
+                },
+                Cancel: function() {
+                    $(this).dialog("close");
+                },
+                "Clear Page": function() {
+                    $("#page_to_name").text('No Page');
+                    $("#page_to").val('');
+                    $(this).dialog("close");
+                }
+            }
+        });
+        $("#pages").load('blocks.php?ac=Add', function(){
+            $('#demo1').columnview({
+                preview:false,
+                onchange: function(element) {
+                    $("#page_to_name").text($(element).text());
+                    $("#page_to").val($(element).attr('rel'));
+                }
+            });
+        });
+        return false;
+    });
+    $(".editPageTo").click(function(){
+        var blockId = $(this).attr('rel');
+        $("#dialog-modal").dialog({
+            height: 240,
+            width: 800,
+            modal: true,
+            buttons: {
+                "Select Page": function() {
+                    if ($('[name="page_to"][rel="' + blockId + '"]').val() != '') {
+                        $(this).dialog("close");
+                    } else {
+                        alert("Select a Page");
+                    }
+                },
+                Cancel: function() {
+                    $(this).dialog("close");
+                },
+                "Clear Page": function() {
+                    $('[class="editPageTo"][rel="' + blockId + '"]').text('No Page');
+                    $('[name="page_to"][rel="' + blockId + '"]').val('');
+                    $(this).dialog("close");
+                }
+            }
+        });
+        $("#pages").load('blocks.php?ac=Add', function(){
+            $('#demo1').columnview({
+                preview:false,
+                onchange: function(element) {
+                    $('[class="editPageTo"][rel="' + blockId + '"]').text($(element).text());
+                    $('[name="page_to"][rel="' + blockId + '"]').val($(element).attr('rel'));
+                }
+            });
+        });
+        return false;
+    });
+    $(".blockForm").submit(function(){
+        var msg = '';
+        var errors = 0;
+        var title = $('input[name="title"]', this).val();
+        if (title == '') {
+            errors++;
+            msg += "Headline Required\n";
+        }
+        var page_to = $('input[name="page_to"]', this).val();
+        var blockUrl = $('input[name="url"]', this).val();
+        if (page_to == '' && blockUrl == '') {
+            errors++;
+            msg += "Please select a Page to link to\nor Enter a URL!\n";
+        }
+        if (errors > 0) {
+            alert("Error: " + msg);
+            return false;
+        } else {
+            return true;
+        }
+    });
+});
+
+
+
+$(document).ready(function() {
+  $('.file-wrapper input[type=file]').bind('change focus click', SITE.fileInputs);
+});
diff --git a/Toolkit/Blocks/js/jquery.columnview.js b/Toolkit/Blocks/js/jquery.columnview.js
new file mode 100644 (file)
index 0000000..4131b1d
--- /dev/null
@@ -0,0 +1,267 @@
+/**
+ * jquery.columnview-1.2.js
+ *
+ * Created by Chris Yates on 2009-02-26.
+ * http://christianyates.com
+ * Copyright 2009 Christian Yates and ASU Mars Space Flight Facility. All rights reserved.
+ *
+ * Supported under jQuery 1.2.x or later
+ * Keyboard navigation supported under 1.3.x or later
+ *
+ * Dual licensed under MIT and GPL.
+ */
+
+(function($){
+  $.fn.columnview = function(options){
+
+    var settings = $.extend({}, $.fn.columnview.defaults, options);
+
+    // Add stylesheet, but only once
+    if(!$('.containerobj').get(0)){
+      $('head').prepend('\
+      <style type="text/css" media="screen">\
+        .containerobj {\
+          border: 1px solid #ccc;\
+          height:5em;\
+          overflow-x:auto;\
+          overflow-y:hidden;\
+          white-space:nowrap;\
+          position:relative;\
+        }\
+        .containerobj div {\
+          height:100%;\
+          overflow-y:scroll;\
+          overflow-x:hidden;\
+          position:absolute;\
+        }\
+        .containerobj a {\
+          display:block;\
+          white-space:nowrap;\
+          clear:both;\
+          padding-right:15px;\
+          overflow:hidden;\
+          text-decoration:none;\
+        }\
+        .containerobj a:focus {\
+          outline:none;\
+        }\
+        .containerobj a canvas {\
+        }\
+        .containerobj .feature {\
+          min-width:200px;\
+          overflow-y:auto;\
+        }\
+        .containerobj .feature a {\
+          white-space:normal;\
+        }\
+        .containerobj .hasChildMenu {\
+        }\
+        .containerobj .active {\
+          background-color:#3671cf;\
+          color:#fff;\
+        }\
+        .containerobj .inpath {\
+          background-color:#d0d0d0;\
+          color:#000;\
+        }\
+        .containerobj .hasChildMenu .widget {\
+          color:black;\
+          position:absolute;\
+          right:0;\
+          text-decoration:none;\
+          font-size:0.7em;\
+        }\
+      </style>');
+    }
+
+    // Hide original list
+    $(this).hide();
+    // Reset the original list's id
+    var origid = $(this).attr('id');
+    if (origid) {
+      $(this).attr('id', origid + "-processed");
+    }
+
+    // Create new top container from top-level LI tags
+    var top = $(this).children('li');
+    var container = $('<div/>').addClass('containerobj').attr('id', origid).insertAfter(this);
+    var topdiv = $('<div class="top"></div>').appendTo(container);
+    // Set column width
+    if (settings.fixedwidth || $.browser.msie) { // MSIE doesn't support auto-width
+      var width = typeof settings.fixedwidth == "string" ? settings.fixedwidth : '200px';
+      $('.top').width(width);
+    }
+    $.each(top,function(i,item){
+      var topitem = $(':eq(0)',item).clone(true).wrapInner("<span/>").data('sub',$(item).children('ul')).appendTo(topdiv);
+      if (settings.fixedwidth || $.browser.msie)
+      $(topitem).css({'text-overflow':'ellipsis', '-o-text-overflow':'ellipsis','-ms-text-overflow':'ellipsis'});
+      if($(topitem).data('sub').length) {
+        $(topitem).addClass('hasChildMenu');
+        addWidget(container, topitem);
+      }
+    });
+
+    // Firefox doesn't repeat keydown events when the key is held, so we use
+    // keypress with FF/Gecko/Mozilla to enable continuous keyboard scrolling.
+    var key_event = $.browser.mozilla ? 'keypress' : 'keydown';
+
+    // Event handling functions
+    $(container).bind("click " + key_event, function(event){
+      if ($(event.target).is("a,span")) {
+        if ($(event.target).is("span")){
+          var self = $(event.target).parent();
+        }
+        else {
+          var self = event.target;
+        }
+        if (!settings.multi) {
+          delete event.shiftKey;
+          delete event.metaKey;
+        }
+        self.focus();
+        var container = $(self).parents('.containerobj');
+        // Handle clicks
+        if (event.type == "click"){
+          var level = $('div',container).index($(self).parents('div'));
+          var isleafnode = false;
+          // Remove blocks to the right in the tree, and 'deactivate' other
+          // links within the same level, if metakey is not being used
+          $('div:gt('+level+')',container).remove();
+          if (!event.metaKey && !event.shiftKey) {
+            $('div:eq('+level+') a',container).removeClass('active').removeClass('inpath');
+            $('.active',container).addClass('inpath');
+            $('div:lt('+level+') a',container).removeClass('active');
+          }
+          // Select intermediate items when shift clicking
+          // Sorry, only works with jQuery 1.4 due to changes in the .index() function
+          if (event.shiftKey) {
+            var first = $('a.active:first', $(self).parent()).index();
+            var cur = $(self).index();
+            var range = [first,cur].sort(function(a,b){return a - b;});
+            $('div:eq('+level+') a', container).slice(range[0], range[1]).addClass('active');
+          }
+          $(self).addClass('active');
+          if ($(self).data('sub').children('li').length && !event.metaKey) {
+            // Menu has children, so add another submenu
+            var w = false;
+            if (settings.fixedwidth || $.browser.msie)
+            w = typeof settings.fixedwidth == "string" ? settings.fixedwidth : '200px';
+            submenu(container,self,w);
+          }
+          else if (!event.metaKey && !event.shiftKey) {
+            // No children, show title instead (if it exists, or a link)
+            isleafnode = true;
+            var previewcontainer = $('<div/>').addClass('feature').appendTo(container);
+            // Fire preview handler function
+            if ($.isFunction(settings.preview)) {
+              // We're passing the element back to the callback
+              var preview = settings.preview($(self));
+            }
+            // If preview is specifically disabled, do nothing with the previewbox
+            else if (!settings.preview) {
+            }
+            // If no preview function is specificied, use a default behavior
+            else {
+              var title = $('<a/>').attr({href:$(self).attr('href')}).text($(self).attr('title') ? $(self).attr('title') : $(self).text());
+              $(previewcontainer).html(title);
+            }
+            // Set the width
+            var remainingspace = 0;
+            $.each($(container).children('div').slice(0,-1),function(i,item){
+              remainingspace += $(item).width();
+            });
+            var fillwidth = $(container).width() - remainingspace;
+            $(previewcontainer).css({'top':0,'left':remainingspace}).width(fillwidth).show();
+          }
+          // Fire onchange handler function, but only if multi-select is off.
+          // FIXME Need to deal multiple selections.
+          if ($.isFunction(settings.onchange) && !settings.multi) {
+            // We're passing the element back to the callback
+            var onchange = settings.onchange($(self), isleafnode);
+          }
+        }
+        // Handle Keyboard navigation
+        if(event.type == key_event){
+          switch(event.keyCode){
+            case(37): //left
+              $(self).parent().prev().children('.inpath').focus().trigger("click");
+              break;
+            case(38): //up
+              $(self).prev().focus().trigger("click");
+              break;
+            case(39): //right
+              if($(self).hasClass('hasChildMenu')){
+                $(self).parent().next().children('a:first').focus().trigger("click");
+              }
+              break;
+            case(40): //down
+              $(self).next().focus().trigger("click");
+              break;
+            case(13): //enter
+              $(self).trigger("dblclick");
+              break;
+          }
+        }
+        event.preventDefault();
+      }
+    });
+
+  };
+
+  $.fn.columnview.defaults = {
+    multi: false,     // Allow multiple selections
+    preview: true,    // Handler for preview pane
+    fixedwidth: false,// Use fixed width columns
+    onchange: false   // Handler for selection change
+  };
+
+  // Generate deeper level menus
+  function submenu(container,item,width){
+    var leftPos = 0;
+    $.each($(container).children('div'),function(i,mydiv){
+      leftPos += $(mydiv).width();
+    });
+    var submenu = $('<div/>').css({'top':0,'left':leftPos}).appendTo(container);
+    // Set column width
+    if (width)
+    $(submenu).width(width);
+    var subitems = $(item).data('sub').children('li');
+    $.each(subitems,function(i,subitem){
+      var subsubitem = $(':eq(0)',subitem).clone(true).wrapInner("<span/>").data('sub',$(subitem).children('ul')).appendTo(submenu);
+      if (width)
+      $(subsubitem).css({'text-overflow':'ellipsis', '-o-text-overflow':'ellipsis','-ms-text-overflow':'ellipsis'});
+      if($(subsubitem).data('sub').length) {
+        $(subsubitem).addClass('hasChildMenu');
+        addWidget(container, subsubitem);
+      }
+    });
+  }
+
+  // Uses canvas, if available, to draw a triangle to denote that item is a parent
+  function addWidget(container, item, color){
+    var triheight = $(item).height();
+    var canvas = $("<canvas></canvas>").attr({height:triheight,width:10}).addClass('widget').appendTo(item);    if(!color){ color = $(canvas).css('color'); }
+    canvas = $(canvas).get(0);
+    if(canvas.getContext){
+      var context = canvas.getContext('2d');
+      context.fillStyle = color;
+      context.beginPath();
+      context.moveTo(3,(triheight/2 - 3));
+      context.lineTo(10,(triheight/2));
+      context.lineTo(3,(triheight/2 + 3));
+      context.fill();
+    } else {
+      /**
+       * Canvas not supported - put something in there anyway that can be
+       * suppressed later if desired. We're using a decimal character here
+       * representing a "black right-pointing pointer" in Windows since IE
+       * is the likely case that doesn't support canvas.
+       */
+      $("<span>&#9658;</span>").addClass('widget').css({'height':triheight,'width':10}).prependTo(item);
+    }
+    $(container).find('.widget').bind('click', function(event){
+      event.preventDefault();
+    });
+
+  }
+})(jQuery);
diff --git a/Toolkit/Blocks/js/listPages.js b/Toolkit/Blocks/js/listPages.js
new file mode 100644 (file)
index 0000000..c3d4afb
--- /dev/null
@@ -0,0 +1,35 @@
+$(document).ready(function(){
+    $('.deleteBlock > a').click(function(){
+        return confirm('This Delete cannot be undone!\n Are You Sure?');
+    });
+    $("#addPageUrl").click(function(){
+        $("#dialog-modal").dialog({
+            height: 240,
+            width: 800,
+            modal: true,
+            buttons: {
+                "Select Page": function() {
+                    if ($("#page_on").text() != '') {
+                        location.href = "blocks.php?ac=Edit&page_on=" +
+                            $("#page_on").text();
+                        $(this).dialog("close");
+                    } else {
+                        alert("Select a Page");
+                    }
+                },
+                Cancel: function() {
+                    $(this).dialog("close");
+                }
+            }
+        });
+        $("#pages").load('blocks.php?ac=Add', function(){
+            $('#demo1').columnview({
+                preview:false,
+                onchange: function(element) {
+                    $("#page_on").text($(element).attr('rel'));
+                }
+            });
+        });
+        return false;
+    });
+});
diff --git a/Toolkit/Blocks/positionBlock.php b/Toolkit/Blocks/positionBlock.php
new file mode 100644 (file)
index 0000000..9b02d34
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+require_once '../../setup.phtml';
+$blocks = $_REQUEST['block'];
+$newPos = 1;
+
+if (is_array($blocks) && !empty($blocks)) {
+    $pageOn = null;
+    $dbh = Toolkit_Database::getInstance();
+    foreach ($blocks as $blockId) {
+        if (is_numeric($blockId)) {
+            $block = Toolkit_Blocks_Block::fetchById($dbh, $blockId);
+            $block->setPos($newPos)->save($dbh);
+            $pageOn = $block->getPageOn();
+        }
+        ++$newPos;
+    }
+    // remove this cache file for the block
+    $cache = new Cache_Lite($GLOBALS['cacheOptions']);
+    $cache->remove($pageOn, 'Block');
+}
+return true;
\ No newline at end of file
diff --git a/Toolkit/Blocks/templates/editPage.html b/Toolkit/Blocks/templates/editPage.html
new file mode 100644 (file)
index 0000000..808e70b
--- /dev/null
@@ -0,0 +1,160 @@
+{if:canCreateOnAnyPage}
+<a id="backBtn" href="../admin/blocks.php">Back to All Blocks</a>
+{end:}
+<div id="blocksEditWrapper">
+    <h2>Add New {pageName} Block</h2>
+    <ul id="newBlockForm">
+        <li class="ui-widget-content">
+            <form
+                id="newForm"
+                class="blockForm"
+                method="post"
+                action="blocks.php?ac=Edit"
+                enctype="multipart/form-data"
+                flexy:ignore="yes">
+                <input type="hidden" name="page_on" value="{pageOn}">
+                <input type="hidden" id="page_to" name="page_to">
+                <div class="imageBlock">
+                    <span class="file-wrapper">
+                        <input
+                            type="file"
+                            name="image"
+                            id="image"
+                            class="image">
+                        <span class="button">Choose Image</span>
+                    </span>
+                </div>
+                <div class="textBlock">
+                    <input
+                        class="title"
+                        type="text"
+                        name="title"
+                        placeholder="Headline">
+                    <div class="internal_link">
+                    <h3>Internal Link</h3>
+                    <label
+                        class="titleLabel">Links to:</label>
+                    <div id="page_to_name"></div>
+                    <button id="addPageTo">Choose</button>
+                    </div>
+                    <div class="external_link">
+                    <h3>External Link</h3>
+                    <label
+                        class="title">External URL:
+                        <input type="checkbox" name="external">
+                    </label>
+                    <input
+                        class="title"
+                        type="text"
+                        name="url"
+                        placeholder="URL">
+                    </div>
+                    <textarea
+                        name="description"
+                        id="descr-new"
+                        class="textBlockTextArea"></textarea>
+                    <input id="addBtn" type="submit" value="Add">
+                </div>
+            </form>
+        </li>
+    </ul>
+    <h2>Edit Current {pageName} Blocks</h2>
+    <div id="dialog-modal" title="Page Selector" style="display:none;">
+        <div id="pages"></div>
+    </div>
+    <ul id="sortable">
+        <li
+            flexy:foreach="blocks,block"
+            id="block_{block[id]}"
+            class="ui-widget-content">
+            <span class="ui-icon ui-icon-arrow-4-diag"></span>
+            <form
+                id="form-{block[id]}"
+                class="blockForm"
+                method="post"
+                action="blocks.php?ac=Edit"
+                enctype="multipart/form-data"
+                flexy:ignore="yes">
+                <input
+                    type="hidden"
+                    rel="{block[id]}"
+                    name="page_on"
+                    value="{block[page_on]}">
+                <input
+                    type="hidden"
+                    rel="{block[id]}"
+                    name="page_to"
+                    value="{block[page_to]}">
+                <input
+                    type="hidden"
+                    name="blockId"
+                    value="{block[id]}">
+                <input
+                    type="hidden" name="oldImage" value="{block[image]}">
+                <div class="imageBlock">
+                    <div class="upload">
+                        <input type="file" class="image" name="image">
+                        <a id="upload_text" class="button">
+                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change Image
+                        </a>
+                    </div>
+                    {if:block[imageUrl]}
+                    <img id="sideImage" src="{block[imageUrl]:h}">
+                    {end:}
+                </div>
+                <div class="textBlock">
+                    <input
+                        type="text"
+                        class="title"
+                        name="title"
+                        value="{block[title]}">
+                    <div class="internal_link">
+                    <h3>Internal Link</h3>
+                    <label class="titleLabel">Links to:</label>
+                    {if:block[navigation_name]}
+                    <a
+                        class="editPageTo"
+                        rel="{block[id]}"
+                        href="#">{block[navigation_name]}</a>
+                    {else:}
+                    <a
+                        class="editPageTo"
+                        rel="{block[id]}"
+                        href="#">No Page</a>
+                    {end:}
+                    </div>
+                    <div class="external_link">
+                    <h3>External Link</h3>
+                    <label
+                        class="title">External URL:
+                        {if:block[external]}
+                        <input type="checkbox" name="external" checked>
+                        {else:}
+                        <input type="checkbox" name="external">
+                        {end:}
+                    </label>
+                    <input
+                        class="title"
+                        type="text"
+                        name="url"
+                        placeholder="URL"
+                        value="{block[url]}">
+                    </div>
+                    <textarea
+                        name="description"
+                        id="descr-{block[id]}"
+                        class="textBlockTextArea"
+                        style="min-height:{block[imageHeight]}px;">{block[description]}</textarea>
+                    <input id="updateBtn" type="submit" value="Update" />
+                    <div class="deleteBlock">
+                        <a
+                            id="deleteBtn2"
+                            class=".deleteBlock"
+                            href="{block[deleteUrl]:h}"
+                            rel="{block[id]}">Delete</a>
+                    </div>
+                </div>
+            </form>
+        </li>
+    </ul>
+</div>
diff --git a/Toolkit/Blocks/templates/listPages.html b/Toolkit/Blocks/templates/listPages.html
new file mode 100644 (file)
index 0000000..f362084
--- /dev/null
@@ -0,0 +1,28 @@
+<a id="addPageUrl" href="{addUrl:h}">Add GLM Blocks to a Page</a>
+<div id="dialog-modal" title="Page Selector" style="display:none;">
+    <input type="hidden" name="page_on" id="page_on">
+    <div id="pages"></div>
+</div>
+<div id="blocksListWrapper">
+    <h2 class="blockhead">Current Pages with GLM Blocks</h2>
+    <ul flexy:if="pages" id="notsortable">
+        <li flexy:foreach="pages,page" class="ui-widget-content">
+            <div id="editPane">
+                <a id="editBtn" href="{page[editUrl]:h}">Edit</a>
+            </div><!-- /#editPane -->
+            <div id="mainPane">
+                <a id="titletext" target="_blank" href="{page[pageUrl]:h}">{page[navigation_name]}</a>
+                {page[breadCrumbs]:h} 
+            </div><!-- /#mainPane -->
+            <div id="deletePane" class="deleteBlock">
+                <a id="deleteBtn"  href="{page[deleteUrl]:h}">Delete</a>
+            </div><!-- /#deletePane -->
+            <div id="numberPane">
+                <div id="numRight"></div>
+                <div id="numMain">{page[count]}</div>
+                <div id="numLeft"></div>
+                <div id="linktext">Links:</div>
+            </div><!-- /#numberPane -->
+        </li><!-- /.ui-widget-content -->
+    </ul><!-- /#notsortable -->
+</div><!-- /#blocksListWrapper -->
diff --git a/admin/blocks.php b/admin/blocks.php
new file mode 100644 (file)
index 0000000..0d28b05
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * blocks.php
+ *
+ * PHP version 5.2
+ *
+ * @category  Admin
+ * @package   Blocks
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2012 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+/**
+ * required files
+ */
+require_once '../setup.phtml';
+// get Application config file loaded into Zend_Config
+$config = new Zend_Config_Ini(
+    BASE . 'Toolkit/Blocks/application.ini',
+    strtolower($_ENV['GLM_HOST_ID'])
+);
+// add our custom jquery ui js file to all areas of this admin side application
+$jQueryVersion = $config->jqueryui->version;
+$jQueryTheme   = $config->jqueryui->theme;
+$GLOBALS['bottomScripts'][]
+    = MEDIA_APP_BASE_URL .
+    "libjs/jqueryui/{$jQueryVersion}/js/jquery-ui-{$jQueryVersion}.custom.min.js";
+$GLOBALS['styleSheets'][]
+    = MEDIA_APP_BASE_URL .
+    "libjs/jqueryui/{$jQueryVersion}/development-bundle/themes/{$jQueryTheme}/jquery.ui.all.css";
+// create Registry
+$registry         = new Toolkit_Registry;
+$registry->dbh    = Toolkit_Database::getInstance();
+$registry->logger = Toolkit_Logger::getLogger();
+$registry->router = new Toolkit_Router($registry);
+$registry->router->setPath($config->router->path);
+$registry->router->setApplication($config->router->application);
+$registry->appConfig = $config;
+
+// call loader()
+$html = $registry->router->loader();
+
+
+GLM_TOOLBOX::top($config->application->name, '');
+echo $html;
+GLM_TOOLBOX::footer();