This commit is contained in:
cutemeli
2025-12-22 10:35:30 +00:00
parent 0bfc6c8425
commit 5ce7ca2c5d
38927 changed files with 0 additions and 4594700 deletions

View File

@@ -1,22 +0,0 @@
<?php
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} elseif (!headers_sent()) {
echo $err;
}
}
throw new RuntimeException($err);
}
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit4b8cdac3942101cb91ee38514c8b734c::getLoader();

View File

@@ -1,579 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see https://www.php-fig.org/psr/psr-0/
* @see https://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
/** @var bool */
private $useIncludePath = false;
/**
* @var array<string, string>
*/
private $classMap = array();
/** @var bool */
private $classMapAuthoritative = false;
/**
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var string|null */
private $apcuPrefix;
/**
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
}
return array();
}
/**
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
/**
* @return list<string>
*/
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
/**
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
/**
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
$paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
$paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
* @return void
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*
* @return void
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*
* @return void
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*
* @return void
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*
* @return void
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
if (null === $this->vendorDir) {
return;
}
if ($prepend) {
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
} else {
unset(self::$registeredLoaders[$this->vendorDir]);
self::$registeredLoaders[$this->vendorDir] = $this;
}
}
/**
* Unregisters this instance as an autoloader.
*
* @return void
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
if (null !== $this->vendorDir) {
unset(self::$registeredLoaders[$this->vendorDir]);
}
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return true|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
return null;
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
/**
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
return self::$registeredLoaders;
}
/**
* @param string $class
* @param string $ext
* @return string|false
*/
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*
* @param string $file
* @return void
*/
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@@ -1,396 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer;
use Composer\Autoload\ClassLoader;
use Composer\Semver\VersionParser;
/**
* This class is copied in every Composer installed project and available to all
*
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
*
* To require its presence, you can require `composer-runtime-api ^2.0`
*
* @final
*/
class InstalledVersions
{
/**
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
* @internal
*/
private static $selfDir = null;
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
/**
* @var bool
*/
private static $installedIsLocalDir;
/**
* @var bool|null
*/
private static $canGetVendors;
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
/**
* Returns a list of all package names which are present, either by being installed, replaced or provided
*
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackages()
{
$packages = array();
foreach (self::getInstalled() as $installed) {
$packages[] = array_keys($installed['versions']);
}
if (1 === \count($packages)) {
return $packages[0];
}
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
}
/**
* Returns a list of all package names with a specific type e.g. 'library'
*
* @param string $type
* @return string[]
* @psalm-return list<string>
*/
public static function getInstalledPackagesByType($type)
{
$packagesByType = array();
foreach (self::getInstalled() as $installed) {
foreach ($installed['versions'] as $name => $package) {
if (isset($package['type']) && $package['type'] === $type) {
$packagesByType[] = $name;
}
}
}
return $packagesByType;
}
/**
* Checks whether the given package is installed
*
* This also returns true if the package name is provided or replaced by another package
*
* @param string $packageName
* @param bool $includeDevRequirements
* @return bool
*/
public static function isInstalled($packageName, $includeDevRequirements = true)
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
return false;
}
/**
* Checks whether the given package satisfies a version constraint
*
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
*
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
*
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
* @param string $packageName
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
* @return bool
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
}
/**
* Returns a version constraint representing all the range(s) which are installed for a given package
*
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
* whether a given version of a package is installed, and not just whether it exists
*
* @param string $packageName
* @return string Version constraint usable with composer/semver
*/
public static function getVersionRanges($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
$ranges = array();
if (isset($installed['versions'][$packageName]['pretty_version'])) {
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
}
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
}
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
}
if (array_key_exists('provided', $installed['versions'][$packageName])) {
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
}
return implode(' || ', $ranges);
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['version'])) {
return null;
}
return $installed['versions'][$packageName]['version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
*/
public static function getPrettyVersion($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
return null;
}
return $installed['versions'][$packageName]['pretty_version'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
*/
public static function getReference($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
if (!isset($installed['versions'][$packageName]['reference'])) {
return null;
}
return $installed['versions'][$packageName]['reference'];
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @param string $packageName
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
*/
public static function getInstallPath($packageName)
{
foreach (self::getInstalled() as $installed) {
if (!isset($installed['versions'][$packageName])) {
continue;
}
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
}
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
}
/**
* @return array
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
$installed = self::getInstalled();
return $installed[0]['root'];
}
/**
* Returns the raw installed.php data for custom implementations
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = include __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
return self::$installed;
}
/**
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
return self::getInstalled();
}
/**
* Lets you reload the static array from another file
*
* This is only useful for complex integrations in which a project needs to use
* this class but then also needs to execute another project's autoloader in process,
* and wants to ensure both projects have access to their version of installed.php.
*
* A typical case would be PHPUnit, where it would need to make sure it reads all
* the data it needs from this class, then call reload() with
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
* the project in which it runs can then also use this class safely, without
* interference between PHPUnit's dependencies and the project's dependencies.
*
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
self::$installed = $data;
self::$installedByVendor = array();
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
// so we have to assume it does not, and that may result in duplicate data being returned when listing
// all installed packages for example
self::$installedIsLocalDir = false;
}
/**
* @return string
*/
private static function getSelfDir()
{
if (self::$selfDir === null) {
self::$selfDir = strtr(__DIR__, '\\', '/');
}
return self::$selfDir;
}
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
if (null === self::$canGetVendors) {
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
}
$installed = array();
$copiedLocalDir = false;
if (self::$canGetVendors) {
$selfDir = self::getSelfDir();
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
$vendorDir = strtr($vendorDir, '\\', '/');
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
self::$installedByVendor[$vendorDir] = $required;
$installed[] = $required;
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
self::$installed = $required;
self::$installedIsLocalDir = true;
}
}
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
$copiedLocalDir = true;
}
}
}
if (null === self::$installed) {
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array() && !$copiedLocalDir) {
$installed[] = self::$installed;
}
return $installed;
}
}

View File

@@ -1,21 +0,0 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,18 +0,0 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname(dirname($vendorDir)));
return array(
'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);

View File

@@ -1,19 +0,0 @@
<?php
// autoload_files.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname(dirname($vendorDir)));
return array(
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
'a0d10bb2c55d40000bcd36bb9bb54cfa' => $vendorDir . '/plesk/ext-git-plugins/src/DeploymentPlugin/DeploymentPlugin.php',
'dd961c1d949056a79820f472ca79dee1' => $vendorDir . '/plesk/ext-git-plugins/src/DeploymentPlugin/DeploymentStep.php',
'dec7b629a84f3347144cbc5760fbe9bd' => $vendorDir . '/plesk/ext-git-plugins/src/Dto/Repository.php',
'f8e12e3fa6fdccdae2b1a1fc60611fce' => $vendorDir . '/plesk/ext-git-plugins/src/GitPluginHook.php',
);

View File

@@ -1,10 +0,0 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname(dirname($vendorDir)));
return array(
'JsonMapper' => array($vendorDir . '/netresearch/jsonmapper/src'),
);

View File

@@ -1,24 +0,0 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(__DIR__);
$baseDir = dirname(dirname(dirname($vendorDir)));
return array(
'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
'Symfony\\Component\\Validator\\' => array($vendorDir . '/symfony/validator'),
'Symfony\\Component\\DependencyInjection\\' => array($vendorDir . '/symfony/dependency-injection'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'PleskX\\' => array($vendorDir . '/plesk/api-php-lib/src'),
'PleskExt\\Upgrader\\' => array($vendorDir . '/plesk/db-upgrader/src'),
'PleskExt\\Git\\DI\\' => array($baseDir . '/src/dev/DI', $baseDir . '/modules/git/dev/DI'),
'PleskExt\\Git\\' => array($baseDir . '/modules/git/library', $baseDir . '/src/plib/library'),
);

View File

@@ -1,48 +0,0 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit4b8cdac3942101cb91ee38514c8b734c
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
/**
* @return \Composer\Autoload\ClassLoader
*/
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit4b8cdac3942101cb91ee38514c8b734c', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInit4b8cdac3942101cb91ee38514c8b734c', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c::getInitializer($loader));
$loader->register(true);
$filesToLoad = \Composer\Autoload\ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}

View File

@@ -1,143 +0,0 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c
{
public static $files = array (
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
'a0d10bb2c55d40000bcd36bb9bb54cfa' => __DIR__ . '/..' . '/plesk/ext-git-plugins/src/DeploymentPlugin/DeploymentPlugin.php',
'dd961c1d949056a79820f472ca79dee1' => __DIR__ . '/..' . '/plesk/ext-git-plugins/src/DeploymentPlugin/DeploymentStep.php',
'dec7b629a84f3347144cbc5760fbe9bd' => __DIR__ . '/..' . '/plesk/ext-git-plugins/src/Dto/Repository.php',
'f8e12e3fa6fdccdae2b1a1fc60611fce' => __DIR__ . '/..' . '/plesk/ext-git-plugins/src/GitPluginHook.php',
);
public static $prefixLengthsPsr4 = array (
'S' =>
array (
'Symfony\\Polyfill\\Php81\\' => 23,
'Symfony\\Polyfill\\Php80\\' => 23,
'Symfony\\Polyfill\\Php73\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Ctype\\' => 23,
'Symfony\\Contracts\\Translation\\' => 30,
'Symfony\\Contracts\\Service\\' => 26,
'Symfony\\Component\\Validator\\' => 28,
'Symfony\\Component\\DependencyInjection\\' => 38,
),
'P' =>
array (
'Psr\\Log\\' => 8,
'Psr\\Container\\' => 14,
'PleskX\\' => 7,
'PleskExt\\Upgrader\\' => 18,
'PleskExt\\Git\\DI\\' => 16,
'PleskExt\\Git\\' => 13,
),
);
public static $prefixDirsPsr4 = array (
'Symfony\\Polyfill\\Php81\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php81',
),
'Symfony\\Polyfill\\Php80\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
),
'Symfony\\Polyfill\\Php73\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php73',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Symfony\\Contracts\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation-contracts',
),
'Symfony\\Contracts\\Service\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/service-contracts',
),
'Symfony\\Component\\Validator\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/validator',
),
'Symfony\\Component\\DependencyInjection\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dependency-injection',
),
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
),
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'PleskX\\' =>
array (
0 => __DIR__ . '/..' . '/plesk/api-php-lib/src',
),
'PleskExt\\Upgrader\\' =>
array (
0 => __DIR__ . '/..' . '/plesk/db-upgrader/src',
),
'PleskExt\\Git\\DI\\' =>
array (
0 => __DIR__ . '/../../../..' . '/src/dev/DI',
1 => __DIR__ . '/../../../..' . '/modules/git/dev/DI',
),
'PleskExt\\Git\\' =>
array (
0 => __DIR__ . '/../../../..' . '/modules/git/library',
1 => __DIR__ . '/../../../..' . '/src/plib/library',
),
);
public static $prefixesPsr0 = array (
'J' =>
array (
'JsonMapper' =>
array (
0 => __DIR__ . '/..' . '/netresearch/jsonmapper/src',
),
),
);
public static $classMap = array (
'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php',
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php',
'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c::$prefixDirsPsr4;
$loader->prefixesPsr0 = ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c::$prefixesPsr0;
$loader->classMap = ComposerStaticInit4b8cdac3942101cb91ee38514c8b734c::$classMap;
}, null, ClassLoader::class);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,181 +0,0 @@
<?php return array(
'root' => array(
'name' => 'plesk/ext-git',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '93059c7cb721874454fa4d19f2f710984a855a37',
'type' => 'library',
'install_path' => __DIR__ . '/../../../../',
'aliases' => array(),
'dev' => false,
),
'versions' => array(
'netresearch/jsonmapper' => array(
'pretty_version' => 'v5.0.0',
'version' => '5.0.0.0',
'reference' => '8c64d8d444a5d764c641ebe97e0e3bc72b25bf6c',
'type' => 'library',
'install_path' => __DIR__ . '/../netresearch/jsonmapper',
'aliases' => array(),
'dev_requirement' => false,
),
'plesk/api-php-lib' => array(
'pretty_version' => 'v2.2.1',
'version' => '2.2.1.0',
'reference' => '2ceece815106b8997319bcc62fe79d5fe095c65f',
'type' => 'library',
'install_path' => __DIR__ . '/../plesk/api-php-lib',
'aliases' => array(),
'dev_requirement' => false,
),
'plesk/db-upgrader' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '0d0e23a938e43c3921221cd69b77018572979caf',
'type' => 'library',
'install_path' => __DIR__ . '/../plesk/db-upgrader',
'aliases' => array(
0 => '9999999-dev',
),
'dev_requirement' => false,
),
'plesk/ext-git' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '93059c7cb721874454fa4d19f2f710984a855a37',
'type' => 'library',
'install_path' => __DIR__ . '/../../../../',
'aliases' => array(),
'dev_requirement' => false,
),
'plesk/ext-git-plugins' => array(
'pretty_version' => '0.0.7',
'version' => '0.0.7.0',
'reference' => '64c4f236aac26fddf3bb801f5e91cee8991ffc81',
'type' => 'library',
'install_path' => __DIR__ . '/../plesk/ext-git-plugins',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/container' => array(
'pretty_version' => '1.1.2',
'version' => '1.1.2.0',
'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/container',
'aliases' => array(),
'dev_requirement' => false,
),
'psr/container-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0',
),
),
'psr/log' => array(
'pretty_version' => '1.1.4',
'version' => '1.1.4.0',
'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/dependency-injection' => array(
'pretty_version' => 'v5.4.40',
'version' => '5.4.40.0',
'reference' => '408b33326496030c201b8051b003e9e8cdb2efc9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/dependency-injection',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/deprecation-contracts' => array(
'pretty_version' => 'v2.5.3',
'version' => '2.5.3.0',
'reference' => '80d075412b557d41002320b96a096ca65aa2c98d',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => 'v1.30.0',
'version' => '1.30.0.0',
'reference' => '0424dff1c58f028c451efff2045f5d92410bd540',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => 'v1.30.0',
'version' => '1.30.0.0',
'reference' => 'fd22ab50000ef01661e2a31d850ebaa297f8e03c',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php73' => array(
'pretty_version' => 'v1.30.0',
'version' => '1.30.0.0',
'reference' => 'ec444d3f3f6505bb28d11afa41e75faadebc10a1',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php73',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php80' => array(
'pretty_version' => 'v1.30.0',
'version' => '1.30.0.0',
'reference' => '77fa7995ac1b21ab60769b7323d600a991a90433',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/polyfill-php81' => array(
'pretty_version' => 'v1.30.0',
'version' => '1.30.0.0',
'reference' => '3fb075789fb91f9ad9af537c4012d523085bd5af',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php81',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/service-contracts' => array(
'pretty_version' => 'v2.5.3',
'version' => '2.5.3.0',
'reference' => 'a2329596ddc8fd568900e3fc76cba42489ecc7f3',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/service-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/service-implementation' => array(
'dev_requirement' => false,
'provided' => array(
0 => '1.0|2.0',
),
),
'symfony/translation-contracts' => array(
'pretty_version' => 'v2.5.3',
'version' => '2.5.3.0',
'reference' => 'b0073a77ac0b7ea55131020e87b1e3af540f4664',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/translation-contracts',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/validator' => array(
'pretty_version' => 'v5.4.48',
'version' => '5.4.48.0',
'reference' => '883667679d93d6c30f1b7490d669801712d3be2f',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/validator',
'aliases' => array(),
'dev_requirement' => false,
),
),
);

View File

@@ -1,47 +0,0 @@
Open Software License v. 3.0 (OSL-3.0)
This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
Licensed under the Open Software License version 3.0
1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
a) to reproduce the Original Work in copies, either alone or as part of a collective work;
b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
c) to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;
d) to perform the Original Work publicly; and
e) to display the Original Work publicly.
2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensors trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including “fair use” or “fair dealing”). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
16) Modification of This License. This License is Copyright (c) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.

