From 6a6a7893bf32b4dd52c3484abe648e6cc09f6b75 Mon Sep 17 00:00:00 2001
From: Henning Leutz <leutz@pcsg.de>
Date: Mon, 12 Jan 2015 13:31:34 +0100
Subject: [PATCH] site cache - site events

---
 bin/Site/Area.js           | 60 ++++++++++++++++++++++++++-
 database.xml               |  8 ++++
 events.xml                 |  4 ++
 lib/QUI/Bricks/Events.php  | 74 +++++++++++++++++++++++++++++++++
 lib/QUI/Bricks/Manager.php | 85 ++++++++++++++++++++++++++++++++++++--
 lib/QUI/Bricks/Utils.php   | 51 +++++++++++++++++------
 6 files changed, 263 insertions(+), 19 deletions(-)
 create mode 100644 events.xml
 create mode 100644 lib/QUI/Bricks/Events.php

diff --git a/bin/Site/Area.js b/bin/Site/Area.js
index 8886cc2..a07b216 100644
--- a/bin/Site/Area.js
+++ b/bin/Site/Area.js
@@ -10,12 +10,14 @@ define('package/quiqqer/bricks/bin/Site/Area', [
     'qui/QUI',
     'qui/controls/Control',
     'qui/controls/buttons/Button',
+    'qui/controls/windows/Popup',
+    'qui/controls/elements/List',
     'Locale',
     'Ajax',
 
     'css!package/quiqqer/bricks/bin/Site/Area'
 
-], function (QUI, QUIControl, QUIButton, QUILocale, QUIAjax)
+], function (QUI, QUIControl, QUIButton, QUIPopup, QUIList, QUILocale, QUIAjax)
 {
     "use strict";
 
@@ -25,6 +27,7 @@ define('package/quiqqer/bricks/bin/Site/Area', [
         Type    : 'package/quiqqer/bricks/bin/Site/Area',
 
         Binds : [
+            'openBrickDialog',
             'addBrick',
             '$onInject'
         ],
@@ -76,7 +79,7 @@ define('package/quiqqer/bricks/bin/Site/Area', [
                 textimage : 'icon-plus',
                 disable   : true,
                 events    : {
-                    onClick : this.addBrick
+                    onClick : this.openBrickDialog
                 }
             }).inject( Buttons );
 
@@ -181,6 +184,59 @@ define('package/quiqqer/bricks/bin/Site/Area', [
             }
 
             return Elm;
+        },
+
+        /**
+         * Opens the brick add dialog
+         */
+        openBrickDialog : function()
+        {
+            if ( !this.$availableBricks.length ) {
+                return;
+            }
+
+            var self = this;
+
+            new QUIPopup({
+                title     : 'Baustein hinzufügen',
+                icon      : 'icon-th',
+                maxWidth  : 500,
+                maxHeight : 600,
+                autoclose : false,
+                events    :
+                {
+                    onOpen : function(Win)
+                    {
+                        var items   = [],
+                            Content = Win.getContent(),
+
+                            List = new QUIList({
+                                events :
+                                {
+                                    onClick : function(List, data)
+                                    {
+                                        self.addBrickById( data.brickId );
+                                        Win.close();
+                                    }
+                                }
+                            });
+
+                        List.inject( Content );
+
+                        for ( var i = 0, len = self.$availableBricks.length; i < len; i++ )
+                        {
+                            items.push({
+                                brickId : self.$availableBricks[ i ].id,
+                                icon    : 'icon-th',
+                                title   : self.$availableBricks[ i ].title,
+                                text    : self.$availableBricks[ i ].description
+                            });
+                        }
+
+                        List.addItems( items );
+                    }
+                }
+            }).open();
         }
     });
 });
diff --git a/database.xml b/database.xml
index 3891259..b3921c5 100644
--- a/database.xml
+++ b/database.xml
@@ -15,4 +15,12 @@
         </table>
     </global>
 
+    <projects>
+        <table name="bricksCache" no-auto-update="1" no-site-reference="1">
+            <field type="bigint( 20 ) NOT NULL">id</field>
+            <field type="VARCHAR( 255 )">area</field>
+            <field type="TEXT">brick</field>
+        </table>
+    </projects>
+
 </database>
