--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/vortex/box.xsd">
+ <import>
+ <box identifier="com.woltlab.wcf.RecentActivity">
+ <name language="de">Letzte Aktivitäten</name>
+ <name language="en">Recent Activity</name>
+ <boxType>system</boxType>
+ <controller>wcf\system\box\RecentActivityBoxController</controller>
+ <position>contentBottom</position>
+ <showHeader>0</showHeader>
+ <visibleEverywhere>0</visibleEverywhere>
+ <visibilityExceptions>
+ <page>com.woltlab.wcf.Dashboard</page>
+ </visibilityExceptions>
+ </box>
+
+ <box identifier="com.woltlab.wcf.RecentActivitySidebar">
+ <name language="de">Letzte Aktivitäten (Sidebar)</name>
+ <name language="en">Recent Activity (Sidebar)</name>
+ <boxType>system</boxType>
+ <controller>wcf\system\box\RecentActivityBoxController</controller>
+ <position>sidebarRight</position>
+ <showHeader>1</showHeader>
+ <visibleEverywhere>0</visibleEverywhere>
+ <visibilityExceptions>
+ <page>com.woltlab.wcf.Dashboard</page>
+ </visibilityExceptions>
+ </box>
+ </import>
+</data>
<instruction type="page" />
<instruction type="menu" />
<instruction type="menuItem" />
+ <instruction type="box" />
<instruction type="script">acp/post_install.php</instruction>
</instructions>
<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/maelstrom/page.xsd">
<import>
<!-- dynamic -->
- <page identifier="com.woltlab.wcf.Dashboard">
- <pageType>system</pageType>
- <controller>wcf\page\DashboardPage</controller>
- <name language="de"><![CDATA[Dashboard]]></name>
- <name language="en"><![CDATA[Dashboard]]></name>
- <options>module_dashboard_page</options>
- </page>
-
<page identifier="com.woltlab.wcf.MembersList">
<pageType>system</pageType>
<controller>wcf\page\MembersListPage</controller>
</page>
<!-- static -->
+ <page identifier="com.woltlab.wcf.Dashboard">
+ <pageType>text</pageType>
+ <name language="de"><![CDATA[Dashboard]]></name>
+ <name language="en"><![CDATA[Dashboard]]></name>
+ <options>module_dashboard_page</options>
+
+ <content>
+ <title>Dashboard</title>
+ <content><![CDATA[]]></content>
+ <customURL>dashboard</customURL>
+ </content>
+ </page>
+
<page identifier="com.woltlab.wcf.CookiePolicy">
<pageType>text</pageType>
<name language="en">Cookie Policy</name>
--- /dev/null
+<section class="section sectionContainerList dashboardBoxRecentActivity" id="dashboardBoxRecentActivity">
+ <header class="sectionHeader">
+ <h2 class="sectionTitle">{lang}wcf.user.recentActivity{/lang}</h2>
+
+ {if $canFilterByFollowedUsers}{*todo*}
+ <nav class="jsMobileNavigation buttonGroupNavigation jsOnly jsRecentActivitySwitchContext">
+ <ul class="buttonGroup">
+ <li><a href="#" class="button small{if !$filteredByFollowedUsers} active{/if}">{lang}wcf.user.recentActivity.scope.all{/lang}</a></li>
+ <li><a href="#" class="button small{if $filteredByFollowedUsers} active{/if}">{lang}wcf.user.recentActivity.scope.followedUsers{/lang}</a></li>
+ </ul>
+ </nav>
+ {/if}
+ </header>
+
+ {assign var='__events' value=$eventList->getObjects()}
+ {assign var='__lastEvent' value=$__events|end}
+ <ul id="recentActivities" class="containerList recentActivityList" data-last-event-time="{@$lastEventTime}" data-last-event-id="{if $__lastEvent}{@$__lastEvent->eventID}{else}0{/if}">
+ {include file='recentActivityListItem'}
+ </ul>
+</section>
+
+<script data-relocate="true">
+ //<![CDATA[
+ $(function() {
+ WCF.Language.addObject({
+ 'wcf.user.recentActivity.more': '{lang}wcf.user.recentActivity.more{/lang}',
+ 'wcf.user.recentActivity.noMoreEntries': '{lang}wcf.user.recentActivity.noMoreEntries{/lang}'
+ });
+
+ new WCF.User.RecentActivityLoader(null, {if $filteredByFollowedUsers}true{else}false{/if});
+ });
+ //]]>
+</script>
--- /dev/null
+<ul class="sidebarBoxList">
+ {foreach from=$eventList item=event}
+ <li class="box24">
+ <a href="{link controller='User' object=$event->getUserProfile()}{/link}" title="{$event->getUserProfile()->username}">{@$event->getUserProfile()->getAvatar()->getImageTag(24)}</a>
+
+ <div class="sidebarBoxHeadline">
+ <h3>
+ <a href="{link controller='User' object=$event->getUserProfile()}{/link}" class="userLink" data-user-id="{@$event->getUserProfile()->userID}">{$event->getUserProfile()->username}</a>
+ <small class="separatorLeft">{@$event->time|time}</small>
+ </h3>
+ <small>{@$event->getTitle()}</small>
+ </div>
+ </li>
+ {/foreach}
+</ul>
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute([1]);
-// landing page
-$sql = "UPDATE wcf".WCF_N."_page
- SET isLandingPage = ?
- WHERE identifier = ?";
-$statement = WCF::getDB()->prepareStatement($sql);
-$statement->execute([
- 1,
- 'com.woltlab.wcf.Dashboard'
-]);
-
// get server timezone
if ($timezone = @date_default_timezone_get()) {
if ($timezone != 'Europe/London' && in_array($timezone, DateUtil::getAvailableTimezones())) {
<?php
use wcf\data\user\UserEditor;
use wcf\data\user\UserProfileAction;
-use wcf\system\dashboard\DashboardHandler;
use wcf\system\WCF;
-// set dashboard default values
-DashboardHandler::setDefaultValues('com.woltlab.wcf.user.DashboardPage', array(
-// content
-'com.woltlab.wcf.user.recentActivity' => 1,
-// sidebar
-'com.woltlab.wcf.user.registerButton' => 1,
-'com.woltlab.wcf.user.signedInAs' => 2,
-'com.woltlab.wcf.user.statsSidebar' => 3
-));
-DashboardHandler::setDefaultValues('com.woltlab.wcf.user.MembersListPage', array(
-'com.woltlab.wcf.user.newestMembers' => 1,
-'com.woltlab.wcf.user.mostActiveMembers' => 2
-));
+// set default landing page
+$sql = "UPDATE wcf".WCF_N."_page
+ SET isLandingPage = ?
+ WHERE identifier = ?";
+$statement = WCF::getDB()->prepareStatement($sql);
+$statement->execute([
+ 1,
+ 'com.woltlab.wcf.Dashboard'
+]);
// update administrator user rank and user online marking
$editor = new UserEditor(WCF::getUser());
</dd>
</dl>
- <dl{if $errorField == 'className'} class="formError"{/if}>
- <dt><label for="className">{lang}wcf.acp.box.className{/lang}</label></dt>
+ <dl{if $errorField == 'controller'} class="formError"{/if}>
+ <dt><label for="controller">{lang}wcf.acp.box.controller{/lang}</label></dt>
<dd>
- <input type="text" id="className" name="className" value="{$className}" class="long" />
- {if $errorField == 'className'}
+ <input type="text" id="controller" name="controller" value="{$controller}" class="long" />
+ {if $errorField == 'controller'}
<small class="innerError">
{if $errorType == 'empty'}
{lang}wcf.global.form.error.empty{/lang}
{else}
- {lang}wcf.acp.box.className.error.{@$errorType}{/lang}
+ {lang}wcf.acp.box.controller.error.{@$errorType}{/lang}
{/if}
</small>
{/if}
public $showHeader = 1;
/**
- * php class name
+ * box controller
* @var string
*/
- public $className = '';
+ public $controller = '';
/**
* box name
if (isset($_POST['visibleEverywhere'])) $this->visibleEverywhere = intval($_POST['visibleEverywhere']);
if (isset($_POST['cssClassName'])) $this->cssClassName = StringUtil::trim($_POST['cssClassName']);
if (isset($_POST['showHeader'])) $this->showHeader = intval($_POST['showHeader']);
- if (isset($_POST['className'])) $this->className = StringUtil::trim($_POST['className']);
+ if (isset($_POST['controller'])) $this->controller = StringUtil::trim($_POST['controller']);
if (isset($_POST['pageIDs']) && is_array($_POST['pageIDs'])) $this->pageIDs = ArrayUtil::toIntegerArray($_POST['pageIDs']);
if (isset($_POST['title']) && is_array($_POST['title'])) $this->title = ArrayUtil::trim($_POST['title']);
// validate class name
if ($this->boxType == 'system') {
- if (empty($this->className)) {
- throw new UserInputException('className');
+ if (empty($this->controller)) {
+ throw new UserInputException('controller');
}
- // @todo check class
+ // @todo check controller
}
// validate page ids
'visibleEverywhere' => $this->visibleEverywhere,
'cssClassName' => $this->cssClassName,
'showHeader' => $this->showHeader,
- 'className' => $this->className,
+ 'controller' => $this->controller,
'identifier' => ''
]), 'content' => $content, 'pageIDs' => $this->pageIDs ]);
$returnValues = $this->objectAction->executeAction();
WCF::getTPL()->assign('success', true);
// reset variables
- $this->boxType = $this->position = $this->cssClassName = $this->className = $this->name = '';
+ $this->boxType = $this->position = $this->cssClassName = $this->controller = $this->name = '';
$this->showOrder = 0;
$this->visibleEverywhere = $this->showHeader = 1;
$this->title = $this->content = $this->images = $this->imageID = [];
'boxType' => $this->boxType,
'position' => $this->position,
'cssClassName' => $this->cssClassName,
- 'className' => $this->className,
+ 'controller' => $this->controller,
'showOrder' => $this->showOrder,
'visibleEverywhere' => $this->visibleEverywhere,
'showHeader' => $this->showHeader,
'visibleEverywhere' => $this->visibleEverywhere,
'cssClassName' => $this->cssClassName,
'showHeader' => $this->showHeader,
- 'className' => $this->className
+ 'controller' => $this->controller
]), 'content' => $content, 'pageIDs' => $this->pageIDs]);
$this->objectAction->executeAction();
$this->position = $this->box->position;
$this->showOrder = $this->box->showOrder;
$this->cssClassName = $this->box->cssClassName;
- $this->className = $this->box->className;
+ $this->controller = $this->box->controller;
if ($this->box->showHeader) $this->showHeader = 1;
if ($this->box->visibleEverywhere) $this->visibleEverywhere = 1;
else $this->visibleEverywhere = 0;
* @property-read integer $showHeader
* @property-read integer $originIsSystem
* @property-read integer $packageID
- * @property-read string $className
+ * @property-read string $controller
* @property-read integer|null $menuID
*/
class Box extends DatabaseObject {
*/
protected $pageIDs;
+ /**
+ * box controller
+ * @var \wcf\system\box\IBoxController
+ */
+ protected $__controller;
+
/**
* Returns true if the active user can delete this box.
*
return !empty($content);
}
+ /**
+ * Returns the box controller.
+ *
+ * @return \wcf\system\box\IBoxController
+ */
public function getController() {
- // @todo
+ if ($this->__controller === null) {
+ if ($this->controller && class_exists($this->controller)) {
+ $this->__controller = new $this->controller;
+ $this->__controller->setBox($this);
+ }
+ }
+
+ return $this->__controller;
}
/**
--- /dev/null
+<?php
+namespace wcf\system\box;
+use wcf\data\box\Box;
+
+/**
+ * Default implementation for box controllers.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.box
+ * @category Community Framework
+ */
+abstract class AbstractBoxController implements IBoxController {
+ /**
+ * database object of this box
+ * @var Box
+ */
+ protected $box;
+
+ /**
+ * box content
+ * @var string
+ */
+ protected $content;
+
+ /**
+ * supported box positions
+ * @var string[]
+ */
+ protected $supportedPositions = [];
+
+ /**
+ * @inheritDoc
+ */
+ public function getTitle() {
+ return '';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getContent() {
+ if ($this->content === null) {
+ $this->content = '';
+ $this->loadContent();
+ }
+
+ return $this->content;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function hasContent() {
+ return !empty($this->getContent());
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getImage() {
+ return null;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function hasImage() {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getLink() {
+ return '';
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function hasLink() {
+ return false;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getBox() {
+ return $this->box;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function setBox(Box $box) {
+ $this->box = $box;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getSupportedPositions() {
+ if (!empty($this->supportedPositions)) {
+ return $this->supportedPositions;
+ }
+
+ return Box::$availablePositions;
+ }
+
+ /**
+ * Loads the content of this box.
+ */
+ protected abstract function loadContent();
+}
--- /dev/null
+<?php
+namespace wcf\system\box;
+use wcf\data\box\Box;
+
+/**
+ * Default interface for box controllers.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.box
+ * @category Community Framework
+ */
+interface IBoxController {
+ /**
+ * Returns the title of this box.
+ *
+ * @return string
+ */
+ public function getTitle();
+
+ /**
+ * Returns the content of this box.
+ *
+ * @return string
+ */
+ public function getContent();
+
+ /**
+ * Returns false if this box has no content.
+ *
+ * @return boolean
+ */
+ public function hasContent();
+
+ /**
+ * Returns the image of this box.
+ *
+ * @return \wcf\data\media\ViewableMedia
+ */
+ public function getImage();
+
+ /**
+ * Returns true if this box has an image.
+ *
+ * @return boolean
+ */
+ public function hasImage();
+
+ /**
+ * Returns the title link of this box.
+ *
+ * @return string
+ */
+ public function getLink();
+
+ /**
+ * Returns true if this box has a title link.
+ *
+ * @return boolean
+ */
+ public function hasLink();
+
+ /**
+ * Returns the database object of this box.
+ *
+ * @return Box
+ */
+ public function getBox();
+
+ /**
+ * Sets the database object of this box.
+ *
+ * @param Box $box
+ */
+ public function setBox(Box $box);
+
+ /**
+ * Returns a list of supported box positions.
+ *
+ * @return string[]
+ */
+ public function getSupportedPositions();
+}
\ No newline at end of file
--- /dev/null
+<?php
+namespace wcf\system\box;
+use wcf\data\user\activity\event\ViewableUserActivityEventList;
+use wcf\system\request\LinkHandler;
+use wcf\system\user\activity\event\UserActivityEventHandler;
+use wcf\system\WCF;
+
+/**
+ * Box for recent activities.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package com.woltlab.wcf
+ * @subpackage system.box
+ * @category Community Framework
+ */
+class RecentActivityBoxController extends AbstractBoxController {
+ /**
+ * @inheritDoc
+ */
+ protected $supportedPositions = ['contentTop', 'contentBottom', 'sidebarLeft', 'sidebarRight'];
+
+ /**
+ * @inheritDoc
+ */
+ public function getTitle() {
+ return WCF::getLanguage()->get('wcf.user.recentActivity');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function getLink() {
+ return LinkHandler::getInstance()->getLink('RecentActivityList');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function hasLink() {
+ return true;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ protected function loadContent() {
+ if ($this->getBox()->position == 'contentTop' || $this->getBox()->position == 'contentBottom') {
+ $canFilterByFollowedUsers = $filteredByFollowedUsers = false;
+ if (WCF::getUser()->userID && count(WCF::getUserProfileHandler()->getFollowingUsers())) {
+ $canFilterByFollowedUsers = true;
+ }
+
+ $eventList = new ViewableUserActivityEventList();
+ if ($canFilterByFollowedUsers && WCF::getUser()->recentActivitiesFilterByFollowing) {
+ $filteredByFollowedUsers = true;
+ $eventList->getConditionBuilder()->add('user_activity_event.userID IN (?)', [WCF::getUserProfileHandler()->getFollowingUsers()]);
+ }
+ $eventList->sqlLimit = RECENT_ACTIVITY_ITEMS;
+ $eventList->readObjects();
+ $lastEventTime = $eventList->getLastEventTime();
+
+ // removes orphaned and non-accessable events
+ UserActivityEventHandler::validateEvents($eventList);
+
+ if (count($eventList) || $filteredByFollowedUsers) {
+ WCF::getTPL()->assign([
+ 'canFilterByFollowedUsers' => $canFilterByFollowedUsers,
+ 'eventList' => $eventList, 'lastEventTime' => $lastEventTime,
+ 'filteredByFollowedUsers' => $filteredByFollowedUsers
+ ]);
+
+ $this->content = WCF::getTPL()->fetch('boxRecentActivity');
+ }
+ }
+ else {
+ $eventList = new ViewableUserActivityEventList();
+ $eventList->sqlLimit = RECENT_ACTIVITY_SIDEBAR_ITEMS;
+ $eventList->readObjects();
+
+ // removes orphaned and non-accessable events
+ UserActivityEventHandler::validateEvents($eventList);
+
+ if (count($eventList)) {
+ WCF::getTPL()->assign([
+ 'eventList' => $eventList
+ ]);
+
+ $this->content = WCF::getTPL()->fetch('boxRecentActivitySidebar');
+ }
+ }
+ }
+}
*/
protected function executeUninstallScript() {
// check if uninstall script file for the uninstalled package exists
- $uninstallScript = WCF_DIR.'acp/uninstall/'.$this->package->package.'.php';
+ $uninstallScript = WCF_DIR.'acp/uninstall/'.$this->getPackage()->package.'.php';
if (file_exists($uninstallScript)) {
include($uninstallScript);
}
namespace wcf\system\package\plugin;
use wcf\data\box\Box;
use wcf\data\box\BoxEditor;
+use wcf\system\database\util\PreparedStatementConditionBuilder;
use wcf\system\exception\SystemException;
use wcf\system\WCF;
*/
public $tagName = 'box';
+ /**
+ * visibility exceptions per box
+ * @var string[]
+ */
+ public $visibilityExceptions = [];
+
/**
* @inheritDoc
*/
'title' => $children['title']
];
}
+ else if ($element->tagName === 'visibilityExceptions') {
+ $elements['visibilityExceptions'] = [];
+ /** @var \DOMElement $child */
+ foreach ($xpath->query('child::*', $element) as $child) {
+ $elements['visibilityExceptions'][] = $child->nodeValue;
+ }
+ }
else {
$elements[$element->tagName] = $nodeValue;
}
*/
protected function prepareImport(array $data) {
$boxType = $data['elements']['boxType'];
- $className = '';
+ $controller = '';
$identifier = $data['attributes']['identifier'];
$isMultilingual = false;
$position = $data['elements']['position'];
switch ($boxType) {
case 'system':
- if (empty($data['elements']['className'])) {
- throw new SystemException("Missing required element 'classname' for 'system'-type box '{$identifier}'");
+ if (empty($data['elements']['controller'])) {
+ throw new SystemException("Missing required element 'controller' for 'system'-type box '{$identifier}'");
}
- $className = $data['elements']['className'];
+ $controller = $data['elements']['controller'];
break;
case 'html':
case 'text':
+ case 'tpl':
if (empty($data['elements']['content'])) {
throw new SystemException("Missing required 'content' element(s) for box '{$identifier}'");
}
break;
}
+ if (!empty($data['elements']['visibilityExceptions'])) {
+ $this->visibilityExceptions[$identifier] = $data['elements']['visibilityExceptions'];
+ }
+
return [
'identifier' => $identifier,
'name' => $this->getI18nValues($data['elements']['name'], true),
'cssClassName' => (!empty($data['elements']['cssClassName'])) ? $data['elements']['cssClassName'] : '',
'showHeader' => (!empty($data['elements']['showHeader'])) ? 1 : 0,
'originIsSystem' => 1,
- 'className' => $className
+ 'controller' => $controller
];
}
return parent::import($row, $data);
}
+
+ /**
+ * @inheritDoc
+ */
+ protected function postImport() {
+ if (empty($this->visibilityExceptions)) return;
+
+ // get all boxes belonging to the identifiers
+ $conditions = new PreparedStatementConditionBuilder();
+ $conditions->add("identifier IN (?)", [array_keys($this->visibilityExceptions)]);
+ $conditions->add("packageID = ?", [$this->installation->getPackageID()]);
+
+ $sql = "SELECT *
+ FROM wcf".WCF_N."_box
+ ".$conditions;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditions->getParameters());
+ $boxes = [];
+ while ($box = $statement->fetchObject(Box::class)) {
+ $boxes[$box->identifier] = $box;
+ }
+
+ // save visibility exceptions
+ $sql = "DELETE FROM wcf".WCF_N."_box_to_page
+ WHERE boxID = ?";
+ $deleteStatement = WCF::getDB()->prepareStatement($sql);
+ $sql = "INSERT IGNORE wcf".WCF_N."_box_to_page
+ (boxID, pageID, visible)
+ VALUES (?, ?, ?)";
+ $insertStatement = WCF::getDB()->prepareStatement($sql);
+ foreach ($this->visibilityExceptions as $boxIdentifier => $pages) {
+ // delete old visibility exceptions
+ $deleteStatement->execute([$boxes[$boxIdentifier]->boxID]);
+
+ // get page ids
+ $conditionBuilder = new PreparedStatementConditionBuilder();
+ $conditionBuilder->add('identifier IN (?)', array($pages));
+ $sql = "SELECT pageID
+ FROM wcf".WCF_N."_page
+ ".$conditionBuilder;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditionBuilder->getParameters());
+ $pageIDs = [];
+ while ($row = $statement->fetchArray()) {
+ $pageIDs[] = $row['pageID'];
+ }
+
+ // save page ids
+ foreach ($pageIDs as $pageID) {
+ $insertStatement->execute([$boxes[$boxIdentifier]->boxID, $pageID, ($boxes[$boxIdentifier]->visibleEverywhere ? 0 : 1)]);
+ }
+ }
+ }
}
*/
public $boxData = [];
+ /**
+ * visibility exceptions per box
+ * @var string[]
+ */
+ public $visibilityExceptions = [];
+
/**
* @inheritDoc
*/
$elements['box']['name'][$element->getAttribute('language')] = $element->nodeValue;
}
+ else if ($child->tagName === 'visibilityExceptions') {
+ $elements['box']['visibilityExceptions'] = [];
+ /** @var \DOMElement $child */
+ foreach ($xpath->query('child::*', $child) as $child2) {
+ $elements['box']['visibilityExceptions'][] = $child2->nodeValue;
+ }
+ }
else {
$elements['box'][$child->tagName] = $child->nodeValue;
}
'packageID' => $this->installation->getPackageID()
];
+ if (!empty($data['elements']['box']['visibilityExceptions'])) {
+ $this->visibilityExceptions[$identifier] = $data['elements']['box']['visibilityExceptions'];
+ }
+
unset($data['elements']['box']);
}
$menus[$menu->identifier] = $menu;
}
+ // handle visibility exceptions
+ $sql = "DELETE FROM wcf".WCF_N."_box_to_page
+ WHERE boxID = ?";
+ $deleteStatement = WCF::getDB()->prepareStatement($sql);
+ $sql = "INSERT IGNORE wcf".WCF_N."_box_to_page
+ (boxID, pageID, visible)
+ VALUES (?, ?, ?)";
+ $insertStatement = WCF::getDB()->prepareStatement($sql);
foreach ($this->boxData as $identifier => $data) {
// connect box with menu
if (isset($menus[$identifier])) {
$data['menuID'] = $menus[$identifier]->menuID;
}
+ $box = null;
if (isset($boxes[$identifier])) {
+ $box = $boxes[$identifier];
+
+ // delete old visibility exceptions
+ $deleteStatement->execute([$box->boxID]);
+
// skip both 'identifier' and 'packageID' as these properties are immutable
unset($data['identifier']);
unset($data['packageID']);
- $boxEditor = new BoxEditor($boxes[$identifier]);
+ $boxEditor = new BoxEditor($box);
$boxEditor->update($data);
}
else {
- BoxEditor::create($data);
+ $box = BoxEditor::create($data);
+ }
+
+ // save visibility exceptions
+ if (!empty($this->visibilityExceptions[$identifier])) {
+ // get page ids
+ $conditionBuilder = new PreparedStatementConditionBuilder();
+ $conditionBuilder->add('identifier IN (?)', [$this->visibilityExceptions[$identifier]]);
+ $sql = "SELECT pageID
+ FROM wcf" . WCF_N . "_page
+ " . $conditionBuilder;
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute($conditionBuilder->getParameters());
+ $pageIDs = [];
+ while ($row = $statement->fetchArray()) {
+ $pageIDs[] = $row['pageID'];
+ }
+
+ // save page ids
+ foreach ($pageIDs as $pageID) {
+ $insertStatement->execute([$box->boxID, $pageID, ($box->visibleEverywhere ? 0 : 1)]);
+ }
}
}
}
*/
protected function prepareImport(array $data) {
$isStatic = false;
+
if (!empty($data['elements']['content'])) {
$isStatic = true;
WCF::getDB()->beginTransaction();
foreach ($this->content as $pageID => $contentData) {
foreach ($contentData as $languageCode => $content) {
- $language = LanguageFactory::getInstance()->getLanguageByCode($languageCode);
- if ($language !== null) {
- $statement->execute([
- $pageID,
- $language->languageID,
- $content['title'],
- $content['content'],
- $content['metaDescription'],
- $content['metaKeywords'],
- $content['customURL']
- ]);
+ $languageID = null;
+ if ($languageCode != '') {
+ $language = LanguageFactory::getInstance()->getLanguageByCode($languageCode);
+ if ($language === null) continue;
+
+ $languageID = $language->languageID;
}
+
+ $statement->execute([
+ $pageID,
+ $languageID,
+ $content['title'],
+ $content['content'],
+ $content['metaDescription'],
+ $content['metaKeywords'],
+ $content['customURL']
+ ]);
}
}
WCF::getDB()->commitTransaction();
showHeader TINYINT(1) NOT NULL DEFAULT 1,
originIsSystem TINYINT(1) NOT NULL DEFAULT 0,
packageID INT(10) NOT NULL,
- className VARCHAR(255) NOT NULL DEFAULT '',
+ controller VARCHAR(255) NOT NULL DEFAULT '',
menuID INT(10) NULL
);