protected function execute(InputInterface $input, OutputInterface $output)
 {
     Wp::load();
     $targetTheme = null;
     $targetThemeSlug = $input->getArgument('theme');
     if (static::CURRENT_THEME == $input->getArgument('theme')) {
         // no user chosen theme: load current
         /** @var \WP_Theme $targetTheme */
         $targetTheme = wp_get_theme();
         $targetThemeSlug = $targetTheme->get_stylesheet();
     }
     if (!$targetTheme) {
         // load user chosen theme
         $targetTheme = wp_get_theme($targetThemeSlug);
     }
     if (!$targetTheme->exists()) {
         throw new \DomainException('Theme ' . $targetThemeSlug . ' does not exist.');
     }
     if ($output->isDebug()) {
         $output->writeln('Theme: ' . $targetTheme->get_stylesheet());
     }
     $morphMethod = $this->getMorphMethod($input);
     // resolve readable name
     $name = $targetThemeSlug;
     if ($targetTheme->get('Name')) {
         $name = $targetTheme->get('Name');
     }
     $this->verbose('Checking ' . $name);
     // resolve theme text domain
     $textDomain = $name;
     if ($targetTheme->get('TextDomain')) {
         $textDomain = $targetTheme->get('TextDomain');
     }
     $this->verbose(' (TextDomain: ' . $textDomain . ')' . PHP_EOL);
     $langPath = WpTheme::resolveLanguagesPath($targetTheme);
     // fetch strings
     $extractor = new WordPressExtractor();
     $extractor::$extractComments = true;
     $extractor::$textDomain = $textDomain;
     $translatable = $extractor->fromDirectory($targetTheme->get_stylesheet_directory());
     // todo B fetch and merge translations from po file
     $translatable->setDomain($textDomain);
     $translatable->ksort();
     // skeleton created
     // file name is same as the slug which is a common way if you look at twenty* themes.
     $skeletonBasename = $targetThemeSlug . '.' . $input->getOption('format');
     if ('po' == $input->getOption('format')) {
         // po templates have the pot extension in the filename
         $skeletonBasename .= 't';
     }
     // merge with existing template
     $skeletonPath = $langPath . '/' . $skeletonBasename;
     $extractMethod = 'from' . ucfirst($input->getOption('format')) . 'File';
     /** @var Translations $skeletonTranslation */
     $skeletonTranslation = call_user_func(['\\Gettext\\Translations', $extractMethod], [$skeletonPath]);
     $this->sanitizeTranslation($translatable, $textDomain, $targetTheme->get_stylesheet_directory());
     $skeletonTranslation->mergeWith($translatable, $translatable::MERGE_ADD | $translatable::MERGE_REFERENCES);
     $this->writeTranslation($input, $output, $skeletonPath, $skeletonTranslation);
     $this->updateTranslations($input, $output, $targetTheme, $skeletonTranslation, $textDomain);
 }
 /**
  * All known translation functions are covered.
  */
 public function testAllKnownTranslationFunctionsAreCovered()
 {
     $extractor = new WordPressExtractor();
     $translations = new Translations();
     $translations->setDomain('test');
     $translations = $extractor->fromDirectory($this->getResourcesPath() . 'commonSources', $translations);
     // file_put_contents($this->getResourcesPath() . 'commonSources.php', var_export($arrayCopy, true));
     $poContent = $translations->toPoString();
     // strip base path for better comparison
     $poContent = str_replace($this->getResourcesPath(), '', $poContent);
     $this->assertContains('"translate"', $poContent);
     $this->assertContains('"translate_with_gettext_context"', $poContent);
     $this->assertContains('"__"', $poContent);
     $this->assertContains('"_x"', $poContent);
     $this->assertContains('"_e"', $poContent);
     $this->assertContains('"_ex"', $poContent);
     $this->assertContains('"esc_attr__"', $poContent);
     $this->assertContains('"esc_attr_e"', $poContent);
     $this->assertContains('"esc_attr_x"', $poContent);
     $this->assertContains('"esc_html__"', $poContent);
     $this->assertContains('"esc_html_e"', $poContent);
     $this->assertContains('"esc_html_x"', $poContent);
     $this->assertContains('"_n-single"', $poContent);
     $this->assertContains('"_n-plural"', $poContent);
     $this->assertContains('"_nx-context"', $poContent);
     $this->assertContains('"_nx-single"', $poContent);
     $this->assertContains('"_nx-plural"', $poContent);
     $this->assertContains('"_n_noop-singular"', $poContent);
     $this->assertContains('"_n_noop-plural"', $poContent);
     $this->assertContains('"_nx_noop-context"', $poContent);
     $this->assertContains('"_nx_noop-singular"', $poContent);
     $this->assertContains('"_nx_noop-plural"', $poContent);
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     Wp::load();
     $this->verbose('WP loaded' . PHP_EOL);
     $targetPluginSlug = $input->getArgument('plugin');
     require_once ABSPATH . '/wp-admin/includes/plugin.php';
     $targetPluginDir = $this->resolvePluginDir($targetPluginSlug);
     $targetPluginRealPath = WP_CONTENT_DIR . '/plugins/' . $targetPluginDir;
     if (!is_readable($targetPluginRealPath)) {
         throw new \DomainException('Path to plugin can not be resolved.');
     }
     // resolve readable name
     $name = $targetPluginSlug;
     $allPlugins = get_plugins();
     $pluginData = $allPlugins[$targetPluginDir];
     if (isset($pluginData['Name']) && $pluginData['Name']) {
         $name = $pluginData['Name'];
     }
     $this->verbose('Translating ' . $name);
     // resolve theme text domain
     $textDomain = $name;
     if (isset($pluginData['TextDomain']) && $pluginData['TextDomain']) {
         $textDomain = $pluginData['TextDomain'];
     }
     $this->verbose(' (TextDomain: ' . $textDomain . ')' . PHP_EOL);
     $langDir = $this->resolveLanguagesDir($pluginData);
     $langPath = dirname($targetPluginRealPath) . '/' . $langDir;
     if ($langPath && !is_dir($langPath)) {
         $this->debug('Creating ' . $langPath . PHP_EOL);
         // not yet translated => create translation
         mkdir($langPath, 0777, true);
     }
     // fetch strings
     $extractor = new WordPressExtractor();
     $extractor::$extractComments = true;
     $extractor::$textDomain = $textDomain;
     $translatable = $extractor->fromDirectory(dirname($targetPluginRealPath), null, $langDir);
     $translatable->setDomain($textDomain);
     $translatable->ksort();
     $this->sanitizeTranslation($translatable, $textDomain, dirname($targetPluginRealPath));
     // create skeleton
     // file name is same as the slug which is a common way if you look at twenty* themes.
     $skeletonBasename = $textDomain . '.' . $input->getOption('format');
     if ('po' == $input->getOption('format')) {
         // po templates have the pot extension in the filename
         $skeletonBasename .= 't';
     }
     // merge with existing template
     $skeletonPath = $langPath . '/' . $skeletonBasename;
     $skeletonTranslation = new Translations();
     if (file_exists($skeletonPath)) {
         $extractMethod = $this->getExtractMethod($input);
         /** @var Translations $skeletonTranslation */
         $skeletonTranslation = call_user_func(['\\Gettext\\Translations', $extractMethod], [$skeletonPath]);
         $this->sanitizeTranslation($skeletonTranslation, $textDomain, dirname($targetPluginRealPath));
     }
     // todo B fetch and merge translations from po file
     $skeletonTranslation->mergeWith($translatable, $translatable::MERGE_ADD | $translatable::MERGE_REFERENCES);
     $this->writeTranslation($input, $output, $skeletonPath, $skeletonTranslation);
     $this->updateTranslations($input, $output, $pluginData, $skeletonTranslation, $targetPluginSlug, $textDomain);
 }