View File

@@ -1,3 +0,0 @@
check:
./vendor/bin/phpunit
./vendor/bin/phpcs

View File

@@ -1,42 +0,0 @@
{
"name": "netresearch/jsonmapper",
"description": "Map nested JSON structures onto PHP classes",
"license": "OSL-3.0",
"autoload": {
"psr-0": {"JsonMapper": "src/"}
},
"autoload-dev": {
"psr-4": {
"namespacetest\\": "tests/support/namespacetest",
"othernamespace\\": "tests/support/othernamespace",
"Enums\\": "tests/support/Enums"
},
"psr-0": {
"JsonMapperTest_": "tests/support",
"": ["tests/support/Zoo"]
}
},
"authors": [
{
"name": "Christian Weiske",
"email": "cweiske@cweiske.de",
"homepage": "http://github.com/cweiske/jsonmapper/",
"role": "Developer"
}
],
"support": {
"email": "cweiske@cweiske.de",
"issues": "https://github.com/cweiske/jsonmapper/issues"
},
"require":{
"php": ">=7.1",
"ext-spl": "*",
"ext-json": "*",
"ext-pcre": "*",
"ext-reflection": "*"
},
"require-dev": {
"phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0",
"squizlabs/php_codesniffer": "~3.5"
}
}

View File

@@ -1,17 +0,0 @@
<?xml version="1.0"?>
<ruleset name="JsonMapper"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="phpcs.xsd">
<rule ref="PEAR">
<exclude name="PEAR.Commenting.FileComment.Missing"/>
<exclude name="PEAR.Commenting.ClassComment.MissingCategoryTag"/>
</rule>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="100"/>
</properties>
</rule>
<file>src/</file>
</ruleset>

View File

@@ -1,22 +0,0 @@
<?xml version="1.0"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
backupGlobals="false"
bootstrap="tests/bootstrap.php"
colors="true"
beStrictAboutChangesToGlobalState="true"
beStrictAboutOutputDuringTests="true"
beStrictAboutTestsThatDoNotTestAnything="true"
>
<testsuites>
<testsuite name="all">
<directory>tests</directory>
</testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">src/</directory>
</include>
</source>
</phpunit>

View File

