From 61e1880d0b49df6bbbed69634505c69f023ae336 Mon Sep 17 00:00:00 2001
From: Henning Leutz <leutz@pcsg.de>
Date: Mon, 5 Jan 2015 21:03:03 +0100
Subject: [PATCH] blocks -> verwaltung, anlegen, editieren, controls integriert

---
 ajax/project/getAreas.php  |   9 +-
 bin/BlockAreas.js          |   7 +-
 bin/BlockEdit.js           |  32 +++++--
 bin/Manager.js             |  15 ++-
 bin/Site/Area.css          |  40 ++++++++
 bin/Site/Area.js           | 185 +++++++++++++++++++++++++++++++++++++
 bin/Site/Category.css      |   7 ++
 bin/Site/Category.js       | 165 +++++++++++++++++++++++++++++++++
 blocks.xml                 |  24 +++++
 lib/QUI/Blocks/Block.php   |   2 +-
 lib/QUI/Blocks/Manager.php |  29 +++++-
 lib/QUI/Blocks/Utils.php   |  16 +++-
 locale.xml                 |  30 +++++-
 site.xml                   |  18 ++++
 14 files changed, 555 insertions(+), 24 deletions(-)
 create mode 100644 bin/Site/Area.css
 create mode 100644 bin/Site/Area.js
 create mode 100644 bin/Site/Category.css
 create mode 100644 bin/Site/Category.js
 create mode 100644 blocks.xml
 create mode 100644 site.xml

diff --git a/ajax/project/getAreas.php b/ajax/project/getAreas.php
index 798396e..08c33a8 100644
--- a/ajax/project/getAreas.php
+++ b/ajax/project/getAreas.php
@@ -7,19 +7,20 @@
 /**
  * Returns the feed list
  *
- * @param string $project - json array, Project Data
+ * @param string $project  - json array, Project Data
+ * @param string $siteType - siteType
  * @return array
  */
-function package_quiqqer_blocks_ajax_project_getAreas($project)
+function package_quiqqer_blocks_ajax_project_getAreas($project, $siteType)
 {
     $Project      = QUI::getProjectManager()->decode( $project );
     $BlockManager = new QUI\Blocks\Manager();
 
-    return $BlockManager->getAreasByProject( $Project );
+    return $BlockManager->getAreasByProject( $Project, $siteType );
 }
 
 QUI::$Ajax->register(
     'package_quiqqer_blocks_ajax_project_getAreas',
-    array( 'project' ),
+    array( 'project', 'siteType' ),
     'Permission::checkAdminUser'
 );
