/**
  * @see	\wcf\system\faker\AbstractLikeFaker::getLikeableObject()
  */
 public function getLikeableObjectID()
 {
     $sql = "SELECT\t\tcommentID\n\t\t\tFROM\t\twcf" . WCF_N . "_comment\n\t\t\t" . $this->condition;
     $statement = \wcf\system\WCF::getDB()->prepareStatement($sql, 1, $this->generator->numberBetween(0, $this->commentCount - 1));
     $statement->execute($this->condition->getParameters());
     return $statement->fetchColumn();
 }
 /**
  * @see	\wcf\system\search\acp\IACPSearchResultProvider::search()
  */
 public function search($query)
 {
     if (!WCF::getSession()->getPermission('admin.system.package.canUpdatePackage') && !WCF::getSession()->getPermission('admin.system.package.canUninstallPackage')) {
         return array();
     }
     $results = array();
     // search by language item
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("languageID = ?", array(WCF::getLanguage()->languageID));
     $conditions->add("languageItem LIKE ?", array('wcf.acp.package.packageName.package%'));
     $conditions->add("languageItemValue LIKE ?", array('%' . $query . '%'));
     $sql = "SELECT\t\tlanguageItem\n\t\t\tFROM\t\twcf" . WCF_N . "_language_item\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $packageIDs = array();
     while ($row = $statement->fetchArray()) {
         $packageIDs[] = str_replace('wcf.acp.package.packageName.package', '', $row['languageItem']);
     }
     $conditions = new PreparedStatementConditionBuilder(false);
     if (!empty($packageIDs)) {
         $conditions->add("packageID IN (?)", array($packageIDs));
     }
     $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\tWHERE\tpackageName LIKE ?\n\t\t\t\tOR package LIKE ?\n\t\t\t\t" . (count($conditions->getParameters()) ? "OR " . $conditions : "");
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array_merge(array($query . '%', $query . '%'), $conditions->getParameters()));
     while ($package = $statement->fetchObject('wcf\\data\\package\\Package')) {
         $results[] = new ACPSearchResult($package->getName(), LinkHandler::getInstance()->getLink('Package', array('id' => $package->packageID, 'title' => $package->getName())));
     }
     return $results;
 }
예제 #3
0
 /**
  * @see	\wcf\data\AbstractDatabaseObjectAction::delete()
  */
 public function delete()
 {
     parent::delete();
     if (!empty($this->objects)) {
         // identify i18n labels
         $languageVariables = array();
         foreach ($this->objects as $object) {
             if (preg_match('~wcf.acp.label.label\\d+~', $object->label)) {
                 $languageVariables[] = $object->label;
             }
         }
         // remove language variables
         if (!empty($languageVariables)) {
             $conditions = new PreparedStatementConditionBuilder();
             $conditions->add("languageItem IN (?)", array($languageVariables));
             $sql = "SELECT\tlanguageItemID\n\t\t\t\t\tFROM\twcf" . WCF_N . "_language_item\n\t\t\t\t\t" . $conditions;
             $statement = WCF::getDB()->prepareStatement($sql);
             $statement->execute($conditions->getParameters());
             $languageItemIDs = array();
             while ($row = $statement->fetchArray()) {
                 $languageItemIDs[] = $row['languageItemID'];
             }
             $objectAction = new LanguageItemAction($languageItemIDs, 'delete');
             $objectAction->executeAction();
         }
     }
 }
예제 #4
0
 /**
  * @see wcf\system\setup\IFileHandler::logFiles()
  */
 public function logFiles(array $files)
 {
     if (empty($files)) {
         return;
     }
     // fetch already installed files
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("packageID = ?", array($this->packageInstallation->getPackageID()));
     $conditions->add("filename IN (?)", array($files));
     $sql = "SELECT\tfilename\n\t\t\tFROM\twcf" . WCF_N . "_package_installation_file_log\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $installedFiles = array();
     while ($row = $statement->fetchArray()) {
         $installedFiles[] = $row['filename'];
     }
     // ignore files which have already been installed
     $installFiles = array();
     foreach ($files as $file) {
         if (in_array($file, $installedFiles)) {
             continue;
         }
         $installFiles[] = $file;
     }
     if (!empty($installFiles)) {
         $sql = "INSERT INTO\twcf" . WCF_N . "_package_installation_file_log\n\t\t\t\t\t\t(packageID, filename)\n\t\t\t\tVALUES\t\t(?, ?)";
         $statement = WCF::getDB()->prepareStatement($sql);
         foreach ($installFiles as $file) {
             $statement->execute(array($this->packageInstallation->getPackageID(), $file));
         }
     }
 }
 /**
  * Updates the participants of this conversation.
  * 
  * @param	array<integer>	$participantIDs
  * @param	array<integer>	$invisibleParticipantIDs
  */
 public function updateParticipants(array $participantIDs, array $invisibleParticipantIDs = array())
 {
     $usernames = array();
     if (!empty($participantIDs) || !empty($invisibleParticipantIDs)) {
         $conditions = new PreparedStatementConditionBuilder();
         $conditions->add("userID IN (?)", array(array_merge($participantIDs, $invisibleParticipantIDs)));
         $sql = "SELECT\tuserID, username\n\t\t\t\tFROM\twcf" . WCF_N . "_user\n\t\t\t\t" . $conditions;
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute($conditions->getParameters());
         while ($row = $statement->fetchArray()) {
             $usernames[$row['userID']] = $row['username'];
         }
     }
     if (!empty($participantIDs)) {
         WCF::getDB()->beginTransaction();
         $sql = "INSERT INTO\t\twcf" . WCF_N . "_conversation_to_user\n\t\t\t\t\t\t\t(conversationID, participantID, username, isInvisible)\n\t\t\t\tVALUES\t\t\t(?, ?, ?, ?)\n\t\t\t\tON DUPLICATE KEY\n\t\t\t\tUPDATE\t\t\thideConversation = 0";
         $statement = WCF::getDB()->prepareStatement($sql);
         foreach ($participantIDs as $userID) {
             $statement->execute(array($this->conversationID, $userID, $usernames[$userID], 0));
         }
         WCF::getDB()->commitTransaction();
     }
     if (!empty($invisibleParticipantIDs)) {
         WCF::getDB()->beginTransaction();
         $sql = "INSERT INTO\t\twcf" . WCF_N . "_conversation_to_user\n\t\t\t\t\t\t\t(conversationID, participantID, username, isInvisible)\n\t\t\t\tVALUES\t\t\t(?, ?, ?, ?)";
         $statement = WCF::getDB()->prepareStatement($sql);
         foreach ($invisibleParticipantIDs as $userID) {
             $statement->execute(array($this->conversationID, $userID, $usernames[$userID], 1));
         }
         WCF::getDB()->commitTransaction();
     }
     $this->updateParticipantCount();
 }
 /**
  * @see	\wcf\system\cache\builder\AbstractCacheBuilder::rebuild()
  */
 protected function rebuild(array $parameters)
 {
     $data = array('boxes' => array(), 'pages' => array());
     // load boxes
     $boxList = new DashboardBoxList();
     $boxList->readObjects();
     foreach ($boxList as $box) {
         $data['boxes'][$box->boxID] = $box;
     }
     // load settings
     $objectTypes = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.user.dashboardContainer');
     $objectTypeIDs = array();
     foreach ($objectTypes as $objectType) {
         $objectTypeIDs[] = $objectType->objectTypeID;
     }
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("objectTypeID IN (?)", array($objectTypeIDs));
     $sql = "SELECT\t\t*\n\t\t\tFROM\t\twcf" . WCF_N . "_dashboard_option\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\tshowOrder ASC";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     while ($row = $statement->fetchArray()) {
         if (!isset($data['pages'][$row['objectTypeID']])) {
             $data['pages'][$row['objectTypeID']] = array();
         }
         $data['pages'][$row['objectTypeID']][] = $row['boxID'];
     }
     return $data;
 }
