diff --git a/composer.json b/composer.json index 6e3b6731..966a018d 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,7 @@ ], "require": { "php": "^7.3", + "ext-json": "*", "ezsystems/ezplatform-kernel": "^1.3@dev", "ezsystems/ezplatform-core": "^2.1@dev", "ezsystems/ezplatform-admin-ui": "^2.2@dev", diff --git a/src/bundle/DependencyInjection/EzSystemsEzSupportToolsExtension.php b/src/bundle/DependencyInjection/EzSystemsEzSupportToolsExtension.php index 4fc0fe83..4ded980f 100644 --- a/src/bundle/DependencyInjection/EzSystemsEzSupportToolsExtension.php +++ b/src/bundle/DependencyInjection/EzSystemsEzSupportToolsExtension.php @@ -63,15 +63,10 @@ public function prepend(ContainerBuilder $container) private function getPoweredByName(ContainerBuilder $container, ?string $release): string { - // Autodetect product name if configured name is null (default) $vendor = $container->getParameter('kernel.project_dir') . '/vendor/'; - if (is_dir($vendor . IbexaSystemInfoCollector::COMMERCE_PACKAGES[0])) { - $name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['commerce']; - } elseif (is_dir($vendor . IbexaSystemInfoCollector::ENTERPRISE_PACKAGES[0])) { - $name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['experience']; - } else { - $name = IbexaSystemInfo::PRODUCT_NAME_OSS; - } + + // Autodetect product name + $name = self::getNameByPackages($vendor); if ($release === 'major') { $name .= ' v' . (int)EzPlatformCoreBundle::VERSION; @@ -98,4 +93,19 @@ private function prependJMSTranslation(ContainerBuilder $container): void ], ]); } + + public static function getNameByPackages(string $vendor): string + { + if (is_dir($vendor . IbexaSystemInfoCollector::COMMERCE_PACKAGES[0])) { + $name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['commerce']; + } elseif (is_dir($vendor . IbexaSystemInfoCollector::EXPERIENCE_PACKAGES[0])) { + $name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['experience']; + } elseif (is_dir($vendor . IbexaSystemInfoCollector::CONTENT_PACKAGES[0])) { + $name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['content']; + } else { + $name = IbexaSystemInfo::PRODUCT_NAME_OSS; + } + + return $name; + } } diff --git a/src/bundle/Resources/config/services.yaml b/src/bundle/Resources/config/services.yaml index 1f14b2fe..0ef79716 100644 --- a/src/bundle/Resources/config/services.yaml +++ b/src/bundle/Resources/config/services.yaml @@ -17,20 +17,21 @@ parameters: support_tools.system_info.collector.symfony.kernel.config.class: EzSystems\EzSupportToolsBundle\SystemInfo\Collector\ConfigurationSymfonyKernelSystemInfoCollector support_tools.system_info.output_format.json.class: EzSystems\EzSupportToolsBundle\SystemInfo\OutputFormat\JsonOutputFormat ezplatform_support_tools.system_info.powered_by.name: '' - support_tools.ez_url_list: - contact: "https://ez.no/About-eZ/Contact-Us" - license: "https://ez.no/About-our-Software/Licenses-and-agreements" - ttl: "https://ez.no/About-our-Software/Licenses-and-agreements/eZ-Trial-and-Test-License-Agreement-eZ-TTL-v2.1" - service_life: "https://support.ez.no/Public/Service-Life" - support_service: "https://ez.no/Services/Support-Maintenance" - training_service: "https://ez.no/Services/Training" - consulting_service: "https://ez.no/Services/Consulting" - ee_product: "https://ez.no/Products/eZ-Platform-Enterprise-Edition" - install_ee: "https://doc.ezplatform.com/en/{ez.release}/getting_started/install_ez_enterprise/" - doc: "https://doc.ezplatform.com" - update: "https://doc.ezplatform.com/en/latest/releases/updating_ez_platform/" + ibexa.system_info.ibexa_url_list: + contact: "https://www.ibexa.co/about-ibexa/contact-us" + license: "https://www.ibexa.co/software-information/licenses-and-agreements" + ttl: "https://www.ibexa.co/software-information/licenses-and-agreements/ez-trial-and-test-license-agreement-ez-ttl-v2.1" + service_life: "https://support.ibexa.co/Public/Service-Life" + support_service: "https://www.ibexa.co/services/support-maintenance" + training_service: "https://www.ibexa.co/services/training" + consulting_service: "https://www.ibexa.co/services/consulting-services" + ee_product: "https://www.ibexa.co/products" + install_ee: "https://doc.ibexa.co/en/{ez.release}/getting_started/install_ez_enterprise/" + doc: "https://doc.ibexa.co" + update: "https://doc.ibexa.co/en/latest/updating/updating_ez_platform/" gpl_faq: "https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.en.html#GPLModuleLicense" - support: "https://support.ez.no" + support: "https://support.ibexa.co" + support_tools.ez_url_list: '%ibexa.system_info.ibexa_url_list%' # BC services: # EventSubscriber @@ -63,10 +64,11 @@ services: # SystemInfoCollectors support_tools.system_info.collector.system.ibexa: - class: "%support_tools.system_info.collector.system.ibexa.class%" + class: '%support_tools.system_info.collector.system.ibexa.class%' arguments: - - "@support_tools.system_info.collector.composer.lock_file" - - "%kernel.debug%" + $composerCollector: "@support_tools.system_info.collector.composer.lock_file" + $kernelProjectDir: '%kernel.project_dir%' + $debug: '%kernel.debug%' tags: - { name: "support_tools.system_info.collector", identifier: "ibexa" } diff --git a/src/bundle/Resources/config/view.yaml b/src/bundle/Resources/config/view.yaml index 72d626a6..f7152ca1 100644 --- a/src/bundle/Resources/config/view.yaml +++ b/src/bundle/Resources/config/view.yaml @@ -45,6 +45,6 @@ services: arguments: $template: '@@ezdesign/ui/dashboard/block/ez.html.twig' $ibexaSystemInfo: "@=service('support_tools.system_info.collector.system.ibexa').collect()" - $urlList: '%support_tools.ez_url_list%' + $urlList: '%ibexa.system_info.ibexa_url_list%' tags: - { name: ezplatform.admin_ui.component, group: 'dashboard-blocks', priority: 200 } diff --git a/src/bundle/SystemInfo/Collector/IbexaSystemInfoCollector.php b/src/bundle/SystemInfo/Collector/IbexaSystemInfoCollector.php index f6303821..60cf81ef 100644 --- a/src/bundle/SystemInfo/Collector/IbexaSystemInfoCollector.php +++ b/src/bundle/SystemInfo/Collector/IbexaSystemInfoCollector.php @@ -7,8 +7,9 @@ namespace EzSystems\EzSupportToolsBundle\SystemInfo\Collector; use EzSystems\EzPlatformCoreBundle\EzPlatformCoreBundle; +use EzSystems\EzSupportToolsBundle\DependencyInjection\EzSystemsEzSupportToolsExtension; use EzSystems\EzSupportToolsBundle\SystemInfo\Exception\ComposerLockFileNotFoundException; -use EzSystems\EzSupportToolsBundle\SystemInfo\Value\ComposerPackage; +use EzSystems\EzSupportToolsBundle\SystemInfo\Value\ComposerSystemInfo; use EzSystems\EzSupportToolsBundle\SystemInfo\Value\IbexaSystemInfo; use DateTime; @@ -30,7 +31,7 @@ class IbexaSystemInfoCollector implements SystemInfoCollector * * Mainly for usage for trial to calculate TTL expiry. */ - const RELEASES = [ + public const RELEASES = [ '2.5' => '2019-03-29T16:59:59+00:00', '3.0' => '2020-04-02T23:59:59+00:00', '3.1' => '2020-07-15T23:59:59+00:00', @@ -51,12 +52,12 @@ class IbexaSystemInfoCollector implements SystemInfoCollector * * @see: https://support.ibexa.co/Public/Service-Life */ - const EOM = [ + public const EOM = [ '2.5' => '2022-03-29T23:59:59+00:00', '3.0' => '2020-07-10T23:59:59+00:00', '3.1' => '2020-11-30T23:59:59+00:00', '3.2' => '2021-02-28T23:59:59+00:00', - '3.3' => '2021-04-30T23:59:59+00:00', // Estimate at time of writing + '3.3' => '2023-12-30T23:59:59+00:00', // Estimate at time of writing ]; /** @@ -66,23 +67,38 @@ class IbexaSystemInfoCollector implements SystemInfoCollector * * @see: https://support.ibexa.co/Public/Service-Life */ - const EOL = [ + public const EOL = [ '2.5' => '2024-03-29T23:59:59+00:00', '3.0' => '2020-08-31T23:59:59+00:00', '3.1' => '2021-01-30T23:59:59+00:00', '3.2' => '2021-04-30T23:59:59+00:00', - '3.3' => '2021-06-30T23:59:59+00:00', // Estimate at time of writing + '3.3' => '2025-12-30T23:59:59+00:00', // Estimate at time of writing ]; /** * Vendors we watch for stability (and potentially more). */ - const PACKAGE_WATCH_REGEX = '/^(doctrine|ezsystems|silversolutions|symfony)\//'; + public const PACKAGE_WATCH_REGEX = '/^(doctrine|ezsystems|silversolutions|symfony)\//'; + + /** + * Packages that identify installation as "Content". + */ + public const CONTENT_PACKAGES = [ + 'ezsystems/ezplatform-workflow', + ]; + + public const EXPERIENCE_PACKAGES = [ + 'ezsystems/ezplatform-page-builder', + 'ezsystems/landing-page-fieldtype-bundle', + ]; /** * Packages that identify installation as "Enterprise". + * + * @deprecated since Ibexa DXP 3.3. Rely either on IbexaSystemInfoCollector::EXPERIENCE_PACKAGES + * or IbexaSystemInfoCollector::CONTENT_PACKAGES. */ - const ENTERPRISE_PACKAGES = [ + public const ENTERPRISE_PACKAGES = [ 'ezsystems/ezplatform-page-builder', 'ezsystems/flex-workflow', 'ezsystems/landing-page-fieldtype-bundle', @@ -91,8 +107,8 @@ class IbexaSystemInfoCollector implements SystemInfoCollector /** * Packages that identify installation as "Commerce". */ - const COMMERCE_PACKAGES = [ - 'ezsystems/ezcommerce-shop', + public const COMMERCE_PACKAGES = [ + 'ezsystems/ezcommerce-admin-ui', 'silversolutions/silver.e-shop', ]; @@ -106,18 +122,25 @@ class IbexaSystemInfoCollector implements SystemInfoCollector */ private $debug; + /** @var string */ + private $kernelProjectDir; + /** * @param \EzSystems\EzSupportToolsBundle\SystemInfo\Collector\JsonComposerLockSystemInfoCollector|\EzSystems\EzSupportToolsBundle\SystemInfo\Collector\SystemInfoCollector $composerCollector * @param bool $debug */ - public function __construct(SystemInfoCollector $composerCollector, $debug = false) - { + public function __construct( + SystemInfoCollector $composerCollector, + string $kernelProjectDir, + bool $debug = false + ) { try { $this->composerInfo = $composerCollector->collect(); } catch (ComposerLockFileNotFoundException $e) { // do nothing } $this->debug = $debug; + $this->kernelProjectDir = $kernelProjectDir; } /** @@ -129,62 +152,63 @@ public function __construct(SystemInfoCollector $composerCollector, $debug = fal */ public function collect(): IbexaSystemInfo { - $ibexa = new IbexaSystemInfo(['debug' => $this->debug, 'composerInfo' => $this->composerInfo]); - if ($this->composerInfo === null) { - return $ibexa; - } + $vendorDir = sprintf('%s/vendor/', $this->kernelProjectDir); + + $ibexa = new IbexaSystemInfo([ + 'debug' => $this->debug, + 'name' => EzSystemsEzSupportToolsExtension::getNameByPackages($vendorDir), + ]); + + $this->setReleaseInfo($ibexa); + $this->extractComposerInfo($ibexa); + + return $ibexa; + } + /** + * @throws \Exception + */ + private function setReleaseInfo(IbexaSystemInfo $ibexa): void + { $ibexa->release = EzPlatformCoreBundle::VERSION; // try to extract version number, but prepare for unexpected string [$majorVersion, $minorVersion] = array_pad(explode('.', $ibexa->release), 2, ''); $ibexaRelease = "{$majorVersion}.{$minorVersion}"; - // In case someone switches from TTL to BUL, make sure we only identify installation as Trial if this is present, - // as well as TTL packages - $hasTTLComposerRepo = \in_array('https://updates.ez.no/ttl', $this->composerInfo->repositoryUrls); - - if ($package = $this->getFirstPackage(self::ENTERPRISE_PACKAGES)) { - $ibexa->isEnterprise = true; - $ibexa->isTrial = $hasTTLComposerRepo && $package->license === 'TTL-2.0'; - $ibexa->name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['experience']; + if (isset(self::EOM[$ibexaRelease])) { + $ibexa->isEndOfMaintenance = strtotime(self::EOM[$ibexaRelease]) < time(); } - if ($package = $this->getFirstPackage(self::COMMERCE_PACKAGES)) { - $ibexa->isCommerce = true; - $ibexa->isTrial = $ibexa->isTrial || ($hasTTLComposerRepo && $package->license === 'TTL-2.0'); - $ibexa->name = IbexaSystemInfo::PRODUCT_NAME_VARIANTS['commerce']; + if (isset(self::EOL[$ibexaRelease])) { + $ibexa->isEndOfLife = strtotime(self::EOL[$ibexaRelease]) < time(); } - if ($ibexa->isTrial && isset(self::RELEASES[$ibexaRelease])) { - $months = (new DateTime(self::RELEASES[$ibexaRelease]))->diff(new DateTime())->m; - $ibexa->isEndOfMaintenance = $months > 3; - // @todo We need to detect this in a better way, this is temporary until some of the work described in class doc is done. - $ibexa->isEndOfLife = $months > 6; - } else { - if (isset(self::EOM[$ibexaRelease])) { - $ibexa->isEndOfMaintenance = strtotime(self::EOM[$ibexaRelease]) < time(); - } + $ibexa->endOfMaintenanceDate = $this->getEOMDate($ibexaRelease); + $ibexa->endOfLifeDate = $this->getEOLDate($ibexaRelease); + } - if (isset(self::EOL[$ibexaRelease])) { - if (!$ibexa->isEnterprise) { - $ibexa->isEndOfLife = $ibexa->isEndOfMaintenance; - } else { - $ibexa->isEndOfLife = strtotime(self::EOL[$ibexaRelease]) < time(); - } - } + private function extractComposerInfo(IbexaSystemInfo $ibexa): void + { + if ($this->composerInfo === null) { + return; } - $ibexa->endOfMaintenanceDate = $this->getEOMDate($ibexaRelease); - $ibexa->endOfLifeDate = $this->getEOLDate($ibexaRelease); - $ibexa->stability = $this->getStability(); + // BC (deprecated property) + $ibexa->composerInfo = ['minimumStability' => $this->composerInfo->minimumStability]; - return $ibexa; + $dxpPackages = array_merge( + self::CONTENT_PACKAGES, + self::EXPERIENCE_PACKAGES, + self::COMMERCE_PACKAGES + ); + $ibexa->isEnterprise = self::hasAnyPackage($this->composerInfo, $dxpPackages); + $ibexa->stability = $ibexa->lowestStability = self::getStability($this->composerInfo); } /** * @throws \Exception */ - private function getEOMDate(string $ibexaRelease): ?\DateTime + private function getEOMDate(string $ibexaRelease): ?DateTime { return isset(self::EOM[$ibexaRelease]) ? new DateTime(self::EOM[$ibexaRelease]) : @@ -194,24 +218,24 @@ private function getEOMDate(string $ibexaRelease): ?\DateTime /** * @throws \Exception */ - private function getEOLDate(string $ibexaRelease): ?\DateTime + private function getEOLDate(string $ibexaRelease): ?DateTime { return isset(self::EOL[$ibexaRelease]) ? new DateTime(self::EOL[$ibexaRelease]) : null; } - private function getStability(): string + private static function getStability(ComposerSystemInfo $composerInfo): string { $stabilityFlags = array_flip(JsonComposerLockSystemInfoCollector::STABILITIES); // Root package stability - $stabilityFlag = $this->composerInfo->minimumStability !== null ? - $stabilityFlags[$this->composerInfo->minimumStability] : + $stabilityFlag = $composerInfo->minimumStability !== null ? + $stabilityFlags[$composerInfo->minimumStability] : $stabilityFlags['stable']; // Check if any of the watched packages has lower stability than root - foreach ($this->composerInfo->packages as $name => $package) { + foreach ($composerInfo->packages as $name => $package) { if (!preg_match(self::PACKAGE_WATCH_REGEX, $name)) { continue; } @@ -228,14 +252,16 @@ private function getStability(): string return JsonComposerLockSystemInfoCollector::STABILITIES[$stabilityFlag]; } - private function getFirstPackage($packageNames): ?ComposerPackage - { + private static function hasAnyPackage( + ComposerSystemInfo $composerInfo, + array $packageNames + ): bool { foreach ($packageNames as $packageName) { - if (isset($this->composerInfo->packages[$packageName])) { - return $this->composerInfo->packages[$packageName]; + if (isset($composerInfo->packages[$packageName])) { + return true; } } - return null; + return false; } } diff --git a/src/bundle/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php b/src/bundle/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php index 9b605d97..4c421495 100644 --- a/src/bundle/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php +++ b/src/bundle/SystemInfo/Collector/JsonComposerLockSystemInfoCollector.php @@ -19,7 +19,7 @@ class JsonComposerLockSystemInfoCollector implements SystemInfoCollector * * Needed as long as we don't want to depend on Composer. */ - const STABILITIES = [ + public const STABILITIES = [ 0 => 'stable', 5 => 'RC', 10 => 'beta', diff --git a/src/bundle/SystemInfo/Value/IbexaSystemInfo.php b/src/bundle/SystemInfo/Value/IbexaSystemInfo.php index 92a60e20..7b007814 100644 --- a/src/bundle/SystemInfo/Value/IbexaSystemInfo.php +++ b/src/bundle/SystemInfo/Value/IbexaSystemInfo.php @@ -49,21 +49,29 @@ class IbexaSystemInfo extends ValueObject implements SystemInfo /** * @var bool + * + * @uses $endOfMaintenanceDate */ public $isEndOfMaintenance = true; /** - * @var \DateTime + * @var \DateTime EOM for the given release, if you have an Ibexa DXP / Enterpise susbscription. + * + * @see https://support.ibexa.co/Public/Service-Life */ public $endOfMaintenanceDate; /** * @var bool + * + * @uses $endOfLifeDate */ public $isEndOfLife = true; /** - * @var \DateTime + * @var \DateTime EOL for the given release, if you have an Ibexa DXP susbscription. + * + * @see https://support.ibexa.co/Public/Service-Life */ public $endOfLifeDate; @@ -73,17 +81,30 @@ class IbexaSystemInfo extends ValueObject implements SystemInfo public $isTrial = false; /** + * Lowest stability found in the installation (packages / minimumStability). + * + * @var string One of {@see \EzSystems\EzSupportToolsBundle\SystemInfo\Collector\JsonComposerLockSystemInfoCollector::STABILITIES}. + */ + public $lowestStability; + + /** + * @deprecated Instead use $lowestStability. + * * @var string One of {@see \EzSystems\EzSupportToolsBundle\SystemInfo\Collector\JsonComposerLockSystemInfoCollector::STABILITIES}. */ public $stability; /** + * @deprecated Duplicates collected info on symfony + * * @var bool */ public $debug; /** - * @var \EzSystems\EzSupportToolsBundle\SystemInfo\Value\ComposerSystemInfo|null + * @deprecated This was duplication of collected info from Composer, now only contains key 'minimumStability' + * + * @var array|null */ public $composerInfo; } diff --git a/src/bundle/Tests/SystemInfo/Collector/IbexaSystemInfoCollectorTest.php b/src/bundle/Tests/SystemInfo/Collector/IbexaSystemInfoCollectorTest.php index bd63404e..cde6575d 100644 --- a/src/bundle/Tests/SystemInfo/Collector/IbexaSystemInfoCollectorTest.php +++ b/src/bundle/Tests/SystemInfo/Collector/IbexaSystemInfoCollectorTest.php @@ -22,7 +22,9 @@ public function testCollect(): void __DIR__ . '/_fixtures/composer.lock', __DIR__ . '/_fixtures/composer.json' ); - $systemInfoCollector = new IbexaSystemInfoCollector($composerCollector); + $systemInfoCollector = new IbexaSystemInfoCollector( + $composerCollector, dirname(__DIR__, 5) + ); $systemInfo = $systemInfoCollector->collect(); self::assertSame(IbexaSystemInfo::PRODUCT_NAME_OSS, $systemInfo->name); self::assertSame(EzPlatformCoreBundle::VERSION, $systemInfo->release);