/** * Install packages slated for installation during transaction */ static function commit() { if (self::$inTransaction === false) { return false; } $installer = new Uninstaller; // validate dependencies $errs = new \PEAR2\MultiErrors; $reg = Config::current()->registry; try { foreach (self::$uninstallPackages as $package) { $package->validateUninstallDependencies(self::$uninstallPackages, $errs); } if (count($errs->E_ERROR)) { throw new Installer\Exception('Dependency validation failed ' . 'for some installed packages, installation aborted', $errs); } // create dependency connections and load them into the directed graph $graph = new DirectedGraph; foreach (self::$uninstallPackages as $package) { $package->makeUninstallConnections($graph, self::$uninstallPackages); } // topologically sort packages and install them via iterating over the graph $actual = array(); foreach ($graph as $package) { $actual[] = $package; } // easy reverse topological sort array_reverse($actual); AtomicFileTransaction::begin(); $reg->begin(); try { foreach ($actual as $package) { $installer->uninstall($package, $reg); self::$uninstalledPackages[] = $package; } $dirtrees = array(); foreach (self::$uninstalledPackages as $package) { $dirtrees[] = $reg->info($package->name, $package->channel, 'dirtree'); $previous = $reg->toPackageFile($package->name, $package->channel, true); self::$registeredPackages[] = array($package, $previous); $reg->uninstall($package->name, $package->channel); } AtomicFileTransaction::rmEmptyDirs($dirtrees); AtomicFileTransaction::commit(); $reg->commit(); AtomicFileTransaction::removeBackups(); } catch (\Exception $e) { if (AtomicFileTransaction::inTransaction()) { AtomicFileTransaction::rollback(); } $reg->rollback(); throw $e; } self::$uninstallPackages = array(); Config::current()->saveConfig(); if (isset(Main::$options['install-plugins'])) { Config::setCurrent(self::$lastCurrent->path); } } catch (\Exception $e) { self::rollback(); throw $e; } }