/** * Sets the filter based on the $_GET array. */ private function setFilter() { $this->filter['language'] = $this->getParameter('language', 'array') != '' ? $this->getParameter('language', 'array') : BL::getWorkingLanguage(); $this->filter['application'] = $this->getParameter('application'); $this->filter['module'] = $this->getParameter('module'); $this->filter['type'] = $this->getParameter('type', 'array'); $this->filter['name'] = $this->getParameter('name'); $this->filter['value'] = $this->getParameter('value'); $this->filterQuery = BackendLocaleModel::buildURLQueryByFilter($this->filter); }
/** * Execute the action */ public function execute() { parent::execute(); $isGod = BackendAuthentication::getUser()->isGod(); // get possible languages if ($isGod) { $possibleLanguages = array_unique(array_merge(BL::getWorkingLanguages(), BL::getInterfaceLanguages())); } else { $possibleLanguages = BL::getWorkingLanguages(); } // get parameters $language = \SpoonFilter::getPostValue('language', array_keys($possibleLanguages), null, 'string'); $module = \SpoonFilter::getPostValue('module', BackendModel::getModules(), null, 'string'); $name = \SpoonFilter::getPostValue('name', null, null, 'string'); $type = \SpoonFilter::getPostValue('type', BackendModel::getContainer()->get('database')->getEnumValues('locale', 'type'), null, 'string'); $application = \SpoonFilter::getPostValue('application', array('Backend', 'Frontend'), null, 'string'); $value = \SpoonFilter::getPostValue('value', null, null, 'string'); // validate values if (trim($value) == '' || $language == '' || $module == '' || $type == '' || $application == '' || $application == 'Frontend' && $module != 'Core') { $error = BL::err('InvalidValue'); } // in case this is a 'act' type, there are special rules concerning possible values if ($type == 'act' && !isset($error)) { if (urlencode($value) != CommonUri::getUrl($value)) { $error = BL::err('InvalidActionValue', $this->getModule()); } } // no error? if (!isset($error)) { // build item $item['language'] = $language; $item['module'] = $module; $item['name'] = $name; $item['type'] = $type; $item['application'] = $application; $item['value'] = $value; $item['edited_on'] = BackendModel::getUTCDate(); $item['user_id'] = BackendAuthentication::getUser()->getUserId(); // does the translation exist? if (BackendLocaleModel::existsByName($name, $type, $module, $language, $application)) { // add the id to the item $item['id'] = (int) BackendLocaleModel::getByName($name, $type, $module, $language, $application); // update in db BackendLocaleModel::update($item); } else { // insert in db BackendLocaleModel::insert($item); } // output OK $this->output(self::OK); } else { $this->output(self::ERROR, null, $error); } }
/** * Build items array and group all items by application, module, type and name. */ private function setItems() { $this->locale = array(); // get items $frontend = BackendLocaleModel::getNonExistingFrontendLocale($this->filter['language']); // group by application, module, type and name foreach ($frontend as $item) { $item['value'] = null; $this->locale[$item['application']][$item['module']][$item['type']][$item['name']][] = $item; } // no need to keep this around unset($frontend); // get items $backend = BackendLocaleModel::getNonExistingBackendLocale($this->filter['language']); // group by application, module, type and name foreach ($backend as $item) { $item['value'] = null; $this->locale[$item['application']][$item['module']][$item['type']][$item['name']][] = $item; } // no need to keep this around unset($backend); }
/** * @param string $localePath * @param bool $overwrite * @param OutputInterFace $output * @throws Exception */ private function importLocale($localePath, $overwrite, OutputInterface $output) { // Load the xml from the file $xmlData = @simplexml_load_file($localePath); // This is an invalid xml file if ($xmlData === false) { throw new Exception('Invalid locale.xml file.'); } // Everything ok, let's import the locale $results = BackendLocaleModel::importXML($xmlData, $overwrite, null, null, 1); if ($results['total'] < 0) { $output->writeln('<error>Something went wrong during import.</error>'); return; } if ($results['imported'] > 0) { $output->writeln('<comment>Imported ' . $results['imported'] . ' translations succesfully!</comment>'); return; } if ($results['imported'] == 0) { $output->writeln('<info>No locale was imported. Try adding the overwrite (-o) option.</info>'); return; } }
/** * Validate the form */ private function validateForm() { if ($this->frm->isSubmitted()) { $this->frm->cleanupFields(); // redefine fields $txtName = $this->frm->getField('name'); $txtValue = $this->frm->getField('value'); // name checks if ($txtName->isFilled(BL::err('FieldIsRequired'))) { // allowed regex (a-z and 0-9) if ($txtName->isValidAgainstRegexp('|^([a-z0-9])+$|i', BL::err('InvalidName'))) { // first letter does not seem to be a capital one if (!in_array(substr($txtName->getValue(), 0, 1), range('A', 'Z'))) { $txtName->setError(BL::err('InvalidName')); } else { // this name already exists in this language if (BackendLocaleModel::existsByName($txtName->getValue(), $this->frm->getField('type')->getValue(), $this->frm->getField('module')->getValue(), $this->frm->getField('language')->getValue(), $this->frm->getField('application')->getValue())) { $txtName->setError(BL::err('AlreadyExists')); } } } } // value checks if ($txtValue->isFilled(BL::err('FieldIsRequired'))) { // in case this is a 'act' type, there are special rules concerning possible values if ($this->frm->getField('type')->getValue() == 'act') { if (urlencode($txtValue->getValue()) != CommonUri::getUrl($txtValue->getValue())) { $txtValue->addError(BL::err('InvalidValue')); } } } // module should be 'core' for any other application than backend if ($this->frm->getField('application')->getValue() != 'Backend' && $this->frm->getField('module')->getValue() != 'Core') { $this->frm->getField('module')->setError(BL::err('ModuleHasToBeCore')); } if ($this->frm->isCorrect()) { // build item $item['user_id'] = BackendAuthentication::getUser()->getUserId(); $item['language'] = $this->frm->getField('language')->getValue(); $item['application'] = $this->frm->getField('application')->getValue(); $item['module'] = $this->frm->getField('module')->getValue(); $item['type'] = $this->frm->getField('type')->getValue(); $item['name'] = $this->frm->getField('name')->getValue(); $item['value'] = $this->frm->getField('value')->getValue(); $item['edited_on'] = BackendModel::getUTCDate(); // update item $item['id'] = BackendLocaleModel::insert($item); // trigger event BackendModel::triggerEvent($this->getModule(), 'after_add', array('item' => $item)); // everything is saved, so redirect to the overview $this->redirect(BackendModel::createURLForAction('Index', null, null, null) . '&report=added&var=' . urlencode($item['name']) . '&highlight=row-' . $item['id'] . $this->filterQuery); } } }
$baseFile = $options['f']; if (!file_exists($baseFile)) { throw new Exception('The given file(' . $baseFile . ') does not exist.'); } } // bootstrap Fork define('APPLICATION', 'Backend'); $kernel = new AppKernel('prod', false); $kernel->boot(); $kernel->defineForkConstants(); if (!defined('PATH_WWW')) { define('PATH_WWW', __DIR__ . '/..'); } $loader = new BackendInit($kernel); $loader->initialize('Backend'); $loader->passContainerToModels(); // create needed constants $container = $kernel->getContainer(); // Set the overwrite parameter $overwrite = isset($options['o']); // Set the basedir $baseDir = getcwd() . '/..'; // load the xml from the file $xmlData = @simplexml_load_file($baseFile); // this is an invalid xml file if ($xmlData === false) { throw new Exception('Invalid locale.xml file.'); } // Everything ok, let's install the locale BackendLocaleModel::importXML($xmlData, $overwrite, null, null, 1);
/** * Sets the filter based on the $_GET array. */ private function setFilter() { // if no language is selected, set the working language as the selected if ($this->getParameter('language', 'array') == null) { $_GET['language'] = array(BL::getWorkingLanguage()); $this->parameters['language'] = array(BL::getWorkingLanguage()); } // if no type is selected, set labels as the selected type if ($this->getParameter('type', 'array') == null) { $_GET['type'] = array('lbl'); $this->parameters['type'] = array('lbl', 'act', 'err', 'msg'); } // set filter $this->filter['application'] = $this->getParameter('application', 'string', null); $this->filter['module'] = $this->getParameter('module', 'string', null); $this->filter['type'] = $this->getParameter('type', 'array'); $this->filter['language'] = $this->getParameter('language', 'array'); $this->filter['name'] = $this->getParameter('name') == null ? '' : $this->getParameter('name'); $this->filter['value'] = $this->getParameter('value') == null ? '' : $this->getParameter('value'); // only allow values from our types checkboxes to be set $this->filter['type'] = array_filter($this->filter['type'], function ($type) { return array_key_exists($type, BackendLocaleModel::getTypesForMultiCheckbox()); }); // only allow languages from our language checkboxes to be set $isGod = $this->isGod; $this->filter['language'] = array_filter($this->filter['language'], function ($language) use($isGod) { return array_key_exists($language, BackendLocaleModel::getLanguagesForMultiCheckbox($isGod)); }); // build query for filter $this->filterQuery = BackendLocaleModel::buildURLQueryByFilter($this->filter); }
/** * Create locale cache files * * @param InstallationData $data */ protected function createLocaleFiles(InstallationData $data) { // all available languages $languages = array_unique(array_merge($data->getLanguages(), $data->getInterfaceLanguages())); // loop all the languages foreach ($languages as $language) { // get applications $applications = $this->container->get('database')->getColumn('SELECT DISTINCT application FROM locale WHERE language = ?', array((string) $language)); // loop applications foreach ((array) $applications as $application) { // build application locale cache BackendLocaleModel::buildCache($language, $application); } } }
/** * Validate the form */ private function validateForm() { if ($this->frm->isSubmitted()) { $this->frm->cleanupFields(); // redefine fields /** @var $fileFile \SpoonFormFile */ $fileFile = $this->frm->getField('file'); $chkOverwrite = $this->frm->getField('overwrite'); // name checks if ($fileFile->isFilled(BL::err('FieldIsRequired'))) { // only xml files allowed if ($fileFile->isAllowedExtension(array('xml'), sprintf(BL::getError('ExtensionNotAllowed'), 'xml'))) { // load xml $xml = @simplexml_load_file($fileFile->getTempFileName()); // invalid xml if ($xml === false) { $fileFile->addError(BL::getError('InvalidXML')); } } } if ($this->frm->isCorrect()) { // import $statistics = BackendLocaleModel::importXML($xml, $chkOverwrite->getValue()); // trigger event BackendModel::triggerEvent($this->getModule(), 'after_import', array('statistics' => $statistics)); // everything is imported, so redirect to the overview $this->redirect(BackendModel::createURLForAction('Index') . '&report=imported&var=' . ($statistics['imported'] . '/' . $statistics['total']) . $this->filterQuery); } } }
/** * Load the datagrids */ private function loadDataGrids() { /* * Frontend datagrid */ $this->dgFrontend = new BackendDataGridArray(BackendLocaleModel::getNonExistingFrontendLocale(BL::getWorkingLanguage())); // overrule default URL $this->dgFrontend->setURL(BackendModel::createURLForAction(null, null, null, array('offset' => '[offset]', 'order' => '[order]', 'sort' => '[sort]'), false)); // sorting columns $this->dgFrontend->setSortingColumns(array('language', 'application', 'module', 'type', 'name'), 'name'); // check if this action is allowed if (BackendAuthentication::isAllowedAction('Add')) { // set column URLs $this->dgFrontend->setColumnURL('name', BackendModel::createURLForAction('Add') . '&language=[language]&application=[application]&module=[module]&type=[type]&name=[name]'); } // set column functions $this->dgFrontend->setColumnFunction(array(__CLASS__, 'formatFilesList'), '[used_in]', 'used_in', true); // check if this action is allowed if (BackendAuthentication::isAllowedAction('SaveTranslation')) { // add columns $this->dgFrontend->addColumn('translation', null, null, null, BL::lbl('Add')); // add a class for the inline edit $this->dgFrontend->setColumnAttributes('translation', array('class' => 'translationValue')); // add attributes, so the inline editing has all the needed data $this->dgFrontend->setColumnAttributes('translation', array('data-id' => '{language: \'[language]\', application: \'[application]\', module: \'[module]\', name: \'[name]\', type: \'[type]\'}')); $this->dgFrontend->setColumnAttributes('translation', array('style' => 'width: 150px')); } // disable paging $this->dgFrontend->setPaging(false); /* * Backend datagrid */ $this->dgBackend = new BackendDataGridArray(BackendLocaleModel::getNonExistingBackendLocale(BL::getWorkingLanguage())); // overrule default URL $this->dgBackend->setURL(BackendModel::createURLForAction(null, null, null, array('offset' => '[offset]', 'order' => '[order]', 'sort' => '[sort]'), false)); // sorting columns $this->dgBackend->setSortingColumns(array('language', 'application', 'module', 'type', 'name'), 'name'); // check if this action is allowed if (BackendAuthentication::isAllowedAction('Add')) { // set column URLs $this->dgBackend->setColumnURL('name', BackendModel::createURLForAction('Add') . '&language=[language]&application=[application]&module=[module]&type=[type]&name=[name]'); } // set column functions $this->dgBackend->setColumnFunction(array(__CLASS__, 'formatFilesList'), '[used_in]', 'used_in', true); // check if this action is allowed if (BackendAuthentication::isAllowedAction('SaveTranslation')) { // add columns $this->dgBackend->addColumn('translation', null, null, null, BL::lbl('Add')); // add a class for the inline edit $this->dgBackend->setColumnAttributes('translation', array('class' => 'translationValue')); // add attributes, so the inline editing has all the needed data $this->dgBackend->setColumnAttributes('translation', array('data-id' => '{language: \'[language]\', application: \'[application]\', module: \'[module]\', name: \'[name]\', type: \'[type]\'}')); $this->dgBackend->setColumnAttributes('translation', array('style' => 'width: 150px')); } // disable paging $this->dgBackend->setPaging(false); }
/** * Create the XML based on the locale items. */ private function createXML() { $charset = BackendModel::getContainer()->getParameter('kernel.charset'); // create XML $xmlOutput = BackendLocaleModel::createXMLForExport($this->locale); // xml headers header('Content-Disposition: attachment; filename="locale_' . BackendModel::getUTCDate('d-m-Y') . '.xml"'); header('Content-Type: application/octet-stream;charset=' . $charset); header('Content-Length: ' . strlen($xmlOutput)); // output XML echo $xmlOutput; exit; }
/** * Imports the locale XML file * * @param string $filename The full path for the XML-file. * @param bool $overwriteConflicts Should we overwrite when there is a conflict? */ protected function importLocale($filename, $overwriteConflicts = false) { $filename = (string) $filename; $overwriteConflicts = (bool) $overwriteConflicts; // load the file content and execute it $content = trim(file_get_contents($filename)); // file actually has content if (!empty($content)) { // load xml $xml = @simplexml_load_string($content); // import if it's valid xml if ($xml !== false) { // import locale BackendLocaleModel::importXML($xml, $overwriteConflicts, $this->getLanguages(), $this->getInterfaceLanguages(), $this->getDefaultUserID(), gmdate('Y-m-d H:i:s')); } } }
/** * Set locale * It will require the correct file and init the needed vars * * @param string $language The language to load. */ public static function setLocale($language) { $language = (string) $language; // validate file, generate it if needed if (!is_file(BACKEND_CACHE_PATH . '/Locale/en.json')) { BackendLocaleModel::buildCache('en', APPLICATION); } if (!is_file(BACKEND_CACHE_PATH . '/Locale/' . $language . '.json')) { // if you use the language in the console act like it is in the backend BackendLocaleModel::buildCache($language, defined('APPLICATION') && APPLICATION === 'Console' ? 'Backend' : APPLICATION); } // store self::$currentInterfaceLanguage = $language; // attempt to set a cookie try { // Needed to make it possible to use the backend language in the console. if (defined('APPLICATION') && APPLICATION !== 'Console') { CommonCookie::set('interface_language', $language); } } catch (\SpoonCookieException $e) { // settings cookies isn't allowed, because this isn't a real problem we ignore the exception } // set English translations, they'll be the fallback $translations = json_decode(file_get_contents(BACKEND_CACHE_PATH . '/Locale/en.json'), true); self::$err = (array) $translations['err']; self::$lbl = (array) $translations['lbl']; self::$msg = (array) $translations['msg']; // overwrite with the requested language's translations $translations = json_decode(file_get_contents(BACKEND_CACHE_PATH . '/Locale/' . $language . '.json'), true); $err = (array) $translations['err']; $lbl = (array) $translations['lbl']; $msg = (array) $translations['msg']; foreach ($err as $module => $translations) { if (!isset(self::$err[$module])) { self::$err[$module] = array(); } self::$err[$module] = array_merge(self::$err[$module], $translations); } foreach ($lbl as $module => $translations) { if (!isset(self::$lbl[$module])) { self::$lbl[$module] = array(); } self::$lbl[$module] = array_merge(self::$lbl[$module], $translations); } foreach ($msg as $module => $translations) { if (!isset(self::$msg[$module])) { self::$msg[$module] = array(); } self::$msg[$module] = array_merge(self::$msg[$module], $translations); } }
/** * Create the XML based on the locale items. */ public function getContent() { $charset = BackendModel::getContainer()->getParameter('kernel.charset'); // create XML $xmlOutput = BackendLocaleModel::createXMLForExport($this->locale); return new Response($xmlOutput, Response::HTTP_OK, ['Content-Disposition' => 'attachment; filename="locale_' . BackendModel::getUTCDate('d-m-Y') . '.xml"', 'Content-Type' => 'application/octet-stream;charset=' . $charset, 'Content-Length' => '' . mb_strlen($xmlOutput)]); }