One Hat Cyber Team
Your IP :
216.73.216.220
Server IP :
203.175.9.166
Server :
Linux tanggamus.iixcp.rumahweb.net 5.14.0-427.28.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Aug 2 03:44:10 EDT 2024 x86_64
Server Software :
LiteSpeed
PHP Version :
7.4.33
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
home
/
cite5577
/
www
/
lib
/
pkp
/
plugins
/
generic
/
acron
/
Edit File:
PKPAcronPlugin.inc.php
<?php /** * @file plugins/generic/acron/PKPAcronPlugin.inc.php * * Copyright (c) 2013-2021 Simon Fraser University * Copyright (c) 2000-2021 John Willinsky * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. * * @class PKPAcronPlugin * @ingroup plugins_generic_acron * * @brief Removes dependency on 'cron' for scheduled tasks, including * possible tasks defined by plugins. See the PKPAcronPlugin::parseCrontab * hook implementation. */ import('lib.pkp.classes.plugins.GenericPlugin'); import('lib.pkp.classes.scheduledTask.ScheduledTaskHelper'); import('lib.pkp.classes.xml.PKPXMLParser'); // TODO: Error handling. If a scheduled task encounters an error...? class PKPAcronPlugin extends GenericPlugin { /** @var $_workingDir string */ var $_workingDir; /** @var $_tasksToRun array */ var $_tasksToRun; /** * @copydoc Plugin::register() */ function register($category, $path, $mainContextId = null) { $success = parent::register($category, $path, $mainContextId); HookRegistry::register('Installer::postInstall', array(&$this, 'callbackPostInstall')); if (!Config::getVar('general', 'installed') || defined('RUNNING_UPGRADE')) return $success; if ($success) { $this->addLocaleData(); HookRegistry::register('LoadHandler',array(&$this, 'callbackLoadHandler')); // Need to reload cron tab on possible enable or disable generic plugin actions. HookRegistry::register('PluginGridHandler::plugin', array(&$this, 'callbackManage')); } return $success; } /** * @copydoc Plugin::isSitePlugin() */ function isSitePlugin() { // This is a site-wide plugin. return true; } /** * @copydoc LazyLoadPlugin::getName() */ function getName() { return 'acronPlugin'; } /** * @copydoc Plugin::getDisplayName() */ function getDisplayName() { return __('plugins.generic.acron.name'); } /** * @copydoc Plugin::getDescription() */ function getDescription() { return __('plugins.generic.acron.description'); } /** * @copydoc Plugin::getInstallSitePluginSettingsFile() */ function getInstallSitePluginSettingsFile() { return PKP_LIB_PATH . DIRECTORY_SEPARATOR . $this->getPluginPath() . '/settings.xml'; } /** * @copydoc Plugin::getActions() */ function getActions($request, $actionArgs) { import('lib.pkp.classes.linkAction.request.AjaxAction'); $router = $request->getRouter(); return array_merge( $this->getEnabled()?array( new LinkAction( 'reload', new AjaxAction( $router->url($request, null, null, 'manage', null, array('verb' => 'reload', 'plugin' => $this->getName(), 'category' => 'generic')) ), __('plugins.generic.acron.reload'), null ) ):array(), parent::getActions($request, $actionArgs) ); } /** * @see Plugin::manage() */ function manage($args, $request) { switch($request->getUserVar('verb')) { case 'reload': $this->_parseCrontab(); $notificationManager = new NotificationManager(); $user = $request->getUser(); $notificationManager->createTrivialNotification( $user->getId(), NOTIFICATION_TYPE_SUCCESS, array('contents' => __('plugins.generic.acron.tasksReloaded')) ); return DAO::getDataChangedEvent(); } return parent::manage($args, $request); } /** * Post install hook to flag cron tab reload on every install/upgrade. * @param $hookName string * @param $args array * @return boolean * @see Installer::postInstall() for the hook call. */ function callbackPostInstall($hookName, $args) { $this->_parseCrontab(); return false; } /** * Load handler hook to check for tasks to run. * @param $hookName string * @param $args array * @return boolean * @see PKPPageRouter::loadHandler() for the hook call. */ function callbackLoadHandler($hookName, $args) { $request = Application::get()->getRequest(); $router = $request->getRouter(); // Avoid controllers requests because of the shutdown function usage. if (!is_a($router, 'PKPPageRouter')) return false; $tasksToRun = $this->_getTasksToRun(); if (!empty($tasksToRun)) { // Save the current working directory, so we can fix // it inside the shutdown function. $this->_workingDir = getcwd(); // Save the tasks to be executed. $this->_tasksToRun = $tasksToRun; // Need output buffering to send a finish message // to browser inside the shutdown function. Couldn't // do without the buffer. ob_start(); // This callback will be used as soon as the main script // is finished. It will not stop running, even if the user cancels // the request or the time limit is reach. register_shutdown_function(array(&$this, 'shutdownFunction')); } return false; } /** * Syncronize crontab with lazy load plugins management. * @param $hookName string * @param $args array * @return boolean * @see PluginHandler::plugin() for the hook call. */ function callbackManage($hookName, $args) { $verb = $args[0]; $plugin = $args[4]; /* @var $plugin LazyLoadPlugin */ // Only interested in plugins that can be enabled/disabled. if (!is_a($plugin, 'LazyLoadPlugin')) return false; // Only interested in enable/disable actions. if ($verb !== 'enable' && $verb !== 'disable') return false; // Check if the plugin wants to add its own // scheduled task into the cron tab. foreach (HookRegistry::getHooks('AcronPlugin::parseCronTab') as $hookPriorityList) { foreach ($hookPriorityList as $priority => $callback) { if ($callback[0] == $plugin) { $this->_parseCrontab(); break; } } } return false; } /** * Shutdown callback. */ function shutdownFunction() { // After PHP 4.1.0, the execution of this callback is part of the request, // so users will have no response until it finishes executing it. We avoid // that by sending headers to the browser that makes them believe the script // is over. header("Connection: close"); // This header is needed so avoid using any kind of compression. If zlib is // enabled, for example, the buffer will not output until the end of the // script execution. header("Content-Encoding: none"); header("Content-Length: " . ob_get_length()); ob_end_flush(); flush(); set_time_limit(0); // Fix the current working directory. See // http://www.php.net/manual/en/function.register-shutdown-function.php#92657 chdir($this->_workingDir); $taskDao = DAORegistry::getDAO('ScheduledTaskDAO'); foreach($this->_tasksToRun as $task) { // Strip off the package name(s) to get the base class name $className = $task['className']; $pos = strrpos($className, '.'); if ($pos === false) { $baseClassName = $className; } else { $baseClassName = substr($className, $pos+1); } $taskArgs = array(); if (isset($task['args'])) { $taskArgs = $task['args']; } // There's a race here. Several requests may come in closely spaced. // Each may decide it's time to run scheduled tasks, and more than one // can happily go ahead and do it before the "last run" time is updated. // By updating the last run time as soon as feasible, we can minimize // the race window. See bug #8737. $tasksToRun = $this->_getTasksToRun(); $updateResult = 0; if (in_array($task, $tasksToRun, true)) { $updateResult = $taskDao->updateLastRunTime($className, time()); } if ($updateResult === false || $updateResult === 1) { // DB doesn't support the get affected rows used inside update method, or one row was updated when we introduced a new last run time. // Load and execute the task. import($className); $task = new $baseClassName($taskArgs); $task->execute(); } } } // // Private helper methods. // /** * Parse all scheduled tasks files and * save the result object in database. */ function _parseCrontab() { $xmlParser = new PKPXMLParser(); $taskFilesPath = array(); // Load all plugins so any plugin can register a crontab. PluginRegistry::loadAllPlugins(); // Let plugins register their scheduled tasks too. HookRegistry::call('AcronPlugin::parseCronTab', array(&$taskFilesPath)); // Reference needed. // Add the default tasks file. $taskFilesPath[] = 'registry/scheduledTasks.xml'; // TODO: make this a plugin setting, rather than assuming. $tasks = array(); foreach ($taskFilesPath as $filePath) { $tree = $xmlParser->parse($filePath); if (!$tree) { fatalError('Error parsing scheduled tasks XML file: ' . $filePath); } foreach ($tree->getChildren() as $task) { $frequency = $task->getChildByName('frequency'); $args = ScheduledTaskHelper::getTaskArgs($task); // Tasks without a frequency defined, or defined to zero, will run on every request. // To avoid that happening (may cause performance problems) we // setup a default period of time. $setDefaultFrequency = true; $minHoursRunPeriod = 24; if ($frequency) { $frequencyAttributes = $frequency->getAttributes(); if (is_array($frequencyAttributes)) { foreach($frequencyAttributes as $key => $value) { if ($value != 0) { $setDefaultFrequency = false; break; } } } } $tasks[] = array( 'className' => $task->getAttribute('class'), 'frequency' => $setDefaultFrequency ? array('hour' => $minHoursRunPeriod) : $frequencyAttributes, 'args' => $args ); } } // Store the object. $this->updateSetting(0, 'crontab', $tasks, 'object'); } /** * Get all scheduled tasks that needs to be executed. * @return array */ function _getTasksToRun() { $tasksToRun = array(); $isEnabled = $this->getSetting(0, 'enabled'); if($isEnabled) { $taskDao = DAORegistry::getDAO('ScheduledTaskDAO'); // Grab the scheduled scheduled tree $scheduledTasks = $this->getSetting(0, 'crontab'); if(is_null($scheduledTasks)) { $this->_parseCrontab(); $scheduledTasks = $this->getSetting(0, 'crontab'); } foreach($scheduledTasks as $task) { // We don't allow tasks without frequency, see _parseCronTab(). $frequency = new XMLNode(); $frequency->setAttribute(key($task['frequency']), current($task['frequency'])); $canExecute = ScheduledTaskHelper::checkFrequency($task['className'], $frequency); if ($canExecute) { $tasksToRun[] = $task; } } } return $tasksToRun; } }
Simpan