| Current Path : /home/w/u/e/wuectly/www/03cbe/ |
| Current File : /home/w/u/e/wuectly/www/03cbe/Base.zip |
PK n�!]�Y��! ! Exceptions/ErrorException.phpnu &1i� <?php
/**
* Akeeba Engine
*
* @package akeebaengine
* @copyright Copyright (c)2006-2024 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3, or later
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
namespace Akeeba\Engine\Base\Exceptions;
defined('AKEEBAENGINE') || die();
use RuntimeException;
/**
* An exception which leads to an error (and complete halt) in the backup process
*/
class ErrorException extends RuntimeException
{
}
PK n�!]h}� Exceptions/WarningException.phpnu &1i� <?php
/**
* Akeeba Engine
*
* @package akeebaengine
* @copyright Copyright (c)2006-2024 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3, or later
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
namespace Akeeba\Engine\Base\Exceptions;
defined('AKEEBAENGINE') || die();
use RuntimeException;
/**
* An exception which leads to a warning in the backup process
*/
class WarningException extends RuntimeException
{
}
PK n�!]��\U�: �: Part.phpnu &1i� <?php
/**
* Akeeba Engine
*
* @package akeebaengine
* @copyright Copyright (c)2006-2024 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License version 3, or later
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
namespace Akeeba\Engine\Base;
defined('AKEEBAENGINE') || die();
use Akeeba\Engine\Base\Exceptions\ErrorException;
use Akeeba\Engine\Factory;
use Exception;
use Akeeba\Engine\Psr\Log\LogLevel;
use Throwable;
/**
* Base class for all Akeeba Engine parts.
*
* Parts are objects which perform a specific function during the backup process, e.g. backing up files or dumping
* database contents. They have a fully defined and controlled lifecycle, from initialization to finalization. The
* transition between lifecycle phases is handled by the `tick()` method which is essentially the only public interface
* to interacting with an engine part.
*/
abstract class Part
{
public const STATE_INIT = 0;
public const STATE_PREPARED = 1;
public const STATE_RUNNING = 2;
public const STATE_POSTRUN = 3;
public const STATE_FINISHED = 4;
public const STATE_ERROR = 99;
/**
* The current state of this part; see the constants at the top of this class
*
* @var int
*/
protected $currentState = self::STATE_INIT;
/**
* The name of the engine part (a.k.a. Domain), used in return table
* generation.
*
* @var string
*/
protected $activeDomain = "";
/**
* The step this engine part is in. Used verbatim in return table and
* should be set by the code in the _run() method.
*
* @var string
*/
protected $activeStep = "";
/**
* A more detailed description of the step this engine part is in. Used
* verbatim in return table and should be set by the code in the _run()
* method.
*
* @var string
*/
protected $activeSubstep = "";
/**
* Any configuration variables, in the form of an array.
*
* @var array
*/
protected $_parametersArray = [];
/**
* The database root key
*
* @var string
*/
protected $databaseRoot = [];
/**
* Should we log the step nesting?
*
* @var bool
*/
protected $nest_logging = false;
/**
* Embedded installer preferences
*
* @var object
*/
protected $installerSettings;
/**
* How much milliseconds should we wait to reach the min exec time
*
* @var int
*/
protected $waitTimeMsec = 0;
/**
* Should I ignore the minimum execution time altogether?
*
* @var bool
*/
protected $ignoreMinimumExecutionTime = false;
/**
* The last exception thrown during the tick() method's execution.
*
* @var null|Exception
*/
protected $lastException = null;
public function _onSerialize()
{
$this->lastException = null;
}
/**
* Public constructor
*
* @return void
*/
public function __construct()
{
// Fetch the installer settings
$this->installerSettings = (object) [
'installerroot' => 'installation',
'sqlroot' => 'installation/sql',
'databasesini' => 1,
'readme' => 1,
'extrainfo' => 1,
'password' => 0,
];
$config = Factory::getConfiguration();
$installerKey = $config->get('akeeba.advanced.embedded_installer');
$installerDescriptors = Factory::getEngineParamsProvider()->getInstallerList();
// Fall back to default ANGIE installer if the selected installer is not found
if (!array_key_exists($installerKey, $installerDescriptors))
{
$installerKey = 'angie';
}
if (array_key_exists($installerKey, $installerDescriptors))
{
$this->installerSettings = (object) $installerDescriptors[$installerKey];
}
}
/**
* Nested logging of exceptions
*
* The message is logged using the specified log level. The detailed information of the Throwable and its trace are
* logged using the DEBUG level.
*
* If the Throwable is nested, its parents are logged recursively. This should create a thorough trace leading to
* the root cause of an error.
*
* @param Exception|Throwable $exception The Exception or Throwable to log
* @param string $logLevel The log level to use, default ERROR
*/
protected static function logErrorsFromException($exception, $logLevel = LogLevel::ERROR)
{
$logger = Factory::getLog();
$logger->log($logLevel, $exception->getMessage());
$logger->debug(sprintf('[%s] %s(%u) – #%u ‹%s›', get_class($exception), $exception->getFile(), $exception->getLine(), $exception->getCode(), $exception->getMessage()));
foreach (explode("\n", $exception->getTraceAsString()) as $line)
{
$logger->debug(rtrim($line));
}
$previous = $exception->getPrevious();
if (!is_null($previous))
{
self::logErrorsFromException($previous, $logLevel);
}
}
/**
* The public interface to an engine part. This method takes care for
* calling the correct method in order to perform the initialisation -
* run - finalisation cycle of operation and return a proper response array.
*
* @param int $nesting
*
* @return array A response array
*/
public function tick($nesting = 0)
{
$configuration = Factory::getConfiguration();
$timer = Factory::getTimer();
$this->waitTimeMsec = 0;
$this->lastException = null;
// Add a small wait based on the existence of a constant. Used in testing, to simulate slow servers.
if (defined('AKEEBA_BACKUP_TESTING_STEP_THROTTLING'))
{
/** @noinspection PhpUndefinedConstantInspection */
usleep((int) AKEEBA_BACKUP_TESTING_STEP_THROTTLING);
}
/**
* Call the right action method, depending on engine part state.
*
* The action method may throw an exception to signal failure, hence the try-catch. If there is an exception we
* will set the part's state to STATE_ERROR and store the last exception.
*/
try
{
switch ($this->getState())
{
case self::STATE_INIT:
$this->_prepare();
break;
case self::STATE_PREPARED:
case self::STATE_RUNNING:
$this->_run();
break;
case self::STATE_POSTRUN:
$this->_finalize();
break;
}
}
catch (Exception $e)
{
$this->lastException = $e;
$this->setState(self::STATE_ERROR);
}
// If there is still time, we are not finished and there is no break flag set, re-run the tick()
// method.
$breakFlag = $configuration->get('volatile.breakflag', false);
if (
!in_array($this->getState(), [self::STATE_FINISHED, self::STATE_ERROR]) &&
($timer->getTimeLeft() > 0) &&
!$breakFlag &&
($nesting < 20) &&
($this->nest_logging)
)
{
// Nesting is only applied if $this->nest_logging == true (currently only Kettenrad has this)
$nesting++;
if ($this->nest_logging)
{
Factory::getLog()->debug("*** Batching successive steps (nesting level $nesting)");
}
return $this->tick($nesting);
}
// Return the output array
$out = $this->makeReturnTable();
// If it's not a nest-logged part (basically, anything other than Kettenrad) return the output array.
if (!$this->nest_logging)
{
return $out;
}
// From here on: things to do for nest-logged parts (i.e. Kettenrad)
if ($breakFlag)
{
Factory::getLog()->debug("*** Engine steps batching: Break flag detected.");
}
// Reset the break flag
$configuration->set('volatile.breakflag', false);
// Log that we're breaking the step
Factory::getLog()->debug("*** Batching of engine steps finished. I will now return control to the caller.");
// Detect whether I need server-side sleep
$serverSideSleep = $this->needsServerSideSleep();
// Enforce minimum execution time
if (!$this->ignoreMinimumExecutionTime)
{
$timer = Factory::getTimer();
$this->waitTimeMsec = (int) $timer->enforce_min_exec_time(true, $serverSideSleep);
}
// Send a Return Table back to the caller
return $out;
}
/**
* Returns a copy of the class's status array
*
* @return array The response array
*/
public function getStatusArray()
{
return $this->makeReturnTable();
}
/**
* Sends any kind of setup information to the engine part. Using this,
* we avoid passing parameters to the constructor of the class. These
* parameters should be passed as an indexed array and should be taken
* into account during the preparation process only. This function will
* set the error flag if it's called after the engine part is prepared.
*
* @param array $parametersArray The parameters to be passed to the engine part.
*
* @return void
*/
public function setup($parametersArray)
{
if ($this->currentState == self::STATE_PREPARED)
{
$this->setState(self::STATE_ERROR);
throw new ErrorException(__CLASS__ . ":: Can't modify configuration after the preparation of " . $this->activeDomain);
}
$this->_parametersArray = $parametersArray;
if (array_key_exists('root', $parametersArray))
{
$this->databaseRoot = $parametersArray['root'];
}
}
/**
* Returns the state of this engine part.
*
* @return int The state of this engine part.
*/
public function getState()
{
if (!is_null($this->lastException))
{
$this->currentState = self::STATE_ERROR;
}
return $this->currentState;
}
/**
* Translate the integer state to a string, used by consumers of the public Engine API.
*
* @param int $state The part state to translate to string
*
* @return string
*/
public function stateToString($state)
{
switch ($state)
{
case self::STATE_ERROR:
return 'error';
break;
case self::STATE_INIT:
return 'init';
break;
case self::STATE_PREPARED:
return 'prepared';
break;
case self::STATE_RUNNING:
return 'running';
break;
case self::STATE_POSTRUN:
return 'postrun';
break;
case self::STATE_FINISHED:
return 'finished';
break;
}
return 'init';
}
/**
* Get the current domain of the engine
*
* @return string The current domain
*/
public function getDomain()
{
return $this->activeDomain;
}
/**
* Get the current step of the engine
*
* @return string The current step
*/
public function getStep()
{
return $this->activeStep;
}
/**
* Get the current sub-step of the engine
*
* @return string The current sub-step
*/
public function getSubstep()
{
return $this->activeSubstep;
}
/**
* Implement this if your Engine Part can return the percentage of its work already complete
*
* @return float A number from 0 (nothing done) to 1 (all done)
*/
public function getProgress()
{
return 0;
}
/**
* Get the value of the minimum execution time ignore flag.
*
* DO NOT REMOVE. It is used by the Engine consumers.
*
* @return boolean
*/
public function isIgnoreMinimumExecutionTime()
{
return $this->ignoreMinimumExecutionTime;
}
/**
* Set the value of the minimum execution time ignore flag. When set, the nested logging parts (basically,
* Kettenrad) will ignore the minimum execution time parameter.
*
* DO NOT REMOVE. It is used by the Engine consumers.
*
* @param boolean $ignoreMinimumExecutionTime
*/
public function setIgnoreMinimumExecutionTime($ignoreMinimumExecutionTime)
{
$this->ignoreMinimumExecutionTime = $ignoreMinimumExecutionTime;
}
/**
* Runs any initialization code. Must set the state to STATE_PREPARED.
*
* @return void
*/
abstract protected function _prepare();
/**
* Runs any finalisation code. Must set the state to STATE_FINISHED.
*
* @return void
*/
abstract protected function _finalize();
/**
* Performs the main objective of this part. While still processing the state must be set to STATE_RUNNING. When the
* main objective is complete and we're ready to proceed to finalization the state must be set to STATE_POSTRUN.
*
* @return void
*/
abstract protected function _run();
/**
* Sets the BREAKFLAG, which instructs this engine part that the current step must break immediately,
* in fear of timing out.
*
* @return void
*/
protected function setBreakFlag()
{
$registry = Factory::getConfiguration();
$registry->set('volatile.breakflag', true);
}
/**
* Sets the engine part's internal state, in an easy to use manner
*
* @param int $state The part state to set
*
* @return void
*/
protected function setState($state = self::STATE_INIT)
{
$this->currentState = $state;
}
/**
* Constructs a Response Array based on the engine part's state.
*
* @return array The Response Array for the current state
*/
protected function makeReturnTable()
{
$errors = [];
$e = $this->lastException;
while (!empty($e))
{
$errors[] = $e->getMessage();
$e = $e->getPrevious();
}
return [
'HasRun' => $this->currentState != self::STATE_FINISHED,
'Domain' => $this->activeDomain,
'Step' => $this->activeStep,
'Substep' => $this->activeSubstep,
'Error' => implode("\n", $errors),
'Warnings' => [],
'ErrorException' => $this->lastException,
];
}
/**
* Set the current domain of the engine
*
* @param string $new_domain The domain to set
*
* @return void
*/
protected function setDomain($new_domain)
{
$this->activeDomain = $new_domain;
}
/**
* Set the current step of the engine
*
* @param string $new_step The step to set
*
* @return void
*/
protected function setStep($new_step)
{
$this->activeStep = $new_step;
}
/**
* Set the current sub-step of the engine
*
* @param string $new_substep The sub-step to set
*
* @return void
*/
protected function setSubstep($new_substep)
{
$this->activeSubstep = $new_substep;
}
/**
* Do I need to apply server-side sleep for the time difference between the elapsed time and the minimum execution
* time?
*
* @return bool
*/
private function needsServerSideSleep()
{
/**
* If the part doesn't support tagging, i.e. I can't determine if this is a backend backup or not, I will always
* use server-side sleep.
*/
if (!method_exists($this, 'getTag'))
{
return true;
}
/**
* If this is not a backend backup I will always use server-side sleep. That is to say that legacy front-end,
* remote JSON API and CLI backups must always use server-side sleep since they do not support client-side
* sleep.
*/
if (!in_array($this->getTag(), ['backend']))
{
return true;
}
return Factory::getConfiguration()->get('akeeba.basic.clientsidewait', 0) == 0;
}
}
PK �"]�n / / Platform.phpnu &1i� <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Platform\Base;
defined('_JEXEC') || die;
use Exception;
use FOF40\Container\Container;
use FOF40\Input\Input;
use FOF40\Platform\PlatformInterface;
use Joomla\CMS\Document\Document;
use Joomla\CMS\User\User;
/**
* Abstract implementation of the Platform integration
*
* @package FOF40\Platform\Base
*/
abstract class Platform implements PlatformInterface
{
/** @var Container The component container */
protected $container;
/** @var bool Are plugins allowed to run in CLI mode? */
protected $allowPluginsInCli = false;
/**
* Public constructor.
*
* @param Container $c The component container
*/
public function __construct(Container $c)
{
$this->container = $c;
}
/**
* Returns the base (root) directories for a given component, i.e the application
* which is running inside our main application (CMS, web app).
*
* The return is a table with the following keys:
* * main The normal location of component files. For a back-end Joomla!
* component this is the administrator/components/com_example
* directory.
* * alt The alternate location of component files. For a back-end
* Joomla! component this is the front-end directory, e.g.
* components/com_example
* * site The location of the component files serving the public part of
* the application.
* * admin The location of the component files serving the administrative
* part of the application.
*
* All paths MUST be absolute. All four paths MAY be the same if the
* platform doesn't make a distinction between public and private parts,
* or when the component does not provide both a public and private part.
* All of the directories MUST be defined and non-empty.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @return array A hash array with keys main, alt, site and admin.
*/
public function getComponentBaseDirs(string $component): array
{
return [
'main' => '',
'alt' => '',
'site' => '',
'admin' => '',
];
}
/**
* Returns the application's template name
*
* @param null|array $params An optional associative array of configuration settings
*
* @return string The template name. System is the fallback.
*/
public function getTemplate(?array $params = null): string
{
return 'system';
}
/**
* Get application-specific suffixes to use with template paths. This allows
* you to look for view template overrides based on the application version.
*
* @return array A plain array of suffixes to try in template names
*/
public function getTemplateSuffixes(): array
{
return [];
}
/**
* Return the absolute path to the application's template overrides
* directory for a specific component. We will use it to look for template
* files instead of the regular component directories. If the application
* does not have such a thing as template overrides return an empty string.
*
* @param string $component The name of the component for which to fetch the overrides
* @param bool $absolute Should I return an absolute or relative path?
*
* @return string The path to the template overrides directory
*/
public function getTemplateOverridePath(string $component, bool $absolute = true): string
{
return '';
}
/**
* Load the translation files for a given component.
*
* @param string $component The name of the component. For Joomla! this
* is something like "com_example"
*
* @return void
*/
public function loadTranslations(string $component): void
{
}
/**
* By default FOF will only use the Controller's onBefore* methods to
* perform user authorisation. In some cases, like the Joomla! back-end,
* you also need to perform component-wide user authorisation in the
* Dispatcher. This method MUST implement this authorisation check. If you
* do not need this in your platform, please always return true.
*
* @param string $component The name of the component.
*
* @return bool True to allow loading the component, false to halt loading
*/
public function authorizeAdmin(string $component): bool
{
return true;
}
/**
* Returns a user object.
*
* @param integer $id The user ID to load. Skip or use null to retrieve
* the object for the currently logged in user.
*
* @return User The User object for the specified user
*/
public function getUser(?int $id = null): User
{
return new User();
}
/**
* Returns the Document object which handles this component's response. You
* may also return null and FOF will a. try to figure out the output type by
* examining the "format" input parameter (or fall back to "html") and b.
* FOF will not attempt to load CSS and Javascript files (as it doesn't make
* sense if there's no Document to handle them).
*
* @return Document|null
*/
public function getDocument(): ?Document
{
return null;
}
/**
* This method will try retrieving a variable from the request (input) data.
* If it doesn't exist it will be loaded from the user state, typically
* stored in the session. If it doesn't exist there either, the $default
* value will be used. If $setUserState is set to true, the retrieved
* variable will be stored in the user session.
*
* @param string $key The user state key for the variable
* @param string $request The request variable name for the variable
* @param Input $input The Input object with the request (input) data
* @param mixed $default The default value. Default: null
* @param string $type The filter type for the variable data. Default: none (no filtering)
* @param bool $setUserState Should I set the user state with the fetched value?
*
* @return mixed The value of the variable
*/
public function getUserStateFromRequest(string $key, string $request, Input $input, $default = null, string $type = 'none', bool $setUserState = true)
{
return $input->get($request, $default, $type);
}
/**
* Load plugins of a specific type. Obviously this seems to only be required
* in the Joomla! CMS itself.
*
* @param string $type The type of the plugins to be loaded
*
* @return void
*/
public function importPlugin(string $type): void
{
}
/**
* Execute plugins (system-level triggers) and fetch back an array with
* their return values.
*
* @param string $event The event (trigger) name, e.g. onBeforeScratchMyEar
* @param array $data A hash array of data sent to the plugins as part of the trigger
*
* @return array A simple array containing the results of the plugins triggered
*/
public function runPlugins(string $event, array $data = []): array
{
return [];
}
/**
* Perform an ACL check. Please note that FOF uses by default the Joomla!
* CMS convention for ACL privileges, e.g core.edit for the edit privilege.
* If your platform uses different conventions you'll have to override the
* FOF defaults using fof.xml or by specialising the controller.
*
* @param string $action The ACL privilege to check, e.g. core.edit
* @param string|null $assetname The asset name to check, typically the component's name
*
* @return bool True if the user is allowed this action
*/
public function authorise(string $action, ?string $assetname = null): bool
{
return true;
}
/**
* Is this the administrative section of the component?
*
* @return boolean
*/
public function isBackend(): bool
{
return true;
}
/**
* Is this the public section of the component?
*
* @param bool $strict True to only confirm if we're under the 'site' client. False to confirm if we're under
* either 'site' or 'api' client (both are front-end access). The default is false which
* causes the method to return true when the application is either 'client' (HTML frontend)
* or 'api' (JSON frontend).
*
* @return bool
*/
public function isFrontend(bool $strict = false): bool
{
return true;
}
/**
* Is this a component running in a CLI application?
*
* @return bool
*/
public function isCli(): bool
{
return true;
}
/**
* Is this a component running under the API application?
*
* @return bool
*/
public function isApi(): bool
{
return true;
}
/**
* Saves something to the cache. This is supposed to be used for system-wide
* FOF data, not application data.
*
* @param string $key The key of the data to save
* @param string $content The actual data to save
*
* @return bool True on success
*/
public function setCache(string $key, string $content): bool
{
return false;
}
/**
* Retrieves data from the cache. This is supposed to be used for system-side
* FOF data, not application data.
*
* @param string $key The key of the data to retrieve
* @param string|null $default The default value to return if the key is not found or the cache is not populated
*
* @return string|null The cached value
*/
public function getCache(string $key, ?string $default = null): ?string
{
return false;
}
/**
* Is the global FOF cache enabled?
*
* @return bool
*/
public function isGlobalFOFCacheEnabled(): bool
{
return true;
}
/**
* Clears the cache of system-wide FOF data. You are supposed to call this in
* your components' installation script post-installation and post-upgrade
* methods or whenever you are modifying the structure of database tables
* accessed by FOF. Please note that FOF's cache never expires and is not
* purged by Joomla!. You MUST use this method to manually purge the cache.
*
* @return bool True on success
*/
public function clearCache(): bool
{
return false;
}
/**
* logs in a user
*
* @param array $authInfo Authentication information
*
* @return bool True on success
*/
public function loginUser(array $authInfo): bool
{
return true;
}
/**
* logs out a user
*
* @return bool True on success
*/
public function logoutUser(): bool
{
return true;
}
/**
* Logs a deprecated practice. In Joomla! this results in the $message being output in the
* deprecated log file, found in your site's log directory.
*
* @param string $message The deprecated practice log message
*
* @return void
*/
public function logDeprecated(string $message): void
{
// The default implementation does nothing. Override this in your platform classes.
}
/** @inheritDoc */
public function logUserAction($title, string $logText, string $extension, User $user = null): void
{
// The default implementation does nothing. Override this in your platform classes.
}
/**
* Returns the version number string of the CMS/application we're running in
*
* @return string
*
* @since 2.1.2
*/
public function getPlatformVersion(): string
{
return '';
}
/**
* Handle an exception in a way that results to an error page.
*
* @param Exception $exception The exception to handle
*
* @throws Exception Possibly rethrown exception
*/
public function showErrorPage(Exception $exception): void
{
throw $exception;
}
/**
* Are plugins allowed to run in CLI mode?
*
* @return bool
*/
public function isAllowPluginsInCli(): bool
{
return $this->allowPluginsInCli;
}
/**
* Set whether plugins are allowed to run in CLI mode
*
* @param bool $allowPluginsInCli
*/
public function setAllowPluginsInCli(bool $allowPluginsInCli): void
{
$this->allowPluginsInCli = $allowPluginsInCli;
}
}
PK �"]���I I Filesystem.phpnu &1i� <?php
/**
* @package FOF
* @copyright Copyright (c)2010-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace FOF40\Platform\Base;
defined('_JEXEC') || die;
use FOF40\Container\Container;
use FOF40\Platform\FilesystemInterface;
abstract class Filesystem implements FilesystemInterface
{
/**
* The list of paths where platform class files will be looked for
*
* @var array
*/
protected static $paths = [];
/** @var Container The component container */
protected $container;
/**
* Public constructor.
*
* @param \FOF40\Container\Container $c The component container
*/
public function __construct(Container $c)
{
$this->container = $c;
}
/**
* Recursive function that will scan every directory unless it's in the ignore list. Files that aren't in the
* ignore list are returned.
*
* @param string $path Folder where we should start looking
* @param array $ignoreFolders Folder ignore list
* @param array $ignoreFiles File ignore list
*
* @return array List of all the files
*/
protected static function scanDirectory(string $path, array $ignoreFolders = [], array $ignoreFiles = []): array
{
$return = [];
$handle = @opendir($path);
if (!$handle)
{
return $return;
}
while (($file = readdir($handle)) !== false)
{
if ($file == '.' || $file == '..')
{
continue;
}
$fullpath = $path . '/' . $file;
if ((is_dir($fullpath) && in_array($file, $ignoreFolders)) || (is_file($fullpath) && in_array($file, $ignoreFiles)))
{
continue;
}
if (is_dir($fullpath))
{
$return = array_merge(self::scanDirectory($fullpath, $ignoreFolders, $ignoreFiles), $return);
}
else
{
$return[] = $path . '/' . $file;
}
}
return $return;
}
/**
* Gets the extension of a file name
*
* @param string $file The file name
*
* @return string The file extension
*/
public function getExt(string $file): string
{
$dot = strrpos($file, '.') + 1;
return substr($file, $dot);
}
/**
* Strips the last extension off of a file name
*
* @param string $file The file name
*
* @return string The file name without the extension
*/
public function stripExt(string $file): string
{
return preg_replace('#\.[^.]*$#', '', $file);
}
}
PK n�!]�Y��! ! Exceptions/ErrorException.phpnu &1i� PK n�!]h}� n Exceptions/WarningException.phpnu &1i� PK n�!]��\U�: �: � Part.phpnu &1i� PK �"]�n / / �C Platform.phpnu &1i� PK �"]���I I s Filesystem.phpnu &1i� PK � �|