예제 #7
0
 protected function getTopOptionCategories($packageID)
 {
     // get all option categories and filter categories with low priority
     $sql = "SELECT\t\tcategoryName, categoryID \n\t\t\tFROM\t\twcf" . WCF_N . "_option_category option_category\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package_dependency package_dependency\n\t\t\tON\t\t(package_dependency.dependency = option_category.packageID)\n\t\t\tWHERE \t\tpackage_dependency.packageID = ?\n\t\t\tORDER BY\tpackage_dependency.priority ASC";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array($packageID));
     $optionCategories = array();
     while ($row = $statement->fetchArray()) {
         $optionCategories[$row['categoryName']] = $row['categoryID'];
     }
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("categoryID IN (?)", array($optionCategories));
     $statementParameters = $conditions->getParameters();
     array_unshift($statementParameters, $packageID);
     $sql = "SELECT \t\tcategoryID, parentCategoryName, categoryName,\n\t\t\t\t\t(\n\t\t\t\t\t\tSELECT COUNT(*) FROM wcf" . WCF_N . "_option WHERE categoryName = category.categoryName AND packageID IN (\n\t\t\t\t\t\t\tSELECT dependency FROM wcf" . WCF_N . "_package_dependency WHERE packageID = ?\n\t\t\t\t\t\t)\n\t\t\t\t\t) AS count\n\t\t\tFROM\t\twcf" . WCF_N . "_option_category category\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($statementParameters);
     while ($row = $statement->fetchArray()) {
         if (!isset($this->optionCategoryStructure[$row['parentCategoryName']])) {
             $this->optionCategoryStructure[$row['parentCategoryName']] = array();
         }
         $this->optionCategoryStructure[$row['parentCategoryName']][] = $row;
     }
     $topOptionCategories = array();
     foreach ($this->optionCategoryStructure[''] as $optionCategory) {
         $count = $optionCategory['count'] + $this->countOptions($optionCategory['categoryName']);
         if ($count > 0) {
             $topOptionCategories[] = $optionCategory['categoryID'];
         }
     }
     return $topOptionCategories;
 }
예제 #8
0
 /**
  * @see wcf\system\cache\ICacheBuilder::getData()
  */
 public function getData(array $cacheResource)
 {
     list($cache, $packageID) = explode('-', $cacheResource['cache']);
     $data = array();
     // get all menu items and filter menu items with low priority
     $sql = "SELECT\t\tmenuItem, menuItemID \n\t\t\tFROM\t\twcf" . WCF_N . "_page_menu_item menu_item\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_package_dependency package_dependency\n\t\t\tON\t\t(package_dependency.dependency = menu_item.packageID)\n\t\t\tWHERE \t\tpackage_dependency.packageID = ?\n\t\t\tORDER BY\tpackage_dependency.priority ASC";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array($packageID));
     $itemIDs = array();
     while ($row = $statement->fetchArray()) {
         $itemIDs[$row['menuItem']] = $row['menuItemID'];
     }
     if (count($itemIDs) > 0) {
         // get needed menu items and build item tree
         $conditions = new PreparedStatementConditionBuilder();
         $conditions->add("menu_item.menuItemID IN (?)", array($itemIDs));
         $conditions->add("menu_item.isDisabled = ?", array(0));
         $sql = "SELECT\t\tmenuItemID, menuItem, parentMenuItem, menuItemLink,\n\t\t\t\t\t\tpermissions, options, packageDir, menuPosition, className,\n\t\t\t\t\t\tCASE WHEN parentPackageID <> 0 THEN parentPackageID ELSE menu_item.packageID END AS packageID\n\t\t\t\tFROM\t\twcf" . WCF_N . "_page_menu_item menu_item\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\t\tON\t\t(package.packageID = menu_item.packageID)\n\t\t\t\t" . $conditions . "\n\t\t\t\tORDER BY\tshowOrder ASC";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute($conditions->getParameters());
         while ($row = $statement->fetchArray()) {
             $data[$row['parentMenuItem'] ? $row['parentMenuItem'] : $row['menuPosition']][] = new PageMenuItem(null, $row);
         }
     }
     return $data;
 }
