Runs installation logic inside a safe transactional thread. This prevent
DB inconsistencies on install failure.

@return bool True on success, false otherwise
4373
protected function _runTransactional()
    {
        // to avoid any possible issue
        snapshot();

        if (!$this->_init()) {
            return $this->_reset();
        }

        if (!$this->params['no-callbacks']) {
            // "before" events occurs even before plugins is moved to its destination
            $this->_attachListeners($this->_plugin['name'], "{$this->_workingDir}/");
            try {
                $event = $this->trigger("Plugin.{$this->_plugin['name']}.beforeInstall");
                if ($event->isStopped() || $event->result === false) {
                    $this->err(__d('installer', 'Task was explicitly rejected by {0}.', ($this->_plugin['type'] == 'plugin' ? __d('installer', 'the plugin') : __d('installer', 'the theme'))));

                    return $this->_reset();
                }
            } catch (\Exception $ex) {
                $this->err(__d('installer', 'Internal error, {0} did not respond to "beforeInstall" callback correctly.', ($this->_plugin['type'] == 'plugin' ? __d('installer', 'plugin') : __d('installer', 'theme'))));

                return $this->_reset();
            }
        }

        $this->loadModel('System.Plugins');
        $entity = $this->Plugins->newEntity([
            'name' => $this->_plugin['name'],
            'package' => $this->_plugin['packageName'],
            'settings' => [],
            'status' => 0,
            'ordering' => 0,
        ], ['validate' => false]);

        // do not move this lines
        if (!$this->_copyPackage()) {
            return $this->_reset();
        }

        if (!$this->_addOptions()) {
            $this->_rollbackCopyPackage();

            return $this->_reset();
        }

        if (!$this->Plugins->save($entity)) {
            $this->_rollbackCopyPackage();

            return $this->_reset();
        }

        // hold these values as _finish() erases them
        $pluginName = $this->_plugin['name'];
        $pluginType = $this->_plugin['type'];
        $this->_finish(); // plugin namespace is available at this point

        if ($this->params['activate']) {
            $this->dispatchShell("Installer.plugins toggle -p {$pluginName} -s enable");
        }

        if (!$this->params['no-callbacks']) {
            try {
                $event = $this->trigger("Plugin.{$pluginName}.afterInstall");
            } catch (\Exception $ex) {
                $this->err(__d('installer', '{0} was installed but some errors occur.', ($pluginType == 'plugin' ? __d('installer', 'The plugin') : __d('installer', 'The theme'))));
            }
        }

        return true;
    }
631252
protected function doExecute()
    {
        if ($this->console->getMode() !== 'dev') {
            throw new \RuntimeException(
                '<error>STOP!</error> please run <info>' . $this->getEnvCmd() . '</info>.'
            );
        }

        $repository = $this->getRepository();

        if (!$this->getOption('no-backup')) {
            // backup
            $this->backup();
        }

        $repository['path'] = $this->console->get('migration.dir');

        try {
            $repository->migrate($this->getArgument(0, null));

            if ($this->getOption('seed') && (string) $this->getArgument(0) !== '0') {
                $io = clone $this->io;

                $io->setArguments(['seed', 'import']);
                $io->setOption('no-backup', true);

                $this->console->getRootCommand()->setIO($io)->execute();
            }
        } catch (\Exception $e) {
            $prompter = new BooleanPrompter();

            $this->out()->out('<error>An error occurred: ' . $e->getMessage() . '</error>');

            if ($prompter->ask('Do you want to restore to last backup? [Y/n] (Y): ', true)) {
                $this->getBackupRepository()->restoreLatest();
            }

            throw $e;
        }

        return true;
    }
127863
public function commit()
    {
        switch ($this->mode) {

            case "mysql":
                $result = $this->server->commit();
                break;

            case "postgres":
            case "redshift":
                $result = $this->query("COMMIT");
                break;

            case "odbc":
                $result = odbc_commit($this->server);
                break;

            default:
                throw new \Exception("commit() not supported in this mode (" . $this->mode . ")");
        }

        if (!$result) {
            $this->error();
        }

        return true;
    }
