Add source for headerImage Application
authorSteve Sutton <steve@gaslightmedia.com>
Fri, 6 Jun 2014 15:29:23 +0000 (11:29 -0400)
committerSteve Sutton <steve@gaslightmedia.com>
Fri, 6 Jun 2014 15:29:23 +0000 (11:29 -0400)
Bring in the discoverkalamazoo code for headerimages.

20 files changed:
Toolkit/HeaderImages/Database/application.sql [new file with mode: 0644]
Toolkit/HeaderImages/Database/removeApplication.sql [new file with mode: 0644]
Toolkit/HeaderImages/Database/tables/images.sql [new file with mode: 0644]
Toolkit/HeaderImages/Display.php [new file with mode: 0644]
Toolkit/HeaderImages/IndexController.php [new file with mode: 0644]
Toolkit/HeaderImages/Models/Image.php [new file with mode: 0644]
Toolkit/HeaderImages/Models/Page.php [new file with mode: 0644]
Toolkit/HeaderImages/Smarty.php [new file with mode: 0644]
Toolkit/HeaderImages/Views/Index/adminList.tpl [new file with mode: 0644]
Toolkit/HeaderImages/Views/Index/editImage.tpl [new file with mode: 0644]
Toolkit/HeaderImages/Views/Index/nav.tpl [new file with mode: 0644]
Toolkit/HeaderImages/Views/css/admin.css [new file with mode: 0644]
Toolkit/HeaderImages/application.ini [new file with mode: 0644]
Toolkit/HeaderImages/assets/arrow_down.png [new file with mode: 0644]
Toolkit/HeaderImages/assets/arrow_up.png [new file with mode: 0644]
Toolkit/HeaderImages/assets/btn_add.gif [new file with mode: 0644]
Toolkit/HeaderImages/assets/btn_add_sm.gif [new file with mode: 0644]
Toolkit/HeaderImages/index.php [new file with mode: 0644]
admin/headerImages.php [new file with mode: 0644]
admin/nav.phtml

