/** * @param $documentId * @param $config * @throws \Exception */ public function preparePdfGeneration($documentId, $config) { $document = $this->getPrintDocument($documentId); if (Model\Tool\TmpStore::get($document->getLockKey())) { throw new \Exception("Process with given document alredy running."); } Model\Tool\TmpStore::add($document->getLockKey(), true); $jobConfig = new \stdClass(); $jobConfig->documentId = $documentId; $jobConfig->config = $config; $this->saveJobConfigObjectFile($jobConfig); $this->updateStatus($documentId, 0, "prepare_pdf_generation"); $args = ["-p " . $jobConfig->documentId]; $env = \Pimcore\Config::getEnvironment(); if ($env !== false) { $args[] = "--environment=" . $env; } $cmd = Tool\Console::getPhpCli() . " " . realpath(PIMCORE_PATH . DIRECTORY_SEPARATOR . "cli" . DIRECTORY_SEPARATOR . "console.php") . " web2print:pdf-creation " . implode(" ", $args); Logger::info($cmd); if (!$config['disableBackgroundExecution']) { Tool\Console::execInBackground($cmd, PIMCORE_LOG_DIRECTORY . DIRECTORY_SEPARATOR . "web2print-output.log"); } else { Processor::getInstance()->startPdfGeneration($jobConfig->documentId); } }
public static function runCrawler() { $running = Configuration::getCoreSetting('running'); if ($running === TRUE) { return FALSE; } $indexDir = \LuceneSearch\Plugin::getFrontendSearchIndex(); if ($indexDir) { exec('rm -Rf ' . str_replace('/index/', '/tmpindex', $indexDir)); \Pimcore\Logger::debug('LuceneSearch: rm -Rf ' . str_replace('/index/', '/tmpindex', $indexDir)); \Pimcore\Logger::debug('LuceneSearch: Starting crawl'); try { $urls = Configuration::get('frontend.urls'); $invalidLinkRegexesSystem = Configuration::get('frontend.invalidLinkRegexes'); $invalidLinkRegexesEditable = Configuration::get('frontend.invalidLinkRegexesEditable'); if (!empty($invalidLinkRegexesEditable) and !empty($invalidLinkRegexesSystem)) { $invalidLinkRegexes = array_merge($invalidLinkRegexesEditable, array($invalidLinkRegexesSystem)); } else { if (!empty($invalidLinkRegexesEditable)) { $invalidLinkRegexes = $invalidLinkRegexesEditable; } else { if (!empty($invalidLinkRegexesSystem)) { $invalidLinkRegexes = array($invalidLinkRegexesSystem); } else { $invalidLinkRegexes = array(); } } } self::setCrawlerState('frontend', 'started', TRUE); try { foreach ($urls as $seed) { $parser = new Parser(); $parser->setDepth(Configuration::get('frontend.crawler.maxLinkDepth'))->setValidLinkRegexes(Configuration::get('frontend.validLinkRegexes'))->setInvalidLinkRegexes($invalidLinkRegexes)->setSearchStartIndicator(Configuration::get('frontend.crawler.contentStartIndicator'))->setSearchEndIndicator(Configuration::get('frontend.crawler.contentEndIndicator'))->setSearchExcludeStartIndicator(Configuration::get('frontend.crawler.contentExcludeStartIndicator'))->setSearchExcludeEndIndicator(Configuration::get('frontend.crawler.contentExcludeEndIndicator'))->setAllowSubdomain(FALSE)->setAllowedSchemes(Configuration::get('frontend.allowedSchemes'))->setDownloadLimit(Configuration::get('frontend.crawler.maxDownloadLimit'))->setSeed($seed); if (Configuration::get('frontend.auth.useAuth') === TRUE) { $parser->setAuth(Configuration::get('frontend.auth.username'), Configuration::get('frontend.auth.password')); } $parser->startParser(); $parser->optimizeIndex(); } } catch (\Exception $e) { } self::setCrawlerState('frontend', 'finished', FALSE); //only remove index, if tmp exists! $tmpIndex = str_replace('/index', '/tmpindex', $indexDir); if (is_dir($tmpIndex)) { exec('rm -Rf ' . $indexDir); \Pimcore\Logger::debug('LuceneSearch: rm -Rf ' . $indexDir); exec('cp -R ' . substr($tmpIndex, 0, -1) . ' ' . substr($indexDir, 0, -1)); \Pimcore\Logger::debug('LuceneSearch: cp -R ' . substr($tmpIndex, 0, -1) . ' ' . substr($indexDir, 0, -1)); \Pimcore\Logger::debug('LuceneSearch: replaced old index'); \Pimcore\Logger::info('LuceneSearch: Finished crawl'); } else { \Pimcore\Logger::error('LuceneSearch: skipped index replacing. no tmp index found.'); } } catch (\Exception $e) { \Pimcore\Logger::error($e); throw $e; } } }
protected function execute(InputInterface $input, OutputInterface $output) { $status = ["success" => true]; $config = $input->getArgument("config"); if ($config) { $job = json_decode($config, true); if (is_array($job)) { if (isset($job["dry-run"])) { // do not do anything here Logger::info("skipped update job because it is in dry-run mode", $job); } elseif ($job["type"] == "files") { Update::installData($job["revision"]); } elseif ($job["type"] == "clearcache") { \Pimcore\Cache::clearAll(); } elseif ($job["type"] == "preupdate") { $status = Update::executeScript($job["revision"], "preupdate"); } elseif ($job["type"] == "postupdate") { $status = Update::executeScript($job["revision"], "postupdate"); } elseif ($job["type"] == "cleanup") { Update::cleanup(); } } } $this->output->write(json_encode($status)); }
protected function execute(InputInterface $input, OutputInterface $output) { $validJobs = []; if ($input->getOption("job")) { $validJobs = explode(",", $input->getOption("job")); } // create manager $manager = Schedule\Manager\Factory::getManager("maintenance.pid"); $manager->setValidJobs($validJobs); $manager->setForce((bool) $input->getOption("force")); // register scheduled tasks $manager->registerJob(new Schedule\Maintenance\Job("scheduledtasks", new Schedule\Task\Executor(), "execute")); $manager->registerJob(new Schedule\Maintenance\Job("logmaintenance", new \Pimcore\Log\Maintenance(), "mail")); $manager->registerJob(new Schedule\Maintenance\Job("cleanuplogfiles", new \Pimcore\Log\Maintenance(), "cleanupLogFiles")); $manager->registerJob(new Schedule\Maintenance\Job("httperrorlog", new \Pimcore\Log\Maintenance(), "httpErrorLogCleanup")); $manager->registerJob(new Schedule\Maintenance\Job("usagestatistics", new \Pimcore\Log\Maintenance(), "usageStatistics")); $manager->registerJob(new Schedule\Maintenance\Job("checkErrorLogsDb", new \Pimcore\Log\Maintenance(), "checkErrorLogsDb")); $manager->registerJob(new Schedule\Maintenance\Job("archiveLogEntries", new \Pimcore\Log\Maintenance(), "archiveLogEntries")); $manager->registerJob(new Schedule\Maintenance\Job("sanitycheck", "\\Pimcore\\Model\\Element\\Service", "runSanityCheck")); $manager->registerJob(new Schedule\Maintenance\Job("versioncleanup", new \Pimcore\Model\Version(), "maintenanceCleanUp")); $manager->registerJob(new Schedule\Maintenance\Job("versioncompress", new \Pimcore\Model\Version(), "maintenanceCompress")); $manager->registerJob(new Schedule\Maintenance\Job("redirectcleanup", "\\Pimcore\\Model\\Redirect", "maintenanceCleanUp")); $manager->registerJob(new Schedule\Maintenance\Job("cleanupbrokenviews", "\\Pimcore\\Db", "cleanupBrokenViews")); $manager->registerJob(new Schedule\Maintenance\Job("downloadmaxminddb", "\\Pimcore\\Update", "updateMaxmindDb")); $manager->registerJob(new Schedule\Maintenance\Job("cleanupcache", "\\Pimcore\\Model\\Cache", "maintenance")); $manager->registerJob(new Schedule\Maintenance\Job("tmpstorecleanup", "\\Pimcore\\Model\\Tool\\TmpStore", "cleanup")); $manager->registerJob(new Schedule\Maintenance\Job("imageoptimize", "\\Pimcore\\Model\\Asset\\Image\\Thumbnail\\Processor", "processOptimizeQueue")); \Pimcore::getEventManager()->trigger("system.maintenance", $manager); $manager->run(); Logger::info("All maintenance-jobs finished!"); }
/** * @param string $provider * @param array|null $params * @return \Hybrid_Provider_Adapter */ public static function authenticate($provider, $params = null) { self::init(); $adapter = null; try { static::initializeHybridAuth(); $provider = @trim(strip_tags($provider)); $adapter = \Hybrid_Auth::authenticate($provider, $params); } catch (\Exception $e) { Logger::info($e); } return $adapter; }
/** * @param $permission * @return mixed|static * @throws \Exception */ public static function create($permission) { if (!$permission) { throw new \Exception("No permisson defined."); } $permissionDefinition = static::getByKey($permission); if ($permissionDefinition instanceof self) { Logger::info("Permission {$permission} allready exists. Skipping creation."); return $permissionDefinition; } else { $permissionDefinition = new static(); $permissionDefinition->setKey($permission); $permissionDefinition->save(); return $permissionDefinition; } }
protected function buildPdf(Document\PrintAbstract $document, $config) { $web2PrintConfig = Config::getWeb2PrintConfig(); $params = []; $params['printermarks'] = $config->printermarks == "true"; $params['screenResolutionImages'] = $config->screenResolutionImages == "true"; $this->updateStatus($document->getId(), 10, "start_html_rendering"); $html = $document->renderDocument($params); $this->updateStatus($document->getId(), 40, "finished_html_rendering"); $filePath = PIMCORE_TEMPORARY_DIRECTORY . "/pdf-reactor-input-" . $document->getId() . ".html"; file_put_contents($filePath, $html); $html = null; $this->updateStatus($document->getId(), 45, "saved_html_file"); ini_set("default_socket_timeout", 3000); ini_set('max_input_time', -1); include_once 'Pimcore/Web2Print/Processor/api/v' . $web2PrintConfig->get('pdfreactorVersion', '8.0') . '/PDFreactor.class.php'; $port = (string) $web2PrintConfig->pdfreactorServerPort ? (string) $web2PrintConfig->pdfreactorServerPort : "9423"; $pdfreactor = new \PDFreactor("http://" . $web2PrintConfig->pdfreactorServer . ":" . $port . "/service/rest"); $filePath = str_replace(PIMCORE_DOCUMENT_ROOT, "", $filePath); $reactorConfig = ["document" => (string) $web2PrintConfig->pdfreactorBaseUrl . $filePath, "baseURL" => (string) $web2PrintConfig->pdfreactorBaseUrl, "author" => $config->author ? $config->author : "", "title" => $config->title ? $config->title : "", "addLinks" => $config->links == "true", "addBookmarks" => $config->bookmarks == "true", "javaScriptMode" => $config->javaScriptMode, "viewerPreferences" => [$config->viewerPreference], "defaultColorSpace" => $config->colorspace, "encryption" => $config->encryption, "addTags" => $config->tags == "true", "logLevel" => $config->loglevel]; if (trim($web2PrintConfig->pdfreactorLicence)) { $reactorConfig["licenseKey"] = trim($web2PrintConfig->pdfreactorLicence); } try { $progress = new \stdClass(); $progress->finished = false; $processId = $pdfreactor->convertAsync($reactorConfig); while (!$progress->finished) { $progress = $pdfreactor->getProgress($processId); $this->updateStatus($document->getId(), 50 + $progress->progress / 2, "pdf_conversion"); Logger::info("PDF converting progress: " . $progress->progress . "%"); sleep(2); } $this->updateStatus($document->getId(), 100, "saving_pdf_document"); $result = $pdfreactor->getDocument($processId); $pdf = base64_decode($result->document); } catch (\Exception $e) { Logger::error($e); $document->setLastGenerateMessage($e->getMessage()); throw new \Exception("Error during REST-Request:" . $e->getMessage()); } $document->setLastGenerateMessage(""); return $pdf; }
public function loginAction() { $user = null; try { \Pimcore::getEventManager()->trigger("admin.login.login.authenticate", $this, ["username" => $this->getParam("username"), "password" => $this->getParam("password")]); $user = $this->getUser(); if (!$user instanceof User) { if ($this->getParam("password")) { $user = Tool\Authentication::authenticatePlaintext($this->getParam("username"), $this->getParam("password")); if (!$user) { throw new \Exception("Invalid username or password"); } } elseif ($this->getParam("token")) { $user = Tool\Authentication::authenticateToken($this->getParam("username"), $this->getParam("token")); if (!$user) { throw new \Exception("Invalid username or token"); } // save the information to session when the user want's to reset the password // this is because otherwise the old password is required => see also PIMCORE-1468 if ($this->getParam("reset")) { Tool\Session::useSession(function ($adminSession) { $adminSession->password_reset = true; }); } } else { throw new \Exception("Invalid authentication method, must be either password or token"); } } } catch (\Exception $e) { //see if module or plugin authenticates user \Pimcore::getEventManager()->trigger("admin.login.login.failed", $this, ["username" => $this->getParam("username"), "password" => $this->getParam("password")]); $user = $this->getUser(); if (!$user instanceof User) { $this->writeLogFile($this->getParam("username"), $e->getMessage()); Logger::info("Login failed: " . $e); } } if ($user instanceof User && $user->getId() && $user->isActive() && $user->getPassword()) { Tool\Session::useSession(function ($adminSession) use($user) { $adminSession->user = $user; Tool\Session::regenerateId(); }); if ($this->getParam('deeplink')) { $this->redirect('/admin/login/deeplink/?' . $this->getParam('deeplink')); } else { $this->redirect("/admin/?_dc=" . time()); } } else { $this->redirect("/admin/login/?auth_failed=true"); exit; } }
/** * @return $this * @throws \Exception */ public function save() { $isUpdate = false; if ($this->getId()) { $isUpdate = true; \Pimcore::getEventManager()->trigger("object.preUpdate", $this); } else { \Pimcore::getEventManager()->trigger("object.preAdd", $this); } $this->correctPath(); // we wrap the save actions in a loop here, so that we can restart the database transactions in the case it fails // if a transaction fails it gets restarted $maxRetries times, then the exception is thrown out // this is especially useful to avoid problems with deadlocks in multi-threaded environments (forked workers, ...) $maxRetries = 5; for ($retries = 0; $retries < $maxRetries; $retries++) { // be sure that unpublished objects in relations are saved also in frontend mode, eg. in importers, ... $hideUnpublishedBackup = self::getHideUnpublished(); self::setHideUnpublished(false); $this->beginTransaction(); try { if (!in_array($this->getType(), self::$types)) { throw new \Exception("invalid object type given: [" . $this->getType() . "]"); } if (!$isUpdate) { $this->getDao()->create(); } // get the old path from the database before the update is done $oldPath = null; if ($isUpdate) { $oldPath = $this->getDao()->getCurrentFullPath(); } // if the old path is different from the new path, update all children // we need to do the update of the children's path before $this->update() because the // inheritance helper needs the correct paths of the children in InheritanceHelper::buildTree() $updatedChildren = []; if ($oldPath && $oldPath != $this->getRealFullPath()) { $this->getDao()->updateWorkspaces(); $updatedChildren = $this->getDao()->updateChildsPaths($oldPath); } $this->update(); self::setHideUnpublished($hideUnpublishedBackup); $this->commit(); break; // transaction was successfully completed, so we cancel the loop here -> no restart required } catch (\Exception $e) { try { $this->rollBack(); } catch (\Exception $er) { // PDO adapter throws exceptions if rollback fails Logger::info($er); } if ($e instanceof Model\Element\ValidationException) { throw $e; } // set "HideUnpublished" back to the value it was originally self::setHideUnpublished($hideUnpublishedBackup); // we try to start the transaction $maxRetries times again (deadlocks, ...) if ($retries < $maxRetries - 1) { $run = $retries + 1; $waitTime = 100000; // microseconds Logger::warn("Unable to finish transaction (" . $run . ". run) because of the following reason '" . $e->getMessage() . "'. --> Retrying in " . $waitTime . " microseconds ... (" . ($run + 1) . " of " . $maxRetries . ")"); usleep($waitTime); // wait specified time until we restart the transaction } else { // if the transaction still fail after $maxRetries retries, we throw out the exception Logger::error("Finally giving up restarting the same transaction again and again, last message: " . $e->getMessage()); throw $e; } } } $additionalTags = []; if (isset($updatedChildren) && is_array($updatedChildren)) { foreach ($updatedChildren as $objectId) { $tag = "object_" . $objectId; $additionalTags[] = $tag; // remove the child also from registry (internal cache) to avoid path inconsistencies during long running scripts, such as CLI \Zend_Registry::set($tag, null); } } $this->clearDependentCache($additionalTags); if ($isUpdate) { \Pimcore::getEventManager()->trigger("object.postUpdate", $this); } else { \Pimcore::getEventManager()->trigger("object.postAdd", $this); } return $this; }
/** * @static * @return mixed|\Zend_Config */ public static function getPerspectivesConfig() { if (\Zend_Registry::isRegistered("pimcore_config_perspectives")) { $config = \Zend_Registry::get("pimcore_config_perspectives"); } else { try { $file = self::locateConfigFile("perspectives.php"); if (file_exists($file)) { $config = new \Zend_Config(include $file); } else { throw new \Exception($file . " doesn't exist"); } self::setPerspectivesConfig($config); } catch (\Exception $e) { Logger::info("Cannot find perspectives configuration, should be located at: " . $file); if (is_file($file)) { $m = "Your perspectives.php located at " . $file . " is invalid, please check and correct it manually!"; Tool::exitWithError($m); } $config = new \Zend_Config(self::getStandardPerspective()); self::setPerspectivesConfig($config); } } return $config; }
/** * Removes entries from the cache matching the given tags * * @param array $tags * @return void */ public static function clearTags($tags = array()) { // do not disable clearing, it's better purging items here than having inconsistent data because of wrong usage /*if (!self::$enabled) { \Logger::debug("Cache is not cleared because it is disabled"); return; }*/ self::setWriteLock(); \Logger::info("clear cache tags: " . implode(",", $tags)); // ensure that every tag is unique $tags = array_unique($tags); // check for ignored tags foreach (self::$ignoredTagsOnClear as $t) { $tagPosition = array_search($t, $tags); if ($tagPosition !== false) { array_splice($tags, $tagPosition, 1); } } // check for the tag output, because items with this tags are only cleared after the process is finished // the reason is that eg. long running importers will clean the output-cache on every save/update, that's not necessary, // only cleaning the output-cache on shutdown should be enough $outputTagPosition = array_search("output", $tags); if ($outputTagPosition !== false) { array_splice($tags, $outputTagPosition, 1); self::addClearTagOnShutdown("output"); } // add tag to clear stack foreach ($tags as $tag) { self::$clearedTagsStack[] = $tag; } // clean tags, except output if ($cache = self::getInstance()) { $cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, $tags); } }
/** * @param AbstractListing $list */ protected static function loadToCache(AbstractListing $list) { $totalCount = $list->getTotalCount(); $iterations = ceil($totalCount / self::getPerIteration()); Logger::info("New list of elements queued for storing into the cache with " . $iterations . " iterations and " . $totalCount . " total items"); for ($i = 0; $i < $iterations; $i++) { Logger::info("Starting iteration " . $i . " with offset: " . self::getPerIteration() * $i); $list->setLimit(self::getPerIteration()); $list->setOffset(self::getPerIteration() * $i); $elements = $list->load(); foreach ($elements as $element) { self::loadElementToCache($element); } \Pimcore::collectGarbage(); sleep(self::getTimoutBetweenIteration()); } }
/** * @param $processId */ public static function execute($processId) { $instance = new self(); $instance->setProcessId($processId); $instanceItem = TmpStore::get($instance->getJobStoreId($processId)); $instance = $instanceItem->getData(); $formats = []; $conversionStatus = "finished"; // check if there is already a transcoding process running, wait if so ... Model\Tool\Lock::acquire("video-transcoding", 7200, 10); // expires after 2 hrs, refreshes every 10 secs $asset = Model\Asset::getById($instance->getAssetId()); // start converting foreach ($instance->queue as $converter) { try { Logger::info("start video " . $converter->getFormat() . " to " . $converter->getDestinationFile()); $success = $converter->save(); Logger::info("finished video " . $converter->getFormat() . " to " . $converter->getDestinationFile()); File::rename($converter->getDestinationFile(), $converter->getStorageFile()); // set proper permissions @chmod($converter->getStorageFile(), File::getDefaultMode()); if ($success) { $formats[$converter->getFormat()] = str_replace($asset->getVideoThumbnailSavePath(), "", $converter->getStorageFile()); } else { $conversionStatus = "error"; } $converter->destroy(); } catch (\Exception $e) { Logger::error($e); } } Model\Tool\Lock::release("video-transcoding"); if ($asset) { $customSetting = $asset->getCustomSetting("thumbnails"); $customSetting = is_array($customSetting) ? $customSetting : []; if (array_key_exists($instance->getConfig()->getName(), $customSetting) && array_key_exists("formats", $customSetting[$instance->getConfig()->getName()]) && is_array($customSetting[$instance->getConfig()->getName()]["formats"])) { $formats = array_merge($customSetting[$instance->getConfig()->getName()]["formats"], $formats); } $customSetting[$instance->getConfig()->getName()] = ["status" => $conversionStatus, "formats" => $formats]; $asset->setCustomSetting("thumbnails", $customSetting); $asset->save(); } TmpStore::delete($instance->getJobStoreId()); }
/** * @param \Zend_Db_Adapter_Abstract $resource */ protected function closeConnectionResource($resource) { if ($resource) { try { $connectionId = null; // unfortunately mysqli doesn't throw an exception in the case the connection is lost (issues a warning) // and when sending a query to the broken connection (eg. when forking) // so we have to handle mysqli and pdo_mysql differently if ($resource instanceof \Zend_Db_Adapter_Mysqli) { if ($resource->getConnection()) { $connectionId = $resource->getConnection()->thread_id; } } elseif ($resource instanceof \Zend_Db_Adapter_Pdo_Mysql) { $connectionId = $resource->fetchOne("SELECT CONNECTION_ID()"); } Logger::debug(get_class($resource) . ": closing MySQL-Server connection with ID: " . $connectionId); $resource->closeConnection(); } catch (\Exception $e) { // this is the case when the mysql connection has gone away (eg. when forking using pcntl) Logger::info($e); } } }
/** * */ public function run() { $this->setLastExecution(); foreach ($this->jobs as $job) { $job->lock(); Logger::info("Executing job with ID: " . $job->getId()); try { $job->execute(); Logger::info("Finished job with ID: " . $job->getId()); } catch (\Exception $e) { Logger::error("Failed to execute job with id: " . $job->getId()); Logger::error($e); } $job->unlock(); } }
/** * */ public static function updateMaxmindDb() { $downloadUrl = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz"; $geoDbFile = PIMCORE_CONFIGURATION_DIRECTORY . "/GeoLite2-City.mmdb"; $geoDbFileGz = $geoDbFile . ".gz"; $firstTuesdayOfMonth = strtotime(date("F") . " 2013 tuesday"); $filemtime = 0; if (file_exists($geoDbFile)) { $filemtime = filemtime($geoDbFile); } // update if file is older than 30 days, or if it is the first tuesday of the month if ($filemtime < time() - 30 * 86400 || date("m/d/Y") == date("m/d/Y", $firstTuesdayOfMonth) && $filemtime < time() - 86400) { $data = Tool::getHttpData($downloadUrl); if (strlen($data) > 1000000) { File::put($geoDbFileGz, $data); @unlink($geoDbFile); $sfp = gzopen($geoDbFileGz, "rb"); $fp = fopen($geoDbFile, "w"); while ($string = gzread($sfp, 4096)) { fwrite($fp, $string, strlen($string)); } gzclose($sfp); fclose($fp); unlink($geoDbFileGz); \Logger::info("Updated MaxMind GeoIP2 Database in: " . $geoDbFile); } else { \Logger::err("Failed to update MaxMind GeoIP2, size is under about 1M"); } } else { \Logger::debug("MayMind GeoIP2 Download skipped, everything up to date, last update: " . date("m/d/Y H:i", $filemtime)); } }
/** * @deprecated * @param string $keywords * @return $this */ public function setKeywords($keywords) { // keywords are not supported anymore Logger::info("setKeywords() is deprecated and will be removed in the future!"); return $this; }
protected function doSendMailInSingleMode(Model\Document\Newsletter $document, AddressSourceAdapterInterface $addressAdapter, $sendingId) { $totalCount = $addressAdapter->getTotalRecordCount(); //calculate page size based on total item count - with min page size 3 and max page size 10 $fifth = $totalCount / 5; $limit = $fifth > 10 ? 10 : ($fifth < 3 ? 3 : intval($fifth)); $offset = 0; $hasElements = true; while ($hasElements) { $tmpStore = Model\Tool\TmpStore::get($sendingId); $data = $tmpStore->getData(); Logger::info("Sending newsletter " . $hasElements . " / " . $totalCount . " [" . $document->getId() . "]"); $data['progress'] = round($offset / $totalCount * 100, 2); $tmpStore->setData($data); $tmpStore->update(); $sendingParamContainers = $addressAdapter->getParamsForSingleSending($limit, $offset); foreach ($sendingParamContainers as $sendingParamContainer) { $mail = \Pimcore\Tool\Newsletter::prepareMail($document, $sendingParamContainer); \Pimcore\Tool\Newsletter::sendNewsletterDocumentBasedMail($mail, $sendingParamContainer); if (empty($tmpStore)) { Logger::warn("Sending configuration for sending ID {$sendingId} was deleted. Cancelling sending process."); exit; } } $offset += $limit; $hasElements = count($sendingParamContainers); \Pimcore::collectGarbage(); } }
/** * @param Mail $mail * @param SendingParamContainer $sendingContainer */ public static function sendNewsletterDocumentBasedMail(Mail $mail, SendingParamContainer $sendingContainer) { $mailAddress = $sendingContainer->getEmail(); if (!empty($mailAddress)) { $mail->setTo($mailAddress); $mail->sendWithoutRendering(); Logger::info("Sent newsletter to: " . self::obfuscateEmail($mailAddress) . " [" . $mail->getDocument()->getId() . "]"); } else { Logger::warn("No E-Mail Address given - cannot send mail. [" . $mail->getDocument()->getId() . "]"); } }
/** * This method is called in Object|Class::save() and is used to create the database table for the localized data * @return void */ public function classSaved($class, $params = []) { if (is_array($this->allowedTypes)) { foreach ($this->allowedTypes as $allowedType) { try { $definition = Object\Objectbrick\Definition::getByKey($allowedType); } catch (\Exception $e) { Logger::info("Unknown allowed type [ {$allowedType} ] ignored."); } if ($definition) { $fieldDefinition = $definition->getFieldDefinitions(); foreach ($fieldDefinition as $fd) { if (method_exists($fd, "classSaved")) { $fd->classSaved($class); } } } } } }
/** * @param $step * @return array * @throws \Exception */ public function fileStep($step) { $filesContainer = $this->getFilesToBackup(); $files = $filesContainer[$step]; $excludePatterns = array(PIMCORE_FRONTEND_MODULE . "/var/backup/.*", PIMCORE_FRONTEND_MODULE . "/var/cache/.*", PIMCORE_FRONTEND_MODULE . "/var/log/.*", PIMCORE_FRONTEND_MODULE . "/var/system/.*", PIMCORE_FRONTEND_MODULE . "/var/tmp/.*", PIMCORE_FRONTEND_MODULE . "/var/webdav/.*"); if (!empty($this->additionalExcludePatterns) && is_array($this->additionalExcludePatterns)) { $excludePatterns = array_merge($excludePatterns, $this->additionalExcludePatterns); } foreach ($excludePatterns as &$excludePattern) { $excludePattern = "@" . $excludePattern . "@"; } clearstatcache(); foreach ($files as $file) { if ($file) { if (file_exists($file) && is_readable($file)) { $exclude = false; $relPath = str_replace(PIMCORE_DOCUMENT_ROOT, "", $file); $relPath = str_replace(DIRECTORY_SEPARATOR, "/", $relPath); // windows compatibility foreach ($excludePatterns as $pattern) { if (preg_match($pattern, $relPath)) { $exclude = true; } } if (!$exclude && is_file($file)) { $this->getArchive()->addFile($file, ltrim($relPath, "/")); } else { \Logger::info("Backup: Excluded: " . $file); } } else { \Logger::err("Backup: Can't read file: " . $file); } } } $this->setFileAmount($this->getFileAmount() + count($files)); return array("success" => true, "filesize" => $this->getFormattedFilesize(), "fileAmount" => $this->getFileAmount()); }
/** * @param $elementTypes * @return array */ public function maintenanceGetOutdatedVersions($elementTypes, $ignoreIds = []) { $ignoreIdsList = implode(",", $ignoreIds); if (!$ignoreIdsList) { $ignoreIdsList = "0"; // set a default to avoid SQL errors (there's no version with ID 0) } $versionIds = []; Logger::debug("ignore ID's: " . $ignoreIdsList); if (!empty($elementTypes)) { $count = 0; $stop = false; foreach ($elementTypes as $elementType) { if ($elementType["days"] > 0) { // by days $deadline = time() - $elementType["days"] * 86400; $tmpVersionIds = $this->db->fetchCol("SELECT id FROM versions as a WHERE (ctype = ? AND date < ?) AND NOT public AND id NOT IN (" . $ignoreIdsList . ")", [$elementType["elementType"], $deadline]); $versionIds = array_merge($versionIds, $tmpVersionIds); } else { // by steps $elementIds = $this->db->fetchCol("SELECT cid,count(*) as amount FROM versions WHERE ctype = ? AND NOT public AND id NOT IN (" . $ignoreIdsList . ") GROUP BY cid HAVING amount > ?", [$elementType["elementType"], $elementType["steps"]]); foreach ($elementIds as $elementId) { $count++; Logger::info($elementId . "(object " . $count . ") Vcount " . count($versionIds)); $elementVersions = $this->db->fetchCol("SELECT id FROM versions WHERE cid = ? and ctype = ? ORDER BY date DESC LIMIT " . $elementType["steps"] . ",1000000", [$elementId, $elementType["elementType"]]); $versionIds = array_merge($versionIds, $elementVersions); // call the garbage collector if memory consumption is > 100MB if (memory_get_usage() > 100000000 && $count % 100 == 0) { \Pimcore::collectGarbage(); sleep(1); $versionIds = array_unique($versionIds); } if (count($versionIds) > 1000) { $stop = true; break; } } $versionIds = array_unique($versionIds); if ($stop) { break; } } } } Logger::info("return " . count($versionIds) . " ids\n"); return $versionIds; }