@@ -1,983 +0,0 @@
<?php
/**
* Automatically map JSON structures into objects.
*
* @package JsonMapper
* @author Christian Weiske <cweiske@cweiske.de>
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link http://cweiske.de/
*/
class JsonMapper
{
/**
* PSR-3 compatible logger object
*
* @link http://www.php-fig.org/psr/psr-3/
* @var \Psr\Log\LoggerInterface|null
* @see setLogger()
*/
protected $logger;
/**
* Throw an exception when JSON data contain a property
* that is not defined in the PHP class
*
* @var boolean
*/
public $bExceptionOnUndefinedProperty = false;
/**
* Throw an exception if the JSON data miss a property
* that is marked with @required in the PHP class
*
* @var boolean
*/
public $bExceptionOnMissingData = false;
/**
* If the types of map() parameters shall be checked.
*
* You have to disable it if you're using the json_decode "assoc" parameter.
*
* json_decode($str, false)
*
* @var boolean
*/
public $bEnforceMapType = true;
/**
* Throw an exception when an object is expected but the JSON contains
* a non-object type.
*
* @var boolean
*/
public $bStrictObjectTypeChecking = true;
/**
* Throw an exception, if null value is found
* but the type of attribute does not allow nulls.
*
* @var boolean
*/
public $bStrictNullTypes = true;
/**
* Throw an exception if null value is found in an array
* but the type of attribute does not allow nulls.
*
* @var boolean
*/
public $bStrictNullTypesInArrays = true;
/**
* Allow mapping of private and protected properties.
*
* @var boolean
*/
public $bIgnoreVisibility = false;
/**
* Remove attributes that were not passed in JSON,
* to avoid confusion between them and NULL values.
*
* @var boolean
*/
public $bRemoveUndefinedAttributes = false;
/**
* Override class names that JsonMapper uses to create objects.
* Useful when your setter methods accept abstract classes or interfaces.
*
* @var array
*/
public $classMap = array();
/**
* Callback used when an undefined property is found.
*
* Works only when $bExceptionOnUndefinedProperty is disabled.
*
* Parameters to this function are:
* 1. Object that is being filled
* 2. Name of the unknown JSON property
* 3. JSON value of the property
*
* @var callable
*/
public $undefinedPropertyHandler = null;
/**
* Runtime cache for inspected classes. This is particularly effective if
* mapArray() is called with a large number of objects
*
* @var array property inspection result cache
*/
protected $arInspectedClasses = array();
/**
* Method to call on each object after deserialization is done.
*
* Is only called if it exists on the object.
*
* @var string|null
*/
public $postMappingMethod = null;
/**
* Optional arguments that are passed to the post mapping method
*
* @var array
*/
public $postMappingMethodArguments = array();
/**
* Map data all data in $json into the given $object instance.
*
* @param object|array $json JSON object structure from json_decode()
* @param object|class-string $object Object to map $json data into
*
* @return mixed Mapped object is returned.
*
* @template T
* @phpstan-param class-string<T>|T $object
* @phpstan-return T
*
* @see mapArray()
*/
public function map($json, $object)
{
if ($this->bEnforceMapType && !is_object($json)) {
throw new InvalidArgumentException(
'JsonMapper::map() requires first argument to be an object'
. ', ' . gettype($json) . ' given.'
);
}
if (!is_object($object) && (!is_string($object) || !class_exists($object))) {
throw new InvalidArgumentException(
'JsonMapper::map() requires second argument to '
. 'be an object or existing class name'
. ', ' . gettype($object) . ' given.'
);
}
if (is_string($object)) {
$object = $this->createInstance($object);
}
$strClassName = get_class($object);
$rc = new ReflectionClass($object);
$strNs = $rc->getNamespaceName();
$providedProperties = array();
foreach ($json as $key => $jvalue) {
$key = $this->getSafeName($key);
$providedProperties[$key] = true;
// Store the property inspection results so we don't have to do it
// again for subsequent objects of the same type
if (!isset($this->arInspectedClasses[$strClassName][$key])) {
$this->arInspectedClasses[$strClassName][$key]
= $this->inspectProperty($rc, $key);
}
list($hasProperty, $accessor, $type, $isNullable)
= $this->arInspectedClasses[$strClassName][$key];
if (!$hasProperty) {
if ($this->bExceptionOnUndefinedProperty) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" does not exist'
. ' in object of type ' . $strClassName
);
} else if ($this->undefinedPropertyHandler !== null) {
$undefinedPropertyKey = call_user_func(
$this->undefinedPropertyHandler,
$object, $key, $jvalue
);
if (is_string($undefinedPropertyKey)) {
list($hasProperty, $accessor, $type, $isNullable)
= $this->inspectProperty($rc, $undefinedPropertyKey);
}
} else {
$this->log(
'info',
'Property {property} does not exist in {class}',
array('property' => $key, 'class' => $strClassName)
);
}
if (!$hasProperty) {
continue;
}
}
if ($accessor === null) {
if ($this->bExceptionOnUndefinedProperty) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" has no public setter method'
. ' in object of type ' . $strClassName
);
}
$this->log(
'info',
'Property {property} has no public setter method in {class}',
array('property' => $key, 'class' => $strClassName)
);
continue;
}
if ($isNullable || !$this->bStrictNullTypes) {
if ($jvalue === null) {
$this->setProperty($object, $accessor, null);
continue;
}
$type = $this->removeNullable($type);
} else if ($jvalue === null) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" in class "'
. $strClassName . '" must not be NULL'
);
}
$type = $this->getFullNamespace($type, $strNs);
$type = $this->getMappedType($type, $jvalue);
if ($type === null || $type === 'mixed') {
//no given type - simply set the json data
$this->setProperty($object, $accessor, $jvalue);
continue;
} else if ($this->isObjectOfSameType($type, $jvalue)) {
$this->setProperty($object, $accessor, $jvalue);
continue;
} else if ($this->isSimpleType($type)
&& !(is_array($jvalue) && $this->hasVariadicArrayType($accessor))
) {
if ($this->isFlatType($type)
&& !$this->isFlatType(gettype($jvalue))
) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" in class "'
. $strClassName . '" is of type ' . gettype($jvalue) . ' and'
. ' cannot be converted to ' . $type
);
}
settype($jvalue, $type);
$this->setProperty($object, $accessor, $jvalue);
continue;
}
//FIXME: check if type exists, give detailed error message if not
if ($type === '') {
throw new JsonMapper_Exception(
'Empty type at property "'
. $strClassName . '::$' . $key . '"'
);
} else if (strpos(str_replace('|null', '', $type), '|')) {
throw new JsonMapper_Exception(
'Cannot decide which of the union types shall be used: '
. $type
);
}
$array = null;
$subtype = null;
if ($this->isArrayOfType($type)) {
//array
$array = array();
$subtype = substr($type, 0, -2);
} else if (substr($type, -1) == ']') {
list($proptype, $subtype) = explode('[', substr($type, 0, -1));
if ($proptype == 'array') {
$array = array();
} else {
$array = $this->createInstance($proptype, false, $jvalue);
}
} else if (is_array($jvalue) && $this->hasVariadicArrayType($accessor)) {
$array = array();
$subtype = $type;
} else {
if (is_a($type, 'ArrayAccess', true)
&& is_a($type, 'Traversable', true)
) {
$array = $this->createInstance($type, false, $jvalue);
}
}
if ($array !== null) {
if (!is_array($jvalue) && $this->isFlatType(gettype($jvalue))) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" must be an array, '
. gettype($jvalue) . ' given'
);
}
$subtypeNullable = $this->isNullable($subtype);
$cleanSubtype = $this->removeNullable($subtype);
$subtype = $this->getFullNamespace($cleanSubtype, $strNs);
if ($subtypeNullable) {
$subtype = '?' . $subtype;
}
$child = $this->mapArray($jvalue, $array, $subtype, $key);
} else if ($this->isFlatType(gettype($jvalue))) {
//use constructor parameter if we have a class
// but only a flat type (i.e. string, int)
if ($this->bStrictObjectTypeChecking) {
throw new JsonMapper_Exception(
'JSON property "' . $key . '" must be an object, '
. gettype($jvalue) . ' given'
);
}
$child = $this->createInstance($type, true, $jvalue);
} else {
$child = $this->createInstance($type, false, $jvalue);
$this->map($jvalue, $child);
}
$this->setProperty($object, $accessor, $child);
}
if ($this->bExceptionOnMissingData) {
$this->checkMissingData($providedProperties, $rc);
}
if ($this->bRemoveUndefinedAttributes) {
$this->removeUndefinedAttributes($object, $providedProperties);
}
if ($this->postMappingMethod !== null
&& $rc->hasMethod($this->postMappingMethod)
) {
$refDeserializePostMethod = $rc->getMethod(
$this->postMappingMethod
);
$refDeserializePostMethod->setAccessible(true);
$refDeserializePostMethod->invoke(
$object, ...$this->postMappingMethodArguments
);
}
return $object;
}
/**
* Convert a type name to a fully namespaced type name.
*
* @param string|null $type Type name (simple type or class name)
* @param string $strNs Base namespace that gets prepended to the type name
*
* @return string|null Fully-qualified type name with namespace
*/
protected function getFullNamespace($type, $strNs)
{
if ($type === null || $type === '' || $type[0] === '\\' || $strNs === '') {
return $type;
}
list($first) = explode('[', $type, 2);
if ($this->isSimpleType($first)) {
return $type;
}
//create a full qualified namespace
return '\\' . $strNs . '\\' . $type;
}
/**
* Check required properties exist in json
*
* @param array $providedProperties array with json properties
* @param ReflectionClass $rc Reflection class to check
*
* @throws JsonMapper_Exception
*
* @return void
*/
protected function checkMissingData($providedProperties, ReflectionClass $rc)
{
foreach ($rc->getProperties() as $property) {
$rprop = $rc->getProperty($property->name);
$docblock = $rprop->getDocComment();
$annotations = static::parseAnnotations($docblock);
if (isset($annotations['required'])
&& !isset($providedProperties[$property->name])
) {
throw new JsonMapper_Exception(
'Required property "' . $property->name . '" of class '
. $rc->getName()
. ' is missing in JSON data'
);
}
}
}
/**
* Remove attributes from object that were not passed in JSON data.
*
* This is to avoid confusion between those that were actually passed
* as NULL, and those that weren't provided at all.
*
* @param object $object Object to remove properties from
* @param array $providedProperties Array with JSON properties
*
* @return void
*/
protected function removeUndefinedAttributes($object, $providedProperties)
{
foreach (get_object_vars($object) as $propertyName => $dummy) {
if (!isset($providedProperties[$propertyName])) {
unset($object->{$propertyName});
}
}
}
/**
* Map an array
*
* @param array $json JSON array structure from json_decode()
* @param mixed $array Array or ArrayObject that gets filled with
* data from $json
* @param string $class Class name for children objects.
* All children will get mapped onto this type.
* Supports class names and simple types
* like "string" and nullability "string|null".
* Pass "null" to not convert any values
* @param string $parent_key Defines the key this array belongs to
* in order to aid debugging.
*
* @return mixed Mapped $array is returned
*/
public function mapArray($json, $array, $class = null, $parent_key = '')
{
$isNullable = $this->isNullable($class);
$class = $this->removeNullable($class);
$originalClass = $class;
foreach ($json as $key => $jvalue) {
if ($jvalue === null && !$isNullable && $this->bStrictNullTypesInArrays) {
throw new JsonMapper_Exception(
'JSON property'
. ' "' . ($parent_key ? $parent_key : '?') . '[' . $key . ']"'
. ' must not be NULL'
);
}
$class = $this->getMappedType($originalClass, $jvalue);
if ($class === null) {
$array[$key] = $jvalue;
} else if ($this->isArrayOfType($class)) {
$array[$key] = $this->mapArray(
$jvalue,
array(),
substr($class, 0, -2)
);
} else if ($this->isFlatType(gettype($jvalue))) {
//use constructor parameter if we have a class
// but only a flat type (i.e. string, int)
if ($jvalue === null) {
$array[$key] = null;
} else {
if ($this->isSimpleType($class)) {
settype($jvalue, $class);
$array[$key] = $jvalue;
} else if ($this->bStrictObjectTypeChecking) {
throw new JsonMapper_Exception(
'JSON property'
. ' "' . ($parent_key ? $parent_key : '?') . '[' . $key . ']"'
. ' must be an object, ' . gettype($jvalue) . ' given'
);
} else {
$array[$key] = $this->createInstance(
$class, true, $jvalue
);
}
}
} else if ($this->isFlatType($class)) {
throw new JsonMapper_Exception(
'JSON property "' . ($parent_key ? $parent_key : '?') . '"'
. ' is an array of type "' . $class . '"'
. ' but contained a value of type'
. ' "' . gettype($jvalue) . '"'
);
} else if (is_a($class, 'ArrayObject', true)) {
$array[$key] = $this->mapArray(
$jvalue,
$this->createInstance($class)
);
} else {
$array[$key] = $this->map(
$jvalue, $this->createInstance($class, false, $jvalue)
);
}
}
return $array;
}
/**
* Try to find out if a property exists in a given class.
* Checks property first, falls back to setter method.
*
* @param ReflectionClass $rc Reflection class to check
* @param string $name Property name
*
* @return array First value: if the property exists
* Second value: the accessor to use (
* ReflectionMethod or ReflectionProperty, or null)
* Third value: type of the property
* Fourth value: if the property is nullable
*/
protected function inspectProperty(ReflectionClass $rc, $name)
{
//try setter method first
$setter = 'set' . $this->getCamelCaseName($name);
if ($rc->hasMethod($setter)) {
$rmeth = $rc->getMethod($setter);
if ($rmeth->isPublic() || $this->bIgnoreVisibility) {
$isNullable = false;
$rparams = $rmeth->getParameters();
if (count($rparams) > 0) {
$isNullable = $rparams[0]->allowsNull();
$ptype = $rparams[0]->getType();
if ($ptype !== null) {
$typeName = $this->stringifyReflectionType($ptype);
//allow overriding an "array" type hint
// with a more specific class in the docblock
if ($typeName !== 'array') {
return array(
true, $rmeth,
$typeName,
$isNullable,
);
}
}
}
$docblock = $rmeth->getDocComment();
$annotations = static::parseAnnotations($docblock);
if (!isset($annotations['param'][0])) {
return array(true, $rmeth, null, $isNullable);
}
list($type) = explode(' ', trim($annotations['param'][0]));
return array(true, $rmeth, $type, $this->isNullable($type));
}
}
//now try to set the property directly
//we have to look it up in the class hierarchy
$class = $rc;
$rprop = null;
do {
if ($class->hasProperty($name)) {
$rprop = $class->getProperty($name);
}
} while ($rprop === null && $class = $class->getParentClass());
if ($rprop === null) {
//case-insensitive property matching
foreach ($rc->getProperties() as $p) {
if ((strcasecmp($p->name, $name) === 0)) {
$rprop = $p;
$class = $rc;
break;
}
}
}
if ($rprop !== null) {
if ($rprop->isPublic() || $this->bIgnoreVisibility) {
$docblock = $rprop->getDocComment();
if (PHP_VERSION_ID >= 80000 && $docblock === false
&& $class->hasMethod('__construct')
) {
$docblock = $class->getMethod('__construct')->getDocComment();
}
$annotations = static::parseAnnotations($docblock);
if (!isset($annotations['var'][0])) {
if (PHP_VERSION_ID >= 80000 && $rprop->hasType()
&& isset($annotations['param'])
) {
foreach ($annotations['param'] as $param) {
if (strpos($param, '$' . $rprop->getName()) !== false) {
list($type) = explode(' ', $param);
return array(
true, $rprop, $type, $this->isNullable($type)
);
}
}
}
// If there is no annotations (higher priority) inspect
// if there's a scalar type being defined
if (PHP_VERSION_ID >= 70400 && $rprop->hasType()) {
$rPropType = $rprop->getType();
$propTypeName = $this->stringifyReflectionType($rPropType);
if ($this->isSimpleType($propTypeName)) {
return array(
true,
$rprop,
$propTypeName,
$rPropType->allowsNull()
);
}
return array(
true,
$rprop,
'\\' . ltrim($propTypeName, '\\'),
$rPropType->allowsNull()
);
}
return array(true, $rprop, null, false);
}
//support "@var type description"
list($type) = explode(' ', $annotations['var'][0]);
return array(true, $rprop, $type, $this->isNullable($type));
} else {
//no setter, private property
return array(true, null, null, false);
}
}
//no setter, no property
return array(false, null, null, false);
}
/**
* Removes - and _ and makes the next letter uppercase
*
* @param string $name Property name
*
* @return string CamelCasedVariableName
*/
protected function getCamelCaseName($name)
{
return str_replace(
' ', '', ucwords(str_replace(array('_', '-'), ' ', $name))
);
}
/**
* Since hyphens cannot be used in variables we have to uppercase them.
*
* Technically you may use them, but they are awkward to access.
*
* @param string $name Property name
*
* @return string Name without hyphen
*/
protected function getSafeName($name)
{
if (strpos($name, '-') !== false) {
$name = $this->getCamelCaseName($name);
}
return $name;
}
/**
* Set a property on a given object to a given value.
*
* Checks if the setter or the property are public are made before
* calling this method.
*
* @param object $object Object to set property on
* @param object $accessor ReflectionMethod or ReflectionProperty
* @param mixed $value Value of property
*
* @return void
*/
protected function setProperty(
$object, $accessor, $value
) {
if (!$accessor->isPublic() && $this->bIgnoreVisibility) {
$accessor->setAccessible(true);
}
if ($accessor instanceof ReflectionProperty) {
$accessor->setValue($object, $value);
} else if (is_array($value) && $this->hasVariadicArrayType($accessor)) {
$accessor->invoke($object, ...$value);
} else {
//setter method
$accessor->invoke($object, $value);
}
}
/**
* Create a new object of the given type.
*
* This method exists to be overwritten in child classes,
* so you can do dependency injection or so.
*
* @param string $class Class name to instantiate
* @param boolean $useParameter Pass $parameter to the constructor or not
* @param mixed $jvalue Constructor parameter (the json value)
*
* @return object Freshly created object
*/
protected function createInstance(
$class, $useParameter = false, $jvalue = null
) {
if ($useParameter) {
if (PHP_VERSION_ID >= 80100
&& is_subclass_of($class, \BackedEnum::class)
) {
return $class::from($jvalue);
}
return new $class($jvalue);
} else {
$reflectClass = new ReflectionClass($class);
$constructor = $reflectClass->getConstructor();
if (null === $constructor
|| $constructor->getNumberOfRequiredParameters() > 0
) {
return $reflectClass->newInstanceWithoutConstructor();
}
return $reflectClass->newInstance();
}
}
/**
* Get the mapped class/type name for this class.
* Returns the incoming classname if not mapped.
*
* Lets you override class names via the $classMap property.
*
* @param string|null $type Type name to map
* @param mixed $jvalue Constructor parameter (the json value)
*
* @return string|null The mapped type/class name
*/
protected function getMappedType($type, $jvalue = null)
{
if (isset($this->classMap[$type])) {
$target = $this->classMap[$type];
} else if (is_string($type) && $type !== '' && $type[0] == '\\'
&& isset($this->classMap[substr($type, 1)])
) {
$target = $this->classMap[substr($type, 1)];
} else {
$target = null;
}
if ($target) {
if (is_callable($target)) {
$type = $target($type, $jvalue);
} else {
$type = $target;
}
}
return $type;
}
/**
* Checks if the given type is a "simple type"
*
* @param string $type type name from gettype()
*
* @return boolean True if it is a simple PHP type
*
* @see isFlatType()
*/
protected function isSimpleType($type)
{
return $type == 'string'
|| $type == 'boolean' || $type == 'bool'
|| $type == 'integer' || $type == 'int'
|| $type == 'double' || $type == 'float'
|| $type == 'array' || $type == 'object'
|| $type === 'mixed';
}
/**
* Checks if the object is of this type or has this type as one of its parents
*
* @param string $type class name of type being required
* @param mixed $value Some PHP value to be tested
*
* @return boolean True if $object has type of $type
*/
protected function isObjectOfSameType($type, $value)
{
if (false === is_object($value)) {
return false;
}
return is_a($value, $type);
}
/**
* Checks if the given type is a type that is not nested
* (simple type except array, object and mixed)
*
* @param string $type type name from gettype()
*
* @return boolean True if it is a non-nested PHP type
*
* @see isSimpleType()
*/
protected function isFlatType($type)
{
return $type == 'NULL'
|| $type == 'string'
|| $type == 'boolean' || $type == 'bool'
|| $type == 'integer' || $type == 'int'
|| $type == 'double' || $type == 'float';
}
/**
* Returns true if type is an array of elements
* (bracket notation)
*
* @param string $strType type to be matched
*
* @return bool
*/
protected function isArrayOfType($strType)
{
return substr($strType, -2) === '[]';
}
/**
* Returns true if accessor is a method and has only one parameter
* which is variadic ("...$args").
*
* @param ReflectionMethod|ReflectionProperty|null $accessor accessor
* to set value
*
* @return bool
*/
protected function hasVariadicArrayType($accessor)
{
if (!$accessor instanceof ReflectionMethod) {
return false;
}
$parameters = $accessor->getParameters();
if (count($parameters) !== 1) {
return false;
}
$parameter = $parameters[0];
return $parameter->isVariadic();
}
/**
* Checks if the given type is nullable
*
* @param string $type type name from the phpdoc param
*
* @return boolean True if it is nullable
*/
protected function isNullable($type)
{
return stripos('|' . $type . '|', '|null|') !== false
|| strpos('|' . $type, '|?') !== false;
}
/**
* Remove the 'null' section of a type
*
* @param string|null $type type name from the phpdoc param
*
* @return string|null The new type value
*/
protected function removeNullable($type)
{
if ($type === null) {
return null;
}
return substr(
str_ireplace(['|null|', '|?'], '|', '|' . $type . '|'),
1, -1
);
}
/**
* Get a string representation of the reflection type.
* Required because named, union and intersection types need to be handled.
*
* @param ReflectionType $type Native PHP type
*
* @return string "foo|bar"
*/
protected function stringifyReflectionType(ReflectionType $type)
{
if ($type instanceof ReflectionNamedType) {
return ($type->isBuiltin() ? '' : '\\') . $type->getName();
}
return implode(
'|',
array_map(
function (ReflectionNamedType $type) {
return ($type->isBuiltin() ? '' : '\\') . $type->getName();
},
$type->getTypes()
)
);
}
/**
* Copied from PHPUnit 3.7.29, Util/Test.php
*
* @param string $docblock Full method docblock
*
* @return array Array of arrays.
* Key is the "@"-name like "param",
* each value is an array of the rest of the @-lines
*/
protected static function parseAnnotations($docblock)
{
$annotations = array();
// Strip away the docblock header and footer
// to ease parsing of one line annotations
$docblock = substr($docblock, 3, -2);
$re = '/@(?P<name>[A-Za-z_-]+)(?:[ \t]+(?P<value>.*?))?[ \t]*\r?$/m';
if (preg_match_all($re, $docblock, $matches)) {
$numMatches = count($matches[0]);
for ($i = 0; $i < $numMatches; ++$i) {
$annotations[$matches['name'][$i]][] = $matches['value'][$i];
}
}
return $annotations;
}
/**
* Log a message to the $logger object
*
* @param string $level Logging level
* @param string $message Text to log
* @param array $context Additional information
*
* @return void
*/
protected function log($level, $message, array $context = array())
{
if ($this->logger) {
$this->logger->log($level, $message, $context);
}
}
/**
* Sets a logger instance on the object
*
* @param \Psr\Log\LoggerInterface $logger PSR-3 compatible logger object
*
* @return void
*/
public function setLogger($logger)
{
$this->logger = $logger;
}
}
?>

