From 47bfb46bac7e8fb0f47df70240cd3cac13a4dd8c Mon Sep 17 00:00:00 2001 From: Robert Korulczyk Date: Mon, 25 May 2020 23:28:37 +0200 Subject: [PATCH] Add support for premium extensions. refs https://github.com/rob006-software/flarum-translations/issues/306 refs https://github.com/rob006-software/flarum-translations-builder/issues/12 --- commands/ConfigController.php | 15 +- commands/ExtensionsController.php | 5 + commands/JanitorController.php | 1 + commands/ReadmeController.php | 1 + commands/ReleaseController.php | 1 + commands/StatsController.php | 4 +- commands/TranslationsController.php | 1 + components/extensions/ConfigGenerator.php | 25 +-- .../extensions/ExtensionsRepository.php | 29 ++- .../extensions/LanguageStatsGenerator.php | 10 +- .../extensions/PullRequestGenerator.php | 12 +- models/Extension.php | 148 ++------------- models/PremiumExtension.php | 66 +++++++ models/RegularExtension.php | 170 ++++++++++++++++++ models/Translations.php | 6 + 15 files changed, 326 insertions(+), 168 deletions(-) create mode 100644 models/PremiumExtension.php create mode 100644 models/RegularExtension.php diff --git a/commands/ConfigController.php b/commands/ConfigController.php index 841a04d..1d90bb1 100644 --- a/commands/ConfigController.php +++ b/commands/ConfigController.php @@ -15,6 +15,7 @@ use app\components\ConsoleController; use app\components\extensions\ConfigGenerator; +use app\models\RegularExtension; use app\models\Repository; use app\models\Translations; use Yii; @@ -66,12 +67,13 @@ public function actionUpdate(array $projects = [], string $configFile = '@app/tr Yii::warning("Unable to update {$component->getId()} extension.", __METHOD__); continue; } - - $configGenerator->updateExtension($extension); - $this->commitRepository( - $translations->getRepository(), - "Update config for {$component->getId()}.\n\n{$extension->getTranslationTagsUrl()}" - ); + if ($extension instanceof RegularExtension) { + $configGenerator->updateExtension($extension); + $this->commitRepository( + $translations->getRepository(), + "Update config for {$component->getId()}.\n\n{$extension->getTranslationTagsUrl()}" + ); + } } } } @@ -86,6 +88,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); if ($this->update) { $output = $translations->getRepository()->update(); if ($this->verbose) { diff --git a/commands/ExtensionsController.php b/commands/ExtensionsController.php index e5ed3d3..365cdcc 100644 --- a/commands/ExtensionsController.php +++ b/commands/ExtensionsController.php @@ -16,6 +16,7 @@ use app\components\ConsoleController; use app\components\extensions\PullRequestGenerator; use app\models\ForkRepository; +use app\models\RegularExtension; use app\models\Translations; use Yii; use const APP_ROOT; @@ -79,6 +80,9 @@ public function actionDetectNew(int $limit = 2, string $configFile = '@app/trans if (!$extension->hasTranslationSource()) { unset($extensions[$index]); } + if (!$extension instanceof RegularExtension) { + unset($extensions[$index]); + } } $repository = new ForkRepository( @@ -99,6 +103,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); if ($this->update) { $output = $translations->getRepository()->update(); if ($this->verbose) { diff --git a/commands/JanitorController.php b/commands/JanitorController.php index e1f8da0..21b7a71 100644 --- a/commands/JanitorController.php +++ b/commands/JanitorController.php @@ -255,6 +255,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); $translations->getRepository()->update(); return $translations; diff --git a/commands/ReadmeController.php b/commands/ReadmeController.php index f7bf593..e16dfd8 100644 --- a/commands/ReadmeController.php +++ b/commands/ReadmeController.php @@ -147,6 +147,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); if ($this->update) { $output = $translations->getRepository()->update(); if ($this->verbose) { diff --git a/commands/ReleaseController.php b/commands/ReleaseController.php index 437d61e..9195b60 100644 --- a/commands/ReleaseController.php +++ b/commands/ReleaseController.php @@ -78,6 +78,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); if ($this->update) { $output = $translations->getRepository()->update(); if ($this->verbose) { diff --git a/commands/StatsController.php b/commands/StatsController.php index 7f21f50..f114c68 100644 --- a/commands/StatsController.php +++ b/commands/StatsController.php @@ -14,6 +14,7 @@ namespace app\commands; use app\components\extensions\LanguageStatsGenerator; +use app\models\RegularExtension; use app\models\Repository; use app\models\Translations; use Yii; @@ -64,7 +65,7 @@ public function actionUpdate(array $languages = [], string $configFile = '@app/t foreach ($translations->getProjects() as $project) { foreach ($project->getExtensionsComponents() as $component) { $extension = Yii::$app->extensionsRepository->getExtension($component->getId()); - if ($extension !== null) { + if ($extension instanceof RegularExtension) { $generator->addExtension($extension, !$component->isValidForLanguage($language)); } } @@ -97,6 +98,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); if ($this->update) { $output = $translations->getRepository()->update(); if ($this->verbose) { diff --git a/commands/TranslationsController.php b/commands/TranslationsController.php index 4e6eb69..5603f2f 100644 --- a/commands/TranslationsController.php +++ b/commands/TranslationsController.php @@ -103,6 +103,7 @@ private function getTranslations(string $configFile): Translations { null, require Yii::getAlias($configFile) ); + Yii::$app->extensionsRepository->setPremiumExtensions($translations->getPremiumExtensionsConfig()); if ($this->update) { $output = $translations->getRepository()->update(); if ($this->verbose) { diff --git a/components/extensions/ConfigGenerator.php b/components/extensions/ConfigGenerator.php index 50a58cc..38fc719 100644 --- a/components/extensions/ConfigGenerator.php +++ b/components/extensions/ConfigGenerator.php @@ -14,6 +14,7 @@ namespace app\components\extensions; use app\models\Extension; +use app\models\RegularExtension; use Dont\DontCall; use Dont\DontCallStatic; use Dont\DontGet; @@ -108,18 +109,20 @@ private function generateConfig(Extension $extension, $extensionConfig): string $extensionConfig = []; } - $extensionConfig['tag'] = $extension->getStableTranslationSourceUrl(); - foreach ($extensionConfig as $key => $url) { - if (strncmp($key, 'tag:', 4) === 0) { - $extensionConfig[$key] = $extension->getStableTranslationSourceUrl([substr($key, 4)]); + if ($extension instanceof RegularExtension) { + $extensionConfig['tag'] = $extension->getStableTranslationSourceUrl(); + foreach ($extensionConfig as $key => $url) { + if (strncmp($key, 'tag:', 4) === 0) { + $extensionConfig[$key] = $extension->getStableTranslationSourceUrl([substr($key, 4)]); + } } - } - if (isset($extensionConfig['branch'])) { - $extensionConfig['branch'] = $extension->getTranslationSourceUrl(); - } - foreach ($extensionConfig as $key => $url) { - if (strncmp($key, 'branch:', 7) === 0) { - $extensionConfig[$key] = $extension->getTranslationSourceUrl(substr($key, 4)); + if (isset($extensionConfig['branch'])) { + $extensionConfig['branch'] = $extension->getTranslationSourceUrl(); + } + foreach ($extensionConfig as $key => $url) { + if (strncmp($key, 'branch:', 7) === 0) { + $extensionConfig[$key] = $extension->getTranslationSourceUrl(substr($key, 4)); + } } } diff --git a/components/extensions/ExtensionsRepository.php b/components/extensions/ExtensionsRepository.php index d447e46..0709dd8 100644 --- a/components/extensions/ExtensionsRepository.php +++ b/components/extensions/ExtensionsRepository.php @@ -19,6 +19,8 @@ use app\components\extensions\exceptions\UnprocessableExtensionInterface; use app\models\Extension; use app\models\packagist\SearchResult; +use app\models\PremiumExtension; +use app\models\RegularExtension; use Composer\Semver\Semver; use Composer\Semver\VersionParser; use mindplay\readable; @@ -50,6 +52,7 @@ final class ExtensionsRepository extends Component { private $_extensions; private $_client; + private $premiumExtensions = []; /** * @param bool $useCache @@ -94,6 +97,26 @@ public function getValidExtensions(array $supportedVersions, bool $useCache = tr return $extensions; } + // @todo I hope this is temporary solution - premium extensions config should be fetched directly from + // https://extiverse.com/, but I don't know any public and stable API for this. + public function setPremiumExtensions(array $extensionsConfig): void { + $this->_extensions = null; + $this->premiumExtensions = []; + foreach ($extensionsConfig as $id => $extension) { + if (!$extension instanceof PremiumExtension) { + $extension = new PremiumExtension( + $id, + $extension['name'], + $extension['vendor'], + $extension['packageName'], + $extension['repositoryUrl'] + ); + + $this->premiumExtensions[$id] = $extension; + } + } + } + private function getClient(): HttpClientInterface { if ($this->_client === null) { $this->_client = HttpClient::create(); @@ -108,10 +131,10 @@ private function fetchExtensions(): array { 'per_page' => 100, ]); - $extensions = []; + $extensions = $this->premiumExtensions; foreach ($results as $result) { assert($result instanceof SearchResult); - $extension = Extension::createFromPackagistSearchResult($result); + $extension = RegularExtension::createFromPackagistSearchResult($result); if ( !isset($extensions[$extension->getId()]) // handle ID conflicts @@ -124,7 +147,7 @@ private function fetchExtensions(): array { return $extensions; } - private function compareExtensions(Extension $a, Extension $b): int { + private function compareExtensions(RegularExtension $a, RegularExtension $b): int { if ($b->isAbandoned()) { return 1; } diff --git a/components/extensions/LanguageStatsGenerator.php b/components/extensions/LanguageStatsGenerator.php index 5dd0a76..3ef31d7 100644 --- a/components/extensions/LanguageStatsGenerator.php +++ b/components/extensions/LanguageStatsGenerator.php @@ -16,7 +16,7 @@ namespace app\components\extensions; -use app\models\Extension; +use app\models\RegularExtension; use app\models\Project; use Dont\DontCall; use Dont\DontCallStatic; @@ -43,7 +43,7 @@ final class LanguageStatsGenerator { use DontGet; use DontSet; - /** @var Extension[] */ + /** @var RegularExtension[] */ private $extensions = []; /** @var bool */ private $disabledExtensions = []; @@ -72,7 +72,7 @@ public function __construct(string $language, array $projects, string $sortingCr } } - public function addExtension(Extension $extension, bool $isDisabled): void { + public function addExtension(RegularExtension $extension, bool $isDisabled): void { $this->extensions[] = $extension; $this->stats[$extension->getId()] = $this->getStats($extension->getPackageName()); $this->disabledExtensions[$extension->getId()] = $isDisabled; @@ -80,7 +80,7 @@ public function addExtension(Extension $extension, bool $isDisabled): void { public function generate(): string { $extensions = $this->extensions; - usort($extensions, function (Extension $a, Extension $b) { + usort($extensions, function (RegularExtension $a, RegularExtension $b) { $result = $this->stats[$b->getId()][$this->sortingCriteria] <=> $this->stats[$a->getId()][$this->sortingCriteria]; if ($result === 0) { $result = $this->stats[$b->getId()]['total'] <=> $this->stats[$a->getId()]['total']; @@ -163,7 +163,7 @@ private function image(string $src, ?string $alt = null): string { ]); } - private function stats(Extension $extension, string $statsType) : string { + private function stats(RegularExtension $extension, string $statsType) : string { $badge = $this->statsChangeBadge($extension->getPackageName(), $statsType, $this->stats[$extension->getId()][$statsType]); $statsUrl = "https://packagist.org/packages/{$extension->getPackageName()}/stats"; diff --git a/components/extensions/PullRequestGenerator.php b/components/extensions/PullRequestGenerator.php index b2ef468..4d3ed07 100644 --- a/components/extensions/PullRequestGenerator.php +++ b/components/extensions/PullRequestGenerator.php @@ -14,7 +14,7 @@ namespace app\components\extensions; use app\components\GithubApi; -use app\models\Extension; +use app\models\RegularExtension; use app\models\ForkRepository; use Dont\DontCall; use Dont\DontCallStatic; @@ -46,7 +46,7 @@ public function __construct(ForkRepository $repository, ?GithubApi $githubApi = } /** - * @param Extension[] $extensions + * @param RegularExtension[] $extensions * @param int $limit */ public function generateForNewExtensions(array $extensions, int $limit): void { @@ -77,7 +77,7 @@ public function generateForNewExtensions(array $extensions, int $limit): void { } } - private function updateBranch(string $branchName, Extension $extension): bool { + private function updateBranch(string $branchName, RegularExtension $extension): bool { $this->repository->checkoutBranch($branchName); $this->addExtensionToConfig($extension); $this->repository->commit("Update config for {$extension->getPackageName()}.", $commited); @@ -86,13 +86,13 @@ private function updateBranch(string $branchName, Extension $extension): bool { return $commited; } - private function addExtensionToConfig(Extension $extension): void { + private function addExtensionToConfig(RegularExtension $extension): void { $filePath = $this->repository->getPath() . "/config/{$extension->getProjectId()}-project.php"; $generator = new ConfigGenerator($filePath); $generator->updateExtension($extension); } - private function openPullRequestForNewExtension(string $branchName, Extension $extension): void { + private function openPullRequestForNewExtension(string $branchName, RegularExtension $extension): void { $this->githubApi->openPullRequest( Yii::$app->params['translationsRepository'], Yii::$app->params['translationsForkRepository'], @@ -115,7 +115,7 @@ private function updatePullRequestForNewExtension(string $branchName): void { ); } - private function generatePullRequestBadges(Extension $extension): string { + private function generatePullRequestBadges(RegularExtension $extension): string { $name = $extension->getPackageName(); $output = << + * Copyright (c) 2020 Robert Korulczyk * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. @@ -14,24 +14,20 @@ namespace app\models; use app\components\extensions\ExtensionsRepository; -use app\components\extensions\IssueGenerator; -use app\models\packagist\SearchResult; use Dont\DontCall; use Dont\DontCallStatic; use Dont\DontGet; use Dont\DontSet; -use Yii; -use yii\helpers\ArrayHelper; -use yii\helpers\Inflector; use function strncmp; use function strpos; +use function strtolower; /** * Class Extension. * * @author Robert Korulczyk */ -final class Extension { +abstract class Extension { use DontCall; use DontCallStatic; @@ -39,88 +35,22 @@ final class Extension { use DontSet; private $id; - private $repositoryUrl; - private $composerData; - private $packagistBasicData; - public function __construct(string $id, string $repositoryUrl) { + public function __construct(string $id) { $this->id = $id; - $this->repositoryUrl = $repositoryUrl; - } - - public static function createFromPackagistSearchResult(SearchResult $result): Extension { - $extension = new Extension(static::nameToId($result->getName()), $result->getRepository()); - $extension->packagistBasicData = $result; - - return $extension; } public function getId(): string { return $this->id; } - public function getName(): string { - return $this->getComposerValue('extra.flarum-extension.title') - ?? Inflector::titleize(strtr(explode('/', $this->getPackageName())[1], ['-' => ' '])); - } + abstract public function getName(): string; - public function getVendor(): string { - return explode('/', $this->getPackageName())[0]; - } + abstract public function getVendor(): string; - public function getPackageName(): string { - return $this->getPackagistBasicData()->getName(); - } + abstract public function getPackageName(): string; - public function getThreadUrl(): ?string { - return $this->getComposerValue('extra.flagrow.discuss'); - } - - public function getRepositoryUrl(): string { - return $this->repositoryUrl; - } - - public function getTranslationTagsUrl(): string { - return Yii::$app->extensionsRepository->getTagsUrl($this->getTranslationsRepository()); - } - - public function getTranslationTagUrl(?string $tagName = null): string { - $tagName = $tagName ?? Yii::$app->extensionsRepository->detectLastTag($this->getTranslationsRepository()); - return Yii::$app->extensionsRepository->getTagUrl($this->getTranslationsRepository(), $tagName); - } - - public function isAbandoned(): bool { - // abandoned packages without replacement have empty string in `abandoned` field - return $this->getPackagistBasicData()->getAbandoned() !== null; - } - - public function getReplacement(): ?string { - return $this->getPackagistBasicData()->getAbandoned(); - } - - public function isOutdated(array $supportedReleases): bool { - $lastTag = Yii::$app->extensionsRepository->detectLastTag($this->repositoryUrl); - if ($lastTag === null) { - return true; - } - $data = Yii::$app->extensionsRepository->getPackagistReleaseData($this->getComposerValue('name'), $lastTag); - if ($data === null || !isset($data['require']['flarum/core'])) { - return true; - } - $requiredFlarum = $data['require']['flarum/core']; - foreach ($supportedReleases as $release) { - // @todo this check is quite naive - we may need to replace it by regular constraint resolving - if (strpos($requiredFlarum, $release) !== false) { - return false; - } - } - - return true; - } - - public function isLanguagePack(): bool { - return $this->getComposerValue('extra.flarum-locale') !== null; - } + abstract public function getRepositoryUrl(): string; public function getProjectId(): string { if (strncmp('fof/', $this->getPackageName(), 4) === 0) { @@ -133,69 +63,15 @@ public function getProjectId(): string { return 'various'; } - public function getTranslationSourceUrl(?string $branchName = null): string { - if ($this->getProjectId() === 'flarum') { - return Yii::$app->extensionsRepository - ->detectTranslationSourceUrl('https://github.com/flarum/lang-english', $branchName, [ - "locale/{$this->getId()}.yml", - ]); - } - - return Yii::$app->extensionsRepository->detectTranslationSourceUrl($this->repositoryUrl, $branchName); - } - - public function getStableTranslationSourceUrl(?array $prefixes = null): ?string { - $defaultTag = Yii::$app->extensionsRepository->detectLastTag($this->getTranslationsRepository(), $prefixes); - if ($defaultTag === null) { - return null; - } - return $this->getTranslationSourceUrl($defaultTag); - } - - private function getTranslationsRepository(): string { - if ($this->getProjectId() === 'flarum') { - return 'https://github.com/flarum/lang-english'; - } - - return $this->repositoryUrl; - } - public function hasTranslationSource(): bool { $url = $this->getStableTranslationSourceUrl(); return $url !== null && strpos($url, ExtensionsRepository::NO_TRANSLATION_FILE) === false; } - private function getComposerValue(string $key, $default = null) { - return ArrayHelper::getValue($this->getComposerData(), $key, $default); - } - - private function getComposerData(bool $refresh = false): array { - if ($this->composerData === null || $refresh) { - $this->composerData = Yii::$app->extensionsRepository->getComposerJsonData($this->repositoryUrl, $refresh); - } - - return $this->composerData; - } - - private function getPackagistBasicData(): SearchResult { - if ($this->packagistBasicData === null) { - $this->packagistBasicData = Yii::$app->extensionsRepository->getPackagistBasicData($this->getComposerValue('name')); - } - - return $this->packagistBasicData; - } - - public function verifyName(): bool { - $githubName = static::nameToId($this->getComposerData(true)['name']); - $packagistName = static::nameToId($this->getPackageName()); - if ($packagistName === $githubName) { - return true; - } - - (new IssueGenerator())->generateForMigration($packagistName, $githubName); - - return false; - } + /** + * @return bool `true` if name was not changed, `false` otherwise. + */ + abstract public function verifyName(): bool; public static function nameToId(string $name): string { return strtr(strtolower($name), [ diff --git a/models/PremiumExtension.php b/models/PremiumExtension.php new file mode 100644 index 0000000..c401380 --- /dev/null +++ b/models/PremiumExtension.php @@ -0,0 +1,66 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace app\models; + +/** + * Premium extension handled manually. + * + * @see https://extiverse.com/ + * + * @todo Reconsider naming. + * + * @author Robert Korulczyk + */ +final class PremiumExtension extends Extension { + + private $name; + private $vendor; + private $packageName; + private $repositoryUrl; + + public function __construct( + string $id, + string $name, + string $vendor, + string $packageName, + string $repositoryUrl + ) { + $this->name = $name; + $this->vendor = $vendor; + $this->packageName = $packageName; + $this->repositoryUrl = $repositoryUrl; + + parent::__construct($id); + } + + public function getName(): string { + return $this->name; + } + + public function getVendor(): string { + return $this->vendor; + } + + public function getPackageName(): string { + return $this->packageName; + } + + public function getRepositoryUrl(): string { + return $this->repositoryUrl; + } + + public function verifyName(): bool { + return true; + } +} diff --git a/models/RegularExtension.php b/models/RegularExtension.php new file mode 100644 index 0000000..e355961 --- /dev/null +++ b/models/RegularExtension.php @@ -0,0 +1,170 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +declare(strict_types=1); + +namespace app\models; + +use app\components\extensions\IssueGenerator; +use app\models\packagist\SearchResult; +use Yii; +use yii\helpers\ArrayHelper; +use yii\helpers\Inflector; +use function strpos; + +/** + * Basic extension from Packagist. + * + * @todo Reconsider naming. + * + * @author Robert Korulczyk + */ +final class RegularExtension extends Extension { + + private $repositoryUrl; + private $composerData; + private $packagistBasicData; + + public function __construct(string $id, string $repositoryUrl) { + $this->repositoryUrl = $repositoryUrl; + + parent::__construct($id); + } + + public static function createFromPackagistSearchResult(SearchResult $result): self { + $extension = new static(static::nameToId($result->getName()), $result->getRepository()); + $extension->packagistBasicData = $result; + + return $extension; + } + + public function getName(): string { + return $this->getComposerValue('extra.flarum-extension.title') + ?? Inflector::titleize(strtr(explode('/', $this->getPackageName())[1], ['-' => ' '])); + } + + public function getVendor(): string { + return explode('/', $this->getPackageName())[0]; + } + + public function getPackageName(): string { + return $this->getPackagistBasicData()->getName(); + } + + public function getThreadUrl(): ?string { + return $this->getComposerValue('extra.flagrow.discuss'); + } + + public function getRepositoryUrl(): string { + return $this->repositoryUrl; + } + + public function getTranslationTagsUrl(): string { + return Yii::$app->extensionsRepository->getTagsUrl($this->getTranslationsRepository()); + } + + public function getTranslationTagUrl(?string $tagName = null): string { + $tagName = $tagName ?? Yii::$app->extensionsRepository->detectLastTag($this->getTranslationsRepository()); + return Yii::$app->extensionsRepository->getTagUrl($this->getTranslationsRepository(), $tagName); + } + + public function isAbandoned(): bool { + // abandoned packages without replacement have empty string in `abandoned` field + return $this->getPackagistBasicData()->getAbandoned() !== null; + } + + public function getReplacement(): ?string { + return $this->getPackagistBasicData()->getAbandoned(); + } + + public function isOutdated(array $supportedReleases): bool { + $lastTag = Yii::$app->extensionsRepository->detectLastTag($this->repositoryUrl); + if ($lastTag === null) { + return true; + } + $data = Yii::$app->extensionsRepository->getPackagistReleaseData($this->getComposerValue('name'), $lastTag); + if ($data === null || !isset($data['require']['flarum/core'])) { + return true; + } + $requiredFlarum = $data['require']['flarum/core']; + foreach ($supportedReleases as $release) { + // @todo this check is quite naive - we may need to replace it by regular constraint resolving + if (strpos($requiredFlarum, $release) !== false) { + return false; + } + } + + return true; + } + + public function isLanguagePack(): bool { + return $this->getComposerValue('extra.flarum-locale') !== null; + } + + public function getTranslationSourceUrl(?string $branchName = null): string { + if ($this->getProjectId() === 'flarum') { + return Yii::$app->extensionsRepository + ->detectTranslationSourceUrl('https://github.com/flarum/lang-english', $branchName, [ + "locale/{$this->getId()}.yml", + ]); + } + + return Yii::$app->extensionsRepository->detectTranslationSourceUrl($this->repositoryUrl, $branchName); + } + + public function getStableTranslationSourceUrl(?array $prefixes = null): ?string { + $defaultTag = Yii::$app->extensionsRepository->detectLastTag($this->getTranslationsRepository(), $prefixes); + if ($defaultTag === null) { + return null; + } + return $this->getTranslationSourceUrl($defaultTag); + } + + private function getTranslationsRepository(): string { + if ($this->getProjectId() === 'flarum') { + return 'https://github.com/flarum/lang-english'; + } + + return $this->repositoryUrl; + } + + private function getComposerValue(string $key, $default = null) { + return ArrayHelper::getValue($this->getComposerData(), $key, $default); + } + + private function getComposerData(bool $refresh = false): array { + if ($this->composerData === null || $refresh) { + $this->composerData = Yii::$app->extensionsRepository->getComposerJsonData($this->repositoryUrl, $refresh); + } + + return $this->composerData; + } + + private function getPackagistBasicData(): SearchResult { + if ($this->packagistBasicData === null) { + $this->packagistBasicData = Yii::$app->extensionsRepository->getPackagistBasicData($this->getComposerValue('name')); + } + + return $this->packagistBasicData; + } + + public function verifyName(): bool { + $githubName = static::nameToId($this->getComposerData(true)['name']); + $packagistName = static::nameToId($this->getPackageName()); + if ($packagistName === $githubName) { + return true; + } + + (new IssueGenerator())->generateForMigration($packagistName, $githubName); + + return false; + } +} diff --git a/models/Translations.php b/models/Translations.php index 382c5c5..5c002e2 100644 --- a/models/Translations.php +++ b/models/Translations.php @@ -51,6 +51,7 @@ final class Translations { private $vendors; private $languages; private $supportedVersions; + private $premiumExtensions; private $repository; @@ -61,6 +62,7 @@ public function __construct(string $repository, ?string $branch, array $config) $this->sourcesDir = $config['sourcesDir']; $this->translationsDir = $config['translationsDir']; $this->languages = array_keys($config['languages']); + $this->premiumExtensions = $config['premiumExtensions']; $this->vendors = $config['vendors']; $this->subsplits = $config['subsplits']; $this->supportedVersions = $config['supportedVersions']; @@ -202,6 +204,10 @@ public function getVendors(string $projectId): ?array { return $this->vendors[$projectId] ?? null; } + public function getPremiumExtensionsConfig(): array { + return $this->premiumExtensions; + } + public function getSupportedVersions(): array { return $this->supportedVersions; }