2022-03-02 15:40:53 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class RetailcrmClasspathBuilder.
|
|
|
|
* Builds classpath for Bitrix autoloader. Contains some hardcoded things, which will go away when everything refactored.
|
|
|
|
*/
|
|
|
|
class RetailcrmClasspathBuilder
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* File extension as a string. Defaults to ".php".
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $fileExt = 'php';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string $moduleId
|
|
|
|
*/
|
|
|
|
protected $moduleId = 'intaro.retailcrm';
|
|
|
|
|
2022-04-08 18:21:05 +03:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $customizedFilesPath = '/bitrix/php_interface/retailcrm/';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $customizedClassesPath = '../../php_interface/retailcrm/';
|
|
|
|
|
2022-03-02 15:40:53 +03:00
|
|
|
/**
|
|
|
|
* The topmost directory where recursion should begin. Default: `classes/general`. Relative to the __DIR__.
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $path = 'classes/general';
|
|
|
|
|
2022-06-14 14:08:43 +03:00
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $bitrixModulesPath = 'bitrix/modules';
|
|
|
|
|
2022-03-02 15:40:53 +03:00
|
|
|
/**
|
|
|
|
* Do not include directory paths as namespaces.
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
protected $disableNamespaces;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bitrix document root
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $documentRoot;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $version;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array $result
|
|
|
|
*/
|
|
|
|
protected $result = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array $notIncluded
|
|
|
|
*/
|
|
|
|
protected $notIncluded = [];
|
|
|
|
|
2023-07-24 09:10:28 +03:00
|
|
|
protected $directories = [];
|
|
|
|
|
2022-03-02 15:40:53 +03:00
|
|
|
/**
|
|
|
|
* These classes can be customized, in which case they would be replaced with files from
|
|
|
|
* directory <root>/bitrix/php_interface/retailcrm
|
|
|
|
*
|
|
|
|
* Array format:
|
|
|
|
* [
|
|
|
|
* 'class path with namespace' => 'file name'
|
|
|
|
* ]
|
|
|
|
*/
|
|
|
|
protected static $customizableClasses = [
|
2023-07-24 09:10:28 +03:00
|
|
|
'classes' => [
|
|
|
|
'RestNormalizer' => 'RestNormalizer.php',
|
|
|
|
'Logger' => 'Logger.php',
|
|
|
|
'RetailCrm\ApiClient' => 'ApiClient_v5.php',
|
|
|
|
'RetailCrm\Http\Client' => 'Client.php',
|
|
|
|
'RCrmActions' => 'RCrmActions.php',
|
|
|
|
'RetailCrmUser' => 'RetailCrmUser.php',
|
|
|
|
'RetailCrmICML' => 'RetailCrmICML.php',
|
|
|
|
'RetailCrmInventories' => 'RetailCrmInventories.php',
|
|
|
|
'RetailCrmPrices' => 'RetailCrmPrices.php',
|
|
|
|
'RetailCrmCollector' => 'RetailCrmCollector.php',
|
|
|
|
'RetailCrmUa' => 'RetailCrmUa.php',
|
|
|
|
'RetailCrmEvent' => 'RetailCrmEvent.php',
|
|
|
|
'RetailCrmCorporateClient' => 'RetailCrmCorporateClient.php'
|
|
|
|
],
|
|
|
|
'lib/icml' => [
|
|
|
|
'Intaro\RetailCrm\Icml\XmlOfferBuilder' => 'xmlofferbuilder.php',
|
|
|
|
'Intaro\RetailCrm\Icml\XmlOfferDirector' => 'xmlofferdirector.php',
|
|
|
|
'Intaro\RetailCrm\Icml\IcmlWriter' => 'icmlwriter.php',
|
|
|
|
'Intaro\RetailCrm\Icml\QueryParamsMolder' => 'queryparamsmolder.php',
|
|
|
|
'Intaro\RetailCrm\Icml\SettingsService' => 'settingsservice.php',
|
|
|
|
'Intaro\RetailCrm\Icml\XmlCategoryDirector' => 'xmlcategorydirector.php',
|
|
|
|
'Intaro\RetailCrm\Icml\XmlCategoryFactory' => 'xmlcategoryfactory.php',
|
|
|
|
'Intaro\RetailCrm\Icml\IcmlDirector' => 'icmldirector.php'
|
|
|
|
]
|
2022-03-02 15:40:53 +03:00
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* These classes can be customized, in which case they would be replaced with files from
|
|
|
|
* directory <root>/bitrix/php_interface/retailcrm
|
|
|
|
* Customized versions have fixed name, and original versions name depends on API version
|
|
|
|
*
|
|
|
|
* Array format:
|
|
|
|
* [
|
|
|
|
* 'class path with namespace' => ['customized file name', 'original file name with %s for API version']
|
|
|
|
* ]
|
|
|
|
*/
|
|
|
|
protected static $versionedClasses = [
|
2023-07-24 09:10:28 +03:00
|
|
|
'classes' => [
|
|
|
|
'RetailCrm\ApiClient' => ['ApiClient.php', 'ApiClient_%s.php'],
|
|
|
|
'RetailCrmOrder' => ['RetailCrmOrder.php', 'RetailCrmOrder_%s.php'],
|
|
|
|
'RetailCrmHistory' => ['RetailCrmHistory.php', 'RetailCrmHistory_%s.php'],
|
|
|
|
'RetailCrmCart' => ['RetailCrmCart.php', 'RetailCrmCart_%s.php']
|
|
|
|
],
|
|
|
|
'lib/icml' => []
|
2022-03-02 15:40:53 +03:00
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* These classes will be ignored while loading from original files
|
|
|
|
*/
|
|
|
|
protected static $ignoredClasses = [
|
2023-07-24 09:10:28 +03:00
|
|
|
'classes' => [
|
|
|
|
'ApiClient_v4.php',
|
|
|
|
'ApiClient_v5.php',
|
|
|
|
'RetailCrmOrder_v4.php',
|
|
|
|
'RetailCrmOrder_v5.php',
|
|
|
|
'RetailCrmHistory_v4.php',
|
|
|
|
'RetailCrmHistory_v5.php',
|
|
|
|
'RetailCrmCart_v5.php',
|
|
|
|
],
|
|
|
|
'lib/icml' => []
|
2022-03-02 15:40:53 +03:00
|
|
|
];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* These namespaces are hardcoded.
|
|
|
|
*/
|
|
|
|
protected static $hardcodedNamespaces = [
|
2023-07-24 09:10:28 +03:00
|
|
|
'classes' => [
|
|
|
|
'RetailCrm\Response\ApiResponse' => 'ApiResponse.php',
|
|
|
|
'RetailCrm\Exception\InvalidJsonException' => 'InvalidJsonException.php',
|
|
|
|
'RetailCrm\Exception\CurlException' => 'CurlException.php'
|
|
|
|
],
|
|
|
|
'lib/icml' => []
|
2022-03-02 15:40:53 +03:00
|
|
|
];
|
|
|
|
|
|
|
|
protected function buildCustomizableClasspath()
|
|
|
|
{
|
2023-07-24 09:10:28 +03:00
|
|
|
foreach (static::$customizableClasses[$this->path] as $className => $fileName) {
|
2022-04-08 18:21:05 +03:00
|
|
|
if (file_exists($this->documentRoot . $this->customizedFilesPath . $fileName)) {
|
|
|
|
$this->result[$className] = $this->customizedClassesPath . $fileName;
|
2022-03-02 15:40:53 +03:00
|
|
|
} else {
|
|
|
|
$this->notIncluded[$className] = $fileName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function buildVersionedClasspath()
|
|
|
|
{
|
2023-07-24 09:10:28 +03:00
|
|
|
foreach (static::$versionedClasses[$this->path] as $className => $fileNames) {
|
2022-04-08 18:21:05 +03:00
|
|
|
if (file_exists($this->documentRoot . $this->customizedFilesPath . $fileNames[0])) {
|
|
|
|
$this->result[$className] = $this->customizedClassesPath . $fileNames[0];
|
2022-03-02 15:40:53 +03:00
|
|
|
} else {
|
|
|
|
$this->notIncluded[$className] = sprintf($fileNames[1], $this->version);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Traverse through directories, build include paths
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function build(): self
|
|
|
|
{
|
2023-07-24 09:10:28 +03:00
|
|
|
foreach ($this->directories as $path) {
|
|
|
|
$this->path = $path;
|
|
|
|
|
|
|
|
$directory = new RecursiveDirectoryIterator(
|
|
|
|
$this->getSearchPath(),
|
|
|
|
RecursiveDirectoryIterator::SKIP_DOTS
|
|
|
|
);
|
|
|
|
|
|
|
|
$fileIterator = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::LEAVES_ONLY);
|
|
|
|
|
|
|
|
$this->buildCustomizableClasspath();
|
|
|
|
$this->buildVersionedClasspath();
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2023-07-24 09:10:28 +03:00
|
|
|
$notIncludedClasses = array_flip($this->notIncluded);
|
|
|
|
$hardcodedNamespaces = array_flip(static::$hardcodedNamespaces[$path]);
|
|
|
|
|
|
|
|
/** @var \SplFileObject $file */
|
|
|
|
foreach ($fileIterator as $file) {
|
|
|
|
$fileNameWithoutExt = str_ireplace('.' . $this->fileExt, '', $file->getFilename());
|
|
|
|
|
|
|
|
if ($file->getExtension() !== $this->fileExt) {
|
|
|
|
continue;
|
2022-03-02 15:40:53 +03:00
|
|
|
}
|
|
|
|
|
2023-07-24 09:10:28 +03:00
|
|
|
if (in_array($file->getFilename(), static::$customizableClasses[$path])
|
|
|
|
|| in_array($file->getFilename(), static::$ignoredClasses[$path])
|
|
|
|
) {
|
|
|
|
if (in_array($file->getFilename(), $this->notIncluded)) {
|
|
|
|
$this->result[$notIncludedClasses[$file->getFilename()]] = $this->getImportPath($file->getPathname());
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
|
2023-07-24 09:10:28 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in_array($file->getFilename(), static::$hardcodedNamespaces[$path])) {
|
|
|
|
$this->result[$hardcodedNamespaces[$file->getFilename()]] = $this->getImportPath($file->getPathname());
|
|
|
|
} else {
|
|
|
|
$this->result[$this->getImportClass($fileNameWithoutExt, $file->getPath())] = $this->getImportPath($file->getPathname());
|
|
|
|
}
|
2022-03-02 15:40:53 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the $fileExt property
|
|
|
|
*
|
|
|
|
* @param string $fileExt The file extension used for class files. Default is "php".
|
|
|
|
*
|
|
|
|
* @return \RetailcrmClasspathBuilder
|
|
|
|
*/
|
|
|
|
public function setFileExt($fileExt)
|
|
|
|
{
|
|
|
|
$this->fileExt = $fileExt;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $documentRoot
|
|
|
|
*
|
|
|
|
* @return RetailcrmClasspathBuilder
|
|
|
|
*/
|
|
|
|
public function setDocumentRoot(string $documentRoot): RetailcrmClasspathBuilder
|
|
|
|
{
|
|
|
|
$this->documentRoot = $documentRoot;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the $path property
|
|
|
|
*
|
2023-07-24 09:10:28 +03:00
|
|
|
* @param array $path Top path to load files
|
2022-03-02 15:40:53 +03:00
|
|
|
*
|
|
|
|
* @return \RetailcrmClasspathBuilder
|
|
|
|
*/
|
2023-07-24 09:10:28 +03:00
|
|
|
public function setPath(array $path)
|
2022-03-02 15:40:53 +03:00
|
|
|
{
|
|
|
|
$this->path = $path;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2023-07-24 09:10:28 +03:00
|
|
|
/**
|
|
|
|
* @param array $directories
|
|
|
|
* @return \RetailcrmClasspathBuilder
|
|
|
|
*/
|
|
|
|
public function setDirectories(array $directories)
|
|
|
|
{
|
|
|
|
$this->directories = $directories;
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2022-03-02 15:40:53 +03:00
|
|
|
/**
|
|
|
|
* @param mixed $disableNamespaces
|
|
|
|
*
|
|
|
|
* @return RetailcrmClasspathBuilder
|
|
|
|
*/
|
|
|
|
public function setDisableNamespaces($disableNamespaces)
|
|
|
|
{
|
|
|
|
$this->disableNamespaces = $disableNamespaces;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $moduleId
|
|
|
|
*
|
|
|
|
* @return RetailcrmClasspathBuilder
|
|
|
|
*/
|
|
|
|
public function setModuleId(string $moduleId): RetailcrmClasspathBuilder
|
|
|
|
{
|
|
|
|
$this->moduleId = $moduleId;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $version
|
|
|
|
*
|
|
|
|
* @return RetailcrmClasspathBuilder
|
|
|
|
*/
|
|
|
|
public function setVersion(string $version): RetailcrmClasspathBuilder
|
|
|
|
{
|
|
|
|
$this->version = $version;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getResult(): array
|
|
|
|
{
|
|
|
|
return $this->result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function getSearchPath(): string
|
|
|
|
{
|
2022-06-14 14:08:43 +03:00
|
|
|
return $this->documentRoot . DIRECTORY_SEPARATOR . $this->bitrixModulesPath . DIRECTORY_SEPARATOR
|
|
|
|
. $this->moduleId. DIRECTORY_SEPARATOR . $this->path;
|
2022-03-02 15:40:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $filePath
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function getImportPath(string $filePath): string
|
|
|
|
{
|
|
|
|
return (string) str_ireplace(implode(DIRECTORY_SEPARATOR, [
|
|
|
|
$this->documentRoot,
|
2022-06-14 14:08:43 +03:00
|
|
|
$this->bitrixModulesPath,
|
2022-03-02 15:40:53 +03:00
|
|
|
$this->moduleId
|
|
|
|
]) . DIRECTORY_SEPARATOR, '', $filePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $fileNameWithoutExt
|
|
|
|
* @param string $filePath
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function getImportClass(string $fileNameWithoutExt, string $filePath): string
|
|
|
|
{
|
|
|
|
if ($this->disableNamespaces) {
|
|
|
|
return $fileNameWithoutExt;
|
|
|
|
}
|
|
|
|
|
|
|
|
$importClass = str_ireplace($this->getSearchPath(), '', $filePath). '\\' . $fileNameWithoutExt;
|
|
|
|
|
|
|
|
if (strlen($importClass) > 0 && $importClass[0] === '/') {
|
|
|
|
$importClass = '\\' . substr($importClass, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (string) str_replace(DIRECTORY_SEPARATOR, '\\', $importClass);
|
|
|
|
}
|
|
|
|
}
|