Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-32257: Prepared Product name and release detection for Ibexa DXP 3.3 #80

Merged
merged 11 commits into from
Dec 31, 2020
Merged
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
34 changes: 18 additions & 16 deletions src/bundle/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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" }

Expand Down
2 changes: 1 addition & 1 deletion src/bundle/Resources/config/view.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
144 changes: 85 additions & 59 deletions src/bundle/SystemInfo/Collector/IbexaSystemInfoCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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',
Expand All @@ -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
];

/**
Expand All @@ -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 <code>IbexaSystemInfoCollector::EXPERIENCE_PACKAGES</code>
* or <code>IbexaSystemInfoCollector::CONTENT_PACKAGES</code>.
*/
const ENTERPRISE_PACKAGES = [
public const ENTERPRISE_PACKAGES = [
'ezsystems/ezplatform-page-builder',
'ezsystems/flex-workflow',
'ezsystems/landing-page-fieldtype-bundle',
Expand All @@ -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',
];

Expand All @@ -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;
}

/**
Expand All @@ -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),
andrerom marked this conversation as resolved.
Show resolved Hide resolved
]);

$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]) :
Expand All @@ -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;
}
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Loading