20011
protected function doExecute()
    {
        $repository = $this->getRepository();

        $repository['path'] = $this->console->get('migration.dir');

        $migrations = $repository->getMigrations();

        if (!count($migrations)) {
            throw new \RuntimeException('No migrations found.');
        }

        $this->out();
        $this->out(' Status  Version         Migration Name ');
        $this->out('-----------------------------------------');

        $versions = $repository->getVersions();

        $migrations->ksort();

        foreach ($migrations as $migration) {
            $status = (in_array($migration['id'], $versions)) ? '    <info>up</info>' : '  <error>down</error>';

            $info = sprintf(
                '%s   %14.0f  %s',
                $status,
                $migration['id'],
                '<comment>' . $migration['name'] . '</comment>'
            );

            $this->out($info);

            // Remove printed versions
            $index = array_search($migration['id'], $versions);

            unset($versions[$index]);
        }

        foreach ($versions as $version) {
            $info = sprintf(
                '%s   %14.0f  %s',
                '    <info>up</info>',
                $version,
                '** Missing **'
            );

            $this->out($info);
        }

        $this->out();

        return true;
    }
234506
public function execute()
    {
        if (!$this->tryAndProcessRules()) {
            return false;
        }

        $phpmdBinaryPath = $this->phpci->findBinary('phpmd');

        $this->executePhpMd($phpmdBinaryPath);

        $errorCount = $this->processReport(trim($this->phpci->getLastOutput()));
        $this->build->storeMeta('phpmd-warnings', $errorCount);

        return $this->wasLastExecSuccessful($errorCount);
    }