View File

@@ -1,13 +0,0 @@
<?php
/**
* Simple exception
*
* @package JsonMapper
* @author Christian Weiske <cweiske@cweiske.de>
* @license OSL-3.0 http://opensource.org/licenses/osl-3.0
* @link http://cweiske.de/
*/
class JsonMapper_Exception extends Exception
{
}
?>

View File

@@ -1,8 +0,0 @@
version: 2
updates:
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "TECH "

View File

@@ -1,13 +0,0 @@
name: test
on: [push]
jobs:
test:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- run: docker compose run tests
- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -1,5 +0,0 @@
/.env
/vendor/
/phpunit.xml
/.phpunit.result.cache
/coverage.xml

View File

@@ -1,9 +0,0 @@
FROM php:8.2-cli
RUN apt-get update \
&& apt-get install -y unzip \
&& docker-php-ext-install pcntl \
&& pecl install xdebug \
&& echo "zend_extension=xdebug.so" > /usr/local/etc/php/conf.d/xdebug.ini \
&& echo "xdebug.mode=coverage" >> /usr/local/etc/php/conf.d/xdebug.ini \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

View File

@@ -1,13 +0,0 @@
Copyright 1999-2025. WebPros International GmbH.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,67 +0,0 @@
## PHP library for Plesk XML-RPC API
[![Test Status](https://github.com/plesk/api-php-lib/actions/workflows/test.yml/badge.svg)](https://github.com/plesk/api-php-lib/actions/workflows/test.yml)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/plesk/api-php-lib/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/plesk/api-php-lib/?branch=master)
[![codecov](https://codecov.io/gh/plesk/api-php-lib/branch/master/graph/badge.svg?token=5Kwbddpdeb)](https://codecov.io/gh/plesk/api-php-lib)
PHP object-oriented library for Plesk XML-RPC API.
## Install Via Composer
[Composer](https://getcomposer.org/) is a preferable way to install the library:
`composer require plesk/api-php-lib`
## Usage Examples
Here is an example on how to use the library and create a customer with desired properties:
```php
$client = new \PleskX\Api\Client($host);
$client->setCredentials($login, $password);
$client->customer()->create([
'cname' => 'Plesk',
'pname' => 'John Smith',
'login' => 'john',
'passwd' => 'secret',
'email' => 'john@smith.com',
]);
```
It is possible to use a secret key instead of password for authentication.
```php
$client = new \PleskX\Api\Client($host);
$client->setSecretKey($secretKey)
```
In case of Plesk extension creation one can use an internal mechanism to access XML-RPC API. It does not require to pass authentication because the extension works in the context of Plesk.
```php
$client = new \PleskX\Api\InternalClient();
$protocols = $client->server()->getProtos();
```
For additional examples see tests/ directory.
## How to Run Unit Tests
One the possible ways to become familiar with the library is to check the unit tests.
To run the unit tests use the following command:
`REMOTE_HOST=your-plesk-host.dom REMOTE_PASSWORD=password composer test`
To use custom port one can provide a URL (e.g. for Docker container):
`REMOTE_URL=https://your-plesk-host.dom:port REMOTE_PASSWORD=password composer test`
One more way to run tests is to use Docker:
`docker-compose run tests`
## Continuous Testing
During active development it could be more convenient to run tests in continuous manner. Here is the way how to achieve it:
`REMOTE_URL=https://your-plesk-host.dom:port REMOTE_PASSWORD=password composer test:watch`

View File

@@ -1,58 +0,0 @@
{
"name": "plesk/api-php-lib",
"type": "library",
"description": "PHP object-oriented library for Plesk XML-RPC API",
"license": "Apache-2.0",
"authors": [
{
"name": "Alexei Yuzhakov",
"email": "sibprogrammer@gmail.com"
},
{
"name": "WebPros International GmbH.",
"email": "plesk-dev-leads@plesk.com"
}
],
"require": {
"php": "^7.4 || ^8.0",
"ext-curl": "*",
"ext-xml": "*",
"ext-simplexml": "*",
"ext-dom": "*"
},
"require-dev": {
"phpunit/phpunit": "^9",
"spatie/phpunit-watcher": "^1.22",
"vimeo/psalm": "^4.10 || ^5.0",
"squizlabs/php_codesniffer": "^3.6"
},
"config": {
"process-timeout": 0,
"platform": {
"php": "7.4.27"
}
},
"scripts": {
"test": "phpunit",
"test:watch": "phpunit-watcher watch",
"lint": [
"psalm",
"phpcs"
]
},
"autoload": {
"psr-4": {
"PleskX\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"PleskXTest\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +0,0 @@
# Copyright 1999-2025. WebPros International GmbH.
version: '3'
services:
plesk:
image: plesk/plesk:latest
logging:
driver: none
ports:
["8443:8443"]
tmpfs:
- /tmp
- /run
- /run/lock
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup
cgroup: host
tests:
build: .
environment:
REMOTE_URL: https://plesk:8443
REMOTE_PASSWORD: changeme1Q**
command: >
bash -c "cd /opt/api-php-lib
&& composer install
&& ./wait-for-plesk.sh
&& composer lint
&& composer test -- --testdox"
depends_on:
- plesk
links:
- plesk
volumes:
- .:/opt/api-php-lib

View File

@@ -1,28 +0,0 @@
<?xml version="1.0"?>
<!-- Copyright 1999-2025. WebPros International GmbH. -->
<ruleset name="PHP library for Plesk XML-RPC API">
<file>src</file>
<file>tests</file>
<rule ref="Generic">
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent"/>
<exclude name="Generic.Files.EndFileNoNewline"/>
<exclude name="Generic.Files.LowercasedFilename.NotFound"/>
<exclude name="Generic.PHP.RequireStrictTypes"/>
<exclude name="Generic.PHP.ClosingPHPTag"/>
<exclude name="Generic.PHP.UpperCaseConstant"/>
<exclude name="Generic.Arrays.DisallowShortArraySyntax"/>
<exclude name="Generic.Classes.OpeningBraceSameLine"/>
<exclude name="Generic.Functions.OpeningFunctionBraceKernighanRitchie"/>
<exclude name="Generic.Formatting.MultipleStatementAlignment"/>
<exclude name="Generic.Formatting.NoSpaceAfterCast"/>
<exclude name="Generic.Formatting.SpaceBeforeCast"/>
<exclude name="Generic.Formatting.SpaceAfterNot"/>
<exclude name="Generic.Commenting.DocComment"/>
<exclude name="Generic.ControlStructures.DisallowYodaConditions"/>
</rule>
<rule ref="PSR1"/>
<rule ref="PSR2"/>
<rule ref="PSR12">
<exclude name="PSR12.Files.FileHeader"/>
</rule>
</ruleset>

View File

@@ -1,4 +0,0 @@
# Copyright 1999-2025. WebPros International GmbH.
phpunit:
arguments: '--stop-on-failure'
timeout: 0

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 1999-2025. WebPros International GmbH. -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="vendor/autoload.php" verbose="true" colors="true">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
<report>
<clover outputFile="coverage.xml"/>
</report>
</coverage>
<testsuites>
<testsuite name="E2E">
<directory>./tests</directory>
</testsuite>
</testsuites>
<php>
<ini name="error_reporting" value="-1"/>
<env name="REMOTE_URL" value=""/>
<env name="REMOTE_PASSWORD" value=""/>
</php>
<logging/>
</phpunit>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0"?>
<!-- Copyright 1999-2025. WebPros International GmbH. -->
<psalm
errorLevel="3"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<PropertyNotSetInConstructor errorLevel="suppress" />
<UndefinedPropertyFetch errorLevel="suppress" />
</issueHandlers>
</psalm>

View File

@@ -1,76 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api;
abstract class AbstractStruct
{
/**
* @param string $property
* @param mixed $value
*
* @throws \Exception
*/
public function __set(string $property, $value)
{
throw new \Exception("Try to set an undeclared property '$property' to a value: $value.");
}
/**
* Initialize list of scalar properties by response.
*
* @param \SimpleXMLElement $apiResponse
* @param array $properties
*
* @throws \Exception
*/
protected function initScalarProperties(\SimpleXMLElement $apiResponse, array $properties): void
{
foreach ($properties as $property) {
if (is_array($property)) {
$classPropertyName = current($property);
$value = $apiResponse->{key($property)};
} else {
/** @psalm-suppress PossiblyInvalidArgument */
$classPropertyName = $this->underToCamel(str_replace('-', '_', $property));
$value = $apiResponse->$property;
}
$reflectionProperty = new \ReflectionProperty($this, $classPropertyName);
$propertyType = $reflectionProperty->getType();
if (is_null($propertyType)) {
$docBlock = $reflectionProperty->getDocComment();
$propertyType = preg_replace('/^.+ @var ([a-z]+) .+$/', '\1', $docBlock);
} else {
/** @psalm-suppress UndefinedMethod */
$propertyType = $propertyType->getName();
}
if ('string' == $propertyType) {
$value = (string) $value;
} elseif ('int' == $propertyType) {
$value = (int) $value;
} elseif ('bool' == $propertyType) {
$value = in_array((string) $value, ['true', 'on', 'enabled']);
} else {
throw new \Exception("Unknown property type '$propertyType'.");
}
$this->$classPropertyName = $value;
}
}
/**
* Convert underscore separated words into camel case.
*
* @param string $under
*
* @return string
*/
private function underToCamel(string $under): string
{
$under = '_' . str_replace('_', ' ', strtolower($under));
return ltrim(str_replace(' ', '', ucwords($under)), '_');
}
}

View File

@@ -1,577 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api;
use DOMDocument;
use SimpleXMLElement;
/**
* Client for Plesk XML-RPC API.
*/
class Client
{
public const RESPONSE_SHORT = 1;
public const RESPONSE_FULL = 2;
private string $host;
private int $port;
private string $protocol;
protected string $login = '';
private string $password = '';
private string $proxy = '';
private string $secretKey = '';
private string $version = '';
protected array $operatorsCache = [];
/**
* @var callable|null
*/
protected $verifyResponseCallback;
/**
* Create client.
*
* @param string $host
* @param int $port
* @param string $protocol
*/
public function __construct(string $host, int $port = 8443, string $protocol = 'https')
{
$this->host = $host;
$this->port = $port;
$this->protocol = $protocol;
}
/**
* Setup credentials for authentication.
*
* @param string $login
* @param string $password
*/
public function setCredentials(string $login, string $password): void
{
$this->login = $login;
$this->password = $password;
}
/**
* Define secret key for alternative authentication.
*
* @param string $secretKey
*/
public function setSecretKey(string $secretKey): void
{
$this->secretKey = $secretKey;
}
/**
* Set proxy server for requests.
*
* @param string $proxy
*/
public function setProxy(string $proxy): void
{
$this->proxy = $proxy;
}
/**
* Set default version for requests.
*
* @param string $version
*/
public function setVersion(string $version): void
{
$this->version = $version;
}
/**
* Set custom function to verify response of API call according your own needs.
* Default verifying will be used if it is not specified.
*
* @param callable|null $function
*/
public function setVerifyResponse(?callable $function = null): void
{
$this->verifyResponseCallback = $function;
}
/**
* Retrieve host used for communication.
*
* @return string
*/
public function getHost(): string
{
return $this->host;
}
/**
* Retrieve port used for communication.
*
* @return int
*/
public function getPort(): int
{
return $this->port;
}
/**
* Retrieve name of the protocol (http or https) used for communication.
*
* @return string
*/
public function getProtocol(): string
{
return $this->protocol;
}
/**
* Retrieve XML template for packet.
*
* @param string|null $version
*
* @return SimpleXMLElement
*/
public function getPacket($version = null): SimpleXMLElement
{
$protocolVersion = !is_null($version) ? $version : $this->version;
$content = "<?xml version='1.0' encoding='UTF-8' ?>";
$content .= '<packet' . ('' === $protocolVersion ? '' : " version='$protocolVersion'") . '/>';
return new SimpleXMLElement($content);
}
/**
* Perform API request.
*
* @param string|array|SimpleXMLElement $request
* @param int $mode
*
* @return XmlResponse
* @throws \Exception
*/
public function request($request, int $mode = self::RESPONSE_SHORT): XmlResponse
{
if ($request instanceof SimpleXMLElement) {
$request = $request->asXml();
} else {
$xml = $this->getPacket();
if (is_array($request)) {
$request = $this->arrayToXml($request, $xml)->asXML();
} elseif (preg_match('/^[a-z]/', $request)) {
$request = $this->expandRequestShortSyntax($request, $xml);
}
}
if ('sdk' == $this->protocol) {
$xml = $this->performSdkCall((string) $request);
} else {
$xml = $this->performHttpRequest((string) $request);
}
$this->verifyResponseCallback
? call_user_func($this->verifyResponseCallback, $xml)
: $this->verifyResponse($xml);
$result = (self::RESPONSE_FULL === $mode)
? $xml
: ($xml->xpath('//result') ?: [null])[0];
return new XmlResponse($result ? (string) $result->asXML() : '');
}
private function performSdkCall(string $request): XmlResponse
{
$version = ('' == $this->version) ? null : $this->version;
$requestXml = new SimpleXMLElement($request);
$innerNodes = $requestXml->children();
$innerXml = $innerNodes && count($innerNodes) > 0 && $innerNodes[0] ? $innerNodes[0]->asXml() : '';
/** @psalm-suppress UndefinedClass */
$result = \pm_ApiRpc::getService($version)->call($innerXml, $this->login);
return new XmlResponse($result ? (string) $result->asXML() : '');
}
/**
* Perform HTTP request to end-point.
*
* @param string $request
*
* @throws Client\Exception
*
* @return XmlResponse
*/
private function performHttpRequest($request)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "$this->protocol://$this->host:$this->port/enterprise/control/agent.php");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, $this->getHeaders());
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
if ('' !== $this->proxy) {
curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
}
$result = curl_exec($curl);
if (false === $result) {
throw new Client\Exception(curl_error($curl), curl_errno($curl));
}
curl_close($curl);
return new XmlResponse((string) $result);
}
/**
* Perform multiple API requests using single HTTP request.
*
* @param array $requests
* @param int $mode
*
* @throws Client\Exception
*
* @return array
*/
public function multiRequest(array $requests, int $mode = self::RESPONSE_SHORT): array
{
$requestXml = $this->getPacket();
foreach ($requests as $request) {
if ($request instanceof SimpleXMLElement) {
throw new Client\Exception('SimpleXML type of request is not supported for multi requests.');
} else {
if (is_array($request)) {
$request = $this->arrayToXml($request, $requestXml)->asXML();
if (!$request) {
throw new Client\Exception('Failed to create an XML string for request');
}
} elseif (preg_match('/^[a-z]/', $request)) {
$this->expandRequestShortSyntax($request, $requestXml);
}
}
}
if ('sdk' == $this->protocol) {
throw new Client\Exception('Multi requests are not supported via SDK.');
} else {
$xmlString = $requestXml->asXML();
if (!$xmlString) {
throw new Client\Exception('Failed to create an XML string for request');
}
$responseXml = $this->performHttpRequest($xmlString);
}
return $this->splitResponseToArray($responseXml, $mode);
}
private function splitResponseToArray(XmlResponse $responseXml, $mode = self::RESPONSE_SHORT): array
{
$responses = [];
$nodes = $responseXml->children();
if (!$nodes) {
return [];
}
foreach ($nodes as $childNode) {
$dom = $this->getDomDocument($this->getPacket());
if (!$dom) {
continue;
}
$childDomNode = dom_import_simplexml($childNode);
if (!is_null($childDomNode)) {
$childDomNode = $dom->importNode($childDomNode, true);
$dom->documentElement->appendChild($childDomNode);
}
$response = simplexml_load_string($dom->saveXML());
if (!$response) {
return [];
}
$responses[] = (self::RESPONSE_FULL == $mode)
? $response
: ($response->xpath('//result') ?: [null])[0];
}
return $responses;
}
private function getDomDocument(SimpleXMLElement $xml): ?DOMDocument
{
$dom = dom_import_simplexml($xml);
if (is_null($dom)) {
return null;
}
return $dom->ownerDocument;
}
/**
* Retrieve list of headers needed for request.
*
* @return array
*/
private function getHeaders()
{
$headers = [
'Content-Type: text/xml',
'HTTP_PRETTY_PRINT: TRUE',
];
if ($this->secretKey) {
$headers[] = "KEY: $this->secretKey";
} else {
$headers[] = "HTTP_AUTH_LOGIN: $this->login";
$headers[] = "HTTP_AUTH_PASSWD: $this->password";
}
return $headers;
}
/**
* Verify that response does not contain errors.
*
* @param XmlResponse $xml
*
* @throws Exception
*/
private function verifyResponse($xml): void
{
if ($xml->system && $xml->system->status && 'error' == (string) $xml->system->status) {
throw new Exception((string) $xml->system->errtext, (int) $xml->system->errcode);
}
if ($xml->xpath('//status[text()="error"]') && $xml->xpath('//errcode') && $xml->xpath('//errtext')) {
$errorCode = (int) ($xml->xpath('//errcode') ?: [null])[0];
$errorMessage = (string) ($xml->xpath('//errtext') ?: [null])[0];
throw new Exception($errorMessage, $errorCode);
}
}
/**
* Expand short syntax (some.method.call) into full XML representation.
*
* @param string $request
* @param SimpleXMLElement $xml
*
* @return false|string
*/
private function expandRequestShortSyntax($request, SimpleXMLElement $xml)
{
$parts = explode('.', $request);
$node = $xml;
$lastParts = end($parts);
foreach ($parts as $part) {
// phpcs:ignore
@list($name, $value) = explode('=', $part);
if ($part !== $lastParts) {
$node = $node->addChild($name);
} else {
$node->{$name} = (string) $value;
}
}
return $xml->asXML();
}
/**
* Convert array to XML representation.
*
* @param array $array
* @param SimpleXMLElement $xml
* @param string $parentEl
*
* @return SimpleXMLElement
*/
private function arrayToXml(array $array, SimpleXMLElement $xml, $parentEl = null)
{
foreach ($array as $key => $value) {
$el = is_int($key) && $parentEl ? $parentEl : $key;
if (is_array($value)) {
$this->arrayToXml($value, $this->isAssocArray($value) ? $xml->addChild($el) : $xml, $el);
} elseif (!isset($xml->{$el})) {
$xml->{$el} = (string) $value;
} else {
$xml->{$el}[] = (string) $value;
}
}
return $xml;
}
/**
* @param array $array
*
* @return bool
*/
private function isAssocArray(array $array)
{
return $array && array_keys($array) !== range(0, count($array) - 1);
}
/**
* @param string $name
*
* @return mixed
*/
private function getOperator(string $name)
{
if (!isset($this->operatorsCache[$name])) {
$className = '\\PleskX\\Api\\Operator\\' . $name;
/** @psalm-suppress InvalidStringClass */
$this->operatorsCache[$name] = new $className($this);
}
return $this->operatorsCache[$name];
}
public function server(): Operator\Server
{
return $this->getOperator('Server');
}
public function customer(): Operator\Customer
{
return $this->getOperator('Customer');
}
public function webspace(): Operator\Webspace
{
return $this->getOperator('Webspace');
}
public function subdomain(): Operator\Subdomain
{
return $this->getOperator('Subdomain');
}
public function dns(): Operator\Dns
{
return $this->getOperator('Dns');
}
public function dnsTemplate(): Operator\DnsTemplate
{
return $this->getOperator('DnsTemplate');
}
public function databaseServer(): Operator\DatabaseServer
{
return $this->getOperator('DatabaseServer');
}
public function mail(): Operator\Mail
{
return $this->getOperator('Mail');
}
public function certificate(): Operator\Certificate
{
return $this->getOperator('Certificate');
}
public function siteAlias(): Operator\SiteAlias
{
return $this->getOperator('SiteAlias');
}
public function ip(): Operator\Ip
{
return $this->getOperator('Ip');
}
public function eventLog(): Operator\EventLog
{
return $this->getOperator('EventLog');
}
public function secretKey(): Operator\SecretKey
{
return $this->getOperator('SecretKey');
}
public function ui(): Operator\Ui
{
return $this->getOperator('Ui');
}
public function servicePlan(): Operator\ServicePlan
{
return $this->getOperator('ServicePlan');
}
public function virtualDirectory(): Operator\VirtualDirectory
{
return $this->getOperator('VirtualDirectory');
}
public function database(): Operator\Database
{
return $this->getOperator('Database');
}
public function session(): Operator\Session
{
return $this->getOperator('Session');
}
public function locale(): Operator\Locale
{
return $this->getOperator('Locale');
}
public function logRotation(): Operator\LogRotation
{
return $this->getOperator('LogRotation');
}
public function protectedDirectory(): Operator\ProtectedDirectory
{
return $this->getOperator('ProtectedDirectory');
}
public function reseller(): Operator\Reseller
{
return $this->getOperator('Reseller');
}
public function resellerPlan(): Operator\ResellerPlan
{
return $this->getOperator('ResellerPlan');
}
public function aps(): Operator\Aps
{
return $this->getOperator('Aps');
}
public function servicePlanAddon(): Operator\ServicePlanAddon
{
return $this->getOperator('ServicePlanAddon');
}
public function site(): Operator\Site
{
return $this->getOperator('Site');
}
public function phpHandler(): Operator\PhpHandler
{
return $this->getOperator('PhpHandler');
}
}

View File

@@ -1,11 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Client;
/**
* Transport layer exception.
*/
class Exception extends \Exception
{
}

View File

@@ -1,11 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api;
/**
* Exceptions for XML-RPC API client.
*/
class Exception extends \Exception
{
}

View File

@@ -1,25 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api;
/**
* Internal client for Plesk XML-RPC API (via SDK).
*/
class InternalClient extends Client
{
public function __construct()
{
parent::__construct('localhost', 0, 'sdk');
}
/**
* Setup login to execute requests under certain user.
*
* @param string $login
*/
public function setLogin(string $login): void
{
$this->login = $login;
}
}

View File

@@ -1,106 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api;
class Operator
{
protected string $wrapperTag = '';
protected Client $client;
public function __construct(Client $client)
{
$this->client = $client;
if ('' === $this->wrapperTag) {
$classNameParts = explode('\\', get_class($this));
$this->wrapperTag = end($classNameParts);
$this->wrapperTag = strtolower(preg_replace('/([a-z])([A-Z])/', '\1-\2', $this->wrapperTag));
}
}
/**
* Perform plain API request.
*
* @param string|array $request
* @param int $mode
*
* @return XmlResponse
*/
public function request($request, $mode = Client::RESPONSE_SHORT): XmlResponse
{
$wrapperTag = $this->wrapperTag;
if (is_array($request)) {
$request = [$wrapperTag => $request];
} elseif (preg_match('/^[a-z]/', $request)) {
$request = "$wrapperTag.$request";
} else {
$request = "<$wrapperTag>$request</$wrapperTag>";
}
return $this->client->request($request, $mode);
}
/**
* @param string $field
* @param int|string $value
* @param string $deleteMethodName
*
* @return bool
*/
protected function deleteBy(string $field, $value, string $deleteMethodName = 'del'): bool
{
$response = $this->request([
$deleteMethodName => [
'filter' => [
$field => $value,
],
],
]);
return 'ok' === (string) $response->status;
}
/**
* @param string $structClass
* @param string $infoTag
* @param string|null $field
* @param int|string|null $value
* @param callable|null $filter
*
* @return array
*/
protected function getItems($structClass, $infoTag, $field = null, $value = null, ?callable $filter = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->{$field} = (string) $value;
}
$getTag->addChild('dataset')->addChild($infoTag);
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult || !isset($xmlResult->data) || !isset($xmlResult->data->$infoTag)) {
continue;
}
if (!is_null($filter) && !$filter($xmlResult->data->$infoTag)) {
continue;
}
/** @psalm-suppress InvalidStringClass */
$item = new $structClass($xmlResult->data->$infoTag);
if (isset($xmlResult->id) && property_exists($item, 'id')) {
$item->id = (int) $xmlResult->id;
}
$items[] = $item;
}
return $items;
}
}

View File

@@ -1,8 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
class Aps extends \PleskX\Api\Operator
{
}

View File

@@ -1,87 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Certificate as Struct;
class Certificate extends \PleskX\Api\Operator
{
public function generate(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('generate')->addChild('info');
foreach ($properties as $name => $value) {
$info->{$name} = $value;
}
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param array $properties
* @param string|Struct\Info $certificate
* @param string|null $privateKey
*/
public function install(array $properties, $certificate, ?string $privateKey = null): bool
{
return $this->callApi('install', $properties, $certificate, $privateKey);
}
/**
* @param array $properties
* @param Struct\Info $certificate
*/
public function update(array $properties, Struct\Info $certificate): bool
{
return $this->callApi('update', $properties, $certificate);
}
/**
* @param string $method
* @param array $properties
* @param string|Struct\Info $certificate
* @param string|null $privateKey
*/
private function callApi(string $method, array $properties, $certificate, ?string $privateKey = null): bool
{
$packet = $this->client->getPacket();
$installTag = $packet->addChild($this->wrapperTag)->addChild($method);
foreach ($properties as $name => $value) {
$installTag->{$name} = $value;
}
$contentTag = $installTag->addChild('content');
if (is_string($certificate)) {
$contentTag->addChild('csr', $certificate);
$contentTag->addChild('pvt', $privateKey);
} elseif ($certificate instanceof \PleskX\Api\Struct\Certificate\Info) {
foreach ($certificate->getMapping() as $name => $value) {
$contentTag->{$name} = $value;
}
}
$result = $this->client->request($packet);
return 'ok' == (string) $result->status;
}
public function delete(string $name, array $properties): bool
{
$packet = $this->client->getPacket();
$removeTag = $packet->addChild($this->wrapperTag)->addChild('remove');
$removeTag->addChild('filter')->addChild('name', $name);
foreach ($properties as $name => $value) {
$removeTag->{$name} = $value;
}
$result = $this->client->request($packet);
return 'ok' == (string) $result->status;
}
}

View File

@@ -1,99 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Customer as Struct;
class Customer extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add')->addChild('gen_info');
foreach ($properties as $name => $value) {
$info->{$name} = $value;
}
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\GeneralInfo
*/
public function get(string $field, $value): Struct\GeneralInfo
{
$items = $this->getItems(Struct\GeneralInfo::class, 'gen_info', $field, $value);
return reset($items);
}
/**
* @return Struct\GeneralInfo[]
*/
public function getAll(): array
{
return $this->getItems(Struct\GeneralInfo::class, 'gen_info');
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function enable(string $field, $value): bool
{
return $this->setProperties($field, $value, ['status' => 0]);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function disable(string $field, $value): bool
{
return $this->setProperties($field, $value, ['status' => 16]);
}
/**
* @param string $field
* @param int|string $value
* @param array $properties
*
* @return bool
*/
public function setProperties(string $field, $value, array $properties): bool
{
$packet = $this->client->getPacket();
$setTag = $packet->addChild($this->wrapperTag)->addChild('set');
$setTag->addChild('filter')->addChild($field, (string) $value);
$genInfoTag = $setTag->addChild('values')->addChild('gen_info');
foreach ($properties as $property => $propertyValue) {
$genInfoTag->addChild($property, (string) $propertyValue);
}
$response = $this->client->request($packet);
return 'ok' === (string) $response->status;
}
}

View File

@@ -1,149 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Database as Struct;
use PleskX\Api\XmlResponse;
class Database extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
return new Struct\Info($this->process('add-db', $properties));
}
public function createUser(array $properties): Struct\UserInfo
{
return new Struct\UserInfo($this->process('add-db-user', $properties));
}
private function process(string $command, array $properties): XmlResponse
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild($command);
foreach ($properties as $name => $value) {
if (false !== strpos($value, '&')) {
$info->$name = $value;
continue;
}
$info->{$name} = $value;
}
return $this->client->request($packet);
}
public function updateUser(array $properties): bool
{
$response = $this->process('set-db-user', $properties);
return 'ok' === (string) $response->status;
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\UserInfo
*/
public function getUser(string $field, $value): Struct\UserInfo
{
$items = $this->getAllUsers($field, $value);
return reset($items);
}
/**
* @param string|null $field
* @param int|string $value
*
* @return Struct\Info[]
*/
public function getAll(?string $field, $value): array
{
$response = $this->getBy('get-db', $field, $value);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if ($xmlResult) {
$items[] = new Struct\Info($xmlResult);
}
}
return $items;
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\UserInfo[]
*/
public function getAllUsers(string $field, $value): array
{
$response = $this->getBy('get-db-users', $field, $value);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if ($xmlResult) {
$items[] = new Struct\UserInfo($xmlResult);
}
}
return $items;
}
/**
* @param string $command
* @param string|null $field
* @param int|string $value
*
* @return XmlResponse
*/
private function getBy(string $command, ?string $field, $value): XmlResponse
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild($command);
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->{$field} = (string) $value;
}
return $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value, 'del-db');
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function deleteUser(string $field, $value): bool
{
return $this->deleteBy($field, $value, 'del-db-user');
}
}

