Add condition handling for boxes
authorjoshuaruesweg <ruesweg@woltlab.com>
Mon, 30 Aug 2021 08:28:33 +0000 (10:28 +0200)
committerjoshuaruesweg <ruesweg@woltlab.com>
Mon, 30 Aug 2021 08:28:33 +0000 (10:28 +0200)
wcfsetup/install/files/acp/templates/boxAdd.tpl
wcfsetup/install/files/lib/acp/form/BoxAddForm.class.php
wcfsetup/install/files/lib/acp/form/BoxEditForm.class.php
wcfsetup/install/files/lib/data/box/Box.class.php
wcfsetup/install/files/lib/system/box/BoxHandler.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 2c83daf0d372bcf289d08cfedf62ae7e8d922746..779c3d877c0282337ae1cd0f2f68ce4e3d3495b8 100644 (file)
@@ -97,6 +97,7 @@
                                <li><a href="{@$__wcf->getAnchor('general')}">{lang}wcf.global.form.data{/lang}</a></li>
                                <li><a href="{@$__wcf->getAnchor('contents')}">{lang}wcf.acp.box.contents{/lang}</a></li>
                                <li><a href="{@$__wcf->getAnchor('pages')}">{lang}wcf.acp.page.list{/lang}</a></li>
+                               <li><a href="{@$__wcf->getAnchor('conditions')}">{lang}wcf.acp.box.conditions{/lang}</a></li>
                                <li><a href="{@$__wcf->getAnchor('acl')}">{lang}wcf.acl.access{/lang}</a></li>
 
                                {event name='tabMenuTabs'}
                        {include file='aclSimple' __supportsInvertedPermissions=true}
                </div>
 
+               <div id="conditions" class="tabMenuContent">
+                       <section class="section">
+                               <header class="sectionHeader">
+                                       <h2 class="sectionTitle">{lang}wcf.acp.box.conditions.page{/lang}</h2>
+                               </header>
+
+                               {foreach from=$groupedConditionObjectTypes['com.woltlab.wcf.page'] item='pageConditionObjectType'}
+                                       {@$pageConditionObjectType->getProcessor()->getHtml()}
+                               {/foreach}
+                       </section>
+
+                       {if $groupedConditionObjectTypes['com.woltlab.wcf.pointInTime']|isset}
+                               <section class="section">
+                                       <header class="sectionHeader">
+                                               <h2 class="sectionTitle">{lang}wcf.acp.box.conditions.pointInTime{/lang}</h2>
+                                       </header>
+
+                                       {foreach from=$groupedConditionObjectTypes['com.woltlab.wcf.pointInTime'] item='pointInTimeConditionObjectType'}
+                                               {@$pointInTimeConditionObjectType->getProcessor()->getHtml()}
+                                       {/foreach}
+                               </section>
+                       {/if}
+
+                       {if $groupedConditionObjectTypes['com.woltlab.wcf.user']|isset}
+                               <section class="section">
+                                       <header class="sectionHeader">
+                                               <h2 class="sectionTitle">{lang}wcf.acp.box.conditions.user{/lang}</h2>
+                                       </header>
+
+                                       {include file='userConditions' groupedObjectTypes=$groupedConditionObjectTypes['com.woltlab.wcf.user']}
+                               </section>
+                       {/if}
+
+                       {event name='conditionContainers'}
+               </div>
+
                {event name='tabMenuContents'}
        </div>
 
index 2b6dccfb5ebae8c9153e0f660e7455eb7868c884..4c40f67f829911533fbad3ae20e0b130b09b8c83 100644 (file)
@@ -16,6 +16,7 @@ use wcf\form\AbstractForm;
 use wcf\system\acl\simple\SimpleAclHandler;
 use wcf\system\box\IBoxController;
 use wcf\system\box\IConditionBoxController;
+use wcf\system\condition\ConditionHandler;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\exception\IllegalLinkException;
 use wcf\system\exception\UserInputException;
@@ -222,6 +223,12 @@ class BoxAddForm extends AbstractForm
      */
     public $invertPermissions;
 
+    /**
+     * grouped boxes condition object types
+     * @var ObjectType[][]
+     */
+    public $groupedConditionObjectTypes = [];
+
     /**
      * @inheritDoc
      */
@@ -393,6 +400,18 @@ class BoxAddForm extends AbstractForm
         if ($this->boxType === 'system') {
             $this->boxController = ObjectTypeCache::getInstance()->getObjectType($this->boxControllerID);
         }
