/**
  * Extracts messages to be translated from source code.
  *
  * This command will search through source code files and extract
  * messages that need to be translated in different languages.
  *
  * @param string $configFile the path or alias of the configuration file.
  * You may use the "yii message/config" command to generate
  * this file and then customize it for your needs.
  * @throws Exception on failure.
  */
 public function actionExtract($configFile)
 {
     $configFile = Leaps::getAlias($configFile);
     if (!is_file($configFile)) {
         throw new Exception("The configuration file does not exist: {$configFile}");
     }
     $config = array_merge(['translator' => 'Yii::t', 'overwrite' => false, 'removeUnused' => false, 'markUnused' => true, 'sort' => false, 'format' => 'php', 'ignoreCategories' => []], require $configFile);
     if (!isset($config['sourcePath'], $config['languages'])) {
         throw new Exception('The configuration file must specify "sourcePath" and "languages".');
     }
     if (!is_dir($config['sourcePath'])) {
         throw new Exception("The source path {$config['sourcePath']} is not a valid directory.");
     }
     if (empty($config['format']) || !in_array($config['format'], ['php', 'po', 'pot', 'db'])) {
         throw new Exception('Format should be either "php", "po", "pot" or "db".');
     }
     if (in_array($config['format'], ['php', 'po', 'pot'])) {
         if (!isset($config['messagePath'])) {
             throw new Exception('The configuration file must specify "messagePath".');
         } elseif (!is_dir($config['messagePath'])) {
             throw new Exception("The message path {$config['messagePath']} is not a valid directory.");
         }
     }
     if (empty($config['languages'])) {
         throw new Exception("Languages cannot be empty.");
     }
     $files = FileHelper::findFiles(realpath($config['sourcePath']), $config);
     $messages = [];
     foreach ($files as $file) {
         $messages = array_merge_recursive($messages, $this->extractMessages($file, $config['translator'], $config['ignoreCategories']));
     }
     if (in_array($config['format'], ['php', 'po'])) {
         foreach ($config['languages'] as $language) {
             $dir = $config['messagePath'] . DIRECTORY_SEPARATOR . $language;
             if (!is_dir($dir)) {
                 @mkdir($dir);
             }
             if ($config['format'] === 'po') {
                 $catalog = isset($config['catalog']) ? $config['catalog'] : 'messages';
                 $this->saveMessagesToPO($messages, $dir, $config['overwrite'], $config['removeUnused'], $config['sort'], $catalog, $config['markUnused']);
             } else {
                 $this->saveMessagesToPHP($messages, $dir, $config['overwrite'], $config['removeUnused'], $config['sort'], $config['markUnused']);
             }
         }
     } elseif ($config['format'] === 'db') {
         $db = \Leaps::$app->get(isset($config['db']) ? $config['db'] : 'db');
         if (!$db instanceof \Leaps\Db\Connection) {
             throw new Exception('The "db" option must refer to a valid database application component.');
         }
         $sourceMessageTable = isset($config['sourceMessageTable']) ? $config['sourceMessageTable'] : '{{%source_message}}';
         $messageTable = isset($config['messageTable']) ? $config['messageTable'] : '{{%message}}';
         $this->saveMessagesToDb($messages, $db, $sourceMessageTable, $messageTable, $config['removeUnused'], $config['languages'], $config['markUnused']);
     } elseif ($config['format'] === 'pot') {
         $catalog = isset($config['catalog']) ? $config['catalog'] : 'messages';
         $this->saveMessagesToPOT($messages, $config['messagePath'], $catalog);
     }
 }
 /**
  * Finds fixtures to be loaded, for example "User", if no fixtures were specified then all of them
  * will be searching by suffix "Fixture.php".
  * @param array $fixtures fixtures to be loaded
  * @return array Array of found fixtures. These may differ from input parameter as not all fixtures may exists.
  */
 private function findFixtures(array $fixtures = [])
 {
     $fixturesPath = $this->getFixturePath();
     $filesToSearch = ['*Fixture.php'];
     $findAll = $fixtures == [];
     if (!$findAll) {
         $filesToSearch = [];
         foreach ($fixtures as $fileName) {
             $filesToSearch[] = $fileName . 'Fixture.php';
         }
     }
     $files = FileHelper::findFiles($fixturesPath, ['only' => $filesToSearch]);
     $foundFixtures = [];
     foreach ($files as $fixture) {
         $foundFixtures[] = basename($fixture, 'Fixture.php');
     }
     return $foundFixtures;
 }