/** * @see Action::execute() */ public function execute() { parent::execute(); // check permission WCF::getUser()->checkPermission('admin.user.canMailUser'); // sql condition $condition = ''; if ($this->userMailData['action'] == '') { $condition = "WHERE user.userID IN (" . $this->userMailData['userIDs'] . ")"; } if ($this->userMailData['action'] == 'group') { $condition = "WHERE user.userID IN (SELECT userID FROM wcf" . WCF_N . "_user_to_groups WHERE groupID IN (" . $this->userMailData['groupIDs'] . "))"; } // count users $sql = "SELECT\tCOUNT(*) AS count\n\t\t\tFROM\twcf" . WCF_N . "_user user\n\t\t\t" . $condition; $row = WCF::getDB()->getFirstRow($sql); $count = $row['count']; if ($count <= $this->limit * $this->loop) { // unmark users UserEditor::unmarkAll(); // clear session $userMailData = WCF::getSession()->getVar('userMailData'); unset($userMailData[$this->mailID]); WCF::getSession()->register('userMailData', $userMailData); $this->calcProgress(); $this->finish(); } // get users $sql = "SELECT\t\tuser_option.*, user.*\n\t\t\tFROM\t\twcf" . WCF_N . "_user user\n\t\t\tLEFT JOIN\twcf" . WCF_N . "_user_option_value user_option\n\t\t\tON\t\t(user_option.userID = user.userID)\n\t\t\t" . $condition . "\n\t\t\tORDER BY\tuser.userID"; $result = WCF::getDB()->sendQuery($sql, $this->limit, $this->limit * $this->loop); while ($row = WCF::getDB()->fetchArray($result)) { $user = new User(null, $row); $adminCanMail = $user->adminCanMail; if ($adminCanMail === null || $adminCanMail == 1) { $this->sendMail($user); } } $this->executed(); $this->calcProgress($this->limit * $this->loop, $count); $this->nextLoop('wcf.acp.worker.progress.working', 'index.php?action=' . $this->action . '&mailID=' . $this->mailID . '&limit=' . $this->limit . '&loop=' . ($this->loop + 1) . '&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); }
/** * @see Action::execute() */ public function execute() { parent::execute(); // export is not finished. export further if (empty($this->downloadFile)) { // get session data $sessionData = WCF::getSession()->getVar('databaseExportData'); $loopTimeLimit = $sessionData['loopTimeLimit']; $isGzip = $sessionData['isGzip']; $limit = $sessionData['limit']; $tableName = $sessionData['tableName']; $offset = $sessionData['offset']; $importErrors = ''; $stepInfo = array(); // start export operations $loopStart = time(); $backupFile = $sessionData['backupFile']; $tables = $sessionData['tables']; // TODO: check if file could be opened (e.g. if directory exists) // open backupfile if ($isGzip) { $file = new ZipFile($backupFile, $offset == -1 ? 'wb' : 'ab'); } else { $file = new File($backupFile, $offset == -1 ? 'wb' : 'ab'); } // export database operations (only up to $limit) $stepInfo = DatabaseDumper::export($file, $tables, $limit, $loopTimeLimit, $loopStart, $offset, $tableName); // delete completed tables from session foreach ($stepInfo['completedTables'] as $table) { $key = array_search($table, $sessionData['tables']); if ($key !== false) { unset($sessionData['tables'][$key]); } } $loopEnd = time(); $duration = $loopEnd - $loopStart; // check if limit should be changed (more or less db-operations per loop) if ($stepInfo['resetLimit']) { $sessionData['limit'] = 250; } elseif ($duration != $loopTimeLimit) { // higher export step size if ($duration > 0) { $sessionData['limit'] = round($limit * ($loopTimeLimit / $duration), 0); } else { $sessionData['limit'] = $limit * 10; } } // refresh session data $sessionData['tableName'] = $stepInfo['tableName']; $sessionData['offset'] = $stepInfo['offset']; $sessionData['remain'] -= $stepInfo['done']; // show finish if ($sessionData['remain'] <= 0) { // cleanup session data. save backupFile to session WCF::getSession()->register('databaseExportData', $backupFile); WCF::getTPL()->assign(array('export' => true, 'success' => true, 'totalTables' => $sessionData['tableCount'], 'totalRecords' => $sessionData['rowCount'], 'backupFile' => $backupFile)); WCF::getTPL()->append('message', WCF::getTPL()->fetch('dbMessage')); $title = 'wcf.acp.db.progress.finish'; $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']); $this->finish($title, 'index.php?form=DatabaseExport&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); } WCF::getSession()->register('databaseExportData', $sessionData); // refresh progressbar and go to the next step $title = 'wcf.acp.db.export.progress.working'; $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']); $this->nextLoop($title); } else { $fileName = basename($this->downloadFile); $backupFile = WCF::getSession()->getVar('databaseExportData'); WCF::getSession()->unregister('databaseExportData'); if ($this->downloadFile == $backupFile) { // file type header('Content-Type: application/octet-stream'); // file name header('Content-Disposition: attachment; filename="' . $fileName . '"'); // send file size header('Content-Length: ' . filesize($this->downloadFile)); // no cache headers header('Pragma: no-cache'); header('Expires: 0'); // send file readfile($this->downloadFile); } else { throw new SystemException("Expected parameter for download file: " . $this->downloadFile, 102000); } } }
/** * @see Action::execute() */ public function execute() { parent::execute(); // get session data $sessionData = WCF::getSession()->getVar('databaseImportData'); $filesize = $sessionData['filesize']; $isGzip = $sessionData['isGzip']; $extendedCommand = $sessionData['extendedCommand']; $offset = $sessionData['offset']; $charset = $sessionData['importCharset']; $ignoreErrors = $sessionData['ignoreErrors']; $importErrors = ''; $stepInfo = array(); // start export operations $loopStart = time(); $importFile = $sessionData['importFile']; if ($isGzip) { $file = new ZipFile($importFile, 'rb'); } else { $file = new File($importFile, 'rb'); } // import database operations (only up to $this->limit) $loopInfo = DatabaseDumper::import($file, $filesize, $isGzip, $this->limit, $loopStart, $offset, $charset, $extendedCommand, $ignoreErrors); $file->close(); // store charset if (!empty($loopInfo['charset']) && $loopInfo['charset'] != $sessionData['wcfCharset']) { $sessionData['importCharset'] = $loopInfo['charset']; } // delete aftereffected erros (no insert errors will be displayed if the table caused an error before) $tableErrors = $sessionData['tableErrors']; foreach ($loopInfo['errors']['messages'] as $key => $message) { if (preg_match("/CREATE TABLE `?(\\w+)`?/i", $message, $match)) { $tableErrors[] = $match[1]; } elseif (preg_match("/(INSERT|REPLACE).*?INTO `?(\\w+)`?/i", $message, $match)) { if (in_array($match[1], $tableErrors)) { unset($loopInfo['errors']['messages'][$key]); unset($loopInfo['errors']['errorDescriptions'][$key]); } else { $tableErrors[] = $match[1]; } } } // save errors $errors = array('messages' => array_merge($sessionData['errors']['messages'], $loopInfo['errors']['messages']), 'errorDescriptions' => array_merge($sessionData['errors']['errorDescriptions'], $loopInfo['errors']['errorDescriptions'])); $sessionData['errors'] = $errors; $sessionData['tableErrors'] = $tableErrors; // refresh session data $sessionData['extendedCommand'] = $loopInfo['extendedCommand']; $sessionData['offset'] = $loopInfo['offset']; $sessionData['remain'] -= $loopInfo['done']; $sessionData['commandCount'] += $loopInfo['commandCount']; // calculate progressbar $this->calcProgress($sessionData['count'] - $sessionData['remain'], $sessionData['count']); // show finish if ($sessionData['remain'] <= 0) { // reset charset for database connection if (!empty($sessionData['importCharset'])) { WCF::getDB()->setCharset($sessionData['wcfCharset']); } // cleanup session data WCF::getSession()->unregister('databaseImportData'); // delete imported upload/remote file if ($sessionData['isTmpFile']) { @unlink($importFile); } // clear all standalone caches // get standalone package directories $sql = "SELECT\tpackageDir \n\t\t\t\tFROM\twcf" . WCF_N . "_package\n\t\t\t\tWHERE\tstandalone = 1\n\t\t\t\t\tAND packageDir <> ''"; $result = WCF::getDB()->sendQuery($sql); while ($row = WCF::getDB()->fetchArray($result)) { // check if standalone package got cache directory $realPackageDir = FileUtil::addTrailingSlash(FileUtil::getRealPath(WCF_DIR . $row['packageDir'])); if (file_exists($realPackageDir . 'cache')) { // delete all cache files WCF::getCache()->clear($realPackageDir . 'cache', '*.php', true); } } // clear wcf cache WCF::getCache()->clear(WCF_DIR . 'cache', '*.php', true); // delete all language files LanguageEditor::updateAll(); // set data for template WCF::getTPL()->assign(array('import' => true, 'success' => empty($errors['messages']) && $sessionData['commandCount'] > 0, 'commandCount' => $sessionData['commandCount'], 'errors' => $errors)); WCF::getTPL()->append('message', WCF::getTPL()->fetch('dbMessage')); // show finish template $title = 'wcf.acp.db.progress.finish'; $this->finish($title, 'index.php?form=DatabaseImport&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); } WCF::getSession()->register('databaseImportData', $sessionData); // next loop $title = 'wcf.acp.db.import.progress.working'; $this->nextLoop($title); }
/** * Shows the worker finish page. */ protected function finish($title = '', $url = '') { parent::finish('wcf.acp.worker.progress.finish', 'index.php?form=UpdateCounters&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); }
/** * @see Action::execute() */ public function execute() { parent::execute(); // check permission WCF::getUser()->checkPermission('admin.user.canPMToUserGroups'); $sql = "SELECT COUNT(DISTINCT u.userID) AS cnt" . "\n FROM wcf" . WCF_N . "_user u" . "\n LEFT JOIN wcf" . WCF_N . "_user_to_groups g ON (g.userID = u.userID)" . "\n LEFT JOIN wcf" . WCF_N . "_group_option_value v ON (v.groupID = g.groupID)" . "\n LEFT JOIN wcf" . WCF_N . "_group_option o ON (o.optionID = v.optionID)" . "\n WHERE o.optionName = 'user.pm.canUsePm'" . "\n AND v.optionValue = '1'" . "\n AND u.userID != " . $this->userID . "\n AND g.groupID IN (" . $this->pmData['groupIDs'] . ")"; $row = WCF::getDB()->getFirstRow($sql); $count = $row['cnt']; if (!$count > 0) { // clear session if (isset($this->pmData)) { $pmData = WCF::getSession()->getVar('pmData'); unset($pmData[$this->pmSessionID]); WCF::getSession()->register('pmData', $pmData); } $this->finish('wcf.pmToUgrps.error.noRecipients', 'index.php?form=PMToUserGroups&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); } if ($count <= $this->limit * $this->loop) { $endTime = TIME_NOW; $lf = "\n"; // remove from outbox $sql = "UPDATE wcf" . WCF_N . "_pm" . "\n SET saveInOutbox = 0" . "\n WHERE pmID = " . $this->pmID; WCF::getDB()->sendQuery($sql); // groups... $groups = ''; $sql = "SELECT groupName" . "\n FROM wcf" . WCF_N . "_group" . "\n WHERE groupID IN (" . $this->pmData['groupIDs'] . ")" . "\n ORDER BY groupName"; $result = WCF::getDB()->sendQuery($sql); while ($row = WCF::getDB()->fetchArray($result)) { if (!empty($groups)) { $groups .= ', '; } $groups .= StringUtil::decodeHTML($row['groupName']); } // log... $log = ''; $subject = WCF::getLanguage()->get('wcf.pmToUgrps.log.subject', array('$pmID' => $this->pmID)) . ' ' . $this->pmData['subject']; if ($this->pmData['enableHtml']) { $log .= '<pre>'; } $log .= WCF::getLanguage()->get('wcf.pmToUgrps.log.started', array('$startTime' => DateUtil::formatDate('%d.%m.%Y %H:%M:%S', $this->pmData['startTime']))) . $lf; $log .= WCF::getLanguage()->get('wcf.pmToUgrps.log.finished', array('$endTime' => DateUtil::formatDate('%d.%m.%Y %H:%M:%S', $endTime))) . $lf; $log .= WCF::getLanguage()->get('wcf.pmToUgrps.log.recipients', array('$groups' => $groups, '$count' => StringUtil::decodeHTML(StringUtil::formatInteger($count)))) . $lf; $log .= str_repeat('-', 60) . $lf; if ($this->pmData['enableHtml']) { $log .= '</pre>' . $lf; } $log .= $this->pmData['text']; $this->recipientArray = $this->blindCopyArray = array(); $this->recipientArray[0]['userID'] = $this->userID; $this->recipientArray[0]['username'] = $this->username; PMEditor::create($this->draft, $this->recipientArray, $this->blindCopyArray, $subject, $log, $this->userID, $this->username, array('enableSmilies' => $this->pmData['enableSmilies'], 'enableHtml' => $this->pmData['enableHtml'], 'enableBBCodes' => $this->pmData['enableBBCodes'], 'showSignature' => false)); // clear session $pmData = WCF::getSession()->getVar('pmData'); unset($pmData[$this->pmSessionID]); WCF::getSession()->register('pmData', $pmData); $this->calcProgress(); $msg = WCF::getLanguage()->get('wcf.pmToUgrps.finish', array('$count' => StringUtil::decodeHTML(StringUtil::formatInteger($count)), '$startTime' => DateUtil::formatShortTime('%H:%M:%S', $this->pmData['startTime']), '$endTime' => DateUtil::formatShortTime('%H:%M:%S', $endTime))); $this->finish($msg, 'index.php?form=PMToUserGroups&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); } // get users $sql = "SELECT DISTINCT u.userID, u.username" . "\n FROM wcf" . WCF_N . "_user u" . "\n LEFT JOIN wcf" . WCF_N . "_user_to_groups g ON (g.userID = u.userID)" . "\n LEFT JOIN wcf" . WCF_N . "_group_option_value v ON (v.groupID = g.groupID)" . "\n LEFT JOIN wcf" . WCF_N . "_group_option o ON (o.optionID = v.optionID)" . "\n WHERE o.optionName = 'user.pm.canUsePm'" . "\n AND v.optionValue = '1'" . "\n AND u.userID != " . $this->userID . "\n AND g.groupID IN (" . $this->pmData['groupIDs'] . ")" . "\n ORDER BY u.userID"; $this->blindCopyArray = array(); $i = 0; $result = WCF::getDB()->sendQuery($sql, $this->limit, $this->limit * $this->loop); while ($row = WCF::getDB()->fetchArray($result)) { $this->blindCopyArray[$i]['userID'] = $row['userID']; $this->blindCopyArray[$i]['username'] = $row['username']; $i++; } if (count($this->blindCopyArray)) { if (empty($this->pmID)) { $tmp = PMEditor::create($this->draft, $this->recipientArray, $this->blindCopyArray, $this->pmData['subject'], $this->pmData['text'], $this->userID, $this->username, array('enableSmilies' => $this->pmData['enableSmilies'], 'enableHtml' => $this->pmData['enableHtml'], 'enableBBCodes' => $this->pmData['enableBBCodes'], 'showSignature' => $this->pmData['showSignature'])); if ($tmp->pmID) { $this->pmID = intval($tmp->pmID); $pmData = WCF::getSession()->getVar('pmData'); $pmData[$this->pmSessionID]['pmID'] = $this->pmID; WCF::getSession()->register('pmData', $pmData); $mlt = intval($this->pmData['maxLifeTime']); if ($mlt > 0) { $mlt = $this->pmData['startTime'] + 86400 * $mlt; } else { $mlt = 0; } $sql = "INSERT IGNORE INTO wcf" . WCF_N . "_pm_bulk_mailing" . "\n (pmID, elapsedTime, time, userID)" . "\nVALUES (" . $this->pmID . ", " . $mlt . ", " . $this->pmData['startTime'] . ", " . $this->userID . ")"; WCF::getDB()->sendQuery($sql); } } else { $recipientIDs = $inserts = ''; foreach ($this->blindCopyArray as $k => $v) { $username = WCF::getDB()->escapeString($this->blindCopyArray[$k]['username']); if (!empty($recipientIDs)) { $recipientIDs .= ','; } $recipientIDs .= $this->blindCopyArray[$k]['userID']; if (!empty($inserts)) { $inserts .= ','; } $inserts .= "\n (" . $this->pmID . ", " . intval($this->blindCopyArray[$k]['userID']) . ", '" . $username . "', 1)"; } if (!empty($recipientIDs) && !empty($inserts)) { $sql = "INSERT IGNORE INTO wcf" . WCF_N . "_pm_to_user" . "\n (pmID, recipientID, recipient, isBlindCopy)" . "\nVALUES " . $inserts; WCF::getDB()->sendQuery($sql); PMEditor::updateUnreadMessageCount($recipientIDs); PMEditor::updateTotalMessageCount($recipientIDs); Session::resetSessions($recipientIDs, true, false); } } } $this->executed(); $this->calcProgress($this->limit * $this->loop, $count); $msg = WCF::getLanguage()->get('wcf.pmToUgrps.progress', array('$loop' => StringUtil::decodeHTML(StringUtil::formatInteger($this->limit * $this->loop)), '$count' => StringUtil::decodeHTML(StringUtil::formatInteger($count)))); $this->nextLoop($msg, 'index.php?action=' . $this->action . '&pmSessionID=' . $this->pmSessionID . '&limit=' . $this->limit . '&loop=' . ($this->loop + 1) . '&packageID=' . PACKAGE_ID . SID_ARG_2ND_NOT_ENCODED); }