339788
public function run()
    {
        gc_collect_cycles();
        gc_disable();

        if ($this->dryRun) {
            $this->verbose = true;
            $this->runScripts = false;
            $this->installationManager->addInstaller(new NoopInstaller);
            $this->mockLocalRepositories($this->repositoryManager);
        }

        // TODO remove this BC feature at some point
        // purge old require-dev packages to avoid conflicts with the new way of handling dev requirements
        $devRepo = new InstalledFilesystemRepository(new JsonFile($this->config->get('vendor-dir').'/composer/installed_dev.json'));
        if ($devRepo->getPackages()) {
            $this->io->writeError('<warning>BC Notice: Removing old dev packages to migrate to the new require-dev handling.</warning>');
            foreach ($devRepo->getPackages() as $package) {
                if ($this->installationManager->isPackageInstalled($devRepo, $package)) {
                    $this->installationManager->uninstall($devRepo, new UninstallOperation($package));
                }
            }
            unlink($this->config->get('vendor-dir').'/composer/installed_dev.json');
        }
        unset($devRepo, $package);
        // end BC

        if ($this->runScripts) {
            // dispatch pre event
            $eventName = $this->update ? ScriptEvents::PRE_UPDATE_CMD : ScriptEvents::PRE_INSTALL_CMD;
            $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
        }

        $this->downloadManager->setPreferSource($this->preferSource);
        $this->downloadManager->setPreferDist($this->preferDist);

        // clone root package to have one in the installed repo that does not require anything
        // we don't want it to be uninstallable, but its requirements should not conflict
        // with the lock file for example
        $installedRootPackage = clone $this->package;
        $installedRootPackage->setRequires(array());
        $installedRootPackage->setDevRequires(array());

        // create installed repo, this contains all local packages + platform packages (php & extensions)
        $localRepo = $this->repositoryManager->getLocalRepository();
        if (!$this->update && $this->locker->isLocked()) {
            $platformOverrides = $this->locker->getPlatformOverrides();
        } else {
            $platformOverrides = $this->config->get('platform') ?: array();
        }
        $platformRepo = new PlatformRepository(array(), $platformOverrides);
        $repos = array(
            $localRepo,
            new InstalledArrayRepository(array($installedRootPackage)),
            $platformRepo,
        );
        $installedRepo = new CompositeRepository($repos);
        if ($this->additionalInstalledRepository) {
            $installedRepo->addRepository($this->additionalInstalledRepository);
        }

        $aliases = $this->getRootAliases();
        $this->aliasPlatformPackages($platformRepo, $aliases);

        try {
            $this->suggestedPackages = array();
            $res = $this->doInstall($localRepo, $installedRepo, $platformRepo, $aliases, $this->devMode);
            if ($res !== 0) {
                return $res;
            }
        } catch (\Exception $e) {
            $this->installationManager->notifyInstalls();

            throw $e;
        }
        $this->installationManager->notifyInstalls();

        // output suggestions if we're in dev mode
        if ($this->devMode) {
            foreach ($this->suggestedPackages as $suggestion) {
                $target = $suggestion['target'];
                foreach ($installedRepo->getPackages() as $package) {
                    if (in_array($target, $package->getNames())) {
                        continue 2;
                    }
                }

                $this->io->writeError($suggestion['source'].' suggests installing '.$suggestion['target'].' ('.$suggestion['reason'].')');
            }
        }

        # Find abandoned packages and warn user
        foreach ($localRepo->getPackages() as $package) {
            if (!$package instanceof CompletePackage || !$package->isAbandoned()) {
                continue;
            }

            $replacement = (is_string($package->getReplacementPackage()))
                ? 'Use ' . $package->getReplacementPackage() . ' instead'
                : 'No replacement was suggested';

            $this->io->writeError(
                sprintf(
                    "<warning>Package %s is abandoned, you should avoid using it. %s.</warning>",
                    $package->getPrettyName(),
                    $replacement
                )
            );
        }

        if (!$this->dryRun) {
            // write lock
            if ($this->update || !$this->locker->isLocked()) {
                $localRepo->reload();

                // if this is not run in dev mode and the root has dev requires, the lock must
                // contain null to prevent dev installs from a non-dev lock
                $devPackages = ($this->devMode || !$this->package->getDevRequires()) ? array() : null;

                // split dev and non-dev requirements by checking what would be removed if we update without the dev requirements
                if ($this->devMode && $this->package->getDevRequires()) {
                    $policy = $this->createPolicy();
                    $pool = $this->createPool(true);
                    $pool->addRepository($installedRepo, $aliases);

                    // creating requirements request
                    $request = $this->createRequest($this->package, $platformRepo);
                    $request->updateAll();
                    foreach ($this->package->getRequires() as $link) {
                        $request->install($link->getTarget(), $link->getConstraint());
                    }

                    $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::PRE_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request);
                    $solver = new Solver($policy, $pool, $installedRepo);
                    $ops = $solver->solve($request, $this->ignorePlatformReqs);
                    $this->eventDispatcher->dispatchInstallerEvent(InstallerEvents::POST_DEPENDENCIES_SOLVING, false, $policy, $pool, $installedRepo, $request, $ops);
                    foreach ($ops as $op) {
                        if ($op->getJobType() === 'uninstall') {
                            $devPackages[] = $op->getPackage();
                        }
                    }
                }

                $platformReqs = $this->extractPlatformRequirements($this->package->getRequires());
                $platformDevReqs = $this->devMode ? $this->extractPlatformRequirements($this->package->getDevRequires()) : array();

                $updatedLock = $this->locker->setLockData(
                    array_diff($localRepo->getCanonicalPackages(), (array) $devPackages),
                    $devPackages,
                    $platformReqs,
                    $platformDevReqs,
                    $aliases,
                    $this->package->getMinimumStability(),
                    $this->package->getStabilityFlags(),
                    $this->preferStable || $this->package->getPreferStable(),
                    $this->preferLowest,
                    $this->config->get('platform') ?: array()
                );
                if ($updatedLock) {
                    $this->io->writeError('<info>Writing lock file</info>');
                }
            }

            if ($this->dumpAutoloader) {
                // write autoloader
                if ($this->optimizeAutoloader) {
                    $this->io->writeError('<info>Generating optimized autoload files</info>');
                } else {
                    $this->io->writeError('<info>Generating autoload files</info>');
                }

                $this->autoloadGenerator->setDevMode($this->devMode);
                $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader);
            }

            if ($this->runScripts) {
                // dispatch post event
                $eventName = $this->update ? ScriptEvents::POST_UPDATE_CMD : ScriptEvents::POST_INSTALL_CMD;
                $this->eventDispatcher->dispatchScript($eventName, $this->devMode);
            }

            $vendorDir = $this->config->get('vendor-dir');
            if (is_dir($vendorDir)) {
                touch($vendorDir);
            }
        }

        return 0;
    }