diff --git a/events.xml b/events.xml
new file mode 100644
index 0000000..8c34c69
--- /dev/null
+++ b/events.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<events>
+    <event on="onSiteSave" fire="\QUI\Bricks\Events::onSiteSave" />
+</events>
\ No newline at end of file
diff --git a/lib/QUI/Bricks/Events.php b/lib/QUI/Bricks/Events.php
new file mode 100644
index 0000000..e96965a
--- /dev/null
+++ b/lib/QUI/Bricks/Events.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * This file contains \QUI\Bricks\Events
+ */
+
+namespace QUI\Bricks;
+
+use QUI;
+use QUI\Projects\Site;
+use QUI\Projects\Site\Edit;
+
+/**
+ * Class Events
+ *
+ * @package quiqqer/bricks
+ */
+class Events
+{
+    /**
+     * Event : on site save
+     * Create site brick cache, for inheritance
+     *
+     * @param Site|Edit $Site
+     */
+    static function onSiteSave($Site)
+    {
+        $areas = $Site->getAttribute( 'quiqqer.bricks.areas' );
+        $areas = json_decode( $areas, true );
+
+        if ( !$areas || empty( $areas ) ) {
+            return;
+        }
+
+        $Manager = new Manager();
+
+        // get inharitance areas
+        $Project      = $Site->getProject();
+        $projectAreas = $Manager->getAreasByProject( $Project );
+        $projectTable = QUI::getDBProjectTableName( Manager::TABLE_CACHE, $Project );
+
+        foreach ( $projectAreas as $area )
+        {
+            if ( !$area[ 'inheritance' ] ) {
+                continue;
+            }
+
+            if ( !isset( $areas[ $area[ 'name' ] ] ) ) {
+                continue;
+            }
+
+            if ( empty( $areas[ $area[ 'name' ] ] ) ) {
+                continue;
+            }
+
+            $bricks = $areas[ $area[ 'name' ] ];
+
+            // clear area and new data set
+            QUI::getDataBase()->delete($projectTable, array(
+                'id'   => $Site->getId(),
+                'area' => $area
+            ));
+
+            foreach ( $bricks as $brickId )
+            {
+                QUI::getDataBase()->insert($projectTable, array(
+                    'id'    => $Site->getId(),
+                    'area'  => $area[ 'name' ],
+                    'brick' => $brickId
+                ));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lib/QUI/Bricks/Manager.php b/lib/QUI/Bricks/Manager.php
index 040abdf..e2cbce5 100644
--- a/lib/QUI/Bricks/Manager.php
+++ b/lib/QUI/Bricks/Manager.php
@@ -20,7 +20,8 @@ class Manager
     /**
      * Bricks table name
      */
-    const TABLE = 'bricks';
+    const TABLE       = 'bricks';
+    const TABLE_CACHE = 'bricksCache';
 
     /**
      * Brick temp collector
@@ -267,12 +268,17 @@ public function getBricksByArea($brickArea, Site $Site)
         $brickAreas = $Site->getAttribute( 'quiqqer.bricks.areas' );
         $brickAreas = json_decode( $brickAreas, true );
 
-        if ( !isset( $brickAreas[ $brickArea ] ) ) {
-            return array();
+        if ( !isset( $brickAreas[ $brickArea ] ) || empty( $brickAreas[ $brickArea ] ) )
+        {
+            $bricks = $this->_getInheritedBricks( $brickArea, $Site );
+
+        } else
+        {
+            $bricks = $brickAreas[ $brickArea ];
         }
 
+
         $result = array();
-        $bricks = $brickAreas[ $brickArea ];
 
         foreach ( $bricks as $brickId )
         {
@@ -430,4 +436,75 @@ protected function _getBricksXMLFiles()
 
         return $result;
     }
+
+    /**
+     * Return the bricks from an area which are inherited from its parents
+     *
+     * @param String $brickArea - Name of the area
+     * @param Site $Site - Site object
+     * @return array
+     */
+    protected function _getInheritedBricks($brickArea, Site $Site)
+    {
+
+        // inheritance ( vererbung )
+        $Project = $Site->getProject();
+        $areas   = $this->getAreasByProject( $Project );
+
+        foreach ( $areas as $area )
+        {
+            if ( $area['name'] != $brickArea ) {
+                continue;
+            }
+
+            if ( !$area['inheritance'] ) {
+                return array();
+            }
+
+            break;
+        }
+
+
+        if ( !isset( $area ) || !isset( $area['name'] ) ) {
+            return array();
+        }
+
+        if ( $area['name'] != $brickArea ) {
+            return array();
+        }
+
+        if ( !Utils::hasInheritance( $Project, $brickArea ) ) {
+            return array();
+        }
+
+
+        $result    = array();
+        $parentIds = $Site->getParentIdTree();
+        $parentIds = array_reverse( $parentIds );
+
+        $projectCacheTable = QUI::getDBProjectTableName( self::TABLE_CACHE, $Project );
+
+        foreach ( $parentIds as $parentId )
+        {
+            $bricks = QUI::getDataBase()->fetch(array(
+                'from'  => $projectCacheTable,
+                'where' => array(
+                    'id'   => $parentId,
+                    'area' => $brickArea
+                )
+            ));
+
+            if ( empty( $bricks ) ) {
+                continue;
+            }
+
+            foreach ( $bricks as $brick ) {
+                $result[] = $brick['brick'];
+            }
+
+            break;
+        }
+
+        return $result;
+    }
 }
diff --git a/lib/QUI/Bricks/Utils.php b/lib/QUI/Bricks/Utils.php
index 60473e8..0e7eb4e 100644
--- a/lib/QUI/Bricks/Utils.php
+++ b/lib/QUI/Bricks/Utils.php
@@ -8,6 +8,7 @@
 
 use QUI;
 use QUI\Utils\XML;
+use QUI\Projects\Project;
 
 /**
  * Class Utils
@@ -42,7 +43,7 @@ static function getBricksFromXML($file)
         }
 
         foreach ( $bricks as $Brick ) {
-            $list[] = self::parseBrickToArray( $Brick, $Path );
+            $list[] = self::parseAreaToArray( $Brick, $Path );
         }
 
         return $list;
@@ -64,33 +65,33 @@ static function getTemplateAreasFromXML($file, $siteType=false)
         $Dom  = XML::getDomFromXml( $file );
         $Path = new \DOMXPath( $Dom );
 
-        $globalBricks = $Path->query( "//quiqqer/bricks/templateAreas/areas/area" );
+        $globalAreas = $Path->query( "//quiqqer/bricks/templateAreas/areas/area" );
 
         if ( $siteType )
         {
-            $typeBricks = $Path->query(
+            $typeAreas = $Path->query(
                 "//quiqqer/bricks/templateAreas/types/type[@type='{$siteType}']/area"
             );
 
         } else
         {
-            $typeBricks = $Path->query( "//quiqqer/bricks/templateAreas/types/type/area" );
+            $typeAreas = $Path->query( "//quiqqer/bricks/templateAreas/types/type/area" );
         }
 
 
         $list = array();
 
-        if ( $globalBricks->length )
+        if ( $globalAreas->length )
         {
-            foreach ( $globalBricks as $Brick ) {
-                $list[] = self::parseBrickToArray( $Brick, $Path );
+            foreach ( $globalAreas as $Area ) {
+                $list[] = self::parseAreaToArray( $Area, $Path );
             }
         }
 
-        if ( $typeBricks->length )
+        if ( $typeAreas->length )
         {
-            foreach ( $typeBricks as $Brick ) {
-                $list[] = self::parseBrickToArray( $Brick, $Path );
+            foreach ( $typeAreas as $Area ) {
+                $list[] = self::parseAreaToArray( $Area, $Path );
             }
         }
 
@@ -103,19 +104,20 @@ static function getGlobalTemplateAreasFromXML()
 
     }
 
+
     static function getTypeTemplateAreasFromXML($file, $siteType)
     {
 
     }
 
     /**
-     * parse a <brick> xml node to an array
+     * parse a <area> xml node to an array
      *
      * @param \DOMElement $Brick
      * @param \DOMXPath $Path
      * @return array
      */
-    static function parseBrickToArray(\DOMElement $Brick, \DOMXPath $Path)
+    static function parseAreaToArray(\DOMElement $Brick, \DOMXPath $Path)
     {
         $control     = $Brick->getAttribute( 'control' );
         $name        = $Brick->getAttribute( 'name' );
@@ -145,7 +147,30 @@ static function parseBrickToArray(\DOMElement $Brick, \DOMXPath $Path)
             'control'     => $control,
             'name'        => $name,
             'title'       => $title,
-            'description' => $description
+            'description' => $description,
+            'inheritance' => $Brick->getAttribute( 'inheritance' )
         );
     }
+
+    /**
+     *
+     * @param Project $Project
+     * @param String $areaName
+     * @return bool
+     */
+    static function hasInheritance(Project $Project, $areaName)
+    {
+        $template = $Project->getAttribute( 'template' );
+
+        // getAreasByProject
+        $brickXML = realpath( OPT_DIR . $template .'/bricks.xml' );
+        $bricks   = self::getTemplateAreasFromXML( $brickXML );
+
+        foreach ( $bricks as $brickData )
+        {
+            QUI\Log::writeRecursive( $brickData );
+        }
+
+        return true;
+    }
 }
-- 
GitLab