+
+        foreach ($this->groupedConditionObjectTypes as $groupedObjectTypes) {
+            foreach ($groupedObjectTypes as $objectTypes) {
+                if (\is_array($objectTypes)) {
+                    foreach ($objectTypes as $objectType) {
+                        $objectType->getProcessor()->readFormParameters();
+                    }
+                } else {
+                    $objectTypes->getProcessor()->readFormParameters();
+                }
+            }
+        }
     }
 
     /**
@@ -532,6 +551,18 @@ class BoxAddForm extends AbstractForm
             $statement->execute($conditionBuilder->getParameters());
             $this->pageIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
         }
+
+        foreach ($this->groupedConditionObjectTypes as $groupedObjectTypes) {
+            foreach ($groupedObjectTypes as $objectTypes) {
+                if (\is_array($objectTypes)) {
+                    foreach ($objectTypes as $objectType) {
+                        $objectType->getProcessor()->validate();
+                    }
+                } else {
+                    $objectTypes->getProcessor()->validate();
+                }
+            }
+        }
     }
 
     /**
@@ -637,6 +668,19 @@ class BoxAddForm extends AbstractForm
         // save acl
         SimpleAclHandler::getInstance()->setValues('com.woltlab.wcf.box', $box->boxID, $this->aclValues);
 
+        // transform conditions array into one-dimensional array
+        $conditions = [];
+        foreach ($this->groupedConditionObjectTypes as $groupedObjectTypes) {
+            foreach ($groupedObjectTypes as $objectTypes) {
+                if (\is_array($objectTypes)) {
+                    $conditions = \array_merge($conditions, $objectTypes);
+                } else {
+                    $conditions[] = $objectTypes;
+                }
+            }
+        }
+        ConditionHandler::getInstance()->createConditions($box->boxID, $conditions);
+
         // call saved event
         $this->saved();
 
@@ -659,6 +703,10 @@ class BoxAddForm extends AbstractForm
         $this->linkType = 'none';
         $this->linkPageID = 0;
         $this->linkPageObjectID = 0;
+
+        foreach ($conditions as $condition) {
+            $condition->getProcessor()->reset();
+        }
     }
 
     /**
@@ -666,6 +714,27 @@ class BoxAddForm extends AbstractForm
      */
     public function readData()
     {
+        $objectTypes = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.condition.box');
+        foreach ($objectTypes as $objectType) {
+            if (!$objectType->conditionobject) {
+                continue;
+            }
+
+            if (!isset($this->groupedConditionObjectTypes[$objectType->conditionobject])) {
+                $this->groupedConditionObjectTypes[$objectType->conditionobject] = [];
+            }
+
+            if ($objectType->conditiongroup) {
+                if (!isset($this->groupedConditionObjectTypes[$objectType->conditionobject][$objectType->conditiongroup])) {
+                    $this->groupedConditionObjectTypes[$objectType->conditionobject][$objectType->conditiongroup] = [];
+                }
+
+                $this->groupedConditionObjectTypes[$objectType->conditionobject][$objectType->conditiongroup][$objectType->objectTypeID] = $objectType;
+            } else {
+                $this->groupedConditionObjectTypes[$objectType->conditionobject][$objectType->objectTypeID] = $objectType;
+            }
+        }
+
         parent::readData();
 
         if (empty($_POST) && $this->presetBox) {
@@ -758,6 +827,7 @@ class BoxAddForm extends AbstractForm
             'aclValues' => SimpleAclHandler::getInstance()->getOutputValues($this->aclValues),
             'availableBoxPositions' => $this->availableBoxPositions,
             'invertPermissions' => $this->invertPermissions,
+            'groupedConditionObjectTypes' => $this->groupedConditionObjectTypes,
         ]);
     }
 }
index 9832dc5c4e916097259d32a018713beb88851ee5..46ceef3b3476263848bd15a70ecfd28a7436651f 100644 (file)
@@ -166,6 +166,24 @@ class BoxEditForm extends BoxAddForm
 
         SimpleAclHandler::getInstance()->setValues('com.woltlab.wcf.box', $this->box->boxID, $this->aclValues);
 
+        // transform conditions array into one-dimensional array
+        $conditions = [];
+        foreach ($this->groupedConditionObjectTypes as $groupedObjectTypes) {
+            foreach ($groupedObjectTypes as $objectTypes) {
+                if (\is_array($objectTypes)) {
+                    $conditions = \array_merge($conditions, $objectTypes);
+                } else {
+                    $conditions[] = $objectTypes;
+                }
+            }
+        }
+
+        ConditionHandler::getInstance()->updateConditions(
+            $this->box->boxID,
+            $this->box->getConditions2(),
+            $conditions
+        );
+
         // call saved event
         $this->saved();
 
@@ -239,6 +257,26 @@ class BoxEditForm extends BoxAddForm
             $this->invertPermissions = $this->box->invertPermissions;
 
             $this->readBoxImages();