894957
public function install()
    {
        $this->shareDependenciesFolder();

        return $this->runWithBeforeAfterEvents(function () {
            return $this->getBinary()->runForApplication('install', [], $this->getInstallationOptions('install'));
        });
    }
389771
public function commitTransaction()
    {
        $this->connect();
        if (!$this->_connection->inTransaction()) {
            return false;
        }

        return $this->_connection->commit();
    }
719729
protected function processInstall()
    {
        if (!$this->isError()) {

            $settings = $this->getSubmitted();
            $this->install->connectDb($settings['database']);
            $result = $this->install->process($settings, $this->current_route);

            if ($result['severity'] === 'success') {
                $this->line($result['message']);
            } else {
                $this->error($result['message']);
            }
        }
    }
414335
public function commit() {
        if ($this->transactionLevel < 0) throw new RuntimeException('Negative transaction nesting level detected: '.$this->transactionLevel);

        if      (!$this->isConnected())    trigger_error('Not connected', E_USER_WARNING);
        else if (!$this->transactionLevel) trigger_error('No database transaction to commit', E_USER_WARNING);
        else {
            if ($this->transactionLevel == 1)
                $this->execute('commit');
            $this->transactionLevel--;
        }
        return $this;
    }
914004
public function install()
    {
        $module = Core::app()->getModuleById($this->sModuleAlias);

        if (!$module)
        {
            // 1. add row to the modules table
            $moduleDir = RX_PATH.'/ruxon/modules/'.$this->sModuleAlias;

            $info = Loader::loadConfigFile($moduleDir, 'module');

            $module = array(
                'Name' => $info['Name'],
                'Description' => $info['Description'],
                'Version' => $info['Version'],
                'DbRevision' => '-1'
            );

            Core::app()->updateModuleById($this->sModuleAlias, $module);

            $sClassName = $this->sModuleAlias.'Module';
            $classNameWithNamespaces = '\ruxon\modules\\'.$this->sModuleAlias.'\classes\\'.$sClassName;
            Manager::getInstance()->setModule($this->sModuleAlias, class_exists($classNameWithNamespaces) ? new $classNameWithNamespaces : new $sClassName);

            // 2. create table structure
            $migrator = new MysqlDbMigrator($this->sModuleAlias);
            $migrator->migrateTo('last');


            // 3. copy default config to config folder
            $file1 = RX_PATH.'/ruxon/modules/'.$this->sModuleAlias.'/config/module.inc.php';
            $file2 = RX_PATH.'/ruxon/config/modules/'.$this->sModuleAlias.'.inc.php';
            if (file_exists($file1) && !file_exists($file2))
            {
                copy($file1, $file2);
            }

            return true;
        }

        return false;
    }
