14 use TYPO3\Flow\Annotations as Flow;
87 $this->packagesBasePaths = array(
88 'local' => PATH_typo3conf .
'ext',
89 'global' => PATH_typo3 .
'ext',
90 'sysext' => PATH_typo3 .
'sysext',
91 'composer' => PATH_site .
'Packages',
93 $this->packageStatesPathAndFilename = PATH_typo3conf .
'PackageStates.php';
127 $loadedFromCache = FALSE;
130 $loadedFromCache = TRUE;
131 }
catch (
Exception\PackageManagerCacheUnavailableException $exception) {
138 if (!defined(
'REQUIRED_EXTENSIONS')) {
140 define(
'REQUIRED_EXTENSIONS', implode(
',', $this->requiredPackageKeys));
149 $this->classLoader->setCacheIdentifier(
$cacheIdentifier)->setPackages($this->activePackages);
151 foreach ($this->activePackages as $package) {
153 $package->boot($bootstrap);
156 if (!$loadedFromCache) {
165 if (!isset($this->packageFactory)) {
175 if ($this->cacheIdentifier === NULL) {
176 $mTime = @filemtime($this->packageStatesPathAndFilename);
177 if ($mTime !== FALSE) {
178 $this->cacheIdentifier = md5($this->packageStatesPathAndFilename . $mTime);
180 $this->cacheIdentifier = NULL;
199 if ($cacheEntryIdentifier !== NULL && !$this->coreCache->has($cacheEntryIdentifier)) {
201 $packageObjectsCacheEntryIdentifier = str_replace(
'.',
'', uniqid(
'PackageObjects_', TRUE));
203 $packageCache = array(
204 'packageStatesConfiguration' => $this->packageStatesConfiguration,
205 'packageAliasMap' => $this->packageAliasMap,
206 'packageKeys' => $this->packageKeys,
207 'activePackageKeys' => array_keys($this->activePackages),
208 'requiredPackageKeys' => $this->requiredPackageKeys,
209 'loadedExtArray' =>
$GLOBALS[
'TYPO3_LOADED_EXT'],
210 'packageObjectsCacheEntryIdentifier' => $packageObjectsCacheEntryIdentifier
212 $packageClassSources = array(
213 'typo3\\flow\\package\\package' => NULL,
214 'typo3\\cms\\core\\package\\package' => NULL,
216 foreach ($this->packages as $package) {
217 $packageClassName = strtolower(get_class($package));
218 if (!isset($packageClassSources[$packageClassName]) || $packageClassSources[$packageClassName] === NULL) {
219 $reflectionPackageClass = new \ReflectionClass($packageClassName);
220 $packageClassSource = file_get_contents($reflectionPackageClass->getFileName());
221 $packageClassSources[$packageClassName] = preg_replace(
'/<\?php|\?>/i',
'', $packageClassSource);
224 $this->coreCache->set($packageObjectsCacheEntryIdentifier, serialize($this->packages));
225 $this->coreCache->set(
226 $cacheEntryIdentifier,
227 implode(PHP_EOL, $packageClassSources) . PHP_EOL .
228 'return ' . PHP_EOL . var_export($packageCache, TRUE) .
';' 240 if ($cacheEntryIdentifier === NULL || !$this->coreCache->has($cacheEntryIdentifier) || !($packageCache = $this->coreCache->requireOnce($cacheEntryIdentifier))) {
241 throw new Exception\PackageManagerCacheUnavailableException(
'The package state cache could not be loaded.', 1393883342);
243 $this->packageStatesConfiguration = $packageCache[
'packageStatesConfiguration'];
244 $this->packageAliasMap = $packageCache[
'packageAliasMap'];
245 $this->packageKeys = $packageCache[
'packageKeys'];
246 $this->requiredPackageKeys = $packageCache[
'requiredPackageKeys'];
247 $GLOBALS[
'TYPO3_LOADED_EXT'] = $packageCache[
'loadedExtArray'];
248 $GLOBALS[
'TYPO3_currentPackageManager'] = $this;
250 $packageObjects = substr(substr($this->coreCache->get($packageCache[
'packageObjectsCacheEntryIdentifier']), 6), 0, -2);
251 $this->packages = unserialize($packageObjects);
252 foreach ($packageCache[
'activePackageKeys'] as $activePackageKey) {
253 $this->activePackages[$activePackageKey] = $this->packages[$activePackageKey];
255 unset(
$GLOBALS[
'TYPO3_currentPackageManager']);
266 $this->packageStatesConfiguration = @include($this->packageStatesPathAndFilename) ?: array();
267 if (!isset($this->packageStatesConfiguration[
'version']) || $this->packageStatesConfiguration[
'version'] < 4) {
268 $this->packageStatesConfiguration = array();
270 if ($this->packageStatesConfiguration !== array()) {
273 throw new Exception\PackageStatesUnavailableException(
'The PackageStates.php file is either corrupt or unavailable.', 1381507733);
285 $requiredPackages = array();
286 foreach ($this->packages as $packageKey => $package) {
287 $protected = $package->isProtected();
289 $requiredPackages[$packageKey] = $package;
291 if (isset($this->packageStatesConfiguration[
'packages'][$packageKey][
'state']) && $this->packageStatesConfiguration[
'packages'][$packageKey][
'state'] ===
'active') {
292 $this->activePackages[$packageKey] = $package;
296 $this->activePackages = array_merge($requiredPackages, $this->activePackages);
297 $this->requiredPackageKeys = array_keys($requiredPackages);
299 if ($this->activePackages != $previousActivePackage) {
300 foreach ($this->requiredPackageKeys as $requiredPackageKey) {
301 $this->packageStatesConfiguration[
'packages'][$requiredPackageKey][
'state'] =
'active';
313 $loadedExtObj = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionsArray($this);
314 $GLOBALS[
'TYPO3_LOADED_EXT'] = $loadedExtObj->toArray();
328 if (isset($this->packageStatesConfiguration[
'packages'])) {
329 foreach ($this->packageStatesConfiguration[
'packages'] as $packageKey => $configuration) {
330 if (!@file_exists($this->packagesBasePath . $configuration[
'packagePath'])) {
331 unset($this->packageStatesConfiguration[
'packages'][$packageKey]);
335 $this->packageStatesConfiguration[
'packages'] = array();
340 unset($this->packagesBasePaths[$key]);
344 $packagePaths = $this->scanLegacyExtensions();
349 foreach ($packagePaths as $composerManifestPath) {
350 $packagePath = $composerManifestPath;
351 $packagesBasePath = PATH_site;
352 foreach ($this->packagesBasePaths as $basePath) {
353 if (strpos($packagePath, $basePath) === 0) {
354 $packagesBasePath = $basePath;
359 $composerManifest = self::getComposerManifest($composerManifestPath);
361 $this->composerNameToPackageKeyMap[strtolower($composerManifest->name)] = $packageKey;
362 $this->packageStatesConfiguration[
'packages'][$packageKey][
'manifestPath'] = substr($composerManifestPath, strlen($packagePath)) ? :
'';
363 $this->packageStatesConfiguration[
'packages'][$packageKey][
'composerName'] = $composerManifest->name;
365 $relativePackagePath = substr($packagePath, strlen($packagesBasePath));
366 $packageKey = substr($relativePackagePath, strpos($relativePackagePath,
'/') + 1, -1);
373 if (!isset($this->packageStatesConfiguration[
'packages'][$packageKey][
'state'])) {
374 $this->packageStatesConfiguration[
'packages'][$packageKey][
'state'] =
'inactive';
377 $this->packageStatesConfiguration[
'packages'][$packageKey][
'packagePath'] = str_replace($this->packagesBasePath,
'', $packagePath);
383 $registerOnlyNewPackages = !empty($this->packages);
385 if ($this->packageStatesConfiguration != $previousPackageStatesConfiguration) {
386 $this->sortAndsavePackageStates();
394 protected function scanLegacyExtensions(&$collectedExtensionPaths = array()) {
395 $legacyCmsPackageBasePathTypes = array(
'sysext',
'global',
'local');
396 foreach ($this->packagesBasePaths as $type => $packageBasePath) {
397 if (!in_array($type, $legacyCmsPackageBasePathTypes)) {
401 foreach (
new \DirectoryIterator($packageBasePath) as $fileInfo) {
402 if (!$fileInfo->isDir()) {
405 $filename = $fileInfo->getFilename();
406 if ($filename[0] !==
'.') {
411 if (file_exists($currentPath .
'ext_emconf.php') && !isset($collectedExtensionPaths[$filename])) {
412 $collectedExtensionPaths[$filename] = $currentPath;
417 return $collectedExtensionPaths;
428 if (file_exists($packagePath .
'/ext_emconf.php')) {
431 return parent::findComposerManifestPaths($packagePath);
442 $packageStatesHasChanged = FALSE;
443 foreach ($this->packageStatesConfiguration[
'packages'] as $packageKey => $stateConfiguration) {
449 $packagePath = isset($stateConfiguration[
'packagePath']) ? $stateConfiguration[
'packagePath'] : NULL;
450 $classesPath = isset($stateConfiguration[
'classesPath']) ? $stateConfiguration[
'classesPath'] : NULL;
451 $manifestPath = isset($stateConfiguration[
'manifestPath']) ? $stateConfiguration[
'manifestPath'] : NULL;
454 $package = $this->
getPackageFactory()->create($this->packagesBasePath, $packagePath, $packageKey, $classesPath, $manifestPath);
457 $packageStatesHasChanged = TRUE;
461 $packageStatesHasChanged = TRUE;
468 throw new \TYPO3\Flow\Package\Exception\CorruptPackageException(sprintf(
'The package class in package "%s" does not implement PackageInterface.', $packageKey), 1300782488);
471 $this->packageKeys[strtolower($packageKey)] = $packageKey;
472 if ($stateConfiguration[
'state'] ===
'active') {
473 $this->activePackages[$packageKey] = $this->packages[$packageKey];
476 if ($packageStatesHasChanged) {
490 $package = parent::registerPackage($package, $sortAndSave);
492 foreach ($package->getPackageReplacementKeys() as $packageToReplace => $versionConstraint) {
493 $this->packageAliasMap[strtolower($packageToReplace)] = $package->getPackageKey();
509 foreach ($package->getPackageReplacementKeys() as $packageToReplace => $versionConstraint) {
510 unset($this->packageAliasMap[strtolower($packageToReplace)]);
512 $packageKey = $package->getPackageKey();
516 unset($this->packages[$packageKey]);
517 unset($this->packageKeys[strtolower($packageKey)]);
518 unset($this->packageStatesConfiguration[
'packages'][$packageKey]);
529 if (isset($this->packageAliasMap[$composerName])) {
530 return $this->packageAliasMap[$composerName];
533 return parent::getPackageKeyFromComposerName($composerName);
535 return $composerName;
543 if (!isset($this->extAutoloadClassFiles)) {
544 $classRegistry = array();
545 foreach ($this->activePackages as $packageKey => $packageData) {
548 if (@file_exists($extensionAutoloadFile)) {
549 $classRegistry = array_merge($classRegistry, require $extensionAutoloadFile);
551 }
catch (\BadFunctionCallException $e) {
554 $this->extAutoloadClassFiles = $classRegistry;
569 if (isset($this->packageAliasMap[$lowercasedPackageKey = strtolower($packageKey)])) {
570 $packageKey = $this->packageAliasMap[$lowercasedPackageKey];
572 return parent::getPackage($packageKey);
584 if (isset($this->packageAliasMap[$lowercasedPackageKey = strtolower($packageKey)])) {
585 $packageKey = $this->packageAliasMap[$lowercasedPackageKey];
587 return parent::isPackageAvailable($packageKey);
598 if (isset($this->packageAliasMap[$lowercasedPackageKey = strtolower($packageKey)])) {
599 $packageKey = $this->packageAliasMap[$lowercasedPackageKey];
601 return isset($this->runtimeActivatedPackages[$packageKey]) || parent::isPackageActive($packageKey);
609 parent::deactivatePackage($package->getPackageKey());
617 parent::activatePackage($package->getPackageKey());
618 $this->classLoader->addActivePackage($package);
629 $this->runtimeActivatedPackages[$package->getPackageKey()] = $package;
630 $this->classLoader->addActivePackage($package);
631 if (!isset(
$GLOBALS[
'TYPO3_LOADED_EXT'][$package->getPackageKey()])) {
632 $loadedExtArrayElement = new \TYPO3\CMS\Core\Compatibility\LoadedExtensionArrayElement($package);
633 $GLOBALS[
'TYPO3_LOADED_EXT'][$package->getPackageKey()] = $loadedExtArrayElement->toArray();
643 parent::deletePackage($package->getPackageKey());
652 parent::freezePackage($package->getPackageKey());
661 return parent::isPackageFrozen($package->getPackageKey());
669 parent::unfreezePackage($package->getPackageKey());
677 parent::refreezePackage($package->getPackageKey());
689 return array_merge(parent::getActivePackages(), $this->runtimeActivatedPackages);
703 ksort($this->packageStatesConfiguration[
'packages']);
704 $this->packageStatesConfiguration[
'packages'] = $this->dependencyResolver->sortPackageStatesConfigurationByDependency($this->packageStatesConfiguration[
'packages']);
707 $newPackages = array();
708 foreach ($this->packageStatesConfiguration[
'packages'] as $packageKey => $_) {
709 $newPackages[$packageKey] = $this->packages[$packageKey];
711 $this->packages = $newPackages;
722 parent::resolvePackageDependencies();
723 foreach ($this->packages as $packageKey => $package) {
735 if (!isset($this->packages[$packageKey])) {
738 $suggestedPackageKeys = array();
739 $suggestedPackageConstraints = $this->packages[$packageKey]->getPackageMetaData()->getConstraintsByType(\
TYPO3\Flow\
Package\MetaDataInterface::CONSTRAINT_TYPE_SUGGESTS);
740 foreach ($suggestedPackageConstraints as $constraint) {
741 if ($constraint instanceof \
TYPO3\Flow\
Package\MetaData\PackageConstraint) {
742 $suggestedPackageKey = $constraint->getValue();
743 if (isset($this->packages[$suggestedPackageKey])) {
744 $suggestedPackageKeys[] = $suggestedPackageKey;
748 return array_reverse($suggestedPackageKeys);
758 parent::sortAndSavePackageStates();
sortAndSavePackageStates()
getPackageKeyFromComposerName($composerName)
initializePackageObjects()
initializeCompatibilityLoadedExtArray()
injectCoreCache(\TYPO3\CMS\Core\Cache\Frontend\PhpFrontend $coreCache)
isPackageKeyValid($packageKey)
getSuggestionArrayForPackage($packageKey)
registerPackagesFromConfiguration()
deletePackage($packageKey)
unfreezePackage($packageKey)
static extPath($key, $script='')
static getPackageKeyFromManifest($manifest, $packagePath, $packagesBasePath)
const PATTERN_MATCH_EXTENSIONKEY
scanPackagesInPath($startPath, array &$collectedPackagePaths=array())
deactivatePackage($packageKey)
static clearAllActive($fileAbsPath=NULL)
initialize(\TYPO3\Flow\Core\Bootstrap $bootstrap)
activatePackage($packageKey)
static fixPermissions($path, $recursive=FALSE)
injectClassLoader(\TYPO3\CMS\Core\Core\ClassLoader $classLoader)
sortAvailablePackagesByDependencies()
injectDependencyResolver(DependencyResolver $dependencyResolver)
freezePackage($packageKey)
$runtimeActivatedPackages
resolvePackageDependencies()
isPackageFrozen($packageKey)
activatePackageDuringRuntime($packageKey)
unregisterPackageByPackageKey($packageKey)
loadPackageManagerStatesFromCache()
findComposerManifestPaths($packagePath)
registerPackagesFromConfiguration($registerOnlyNewPackages=FALSE)
refreezePackage($packageKey)
getCacheEntryIdentifier()
isPackageAvailable($packageKey)
registerPackage(\TYPO3\Flow\Package\PackageInterface $package, $sortAndSave=TRUE)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
$packageStatesConfiguration
static getUnixStylePath($path)
isPackageActive($packageKey)