예제 #9
0
 /**
  * @see	\wcf\system\setup\IFileHandler::checkFiles()
  */
 public function checkFiles(array $files)
 {
     if ($this->packageInstallation->getPackage()->package != 'com.woltlab.wcf') {
         if (!empty($files)) {
             // get registered files of other packages for the
             // same application
             $conditions = new PreparedStatementConditionBuilder();
             $conditions->add('packageID <> ?', array($this->packageInstallation->getPackageID()));
             $conditions->add('filename IN (?)', array($files));
             $conditions->add('application = ?', array($this->application));
             $sql = "SELECT\tfilename, packageID\n\t\t\t\t\tFROM\twcf" . WCF_N . "_package_installation_file_log\n\t\t\t\t\t" . $conditions;
             $statement = WCF::getDB()->prepareStatement($sql);
             $statement->execute($conditions->getParameters());
             $lockedFiles = array();
             while ($row = $statement->fetchArray()) {
                 $lockedFiles[$row['filename']] = $row['packageID'];
             }
             // check delivered files
             if (!empty($lockedFiles)) {
                 foreach ($files as $key => $file) {
                     if (isset($lockedFiles[$file])) {
                         $owningPackage = new Package($lockedFiles[$file]);
                         throw new SystemException("A package can't overwrite files from other packages. Only an update from the package which owns the file can do that. (Package '" . $this->packageInstallation->getPackage()->package . "' tries to overwrite file '" . $file . "', which is owned by package '" . $owningPackage->package . "')");
                     }
                 }
             }
         }
     }
 }
 /**
  * @see	\wcf\system\moderation\queue\IModerationQueueHandler::assignQueues()
  */
 public function assignQueues(array $queues)
 {
     $assignments = array();
     // read comments and responses
     $responseIDs = array();
     foreach ($queues as $queue) {
         $responseIDs[] = $queue->objectID;
     }
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("comment_response.responseID IN (?)", array($responseIDs));
     $sql = "SELECT\t\tcomment_response.responseID, comment.commentID, comment.objectTypeID, comment.objectID\n\t\t\tFROM\t\twcf" . WCF_N . "_comment_response comment_response\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_comment comment\n\t\t\tON\t\t(comment.commentID = comment_response.commentID)\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $comments = $responses = array();
     while ($row = $statement->fetchArray()) {
         $comments[$row['commentID']] = new Comment(null, $row);
         $responses[$row['responseID']] = new CommentResponse(null, $row);
     }
     $orphanedQueueIDs = array();
     foreach ($queues as $queue) {
         $assignUser = false;
         if (!isset($responses[$queue->objectID]) || !isset($comments[$responses[$queue->objectID]->commentID])) {
             $orphanedQueueIDs[] = $queue->queueID;
             continue;
         }
         $comment = $comments[$responses[$queue->objectID]->commentID];
         if ($this->getCommentManager($comment)->canModerate($comment->objectTypeID, $comment->objectID)) {
             $assignUser = true;
         }
         $assignments[$queue->queueID] = $assignUser;
     }
     ModerationQueueManager::getInstance()->removeOrphans($orphanedQueueIDs);
     ModerationQueueManager::getInstance()->setAssignment($assignments);
 }
예제 #11
0
 /**
  * @see	\wcf\data\ISortableAction::validateUpdatePosition()
  */
 public function validateUpdatePosition()
 {
     if (!WCF::getSession()->getPermission('admin.project.canEditProject')) {
         throw new PermissionDeniedException();
     }
     if (!isset($this->parameters['data']['structure'])) {
         throw new UserInputException('structure');
     }
     $projectIDs = array();
     foreach ($this->parameters['data']['structure'][0] as $projectID) {
         if (!$projectID) {
             throw new UserInputException('structure');
         }
         $projectIDs[] = $projectID;
     }
     $projectIDs = array_unique($projectIDs);
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("projectID IN (?)", array($projectIDs));
     $sql = "SELECT\tprojectID\n\t\t\t\tFROM\tict" . WCF_N . "_project\n\t\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     while ($row = $statement->fetchArray()) {
         $key = array_search($row['projectID'], $projectIDs);
         if ($key !== false) {
             unset($projectIDs[$key]);
         }
     }
     if (!empty($projectIDs)) {
         throw new UserInputException('structure');
     }
 }
