Example #1
0
    /**
     * 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;
        }
    }