View File

@@ -1,85 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\DatabaseServer as Struct;
class DatabaseServer extends \PleskX\Api\Operator
{
protected string $wrapperTag = 'db_server';
public function getSupportedTypes(): array
{
$response = $this->request('get-supported-types');
return (array) $response->type;
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getBy($field, $value);
return reset($items);
}
/**
* @return Struct\Info[]
*/
public function getAll(): array
{
return $this->getBy();
}
public function getDefault(string $type): Struct\Info
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get-default');
$filterTag = $getTag->addChild('filter');
/** @psalm-suppress UndefinedPropertyAssignment */
$filterTag->type = $type;
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param string|null $field
* @param int|string|null $value
*
* @return Struct\Info[]
*/
private function getBy($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->{$field} = (string) $value;
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
if (!is_null($xmlResult->data)) {
$item = new Struct\Info($xmlResult->data);
$item->id = (int) $xmlResult->id;
$items[] = $item;
}
}
return $items;
}
}

View File

@@ -1,132 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Dns as Struct;
class Dns extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add_rec');
foreach ($properties as $name => $value) {
$info->{$name} = $value;
}
return new Struct\Info($this->client->request($packet));
}
/**
* Send multiply records by one request.
*
* @param array $records
*
* @return \SimpleXMLElement[]
*/
public function bulkCreate(array $records): array
{
$packet = $this->client->getPacket();
foreach ($records as $properties) {
$info = $packet->addChild($this->wrapperTag)->addChild('add_rec');
foreach ($properties as $name => $value) {
$info->{$name} = $value;
}
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if ($xmlResult) {
$items[] = $xmlResult;
}
}
return $items;
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info[]
*/
public function getAll(string $field, $value): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get_rec');
$filterTag = $getTag->addChild('filter');
$filterTag->addChild($field, (string) $value);
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
if (!is_null($xmlResult->data)) {
$item = new Struct\Info($xmlResult->data);
$item->id = (int) $xmlResult->id;
$items[] = $item;
}
}
return $items;
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value, 'del_rec');
}
/**
* Delete multiply records by one request.
*
* @param array $recordIds
*
* @return \SimpleXMLElement[]
*/
public function bulkDelete(array $recordIds): array
{
$packet = $this->client->getPacket();
foreach ($recordIds as $recordId) {
$packet->addChild($this->wrapperTag)->addChild('del_rec')
->addChild('filter')->addChild('id', $recordId);
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if ($xmlResult) {
$items[] = $xmlResult;
}
}
return $items;
}
}

