/**
  * Find existed or create new vocabularies.
  */
 public function actionImportVocs($dir_path)
 {
     $counter_new_vocs = 0;
     $counter_new_terms = 0;
     $counter_new_synonyms = 0;
     if (!is_dir($dir_path)) {
         echo "Passed directory path '{$dir_path}' is not a directory\n";
         return;
     }
     $dirs = scandir($dir_path);
     unset($dirs[0]);
     unset($dirs[1]);
     $cat_dirs = array_filter($dirs, function ($file) use($dir_path) {
         return is_dir(implode('/', [$dir_path, $file]));
     });
     foreach ($cat_dirs as $cat_dir) {
         $dirs = scandir($dir_path . '/' . $cat_dir);
         unset($dirs[0]);
         unset($dirs[1]);
         $term_files = array_filter($dirs, function ($file) use($dir_path, $cat_dir) {
             return is_file(implode('/', [$dir_path, $cat_dir, $file])) && pathinfo($file)['extension'] == 'txt';
         });
         foreach ($term_files as $term_file) {
             // pathinfo works wrong on our server, so use explode instead
             $key = $this->toUTF(explode('.', $term_file)[0]);
             $category_id = $cat_dir;
             // Find existed or create a new one vocabulary
             $voc = SpecTermsVoc::findOne(['key' => $key, 'category_id' => $category_id]);
             if (empty($voc)) {
                 $voc = new SpecTermsVoc();
                 $voc->key = (string) $key;
                 $voc->category_id = (int) $category_id;
                 try {
                     if ($voc->save()) {
                         echo "New vocabulary '{$voc->name}' created with id {$voc->id} \n";
                         $counter_new_vocs++;
                     }
                 } catch (Exception $e) {
                     echo "Vocabulary for key '{$key}' and category id {$category_id} NOT created\n";
                     continue;
                 }
             }
             $existed_voc_terms = [];
             $sql = "SELECT t.name as term, s.name as synonym " . "FROM term t LEFT JOIN term_synonym s ON t.id = s.term_id " . "WHERE t.vocabulary_id = {$voc->id}";
             foreach (Yii::$app->db->createCommand($sql)->queryAll() as $row) {
                 if (!isset($existed_voc_terms[$row['term']])) {
                     $existed_voc_terms[$row['term']] = array();
                 }
                 if (!empty($row['synonym'])) {
                     $existed_voc_terms[$row['term']][] = $row['synonym'];
                 }
             }
             $content = file_get_contents(implode('/', [$dir_path, $cat_dir, $term_file]));
             $content = $this->toUTF($content);
             $import_terms = SpecTerm::parseTermsStr($content);
             foreach ($import_terms as $term_name => $synonyms) {
                 if (!array_key_exists($term_name, $existed_voc_terms)) {
                     $term = new SpecTerm();
                     $term->name = (string) $term_name;
                     $term->vocabulary_id = $voc->id;
                     if ($term->save()) {
                         echo "New term '{$term->name}' created with id {$term->id} for vocabulary {$voc->name} \n";
                         $counter_new_terms++;
                     }
                 } else {
                     $term = SpecTerm::findOne(['name' => $term_name]);
                 }
                 foreach ($synonyms as $synonym_name) {
                     if (!isset($existed_voc_terms[$term_name]) || !in_array($synonym_name, $existed_voc_terms[$term_name])) {
                         $synonym = new TermSynonym();
                         $synonym->term_id = $term->id;
                         $synonym->name = (string) $synonym_name;
                         if ($synonym->save()) {
                             echo "New synonym '{$synonym->name}' created with id {$synonym->id} for term {$term->name} \n";
                             $counter_new_synonyms++;
                         }
                     }
                 }
             }
         }
     }
     echo "{$counter_new_vocs} vocabularies created \n";
     echo "{$counter_new_terms} terms created \n";
     echo "{$counter_new_synonyms} synonyms created \n";
 }
 private static function initVocsMap()
 {
     // load vocsmap
     $vocs = SpecTermsVoc::find()->all();
     self::$vocs_map = array('by_key' => [], 'by_category' => []);
     foreach ($vocs as $voc) {
         if (!empty($voc->key)) {
             self::$vocs_map['by_key'][$voc->key][] = $voc->id;
         }
         if (!empty($voc->category_id)) {
             self::$vocs_map['by_category'][$voc->category_id][] = $voc->id;
         }
     }
 }