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;
    }
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;
    }
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 ; }
Runs installation logic inside a safe transactional thread. This prevent
DB inconsistencies on install failure.

@return bool True on success, false otherwise
Runs installation logic inside a safe transactional thread . This prevent DB inconsistencies on install failure .