View File

@@ -1,93 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Dns as Struct;
class DnsTemplate extends \PleskX\Api\Operator
{
protected string $wrapperTag = 'dns';
/**
* @param array $properties
*
* @return Struct\Info
*/
public function create(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add_rec');
unset($properties['site-id'], $properties['site-alias-id']);
foreach ($properties as $name => $value) {
$info->{$name} = $value;
}
return new Struct\Info($this->client->request($packet));
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info[]
*/
public function getAll($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get_rec');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->{$field} = (string) $value;
}
$getTag->addChild('template');
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
if (!is_null($xmlResult->data)) {
$item = new Struct\Info($xmlResult->data);
$item->id = (int) $xmlResult->id;
$items[] = $item;
}
}
return $items;
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
$packet = $this->client->getPacket();
$delTag = $packet->addChild($this->wrapperTag)->addChild('del_rec');
$delTag->addChild('filter')->addChild($field, (string) $value);
$delTag->addChild('template');
$response = $this->client->request($packet);
return 'ok' === (string) $response->status;
}
}

View File

@@ -1,46 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\EventLog as Struct;
class EventLog extends \PleskX\Api\Operator
{
protected string $wrapperTag = 'event_log';
/**
* @return Struct\Event[]
*/
public function get(): array
{
$records = [];
$response = $this->request('get');
foreach ($response->event ?? [] as $eventInfo) {
$records[] = new Struct\Event($eventInfo);
}
return $records;
}
/**
* @return Struct\DetailedEvent[]
*/
public function getDetailedLog(): array
{
$records = [];
$response = $this->request('get_events');
foreach ($response->event ?? [] as $eventInfo) {
$records[] = new Struct\DetailedEvent($eventInfo);
}
return $records;
}
public function getLastId(): int
{
return (int) $this->request('get-last-id')->getValue('id');
}
}

View File

@@ -1,26 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Ip as Struct;
class Ip extends \PleskX\Api\Operator
{
/**
* @return Struct\Info[]
*/
public function get(): array
{
$ips = [];
$packet = $this->client->getPacket();
$packet->addChild($this->wrapperTag)->addChild('get');
$response = $this->client->request($packet);
foreach ($response->addresses->ip_info ?? [] as $ipInfo) {
$ips[] = new Struct\Info($ipInfo);
}
return $ips;
}
}

View File

@@ -1,35 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Locale as Struct;
class Locale extends \PleskX\Api\Operator
{
/**
* @param string|null $id
*
* @return Struct\Info|Struct\Info[]
*/
public function get($id = null)
{
$locales = [];
$packet = $this->client->getPacket();
$filter = $packet->addChild($this->wrapperTag)->addChild('get')->addChild('filter');
if (!is_null($id)) {
$filter->addChild('id', $id);
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
foreach ($response->locale->get->result ?? [] as $localeInfo) {
if (!is_null($localeInfo->info)) {
$locales[(string) $localeInfo->info->id] = new Struct\Info($localeInfo->info);
}
}
return !is_null($id) ? reset($locales) : $locales;
}
}

View File

@@ -1,8 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
class LogRotation extends \PleskX\Api\Operator
{
}

View File

@@ -1,91 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Client;
use PleskX\Api\Operator;
use PleskX\Api\Struct\Mail as Struct;
class Mail extends Operator
{
public function create(string $name, int $siteId, bool $mailbox = false, string $password = ''): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('create');
$filter = $info->addChild('filter');
$filter->addChild('site-id', (string) $siteId);
$mailname = $filter->addChild('mailname');
$mailname->addChild('name', $name);
if ($mailbox) {
$mailname->addChild('mailbox')->addChild('enabled', 'true');
}
if (!empty($password)) {
/** @psalm-suppress UndefinedPropertyAssignment */
$mailname->addChild('password')->value = $password;
}
$response = $this->client->request($packet);
/** @psalm-suppress PossiblyNullArgument */
return new Struct\Info($response->mailname);
}
/**
* @param string $field
* @param int|string $value
* @param int $siteId
*
* @return bool
*/
public function delete(string $field, $value, int $siteId): bool
{
$packet = $this->client->getPacket();
$filter = $packet->addChild($this->wrapperTag)->addChild('remove')->addChild('filter');
$filter->addChild('site-id', (string) $siteId);
$filter->{$field} = (string) $value;
$response = $this->client->request($packet);
return 'ok' === (string) $response->status;
}
public function get(string $name, int $siteId): Struct\GeneralInfo
{
$items = $this->getAll($siteId, $name);
return reset($items);
}
/**
* @param int $siteId
* @param string|null $name
*
* @return Struct\GeneralInfo[]
*/
public function getAll(int $siteId, $name = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get_info');
$filterTag = $getTag->addChild('filter');
$filterTag->addChild('site-id', (string) $siteId);
if (!is_null($name)) {
$filterTag->addChild('name', $name);
}
$response = $this->client->request($packet, Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult || !isset($xmlResult->mailname)) {
continue;
}
$item = new Struct\GeneralInfo($xmlResult->mailname);
$items[] = $item;
}
return $items;
}
}

View File

@@ -1,62 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Client;
use PleskX\Api\Operator;
use PleskX\Api\Struct\PhpHandler\Info;
class PhpHandler extends Operator
{
/**
* @param string|null $field
* @param int|string|null $value
*
* @return Info
*/
public function get($field = null, $value = null): ?Info
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->addChild($field, (string) $value);
}
$response = $this->client->request($packet, Client::RESPONSE_FULL);
$xmlResult = ($response->xpath('//result') ?: [null])[0];
return $xmlResult ? new Info($xmlResult) : null;
}
/**
* @param string|null $field
* @param int|string $value
*
* @return Info[]
*/
public function getAll($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->addChild($field, (string) $value);
}
$response = $this->client->request($packet, Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
$item = new Info($xmlResult);
$items[] = $item;
}
return $items;
}
}

View File

@@ -1,118 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Client;
use PleskX\Api\Operator;
use PleskX\Api\Struct\ProtectedDirectory as Struct;
class ProtectedDirectory extends Operator
{
protected string $wrapperTag = 'protected-dir';
public function add(string $name, int $siteId, string $header = ''): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add');
$info->addChild('site-id', (string) $siteId);
$info->addChild('name', $name);
$info->addChild('header', $header);
return new Struct\Info($this->client->request($packet));
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value, 'delete');
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\DataInfo
*/
public function get(string $field, $value): Struct\DataInfo
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\DataInfo[]
*/
public function getAll(string $field, $value): array
{
$response = $this->getBy('get', $field, $value);
$items = [];
foreach ((array) $response->xpath('//result/data') as $xmlResult) {
if (!$xmlResult) {
continue;
}
$items[] = new Struct\DataInfo($xmlResult);
}
return $items;
}
/**
* @param Struct\Info $protectedDirectory
* @param string $login
* @param string $password
*
* @return Struct\UserInfo
* @psalm-suppress UndefinedPropertyAssignment
*/
public function addUser($protectedDirectory, $login, $password)
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add-user');
$info->{'pd-id'} = (string) $protectedDirectory->id;
$info->login = $login;
$info->password = $password;
return new Struct\UserInfo($this->client->request($packet));
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function deleteUser($field, $value)
{
return $this->deleteBy($field, $value, 'delete-user');
}
/**
* @param string $command
* @param string $field
* @param int|string $value
*
* @return \PleskX\Api\XmlResponse
*/
private function getBy(string $command, string $field, $value)
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild($command);
$filterTag = $getTag->addChild('filter');
$filterTag->{$field} = (string) $value;
return $this->client->request($packet, Client::RESPONSE_FULL);
}
}

