/** * Return array of available languages * * @return array Arry of strings, each containing its ISO language code */ public function getAvailableLanguages() { if (!is_null($this->languageNames)) { return $this->languageNames; } $path = PIWIK_INCLUDE_PATH . "/lang/"; $languagesPath = _glob($path . "*.json"); $pathLength = strlen($path); $languages = array(); if ($languagesPath) { foreach ($languagesPath as $language) { $languages[] = substr($language, $pathLength, -strlen('.json')); } } /** * Hook called after loading available language files. * * Use this hook to customise the list of languagesPath available in Piwik. * * @param array */ Piwik::postEvent('LanguageManager.getAvailableLanguages', array(&$languages)); $this->languageNames = $languages; return $languages; }
public function getPluginsFromDirectoy($directoryToLook) { $directories = _glob($directoryToLook . '/plugins/' . '*', GLOB_ONLYDIR); $directories = array_map(function ($directory) use($directoryToLook) { return str_replace($directoryToLook, '', $directory); }, $directories); return $directories; }
protected function getPluginNamesHavingNotSpecificFile($filename) { $pluginDirs = \_glob(PIWIK_INCLUDE_PATH . '/plugins/*', GLOB_ONLYDIR); $pluginNames = array(); foreach ($pluginDirs as $pluginDir) { if (!file_exists($pluginDir . '/' . $filename)) { $pluginNames[] = basename($pluginDir); } } return $pluginNames; }
function load_templates($tpl_array = null) { global $replacement; $k = array_keys($replacement); $r = array_values($replacement); $path = THEME_PATH . '/templates/'; if (empty($tpl_array)) { $tpl_array = _glob($path, $pattern = 'html'); } foreach ($tpl_array as $key => $tpl) { $tpl = _basename($tpl); $tpl_name = substr($tpl, 0, strlen($tpl) - 5); $templates[$tpl_name] = str_replace($k, $r, file_get_contents($path . $tpl)); } return $templates; }
function tree($dir = '.', $files = true) { if (!isset($dossiers[0]) || $dossiers[0] != $dir) { $dossiers[0] = $dir; } if (!is_dir($dir) && $files) { return array($dir); } elseif (!is_dir($dir) && !$files) { return array(); } $list = _glob(addslash_if_needed($dir)); foreach ($list as $dossier) { $dossiers = array_merge($dossiers, tree($dossier, $files)); } return $dossiers; }
/** * Return array of available languages * * @return array Arry of strings, each containing its ISO language code */ public function getAvailableLanguages() { if (!is_null($this->languageNames)) { return $this->languageNames; } $path = PIWIK_INCLUDE_PATH . "/lang/"; $languages = _glob($path . "*.php"); $pathLength = strlen($path); $languageNames = array(); if ($languages) { foreach ($languages as $language) { $languageNames[] = substr($language, $pathLength, -strlen('.php')); } } $this->languageNames = $languageNames; return $languageNames; }
/** * @return File[] */ public function find() { $jsFiles = array(); if (!$this->ignoreMinified) { $trackerFiles = \_glob($this->dir . '*/' . self::MIN_TRACKER_FILE); foreach ($trackerFiles as $trackerFile) { $plugin = $this->getPluginNameFromFile($trackerFile); if ($this->isPluginActivated($plugin)) { $jsFiles[$plugin] = new File($trackerFile); } } } $trackerFiles = \_glob($this->dir . '*/' . self::TRACKER_FILE); foreach ($trackerFiles as $trackerFile) { $plugin = $this->getPluginNameFromFile($trackerFile); if (!isset($jsFiles[$plugin])) { if ($this->isPluginActivated($plugin)) { $jsFiles[$plugin] = new File($trackerFile); } } } return $jsFiles; }
/** * Reads the directories inside the plugins/ directory and returns their names in an array * * @return array */ public function readPluginsDirectory() { $pluginsName = _glob(PIWIK_INCLUDE_PATH . '/plugins/*', GLOB_ONLYDIR); $result = array(); if ($pluginsName != false) { foreach ($pluginsName as $path) { $name = basename($path); if (file_exists($path . '/' . $name . '.php')) { $result[] = $name; } } } return $result; }
/** * Check that directories in plugins/ folder are specifically either enabled or disabled. * * This fails when a new folder is added to plugins/* and forgot to enable or mark as disabled in Manager.php. * * @group Core */ public function test_DirectoriesInPluginsFolder_areKnown() { $pluginsBundledWithPiwik = \Piwik\Config::getInstance()->getFromGlobalConfig('Plugins'); $pluginsBundledWithPiwik = $pluginsBundledWithPiwik['Plugins']; $magicPlugins = 42; $this->assertTrue(count($pluginsBundledWithPiwik) > $magicPlugins); $plugins = _glob(\Piwik\Plugin\Manager::getPluginsDirectory() . '*', GLOB_ONLYDIR); $count = 1; foreach ($plugins as $pluginPath) { $pluginName = basename($pluginPath); $addedToGit = $this->isPathAddedToGit($pluginPath); if (!$addedToGit) { // if not added to git, then it is not part of the release checklist. continue; } $manager = \Piwik\Plugin\Manager::getInstance(); $isGitSubmodule = $manager->isPluginOfficialAndNotBundledWithCore($pluginName); $disabled = in_array($pluginName, $manager->getCorePluginsDisabledByDefault()) || $isGitSubmodule; $enabled = in_array($pluginName, $pluginsBundledWithPiwik); $this->assertTrue($enabled + $disabled === 1, "Plugin {$pluginName} should be either enabled (in global.ini.php) or disabled (in Piwik\\Plugin\\Manager).\n It is currently (enabled=" . (int) $enabled . ", disabled=" . (int) $disabled . ")"); $count++; } $this->assertTrue($count > $magicPlugins); }
if (strlen($id) > strlen(uniqid(true))) { # add class password protected $class = 'locked'; $title = e('The user can access this only with the password', false); } } $extension = strtolower(pathinfo($fichier, PATHINFO_EXTENSION)); if (visualizeIcon($extension)) { $icone_visu = '<a class="visu" href="index.php?f=' . $id . '" target="_BLANK" title="' . e('View this file', false) . '"> </a>'; } else { $icone_visu = ''; } $fichier_short = substr($fichier, $upload_path_size); if (is_dir($fichier)) { # Item is a folder $taille = count(_glob($fichier . '/')); $array = array('#CLASS' => $class, '#ID' => $id, '#FICHIER' => $fichier_short, '#TOKEN' => returnToken(), '#SIZE' => $taille, '#NAME' => $nom, '#TITLE' => $title, '#SLASHEDNAME' => addslashes($nom), '#SLASHEDFICHIER' => addslashes($fichier)); $folderlist .= template($mode . '_folder_' . $layout, $array); } elseif ($extension == 'gif' || $extension == 'jpg' || $extension == 'jpeg' || $extension == 'png') { # Item is a picture auto_thumb($fichier, 64, 64); $array = array('#CLASS' => $class, '#ID' => $id, '#FICHIER' => $fichier_short, '#TOKEN' => returnToken(), '#SIZE' => $taille, '#NAME' => $nom, '#TITLE' => $title, '#EXTENSION' => $extension, '#ICONE_VISU' => $icone_visu, '#SLASHEDNAME' => addslashes($nom), '#SLASHEDFICHIER' => addslashes($fichier_short)); $filelist .= template($mode . '_image_' . $layout, $array); } elseif ($extension == 'zip') { # Item is a zip file=> add change to folder $icone_visu = '<a class="tofolder" href="index.php?p=admin&unzip=' . $id . '&token=' . returnToken() . '" title="' . e('Convert this zip file to folder', false) . '"> </a>'; $array = array('#CLASS' => $class, '#ID' => $id, '#FICHIER' => $fichier_short, '#TOKEN' => returnToken(), '#SIZE' => $taille, '#NAME' => $nom, '#TITLE' => $title, '#EXTENSION' => $extension, '#ICONE_VISU' => $icone_visu, '#SLASHEDNAME' => addslashes($nom), '#SLASHEDFICHIER' => addslashes($fichier_short)); $filelist .= template($mode . '_file_' . $layout, $array); } else { # all other types $array = array('#CLASS' => $class, '#ID' => $id, '#FICHIER' => $fichier_short, '#TOKEN' => returnToken(), '#SIZE' => $taille, '#NAME' => $nom, '#TITLE' => $title, '#EXTENSION' => $extension, '#ICONE_VISU' => $icone_visu, '#SLASHEDNAME' => addslashes($nom), '#SLASHEDFICHIER' => addslashes($fichier_short));
function available_languages() { $l = _glob('locale/', 'php'); foreach ($l as $key => $lang) { $l[$key] = str_replace('.php', '', basename($lang)); } return $l; }
/** * Remove files older than one week. They should be cleaned up automatically after each request but for whatever * reason there can be always some files left. */ public static function cleanupNotRemovedFiles() { $timeOneWeekAgo = strtotime('-1 week'); $files = _glob(self::getTmpPath() . '/*'); if (empty($files)) { return; } foreach ($files as $file) { $timeLastModified = filemtime($file); if ($timeOneWeekAgo > $timeLastModified) { unlink($file); } } }
} $liste = array(); $pattern = str_replace('*', '', $pattern); if ($handle = opendir($path)) { while (false !== ($file = readdir($handle))) { if (stripos($file, $pattern) !== false || $pattern == '' && $file != '.' && $file != '..' && $file != '.htaccess') { $liste[] = $path . $file; } } closedir($handle); } natcasesort($liste); return $liste; } } $cssFiles = _glob('./', 'css'); /** * Ideally, you wouldn't need to change any code beyond this point. */ $buffer = ""; foreach ($cssFiles as $cssFile) { $buffer .= file_get_contents($cssFile); } $buffer = str_replace(array_keys($replace), array_values($replace), $buffer); // Remove unnecessary characters $buffer = preg_replace("|/\\*[^*]*\\*+([^/][^*]*\\*+)*/|", "", $buffer); $buffer = preg_replace("/[\\s]*([\\:\\{\\}\\;\\,])[\\s]*/", "\$1", $buffer); // Remove whitespace $buffer = str_replace(array("\r\n", "\r", "\n"), '', $buffer); // Enable GZip encoding. ob_start("ob_gzhandler");
protected function execute(InputInterface $input, OutputInterface $output) { $dialog = $this->getHelperSet()->get('dialog'); $command = $this->getApplication()->find('translations:fetch'); $arguments = array('command' => 'translations:fetch', '--username' => $input->getOption('username'), '--password' => $input->getOption('password')); $inputObject = new ArrayInput($arguments); $inputObject->setInteractive($input->isInteractive()); $command->run($inputObject, $output); $languages = API::getInstance()->getAvailableLanguageNames(); $languageCodes = array(); foreach ($languages as $languageInfo) { $languageCodes[] = $languageInfo['code']; } $plugin = $input->getOption('plugin'); $files = _glob(FetchFromOTrance::getDownloadPath() . DIRECTORY_SEPARATOR . '*.json'); $output->writeln("Starting to import new language files"); if (!$input->isInteractive()) { $output->writeln("(!) Non interactive mode: New languages will be skipped"); } $progress = $this->getHelperSet()->get('progress'); $progress->start($output, count($files)); foreach ($files as $filename) { $progress->advance(); $code = basename($filename, '.json'); if (!in_array($code, $languageCodes)) { if (!empty($plugin)) { continue; # never create a new language for plugin only } $createNewFile = false; if ($input->isInteractive()) { $createNewFile = $dialog->askConfirmation($output, "\nLanguage {$code} does not exist. Should it be added? ", false); } if (!$createNewFile) { continue; # do not create a new file for the language } @touch(PIWIK_DOCUMENT_ROOT . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $code . '.json'); API::unsetInstance(); // unset language manager instance, so valid names are refetched } $command = $this->getApplication()->find('translations:set'); $arguments = array('command' => 'translations:set', '--code' => $code, '--file' => $filename, '--plugin' => $plugin); $inputObject = new ArrayInput($arguments); $inputObject->setInteractive($input->isInteractive()); $command->run($inputObject, new NullOutput()); // update core modules that aren't in their own repo if (empty($plugin)) { foreach (self::getPluginsInCore() as $pluginName) { // update translation files $command = $this->getApplication()->find('translations:set'); $arguments = array('command' => 'translations:set', '--code' => $code, '--file' => $filename, '--plugin' => $pluginName); $inputObject = new ArrayInput($arguments); $inputObject->setInteractive($input->isInteractive()); $command->run($inputObject, new NullOutput()); } } } $progress->finish(); $output->writeln("Finished."); }
protected function execute(InputInterface $input, OutputInterface $output) { $start = microtime(true); /** @var DialogHelper $dialog */ $dialog = $this->getHelperSet()->get('dialog'); $languages = API::getInstance()->getAvailableLanguageNames(); $languageCodes = array(); foreach ($languages as $languageInfo) { $languageCodes[] = $languageInfo['code']; } $plugin = $input->getOption('plugin'); if (!$input->isInteractive()) { $output->writeln("(!) Non interactive mode: New languages will be skipped"); } $pluginList = array($plugin); if (empty($plugin)) { $pluginList = self::getPluginsInCore(); array_unshift($pluginList, ''); } foreach ($pluginList as $plugin) { $output->writeln(""); // fetch base or specific plugin $this->fetchTranslations($input, $output, $plugin); $files = _glob(FetchTranslations::getDownloadPath() . DIRECTORY_SEPARATOR . '*.json'); if (count($files) == 0) { $output->writeln("No translation updates available! Skipped."); continue; } $output->writeln("Starting to import new language files"); /** @var ProgressHelper $progress */ $progress = $this->getHelperSet()->get('progress'); $progress->start($output, count($files)); foreach ($files as $filename) { $progress->advance(); $code = basename($filename, '.json'); if (!in_array($code, $languageCodes)) { if (!empty($plugin)) { continue; # never create a new language for plugin only } $createNewFile = false; if ($input->isInteractive()) { $createNewFile = $dialog->askConfirmation($output, "\nLanguage {$code} does not exist. Should it be added? ", false); } if (!$createNewFile) { continue; # do not create a new file for the language } @touch(PIWIK_DOCUMENT_ROOT . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $code . '.json'); API::unsetInstance(); // unset language manager instance, so valid names are refetched } $command = $this->getApplication()->find('translations:set'); $arguments = array('command' => 'translations:set', '--code' => $code, '--file' => $filename, '--plugin' => $plugin); $inputObject = new ArrayInput($arguments); $inputObject->setInteractive($input->isInteractive()); $command->run($inputObject, new NullOutput()); } $progress->finish(); } $output->writeln("Finished in " . round(microtime(true) - $start, 3) . "s"); }
/** * Reads the directories inside the plugins/ directory and returns their names in an array * * @return array */ public function readPluginsDirectory() { $pluginsName = _glob( PIWIK_INCLUDE_PATH . '/plugins/*', GLOB_ONLYDIR); $pluginsName = $pluginsName == false ? array() : array_map('basename', $pluginsName); return $pluginsName; }
/** * Recursively find pathnames that match a pattern * @see glob() * * @param string $sDir directory * @param string $sPattern pattern * @param int $nFlags glob() flags * @return array */ public static function globr($sDir, $sPattern, $nFlags = NULL) { if(($aFiles = _glob("$sDir/$sPattern", $nFlags)) == false) { $aFiles = array(); } if(($aDirs = _glob("$sDir/*", GLOB_ONLYDIR)) != false) { foreach ($aDirs as $sSubDir) { $aSubFiles = self::globr($sSubDir, $sPattern, $nFlags); $aFiles = array_merge($aFiles, $aSubFiles); } } return $aFiles; }
/** * Recursively find pathnames that match a pattern. * * See {@link http://php.net/manual/en/function.glob.php glob} for more info. * * @param string $sDir directory The directory to glob in. * @param string $sPattern pattern The pattern to match paths against. * @param int $nFlags `glob()` . See {@link http://php.net/manual/en/function.glob.php glob()}. * @return array The list of paths that match the pattern. * @api */ public static function globr($sDir, $sPattern, $nFlags = null) { if (($aFiles = \_glob("{$sDir}/{$sPattern}", $nFlags)) == false) { $aFiles = array(); } if (($aDirs = \_glob("{$sDir}/*", GLOB_ONLYDIR)) != false) { foreach ($aDirs as $sSubDir) { if (is_link($sSubDir)) { continue; } $aSubFiles = self::globr($sSubDir, $sPattern, $nFlags); $aFiles = array_merge($aFiles, $aSubFiles); } } return $aFiles; }
/** * Construct list of update files for the outdated components * * @return array( componentName => array( file1 => version1, [...]), [...]) */ private function loadComponentsWithUpdateFile() { $componentsWithUpdateFile = array(); foreach ($this->componentsWithNewVersion as $name => $versions) { $currentVersion = $versions[self::INDEX_CURRENT_VERSION]; $newVersion = $versions[self::INDEX_NEW_VERSION]; if ($name == 'core') { $pathToUpdates = $this->pathUpdateFileCore . '*.php'; } elseif (ColumnUpdater::isDimensionComponent($name)) { $componentsWithUpdateFile[$name][PIWIK_INCLUDE_PATH . '/core/Columns/Updater.php'] = $newVersion; } else { $pathToUpdates = sprintf($this->pathUpdateFilePlugins, $name) . '*.php'; } if (!empty($pathToUpdates)) { $files = _glob($pathToUpdates); if ($files == false) { $files = array(); } foreach ($files as $file) { $fileVersion = basename($file, '.php'); if (version_compare($currentVersion, $fileVersion) == -1 && version_compare($fileVersion, $newVersion) <= 0) { $componentsWithUpdateFile[$name][$file] = $fileVersion; } } } if (isset($componentsWithUpdateFile[$name])) { // order the update files by version asc uasort($componentsWithUpdateFile[$name], "version_compare"); } else { // there are no update file => nothing to do, update to the new version is successful $this->markComponentSuccessfullyUpdated($name, $newVersion); } } return $componentsWithUpdateFile; }
/** * Construct list of update files for the outdated components * * @return array( componentName => array( file1 => version1, [...]), [...]) */ private function loadComponentsWithUpdateFile() { $componentsWithUpdateFile = array(); foreach($this->componentsWithNewVersion as $name => $versions) { $currentVersion = $versions[self::INDEX_CURRENT_VERSION]; $newVersion = $versions[self::INDEX_NEW_VERSION]; if($name == 'core') { $pathToUpdates = $this->pathUpdateFileCore . '*.php'; } else { $pathToUpdates = sprintf($this->pathUpdateFilePlugins, $name) . '*.php'; } $files = _glob( $pathToUpdates ); if($files == false) { $files = array(); } foreach( $files as $file) { $fileVersion = basename($file, '.php'); if( // if the update is from a newer version version_compare($currentVersion, $fileVersion) == -1 // but we don't execute updates from non existing future releases && version_compare($fileVersion, $newVersion) <= 0) { $componentsWithUpdateFile[$name][$file] = $fileVersion; } } if(isset($componentsWithUpdateFile[$name])) { // order the update files by version asc uasort($componentsWithUpdateFile[$name], "version_compare"); } else { // there are no update file => nothing to do, update to the new version is successful $this->recordComponentSuccessfullyUpdated($name, $newVersion); } } return $componentsWithUpdateFile; }
private function getFilesInTmpFolder() { $dir = PIWIK_INCLUDE_PATH . '/tmp'; $files = \_glob($dir . "/*", null); $subFiles = \_glob($dir . "/*/*", null); $files = array_merge($files, $subFiles); return $files; }
<hr/> <a class="button" href="stats.php"> <?php e('Access log file'); ?> <img src="design/<?php echo $_SESSION['theme']; ?> /img/info.png"/></a> <form action="#" method="get" class="themeform"> <label><?php e('Change theme'); ?> </label> <select name="theme" class="button"> <?php $themes = _glob('design/'); foreach ($themes as $theme) { $theme = basename($theme); if ($theme == $_SESSION['theme']) { $selected = ' selected '; } else { $selected = ''; } echo '<option value="' . $theme . '" ' . $selected . '>' . $theme . '</option>'; } ?> </select> <input type="submit" value="ok"/> <?php newToken();
/** * Reads the directories inside the plugins/ directory and returns their names in an array * * @return array */ public function readPluginsDirectory() { $pluginsName = _glob(self::getPluginsDirectory() . '*', GLOB_ONLYDIR); $result = array(); if ($pluginsName != false) { foreach ($pluginsName as $path) { if (self::pluginStructureLooksValid($path)) { $result[] = basename($path); } } } return $result; }
protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln("Starting to fetch latest language pack"); $dialog = $this->getHelperSet()->get('dialog'); $cookieFile = self::getDownloadPath() . DIRECTORY_SEPARATOR . 'cookie.txt'; @unlink($cookieFile); $username = $input->getOption('username'); $password = $input->getOption('password'); while (!file_exists($cookieFile)) { if (empty($username)) { $username = $dialog->ask($output, 'What is your oTrance username? '); } if (empty($password)) { $password = $dialog->askHiddenResponse($output, 'What is your oTrance password? '); } // send login request to oTrance and save the login cookie $curl = curl_init('http://translations.piwik.org/public/index/login'); curl_setopt($curl, CURLOPT_POSTFIELDS, sprintf("user=%s&pass=%s&autologin=1", $username, $password)); curl_setopt($curl, CURLOPT_COOKIEJAR, $cookieFile); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_exec($curl); curl_close($curl); if (strpos(file_get_contents($cookieFile), 'oTranCe_autologin') !== false) { break; } $username = null; $password = null; @unlink($cookieFile); $output->writeln("Invalid oTrance credentials. Please try again..."); } // send request to create a new download package using the cookie file $createNewPackage = true; if ($input->isInteractive()) { $createNewPackage = $dialog->askConfirmation($output, 'Shall we create a new language pack? '); } if ($createNewPackage) { $curl = curl_init('http://translations.piwik.org/public/export/update.all'); curl_setopt($curl, CURLOPT_COOKIEFILE, $cookieFile); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_exec($curl); curl_close($curl); } // request download page to search for available packages $curl = curl_init('http://translations.piwik.org/public/downloads/'); curl_setopt($curl, CURLOPT_COOKIEFILE, $cookieFile); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($curl); curl_close($curl); preg_match_all('/language\\_pack\\-[0-9]{8}\\-[0-9]{6}\\.tar\\.gz/i', $response, $matches); if (empty($matches[0])) { $output->writeln("No packages found for download. Please try again."); return; } $downloadPackage = array_shift($matches[0]); $continueWithPackage = true; if ($input->isInteractive()) { $continueWithPackage = $dialog->askConfirmation($output, "Found language pack {$downloadPackage}. Proceed? "); } if (!$continueWithPackage) { $output->writeln('Aborted.'); return; } // download language pack $packageHandle = fopen(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'language_pack.tar.gz', 'w'); $curl = curl_init('http://translations.piwik.org/public/downloads/download/file/' . $downloadPackage); curl_setopt($curl, CURLOPT_COOKIEFILE, self::getDownloadPath() . DIRECTORY_SEPARATOR . 'cookie.txt'); curl_setopt($curl, CURLOPT_FILE, $packageHandle); curl_exec($curl); curl_close($curl); @unlink($cookieFile); $output->writeln("Extracting package..."); $unzipper = Unzip::factory('tar.gz', self::getDownloadPath() . DIRECTORY_SEPARATOR . 'language_pack.tar.gz'); $unzipper->extract(self::getDownloadPath()); if (!$input->getOption('keep-english')) { @unlink(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'en.php'); @unlink(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'en.json'); } @unlink(self::getDownloadPath() . DIRECTORY_SEPARATOR . 'language_pack.tar.gz'); $filesToConvert = _glob(self::getDownloadPath() . DIRECTORY_SEPARATOR . '*.php'); $output->writeln("Converting downloaded php files to json"); $progress = $this->getHelperSet()->get('progress'); $progress->start($output, count($filesToConvert)); foreach ($filesToConvert as $filename) { require_once $filename; $basename = explode(".", basename($filename)); $nested = array(); foreach ($translations as $key => $value) { list($plugin, $nkey) = explode("_", $key, 2); $nested[$plugin][$nkey] = $value; } $translations = $nested; $data = json_encode($translations, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); $newFile = sprintf("%s/%s.json", self::getDownloadPath(), $basename[0]); file_put_contents($newFile, $data); @unlink($filename); $progress->advance(); } $progress->finish(); $output->writeln("Finished fetching new language files from oTrance"); }