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