/**
  * Bootstrap method to be called during application bootstrap stage.
  *
  * @param Application $app the application currently running
  */
 public function bootstrap($app)
 {
     $app->i18n->translations['extensions-manager'] = ['class' => 'yii\\i18n\\PhpMessageSource', 'basePath' => __DIR__ . DIRECTORY_SEPARATOR . 'messages'];
     DeferredQueueEvent::on(DeferredController::className(), DeferredController::EVENT_DEFERRED_QUEUE_COMPLETE, [DeferredQueueCompleteHandler::className(), 'handleEvent']);
     if ($app instanceof \yii\console\Application) {
         $app->controllerMap['extension'] = ExtensionController::className();
         $app->on(Application::EVENT_BEFORE_ACTION, function () {
             $module = ExtensionsManager::module();
             if ($module->autoDiscoverMigrations === true) {
                 if (isset(Yii::$app->params['yii.migrations']) === false) {
                     Yii::$app->params['yii.migrations'] = [];
                 }
                 /** @var array $extensions */
                 $extensions = $module->getExtensions();
                 foreach ($extensions as $name => $ext) {
                     if ($ext['composer_type'] === Extension::TYPE_DOTPLANT && $module->discoverDotPlantMigrations === false) {
                         continue;
                     }
                     $extData = ComposerInstalledSet::get()->getInstalled($ext['composer_name']);
                     $packageMigrations = ExtensionDataHelper::getInstalledExtraData($extData, 'migrationPath', true);
                     $packagePath = '@vendor/' . $ext['composer_name'];
                     foreach ($packageMigrations as $migrationPath) {
                         Yii::$app->params['yii.migrations'][] = "{$packagePath}/{$migrationPath}";
                     }
                 }
             }
         });
     }
 }
 /**
  * @return bool
  */
 public static function generateConfig()
 {
     $installed = ComposerInstalledSet::get()->getInstalled();
     $fileName = Yii::getAlias(ExtensionsManager::module()->extensionsStorage);
     $writer = new ApplicationConfigWriter(['filename' => $fileName]);
     $config = self::rebuldConfig($installed);
     $writer->addValues($config);
     return $writer->commit();
 }
 /**
  * Updates config.
  * Calculates differences between @vengor/composer/installed.json and ExtensionsManager::$extensionsStorage
  * and writes new ExtensionsManager::$extensionsStorage
  *
  */
 public function actionUpdateConfig()
 {
     $result = (int) (ExtensionFileWriter::updateConfig() !== true);
     if ($result === 0) {
         $this->stdout('Update OK' . PHP_EOL, Console::FG_GREEN);
     } else {
         $this->stderr('Error updating extensions storage: ', Console::FG_RED);
         $this->stderr(ExtensionsManager::module()->extensionsStorage . PHP_EOL);
     }
     return $result;
 }
 /**
  * @param bool $onlyActive load configurables only for active extensions
  * @return array
  */
 public static function getConfigurables($onlyActive = false)
 {
     $installed = ComposerInstalledSet::get()->getInstalled();
     $configurables = [];
     foreach ($installed as $package) {
         $packageConfigurablesFile = ArrayHelper::getValue($package, 'extra.configurables', null);
         if ($packageConfigurablesFile === null || true === $onlyActive && false === ExtensionsManager::module()->extensionIsActive($package['name'])) {
             continue;
         }
         $fn = Yii::getAlias('@vendor') . DIRECTORY_SEPARATOR . $package['name'] . DIRECTORY_SEPARATOR . $packageConfigurablesFile;
         if (file_exists($fn) && is_readable($fn)) {
             $packageConfigurables = (include $fn);
             array_walk($packageConfigurables, function (&$item) use($package) {
                 $item['package'] = $package['name'];
                 $item['sectionNameTranslated'] = ExtensionDataHelper::getLocalizedDataField($package, Extension::TYPE_YII, 'name');
             });
             $configurables = ArrayHelper::merge($configurables, $packageConfigurables);
         }
     }
     return $configurables;
 }
 /**
  * Adds uninstall task into ReportingChain
  *
  * @param $extension
  * @param ReportingChain $chain
  */
 private static function uninstall($extension, ReportingChain $chain)
 {
     $module = ExtensionsManager::module();
     if (true === $module->extensionIsCore($extension['composer_name'])) {
         $dummyTask = ExtensionDataHelper::buildTask([realpath(Yii::getAlias('@app') . '/yii'), 'extension/dummy', '--no-interaction', '-o', 'You are unable to uninstall core extensions!'], ExtensionsManager::EXTENSION_DUMMY_DEFERRED_GROUP);
         $chain->addTask($dummyTask);
     } else {
         self::deactivate($extension, $chain);
         $uninstallTask = ExtensionDataHelper::buildTask([$module->composerPath, 'remove', $extension['composer_name'], "--working-dir={$module->getLocalExtensionsPath()}", $module->verbose == 1 ? '-vvv' : ''], ExtensionsManager::COMPOSER_UNINSTALL_DEFERRED_GROUP);
         $chain->addTask($uninstallTask);
     }
 }
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="row">
    <div class="col-md-3">
        <div class="box box-solid configuration-navigation">
            <div class="box-header">
                <h3 class="box-title">
                    <i class="fa fa-list-alt"></i>
                    <?php 