예제 #12
0
 /**
  * Loads storage for a given set of users.
  * 
  * @param	array<integer>	$userIDs
  * @param	integer		$packageID
  */
 public function loadStorage(array $userIDs, $packageID = PACKAGE_ID)
 {
     $tmp = array();
     foreach ($userIDs as $userID) {
         if (!isset($this->cache[$userID])) {
             $tmp[] = $userID;
         }
     }
     // ignore users whose storage data is already loaded
     if (empty($tmp)) {
         return;
     }
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("userID IN (?)", array($tmp));
     $conditions->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies($packageID)));
     $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_user_storage\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     while ($row = $statement->fetchArray()) {
         if (!isset($this->cache[$row['userID']])) {
             $this->cache[$row['userID']] = array();
         }
         $this->cache[$row['userID']][$row['field']] = $row['fieldValue'];
     }
 }
 /**
  * @see	\wcf\system\event\listener\IParameterizedEventListener::execute()
  */
 public function execute($eventObj, $className, $eventName, array &$parameters)
 {
     // conversation
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("userID IN (?)", array($eventObj->mergedUserIDs));
     $sql = "UPDATE\twcf" . WCF_N . "_conversation\n\t\t\tSET\tuserID = ?\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array_merge(array($eventObj->destinationUserID), $conditions->getParameters()));
     // conversation_to_user
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("participantID IN (?)", array($eventObj->mergedUserIDs));
     $sql = "UPDATE IGNORE\twcf" . WCF_N . "_conversation_to_user\n\t\t\tSET\t\tparticipantID = ?\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array_merge(array($eventObj->destinationUserID), $conditions->getParameters()));
     // conversation_message
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("userID IN (?)", array($eventObj->mergedUserIDs));
     $sql = "UPDATE\twcf" . WCF_N . "_conversation_message\n\t\t\tSET\tuserID = ?\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array_merge(array($eventObj->destinationUserID), $conditions->getParameters()));
     // conversation_label
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("userID IN (?)", array($eventObj->mergedUserIDs));
     $sql = "UPDATE\twcf" . WCF_N . "_conversation_label\n\t\t\tSET\tuserID = ?\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array_merge(array($eventObj->destinationUserID), $conditions->getParameters()));
 }
 /**
  * @see	\wcf\system\worker\IWorker::execute()
  */
 public function execute()
 {
     parent::execute();
     $users = $userIDs = array();
     foreach ($this->getObjectList() as $user) {
         $users[] = new UserEditor($user);
         $userIDs[] = $user->userID;
     }
     // update user ranks
     if (!empty($users)) {
         $action = new UserProfileAction($users, 'updateUserOnlineMarking');
         $action->executeAction();
     }
     if (!empty($userIDs)) {
         // update activity points
         UserActivityPointHandler::getInstance()->updateUsers($userIDs);
         // update like counter
         if (MODULE_LIKE) {
             $conditionBuilder = new PreparedStatementConditionBuilder();
             $conditionBuilder->add('user_table.userID IN (?)', array($userIDs));
             $sql = "UPDATE\twcf" . WCF_N . "_user user_table\n\t\t\t\t\tSET\tlikesReceived = (\n\t\t\t\t\t\t\tSELECT\tCOUNT(*)\n\t\t\t\t\t\t\tFROM\twcf" . WCF_N . "_like\n\t\t\t\t\t\t\tWHERE\tobjectUserID = user_table.userID\n\t\t\t\t\t\t\t\tAND likeValue = " . Like::LIKE . "\n\t\t\t\t\t\t)\n\t\t\t\t\t" . $conditionBuilder;
             $statement = WCF::getDB()->prepareStatement($sql);
             $statement->execute($conditionBuilder->getParameters());
         }
     }
 }
 /**
  * @inheritDoc
  */
 public function getOutstandingItemCount($objectID = null)
 {
     if ($this->notifications === null) {
         $this->notifications = 0;
         if (WCF::getUser()->userID) {
             $data = UserStorageHandler::getInstance()->getField('filebaseUnreaWatchedEntries');
             // cache does not exist or is outdated
             if ($data === null) {
                 $categoryIDs = FilebaseCategory::getAccessibleCategoryIDs();
                 if (!empty($categoryIDs)) {
                     $objectTypeID = UserObjectWatchHandler::getInstance()->getObjectTypeID('de.incendium.filebase.entry');
                     $conditionBuilder = new PreparedStatementConditionBuilder();
                     $conditionBuilder->add('user_object_watch.objectTypeID = ?', array($objectTypeID));
                     $conditionBuilder->add('user_object_watch.userID = ?', array(WCF::getUser()->userID));
                     $conditionBuilder->add('entry.lastChangeTime > ?', array(VisitTracker::getInstance()->getVisitTime('de.incendium.filebase.entry')));
                     $conditionBuilder->add('entry.entryID IN (SELECT entryID FROM filebase' . WCF_N . '_entry_to_category WHERE categoryID IN (?))', array($categoryIDs));
                     $conditionBuilder->add('entry.isDeleted = 0 AND entry.isDisabled = 0');
                     $conditionBuilder->add('(entry.lastChangeTime > tracked_file_visit.visitTime OR tracked_file_visit.visitTime IS NULL)');
                     $sql = "SELECT        COUNT(*) AS count\n                            FROM        wcf" . WCF_N . "_user_object_watch user_object_watch\n                            LEFT JOIN    filebase" . WCF_N . "_entry entry\n                            ON        (entry.entryID = user_object_watch.objectID)\n                            LEFT JOIN    wcf" . WCF_N . "_tracked_visit tracked_file_visit\n                            ON        (tracked_file_visit.objectTypeID = " . VisitTracker::getInstance()->getObjectTypeID('de.incendium.filebase.entry') . " AND tracked_file_visit.objectID = entry.entryID AND tracked_file_visit.userID = " . WCF::getUser()->userID . ")\n                            " . $conditionBuilder;
                     $statement = WCF::getDB()->prepareStatement($sql);
                     $statement->execute($conditionBuilder->getParameters());
                     $row = $statement->fetchArray();
                     $this->notifications = $row['count'];
                 }
                 // update storage data
                 UserStorageHandler::getInstance()->update(WCF::getUser()->userID, 'filebaseUnreadWatchedEntries', $this->notifications);
             } else {
                 $this->notifications = $data;
             }
         }
     }
     return $this->notifications;
 }
예제 #16
0
 /**
  * Reads associated tags.
  */
 protected function getTags()
 {
     $this->tags = array();
     if (!empty($this->objectTypeIDs)) {
         // get tag ids
         $tagIDs = array();
         $conditionBuilder = new PreparedStatementConditionBuilder();
         $conditionBuilder->add('object.objectTypeID IN (?)', array($this->objectTypeIDs));
         $conditionBuilder->add('object.languageID IN (?)', array($this->languageIDs));
         $sql = "SELECT\t\tCOUNT(*) AS counter, object.tagID\n\t\t\t\tFROM\t\twcf" . WCF_N . "_tag_to_object object\n\t\t\t\t" . $conditionBuilder . "\n\t\t\t\tGROUP BY\tobject.tagID\n\t\t\t\tORDER BY\tcounter DESC";
         $statement = WCF::getDB()->prepareStatement($sql, 500);
         $statement->execute($conditionBuilder->getParameters());
         while ($row = $statement->fetchArray()) {
             $tagIDs[$row['tagID']] = $row['counter'];
         }
         // get tags
         if (!empty($tagIDs)) {
             $sql = "SELECT\t*\n\t\t\t\t\tFROM\twcf" . WCF_N . "_tag\n\t\t\t\t\tWHERE\ttagID IN (?" . (count($tagIDs) > 1 ? str_repeat(',?', count($tagIDs) - 1) : '') . ")";
             $statement = WCF::getDB()->prepareStatement($sql);
             $statement->execute(array_keys($tagIDs));
             while ($row = $statement->fetchArray()) {
                 $row['counter'] = $tagIDs[$row['tagID']];
                 $this->tags[$row['name']] = new TagCloudTag(new Tag(null, $row));
             }
             // sort by counter
             uasort($this->tags, array('self', 'compareTags'));
         }
     }
 }