View File

@@ -1,83 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Reseller as Struct;
class Reseller extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add')->addChild('gen-info');
foreach ($properties as $name => $value) {
$info->{$name} = $value;
}
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\GeneralInfo
*/
public function get(string $field, $value): Struct\GeneralInfo
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\GeneralInfo[]
*/
public function getAll($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->addChild($field, (string) $value);
}
$datasetTag = $getTag->addChild('dataset');
$datasetTag->addChild('gen-info');
$datasetTag->addChild('permissions');
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult || !$xmlResult->data) {
continue;
}
$item = new Struct\GeneralInfo($xmlResult->data);
$item->id = (int) $xmlResult->id;
$items[] = $item;
}
return $items;
}
}

View File

@@ -1,8 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
class ResellerPlan extends \PleskX\Api\Operator
{
}

View File

@@ -1,77 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\SecretKey as Struct;
class SecretKey extends \PleskX\Api\Operator
{
protected string $wrapperTag = 'secret_key';
public function create(string $ipAddress = '', string $description = ''): string
{
$packet = $this->client->getPacket();
$createTag = $packet->addChild($this->wrapperTag)->addChild('create');
if ('' !== $ipAddress) {
$createTag->addChild('ip_address', $ipAddress);
}
if ('' !== $description) {
$createTag->addChild('description', $description);
}
$response = $this->client->request($packet);
return (string) $response->key;
}
public function delete(string $keyId): bool
{
return $this->deleteBy('key', $keyId, 'delete');
}
public function get(string $keyId): Struct\Info
{
$items = $this->getBy($keyId);
return reset($items);
}
/**
* @return Struct\Info[]
*/
public function getAll(): array
{
return $this->getBy();
}
/**
* @param string|null $keyId
*
* @return Struct\Info[]
*/
public function getBy($keyId = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get_info');
$filterTag = $getTag->addChild('filter');
if (!is_null($keyId)) {
$filterTag->addChild('key', $keyId);
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result/key_info') as $keyInfo) {
if (!$keyInfo) {
continue;
}
$items[] = new Struct\Info($keyInfo);
}
return $items;
}
}

View File

@@ -1,143 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Server as Struct;
use PleskX\Api\XmlResponse;
class Server extends \PleskX\Api\Operator
{
public function getProtos(): array
{
$packet = $this->client->getPacket();
$packet->addChild($this->wrapperTag)->addChild('get_protos');
$response = $this->client->request($packet);
/** @psalm-suppress PossiblyNullPropertyFetch */
return (array) $response->protos->proto;
}
public function getGeneralInfo(): Struct\GeneralInfo
{
return new Struct\GeneralInfo($this->getInfo('gen_info'));
}
public function getPreferences(): Struct\Preferences
{
return new Struct\Preferences($this->getInfo('prefs'));
}
public function getAdmin(): Struct\Admin
{
return new Struct\Admin($this->getInfo('admin'));
}
public function getKeyInfo(): array
{
$keyInfo = [];
$keyInfoXml = $this->getInfo('key');
foreach ($keyInfoXml->property ?? [] as $property) {
$keyInfo[(string) $property->name] = (string) $property->value;
}
return $keyInfo;
}
public function getComponents(): array
{
$components = [];
$componentsXml = $this->getInfo('components');
foreach ($componentsXml->component ?? [] as $component) {
$components[(string) $component->name] = (string) $component->version;
}
return $components;
}
public function getServiceStates(): array
{
$states = [];
$statesXml = $this->getInfo('services_state');
foreach ($statesXml->srv ?? [] as $service) {
$states[(string) $service->id] = [
'id' => (string) $service->id,
'title' => (string) $service->title,
'state' => (string) $service->state,
];
}
return $states;
}
public function getSessionPreferences(): Struct\SessionPreferences
{
return new Struct\SessionPreferences($this->getInfo('session_setup'));
}
public function getShells(): array
{
$shells = [];
$shellsXml = $this->getInfo('shells');
foreach ($shellsXml->shell ?? [] as $shell) {
$shells[(string) $shell->name] = (string) $shell->path;
}
return $shells;
}
public function getNetworkInterfaces(): array
{
$interfacesXml = $this->getInfo('interfaces');
return (array) $interfacesXml->interface;
}
public function getStatistics(): Struct\Statistics
{
return new Struct\Statistics($this->getInfo('stat'));
}
public function getSiteIsolationConfig(): array
{
$config = [];
$configXml = $this->getInfo('site-isolation-config');
foreach ($configXml->property ?? [] as $property) {
$config[(string) $property->name] = (string) $property->value;
}
return $config;
}
public function getUpdatesInfo(): Struct\UpdatesInfo
{
return new Struct\UpdatesInfo($this->getInfo('updates'));
}
public function createSession(string $login, string $clientIp): string
{
$packet = $this->client->getPacket();
$sessionNode = $packet->addChild($this->wrapperTag)->addChild('create_session');
$sessionNode->addChild('login', $login);
$dataNode = $sessionNode->addChild('data');
$dataNode->addChild('user_ip', base64_encode($clientIp));
$dataNode->addChild('source_server');
$response = $this->client->request($packet);
return (string) $response->id;
}
private function getInfo(string $operation): XmlResponse
{
$packet = $this->client->getPacket();
$packet->addChild($this->wrapperTag)->addChild('get')->addChild($operation);
$response = $this->client->request($packet);
return $response->$operation;
}
}

View File

@@ -1,77 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\ServicePlan as Struct;
class ServicePlan extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
$response = $this->request(['add' => $properties]);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getBy($field, $value);
return reset($items);
}
/**
* @return Struct\Info[]
*/
public function getAll(): array
{
return $this->getBy();
}
/**
* @param string|null $field
* @param int|string|null $value
*
* @return Struct\Info[]
*/
private function getBy($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->addChild($field, (string) $value);
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
$items[] = new Struct\Info($xmlResult);
}
return $items;
}
}

View File

@@ -1,77 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\ServicePlanAddon as Struct;
class ServicePlanAddon extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
$response = $this->request(['add' => $properties]);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getBy($field, $value);
return reset($items);
}
/**
* @return Struct\Info[]
*/
public function getAll(): array
{
return $this->getBy();
}
/**
* @param string|null $field
* @param int|string|null $value
*
* @return Struct\Info[]
*/
private function getBy($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->addChild($field, (string) $value);
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
$items[] = new Struct\Info($xmlResult);
}
return $items;
}
}

View File

@@ -1,47 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Session as Struct;
class Session extends \PleskX\Api\Operator
{
public function create(string $username, string $userIp): string
{
$packet = $this->client->getPacket();
$creator = $packet->addChild('server')->addChild('create_session');
$creator->addChild('login', $username);
$loginData = $creator->addChild('data');
$loginData->addChild('user_ip', base64_encode($userIp));
$loginData->addChild('source_server', '');
$response = $this->client->request($packet);
return (string) $response->id;
}
/**
* @return Struct\Info[]
*/
public function get(): array
{
$sessions = [];
$response = $this->request('get');
foreach ($response->session ?? [] as $sessionInfo) {
$sessions[(string) $sessionInfo->id] = new Struct\Info($sessionInfo);
}
return $sessions;
}
public function terminate(string $sessionId): bool
{
$response = $this->request("terminate.session-id=$sessionId");
return 'ok' === (string) $response->status;
}
}

View File

@@ -1,94 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Site as Struct;
class Site extends \PleskX\Api\Operator
{
public const PROPERTIES_HOSTING = 'hosting';
public function create(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add');
$infoGeneral = $info->addChild('gen_setup');
foreach ($properties as $name => $value) {
if (!is_scalar($value)) {
continue;
}
$infoGeneral->{$name} = (string) $value;
}
// set hosting properties
if (isset($properties[static::PROPERTIES_HOSTING]) && is_array($properties[static::PROPERTIES_HOSTING])) {
$hostingNode = $info->addChild('hosting')->addChild('vrt_hst');
foreach ($properties[static::PROPERTIES_HOSTING] as $name => $value) {
$propertyNode = $hostingNode->addChild('property');
/** @psalm-suppress UndefinedPropertyAssignment */
$propertyNode->name = $name;
/** @psalm-suppress UndefinedPropertyAssignment */
$propertyNode->value = $value;
}
}
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return ?Struct\GeneralInfo
*/
public function get(string $field, $value): ?Struct\GeneralInfo
{
$items = $this->getItems(Struct\GeneralInfo::class, 'gen_info', $field, $value);
return reset($items) ?: null;
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\HostingInfo|null
*/
public function getHosting(string $field, $value): ?Struct\HostingInfo
{
$items = $this->getItems(
Struct\HostingInfo::class,
'hosting',
$field,
$value,
function (\SimpleXMLElement $node) {
return isset($node->vrt_hst);
}
);
return empty($items) ? null : reset($items);
}
/**
* @return Struct\GeneralInfo[]
*/
public function getAll(): array
{
return $this->getItems(Struct\GeneralInfo::class, 'gen_info');
}
}

View File

@@ -1,85 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\SiteAlias as Struct;
class SiteAlias extends \PleskX\Api\Operator
{
public function create(array $properties, array $preferences = []): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('create');
if (count($preferences) > 0) {
$prefs = $info->addChild('pref');
foreach ($preferences as $key => $value) {
$prefs->addChild($key, is_bool($value) ? ($value ? '1' : '0') : $value);
}
}
$info->addChild('site-id', $properties['site-id']);
$info->addChild('name', $properties['name']);
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value, 'delete');
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\GeneralInfo
*/
public function get(string $field, $value): Struct\GeneralInfo
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\GeneralInfo[]
*/
public function getAll($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->{$field} = (string) $value;
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult) {
continue;
}
if (!is_null($xmlResult->info)) {
$item = new Struct\GeneralInfo($xmlResult->info);
$items[] = $item;
}
}
return $items;
}
}

View File