diff --git a/bin/BlockAreas.js b/bin/BlockAreas.js
index 8c3e05d..9dc1850 100644
--- a/bin/BlockAreas.js
+++ b/bin/BlockAreas.js
@@ -98,8 +98,11 @@ define('package/quiqqer/blocks/bin/BlockAreas', [
 
             if ( areas )
             {
-                areas.map(function(area) {
-                    self.addArea( area );
+                areas.map(function(area)
+                {
+                    if ( area !== '' ) {
+                        self.addArea( area );
+                    }
                 });
             }
 
diff --git a/bin/BlockEdit.js b/bin/BlockEdit.js
index 0bba86a..4d08a71 100644
--- a/bin/BlockEdit.js
+++ b/bin/BlockEdit.js
@@ -131,7 +131,7 @@ define('package/quiqqer/blocks/bin/BlockEdit', [
                          '</label>'
             }).inject( this.$Elm );
 
-            var i, len, title;
+            var i, len, title, group, val;
 
             var Type  = this.$Elm.getElement( '[name="type"]'),
                 Title = this.$Elm.getElement( '[name="title"]' );
@@ -140,19 +140,35 @@ define('package/quiqqer/blocks/bin/BlockEdit', [
             {
                 title = this.$availableBlocks[ i ].title;
 
+                if ( 'group' in title )
+                {
+                    group = title.group;
+                    val   = title.var;
+                } else
+                {
+                    group = title[ 0 ];
+                    val   = title[ 1 ];
+                }
+
+
                 new Element('option', {
                     value : this.$availableBlocks[ i ].control,
-                    html  : QUILocale.get( title[ 0 ], title[ 1 ] )
+                    html  : QUILocale.get( group, val )
                 }).inject( Type );
             }
 
             Title.value = this.getAttribute( 'title' );
             Type.value  = this.getAttribute( 'type' );
 
-            var areas = this.getAttribute( 'areas' )
-                            .replace( /^,*/, '' )
-                            .replace( /,*$/, '' )
-                            .split( ',' );
+            var areas = [];
+
+            if ( this.getAttribute( 'areas' ) )
+            {
+                areas = this.getAttribute('areas')
+                    .replace(/^,*/, '')
+                    .replace(/,*$/, '')
+                    .split(',');
+            }
 
             // areas
             this.$Areas = new BlockAreas({
@@ -208,6 +224,10 @@ define('package/quiqqer/blocks/bin/BlockEdit', [
 
             // plugin / package blocks
 
+            if ( typeof callback === 'function' ) {
+                callback();
+            }
+
         },
 
         /**
diff --git a/bin/Manager.js b/bin/Manager.js
index 1ba2c3f..ed0c891 100644
--- a/bin/Manager.js
+++ b/bin/Manager.js
@@ -245,7 +245,7 @@ define('package/quiqqer/blocks/bin/Manager', [
                                 return;
                             }
 
-                            var i, len, title;
+                            var i, len, group, title, val;
                             var Select = Body.getElement( 'select'),
                                 Title  = Body.getElement( '[name="title"]');
 
@@ -253,9 +253,19 @@ define('package/quiqqer/blocks/bin/Manager', [
                             {
                                 title = blocklist[ i ].title;
 
+                                if ( 'group' in title )
+                                {
+                                    group = title.group;
+                                    val   = title.var;
+                                } else
+                                {
+                                    group = title[ 0 ];
+                                    val   = title[ 1 ];
+                                }
+
                                 new Element('option', {
                                     value : blocklist[ i ].control,
-                                    html  : QUILocale.get( title[ 0 ], title[ 1 ] )
+                                    html  : QUILocale.get( group, val )
                                 }).inject( Select );
                             }
 
@@ -303,6 +313,7 @@ define('package/quiqqer/blocks/bin/Manager', [
             this.Loader.show();
 
             var Block;
+
             var self  = this,
                 Sheet = this.createSheet({
                     title : 'Block editieren'
diff --git a/bin/Site/Area.css b/bin/Site/Area.css
new file mode 100644
index 0000000..b1df4e2
--- /dev/null
+++ b/bin/Site/Area.css
@@ -0,0 +1,40 @@
+
+.quiqqer-blocks-site-category-area {
+    float: left;
+    margin-bottom: 20px;
+    position: relative;
+    width: 100%;
+}
+
+.quiqqer-blocks-site-category-area-title {
+    background: #dedede;
+    color: #212527;
+    padding: 10px;
+}
+
+.quiqqer-blocks-site-category-area-block {
+    border-bottom: 1px solid #dedede;
+    clear: both;
+    float: left;
+    width: 100%;
+}
+
+.quiqqer-blocks-site-category-area-buttons {
+    position: absolute;
+    right: 4px;
+    top: 4px;
+}
+
+.quiqqer-blocks-site-category-area-block select {
+    margin: 2px;
+    padding: 2px;
+    width: calc( 100% - 40px );
+}
+
+.quiqqer-blocks-site-category-area-block button {
+    float: right;
+    line-height: 14px;
+    margin: 2px;
+    padding: 5px;
+    width: 30px;
+}
\ No newline at end of file
diff --git a/bin/Site/Area.js b/bin/Site/Area.js
new file mode 100644
index 0000000..998f8ae
--- /dev/null
+++ b/bin/Site/Area.js
@@ -0,0 +1,185 @@
+/**
+ * Area edit control for the site object
+ *
+ * @module package/quiqqer/blocks/bin/Site/Area
+ * @author www.pcsg.de (Henning Leutz)
+ */
+
+define('package/quiqqer/blocks/bin/Site/Area', [
+
+    'qui/QUI',
+    'qui/controls/Control',
+    'qui/controls/buttons/Button',
+    'Locale',
+    'Ajax',
+
+    'css!package/quiqqer/blocks/bin/Site/Area'
+
+], function (QUI, QUIControl, QUIButton, QUILocale, QUIAjax)
+{
+    "use strict";
+
+    return new Class({
+
+        Extends : QUIControl,
+        Type    : 'package/quiqqer/blocks/bin/Site/Area',
+
+        Binds : [
+            'addBlock',
+            '$onInject'
+        ],
+
+        options : {
+            name        : '',
+            description : '',
+            title       : {},
+            Site        : false
+        },
+
+        initialize: function (options)
+        {
+            this.parent( options );
+
+            this.$AddButton       = false;
+            this.$availableBlocks = [];
+            this.$loaded          = false;
+            this.$blockIds        = [];
+
+            this.addEvents({
+                onInject : this.$onInject
+            });
+        },
+
+        /**
+         * Return the domnode element
+         * @return {Element}
+         */
+        create: function ()
+        {
+            var title = this.getAttribute( 'title' );
+
+            this.$Elm = new Element('div', {
+                'class' : 'quiqqer-blocks-site-category-area',
+                html    : '<div class="quiqqer-blocks-site-category-area-title">'+
+                              QUILocale.get( title.group, title.var ) +
+                          '   <div class="quiqqer-blocks-site-category-area-buttons"></div>' +
+                          '</div>',
+                'data-name' : this.getAttribute( 'name' )
+            });
+
+            var Buttons = this.$Elm.getElement(
+                '.quiqqer-blocks-site-category-area-buttons'
+            );
+
+            this.$AddButton = new QUIButton({
+                text      : 'Block hinzufügen',
+                textimage : 'icon-plus',
+                disable   : true,
+                events    : {
+                    onClick : this.addBlock
+                }
+            }).inject( Buttons );
+
+            return this.$Elm;
+        },
+
+        /**
+         * event : on inject
+         */
+        $onInject : function()
+        {
+            var self    = this,
+                Site    = this.getAttribute( 'Site'),
+                Project = Site.getProject();
+
+            QUIAjax.get('package_quiqqer_blocks_ajax_project_getBlocks', function(blocks)
+            {
+                self.$AddButton.enable();
+
+                self.$availableBlocks = blocks;
+                self.$loaded = true;
+
+                self.$blockIds.each(function(blockId) {
+                    self.addBlockById( blockId );
+                });
+
+            }, {
+                'package' : 'quiqqer/blocks',
+                project   : Project.encode()
+            });
+        },
+
+        /**
+         * Return the block list
+         * @returns {array}
+         */
+        getData : function()
+        {
+            return this.$Elm.getElements('select').map(function(Select) {
+                return Select.value;
+            });
+        },
+
+        /**
+         * Add a block by its ID
+         *
+         * @param blockId
+         */
+        addBlockById : function(blockId)
+        {
+            if ( !this.$loaded )
+            {
+                this.$blockIds.push( blockId );
+                return;
+            }
+
+            var found = this.$availableBlocks.filter(function(Item) {
+                return Item.id === blockId;
+            });
+
+            if ( !found.length ) {
+                return;
+            }
+
+            this.addBlock().getElement( 'select').set( 'value', blockId );
+        },
+
+        /**
+         * Add a block selection to the area
+         */
+        addBlock : function()
+        {
+            var i, len, Select;
+
+            var Elm = new Element('div', {
+                'class' : 'quiqqer-blocks-site-category-area-block',
+                html    : '<select></select>'
+            });
+
+            Elm.inject( this.$Elm );
+            Select = Elm.getElement( 'select' );
+
+            new QUIButton({
+                title  : 'Block löschen',
+                icon   : 'icon-remove-circle',
+                events :
+                {
+                    onClick : function() {
+                        Elm.destroy();
+                    }
+                }
+            }).inject( Elm );
+
+
+            for ( i = 0, len = this.$availableBlocks.length; i < len; i++ )
+            {
+                new Element('option', {
+                    html  : this.$availableBlocks[ i ].title,
+                    value : this.$availableBlocks[ i ].id
+                }).inject( Select );
+            }
+
+            return Elm;
+        }
+    });
+});
diff --git a/bin/Site/Category.css b/bin/Site/Category.css
new file mode 100644
index 0000000..673ffb0
--- /dev/null
+++ b/bin/Site/Category.css
@@ -0,0 +1,7 @@
+
+.quiqqer-blocks-site-category {
+    float: left;
+    height: 100%;
+    position: relative;
+    width: 100%;
+}
diff --git a/bin/Site/Category.js b/bin/Site/Category.js
new file mode 100644
index 0000000..9cb70d2
--- /dev/null
+++ b/bin/Site/Category.js
@@ -0,0 +1,165 @@
+
+/**
+ * Area manager for the site object
+ *
+ * @module package/quiqqer/blocks/bin/Site/Category
+ * @author www.pcsg.de (Henning Leutz)
+ *
+ * @event onLoaded
+ */
+
+define('package/quiqqer/blocks/bin/Site/Category', [
+
+    'qui/QUI',
+    'qui/controls/Control',
+    'qui/controls/loader/Loader',
+    'Ajax',
+    'Locale',
+    'package/quiqqer/blocks/bin/Site/Area',
+
+    'css!package/quiqqer/blocks/bin/Site/Category.css'
+
+], function (QUI, QUIControl, QUILoader, QUIAjax, QUILocale, Area)
+{
+    "use strict";
+
+    return new Class({
+
+        Extends : QUIControl,
+        Type    : 'package/quiqqer/blocks/bin/Site/Category',
+
+        Binds : [
+            '$onInject',
+            '$onDestroy'
+        ],
+
+        initialize: function (options)
+        {
+            this.parent(options);
+
+            this.Loader = new QUILoader();
+            this.areas  = [];
+
+            this.addEvents({
+                onInject  : this.$onInject,
+                onDestroy : this.$onDestroy
+            });
+        },
+
+        /**
+         * Return the domnode element
+         * @return {HTMLElement}
+         */
+        create: function ()
+        {
+            this.$Elm = new Element('div', {
+                'class' : 'quiqqer-blocks-site-category'
+            });
+
+            this.Loader.inject( this.$Elm );
+
+
+            return this.$Elm;
+        },
+
+        /**
+         * event : on inject
+         */
+        $onInject : function()
+        {
+            var self = this;
+
+            this.Loader.show();
+
+            this.getBlockAreas(function(blocks)
+            {
+                var i, len, data, AC;
+
+                var Site  = self.getAttribute( 'Site'),
+                    areas = Site.getAttribute( 'quiqqer.blocks.areas' );
+
+                if ( areas ) {
+                    areas = JSON.decode(areas);
+                }
+
+                for ( i = 0, len = blocks.length; i < len; i++ )
+                {
+                    AC = self.$insertBlockAreaEdit( blocks[ i ] );
+
+                    if ( typeof areas[ AC.getAttribute('name') ] === 'undefined' ) {
+                        continue;
+                    }
+
+                    data = areas[ AC.getAttribute('name') ];
+
+                    data.each(function(blockId) {
+                        AC.addBlockById( blockId );
+                    });
+                }
+
+                self.Loader.hide();
+                self.fireEvent( 'loaded' );
+            });
+        },
+
+        /**
+         * event : on destroy
+         */
+        $onDestroy : function()
+        {
+            var i, len, AC;
+
+            var Site  = this.getAttribute( 'Site'),
+                areas = {};
+
+            for ( i = 0, len = this.areas.length; i < len; i++ )
+            {
+                AC = this.areas[ i ];
+
+                areas[ AC.getAttribute( 'name' ) ] = AC.getData();
+            }
+
+            Site.setAttribute( 'quiqqer.blocks.areas', JSON.encode( areas ) );
+        },
+
+        /**
+         * Return the available for the site
+         * @param {Function} callback - callback function
+         */
+        getBlockAreas : function(callback)
+        {
+            var Site    = this.getAttribute( 'Site'),
+                Project = Site.getProject();
+
+            QUIAjax.get('package_quiqqer_blocks_ajax_project_getAreas', callback, {
+                'package' : 'quiqqer/blocks',
+                project   : Project.encode(),
+                siteType  : Site.getAttribute( 'type' )
+            });
+        },
+
+        /**
+         * Create a block area edit container
+         *
+         * @param {Object} area - Data of the area
+         * @return Area
+         */
+        $insertBlockAreaEdit : function(area)
+        {
+            var Site    = this.getAttribute( 'Site'),
+                Project = Site.getProject(),
+                Control = new Area();
+
+            Control.setAttribute( 'Project', Project );
+            Control.setAttribute( 'Site', Site );
+            Control.setAttributes( area );
+
+            Control.inject( this.$Elm );
+
+            this.areas.push( Control );
+
+            return Control;
+        }
+    });
+
+});
\ No newline at end of file
diff --git a/blocks.xml b/blocks.xml
new file mode 100644
index 0000000..cdf7ec6
--- /dev/null
+++ b/blocks.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<quiqqer>
+    <blocks>
+        <!-- available standard blocks -->
+        <block control="\QUI\Controls\Breadcrumb">
+            <title>
+                <locale group="quiqqer/blocks" var="block.control.breadcrumb.title" />
+            </title>
+            <description>
+                <locale group="quiqqer/blocks" var="block.control.breadcrumb.description" />
+            </description>
+        </block>
+
+        <block control="\QUI\Controls\Contact">
+            <title>
+                <locale group="quiqqer/blocks" var="block.control.contact.title" />
+            </title>
+            <description>
+                <locale group="quiqqer/blocks" var="block.control.contact.description" />
+            </description>
+        </block>
+    </blocks>
+
+</quiqqer>
diff --git a/lib/QUI/Blocks/Block.php b/lib/QUI/Blocks/Block.php
index 1adafd1..00c340d 100644
--- a/lib/QUI/Blocks/Block.php
+++ b/lib/QUI/Blocks/Block.php
@@ -74,7 +74,7 @@ public function create()
 
         $Ctrl = $this->getAttribute( 'type' );
 
-        if ( !is_callable( $Ctrl ) ) {
+        if ( !is_callable( $Ctrl ) && !class_exists( $Ctrl ) ) {
             throw new QUI\Exception( 'Control not found. Block could not be create' );
         }
 
diff --git a/lib/QUI/Blocks/Manager.php b/lib/QUI/Blocks/Manager.php
index 8738505..7a8502b 100644
--- a/lib/QUI/Blocks/Manager.php
+++ b/lib/QUI/Blocks/Manager.php
@@ -56,9 +56,10 @@ public function createBlockForProject(Project $Project, Block $Block)
      * Return the areas which are available in the project
      *
      * @param Project $Project
+     * @param string|bool $siteType - optional, returns only the areas for the specific site type (default = false)
      * @return array
      */
-    public function getAreasByProject(Project $Project)
+    public function getAreasByProject(Project $Project, $siteType=false)
     {
         $templates = array();
         $blocks    = array();
@@ -90,7 +91,10 @@ public function getAreasByProject(Project $Project)
                 continue;
             }
 
-            $blocks = array_merge( $blocks, Utils::getTemplateAreasFromXML( $blockXML ) );
+            $blocks = array_merge(
+                $blocks,
+                Utils::getTemplateAreasFromXML( $blockXML, $siteType )
+            );
         }
 
         return $blocks;
@@ -185,12 +189,31 @@ public function getBlocksByArea($blockArea, Site $Site)
         }
 
         $blockAreas = $Site->getAttribute( 'quiqqer.blocks.areas' );
+        $blockAreas = json_decode( $blockAreas, true );
 
+        if ( !isset( $blockAreas[ $blockArea ] ) ) {
+            return array();
+        }
+
+        $result = array();
+        $blocks = $blockAreas[ $blockArea ];
+
+        foreach ( $blocks as $blockId )
+        {
+            $blockId = (int)$blockId;
 
+            try
+            {
+                $result[] = $this->getBlockById( $blockId );
+
+            } catch ( QUI\Exception $Exception )
+            {
 
+            }
+        }
 
 
-        return array();
+        return $result;
     }
 
     /**
diff --git a/lib/QUI/Blocks/Utils.php b/lib/QUI/Blocks/Utils.php
index b4f2961..f3fa166 100644
--- a/lib/QUI/Blocks/Utils.php
+++ b/lib/QUI/Blocks/Utils.php
@@ -52,9 +52,10 @@ static function getBlocksFromXML($file)
      * Return the template blocks from a xml file
      *
      * @param string $file - path to xm file
+     * @param string|bool $siteType - optional, return only the blocks for the specific site type
      * @return array
      */
-    static function getTemplateAreasFromXML($file)
+    static function getTemplateAreasFromXML($file, $siteType=false)
     {
         if ( !file_exists( $file ) ) {
             return array();
@@ -64,7 +65,18 @@ static function getTemplateAreasFromXML($file)
         $Path = new \DOMXPath( $Dom );
 
         $globalBlocks = $Path->query( "//quiqqer/blocks/templateAreas/areas/area" );
-        $typeBlocks   = $Path->query( "//quiqqer/blocks/templateAreas/types/type/area" );
+
+        if ( $siteType )
+        {
+            $typeBlocks = $Path->query(
+                "//quiqqer/blocks/templateAreas/types/type[@type='{$siteType}']/area"
+            );
+
+        } else
+        {
+            $typeBlocks = $Path->query( "//quiqqer/blocks/templateAreas/types/type/area" );
+        }
+
 
         $list = array();
 
diff --git a/locale.xml b/locale.xml
index 1315279..8a2d0b7 100644
--- a/locale.xml
+++ b/locale.xml
@@ -1,18 +1,40 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <locales>
 
-    <groups name="quiqqer/blocks" type="php,js">
+    <groups name="quiqqer/blocks" datatype="php,js">
         <locale name="menu.blocks.text">
             <de><![CDATA[Blockverwaltung]]></de>
             <en><![CDATA[Blocks-Manager]]></en>
         </locale>
-    </groups>
 
-    <groups name="quiqqer/blocks" type="php">
 
+        <!-- Blocks -->
+        <locale name="block.control.breadcrumb.title">
+            <de><![CDATA[Block:Bradcrumb]]></de>
+            <en><![CDATA[Block:Bradcrumb]]></en>
+        </locale>
+        <locale name="block.control.breadcrumb.description">
+            <de><![CDATA[]]></de>
+            <en><![CDATA[]]></en>
+        </locale>
+        <locale name="block.control.contact.title">
+            <de><![CDATA[Block:Kontakt]]></de>
+            <en><![CDATA[Block:Contact]]></en>
+        </locale>
+        <locale name="block.control.contact.description">
+            <de><![CDATA[]]></de>
+            <en><![CDATA[]]></en>
+        </locale>
+    </groups>
+
+    <groups name="quiqqer/blocks" datatype="php">
+        <locale name="site.panel.blocks.category.title">
+            <de><![CDATA[Blöcke]]></de>
+            <en><![CDATA[Blocks]]></en>
+        </locale>
     </groups>
 
-    <groups name="quiqqer/blocks" type="js">
+    <groups name="quiqqer/blocks" datatype="js">
 
     </groups>
 
diff --git a/site.xml b/site.xml
new file mode 100644
index 0000000..3b8febd
--- /dev/null
+++ b/site.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+    <attributes>
+        <attribute>quiqqer.blocks.areas</attribute>
+    </attributes>
+
+    <!-- extend every panel -->
+    <window>
+        <tab name="quiqqer.blocks">
+            <text>
+                <locale group="quiqqer/blocks" var="site.panel.blocks.category.title" />
+            </text>
+            <image>icon-th</image>
+            <onload require="package/quiqqer/blocks/bin/Site/Category"></onload>
+        </tab>
+    </window>
+
+</site>
-- 
GitLab