1054836
public function execute()
    {
        // Update the build in the database, ping any external services.
        $this->build->setStatus(Build::STATUS_RUNNING);
        $this->build->setStarted(new \DateTime());
        $this->store->save($this->build);
        $this->build->sendStatusPostback();
        $success = true;

        $previous_build = $this->build->getProject()->getPreviousBuild($this->build->getBranch());

        $previous_state = Build::STATUS_NEW;

        if ($previous_build) {
            $previous_state = $previous_build->getStatus();
        }

        try {
            // Set up the build:
            $this->setupBuild();

            // Run the core plugin stages:
            foreach (array('setup', 'test') as $stage) {
                $success &= $this->pluginExecutor->executePlugins($this->config, $stage);
            }

            // Set the status so this can be used by complete, success and failure
            // stages.
            if ($success) {
                $this->build->setStatus(Build::STATUS_SUCCESS);
            } else {
                $this->build->setStatus(Build::STATUS_FAILED);
            }


            if ($success) {
                $this->pluginExecutor->executePlugins($this->config, 'success');

                if ($previous_state == Build::STATUS_FAILED) {
                    $this->pluginExecutor->executePlugins($this->config, 'fixed');
                }

                $this->buildLogger->logSuccess(Lang::get('build_success'));
            } else {
                $this->pluginExecutor->executePlugins($this->config, 'failure');

                if ($previous_state == Build::STATUS_SUCCESS || $previous_state == Build::STATUS_NEW) {
                    $this->pluginExecutor->executePlugins($this->config, 'broken');
                }

                $this->buildLogger->logFailure(Lang::get('build_failed'));
            }
        } catch (\Exception $ex) {
            $this->build->setStatus(Build::STATUS_FAILED);
            $this->buildLogger->logFailure(Lang::get('exception') . $ex->getMessage());
        }finally{
            // Complete stage plugins are always run
            $this->pluginExecutor->executePlugins($this->config, 'complete');
        }


        // Update the build in the database, ping any external services, etc.
        $this->build->sendStatusPostback();
        $this->build->setFinished(new \DateTime());

        // Clean up:
        $this->buildLogger->log(Lang::get('removing_build'));
        $this->build->removeBuildDirectory();

        $this->store->save($this->build);
    }
846466
protected function validateInstallerInstall()
    {
        $field = 'installer';

        if ($this->isExcluded($field)) {
            return null;
        }

        $value = $this->getSubmitted($field);

        if (empty($value)) {
            $this->setSubmitted('installer', 'default');
            return null;
        }

        $installer = $this->install->getHandler($value);

        if (empty($installer)) {
            $this->setErrorInvalid('installer', $this->translation->text('Installer'));
            return false;
        }

        return true;
    }
599993
public function install(): OperationResult
    {
        $result = new OperationResult();

        $sourceFile = "{$this->packageInstallDir}/.installer/%s/.env";
        foreach ($this->projectType->getProjectDirs() as $projectDir) {
            $envFile = sprintf($sourceFile, $projectDir);
            if (is_file($envFile)) {
                $content = "\n";
                $content .= "###BEGIN-Rikudou-Installer-{$this->packageName}###\n";
                $content .= "# Do not remove the above line if you want the installer to be able to delete the content on uninstall\n";
                $content .= file_get_contents($envFile) . "\n";
                $content .= "###END-Rikudou-Installer-{$this->packageName}###";

                foreach (self::ENV_FILES as $file) {
                    $targetEnvFile = "{$this->projectRootDir}/${file}";
                    if (file_exists($targetEnvFile)) {
                        if (!file_put_contents($targetEnvFile, $content, FILE_APPEND | LOCK_EX)) {
                            $result->addErrorMessage("<error>Could not copy env variables from {$this->packageName}</error>");
                        }
                    }
                }
            }
        }

        if (!$result->isFailure()) {
            $result->addStatusMessage("Successfully copied env variables from {$this->packageName}");
        }

        return $result;
    }
1163580
public function commit(): bool {
        if ($this->transactionExists) {
            $commited = $this->pdo->commit();
            $this->transactionExists = !$commited;
            return $commited;
        }
        return false;
    }
865026
public function execute()
    {
        $buildPath = $this->phpci->buildPath;

        // Check if there are any actions to be run for the branch we're running on:
        if (!array_key_exists($this->build->getBranch(), $this->actions)) {
            return true;
        }

        // If there are, run them:
        $curdir = getcwd();
        chdir($buildPath);

        $success = true;
        foreach ($this->actions[$this->build->getBranch()] as $action => $options) {
            if (!$this->runAction($action, $options)) {
                $success = false;
                break;
            }
        }

        chdir($curdir);

        return $success;
    }
425981
public function transactionStart()
    {
        if (empty($this->oDb)) {
            $this->connect();
        }

        try {

            $this->oDb->beginTransaction();
            $this->transactionRunning = true;

            return true;

        } catch (\Exception $e) {
            throw new TransactionException($e->getMessage(), $e->getCode());
        }
    }