예제 #17
0
	/**
	 * Compiles LESS stylesheets.
	 * 
	 * @param	wcf\data\style\Style	$style
	 */
	public function compile(Style $style) {
		// read stylesheets by dependency order
		$conditions = new PreparedStatementConditionBuilder();
		$conditions->add("file_log.filename REGEXP ?", array('style/([a-zA-Z0-9\_\-\.]+)\.less'));
		
		$sql = "SELECT		file_log.filename, package.packageDir
			FROM		wcf".WCF_N."_package_installation_file_log file_log
			LEFT JOIN	wcf".WCF_N."_package package
			ON		(file_log.packageID = package.packageID)
			".$conditions;
		$statement = WCF::getDB()->prepareStatement($sql);
		$statement->execute($conditions->getParameters());
		$files = array();
		while ($row = $statement->fetchArray()) {
			$files[] = WCF_DIR.$row['packageDir'].$row['filename'];
		}
		
		// get style variables
		$variables = $style->getVariables();
		$individualLess = '';
		if (isset($variables['individualLess'])) {
			$individualLess = $variables['individualLess'];
			unset($variables['individualLess']);
		}
		
		$this->compileStylesheet(
			WCF_DIR.'style/style-'.$style->styleID,
			$files,
			$variables,
			$individualLess,
			new Callback(function($content) use ($style) {
				return "/* stylesheet for '".$style->styleName."', generated on ".gmdate('r')." -- DO NOT EDIT */\n\n" . $content;
			})
		);
	}
 /**
  * @see	\wcf\system\like\IViewableLikeProvider::prepare()
  */
 public function prepare(array $likes)
 {
     $responseIDs = array();
     foreach ($likes as $like) {
         $responseIDs[] = $like->objectID;
     }
     // get objects type ids
     $responses = array();
     $conditionBuilder = new PreparedStatementConditionBuilder();
     $conditionBuilder->add('comment_response.responseID IN (?)', array($responseIDs));
     $sql = "SELECT\t\tcomment.objectTypeID, comment_response.responseID\n\t\t\tFROM\t\twcf" . WCF_N . "_comment_response comment_response\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_comment comment\n\t\t\tON\t\t(comment.commentID = comment_response.commentID)\n\t\t\t" . $conditionBuilder;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditionBuilder->getParameters());
     while ($row = $statement->fetchArray()) {
         $responses[$row['responseID']] = $row['objectTypeID'];
     }
     // group likes by object type id
     $likeData = array();
     foreach ($likes as $like) {
         if (isset($responses[$like->objectID])) {
             if (!isset($likeData[$responses[$like->objectID]])) {
                 $likeData[$responses[$like->objectID]] = array();
             }
             $likeData[$responses[$like->objectID]][] = $like;
         }
     }
     foreach ($likeData as $objectTypeID => $likes) {
         $objectType = CommentHandler::getInstance()->getObjectType($objectTypeID);
         if (CommentHandler::getInstance()->getCommentManager($objectType->objectType) instanceof IViewableLikeProvider) {
             CommentHandler::getInstance()->getCommentManager($objectType->objectType)->prepare($likes);
         }
     }
 }
예제 #19
0
 /**
  * @see	\wcf\system\setup\IFileHandler::logFiles()
  */
 public function logFiles(array $files)
 {
     $packageID = $this->packageInstallation->getPackageID();
     // remove file extension
     foreach ($files as &$file) {
         $file = substr($file, 0, -4);
     }
     unset($file);
     // get existing templates
     $existingTemplates = $updateTemplateIDs = array();
     $sql = "SELECT\ttemplateName, templateID\n\t\t\tFROM\twcf" . WCF_N . "_template\n\t\t\tWHERE\tpackageID = ?\n\t\t\t\tAND application = ?\n\t\t\t\tAND templateGroupID IS NULL";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute(array($packageID, $this->application));
     while ($row = $statement->fetchArray()) {
         $existingTemplates[$row['templateName']] = $row['templateID'];
     }
     // save new templates
     $sql = "INSERT INTO\twcf" . WCF_N . "_template\n\t\t\t\t\t(packageID, templateName, lastModificationTime, application)\n\t\t\tVALUES\t\t(?, ?, ?, ?)";
     $statement = WCF::getDB()->prepareStatement($sql);
     foreach ($files as $file) {
         if (isset($existingTemplates[$file])) {
             $updateTemplateIDs[] = $existingTemplates[$file];
             continue;
         }
         $statement->execute(array($packageID, $file, TIME_NOW, $this->application));
     }
     if (!empty($updateTemplateIDs)) {
         // update old templates
         $conditionBuilder = new PreparedStatementConditionBuilder();
         $conditionBuilder->add('templateID IN (?)', array($updateTemplateIDs));
         $sql = "UPDATE\twcf" . WCF_N . "_template\n\t\t\t\tSET\tlastModificationTime = ?\n\t\t\t\t" . $conditionBuilder;
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute(array_merge(array(TIME_NOW), $conditionBuilder->getParameters()));
     }
 }
