26 private $composerInformation;
36 private $packagesJson;
46 private $packagesAuth;
51 private $timeZoneProvider;
56 private $objectManagerProvider;
61 private $metapackagesMap;
75 \
Magento\
Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider,
81 $this->objectManagerProvider = $objectManagerProvider;
82 $this->composerInformation = $composerInformation;
83 $this->timeZoneProvider = $timeZoneProvider;
84 $this->packagesAuth = $packagesAuth;
86 $this->typeMapper = $typeMapper;
97 $lastSyncData[
'lastSyncDate'] = $this->getLastSyncDate();
99 $packagesForInstall = $this->syncPackagesForInstall();
100 $lastSyncData = $this->formatLastSyncData($packagesForInstall, $lastSyncData);
101 return $lastSyncData;
103 throw new \RuntimeException($e->getMessage());
112 private function getLastSyncDate()
114 $directory = $this->filesystem->getDirectoryRead(
119 return $fileData[
'mtime'];
131 private function formatLastSyncData($packagesForInstall, $lastSyncData)
133 $lastSyncData[
'countOfInstall']
134 = isset($packagesForInstall[
'packages']) ? count($packagesForInstall[
'packages']) : 0;
135 $lastSyncData[
'countOfUpdate'] = isset($lastSyncData[
'packages']) ? count($lastSyncData[
'packages']) : 0;
136 $lastSyncData[
'installPackages'] = $packagesForInstall[
'packages'];
137 if (isset($lastSyncData[
'lastSyncDate'])) {
138 $lastSyncData[
'lastSyncDate'] = $this->formatSyncDate($lastSyncData[
'lastSyncDate']);
140 return $lastSyncData;
149 private function formatSyncDate($syncDate)
151 $timezone = $this->timeZoneProvider->get();
153 'date' => $timezone->formatDateTime(
154 new \DateTime(
'@' . $syncDate),
155 \IntlDateFormatter::MEDIUM,
156 \IntlDateFormatter::NONE,
161 'time' => $timezone->formatDateTime(
162 new \DateTime(
'@' . $syncDate),
163 \IntlDateFormatter::NONE,
164 \IntlDateFormatter::MEDIUM,
179 $installedPackages = array_intersect_key(
180 $this->composerInformation->getInstalledMagentoPackages(),
181 $this->composerInformation->getRootPackage()->getRequires()
184 foreach ($installedPackages as &$package) {
188 return $this->filterPackagesList($installedPackages);
198 $packagesForUpdate = [];
201 foreach ($packages as $package) {
202 $latestProductVersion = $this->getLatestNonDevVersion($package[
'name']);
203 if ($latestProductVersion && version_compare($latestProductVersion, $package[
'version'],
'>')) {
204 $availableVersions = $this->getPackageAvailableVersions($package[
'name']);
205 $package[
'latestVersion'] = $latestProductVersion;
206 $package[
'versions'] = array_filter($availableVersions,
function (
$version) use ($package) {
207 return version_compare(
$version, $package[
'version'],
'>');
209 $packagesForUpdate[$package[
'name']] = $package;
213 return $packagesForUpdate;
222 private function getLatestNonDevVersion($package)
224 $versionParser = new \Composer\Package\Version\VersionParser();
225 foreach ($this->getPackageAvailableVersions($package) as
$version) {
226 if ($versionParser->parseStability(
$version) !=
'dev') {
239 private function getPackagesJson()
241 if ($this->packagesJson !==
null) {
242 return $this->packagesJson;
247 $directory = $this->filesystem->getDirectoryRead(
253 $packagesData = json_decode($jsonData,
true);
255 $this->packagesJson = isset($packagesData[
'packages']) ?
256 $packagesData[
'packages'] :
259 return $this->packagesJson;
260 }
catch (\Exception $e) {
261 throw new \RuntimeException(
'Error in reading packages.json');
271 private function syncPackagesForInstall()
274 $packagesJson = $this->getPackagesJson();
275 $packages = $this->composerInformation->getInstalledMagentoPackages();
276 $packageNames = array_column($packages,
'name');
277 $installPackages = [];
278 foreach ($packagesJson as $packageName => $package) {
279 if (!empty($package) && isset($package) && is_array($package)) {
282 $packageValues = array_values($package);
284 uksort($package,
'version_compare');
285 $installPackage = $packageValues[0];
286 $installPackage[
'versions'] = array_reverse(array_keys($package));
287 $installPackage[
'name'] = $packageName;
288 $installPackage[
'vendor'] = explode(
'/', $packageName)[0];
293 $packagesForInstall[
'packages'] = $this->filterPackagesList($installPackages);
294 return $packagesForInstall;
295 }
catch (\Exception $e) {
296 throw new \RuntimeException(
'Error in syncing packages for Install');
307 private function getPackageExtraInfo($packageName, $packageVersion)
309 $packagesJson = $this->getPackagesJson();
311 return isset($packagesJson[$packageName][$packageVersion][
'extra']) ?
312 $packagesJson[$packageName][$packageVersion][
'extra'] : [];
323 $extraInfo = $this->getPackageExtraInfo($package[
'name'], $package[
'version']);
325 $package[
'package_title'] = isset($extraInfo[
'x-magento-ext-title']) ?
326 $extraInfo[
'x-magento-ext-title'] : $package[
'name'];
327 $package[
'package_type'] = isset($extraInfo[
'x-magento-ext-type']) ? $extraInfo[
'x-magento-ext-type'] :
328 $this->typeMapper->map($package[
'type']);
329 $package[
'package_link'] = isset($extraInfo[
'x-magento-ext-package-link']) ?
330 $extraInfo[
'x-magento-ext-package-link'] :
'';
344 if (!in_array($package[
'name'], $packageNames) &&
345 in_array($package[
'type'], $this->composerInformation->getPackagesTypes()) &&
346 strpos($package[
'name'],
'magento/product-') ===
false &&
347 strpos($package[
'name'],
'magento/project-') ===
false 362 foreach ($package as $key =>
$version) {
363 if (strpos($key,
'dev') !==
false) {
364 unset($package[$key]);
380 $actualInstallPackages = [];
383 $installPackages = $this->syncPackagesForInstall()[
'packages'];
384 $metaPackageByPackage = $this->getMetaPackageForPackage($installPackages);
385 foreach ($installPackages as $package) {
386 $package[
'metapackage'] =
387 isset($metaPackageByPackage[$package[
'name']]) ? $metaPackageByPackage[$package[
'name']] :
'';
388 $actualInstallPackages[$package[
'name']] = $package;
389 $actualInstallPackages[$package[
'name']][
'version'] = $package[
'versions'][0];
391 $installPackagesInfo[
'packages'] = $actualInstallPackages;
392 return $installPackagesInfo;
394 throw new \RuntimeException(
'Error in getting new packages to install');
404 private function filterPackagesList(array $packages)
410 $item[
'package_type'],
412 \
Magento\
Setup\Model\Grid\TypeMapper::LANGUAGE_PACKAGE_TYPE,
413 \
Magento\
Setup\Model\Grid\TypeMapper::MODULE_PACKAGE_TYPE,
414 \
Magento\
Setup\Model\Grid\TypeMapper::EXTENSION_PACKAGE_TYPE,
415 \
Magento\
Setup\Model\Grid\TypeMapper::THEME_PACKAGE_TYPE,
416 \
Magento\
Setup\Model\Grid\TypeMapper::METAPACKAGE_PACKAGE_TYPE
429 private function getMetaPackageForPackage($packages)
432 foreach ($packages as $package) {
434 if (isset($package[
'require'])) {
435 foreach ($package[
'require'] as $key => $requirePackage) {
436 $result[$key] = $package[
'name'];
441 unset($requirePackage);
453 if ($this->metapackagesMap ===
null) {
454 $packages = $this->getPackagesJson();
455 array_walk($packages,
function ($packageVersions) {
456 $package = array_shift($packageVersions);
458 && isset($package[
'require'])
460 foreach (array_keys($package[
'require']) as $key) {
461 $this->metapackagesMap[$key] = $package[
'name'];
467 return $this->metapackagesMap;
477 private function getPackageAvailableVersions($package)
479 $magentoRepositories = $this->composerInformation->getRootRepositories();
482 if (count($magentoRepositories) === 1
483 && strpos($magentoRepositories[0], $this->packagesAuth->getCredentialBaseUrl()) !==
false 485 $packagesJson = $this->getPackagesJson();
487 if (isset($packagesJson[$package])) {
488 $packageVersions = $packagesJson[$package];
489 uksort($packageVersions,
'version_compare');
490 $packageVersions = array_reverse($packageVersions);
492 return array_keys($packageVersions);
496 return $this->getAvailableVersionsFromAllRepositories($package);
506 private function getAvailableVersionsFromAllRepositories($package)
508 $versionsPattern =
'/^versions\s*\:\s(.+)$/m';
512 self::PARAM_PACKAGE => $package,
513 self::PARAM_AVAILABLE => true
516 $applicationFactory = $this->objectManagerProvider->get()
517 ->get(\
Magento\Framework\Composer\MagentoComposerApplicationFactory::class);
523 preg_match($versionsPattern,
$result, $matches);
524 if (isset($matches[1])) {
525 return explode(
', ', $matches[1]);
528 throw new \RuntimeException(
529 sprintf(
'Couldn\'t get available versions for package %s', $package)
isNewUserPackage($package, $packageNames)
const PATH_TO_PACKAGES_FILE
addPackageExtraInfo(array $package)
__construct(\Magento\Framework\Composer\ComposerInformation $composerInformation, \Magento\Setup\Model\DateTime\TimeZoneProvider $timeZoneProvider, \Magento\Setup\Model\PackagesAuth $packagesAuth, \Magento\Framework\Filesystem $filesystem, \Magento\Setup\Model\ObjectManagerProvider $objectManagerProvider, \Magento\Setup\Model\Grid\TypeMapper $typeMapper)
unsetDevVersions($package)