Файловый менеджер - Редактировать - /home/lmsyaran/public_html/pusher/src.zip
Назад
PK `;�[q�Z� � AbstractApplication.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application; use Joomla\Input\Input; use Joomla\Registry\Registry; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; /** * Joomla Framework Base Application Class * * @since 1.0 */ abstract class AbstractApplication implements LoggerAwareInterface { /** * The application configuration object. * * @var Registry * @since 1.0 */ protected $config; /** * The application input object. * * @var Input * @since 1.0 */ public $input; /** * A logger. * * @var LoggerInterface * @since 1.0 */ private $logger; /** * Class constructor. * * @param Input $input An optional argument to provide dependency injection for the application's input object. If the argument is an * Input object that object will become the application's input object, otherwise a default input object is created. * @param Registry $config An optional argument to provide dependency injection for the application's config object. If the argument * is a Registry object that object will become the application's config object, otherwise a default config * object is created. * * @since 1.0 */ public function __construct(Input $input = null, Registry $config = null) { $this->input = $input instanceof Input ? $input : new Input; $this->config = $config instanceof Registry ? $config : new Registry; // Set the execution datetime and timestamp; $this->set('execution.datetime', gmdate('Y-m-d H:i:s')); $this->set('execution.timestamp', time()); $this->set('execution.microtimestamp', microtime(true)); $this->initialise(); } /** * Method to close the application. * * @param integer $code The exit code (optional; default is 0). * * @return void * * @codeCoverageIgnore * @since 1.0 */ public function close($code = 0) { exit($code); } /** * Method to run the application routines. Most likely you will want to instantiate a controller * and execute it, or perform some sort of task directly. * * @return mixed * * @since 1.0 */ abstract protected function doExecute(); /** * Execute the application. * * @return void * * @since 1.0 */ public function execute() { // @event onBeforeExecute // Perform application routines. $this->doExecute(); // @event onAfterExecute } /** * Returns a property of the object or the default value if the property is not set. * * @param string $key The name of the property. * @param mixed $default The default value (optional) if none is set. * * @return mixed The value of the configuration. * * @since 1.0 */ public function get($key, $default = null) { return $this->config->get($key, $default); } /** * Get the logger. * * @return LoggerInterface * * @since 1.0 */ public function getLogger() { // If a logger hasn't been set, use NullLogger if (! ($this->logger instanceof LoggerInterface)) { $this->logger = new NullLogger; } return $this->logger; } /** * Custom initialisation method. * * Called at the end of the AbstractApplication::__construct method. * This is for developers to inject initialisation code for their application classes. * * @return void * * @codeCoverageIgnore * @since 1.0 */ protected function initialise() { } /** * Modifies a property of the object, creating it if it does not already exist. * * @param string $key The name of the property. * @param mixed $value The value of the property to set (optional). * * @return mixed Previous value of the property * * @since 1.0 */ public function set($key, $value = null) { $previous = $this->config->get($key); $this->config->set($key, $value); return $previous; } /** * Sets the configuration for the application. * * @param Registry $config A registry object holding the configuration. * * @return AbstractApplication Returns itself to support chaining. * * @since 1.0 */ public function setConfiguration(Registry $config) { $this->config = $config; return $this; } /** * Set the logger. * * @param LoggerInterface $logger The logger. * * @return AbstractApplication Returns itself to support chaining. * * @since 1.0 */ public function setLogger(LoggerInterface $logger) { $this->logger = $logger; return $this; } } PK `;�[N�K�Y Y AbstractCliApplication.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application; use Joomla\Input; use Joomla\Registry\Registry; /** * Base class for a Joomla! command line application. * * @since 1.0 * @deprecated 2.0 Use the `joomla/console` package instead */ abstract class AbstractCliApplication extends AbstractApplication { /** * Output object * * @var Cli\CliOutput * @since 1.0 */ protected $output; /** * CLI Input object * * @var Cli\CliInput * @since 1.6.0 */ protected $cliInput; /** * Class constructor. * * @param Input\Cli $input An optional argument to provide dependency injection for the application's input object. If the * argument is an Input\Cli object that object will become the application's input object, otherwise * a default input object is created. * @param Registry $config An optional argument to provide dependency injection for the application's config object. If the * argument is a Registry object that object will become the application's config object, otherwise * a default config object is created. * @param Cli\CliOutput $output An optional argument to provide dependency injection for the application's output object. If the * argument is a Cli\CliOutput object that object will become the application's input object, otherwise * a default output object is created. * @param Cli\CliInput $cliInput An optional argument to provide dependency injection for the application's CLI input object. If the * argument is a Cli\CliInput object that object will become the application's input object, otherwise * a default input object is created. * * @since 1.0 */ public function __construct(Input\Cli $input = null, Registry $config = null, Cli\CliOutput $output = null, Cli\CliInput $cliInput = null) { // Close the application if we are not executed from the command line. // @codeCoverageIgnoreStart if (!\defined('STDOUT') || !\defined('STDIN') || !isset($_SERVER['argv'])) { $this->close(); } // @codeCoverageIgnoreEnd $this->output = ($output instanceof Cli\CliOutput) ? $output : new Cli\Output\Stdout; // Set the CLI input object. $this->cliInput = ($cliInput instanceof Cli\CliInput) ? $cliInput : new Cli\CliInput; // Call the constructor as late as possible (it runs `initialise`). parent::__construct($input instanceof Input\Input ? $input : new Input\Cli, $config); // Set the current directory. $this->set('cwd', getcwd()); } /** * Get an output object. * * @return Cli\CliOutput * * @since 1.0 */ public function getOutput() { return $this->output; } /** * Get a CLI input object. * * @return Cli\CliInput * * @since 1.6.0 */ public function getCliInput() { return $this->cliInput; } /** * Write a string to standard output. * * @param string $text The text to display. * @param boolean $nl True (default) to append a new line at the end of the output string. * * @return AbstractCliApplication Instance of $this to allow chaining. * * @since 1.0 */ public function out($text = '', $nl = true) { $this->getOutput()->out($text, $nl); return $this; } /** * Get a value from standard input. * * @return string The input string from standard input. * * @codeCoverageIgnore * @since 1.0 */ public function in() { return $this->getCliInput()->in(); } } PK `;�[]t?1a 1a AbstractDaemonApplication.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application; use Joomla\Input; use Joomla\Registry\Registry; use Psr\Log\LoggerAwareInterface; /** * Class to turn Cli applications into daemons. It requires CLI and PCNTL support built into PHP. * * @link https://secure.php.net/manual/en/book.pcntl.php * @link https://secure.php.net/manual/en/features.commandline.php * @since 1.0 * @deprecated 2.0 Deprecated without replacement */ abstract class AbstractDaemonApplication extends AbstractCliApplication implements LoggerAwareInterface { /** * @var array The available POSIX signals to be caught by default. * @link https://secure.php.net/manual/pcntl.constants.php * @since 1.0 */ protected static $signals = array( 'SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGIOT', 'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGPIPE', 'SIGALRM', 'SIGTERM', 'SIGSTKFLT', 'SIGCLD', 'SIGCHLD', 'SIGCONT', 'SIGTSTP', 'SIGTTIN', 'SIGTTOU', 'SIGURG', 'SIGXCPU', 'SIGXFSZ', 'SIGVTALRM', 'SIGPROF', 'SIGWINCH', 'SIGPOLL', 'SIGIO', 'SIGPWR', 'SIGSYS', 'SIGBABY', 'SIG_BLOCK', 'SIG_UNBLOCK', 'SIG_SETMASK', ); /** * @var boolean True if the daemon is in the process of exiting. * @since 1.0 */ protected $exiting = false; /** * @var integer The parent process id. * @since 1.0 */ protected $parentId = 0; /** * @var integer The process id of the daemon. * @since 1.0 */ protected $processId = 0; /** * @var boolean True if the daemon is currently running. * @since 1.0 */ protected $running = false; /** * Class constructor. * * @param Input\Cli $input An optional argument to provide dependency injection for the application's input object. If the * argument is an Input\Cli object that object will become the application's input object, otherwise * a default input object is created. * @param Registry $config An optional argument to provide dependency injection for the application's config object. If the * argument is a Registry object that object will become the application's config object, otherwise * a default config object is created. * @param Cli\CliOutput $output An optional argument to provide dependency injection for the application's output object. If the * argument is a Cli\CliOutput object that object will become the application's input object, otherwise * a default output object is created. * @param Cli\CliInput $cliInput An optional argument to provide dependency injection for the application's CLI input object. If the * argument is a Cli\CliInput object that object will become the application's input object, otherwise * a default input object is created. * * @since 1.0 */ public function __construct(Cli $input = null, Registry $config = null, Cli\CliOutput $output = null, Cli\CliInput $cliInput = null) { // Verify that the process control extension for PHP is available. // @codeCoverageIgnoreStart if (!\defined('SIGHUP')) { $this->getLogger()->error('The PCNTL extension for PHP is not available.'); throw new \RuntimeException('The PCNTL extension for PHP is not available.'); } // Verify that POSIX support for PHP is available. if (!\function_exists('posix_getpid')) { $this->getLogger()->error('The POSIX extension for PHP is not available.'); throw new \RuntimeException('The POSIX extension for PHP is not available.'); } // @codeCoverageIgnoreEnd // Call the parent constructor. parent::__construct($input, $config, $output, $cliInput); // Set some system limits. @set_time_limit($this->get('max_execution_time', 0)); if ($this->get('max_memory_limit') !== null) { ini_set('memory_limit', $this->get('max_memory_limit', '256M')); } // Flush content immediately. ob_implicit_flush(); } /** * Method to handle POSIX signals. * * @param integer $signal The received POSIX signal. * * @return void * * @since 1.0 * @see pcntl_signal() * @throws \RuntimeException */ public function signal($signal) { // Log all signals sent to the daemon. $this->getLogger()->debug('Received signal: ' . $signal); // Let's make sure we have an application instance. if (!is_subclass_of($this, __CLASS__)) { $this->getLogger()->emergency('Cannot find the application instance.'); throw new \RuntimeException('Cannot find the application instance.'); } // @event onReceiveSignal switch ($signal) { case SIGINT: case SIGTERM: // Handle shutdown tasks if ($this->running && $this->isActive()) { $this->shutdown(); } else { $this->close(); } break; case SIGHUP: // Handle restart tasks if ($this->running && $this->isActive()) { $this->shutdown(true); } else { $this->close(); } break; case SIGCHLD: // A child process has died while ($this->pcntlWait($signal, WNOHANG || WUNTRACED) > 0) { usleep(1000); } break; case SIGCLD: while ($this->pcntlWait($signal, WNOHANG) > 0) { $signal = $this->pcntlChildExitStatus($signal); } break; default: break; } } /** * Check to see if the daemon is active. This does not assume that $this daemon is active, but * only if an instance of the application is active as a daemon. * * @return boolean True if daemon is active. * * @since 1.0 */ public function isActive() { // Get the process id file location for the application. $pidFile = $this->get('application_pid_file'); // If the process id file doesn't exist then the daemon is obviously not running. if (!is_file($pidFile)) { return false; } // Read the contents of the process id file as an integer. $fp = fopen($pidFile, 'r'); $pid = fread($fp, filesize($pidFile)); $pid = (int) $pid; fclose($fp); // Check to make sure that the process id exists as a positive integer. if (!$pid) { return false; } // Check to make sure the process is active by pinging it and ensure it responds. if (!posix_kill($pid, 0)) { // No response so remove the process id file and log the situation. @ unlink($pidFile); $this->getLogger()->warning('The process found based on PID file was unresponsive.'); return false; } return true; } /** * Load an object or array into the application configuration object. * * @param mixed $data Either an array or object to be loaded into the configuration object. * * @return AbstractDaemonApplication Instance of $this to allow chaining. * * @since 1.0 */ public function loadConfiguration($data) { /* * Setup some application metadata options. This is useful if we ever want to write out startup scripts * or just have some sort of information available to share about things. */ // The application author name. This string is used in generating startup scripts and has // a maximum of 50 characters. $tmp = (string) $this->get('author_name', 'Joomla Framework'); $this->set('author_name', (\strlen($tmp) > 50) ? substr($tmp, 0, 50) : $tmp); // The application author email. This string is used in generating startup scripts. $tmp = (string) $this->get('author_email', 'admin@joomla.org'); $this->set('author_email', filter_var($tmp, FILTER_VALIDATE_EMAIL)); // The application name. This string is used in generating startup scripts. $tmp = (string) $this->get('application_name', 'JApplicationDaemon'); $this->set('application_name', (string) preg_replace('/[^A-Z0-9_-]/i', '', $tmp)); // The application description. This string is used in generating startup scripts. $tmp = (string) $this->get('application_description', 'A generic Joomla Framework application.'); $this->set('application_description', filter_var($tmp, FILTER_SANITIZE_STRING)); /* * Setup the application path options. This defines the default executable name, executable directory, * and also the path to the daemon process id file. */ // The application executable daemon. This string is used in generating startup scripts. $tmp = (string) $this->get('application_executable', basename($this->input->executable)); $this->set('application_executable', $tmp); // The home directory of the daemon. $tmp = (string) $this->get('application_directory', \dirname($this->input->executable)); $this->set('application_directory', $tmp); // The pid file location. This defaults to a path inside the /tmp directory. $name = $this->get('application_name'); $tmp = (string) $this->get('application_pid_file', strtolower('/tmp/' . $name . '/' . $name . '.pid')); $this->set('application_pid_file', $tmp); /* * Setup the application identity options. It is important to remember if the default of 0 is set for * either UID or GID then changing that setting will not be attempted as there is no real way to "change" * the identity of a process from some user to root. */ // The user id under which to run the daemon. $tmp = (int) $this->get('application_uid', 0); $options = array('options' => array('min_range' => 0, 'max_range' => 65000)); $this->set('application_uid', filter_var($tmp, FILTER_VALIDATE_INT, $options)); // The group id under which to run the daemon. $tmp = (int) $this->get('application_gid', 0); $options = array('options' => array('min_range' => 0, 'max_range' => 65000)); $this->set('application_gid', filter_var($tmp, FILTER_VALIDATE_INT, $options)); // Option to kill the daemon if it cannot switch to the chosen identity. $tmp = (bool) $this->get('application_require_identity', 1); $this->set('application_require_identity', $tmp); /* * Setup the application runtime options. By default our execution time limit is infinite obviously * because a daemon should be constantly running unless told otherwise. The default limit for memory * usage is 128M, which admittedly is a little high, but remember it is a "limit" and PHP's memory * management leaves a bit to be desired :-) */ // The maximum execution time of the application in seconds. Zero is infinite. $tmp = $this->get('max_execution_time'); if ($tmp !== null) { $this->set('max_execution_time', (int) $tmp); } // The maximum amount of memory the application can use. $tmp = $this->get('max_memory_limit', '256M'); if ($tmp !== null) { $this->set('max_memory_limit', (string) $tmp); } return $this; } /** * Execute the daemon. * * @return void * * @since 1.0 */ public function execute() { // @event onBeforeExecute // Enable basic garbage collection. gc_enable(); $this->getLogger()->info('Starting ' . $this->name); // Set off the process for becoming a daemon. if ($this->daemonize()) { // Declare ticks to start signal monitoring. When you declare ticks, PCNTL will monitor // incoming signals after each tick and call the relevant signal handler automatically. declare(ticks = 1); // Start the main execution loop. while (true) { // Perform basic garbage collection. $this->gc(); // Don't completely overload the CPU. usleep(1000); // Execute the main application logic. $this->doExecute(); } } else { // We were not able to daemonize the application so log the failure and die gracefully. $this->getLogger()->info('Starting ' . $this->name . ' failed'); } // @event onAfterExecute } /** * Restart daemon process. * * @return void * * @codeCoverageIgnore * @since 1.0 */ public function restart() { $this->getLogger()->info('Stopping ' . $this->name); $this->shutdown(true); } /** * Stop daemon process. * * @return void * * @codeCoverageIgnore * @since 1.0 */ public function stop() { $this->getLogger()->info('Stopping ' . $this->name); $this->shutdown(); } /** * Method to change the identity of the daemon process and resources. * * @return boolean True if identity successfully changed * * @since 1.0 * @see posix_setuid() */ protected function changeIdentity() { // Get the group and user ids to set for the daemon. $uid = (int) $this->get('application_uid', 0); $gid = (int) $this->get('application_gid', 0); // Get the application process id file path. $file = $this->get('application_pid_file'); // Change the user id for the process id file if necessary. if ($uid && (fileowner($file) != $uid) && (!@ chown($file, $uid))) { $this->getLogger()->error('Unable to change user ownership of the process id file.'); return false; } // Change the group id for the process id file if necessary. if ($gid && (filegroup($file) != $gid) && (!@ chgrp($file, $gid))) { $this->getLogger()->error('Unable to change group ownership of the process id file.'); return false; } // Set the correct home directory for the process. if ($uid && ($info = posix_getpwuid($uid)) && is_dir($info['dir'])) { system('export HOME="' . $info['dir'] . '"'); } // Change the user id for the process necessary. if ($uid && (posix_getuid($file) != $uid) && (!@ posix_setuid($uid))) { $this->getLogger()->error('Unable to change user ownership of the proccess.'); return false; } // Change the group id for the process necessary. if ($gid && (posix_getgid($file) != $gid) && (!@ posix_setgid($gid))) { $this->getLogger()->error('Unable to change group ownership of the proccess.'); return false; } // Get the user and group information based on uid and gid. $user = posix_getpwuid($uid); $group = posix_getgrgid($gid); $this->getLogger()->info('Changed daemon identity to ' . $user['name'] . ':' . $group['name']); return true; } /** * Method to put the application into the background. * * @return boolean * * @since 1.0 * @throws \RuntimeException */ protected function daemonize() { // Is there already an active daemon running? if ($this->isActive()) { $this->getLogger()->emergency($this->name . ' daemon is still running. Exiting the application.'); return false; } // Reset Process Information $this->safeMode = !!@ ini_get('safe_mode'); $this->processId = 0; $this->running = false; // Detach process! try { // Check if we should run in the foreground. if (!$this->input->get('f')) { // Detach from the terminal. $this->detach(); } else { // Setup running values. $this->exiting = false; $this->running = true; // Set the process id. $this->processId = (int) posix_getpid(); $this->parentId = $this->processId; } } catch (\RuntimeException $e) { $this->getLogger()->emergency('Unable to fork.'); return false; } // Verify the process id is valid. if ($this->processId < 1) { $this->getLogger()->emergency('The process id is invalid; the fork failed.'); return false; } // Clear the umask. @ umask(0); // Write out the process id file for concurrency management. if (!$this->writeProcessIdFile()) { $this->getLogger()->emergency('Unable to write the pid file at: ' . $this->get('application_pid_file')); return false; } // Attempt to change the identity of user running the process. if (!$this->changeIdentity()) { // If the identity change was required then we need to return false. if ($this->get('application_require_identity')) { $this->getLogger()->critical('Unable to change process owner.'); return false; } $this->getLogger()->warning('Unable to change process owner.'); } // Setup the signal handlers for the daemon. if (!$this->setupSignalHandlers()) { return false; } // Change the current working directory to the application working directory. @ chdir($this->get('application_directory')); return true; } /** * This is truly where the magic happens. This is where we fork the process and kill the parent * process, which is essentially what turns the application into a daemon. * * @return void * * @since 1.0 * @throws \RuntimeException */ protected function detach() { $this->getLogger()->debug('Detaching the ' . $this->name . ' daemon.'); // Attempt to fork the process. $pid = $this->fork(); // If the pid is positive then we successfully forked, and can close this application. if ($pid) { // Add the log entry for debugging purposes and exit gracefully. $this->getLogger()->debug('Ending ' . $this->name . ' parent process'); $this->close(); } else { // We are in the forked child process. // Setup some protected values. $this->exiting = false; $this->running = true; // Set the parent to self. $this->parentId = $this->processId; } } /** * Method to fork the process. * * @return integer The child process id to the parent process, zero to the child process. * * @since 1.0 * @throws \RuntimeException */ protected function fork() { // Attempt to fork the process. $pid = $this->pcntlFork(); // If the fork failed, throw an exception. if ($pid === -1) { throw new \RuntimeException('The process could not be forked.'); } if ($pid === 0) { // Update the process id for the child. $this->processId = (int) posix_getpid(); } else { // Log the fork in the parent. $this->getLogger()->debug('Process forked ' . $pid); } // Trigger the onFork event. $this->postFork(); return $pid; } /** * Method to perform basic garbage collection and memory management in the sense of clearing the * stat cache. We will probably call this method pretty regularly in our main loop. * * @return void * * @codeCoverageIgnore * @since 1.0 */ protected function gc() { // Perform generic garbage collection. gc_collect_cycles(); // Clear the stat cache so it doesn't blow up memory. clearstatcache(); } /** * Method to attach the AbstractDaemonApplication signal handler to the known signals. Applications * can override these handlers by using the pcntl_signal() function and attaching a different * callback method. * * @return boolean * * @since 1.0 * @see pcntl_signal() */ protected function setupSignalHandlers() { // We add the error suppression for the loop because on some platforms some constants are not defined. foreach (self::$signals as $signal) { // Ignore signals that are not defined. if (!\defined($signal) || !\is_int(\constant($signal)) || (\constant($signal) === 0)) { // Define the signal to avoid notices. $this->getLogger()->debug('Signal "' . $signal . '" not defined. Defining it as null.'); \define($signal, null); // Don't listen for signal. continue; } // Attach the signal handler for the signal. if (!$this->pcntlSignal(\constant($signal), array($this, 'signal'))) { $this->getLogger()->emergency(sprintf('Unable to reroute signal handler: %s', $signal)); return false; } } return true; } /** * Method to shut down the daemon and optionally restart it. * * @param boolean $restart True to restart the daemon on exit. * * @return void * * @since 1.0 */ protected function shutdown($restart = false) { // If we are already exiting, chill. if ($this->exiting) { return; } // If not, now we are. $this->exiting = true; // If we aren't already daemonized then just kill the application. if (!$this->running && !$this->isActive()) { $this->getLogger()->info('Process was not daemonized yet, just halting current process'); $this->close(); } // Only read the pid for the parent file. if ($this->parentId == $this->processId) { // Read the contents of the process id file as an integer. $fp = fopen($this->get('application_pid_file'), 'r'); $pid = fread($fp, filesize($this->get('application_pid_file'))); $pid = (int) $pid; fclose($fp); // Remove the process id file. @ unlink($this->get('application_pid_file')); // If we are supposed to restart the daemon we need to execute the same command. if ($restart) { $this->close(exec(implode(' ', $GLOBALS['argv']) . ' > /dev/null &')); } else { // If we are not supposed to restart the daemon let's just kill -9. passthru('kill -9 ' . $pid); $this->close(); } } } /** * Method to write the process id file out to disk. * * @return boolean * * @since 1.0 */ protected function writeProcessIdFile() { // Verify the process id is valid. if ($this->processId < 1) { $this->getLogger()->emergency('The process id is invalid.'); return false; } // Get the application process id file path. $file = $this->get('application_pid_file'); if (empty($file)) { $this->getLogger()->error('The process id file path is empty.'); return false; } // Make sure that the folder where we are writing the process id file exists. $folder = \dirname($file); if (!is_dir($folder) && !@ mkdir($folder, $this->get('folder_permission', 0755))) { $this->getLogger()->error('Unable to create directory: ' . $folder); return false; } // Write the process id file out to disk. if (!file_put_contents($file, $this->processId)) { $this->getLogger()->error('Unable to write proccess id file: ' . $file); return false; } // Make sure the permissions for the proccess id file are accurate. if (!chmod($file, $this->get('file_permission', 0644))) { $this->getLogger()->error('Unable to adjust permissions for the proccess id file: ' . $file); return false; } return true; } /** * Method to handle post-fork triggering of the onFork event. * * @return void * * @since 1.0 */ protected function postFork() { // @event onFork } /** * Method to return the exit code of a terminated child process. * * @param integer $status The status parameter is the status parameter supplied to a successful call to pcntl_waitpid(). * * @return integer The child process exit code. * * @codeCoverageIgnore * @see pcntl_wexitstatus() * @since 1.0 */ protected function pcntlChildExitStatus($status) { return pcntl_wexitstatus($status); } /** * Method to return the exit code of a terminated child process. * * @return integer On success, the PID of the child process is returned in the parent's thread * of execution, and a 0 is returned in the child's thread of execution. On * failure, a -1 will be returned in the parent's context, no child process * will be created, and a PHP error is raised. * * @codeCoverageIgnore * @see pcntl_fork() * @since 1.0 */ protected function pcntlFork() { return pcntl_fork(); } /** * Method to install a signal handler. * * @param integer $signal The signal number. * @param callable $handler The signal handler which may be the name of a user created function, * or method, or either of the two global constants SIG_IGN or SIG_DFL. * @param boolean $restart Specifies whether system call restarting should be used when this * signal arrives. * * @return boolean True on success. * * @codeCoverageIgnore * @see pcntl_signal() * @since 1.0 */ protected function pcntlSignal($signal, $handler, $restart = true) { return pcntl_signal($signal, $handler, $restart); } /** * Method to wait on or return the status of a forked child. * * @param integer $status Status information. * @param integer $options If wait3 is available on your system (mostly BSD-style systems), * you can provide the optional options parameter. * * @return integer The process ID of the child which exited, -1 on error or zero if WNOHANG * was provided as an option (on wait3-available systems) and no child was available. * * @codeCoverageIgnore * @see pcntl_wait() * @since 1.0 */ protected function pcntlWait(&$status, $options = 0) { return pcntl_wait($status, $options); } } PK `;�[R��l l AbstractWebApplication.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application; use Joomla\Input\Input; use Joomla\Registry\Registry; use Joomla\Session\Session; use Joomla\Uri\Uri; /** * Base class for a Joomla! Web application. * * @since 1.0 */ abstract class AbstractWebApplication extends AbstractApplication { /** * Character encoding string. * * @var string * @since 1.0 */ public $charSet = 'utf-8'; /** * Response mime type. * * @var string * @since 1.0 */ public $mimeType = 'text/html'; /** * HTTP protocol version. * * @var string * @since 1.9.0 */ public $httpVersion = '1.1'; /** * The body modified date for response headers. * * @var \DateTime * @since 1.0 */ public $modifiedDate; /** * The application client object. * * @var Web\WebClient * @since 1.0 */ public $client; /** * The application response object. * * @var object * @since 1.0 */ protected $response; /** * The application session object. * * @var Session * @since 1.0 */ private $session; /** * A map of integer HTTP response codes to the full HTTP Status for the headers. * * @var array * @since 1.6.0 * @link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml */ private $responseMap = array( 100 => 'HTTP/{version} 100 Continue', 101 => 'HTTP/{version} 101 Switching Protocols', 102 => 'HTTP/{version} 102 Processing', 200 => 'HTTP/{version} 200 OK', 201 => 'HTTP/{version} 201 Created', 202 => 'HTTP/{version} 202 Accepted', 203 => 'HTTP/{version} 203 Non-Authoritative Information', 204 => 'HTTP/{version} 204 No Content', 205 => 'HTTP/{version} 205 Reset Content', 206 => 'HTTP/{version} 206 Partial Content', 207 => 'HTTP/{version} 207 Multi-Status', 208 => 'HTTP/{version} 208 Already Reported', 226 => 'HTTP/{version} 226 IM Used', 300 => 'HTTP/{version} 300 Multiple Choices', 301 => 'HTTP/{version} 301 Moved Permanently', 302 => 'HTTP/{version} 302 Found', 303 => 'HTTP/{version} 303 See other', 304 => 'HTTP/{version} 304 Not Modified', 305 => 'HTTP/{version} 305 Use Proxy', 306 => 'HTTP/{version} 306 (Unused)', 307 => 'HTTP/{version} 307 Temporary Redirect', 308 => 'HTTP/{version} 308 Permanent Redirect', 400 => 'HTTP/{version} 400 Bad Request', 401 => 'HTTP/{version} 401 Unauthorized', 402 => 'HTTP/{version} 402 Payment Required', 403 => 'HTTP/{version} 403 Forbidden', 404 => 'HTTP/{version} 404 Not Found', 405 => 'HTTP/{version} 405 Method Not Allowed', 406 => 'HTTP/{version} 406 Not Acceptable', 407 => 'HTTP/{version} 407 Proxy Authentication Required', 408 => 'HTTP/{version} 408 Request Timeout', 409 => 'HTTP/{version} 409 Conflict', 410 => 'HTTP/{version} 410 Gone', 411 => 'HTTP/{version} 411 Length Required', 412 => 'HTTP/{version} 412 Precondition Failed', 413 => 'HTTP/{version} 413 Payload Too Large', 414 => 'HTTP/{version} 414 URI Too Long', 415 => 'HTTP/{version} 415 Unsupported Media Type', 416 => 'HTTP/{version} 416 Range Not Satisfiable', 417 => 'HTTP/{version} 417 Expectation Failed', 418 => 'HTTP/{version} 418 I\'m a teapot', 421 => 'HTTP/{version} 421 Misdirected Request', 422 => 'HTTP/{version} 422 Unprocessable Entity', 423 => 'HTTP/{version} 423 Locked', 424 => 'HTTP/{version} 424 Failed Dependency', 426 => 'HTTP/{version} 426 Upgrade Required', 428 => 'HTTP/{version} 428 Precondition Required', 429 => 'HTTP/{version} 429 Too Many Requests', 431 => 'HTTP/{version} 431 Request Header Fields Too Large', 451 => 'HTTP/{version} 451 Unavailable For Legal Reasons', 500 => 'HTTP/{version} 500 Internal Server Error', 501 => 'HTTP/{version} 501 Not Implemented', 502 => 'HTTP/{version} 502 Bad Gateway', 503 => 'HTTP/{version} 503 Service Unavailable', 504 => 'HTTP/{version} 504 Gateway Timeout', 505 => 'HTTP/{version} 505 HTTP Version Not Supported', 506 => 'HTTP/{version} 506 Variant Also Negotiates', 507 => 'HTTP/{version} 507 Insufficient Storage', 508 => 'HTTP/{version} 508 Loop Detected', 510 => 'HTTP/{version} 510 Not Extended', 511 => 'HTTP/{version} 511 Network Authentication Required', ); /** * Class constructor. * * @param Input $input An optional argument to provide dependency injection for the application's input object. If the argument * is an Input object that object will become the application's input object, otherwise a default input * object is created. * @param Registry $config An optional argument to provide dependency injection for the application's config object. If the argument * is a Registry object that object will become the application's config object, otherwise a default config * object is created. * @param Web\WebClient $client An optional argument to provide dependency injection for the application's client object. If the argument * is a Web\WebClient object that object will become the application's client object, otherwise a default client * object is created. * * @since 1.0 */ public function __construct(Input $input = null, Registry $config = null, Web\WebClient $client = null) { $this->client = $client instanceof Web\WebClient ? $client : new Web\WebClient; // Setup the response object. $this->response = new \stdClass; $this->response->cachable = false; $this->response->headers = array(); $this->response->body = array(); // Call the constructor as late as possible (it runs `initialise`). parent::__construct($input, $config); // Set the system URIs. $this->loadSystemUris(); } /** * Execute the application. * * @return void * * @since 1.0 */ public function execute() { // @event onBeforeExecute // Perform application routines. $this->doExecute(); // @event onAfterExecute // If gzip compression is enabled in configuration and the server is compliant, compress the output. if ($this->get('gzip') && !ini_get('zlib.output_compression') && (ini_get('output_handler') != 'ob_gzhandler')) { $this->compress(); } // @event onBeforeRespond // Send the application response. $this->respond(); // @event onAfterRespond } /** * Checks the accept encoding of the browser and compresses the data before * sending it to the client if possible. * * @return void * * @since 1.0 */ protected function compress() { // Supported compression encodings. $supported = array( 'x-gzip' => 'gz', 'gzip' => 'gz', 'deflate' => 'deflate', ); // Get the supported encoding. $encodings = array_intersect($this->client->encodings, array_keys($supported)); // If no supported encoding is detected do nothing and return. if (empty($encodings)) { return; } // Verify that headers have not yet been sent, and that our connection is still alive. if ($this->checkHeadersSent() || !$this->checkConnectionAlive()) { return; } // Iterate through the encodings and attempt to compress the data using any found supported encodings. foreach ($encodings as $encoding) { if (($supported[$encoding] == 'gz') || ($supported[$encoding] == 'deflate')) { // Verify that the server supports gzip compression before we attempt to gzip encode the data. // @codeCoverageIgnoreStart if (!\extension_loaded('zlib') || ini_get('zlib.output_compression')) { continue; } // @codeCoverageIgnoreEnd // Attempt to gzip encode the data with an optimal level 4. $data = $this->getBody(); $gzdata = gzencode($data, 4, ($supported[$encoding] == 'gz') ? FORCE_GZIP : FORCE_DEFLATE); // If there was a problem encoding the data just try the next encoding scheme. // @codeCoverageIgnoreStart if ($gzdata === false) { continue; } // @codeCoverageIgnoreEnd // Set the encoding headers. $this->setHeader('Content-Encoding', $encoding); $this->setHeader('Vary', 'Accept-Encoding'); $this->setHeader('X-Content-Encoded-By', 'Joomla'); // Replace the output with the encoded data. $this->setBody($gzdata); // Compression complete, let's break out of the loop. break; } } } /** * Method to send the application response to the client. All headers will be sent prior to the main * application output data. * * @return void * * @since 1.0 */ protected function respond() { // Send the content-type header. $this->setHeader('Content-Type', $this->mimeType . '; charset=' . $this->charSet); // If the response is set to uncachable, we need to set some appropriate headers so browsers don't cache the response. if (!$this->allowCache()) { // Expires in the past. $this->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true); // Always modified. $this->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true); $this->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0', false); // HTTP 1.0 $this->setHeader('Pragma', 'no-cache'); } else { // Expires. $this->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 900) . ' GMT'); // Last modified. if ($this->modifiedDate instanceof \DateTime) { $this->modifiedDate->setTimezone(new \DateTimeZone('UTC')); $this->setHeader('Last-Modified', $this->modifiedDate->format('D, d M Y H:i:s') . ' GMT'); } } $this->sendHeaders(); echo $this->getBody(); } /** * Redirect to another URL. * * If the headers have not been sent the redirect will be accomplished using a "301 Moved Permanently" * or "303 See Other" code in the header pointing to the new location. If the headers have already been * sent this will be accomplished using a JavaScript statement. * * @param string $url The URL to redirect to. Can only be http/https URL * @param integer $status The HTTP status code to be provided. 303 is assumed by default. * * @return void * * @since 1.0 * @throws \InvalidArgumentException */ public function redirect($url, $status = 303) { // Check for relative internal links. if (preg_match('#^index\.php#', $url)) { $url = $this->get('uri.base.full') . $url; } // Perform a basic sanity check to make sure we don't have any CRLF garbage. $url = preg_split("/[\r\n]/", $url); $url = $url[0]; /* * Here we need to check and see if the URL is relative or absolute. Essentially, do we need to * prepend the URL with our base URL for a proper redirect. The rudimentary way we are looking * at this is to simply check whether or not the URL string has a valid scheme or not. */ if (!preg_match('#^[a-z]+\://#i', $url)) { // Get a Uri instance for the requested URI. $uri = new Uri($this->get('uri.request')); // Get a base URL to prepend from the requested URI. $prefix = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port')); // We just need the prefix since we have a path relative to the root. if ($url[0] == '/') { $url = $prefix . $url; } else { // It's relative to where we are now, so lets add that. $parts = explode('/', $uri->toString(array('path'))); array_pop($parts); $path = implode('/', $parts) . '/'; $url = $prefix . $path . $url; } } // If the headers have already been sent we need to send the redirect statement via JavaScript. if ($this->checkHeadersSent()) { echo '<script>document.location.href=' . json_encode($url) . ";</script>\n"; } else { // We have to use a JavaScript redirect here because MSIE doesn't play nice with utf-8 URLs. if (($this->client->engine == Web\WebClient::TRIDENT) && !static::isAscii($url)) { $html = '<html><head>'; $html .= '<meta http-equiv="content-type" content="text/html; charset=' . $this->charSet . '" />'; $html .= '<script>document.location.href=' . json_encode($url) . ';</script>'; $html .= '</head><body></body></html>'; echo $html; } else { // Check if we have a boolean for the status variable for compatability with v1 of the framework // @deprecated 3.0 if (\is_bool($status)) { $status = $status ? 301 : 303; } if (!\is_int($status) && !$this->isRedirectState($status)) { throw new \InvalidArgumentException('You have not supplied a valid HTTP status code'); } // All other cases use the more efficient HTTP header for redirection. $this->setHeader('Status', $status, true); $this->setHeader('Location', $url, true); } } // Set appropriate headers $this->respond(); // Close the application after the redirect. $this->close(); } /** * Set/get cachable state for the response. If $allow is set, sets the cachable state of the * response. Always returns the current state. * * @param boolean $allow True to allow browser caching. * * @return boolean * * @since 1.0 */ public function allowCache($allow = null) { if ($allow !== null) { $this->response->cachable = (bool) $allow; } return $this->response->cachable; } /** * Method to set a response header. If the replace flag is set then all headers * with the given name will be replaced by the new one. The headers are stored * in an internal array to be sent when the site is sent to the browser. * * @param string $name The name of the header to set. * @param string $value The value of the header to set. * @param boolean $replace True to replace any headers with the same name. * * @return AbstractWebApplication Instance of $this to allow chaining. * * @since 1.0 */ public function setHeader($name, $value, $replace = false) { // Sanitize the input values. $name = (string) $name; $value = (string) $value; // If the replace flag is set, unset all known headers with the given name. if ($replace) { foreach ($this->response->headers as $key => $header) { if ($name == $header['name']) { unset($this->response->headers[$key]); } } // Clean up the array as unsetting nested arrays leaves some junk. $this->response->headers = array_values($this->response->headers); } // Add the header to the internal array. $this->response->headers[] = array('name' => $name, 'value' => $value); return $this; } /** * Method to get the array of response headers to be sent when the response is sent * to the client. * * @return array * * @since 1.0 */ public function getHeaders() { return $this->response->headers; } /** * Method to clear any set response headers. * * @return AbstractWebApplication Instance of $this to allow chaining. * * @since 1.0 */ public function clearHeaders() { $this->response->headers = array(); return $this; } /** * Send the response headers. * * @return AbstractWebApplication Instance of $this to allow chaining. * * @since 1.0 */ public function sendHeaders() { if (!$this->checkHeadersSent()) { foreach ($this->response->headers as $header) { if (strtolower($header['name']) == 'status') { // 'status' headers indicate an HTTP status, and need to be handled slightly differently $status = $this->getHttpStatusValue($header['value']); $this->header($status, true, (int) $header['value']); } else { $this->header($header['name'] . ': ' . $header['value']); } } } return $this; } /** * Set body content. If body content already defined, this will replace it. * * @param string $content The content to set as the response body. * * @return AbstractWebApplication Instance of $this to allow chaining. * * @since 1.0 */ public function setBody($content) { $this->response->body = array((string) $content); return $this; } /** * Prepend content to the body content * * @param string $content The content to prepend to the response body. * * @return AbstractWebApplication Instance of $this to allow chaining. * * @since 1.0 */ public function prependBody($content) { array_unshift($this->response->body, (string) $content); return $this; } /** * Append content to the body content * * @param string $content The content to append to the response body. * * @return AbstractWebApplication Instance of $this to allow chaining. * * @since 1.0 */ public function appendBody($content) { $this->response->body[] = (string) $content; return $this; } /** * Return the body content * * @param boolean $asArray True to return the body as an array of strings. * * @return mixed The response body either as an array or concatenated string. * * @since 1.0 */ public function getBody($asArray = false) { return $asArray ? $this->response->body : implode((array) $this->response->body); } /** * Method to get the application session object. * * @return Session The session object * * @since 1.0 */ public function getSession() { if ($this->session === null) { throw new \RuntimeException('A \Joomla\Session\Session object has not been set.'); } return $this->session; } /** * Check if a given value can be successfully mapped to a valid http status value * * @param string|int $value The given status as int or string * * @return string * * @since 1.8.0 */ protected function getHttpStatusValue($value) { $code = (int) $value; if (array_key_exists($code, $this->responseMap)) { $value = $this->responseMap[$code]; } else { $value = 'HTTP/{version} ' . $code; } return str_replace('{version}', $this->httpVersion, $value); } /** * Check if the value is a valid HTTP status code * * @param integer $code The potential status code * * @return boolean * * @since 1.8.1 */ public function isValidHttpStatus($code) { return array_key_exists($code, $this->responseMap); } /** * Method to check the current client connection status to ensure that it is alive. We are * wrapping this to isolate the connection_status() function from our code base for testing reasons. * * @return boolean True if the connection is valid and normal. * * @codeCoverageIgnore * @see connection_status() * @since 1.0 */ protected function checkConnectionAlive() { return connection_status() === CONNECTION_NORMAL; } /** * Method to check to see if headers have already been sent. We are wrapping this to isolate the * headers_sent() function from our code base for testing reasons. * * @return boolean True if the headers have already been sent. * * @codeCoverageIgnore * @see headers_sent() * @since 1.0 */ protected function checkHeadersSent() { return headers_sent(); } /** * Method to detect the requested URI from server environment variables. * * @return string The requested URI * * @since 1.0 */ protected function detectRequestUri() { // First we need to detect the URI scheme. if ($this->isSslConnection()) { $scheme = 'https://'; } else { $scheme = 'http://'; } /* * There are some differences in the way that Apache and IIS populate server environment variables. To * properly detect the requested URI we need to adjust our algorithm based on whether or not we are getting * information from Apache or IIS. */ $phpSelf = $this->input->server->getString('PHP_SELF', ''); $requestUri = $this->input->server->getString('REQUEST_URI', ''); // If PHP_SELF and REQUEST_URI are both populated then we will assume "Apache Mode". if (!empty($phpSelf) && !empty($requestUri)) { // The URI is built from the HTTP_HOST and REQUEST_URI environment variables in an Apache environment. $uri = $scheme . $this->input->server->getString('HTTP_HOST') . $requestUri; } else { // If not in "Apache Mode" we will assume that we are in an IIS environment and proceed. // IIS uses the SCRIPT_NAME variable instead of a REQUEST_URI variable... thanks, MS $uri = $scheme . $this->input->server->getString('HTTP_HOST') . $this->input->server->getString('SCRIPT_NAME'); $queryHost = $this->input->server->getString('QUERY_STRING', ''); // If the QUERY_STRING variable exists append it to the URI string. if (!empty($queryHost)) { $uri .= '?' . $queryHost; } } return trim($uri); } /** * Method to send a header to the client. We are wrapping this to isolate the header() function * from our code base for testing reasons. * * @param string $string The header string. * @param boolean $replace The optional replace parameter indicates whether the header should * replace a previous similar header, or add a second header of the same type. * @param integer $code Forces the HTTP response code to the specified value. Note that * this parameter only has an effect if the string is not empty. * * @return void * * @codeCoverageIgnore * @see header() * @since 1.0 */ protected function header($string, $replace = true, $code = null) { header(str_replace(\chr(0), '', $string), $replace, $code); } /** * Checks if a state is a redirect state * * @param integer $state The HTTP status code. * * @return boolean * * @since 1.8.0 */ protected function isRedirectState($state) { $state = (int) $state; return $state > 299 && $state < 400 && array_key_exists($state, $this->responseMap); } /** * Determine if we are using a secure (SSL) connection. * * @return boolean True if using SSL, false if not. * * @since 1.0 */ public function isSslConnection() { $serverSSLVar = $this->input->server->getString('HTTPS', ''); if (!empty($serverSSLVar) && strtolower($serverSSLVar) !== 'off') { return true; } $serverForwarderProtoVar = $this->input->server->getString('HTTP_X_FORWARDED_PROTO', ''); return !empty($serverForwarderProtoVar) && strtolower($serverForwarderProtoVar) === 'https'; } /** * Sets the session for the application to use, if required. * * @param Session $session A session object. * * @return AbstractWebApplication Returns itself to support chaining. * * @since 1.0 */ public function setSession(Session $session) { $this->session = $session; return $this; } /** * Method to load the system URI strings for the application. * * @param string $requestUri An optional request URI to use instead of detecting one from the * server environment variables. * * @return void * * @since 1.0 */ protected function loadSystemUris($requestUri = null) { // Set the request URI. // @codeCoverageIgnoreStart if (!empty($requestUri)) { $this->set('uri.request', $requestUri); } else { $this->set('uri.request', $this->detectRequestUri()); } // @codeCoverageIgnoreEnd // Check to see if an explicit base URI has been set. $siteUri = trim($this->get('site_uri')); if ($siteUri != '') { $uri = new Uri($siteUri); $path = $uri->toString(array('path')); } else { // No explicit base URI was set so we need to detect it. Start with the requested URI. $uri = new Uri($this->get('uri.request')); $requestUri = $this->input->server->getString('REQUEST_URI', ''); // If we are working from a CGI SAPI with the 'cgi.fix_pathinfo' directive disabled we use PHP_SELF. if (strpos(PHP_SAPI, 'cgi') !== false && !ini_get('cgi.fix_pathinfo') && !empty($requestUri)) { // We aren't expecting PATH_INFO within PHP_SELF so this should work. $path = \dirname($this->input->server->getString('PHP_SELF', '')); } else { // Pretty much everything else should be handled with SCRIPT_NAME. $path = \dirname($this->input->server->getString('SCRIPT_NAME', '')); } } // Get the host from the URI. $host = $uri->toString(array('scheme', 'user', 'pass', 'host', 'port')); // Check if the path includes "index.php". if (strpos($path, 'index.php') !== false) { // Remove the index.php portion of the path. $path = substr_replace($path, '', strpos($path, 'index.php'), 9); } $path = rtrim($path, '/\\'); // Set the base URI both as just a path and as the full URI. $this->set('uri.base.full', $host . $path . '/'); $this->set('uri.base.host', $host); $this->set('uri.base.path', $path . '/'); // Set the extended (non-base) part of the request URI as the route. if (stripos($this->get('uri.request'), $this->get('uri.base.full')) === 0) { $this->set('uri.route', substr_replace($this->get('uri.request'), '', 0, \strlen($this->get('uri.base.full')))); } // Get an explicitly set media URI is present. $mediaURI = trim($this->get('media_uri')); if ($mediaURI) { if (strpos($mediaURI, '://') !== false) { $this->set('uri.media.full', $mediaURI); $this->set('uri.media.path', $mediaURI); } else { // Normalise slashes. $mediaURI = trim($mediaURI, '/\\'); $mediaURI = !empty($mediaURI) ? '/' . $mediaURI . '/' : '/'; $this->set('uri.media.full', $this->get('uri.base.host') . $mediaURI); $this->set('uri.media.path', $mediaURI); } } else { // No explicit media URI was set, build it dynamically from the base uri. $this->set('uri.media.full', $this->get('uri.base.full') . 'media/'); $this->set('uri.media.path', $this->get('uri.base.path') . 'media/'); } } /** * Checks for a form token in the request. * * Use in conjunction with getFormToken. * * @param string $method The request method in which to look for the token key. * * @return boolean True if found and valid, false otherwise. * * @since 1.0 */ public function checkToken($method = 'post') { $token = $this->getFormToken(); if (!$this->input->$method->get($token, '', 'alnum')) { if ($this->getSession()->isNew()) { // Redirect to login screen. $this->redirect('index.php'); $this->close(); } else { return false; } } else { return true; } } /** * Method to determine a hash for anti-spoofing variable names * * @param boolean $forceNew If true, force a new token to be created * * @return string Hashed var name * * @since 1.0 */ public function getFormToken($forceNew = false) { // @todo we need the user id somehow here $userId = 0; return md5($this->get('secret') . $userId . $this->getSession()->getToken($forceNew)); } /** * Tests whether a string contains only 7bit ASCII bytes. * * You might use this to conditionally check whether a string * needs handling as UTF-8 or not, potentially offering performance * benefits by using the native PHP equivalent if it's just ASCII e.g.; * * @param string $str The string to test. * * @return boolean True if the string is all ASCII * * @since 1.4.0 */ public static function isAscii($str) { // Search for any bytes which are outside the ASCII range... return preg_match('/(?:[^\x00-\x7F])/', $str) !== 1; } } PK `;�[�t t Cli/CliInput.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application\Cli; /** * Class CliInput * * @since 1.6.0 * @deprecated 2.0 Use the `joomla/console` package instead */ class CliInput { /** * Get a value from standard input. * * @return string The input string from standard input. * * @codeCoverageIgnore * @since 1.6.0 */ public function in() { return rtrim(fread(STDIN, 8192), "\n\r"); } } PK `;�[3s�J Cli/CliOutput.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application\Cli; use Joomla\Application\Cli\Output\Processor\ProcessorInterface; /** * Class CliOutput * * @since 1.0 * @deprecated 2.0 Use the `joomla/console` package instead */ abstract class CliOutput { /** * Color processing object * * @var ProcessorInterface * @since 1.0 */ protected $processor; /** * Constructor * * @param ProcessorInterface $processor The output processor. * * @since 1.1.2 */ public function __construct(ProcessorInterface $processor = null) { $this->setProcessor(($processor instanceof ProcessorInterface) ? $processor : new Output\Processor\ColorProcessor); } /** * Set a processor * * @param ProcessorInterface $processor The output processor. * * @return Stdout Instance of $this to allow chaining. * * @since 1.0 */ public function setProcessor(ProcessorInterface $processor) { $this->processor = $processor; return $this; } /** * Get a processor * * @return ProcessorInterface * * @since 1.0 * @throws \RuntimeException */ public function getProcessor() { if ($this->processor) { return $this->processor; } throw new \RuntimeException('A ProcessorInterface object has not been set.'); } /** * Write a string to an output handler. * * @param string $text The text to display. * @param boolean $nl True (default) to append a new line at the end of the output string. * * @return void * * @since 1.0 * @codeCoverageIgnore */ abstract public function out($text = '', $nl = true); } PK `;�[~��u Cli/ColorProcessor.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application\Cli; use \Joomla\Application\Cli\Output\Processor\ColorProcessor as RealColorProcessor; /** * Class ColorProcessor. * * @since 1.0 * @deprecated 2.0 Use the `joomla/console` package instead */ class ColorProcessor extends RealColorProcessor { } PK `;�[MS�* * Cli/ColorStyle.phpnu �[��� <?php /** * Part of the Joomla Framework Application Package * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\Application\Cli; /** * Class ColorStyle * * @since 1.0 * @deprecated 2.0 Use the `joomla/console` package instead */ final class ColorStyle { /** * Known colors * * @var array * @since 1.0 */ private static $knownColors = array( 'black' => 0, 'red' => 1, 'green' => 2, 'yellow' => 3, 'blue' => 4, 'magenta' => 5, 'cyan' => 6, 'white' => 7, ); /** * Known styles * * @var array * @since 1.0 */ private static $knownOptions = array( 'bold' => 1, 'underscore' => 4, 'blink' => 5, 'reverse' => 7, ); /** * Foreground base value * * @var integer * @since 1.0 */ private static $fgBase = 30; /** * Background base value * * @var integer * @since 1.0 */ private static $bgBase = 40; /** * Foreground color * * @var integer * @since 1.0 */ private $fgColor = 0; /** * Background color * * @var integer * @since 1.0 */ private $bgColor = 0; /** * Array of style options * * @var array * @since 1.0 */ private $options = array(); /** * Constructor * * @param string $fg Foreground color. * @param string $bg Background color. * @param array $options Style options. * * @since 1.0 * @throws \InvalidArgumentException */ public function __construct($fg = '', $bg = '', $options = array()) { if ($fg) { if (array_key_exists($fg, static::$knownColors) == false) { throw new \InvalidArgumentException( sprintf('Invalid foreground color "%1$s" [%2$s]', $fg, implode(', ', $this->getKnownColors()) ) ); } $this->fgColor = static::$fgBase + static::$knownColors[$fg]; } if ($bg) { if (array_key_exists($bg, static::$knownColors) == false) { throw new \InvalidArgumentException( sprintf('Invalid background color "%1$s" [%2$s]', $bg, implode(', ', $this->getKnownColors()) ) ); } $this->bgColor = static::$bgBase + static::$knownColors[$bg]; } foreach ($options as $option) { if (array_key_exists($option, static::$knownOptions) == false) { throw new \InvalidArgumentException( sprintf('Invalid option "%1$s" [%2$s]', $option, implode(', ', $this->getKnownOptions()) ) ); } $this->options[] = $option; } } /** * Convert to a string. * * @return string * * @since 1.0 */ public function __toString() { return $this->getStyle(); } /** * Create a color style from a parameter string. * * Example: fg=red;bg=blue;options=bold,blink * * @param string $string The parameter string. * * @return ColorStyle Instance of $this to allow chaining. * * @since 1.0 * @throws \RuntimeException */ public static function fromString($string) { $fg = ''; $bg = ''; $options = array(); $parts = explode(';', $string); foreach ($parts as $part) { $subParts = explode('=', $part); if (\count($subParts) < 2) { continue; } switch ($subParts[0]) { case 'fg': $fg = $subParts[1]; break; case 'bg': $bg = $subParts[1]; break; case 'options': $options = explode(',', $subParts[1]); break; default: throw new \RuntimeException('Invalid option'); break; } } return new self($fg, $bg, $options); } /** * Get the translated color code. * * @return string * * @since 1.0 */ public function getStyle() { $values = array(); if ($this->fgColor) { $values[] = $this->fgColor; } if ($this->bgColor) { $values[] = $this->bgColor; } foreach ($this->options as $option) { $values[] = static::$knownOptions[$option]; } return implode(';', $values); } /** * Get the known colors. * * @return string * * @since 1.0 */ public function getKnownColors() { return array_keys(static::$knownColors); } /** * Get the known options. * * @return array * * @since 1.0 */ public function getKnownOptions() { return array_keys(static::$knownOptions); } } PK `;�[h#�f f '