+
+            $conditions = $this->box->getConditions2();
+            $conditionsByObjectTypeID = [];
+            foreach ($conditions as $condition) {
+                $conditionsByObjectTypeID[$condition->objectTypeID] = $condition;
+            }
+
+            foreach ($this->groupedConditionObjectTypes as $objectTypes1) {
+                foreach ($objectTypes1 as $objectTypes2) {
+                    if (\is_array($objectTypes2)) {
+                        foreach ($objectTypes2 as $objectType) {
+                            if (isset($conditionsByObjectTypeID[$objectType->objectTypeID])) {
+                                $conditionsByObjectTypeID[$objectType->objectTypeID]->getObjectType()->getProcessor()->setData($conditionsByObjectTypeID[$objectType->objectTypeID]);
+                            }
+                        }
+                    } elseif (isset($conditionsByObjectTypeID[$objectTypes2->objectTypeID])) {
+                        $conditionsByObjectTypeID[$objectTypes2->objectTypeID]->getObjectType()->getProcessor()->setData($conditionsByObjectTypeID[$objectTypes2->objectTypeID]);
+                    }
+                }
+            }
         }
     }
 
index 2e00f9522c4150a2bf6a34d87b009c081d618432..2d51e5b16e0d95f35a2e08a165b253ee215f4cf7 100644 (file)
@@ -548,6 +548,32 @@ class Box extends DatabaseObject
         return [];
     }
 
+    /**
+     * @TODO
+     *
+     * @return  Condition[]
+     * @since   5.5
+     */
+    public function getConditions2(): array // @TODO name
+    {
+        return ConditionHandler::getInstance()->getConditions(
+            'com.woltlab.wcf.condition.box', // @TODO make const
+            $this->boxID
+        );
+    }
+
+    public function isVisible(): bool
+    {
+        $conditions = $this->getConditions2();
+        foreach ($conditions as $condition) {
+            if (!$condition->getObjectType()->getProcessor()->showContent($condition)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     /**
      * Returns true if this box is accessible by current user.
      *
index 410b71deb516c2248ac5138dfbf9c551158d0063..6cdb5f82948a8cd8e5e11aea04ed2afa7040213a 100644 (file)
@@ -270,7 +270,7 @@ class BoxHandler extends SingletonFactory
 
         $boxes = [];
         foreach ($boxList as $box) {
-            if (!$forDisplay || $box->isAccessible()) {
+            if (!$forDisplay || ($box->isAccessible() && $box->isVisible())) {
                 $virtualShowOrder = (isset($showOrders[$box->boxID])) ? $showOrders[$box->boxID] : ($box->showOrder + 1000);
                 $box->setVirtualShowOrder($virtualShowOrder);
 
index b1ee46081302f6d2bc7b25a51059f31d31f88568..ada4555558b631a5bf83c0962ba19ca7f2bd0211 100644 (file)
                <item name="wcf.acp.box.controller.limit"><![CDATA[Maximale Anzahl an Einträgen]]></item>
                <item name="wcf.acp.box.controller.sortField"><![CDATA[Sortierung nach]]></item>
                <item name="wcf.acp.box.controller.sortField.description"><![CDATA[Die ausgewählte Objekteigenschaft wird für die Sortierung der Einträge verwendet.]]></item>
+               <item name="wcf.acp.box.conditions"><![CDATA[Bedingungen]]></item>
+               <item name="wcf.acp.box.conditions.page"><![CDATA[Seite]]></item>
+               <item name="wcf.acp.box.conditions.pointInTime"><![CDATA[Zeitpunkt]]></item>
+               <item name="wcf.acp.box.conditions.user"><![CDATA[Aktiver Benutzer]]></item>
        </category>
        <category name="wcf.acp.cache">
                <item name="wcf.acp.cache.button.clear"><![CDATA[Cache leeren]]></item>
index 80cee684f38bb44079e15aa4677723cdb069e035..3aaadf76b077595f66e73168857f16d855da3ea9 100644 (file)
                <item name="wcf.acp.box.controller.sortField"><![CDATA[Sort By]]></item>
                <item name="wcf.acp.box.controller.sortField.description"><![CDATA[The selected object property is used for sorting.]]></item>
                <item name="wcf.acp.box.controller.limit"><![CDATA[Maximum Number of Items]]></item>
+               <item name="wcf.acp.box.conditions"><![CDATA[Conditions]]></item>
+               <item name="wcf.acp.box.conditions.page"><![CDATA[Page]]></item>
+               <item name="wcf.acp.box.conditions.pointInTime"><![CDATA[Time]]></item>
+               <item name="wcf.acp.box.conditions.user"><![CDATA[Active user]]></item>
        </category>
        <category name="wcf.acp.cache">
                <item name="wcf.acp.cache.button.clear"><![CDATA[Clear Cache]]></item>