Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / dashboard / DashboardHandler.class.php
CommitLineData
320f4a6d
MW
1<?php
2namespace wcf\system\dashboard;
3use wcf\data\dashboard\box\DashboardBox;
4use wcf\data\object\type\ObjectTypeCache;
5use wcf\page\IPage;
6use wcf\system\cache\builder\DashboardBoxCacheBuilder;
7use wcf\system\database\util\PreparedStatementConditionBuilder;
8use wcf\system\exception\SystemException;
9use wcf\system\SingletonFactory;
10use wcf\system\WCF;
11use wcf\util\ClassUtil;
12
13/**
14 * Handles dashboard boxes.
15 *
16 * @author Alexander Ebert
ca4ba303 17 * @copyright 2001-2014 WoltLab GmbH
320f4a6d 18 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
f4f05aa5 19 * @package com.woltlab.wcf
320f4a6d
MW
20 * @subpackage system.dashboard
21 * @category Community Framework
22 */
23class DashboardHandler extends SingletonFactory {
24 /**
25 * list of cached dashboard boxes
0ad90fc3 26 * @var array<\wcf\data\dashboard\box\DashboardBox>
320f4a6d
MW
27 */
28 protected $boxCache = null;
29
30 /**
31 * configuration options for pages
32 * @var array<array>
33 */
34 protected $pageCache = null;
35
36 /**
0ad90fc3 37 * @see \wcf\system\SingletonFactory::init()
320f4a6d
MW
38 */
39 protected function init() {
40 $this->boxCache = DashboardBoxCacheBuilder::getInstance()->getData(array(), 'boxes');
41 $this->pageCache = DashboardBoxCacheBuilder::getInstance()->getData(array(), 'pages');
42 }
43
44 /**
2ae67601 45 * Loads the active dashboard boxes for the given object type and page.
320f4a6d
MW
46 *
47 * @param string $objectType
0ad90fc3 48 * @param \wcf\page\IPage $page
320f4a6d
MW
49 */
50 public function loadBoxes($objectType, IPage $page) {
51 $objectTypeObj = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.user.dashboardContainer', $objectType);
52 if ($objectTypeObj === null) {
53 throw new SystemException("Unable to find object type '".$objectType."' for definition 'com.woltlab.wcf.user.dashboardContainer'");
54 }
55
56 $boxIDs = array();
57 if (isset($this->pageCache[$objectTypeObj->objectTypeID]) && is_array($this->pageCache[$objectTypeObj->objectTypeID])) {
58 foreach ($this->pageCache[$objectTypeObj->objectTypeID] as $boxID) {
59 $boxIDs[] = $boxID;
60 }
61 }
62
63 $contentTemplate = $sidebarTemplate = '';
64 foreach ($boxIDs as $boxID) {
65 $className = $this->boxCache[$boxID]->className;
66 if (!ClassUtil::isInstanceOf($className, 'wcf\system\dashboard\box\IDashboardBox')) {
db387ac1 67 throw new SystemException("'".$className."' does not implement 'wcf\system\dashboard\box\IDashboardBox'");
320f4a6d
MW
68 }
69
70 $boxObject = new $className();
71 $boxObject->init($this->boxCache[$boxID], $page);
72
73 if ($this->boxCache[$boxID]->boxType == 'content') {
74 $contentTemplate .= $boxObject->getTemplate();
75 }
76 else {
77 $sidebarTemplate .= $boxObject->getTemplate();
78 }
79 }
80
81 WCF::getTPL()->assign(array(
82 '__boxContent' => $contentTemplate,
83 '__boxSidebar' => $sidebarTemplate
84 ));
85 }
86
87 /**
88 * Sets default values upon installation, you should not call this method
89 * under any other circumstances. If you do not specify a list of box names,
90 * all boxes will be assigned as disabled for given object type.
91 *
92 * @param string $objectType
93 * @param array<names> $enableBoxNames
94 */
95 public static function setDefaultValues($objectType, array $enableBoxNames = array()) {
96 $objectTypeID = 0;
97
98 // no boxes given, aborting
99 if (empty($enableBoxNames)) {
100 return;
101 }
102
103 // get object type id (cache might be outdated)
104 if (PACKAGE_ID && PACKAGE_ID != 1) {
105 // reset object type cache
106 ObjectTypeCache::getInstance()->resetCache();
107
108 // get object type
109 $objectTypeObj = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.user.dashboardContainer', $objectType);
110 if ($objectTypeObj === null) {
111 throw new SystemException("Object type '".$objectType."' is not valid for definition 'com.woltlab.wcf.user.dashboardContainer'");
112 }
113
114 $objectTypeID = $objectTypeObj->objectTypeID;
115
116 // select available box ids
117 $conditions = new PreparedStatementConditionBuilder();
118 $conditions->add("boxName IN (?)", array(array_keys($enableBoxNames)));
119
120 $sql = "SELECT boxID, boxName, boxType
121 FROM wcf".WCF_N."_dashboard_box
122 ".$conditions;
123 $statement = WCF::getDB()->prepareStatement($sql);
124 $statement->execute($conditions->getParameters());
125 }
126 else {
127 // work-around during WCFSetup
128 $conditions = new PreparedStatementConditionBuilder();
129 $conditions->add("object_type.objectType = ?", array($objectType));
130 $conditions->add("object_type_definition.definitionName = ?", array('com.woltlab.wcf.user.dashboardContainer'));
131
132 $sql = "SELECT object_type.objectTypeID
133 FROM wcf".WCF_N."_object_type object_type
134 LEFT JOIN wcf".WCF_N."_object_type_definition object_type_definition
135 ON (object_type_definition.definitionID = object_type.definitionID)
136 ".$conditions;
137 $statement = WCF::getDB()->prepareStatement($sql);
138 $statement->execute($conditions->getParameters());
139 $row = $statement->fetchArray();
140 if ($row) {
141 $objectTypeID = $row['objectTypeID'];
142 }
143
144 if (!$objectTypeID) {
145 throw new SystemException("Object type '".$objectType."' is not valid for definition 'com.woltlab.wcf.user.dashboardContainer'");
146 }
147
148 // select available box ids
149 $conditions = new PreparedStatementConditionBuilder();
150 $conditions->add("boxName IN (?)", array(array_keys($enableBoxNames)));
151
152 $sql = "SELECT boxID, boxName, boxType
153 FROM wcf".WCF_N."_dashboard_box
154 ".$conditions;
155 $statement = WCF::getDB()->prepareStatement($sql);
156 $statement->execute($conditions->getParameters());
157 }
158
159 $boxes = array();
160 while ($row = $statement->fetchArray()) {
161 $boxes[$row['boxID']] = new DashboardBox(null, $row);
162 }
163
164 if (!empty($boxes)) {
165 $sql = "UPDATE wcf".WCF_N."_dashboard_option
166 SET showOrder = showOrder + 1
167 WHERE objectTypeID = ?
168 AND boxID IN (SELECT boxID FROM wcf".WCF_N."_dashboard_box WHERE boxType = ?)
169 AND showOrder >= ?";
170 $updateStatement = WCF::getDB()->prepareStatement($sql);
171 $sql = "INSERT INTO wcf".WCF_N."_dashboard_option
172 (objectTypeID, boxID, showOrder)
173 VALUES (?, ?, ?)";
174 $insertStatement = WCF::getDB()->prepareStatement($sql);
175
176 WCF::getDB()->beginTransaction();
177 foreach ($boxes as $boxID => $box) {
178 // move other boxes
179 $updateStatement->execute(array(
180 $objectTypeID,
181 $box->boxType,
182 $enableBoxNames[$box->boxName]
183 ));
184
185 // insert associations
186 $insertStatement->execute(array(
187 $objectTypeID,
188 $boxID,
189 $enableBoxNames[$box->boxName]
190 ));
191 }
192 WCF::getDB()->commitTransaction();
193 }
194 }
195
196 /**
197 * Clears dashboard box cache.
198 */
199 public static function clearCache() {
200 DashboardBoxCacheBuilder::getInstance()->reset();
201 }
202}