echo Yii::t('extensions-manager', 'Extensions manager');
?>
                </h3>
            </div>
            <div class="box-body">
                <?php 
echo \yii\bootstrap\Nav::widget(['items' => ExtensionsManager::navLinks(), 'options' => ['class' => 'nav-pills nav-stacked']]);
?>
            </div>
        </div>
    </div>
    <div class="col-md-9">
        <div class="extensions-controller__search-extensions box box-solid">
            <div class="box-header clearfix">
                <h3 class="box-title pull-left">
                    <?php 
echo Yii::t('extensions-manager', 'Extensions search');
?>
                </h3>
                <div class="pull-right">
                    <?php 
echo Html::beginForm(['/extensions-manager/extensions/search'], 'GET', ['class' => 'form-inline']);
 /**
  * Updates all application configurations
  *
  * @param bool $usePostData Should we populate all configurationModels with user-data
  * @param bool $loadCurrent if true current states will be loaded and merged with newly created model
  * otherwise configs will be just overwritten with data loaded from post if $usePostData === true
  * @return bool true if all is ok
  * @throws \yii\base\InvalidConfigException
  */
 public function updateConfiguration($usePostData = true)
 {
     /** @var ApplicationConfigWriter[] $configWriters */
     $configWriters = [];
     foreach ($this->configs as $filename => $functionName) {
         $file = $this->generatedConfigsPath . $filename . '.php';
         $configWriters[$filename] = new ApplicationConfigWriter(['filename' => $file]);
     }
     $this->getConfigurables(true);
     $isValid = true;
     $errorSection = '';
     foreach ($this->_configurables as $configurable) {
         if (!isset($configurable['configurationModel'])) {
             continue;
         }
         /** @var BaseConfigurationModel $configurationModel */
         $configurationModel = new $configurable['configurationModel']();
         if (false === ExtensionsManager::module()->extensionIsActive($configurable['package'])) {
             $configurationModel->deleteFromState($this->configurablesStatePath);
             continue;
         } else {
             $configurationModel->loadState($this->configurablesStatePath);
         }
         $dataOk = true;
         if ($usePostData === true) {
             $dataOk = $configurationModel->load(Yii::$app->request->post());
         }
         if ($dataOk === true) {
             $event = new ConfigurationSaveEvent();
             $event->configurable =& $configurable;
             $event->configurationModel =& $configurationModel;
             $configurationModel->trigger($configurationModel->configurationSaveEvent(), $event);
             if ($event->isValid === true) {
                 if ($configurationModel->validate() === true) {
                     $configurationModel->saveState($this->configurablesStatePath);
                 } else {
                     if (Yii::$app->get('session', false)) {
                         Yii::$app->get('session')->setFlash('info', 'Validation error:' . var_export($configurationModel, true));
                     }
                     $isValid = false;
                 }
             } else {
                 $isValid = false;
             }
             if ($isValid === false) {
                 $errorSection = $configurable['sectionName'];
                 // event is valid, stop saving data
                 break;
             }
         }
         // model load from user input
         foreach ($configWriters as $filename => $writer) {
             $callbackFunction = $this->configs[$filename];
             $writer->addValues(call_user_func([$configurationModel, $callbackFunction]));
         }
     }
     // /foreach
     if ($isValid === true) {
         // save all configurations
         $isValid = true;
         foreach ($configWriters as $writer) {
             $isValid = $isValid && $writer->commit();
         }
     }
     if (Yii::$app->get('session', false)) {
         if ($isValid === true) {
             Yii::$app->session->setFlash('success', Yii::t('extensions-manager', 'Configuration saved'));
         } else {
             Yii::$app->session->setFlash('error', Yii::t('extensions-manager', 'Error saving configuration for module {module}', ['module' => $errorSection]));
         }
     }
     return $isValid;
 }
 /**
  * @return string|\yii\web\Response
  */
 public function saveData()
 {
     if (false === isset($this->model)) {
         return '';
     }
     if ($this->model->load(Yii::$app->request->post()) && $this->model->validate()) {
         if (ExtensionsManager::module()->configurationUpdater->updateConfiguration(true)) {
             return $this->controller->redirect([$this->id, 'sectionIndex' => $this->sectionIndex]);
         }
     }
     return '';
 }
 /**
  * This test runs last, because it overrides extensions.php file from installed.json
  * and we have no activated and core extensions there
  *
  * @depends testGetModule
  * @param ExtensionsManager $module
  */
 public function testGetExtensionsNoFile(ExtensionsManager $module)
 {
     TestConfigCleaner::removeExtFile();
     $a = $module->getExtensions('', true);
     $this->assertTrue(TestConfigCleaner::checkExtFile());
     $this->assertEquals(4, count($a));
 }
 /**
  * @inheritdoc
  */
 public function getModuleClassName()
 {
     return ExtensionsManager::className();
 }