예제 #20
0
	/**
	 * Loads storage for a given set of users.
	 * 
	 * @param	array<integer>	$userIDs
	 */
	public function loadStorage(array $userIDs) {
		$tmp = array();
		foreach ($userIDs as $userID) {
			if (!isset($this->cache[$userID])) $tmp[] = $userID;
		}
		
		// ignore users whose storage data is already loaded
		if (empty($tmp)) return;
		
		$conditions = new PreparedStatementConditionBuilder();
		$conditions->add("userID IN (?)", array($tmp));
		
		$sql = "SELECT	*
			FROM	wcf".WCF_N."_user_storage
			".$conditions;
		$statement = WCF::getDB()->prepareStatement($sql);
		$statement->execute($conditions->getParameters());
		while ($row = $statement->fetchArray()) {
			if (!isset($this->cache[$row['userID']])) {
				$this->cache[$row['userID']] = array();
			}
			
			$this->cache[$row['userID']][$row['field']] = $row['fieldValue'];
		}
	}
 /**
  * Rebuilds entry data.
  * 
  * @param	array<integer>		$entryIDs
  */
 public static function rebuildEntryData(array $entryIDs)
 {
     $conditionBuilder = new PreparedStatementConditionBuilder();
     $conditionBuilder->add('entryID IN (?)', array($entryIDs));
     $sql = "UPDATE\tfilebase" . WCF_N . "_entry entry\n\t\t\tSET\tfiles = IF(entry.isDeleted = 0 AND entry.isDisabled = 0, (\n\t\t\t\t\tSELECT\t\tCOUNT(*)\n\t\t\t\t\tFROM\t\tfilebase" . WCF_N . "_file\n\t\t\t\t\tWHERE\t\tentryID = entry.entryID\n\t\t\t\t\t\t\tAND isDisabled = 0\n\t\t\t\t\t\t\tAND isDeleted = 0\n\t\t\t\t), 0),\n                \n                lastFileID = COALESCE((\n\t\t\t\t\tSELECT\t\tfileID\n\t\t\t\t\tFROM\t\tfilebase" . WCF_N . "_file\n\t\t\t\t\tWHERE\t\tentryID = entry.entryID\n\t\t\t\t\t\t\tAND isDisabled = entry.isDisabled\n\t\t\t\t\t\t\tAND isDeleted = entry.isDeleted\n\t\t\t\t\tORDER BY\ttime DESC\n\t\t\t\t\tLIMIT\t\t1\n\t\t\t\t), lastFileID)\n\t\t\t" . $conditionBuilder;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditionBuilder->getParameters());
 }
예제 #22
0
 /**
  * Removes a list of polls by id.
  * 
  * @param	array<integer>		$pollIDs
  */
 public function removePolls(array $pollIDs)
 {
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("pollID IN (?)", array($pollIDs));
     $sql = "DELETE FROM\twcf" . WCF_N . "_poll\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
 }
예제 #23
0
 /**
  * Deletes active sessions of the given users.
  * 
  * @param	array<integer>	$userIDs
  */
 public static function deleteUserSessions(array $userIDs = array())
 {
     $conditionBuilder = new PreparedStatementConditionBuilder();
     if (!empty($userIDs)) {
         $conditionBuilder->add('userID IN (?)', array($userIDs));
     }
     $sql = "DELETE FROM\t" . call_user_func(array(static::$baseClass, 'getDatabaseTableName')) . "\n\t\t\t" . $conditionBuilder;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditionBuilder->getParameters());
 }
예제 #24
0
 /**
  * @see wcf\system\cache\ICacheBuilder::getData()
  */
 public function getData(array $cacheResource)
 {
     // get next execution time
     $conditionBuilder = new PreparedStatementConditionBuilder();
     $conditionBuilder->add("packageID IN (?)", array(PackageDependencyHandler::getInstance()->getDependencies()));
     $sql = "SELECT\t\tMIN(nextExec) AS nextExec,\n\t\t\t\t\tMIN(afterNextExec) AS afterNextExec\n\t\t\tFROM\t\twcf" . WCF_N . "_cronjob\n\t\t\t" . $conditionBuilder->__toString();
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditionBuilder->getParameters());
     $row = $statement->fetchArray();
     return array('afterNextExec' => $row['afterNextExec'], 'nextExec' => $row['nextExec']);
 }
예제 #25
0
 /**
  * @see	\wcf\system\cache\builder\AbstractCacheBuilder::rebuild()
  */
 public function rebuild(array $parameters)
 {
     $data = array('categories' => array(), 'options' => array(), 'categoryStructure' => array(), 'optionToCategories' => array());
     // option categories
     // get all option categories and sort categories by priority
     $sql = "SELECT\tcategoryName, categoryID\n\t\t\tFROM\twcf" . WCF_N . "_" . $this->tableName . "_category";
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute();
     $optionCategories = array();
     while ($row = $statement->fetchArray()) {
         $optionCategories[$row['categoryName']] = $row['categoryID'];
     }
     if (!empty($optionCategories)) {
         // get needed option categories
         $conditions = new PreparedStatementConditionBuilder();
         $conditions->add("categoryID IN (?)", array($optionCategories));
         $sql = "SELECT\t\toption_category.*, package.packageDir\n\t\t\t\tFROM\t\twcf" . WCF_N . "_" . $this->tableName . "_category option_category\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_package package\n\t\t\t\tON\t\t(package.packageID = option_category.packageID)\n\t\t\t\t" . $conditions . "\n\t\t\t\tORDER BY\tshowOrder ASC";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute($conditions->getParameters());
         while ($row = $statement->fetchArray()) {
             $data['categories'][$row['categoryName']] = new OptionCategory(null, $row);
             if (!isset($data['categoryStructure'][$row['parentCategoryName']])) {
                 $data['categoryStructure'][$row['parentCategoryName']] = array();
             }
             $data['categoryStructure'][$row['parentCategoryName']][] = $row['categoryName'];
         }
     }
     // options
     // get all options and sort options by priority
     $optionIDs = array();
     $sql = "SELECT\t\toptionName, optionID\n\t\t\tFROM\t\twcf" . WCF_N . "_" . $this->tableName;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute();
     while ($row = $statement->fetchArray()) {
         $optionIDs[$row['optionName']] = $row['optionID'];
     }
     if (!empty($optionIDs)) {
         // get needed options
         $conditions = new PreparedStatementConditionBuilder();
         $conditions->add("optionID IN (?)", array($optionIDs));
         $sql = "SELECT\t\t*\n\t\t\t\tFROM\t\twcf" . WCF_N . "_" . $this->tableName . "\n\t\t\t\t" . $conditions . "\n\t\t\t\tORDER BY\tshowOrder ASC";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute($conditions->getParameters());
         $optionClassName = $this->optionClassName;
         while ($row = $statement->fetchArray()) {
             $data['options'][$row['optionName']] = new $optionClassName(null, $row);
             if (!isset($data['optionToCategories'][$row['categoryName']])) {
                 $data['optionToCategories'][$row['categoryName']] = array();
             }
             $data['optionToCategories'][$row['categoryName']][] = $row['optionName'];
         }
     }
     return $data;
 }