diff --git a/Toolkit/HeaderImages/Database/application.sql b/Toolkit/HeaderImages/Database/application.sql
new file mode 100644 (file)
index 0000000..cd1409c
--- /dev/null
@@ -0,0 +1,12 @@
+--
+-- setup schema
+--
+
+CREATE SCHEMA headers;
+GRANT ALL ON SCHEMA headers TO nobody;
+
+--
+-- Tables
+--
+
+\i ./tables/images.sql
\ No newline at end of file
diff --git a/Toolkit/HeaderImages/Database/removeApplication.sql b/Toolkit/HeaderImages/Database/removeApplication.sql
new file mode 100644 (file)
index 0000000..5f2a79d
--- /dev/null
@@ -0,0 +1,6 @@
+--
+-- Drops schema
+-- WARNING: CANNOT BE UNDONE
+--
+
+DROP SCHEMA IF EXISTS headers CASCADE;
\ No newline at end of file
diff --git a/Toolkit/HeaderImages/Database/tables/images.sql b/Toolkit/HeaderImages/Database/tables/images.sql
new file mode 100644 (file)
index 0000000..63bd6a7
--- /dev/null
@@ -0,0 +1,14 @@
+DROP TABLE IF EXISTS headers.images;
+
+CREATE TABLE headers.images (
+    id SERIAL,
+    title TEXT,
+    subtitle TEXT,
+    image TEXT NOT NULL,
+    page INTEGER NOT NULL,
+    pos INTEGER NOT NULL DEFAULT 1,
+    PRIMARY KEY (id)
+);
+
+GRANT ALL ON headers.images TO nobody;
+GRANT ALL ON headers.images_id_seq TO nobody;
diff --git a/Toolkit/HeaderImages/Display.php b/Toolkit/HeaderImages/Display.php
new file mode 100644 (file)
index 0000000..470316c
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+
+/**
+ * Display.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Package_Display
+ *
+ * Description of Display
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_HeaderImages_Display
+{
+    private $_page;
+    private $_dbh;
+    private $_headerImages   = array();
+    private $_headerPages    = array();
+    private $_headerSubPages = array();
+
+    public function __construct($page, PDO $dbh)
+    {
+        $this->_page = $page;
+        $this->_dbh  = $dbh;
+        $this->_buildHeaderImageArray();
+    }
+
+    private function _getHeaderPages()
+    {
+        $data = array();
+        try {
+            $sql = "
+            SELECT DISTINCT page
+              FROM headers.images";
+            $stmt = $this->_dbh->query($sql);
+            while ($page = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $subPages = Toolkit_Common::getHierarchicalTreeStructure(
+                    $this->_dbh,
+                    'pages',
+                    'id',
+                    'parent',
+                    'pos',
+                    $page['page']
+                );
+                $data[$page['page']] = array_keys($subPages);
+            }
+            if (is_array($data)) {
+                $mainKeys = array_keys($data);
+                foreach ($mainKeys as $pageId) {
+                    foreach ($data as $mainPageId => $pageSubs) {
+                        $foundKey = array_search($pageId, $pageSubs);
+                        if ($foundKey !== false) {
+                            unset ($data[$mainPageId][$foundKey]);
+                        }
+                    }
+                }
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return $data;
+    }
+
+    private function _buildHeaderImageArray()
+    {
+        $pageArray = $this->_getHeaderPages();
+        $this->_headerPages = array_keys($pageArray);
+        foreach ($pageArray as $mainPage => $subPages) {
+            foreach ($subPages as $subPageId) {
+                $this->_headerSubPages[$subPageId] = $mainPage;
+            }
+        }
+        foreach ($pageArray as $mainPage => $subs) {
+            $page = Toolkit_HeaderImages_Models_Page::fetchPageById(
+                $this->_dbh,
+                $mainPage
+            );
+            $page->getImagesForPage($this->_dbh);
+            $this->_headerImages[$mainPage] = $page->getImages();
+            if (!empty($subs)) {
+                foreach ($subs as $subPage) {
+                    $this->_headerImages[$subPage] = $page->getImages();
+                }
+            }
+        }
+    }
+
+    public function getPageHeaderImage()
+    {
+        if ($this->_headerSubPages[$this->_page]) {
+           $pageId = $this->_headerSubPages[$this->_page];
+        } else if (in_array($this->_page, $this->_headerPages)) {
+            $pageId = $this->_page;
+        } else {
+            return false;
+        }
+        if ($this->_headerImages[$pageId]) {
+            $currentImageNumber = $_SESSION['pageHeader'][$pageId];
+            if ($currentImageNumber !== false) {
+                $currentImageNumber++;
+                if (!$this->_headerImages[$pageId][$currentImageNumber]) {
+                    $currentImageNumber = 0;
+                }
+            } else {
+                $currentImageNumber = 0;
+            }
+            // save current image in session
+            $_SESSION['pageHeader'][$pageId] = $currentImageNumber;
+            return $this->_headerImages[$pageId][$currentImageNumber];
+        } else {
+            return false;
+        }
+    }
+
+}
diff --git a/Toolkit/HeaderImages/IndexController.php b/Toolkit/HeaderImages/IndexController.php
new file mode 100644 (file)
index 0000000..2943c8d
--- /dev/null
@@ -0,0 +1,364 @@
+<?php
+
+/**
+ * Index.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_HeaderImages_IndexController
+ *
+ * Index Controller for the Admin section of Header Images Application.
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_HeaderImages_IndexController
+    extends Toolkit_BaseControllerAbstract
+       implements Toolkit_IController
+{
+    private $dbh;
+    private $page;
+    private $smarty;
+    private $navigation;
+
+    const LEVELS_DEEP = 5;
+
+    public function __construct(Toolkit_Registry $registry)
+    {
+        parent::__construct($registry);
+        $this->dbh = $registry->dbh;
+        $this->page = ($_SERVER['HTTPS'])
+            ? BASE_SECURE_URL . 'admin/headerImages.php'
+            : BASE_URL . 'admin/headerImages.php';
+        $this->_setSmarty();
+        $this->_setNavigation();
+    }
+
+    private function _setSmarty()
+    {
+        // smarty config settings
+        $this->smarty = new Toolkit_HeaderImages_Smarty(
+            $this->registry->appConfig->smarty->templateDir,
+            $this->registry->appConfig->smarty->compileDir,
+            $this->registry->appConfig->smarty->configDir,
+            $this->registry->appConfig->smarty->cacheDir
+        );
+    }
+
+    /**
+     * sort_by_parent
+     *
+     * @param  mixed  $data
+     * @access public
+     * @return void
+     */
+    private function _sort_by_parent($data)
+    {
+        if (!is_array($data)) {
+            return false;
+        }
+        foreach($data as $key=>$value) {
+            $data_new[$value["parent"]][$value["id"]] = $value;
+        }
+        return $data_new;
+    }
+
+    /**
+     * convertParent
+     *
+     * @param  mixed  $threads
+     * @param  mixed  $thread
+     * @access public
+     * @return void
+     */
+    private function _convertParent($threads, $thread)
+    {
+        static $select,$count;
+        if (!$count) {
+            $count = 0;
+        }
+        $bgcolor[] = '#ccc';
+        $bgcolor[] = '#ddd';
+        if (is_array($thread)) {
+            foreach($thread as $parent=>$value) {
+                $color = $bgcolor[$count];
+                $select[$value["id"]]["color"]    = $color;
+                $select[$value["id"]]["category"] = $value["navigation_name"];
+                $select[$value["id"]]["count"]    = $count;
+
+                if (isset($threads[$parent])) {
+                    $count++;
+                    $this->_convertParent($threads, $threads[$parent]);
+                }
+            }
+        }
+        $count--;
+        return $select;
+    }
+
+    private function _parentSelect($catid = null)
+    {
+        // select catid portion
+        $qs  = "
+          SELECT id,navigation_name,parent
+            FROM pages
+        ORDER BY parent,pos";
+
+        $data   = $this->dbh->query($qs)->fetchAll(PDO::FETCH_ASSOC);
+        $data1  = $this->_sort_by_parent($data);
+        $select = '<select name="page"><option value=""></option>';
+        $parts  = $this->_convertParent($data1, $data1[0]);
+        if (is_array($parts)) {
+            foreach($parts as $key => $value) {
+                if (isset($backcount) && $value['count'] <= $backcount) {
+                    unset($backcount);
+                }
+                if ($key == $id && $sel_name = "parent") {
+                    $backcount = $value['count'];
+                }
+
+                if (   (!isset($backcount)
+                        && ($value['count'] < (self::LEVELS_DEEP - 1))
+                    || $sel_name == "catid[]")
+                ) {
+                    $bkg     = $value["color"];
+                    $indent  = (int)$value["count"] * 10;
+                    $cc      = (int)$value["count"] * 2;
+                    $paddman = ($cc > 0) ? str_repeat("&nbsp;", $cc) : '';
+                    $select .= '<option value="' . $key . '"';
+                    if ($catid == $key) {
+                        $select .= ' selected';
+                    }
+                    $select .= ' style="background-color:' . $bkg . ';"';
+                    $select .= '>'.$paddman . $value["category"] . '</option>';
+                }
+            }
+        }
+        $select .= "</select>";
+        return $select;
+    }
+
+    private function _setNavigation()
+    {
+        $this->navigation = array(
+            array(
+                'href'  => $this->page,
+                'label' => 'Home'
+            ),
+            array(
+                'href'  => $this->page . '?ac=add',
+                'label' => 'Add Image'
+            )
+        );
+    }
+
+    public function indexAction()
+    {
+        $baseUrl
+            = ($_SERVER['HTTPS'] == 'on')
+            ? BASE_SECURE_URL
+            : BASE_URL;
+        $GLOBALS['styleSheets'][]
+            = $baseUrl . 'Toolkit/HeaderImages/Views/css/admin.css';
+
+        $pages = $this->_getMainLevelPages();
+        $this->smarty->assign('pages', $pages);
+        $this->smarty->assign('editUrl', $this->page . '?ac=add&id=');
+        $this->smarty->assign('imageBaseUrl', FILE_SERVER_URL . IS_OWNER_ID . '/headerImageThumb/');
+        $this->smarty->assign('glmNav', $this->navigation);
+        $addUrl = $this->registry->application->path
+            . '?ac=Add&page=';
+        $this->smarty->assign('addUrl', $addUrl);
+        return $this->smarty->fetch('Index/adminList.tpl');
+    }
+
+    public function addAction()
+    {
+        $id = filter_var($_REQUEST['id'], FILTER_VALIDATE_INT);
+        if ($_POST) {
+            if ($_FILES['image']['size']) {
+                $imageName = GLM_TOOLBOX::process_image('image');
+            } else {
+                $imageName = filter_var($_REQUEST['oldImage'], FILTER_SANITIZE_STRING);
+            }
+            $hasImage = (bool)$imageName;
+            if ($hasImage) {
+                if ($id) {
+                    $image = Toolkit_HeaderImages_Models_Image::fetchById(
+                        $this->registry->dbh, $id
+                    );
+                    if ($_REQUEST['Delete']) {
+                        $image->delete($this->dbh);
+                        header('Location: ' . $this->page);
+                        exit;
+                    }
+                    $image->setTitle(filter_var($_REQUEST['title'], FILTER_SANITIZE_STRING));
+                    $image->setSubtitle(filter_var($_REQUEST['subtitle'], FILTER_SANITIZE_STRING));
+                    $image->setImage($imageName);
+                    $image->setPage(filter_var($_REQUEST['page'], FILTER_VALIDATE_INT));
+                } else {
+                    $image = Toolkit_HeaderImages_Models_Image::createByValues(
+                        array(
+                            'page'     => filter_var($_REQUEST['page'], FILTER_VALIDATE_INT),
+                            'image'    => $imageName,
+                            'title'    => filter_var($_REQUEST['title'], FILTER_SANITIZE_STRING),
+                            'subtitle' => filter_var($_REQUEST['subtitle'], FILTER_SANITIZE_STRING)
+                        )
+                    );
+                }
+
+                $image->save($this->dbh);
+                header('Location: ' . $this->page);
+                exit;
+            } else {
+                $this->smarty->assign('error', true);
+            }
+        }
+        if ($id) {
+            $image = Toolkit_HeaderImages_Models_Image::fetchById(
+                $this->registry->dbh, $id
+            );
+        }
+        $this->smarty->assign('glmNav', $this->navigation);
+        $baseUrl
+            = ($_SERVER['HTTPS'] == 'on')
+            ? BASE_SECURE_URL
+            : BASE_URL;
+        $GLOBALS['styleSheets'][]
+            = $baseUrl . 'Toolkit/HeaderImages/Views/css/admin.css';
+
+        $formActionUrl = $this->registry->application->path
+            . '?ac=Add';
+        if ($image) {
+            $this->smarty->assign('imageBaseUrl', FILE_SERVER_URL . IS_OWNER_ID . '/headerImageThumb/');
+            $this->smarty->assign('image', $image);
+            $this->smarty->assign('title', $image->getTitle());
+            $this->smarty->assign('subtitle', $image->getSubtitle());
+            $this->smarty->assign('parentSelect', $this->_parentSelect($image->getPage()));
+        } else {
+            if ($_POST) {
+                $this->smarty->assign(
+                    'page',
+                    filter_var($_REQUEST['page'], FILTER_VALIDATE_INT)
+                );
+                $this->smarty->assign(
+                    'title',
+                    filter_var($_REQUEST['title'], FILTER_SANITIZE_STRING)
+                );
+                $this->smarty->assign(
+                    'subtitle',
+                    filter_var($_REQUEST['subtitle'], FILTER_SANITIZE_STRING)
+                );
+            }
+            if ($page = filter_var($_REQUEST['page'], FILTER_VALIDATE_INT)) {
+                $this->smarty->assign('parentSelect', $this->_parentSelect($page));
+            } else {
+                $this->smarty->assign('parentSelect', $this->_parentSelect());
+            }
+            $this->smarty->assign('image', null);
+
+        }
+        $this->smarty->assign('formAction', $formActionUrl);
+        return $this->smarty->fetch('Index/editImage.tpl');
+    }
+
+    private function _getMainLevelPages()
+    {
+        $pages = Toolkit_HeaderImages_Models_Page::fetchMainPages(
+            $this->registry->dbh
+        );
+        if (!empty($pages)) {
+            foreach ($pages as $page) {
+                $page->getImagesForPage($this->registry->dbh);
+            }
+        }
+        $pages = $this->reGroupPages($pages);
+//        echo '<pre>'.print_r($pages, true).'</pre>';exit;
+        return $pages;
+    }
+
+    private function getSubCategories($pageId)
+    {
+        $tree = Toolkit_Common::getHierarchicalTreeStructure(
+            $this->dbh,
+            'pages',
+            'id',
+            'parent',
+            'pos',
+            $pageId
+        );
+        if ($tree) {
+            return array_keys($tree);
+        } else {
+            return array();
+        }
+    }
+
+    private function reGroupPages($pages)
+    {
+        if (!is_array($pages)) {
+            return false;
+        }
+        $pagesSorted = array_reverse($pages, true);
+        foreach ($pages as $pageId => $page) {
+            $subCats = $this->getSubCategories($pageId);
+            if (!empty($subCats)) {
+                foreach ($subCats as $catId) {
+                    if ($pagesSorted[$catId]) {
+                        $pagesSorted[$pageId]->addSubPage($pagesSorted[$catId]);
+                        unset($pagesSorted[$catId]);
+                    }
+                }
+            }
+        }
+        $pagesSorted = array_reverse($pagesSorted, true);
+        return $pagesSorted;
+    }
+
+    public function moveImagesAction()
+    {
+        $values = filter_var_array(
+            $_REQUEST,
+            array(
+                'images' => array(
+                    'filter' => FILTER_VALIDATE_INT,
+                    'flags'  => FILTER_FORCE_ARRAY
+                )
+            )
+        );
+        extract($values);
+        try {
+            $sql = "
+            UPDATE headers.images
+               SET pos = :pos
+             WHERE id = :id";
+            $resetPos = $this->dbh->prepare($sql);
+            $pos = 1;
+            foreach ($images as $imageId) {
+                $resetPos->bindParam(':id', $imageId, PDO::PARAM_INT);
+                $resetPos->bindParam(':pos', $pos, PDO::PARAM_INT);
+                $resetPos->execute();
+                ++$pos;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        exit;
+    }
+
+}
diff --git a/Toolkit/HeaderImages/Models/Image.php b/Toolkit/HeaderImages/Models/Image.php
new file mode 100644 (file)
index 0000000..99eddb4
--- /dev/null
@@ -0,0 +1,250 @@
+<?php
+
+/**
+ * Image.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_HeaderImages_Models_Image
+ *
+ * Model Class for the creation of Image objects
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_HeaderImages_Models_Image
+{
+    private $_id;
+    private $_title;
+    private $_subtitle;
+    private $_image;
+    private $_page;
+    private $_pos;
+
+    private function __construct($values)
+    {
+        extract($values);
+        $this->setId($id)
+            ->setImage($image)
+            ->setPage($page)
+            ->setPos($pos)
+            ->setSubtitle($subtitle)
+            ->setTitle($title);
+    }
+
+    static public function createByValues($values)
+    {
+        if (!is_array($values) || empty($values)) {
+            return false;
+        }
+        return new Toolkit_HeaderImages_Models_Image($values);
+    }
+
+    static public function fetchById(PDO $dbh, $imageId)
+    {
+        try {
+            $sql = "
+            SELECT *
+              FROM headers.images
+             WHERE id = :id
+            ORDER BY pos";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':id', $imageId, PDO::PARAM_INT);
+            $stmt->execute();
+            while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if ($values) {
+                    return Toolkit_HeaderImages_Models_Image::createByValues(
+                            $values
+                        );
+                }
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return false;
+    }
+
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    public function getTitle()
+    {
+        return $this->_title;
+    }
+
+    public function getSubtitle()
+    {
+        return $this->_subtitle;
+    }
+
+    public function getImage()
+    {
+        return $this->_image;
+    }
+
+    public function getPage()
+    {
+        return $this->_page;
+    }
+
+    public function getPos()
+    {
+        return $this->_pos;
+    }
+
+    public function setId($id)
+    {
+        $this->_id = $id;
+        return $this;
+    }
+
+    public function setTitle($title)
+    {
+        $this->_title = $title;
+        return $this;
+    }
+
+    public function setSubtitle($subtitle)
+    {
+        $this->_subtitle = $subtitle;
+        return $this;
+    }
+
+    public function setImage($image)
+    {
+        $this->_image = $image;
+        return $this;
+    }
+
+    public function setPage($page)
+    {
+        $this->_page = $page;
+        return $this;
+    }
+
+    public function setPos($pos)
+    {
+        $this->_pos = $pos;
+        return $this;
+    }
+    public function getMaxPosForPage(PDO $dbh)
+    {
+        try {
+            $sql = "
+            SELECT coalesce( max(pos) + 1, 1)
+              FROM headers.images
+             WHERE page = :page";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':page', $this->getPage(), PDO::PARAM_INT);
+            $stmt->execute();
+            return $stmt->fetchColumn();
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+
+    }
+
+    public function delete(PDO $dbh)
+    {
+        try {
+            $sql = "
+            DELETE
+              FROM headers.images
+             WHERE id = :id";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':id', $this->getId(), PDO::PARAM_INT);
+            $stmt->execute();
+            $sql = "
+            UPDATE headers.images
+               SET pos = :pos
+             WHERE id = :id";
+            $updatePos = $dbh->prepare($sql);
+            $sql = "
+              SELECT id
+                FROM headers.images
+               WHERE page = :page
+            ORDER BY pos";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':page', $this->getPage(), PDO::PARAM_INT);
+            $stmt->execute();
+            $pos = 1;
+            while ($image = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                $updatePos->bindParam(':pos', $pos, PDO::PARAM_INT);
+                $updatePos->bindParam(':id', $image['id'], PDO::PARAM_INT);
+                $updatePos->execute();
+                ++$pos;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+    public function save(PDO $dbh)
+    {
+        try {
+            if ($this->getId()) {
+                $sql = "
+                UPDATE headers.images
+                   SET title = :title,
+                       subtitle = :subtitle,
+                       image = :image,
+                       page = :page,
+                       pos = :pos
+                 WHERE id = :id";
+            } else {
+                $sql = "
+                INSERT INTO headers.images
+                (title, subtitle, image, page, pos)
+                VALUES
+                (:title, :subtitle, :image, :page, :pos)
+                RETURNING id";
+            }
+
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':title', $this->getTitle());
+            $stmt->bindParam(':subtitle', $this->getSubtitle());
+            $stmt->bindParam(':image', $this->getImage());
+            $stmt->bindParam(':page', $this->getPage(), PDO::PARAM_INT);
+            if (!$this->getId()) {
+                $stmt->bindParam(':pos', $this->getMaxPosForPage($dbh));
+            } else {
+                $stmt->bindParam(':pos', $this->getPos());
+            }
+
+            if ($this->getId()) {
+                $stmt->bindParam(':id', $this->getId(), PDO::PARAM_INT);
+            }
+            $stmt->execute();
+
+            if (!$this->getId()) {
+                $this->setId($stmt->fetchColumn());
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+
+        return $this;
+    }
+
+    function __toString()
+    {
+        return '<img src="'.$this->getImage().'">';
+    }
+}
diff --git a/Toolkit/HeaderImages/Models/Page.php b/Toolkit/HeaderImages/Models/Page.php
new file mode 100644 (file)
index 0000000..1da3c57
--- /dev/null
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * Pages.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+
+/**
+ * Toolkit_Package_Pages
+ *
+ * Description of Pages
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_HeaderImages_Models_Page
+{
+    private $_id;
+    private $_navigationName;
+    private $_pos;
+    private $_images = array();
+    private $_subPages = array();
+
+    private function __construct($values)
+    {
+        extract($values);
+        $this->setId($id)
+            ->setNavigationName($navigation_name)
+            ->setPos($pos);
+    }
+
+    static public function createByValues($values)
+    {
+        if (!is_array($values) || empty($values)) {
+            return false;
+        }
+        return new Toolkit_HeaderImages_Models_Page($values);
+    }
+
+    static public function fetchPageById(PDO $dbh, $page)
+    {
+        try {
+            $sql = "
+              SELECT id, navigation_name, pos
+                FROM pages
+               WHERE id = :id
+            ORDER BY pos";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':id', $page, PDO::PARAM_INT);
+            $stmt->execute();
+            $values = $stmt->fetch(PDO::FETCH_ASSOC);
+            if ($values) {
+                return Toolkit_HeaderImages_Models_Page::createByValues($values);
+            } else {
+                return false;
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return false;
+    }
+
+    static public function fetchMainPages(PDO $dbh)
+    {
+        $pages = array();
+        try {
+            $sql = "
+            SELECT id, navigation_name, pos
+              FROM pages
+             WHERE id IN (SELECT DISTINCT page
+                            FROM headers.images)
+            ORDER BY parent,pos";
+            $stmt = $dbh->query($sql);
+            while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if ($values) {
+                    $pages[$values['id']]
+                        = Toolkit_HeaderImages_Models_Page::createByValues(
+                            $values
+                        );
+                }
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+        return $pages;
+    }
+
+    public function getId()
+    {
+        return $this->_id;
+    }
+
+    public function getNavigationName()
+    {
+        return $this->_navigationName;
+    }
+
+    public function getPos()
+    {
+        return $this->_pos;
+    }
+
+    public function getImages()
+    {
+        return $this->_images;
+    }
+
+
+    public function setId($id)
+    {
+        $this->_id = $id;
+        return $this;
+    }
+
+    public function setNavigationName($navigationName)
+    {
+        $this->_navigationName = $navigationName;
+        return $this;
+    }
+
+    public function setPos($pos)
+    {
+        $this->_pos = $pos;
+        return $this;
+    }
+
+    public function addSubPage(Toolkit_HeaderImages_Models_Page $subPage)
+    {
+        $this->_subPages[] = $subPage;
+    }
+
+    public function getSubPages()
+    {
+        return $this->_subPages;
+    }
+
+    public function hasSubPages()
+    {
+        return !empty($this->_subPages);
+    }
+
+    public function getImagesForPage(PDO $dbh)
+    {
+        try {
+            $sql = "
+            SELECT *
+              FROM headers.images
+             WHERE page = :page
+            ORDER BY pos";
+            $stmt = $dbh->prepare($sql);
+            $stmt->bindParam(':page', $this->getId(), PDO::PARAM_INT);
+            $stmt->execute();
+            while ($values = $stmt->fetch(PDO::FETCH_ASSOC)) {
+                if ($values) {
+                    $this->_images[]
+                        = Toolkit_HeaderImages_Models_Image::createByValues(
+                            $values
+                        );
+                }
+            }
+        } catch (PDOException $e) {
+            Toolkit_Common::handleError($e);
+        }
+    }
+
+}
diff --git a/Toolkit/HeaderImages/Smarty.php b/Toolkit/HeaderImages/Smarty.php
new file mode 100644 (file)
index 0000000..983f99d
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Smarty.php
+ *
+ * PHP version 5.3
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @version   SVN: (0.1)
+ * @link      <>
+ */
+if (!defined('SMARTY_DIR')) {
+    define('SMARTY_DIR', '/var/www/server/CommonApps/Smarty/3.1/');
+}
+require_once SMARTY_DIR . 'Smarty.class.php';
+/**
+ * Toolkit_HeaderImages_Smarty
+ *
+ * Smarty Class Extension
+ *
+ * @category  Toolkit
+ * @package   Package
+ * @author    Steve Sutton <steve@gaslightmedia.com>
+ * @copyright 2013 Gaslight Media
+ * @license   Gaslight Media
+ * @release   Release: (0.1)
+ * @link      <>
+ */
+class Toolkit_HeaderImages_Smarty
+    extends Smarty
+{
+
+    function __construct(
+        $templateDir,
+        $compileDir,
+        $configDir,
+        $cacheDir
+    ) {
+        parent::__construct();
+
+        $this->setTemplateDir($templateDir);
+        $this->setCompileDir($compileDir);
+        $this->setConfigDir($configDir);
+        $this->setCacheDir($cacheDir);
+    }
+
+}
diff --git a/Toolkit/HeaderImages/Views/Index/adminList.tpl b/Toolkit/HeaderImages/Views/Index/adminList.tpl
new file mode 100644 (file)
index 0000000..8e1e42c
--- /dev/null
@@ -0,0 +1,82 @@
+{include file='Index/nav.tpl'}
+ <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
+<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
+<div id="adminList">
+    <ul>
+{foreach $pages as $page}
+    <li>
+        <hgroup>
+            <h1>{$page->getNavigationName()}</h1>
+            <h2><a href="{$addUrl}{$page->getId()}">Add</a></h2>
+        </hgroup>
+        <form class="pageGroup" method="get">
+            <input type="hidden" name="ac" value="moveImages">
+            <input type="hidden" name="page" value="{$page->getId()}">
+            {foreach $page->getImages() as $image}
+                <div class="imageBlock" id="image_{$image->getId()}">
+                    <input type="hidden" name="images[]" value="{$image->getId()}">
+                    <a href="{$editUrl}{$image->getId()}">
+                    <img src="{$imageBaseUrl}{$image->getImage()}" id="image_{$image->getId()}">
+                    </a>
+                </div>
+            {/foreach}
+        </form>
+        {if $page->hasSubPages()}
+            <ul>
+            {$subPages=$page->getSubPages()}
+            {foreach $subPages as $subPage}
+                <li>
+                <hgroup>
+                    <h1>{$subPage->getNavigationName()}</h1>
+                    <h2><a href="{$addUrl}{$subPage->getId()}">Add</a></h2>
+                </hgroup>
+                <form class="pageGroup" method="get">
+                    <input type="hidden" name="ac" value="moveImages">
+                    <input type="hidden" name="page" value="{$subPage->getId()}">
+                    {foreach $subPage->getImages() as $image}
+                        <div class="imageBlock" id="image_{$image->getId()}">
+                            <input type="hidden" name="images[]" value="{$image->getId()}">
+                            <a href="{$editUrl}{$image->getId()}">
+                            <img src="{$imageBaseUrl}{$image->getImage()}" id="image_{$image->getId()}">
+                            </a>
+                        </div>
+                    {/foreach}
+                </form>
+                </li>
+            {/foreach}
+            </ul>
+        {/if}
+    </li>
+{/foreach}
+    </ul>
+</div>
+<script>
+    $(function(){
+        $(".pageGroup").sortable({
+            update: function() {
+                var inputs = $(this).serialize();
+                $.get('./headerImages.php', inputs); //, console.log('positions saved')
+            }
+        });
+               
+               /* Setup Show/Hide */
+               $('#adminList hgroup h1').each(function(i) {
+                       //console.log(i);
+                       $(this).parent('hgroup').siblings('form').css('display', 'none');
+                       $(this).siblings('h2').css('display', 'none');
+               });
+               
+               /* Show/Hide Click Hander */
+               $('#adminList hgroup h1').click(function() {
+                       if($(this).parent('hgroup').siblings('form').css('display') == "none") {
+                               $(this).parent('hgroup').siblings('form').css('display', 'block');
+                               $(this).siblings('h2').css('display', 'block');
+                               $(this).css('background', 'url(../assets/arrow_up.png) 100% 50% no-repeat');
+                       } else {
+                               $(this).parent('hgroup').siblings('form').css('display', 'none');
+                               $(this).siblings('h2').css('display', 'none');
+                               $(this).css('background', 'url(../assets/arrow_down.png) 100% 50% no-repeat');
+                       }
+               });
+    });
+</script>
diff --git a/Toolkit/HeaderImages/Views/Index/editImage.tpl b/Toolkit/HeaderImages/Views/Index/editImage.tpl
new file mode 100644 (file)
index 0000000..a77d97a
--- /dev/null
@@ -0,0 +1,60 @@
+{include file='Index/nav.tpl'}
+{if $error}
+    <div class="glmFormError">No image uploaded!</div>
+{/if}
+<form
+    enctype="multipart/form-data"
+    method="post"
+    action="{$formAction}">
+    {if $image}
+        <input type="hidden" name="id" value="{$image->getId()}">
+        <input type="hidden" name="oldImage" value="{$image->getImage()}">
+    {/if}
+
+<table id="admin-edit-table" style="margin-top: 20px;">
+    <tr>
+        <td class="navtd" nowrap align="right">Page:</td>
+        <td class="navtd2">
+            {$parentSelect}
+        </td>
+    </tr>
+    <tr>
+        <td class="navtd" nowrap align="right">Title:</td>
+        <td class="navtd2">
+            <input type="text" name="title" value="{$title}">
+        </td>
+    </tr>
+    <tr>
+        <td class="navtd" nowrap align="right">Sub Title:</td>
+        <td class="navtd2">
+            <input type="text" name="subtitle" value="{$subtitle}">
+        </td>
+    </tr>
+    {if $image}
+    <tr>
+        <td class="navtd" nowrap align="right">Current Image:</td>
+        <td class="navtd2">
+            <img src="{$imageBaseUrl}{$image->getImage()}">
+        </td>
+    </tr>
+    {/if}
+    <tr>
+        <td class="navtd" nowrap align="right">Image:</td>
+        <td class="navtd2">
+            <input type="file" name="image">
+        </td>
+    </tr>
+    <tr>
+        <td nowrap align="center" colspan="2">
+            <input type="submit" value="Save">
+            {if $image}
+                <input
+                    type="submit"
+                    name="Delete"
+                    value="Delete"
+                    onclick="return confirm('This cannot be undone.\nAre you sure?');">
+            {/if}
+        </td>
+    </tr>
+    </table>
+</form>
\ No newline at end of file
diff --git a/Toolkit/HeaderImages/Views/Index/nav.tpl b/Toolkit/HeaderImages/Views/Index/nav.tpl
new file mode 100644 (file)
index 0000000..44d4368
--- /dev/null
@@ -0,0 +1,5 @@
+<ul class="admin_nav">
+    {foreach $glmNav as $nav}
+    <li><a href="{$nav['href']}">{$nav['label']}</a></li>
+    {/foreach}
+</ul>
\ No newline at end of file
diff --git a/Toolkit/HeaderImages/Views/css/admin.css b/Toolkit/HeaderImages/Views/css/admin.css
new file mode 100644 (file)
index 0000000..ce34040
--- /dev/null
@@ -0,0 +1,88 @@
+#adminList {
+       display: block;
+       width: 100%;
+       overflow: hidden;
+}
+#adminList ul {
+       display: block;
+       width: 98%;
+       margin: 10px 2% 10px 0;
+       overflow: hidden;
+       /*background: rgba(0,0,0,0.1);*/
+       padding: 0 10px 0 0px;
+       list-style-type: none;
+}
+#adminList ul li {
+       display: block;
+       width: 98%;
+       margin: 10px 2% 10px 0;
+       overflow: hidden;
+       background: #F5F5F5;
+       background: rgba(0,0,0,0.05);
+       border: 1px solid #AAA;
+       padding: 5px 10px;
+       list-style-type: none;
+}
+#adminList ul li hgroup {
+       display: block;
+       width: 100%;
+       overflow: hidden;
+       height: auto;
+}
+div.pageGroup {
+    margin:5px;
+    background-color: #eaeaea;
+    height: 200px;
+    width:100%;
+    overflow: scroll;
+}
+#adminList hgroup h1 {
+    float: left;
+       display: block;
+       margin: 0;
+       padding: 0 16px 0 0;
+       font-weight: normal;
+       background: url(../../assets/arrow_down.png) 100% 50% no-repeat;
+       cursor: pointer;
+}
+#adminList hgroup h2
+{
+    width:100px;
+    float:right;
+       margin: 0;
+}
+#adminList hgroup a {
+       display: block;
+       position: relative;
+       width: 82px;
+       height: 16px;
+       background: url(../../assets/btn_add_sm.gif) 0 0 no-repeat;
+       border: none;
+       font-size: 12px;
+       padding: 6px;
+       text-align: center;
+       text-decoration: none;
+       color: #000;
+}
+#adminList hgroup a:hover {
+       background-position: 0 -28px;
+       color: #0099FF
+}
+div.imageBlock {
+    background-color: #f90;
+    float: left;
+    margin: 2px;
+    padding:0;
+    width:200px;
+    height:100px;
+}
+div.glmFormError {
+    width:200px;
+    height: 30px;
+    background-color: firebrick;
+    color: white;
+    font-size: larger;
+    font-weight: bold;
+    padding: 15px;
+    border-color: black;
+}
\ No newline at end of file
diff --git a/Toolkit/HeaderImages/application.ini b/Toolkit/HeaderImages/application.ini
new file mode 100644 (file)
index 0000000..34cfa03
--- /dev/null
@@ -0,0 +1,31 @@
+; Production server configuration data
+[production]
+application.name    = "Header Images"
+application.path    = BASE_URL "admin/headerImages.php"
+application.setPath = "Toolkit/HeaderImages"
+
+; router config
+router.path        = BASE "Toolkit/HeaderImages"
+router.application = "HeaderImages"
+
+; smarty settings
+smarty.templateDir = BASE "Toolkit/HeaderImages/Views/"
+smarty.compileDir  = BASE "Toolkit/HeaderImages/Smarty/compiled/"
+smarty.configDir   = BASE "Toolkit/HeaderImages/Smarty/Configs/"
+smarty.cacheDir    = BASE "Toolkit/HeaderImages/Smarty/cache/"
+
+; 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]
\ No newline at end of file
diff --git a/Toolkit/HeaderImages/assets/arrow_down.png b/Toolkit/HeaderImages/assets/arrow_down.png
new file mode 100644 (file)
index 0000000..856bc1b
Binary files /dev/null and b/Toolkit/HeaderImages/assets/arrow_down.png differ
diff --git a/Toolkit/HeaderImages/assets/arrow_up.png b/Toolkit/HeaderImages/assets/arrow_up.png
new file mode 100644 (file)
index 0000000..c9837af
Binary files /dev/null and b/Toolkit/HeaderImages/assets/arrow_up.png differ
diff --git a/Toolkit/HeaderImages/assets/btn_add.gif b/Toolkit/HeaderImages/assets/btn_add.gif
new file mode 100644 (file)
index 0000000..7ca35fb
Binary files /dev/null and b/Toolkit/HeaderImages/assets/btn_add.gif differ
diff --git a/Toolkit/HeaderImages/assets/btn_add_sm.gif b/Toolkit/HeaderImages/assets/btn_add_sm.gif
new file mode 100644 (file)
index 0000000..50994dc
Binary files /dev/null and b/Toolkit/HeaderImages/assets/btn_add_sm.gif differ
diff --git a/Toolkit/HeaderImages/index.php b/Toolkit/HeaderImages/index.php
new file mode 100644 (file)
index 0000000..2acdf68
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+/*
+ * blank index.php page for preventing default dir listings
+ */
+
diff --git a/admin/headerImages.php b/admin/headerImages.php
new file mode 100644 (file)
index 0000000..fcaacd4
--- /dev/null
@@ -0,0 +1,39 @@
+<?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/HeaderImages/application.ini',
+    strtolower($_ENV['GLM_HOST_ID'])
+);
+// 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();
index 2f5d44e..cca2408 100644 (file)
@@ -74,6 +74,11 @@ if (defined('ROTATING_IMAGES') && ROTATING_IMAGES) {
         $nav[$app['name']] = MEDIA_BASE_URL . 'admin/rotatingImages.php?app=' . $app['id'];
     }
 }
+$headerImagesConfig = new Zend_Config_Ini(
+    BASE . 'Toolkit/HeaderImages/application.ini',
+    strtolower($_ENV['GLM_HOST_ID'])
+);
+$nav[$headerImagesConfig->application->name] = BASE_URL.'admin/headerImages.php';
 if (defined('SEASONS') && SEASONS) {
     $seasonConfig = new Zend_Config_Ini(
         BASE . 'Toolkit/Seasons/application.ini',