@@ -1,88 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Subdomain as Struct;
class Subdomain extends \PleskX\Api\Operator
{
public function create(array $properties): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add');
foreach ($properties as $name => $value) {
if (is_array($value)) {
foreach ($value as $propertyName => $propertyValue) {
$property = $info->addChild($name);
/** @psalm-suppress UndefinedPropertyAssignment */
$property->name = $propertyName;
/** @psalm-suppress UndefinedPropertyAssignment */
$property->value = $propertyValue;
}
continue;
}
$info->{$name} = $value;
}
$response = $this->client->request($packet);
return new Struct\Info($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info
*/
public function get(string $field, $value): Struct\Info
{
$items = $this->getAll($field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Info[]
*/
public function getAll($field = null, $value = null): array
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$filterTag = $getTag->addChild('filter');
if (!is_null($field)) {
$filterTag->addChild($field, (string) $value);
}
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
$items = [];
foreach ((array) $response->xpath('//result') as $xmlResult) {
if (!$xmlResult || empty($xmlResult->data)) {
continue;
}
$item = new Struct\Info($xmlResult->data);
$item->id = (int) $xmlResult->id;
$items[] = $item;
}
return $items;
}
}

View File

@@ -1,45 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Struct\Ui as Struct;
class Ui extends \PleskX\Api\Operator
{
public function getNavigation(): array
{
$response = $this->request('get-navigation');
/** @psalm-suppress ImplicitToStringCast, PossiblyNullArgument */
return unserialize(base64_decode($response->navigation));
}
public function createCustomButton(string $owner, array $properties): int
{
$packet = $this->client->getPacket();
$buttonNode = $packet->addChild($this->wrapperTag)->addChild('create-custombutton');
$buttonNode->addChild('owner')->addChild($owner);
$propertiesNode = $buttonNode->addChild('properties');
foreach ($properties as $name => $value) {
$propertiesNode->{$name} = $value;
}
$response = $this->client->request($packet);
return (int) $response->id;
}
public function getCustomButton(int $id): Struct\CustomButton
{
$response = $this->request("get-custombutton.filter.custombutton-id=$id");
return new Struct\CustomButton($response);
}
public function deleteCustomButton(int $id): bool
{
return $this->deleteBy('custombutton-id', $id, 'delete-custombutton');
}
}

View File

@@ -1,9 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
class VirtualDirectory extends \PleskX\Api\Operator
{
protected string $wrapperTag = 'virtdir';
}

View File

@@ -1,199 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Operator;
use PleskX\Api\Operator;
use PleskX\Api\Struct\Webspace as Struct;
class Webspace extends Operator
{
public function getPermissionDescriptor(): Struct\PermissionDescriptor
{
$response = $this->request('get-permission-descriptor.filter');
return new Struct\PermissionDescriptor($response);
}
public function getLimitDescriptor(): Struct\LimitDescriptor
{
$response = $this->request('get-limit-descriptor.filter');
return new Struct\LimitDescriptor($response);
}
public function getPhysicalHostingDescriptor(): Struct\PhysicalHostingDescriptor
{
$response = $this->request('get-physical-hosting-descriptor.filter');
return new Struct\PhysicalHostingDescriptor($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\PhpSettings
*/
public function getPhpSettings(string $field, $value): Struct\PhpSettings
{
$packet = $this->client->getPacket();
$getTag = $packet->addChild($this->wrapperTag)->addChild('get');
$getTag->addChild('filter')->addChild($field, (string) $value);
$getTag->addChild('dataset')->addChild('php-settings');
$response = $this->client->request($packet, \PleskX\Api\Client::RESPONSE_FULL);
return new Struct\PhpSettings($response);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\Limits
*/
public function getLimits(string $field, $value): Struct\Limits
{
$items = $this->getItems(Struct\Limits::class, 'limits', $field, $value);
return reset($items);
}
/**
* @param array $properties
* @param array|null $hostingProperties
* @param string $planName
*
* @return Struct\Info
*/
public function create(array $properties, ?array $hostingProperties = null, string $planName = ''): Struct\Info
{
$packet = $this->client->getPacket();
$info = $packet->addChild($this->wrapperTag)->addChild('add');
$infoGeneral = $info->addChild('gen_setup');
foreach ($properties as $name => $value) {
if (is_array($value)) {
continue;
} else {
$infoGeneral->addChild($name, (string) $value);
}
}
if ($hostingProperties) {
$infoHosting = $info->addChild('hosting')->addChild('vrt_hst');
foreach ($hostingProperties as $name => $value) {
$property = $infoHosting->addChild('property');
/** @psalm-suppress UndefinedPropertyAssignment */
$property->name = $name;
/** @psalm-suppress UndefinedPropertyAssignment */
$property->value = $value;
}
if (isset($properties['ip_address'])) {
foreach ((array) $properties['ip_address'] as $ipAddress) {
$infoHosting->addChild('ip_address', $ipAddress);
}
}
}
if ('' !== $planName) {
$info->addChild('plan-name', $planName);
}
$response = $this->client->request($packet);
return new Struct\Info($response, $properties['name'] ?? '');
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function delete(string $field, $value): bool
{
return $this->deleteBy($field, $value);
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\GeneralInfo
*/
public function get(string $field, $value): Struct\GeneralInfo
{
$items = $this->getItems(Struct\GeneralInfo::class, 'gen_info', $field, $value);
return reset($items);
}
/**
* @return Struct\GeneralInfo[]
*/
public function getAll(): array
{
return $this->getItems(Struct\GeneralInfo::class, 'gen_info');
}
/**
* @param string $field
* @param int|string $value
*
* @return Struct\DiskUsage
*/
public function getDiskUsage(string $field, $value): Struct\DiskUsage
{
$items = $this->getItems(Struct\DiskUsage::class, 'disk_usage', $field, $value);
return reset($items);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function enable(string $field, $value): bool
{
return $this->setProperties($field, $value, ['status' => 0]);
}
/**
* @param string $field
* @param int|string $value
*
* @return bool
*/
public function disable(string $field, $value): bool
{
return $this->setProperties($field, $value, ['status' => 16]);
}
/**
* @param string $field
* @param int|string $value
* @param array $properties
*
* @return bool
*/
public function setProperties(string $field, $value, array $properties): bool
{
$packet = $this->client->getPacket();
$setTag = $packet->addChild($this->wrapperTag)->addChild('set');
$setTag->addChild('filter')->addChild($field, (string) $value);
$genInfoTag = $setTag->addChild('values')->addChild('gen_setup');
foreach ($properties as $property => $propertyValue) {
$genInfoTag->addChild($property, (string) $propertyValue);
}
$response = $this->client->request($packet);
return 'ok' === (string) $response->status;
}
}

View File

@@ -1,38 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Certificate;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public ?string $request = null;
public ?string $privateKey = null;
public ?string $publicKey = null;
public ?string $publicKeyCA = null;
public function __construct($input)
{
if ($input instanceof \SimpleXMLElement) {
$this->initScalarProperties($input, [
['csr' => 'request'],
['pvt' => 'privateKey'],
]);
} else {
foreach ($input as $name => $value) {
$this->$name = $value;
}
}
}
public function getMapping(): array
{
return array_filter([
'csr' => $this->request,
'pvt' => $this->privateKey,
'cert' => $this->publicKey,
'ca' => $this->publicKeyCA,
]);
}
}

View File

@@ -1,48 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Customer;
use PleskX\Api\AbstractStruct;
class GeneralInfo extends AbstractStruct
{
public int $id;
public string $company;
public string $personalName;
public string $login;
public string $guid;
public string $email;
public string $phone;
public string $fax;
public string $address;
public string $postalCode;
public string $city;
public string $state;
public string $country;
public string $description;
public string $externalId;
public bool $enabled;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
['cname' => 'company'],
['pname' => 'personalName'],
'login',
'guid',
'email',
'phone',
'fax',
'address',
['pcode' => 'postalCode'],
'city',
'state',
'country',
'external-id',
'description',
]);
$this->enabled = '0' === (string) $apiResponse->status;
}
}

View File

@@ -1,20 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Customer;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $guid;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'guid',
]);
}
}

View File

@@ -1,28 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Database;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $name;
public string $type;
public int $webspaceId;
public int $dbServerId;
public int $defaultUserId;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'name',
'type',
'webspace-id',
'db-server-id',
'default-user-id',
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Database;
use PleskX\Api\AbstractStruct;
class UserInfo extends AbstractStruct
{
public int $id;
public string $login;
public int $dbId;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'login',
'db-id',
]);
}
}

View File

@@ -1,24 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\DatabaseServer;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $host;
public int $port;
public string $type;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'host',
'port',
'type',
]);
}
}

View File

@@ -1,30 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Dns;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public int $siteId;
public int $siteAliasId;
public string $type;
public string $host;
public string $value;
public string $opt;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'site-id',
'site-alias-id',
'type',
'host',
'value',
'opt',
]);
}
}

View File

@@ -1,30 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\EventLog;
use PleskX\Api\AbstractStruct;
class DetailedEvent extends AbstractStruct
{
public int $id;
public string $type;
public int $time;
public string $class;
public string $objectId;
public string $user;
public string $host;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'type',
'time',
'class',
['obj_id' => 'objectId'],
'user',
'host',
]);
}
}

View File

@@ -1,24 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\EventLog;
use PleskX\Api\AbstractStruct;
class Event extends AbstractStruct
{
public string $type;
public int $time;
public string $class;
public string $id;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'type',
'time',
'class',
'id',
]);
}
}

View File

@@ -1,24 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Ip;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public string $ipAddress;
public string $netmask;
public string $type;
public string $interface;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'ip_address',
'netmask',
'type',
'interface',
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Locale;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public string $id;
public string $language;
public string $country;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
['lang' => 'language'],
'country',
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Mail;
use PleskX\Api\AbstractStruct;
class GeneralInfo extends AbstractStruct
{
public int $id;
public string $name;
public string $description;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'name',
'description',
]);
}
}

View File

@@ -1,20 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Mail;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $name;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'name',
]);
}
}

View File

@@ -1,36 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\PhpHandler;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public string $id;
public string $displayName;
public string $fullVersion;
public string $version;
public string $type;
public string $path;
public string $clipath;
public string $phpini;
public string $custom;
public string $handlerStatus;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'display-name',
'full-version',
'version',
'type',
'path',
'clipath',
'phpini',
'custom',
'handler-status',
]);
}
}

View File

@@ -1,20 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\ProtectedDirectory;
use PleskX\Api\AbstractStruct;
class DataInfo extends AbstractStruct
{
public string $name;
public string $header;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'name',
'header',
]);
}
}

View File

@@ -1,18 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\ProtectedDirectory;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
]);
}
}

View File

@@ -1,18 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\ProtectedDirectory;
use PleskX\Api\AbstractStruct;
class UserInfo extends AbstractStruct
{
public int $id;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
]);
}
}

View File

@@ -1,29 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Reseller;
use PleskX\Api\AbstractStruct;
class GeneralInfo extends AbstractStruct
{
public int $id;
public string $personalName;
public string $login;
public array $permissions;
public function __construct(\SimpleXMLElement $apiResponse)
{
if (!is_null($apiResponse->{'gen-info'})) {
$this->initScalarProperties($apiResponse->{'gen-info'}, [
['pname' => 'personalName'],
'login',
]);
}
$this->permissions = [];
foreach ($apiResponse->permissions->permission ?? [] as $permissionInfo) {
$this->permissions[(string) $permissionInfo->name] = (string) $permissionInfo->value;
}
}
}

View File

@@ -1,20 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Reseller;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $guid;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'guid',
]);
}
}

View File

@@ -1,24 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\SecretKey;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public string $key;
public string $ipAddress;
public string $description;
public string $login;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'key',
'ip_address',
'description',
'login',
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server;
use PleskX\Api\AbstractStruct;
class Admin extends AbstractStruct
{
public string $companyName;
public string $name;
public string $email;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
['admin_cname' => 'companyName'],
['admin_pname' => 'name'],
['admin_email' => 'email'],
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server;
use PleskX\Api\AbstractStruct;
class GeneralInfo extends AbstractStruct
{
public string $serverName;
public string $serverGuid;
public string $mode;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'server_name',
'server_guid',
'mode',
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server;
use PleskX\Api\AbstractStruct;
class Preferences extends AbstractStruct
{
public int $statTtl;
public int $trafficAccounting;
public int $restartApacheInterval;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'stat_ttl',
'traffic_accounting',
'restart_apache_interval',
]);
}
}

View File

@@ -1,18 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server;
use PleskX\Api\AbstractStruct;
class SessionPreferences extends AbstractStruct
{
public int $loginTimeout;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'login_timeout',
]);
}
}

View File

@@ -1,49 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server;
use PleskX\Api\AbstractStruct;
class Statistics extends AbstractStruct
{
/** @var Statistics\Objects */
public $objects;
/** @var Statistics\Version */
public $version;
/** @var Statistics\Other */
public $other;
/** @var Statistics\LoadAverage */
public $loadAverage;
/** @var Statistics\Memory */
public $memory;
/** @var Statistics\Swap */
public $swap;
/** @var Statistics\DiskSpace[] */
public $diskSpace;
/**
* @param \SimpleXMLElement $apiResponse
* @psalm-suppress PossiblyNullArgument
*/
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->objects = new Statistics\Objects($apiResponse->objects);
$this->version = new Statistics\Version($apiResponse->version);
$this->other = new Statistics\Other($apiResponse->other);
$this->loadAverage = new Statistics\LoadAverage($apiResponse->load_avg);
$this->memory = new Statistics\Memory($apiResponse->mem);
$this->swap = new Statistics\Swap($apiResponse->swap);
$this->diskSpace = [];
foreach ($apiResponse->diskspace ?? [] as $disk) {
$this->diskSpace[(string) $disk->device->name] = new Statistics\DiskSpace($disk->device);
}
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class DiskSpace extends AbstractStruct
{
public int $total;
public int $used;
public int $free;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'total',
'used',
'free',
]);
}
}

View File

@@ -1,20 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class LoadAverage extends AbstractStruct
{
public float $load1min;
public float $load5min;
public float $load15min;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->load1min = (float) $apiResponse->l1 / 100.0;
$this->load5min = (float) $apiResponse->l5 / 100.0;
$this->load15min = (float) $apiResponse->l15 / 100.0;
}
}

View File

@@ -1,28 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class Memory extends AbstractStruct
{
public int $total;
public int $used;
public int $free;
public int $shared;
public int $buffer;
public int $cached;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'total',
'used',
'free',
'shared',
'buffer',
'cached',
]);
}
}

View File

@@ -1,38 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class Objects extends AbstractStruct
{
public int $clients;
public int $domains;
public int $databases;
public int $activeDomains;
public int $mailBoxes;
public int $mailRedirects;
public int $mailGroups;
public int $mailResponders;
public int $databaseUsers;
public int $problemClients;
public int $problemDomains;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'clients',
'domains',
'databases',
['active_domains' => 'activeDomains'],
['mail_boxes' => 'mailBoxes'],
['mail_redirects' => 'mailRedirects'],
['mail_groups' => 'mailGroups'],
['mail_responders' => 'mailResponders'],
['database_users' => 'databaseUsers'],
['problem_clients' => 'problemClients'],
['problem_domains' => 'problemDomains'],
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class Other extends AbstractStruct
{
public string $cpu;
public int $uptime;
public bool $insideVz;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'cpu',
'uptime',
['inside_vz' => 'insideVz'],
]);
}
}

View File

@@ -1,22 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class Swap extends AbstractStruct
{
public int $total;
public int $used;
public int $free;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'total',
'used',
'free',
]);
}
}

View File

@@ -1,28 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server\Statistics;
use PleskX\Api\AbstractStruct;
class Version extends AbstractStruct
{
public string $internalName;
public string $version;
public string $build;
public string $osName;
public string $osVersion;
public string $osRelease;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
['plesk_name' => 'internalName'],
['plesk_version' => 'version'],
['plesk_build' => 'build'],
['plesk_os' => 'osName'],
['plesk_os_version' => 'osVersion'],
['os_release' => 'osRelease'],
]);
}
}

View File

@@ -1,20 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\Server;
use PleskX\Api\AbstractStruct;
class UpdatesInfo extends AbstractStruct
{
public string $lastInstalledUpdate;
public bool $installUpdatesAutomatically;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'last_installed_update',
'install_updates_automatically',
]);
}
}

View File

@@ -1,24 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\ServicePlan;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $name;
public string $guid;
public string $externalId;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'name',
'guid',
'external-id',
]);
}
}

View File

@@ -1,24 +0,0 @@
<?php
// Copyright 1999-2025. WebPros International GmbH.
namespace PleskX\Api\Struct\ServicePlanAddon;
use PleskX\Api\AbstractStruct;
class Info extends AbstractStruct
{
public int $id;
public string $name;
public string $guid;
public string $externalId;
public function __construct(\SimpleXMLElement $apiResponse)
{
$this->initScalarProperties($apiResponse, [
'id',
'name',
'guid',
'external-id',
]);
}
}

Some files were not shown because too many files have changed in this diff Show More