예제 #26
0
 /**
  * @see	\wcf\system\category\ICategoryType::afterDeletion()
  */
 public function afterDeletion(CategoryEditor $categoryEditor)
 {
     $categoryIDs = array_keys(CategoryHandler::getInstance()->getChildCategories($categoryEditor->categoryID));
     if (!empty($categoryIDs)) {
         // move child categories to parent category
         $conditionBuilder = new PreparedStatementConditionBuilder();
         $conditionBuilder->add("categoryID IN (?)", array($categoryIDs));
         $sql = "UPDATE\twcf" . WCF_N . "_category\n\t\t\t\tSET\tparentCategoryID = ?\n\t\t\t\t" . $conditionBuilder;
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute(array_merge(array($categoryEditor->parentCategoryID), $conditionBuilder->getParameters()));
     }
 }
	/**
	 * @see	wcf\system\search\acp\IACPSearchResultProvider::search()
	 */
	public function search($query) {
		$results = array();
		
		// search by language item
		$conditions = new PreparedStatementConditionBuilder();
		$conditions->add("languageID = ?", array(WCF::getLanguage()->languageID));
		$conditions->add("languageItemValue LIKE ?", array($query.'%'));
		
		// filter by language item
		$languageItemsConditions = '';
		$languageItemsParameters = array();
		foreach (ACPSearchHandler::getInstance()->getAbbreviations('.acp.menu.link.%') as $abbreviation) {
			if (!empty($languageItemsConditions)) $languageItemsConditions .= " OR ";
			$languageItemsConditions .= "languageItem LIKE ?";
			$languageItemsParameters[] = $abbreviation;
		}
		$conditions->add("(".$languageItemsConditions.")", $languageItemsParameters);
		
		$sql = "SELECT		languageItem, languageItemValue
			FROM		wcf".WCF_N."_language_item
			".$conditions."
			ORDER BY	languageItemValue ASC";
		$statement = WCF::getDB()->prepareStatement($sql); // don't use a limit here
		$statement->execute($conditions->getParameters());
		$languageItems = array();
		while ($row = $statement->fetchArray()) {
			$languageItems[$row['languageItem']] = $row['languageItemValue'];
		}
		
		if (empty($languageItems)) {
			return array();
		}
		
		$conditions = new PreparedStatementConditionBuilder();
		$conditions->add("menuItem IN (?)", array(array_keys($languageItems)));
		$conditions->add("menuItemLink <> ''");
		
		$sql = "SELECT	menuItem, menuItemLink, permissions, options
			FROM	wcf".WCF_N."_acp_menu_item
			".$conditions;
		$statement = WCF::getDB()->prepareStatement($sql); // don't use a limit here
		$statement->execute($conditions->getParameters());
		
		while ($menuItem = $statement->fetchObject('wcf\data\acp\menu\item\ACPMenuItem')) {
			if (!$this->validate($menuItem)) {
				continue;
			}
			
			$results[] = new ACPSearchResult($languageItems[$menuItem->menuItem], $menuItem->getLink());
		}
		
		return $results;
	}
 /**
  * @see	\wcf\system\search\acp\IACPSearchResultProvider::search()
  */
 public function search($query)
 {
     $results = array();
     // search by language item
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("languageID = ?", array(WCF::getLanguage()->languageID));
     // filter by language item
     $languageItemsConditions = '';
     $languageItemsParameters = array();
     foreach (ACPSearchHandler::getInstance()->getAbbreviations('.acp.menu.link.%') as $abbreviation) {
         if (!empty($languageItemsConditions)) {
             $languageItemsConditions .= " OR ";
         }
         $languageItemsConditions .= "languageItem LIKE ?";
         $languageItemsParameters[] = $abbreviation;
     }
     $conditions->add("(" . $languageItemsConditions . ")", $languageItemsParameters);
     $conditions->add("languageItemValue LIKE ?", array('%' . $query . '%'));
     $sql = "SELECT\t\tlanguageItem, languageItemValue\n\t\t\tFROM\t\twcf" . WCF_N . "_language_item\n\t\t\t" . $conditions . "\n\t\t\tORDER BY\tlanguageItemValue ASC";
     $statement = WCF::getDB()->prepareStatement($sql);
     // don't use a limit here
     $statement->execute($conditions->getParameters());
     $languageItems = array();
     while ($row = $statement->fetchArray()) {
         $languageItems[$row['languageItem']] = $row['languageItemValue'];
     }
     if (empty($languageItems)) {
         return array();
     }
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("menuItem IN (?)", array(array_keys($languageItems)));
     $conditions->add("menuItemController <> ''");
     $sql = "SELECT\t*\n\t\t\tFROM\twcf" . WCF_N . "_acp_menu_item\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     // don't use a limit here
     $statement->execute($conditions->getParameters());
     $menuItems = ACPMenu::getInstance()->menuItemList;
     while ($menuItem = $statement->fetchObject('wcf\\data\\acp\\menu\\item\\ACPMenuItem')) {
         // only valid menu items exist in TreeMenu::$menuItemList,
         // so no need to call AbstractACPSearchResultProvider::validate()
         if (!isset($menuItems[$menuItem->menuItem])) {
             continue;
         }
         $parentMenuItem = $menuItem->parentMenuItem;
         $parentMenuItems = array();
         while ($parentMenuItem && isset($menuItems[$parentMenuItem])) {
             array_unshift($parentMenuItems, $parentMenuItem);
             $parentMenuItem = $menuItems[$parentMenuItem]->parentMenuItem;
         }
         $results[] = new ACPSearchResult($languageItems[$menuItem->menuItem], $menuItem->getLink(), WCF::getLanguage()->getDynamicVariable('wcf.acp.search.result.subtitle', array('pieces' => $parentMenuItems)));
     }
     return $results;
 }
 /**
  * @see	\wcf\system\worker\IWorker::execute()
  */
 public function execute()
 {
     parent::execute();
     if (!count($this->objectList)) {
         return;
     }
     if (!$this->loopCount) {
         // remove the activity points
         UserActivityPointHandler::getInstance()->reset('de.voolia.news.activityPointEvent.news');
         // remove the entry from search index
         SearchIndexManager::getInstance()->reset('de.voolia.news.entry');
     }
     // get news attachments
     $attachmentObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', 'de.voolia.news.entry');
     $sql = "SELECT\t\tCOUNT(*) AS attachments\n\t\t\tFROM\t\twcf" . WCF_N . "_attachment\n\t\t\tWHERE\t\tobjectTypeID = ?\n\t\t\tAND\t\tobjectID = ?";
     $attachments = WCF::getDB()->prepareStatement($sql);
     // calculate the cumulative likes
     $conditions = new PreparedStatementConditionBuilder();
     $conditions->add("objectID IN (?)", array($this->objectList->getObjectIDs()));
     $conditions->add("objectTypeID = ?", array(ObjectTypeCache::getInstance()->getObjectTypeIDByName('com.woltlab.wcf.like.likeableObject', 'de.voolia.news.likeableNews')));
     $sql = "SELECT\tobjectID,\n\t\t\t\tcumulativeLikes\n\t\t\tFROM\twcf" . WCF_N . "_like_object\n\t\t\t" . $conditions;
     $statement = WCF::getDB()->prepareStatement($sql);
     $statement->execute($conditions->getParameters());
     $likes = array();
     while ($row = $statement->fetchArray()) {
         $likes[$row['objectID']] = $row['cumulativeLikes'];
     }
     // update the news entries
     $userItems = array();
     foreach ($this->objectList as $news) {
         // new EntryEditor
         $editor = new NewsEditor($news);
         // update search index
         SearchIndexManager::getInstance()->add('de.voolia.news.entry', $news->newsID, $news->message, $news->subject, $news->time, $news->userID, $news->username, $news->languageID);
         // news data
         $newsData = array();
         // likes
         $newsData['cumulativeLikes'] = isset($likes[$news->newsID]) ? $likes[$news->newsID] : 0;
         // attachments
         $attachments->execute(array($attachmentObjectType->objectTypeID, $news->newsID));
         $row = $attachments->fetchArray();
         $newsData['attachments'] = $row['attachments'];
         if ($news->userID) {
             if (!isset($userItems[$news->userID])) {
                 $userItems[$news->userID] = 0;
             }
             $userItems[$news->userID]++;
         }
         $editor->update($newsData);
     }
     // update activity points
     UserActivityPointHandler::getInstance()->fireEvents('de.voolia.news.activityPointEvent.news', $userItems, false);
 }
 /**
  * @see wcf\system\cache\ICacheBuilder::getData()
  */
 public function getData(array $cacheResource)
 {
     list($cache, $packageID, $groupIDs) = explode('-', $cacheResource['cache']);
     $data = array();
     // get all options and filter options with low priority
     if ($packageID == 0) {
         // during the installation of the package wcf
         $sql = "SELECT\t\toptionName, optionID \n\t\t\t\tFROM\t\twcf" . WCF_N . "_user_group_option\n\t\t\t\tWHERE \t\tpackageID IS NULL";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute();
     } else {
         $sql = "SELECT\t\toptionName, optionID \n\t\t\t\tFROM\t\twcf" . WCF_N . "_user_group_option option_table\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_package_dependency package_dependency\n\t\t\t\tON\t\t(package_dependency.dependency = option_table.packageID)\n\t\t\t\tWHERE \t\tpackage_dependency.packageID = ?\n\t\t\t\tORDER BY\tpackage_dependency.priority ASC";
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute(array($packageID));
     }
     $options = array();
     while ($row = $statement->fetchArray()) {
         $options[$row['optionName']] = $row['optionID'];
     }
     if (count($options) > 0) {
         // get needed options
         $conditions = new PreparedStatementConditionBuilder();
         $conditions->add("option_value.groupID IN (?)", array(explode(',', $groupIDs)));
         $conditions->add("option_value.optionID IN (?)", array($options));
         $sql = "SELECT\t\toption_table.optionName, option_table.optionType, option_value.optionValue\n\t\t\t\tFROM\t\twcf" . WCF_N . "_user_group_option_value option_value\n\t\t\t\tLEFT JOIN\twcf" . WCF_N . "_user_group_option option_table\n\t\t\t\tON\t\t(option_table.optionID = option_value.optionID)\n\t\t\t\t" . $conditions;
         $statement = WCF::getDB()->prepareStatement($sql);
         $statement->execute($conditions->getParameters());
         while ($row = $statement->fetchArray()) {
             if (!isset($data[$row['optionName']])) {
                 $data[$row['optionName']] = array('type' => $row['optionType'], 'values' => array());
             }
             $data[$row['optionName']]['values'][] = $row['optionValue'];
         }
         // merge values
         foreach ($data as $optionName => $option) {
             if (count($option['values']) == 1) {
                 $result = $option['values'][0];
             } else {
                 $typeObj = $this->getTypeObject($option['type']);
                 $result = $typeObj->merge($option['values']);
             }
             // unset false values
             if ($result === false) {
                 unset($data[$optionName]);
             } else {
                 $data[$optionName] = $result;
             }
         }
     }
     $data['groupIDs'] = $groupIDs;
     return $data;
 }