/** * Execute the action * * @return void */ public function execute() { // call parent, this will probably add some general CSS/JS or other required files parent::execute(); // user is god? $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(false), null, 'string'); $name = SpoonFilter::getPostValue('name', null, null, 'string'); $type = SpoonFilter::getPostValue('type', BackendModel::getDB()->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 (!SpoonFilter::isValidAgainstRegexp('|^([a-z0-9\\-\\_])+$|', $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); } }
/** * Import a locale XML file. * * @param SimpleXMLElement $xml The locale XML. * @param bool[optional] $overwriteConflicts Should we overwrite when there is a conflict? * @param array[optional] $frontendLanguages The frontend languages to install locale for. * @param array[optional] $backendLanguages The backend languages to install locale for. * @param int[optional] $userId Id of the user these translations should be inserted for. * @param int[optional] $date The date the translation has been inserted. * @return array The import statistics */ public static function importXML(SimpleXMLElement $xml, $overwriteConflicts = false, $frontendLanguages = null, $backendLanguages = null, $userId = null, $date = null) { $overwriteConflicts = (bool) $overwriteConflicts; $statistics = array('total' => 0, 'imported' => 0); // set defaults if necessary // we can't simply use these right away, because this function is also calles by the installer, which does not have Backend-functions if ($frontendLanguages === null) { $frontendLanguages = array_keys(BL::getWorkingLanguages()); } if ($backendLanguages === null) { $backendLanguages = array_keys(BL::getInterfaceLanguages()); } if ($userId === null) { $userId = BackendAuthentication::getUser()->getUserId(); } if ($date === null) { $date = BackendModel::getUTCDate(); } // get database instance (don't use BackendModel::getDB() here because this function will also be called during install) $db = Spoon::get('database'); // possible values $possibleApplications = array('frontend', 'backend'); $possibleModules = (array) $db->getColumn('SELECT m.name FROM modules AS m'); // types $typesShort = (array) $db->getEnumValues('locale', 'type'); foreach ($typesShort as $type) { $possibleTypes[$type] = self::getTypeName($type); } // install English translations anyhow, they're fallback $possibleLanguages = array('frontend' => array_unique(array_merge(array('en'), $frontendLanguages)), 'backend' => array_unique(array_merge(array('en'), $backendLanguages))); // current locale items (used to check for conflicts) $currentLocale = (array) $db->getColumn('SELECT CONCAT(application, module, type, language, name) FROM locale'); // applications foreach ($xml as $application => $modules) { // application does not exist if (!in_array($application, $possibleApplications)) { continue; } // modules foreach ($modules as $module => $items) { // module does not exist if (!in_array($module, $possibleModules)) { continue; } // items foreach ($items as $item) { // attributes $attributes = $item->attributes(); $type = SpoonFilter::getValue($attributes['type'], $possibleTypes, ''); $name = SpoonFilter::getValue($attributes['name'], null, ''); // missing attributes if ($type == '' || $name == '') { continue; } // real type (shortened) $type = array_search($type, $possibleTypes); // translations foreach ($item->translation as $translation) { // statistics $statistics['total']++; // attributes $attributes = $translation->attributes(); $language = SpoonFilter::getValue($attributes['language'], $possibleLanguages[$application], ''); // language does not exist if ($language == '') { continue; } // the actual translation $translation = (string) $translation; // locale item $locale['user_id'] = $userId; $locale['language'] = $language; $locale['application'] = $application; $locale['module'] = $module; $locale['type'] = $type; $locale['name'] = $name; $locale['value'] = $translation; $locale['edited_on'] = $date; // found a conflict, overwrite it with the imported translation if ($overwriteConflicts && in_array($application . $module . $type . $language . $name, $currentLocale)) { // statistics $statistics['imported']++; // overwrite $db->update('locale', $locale, 'application = ? AND module = ? AND type = ? AND language = ? AND name = ?', array($application, $module, $type, $language, $name)); } elseif (!in_array($application . $module . $type . $language . $name, $currentLocale)) { // statistics $statistics['imported']++; // insert $db->insert('locale', $locale); } } } } } // rebuild cache foreach ($possibleApplications as $application) { foreach ($possibleLanguages[$application] as $language) { self::buildCache($language, $application); } } return $statistics; }
/** * Install a module. * * @param string $module The name of the module to be installed. * @param array $information Warnings from the upload of the module. */ public static function installModule($module, array $warnings = array()) { // we need the installer require_once BACKEND_CORE_PATH . '/installer/installer.php'; require_once BACKEND_MODULES_PATH . '/' . $module . '/installer/installer.php'; // installer class name $class = SpoonFilter::toCamelCase($module) . 'Installer'; // possible variables available for the module installers $variables = array(); // run installer $installer = new $class(BackendModel::getDB(true), BL::getActiveLanguages(), array_keys(BL::getInterfaceLanguages()), false, $variables); // execute installation $installer->install(); // add the warnings foreach ($warnings as $warning) { $installer->addWarning($warning); } // save the warnings in session for later use if ($installer->getWarnings()) { $warnings = SpoonSession::exists('installer_warnings') ? SpoonSession::get('installer_warnings') : array(); $warnings = array_merge($warnings, array('module' => $module, 'warnings' => $installer->getWarnings())); SpoonSession::set('installer_warnings', $warnings); } // clear the cache so locale (and so much more) gets rebuilt self::clearCache(); }
/** * Import a locale XML file. * * @return array Import statistics. * @param SimpleXMLElement $xml The locale XML. * @param bool[optional] $overwriteConflicts Should we overwrite when there is a conflict? */ public static function importXML(SimpleXMLElement $xml, $overwriteConflicts = false) { // init $overwriteConflicts = (bool) $overwriteConflicts; $statistics = array('total' => 0, 'imported' => 0); // possible values $possibleApplications = array('frontend', 'backend'); $possibleModules = BackendModel::getModules(false); $possibleLanguages = array('frontend' => array_keys(BL::getWorkingLanguages()), 'backend' => array_keys(BL::getInterfaceLanguages())); $possibleTypes = array(); // types $typesShort = (array) BackendModel::getDB()->getEnumValues('locale', 'type'); foreach ($typesShort as $type) { $possibleTypes[$type] = self::getTypeName($type); } // current locale items (used to check for conflicts) $currentLocale = (array) BackendModel::getDB()->getColumn('SELECT CONCAT(application, module, type, language, name) FROM locale'); // applications foreach ($xml as $application => $modules) { // application does not exist if (!in_array($application, $possibleApplications)) { continue; } // modules foreach ($modules as $module => $items) { // module does not exist if (!in_array($module, $possibleModules)) { continue; } // items foreach ($items as $item) { // attributes $attributes = $item->attributes(); $type = SpoonFilter::getValue($attributes['type'], $possibleTypes, ''); $name = SpoonFilter::getValue($attributes['name'], null, ''); // missing attributes if ($type == '' || $name == '') { continue; } // real type (shortened) $type = array_search($type, $possibleTypes); // translations foreach ($item->translation as $translation) { // statistics $statistics['total']++; // attributes $attributes = $translation->attributes(); $language = SpoonFilter::getValue($attributes['language'], $possibleLanguages[$application], ''); // language does not exist if ($language == '') { continue; } // the actual translation $translation = (string) $translation; // locale item $locale['user_id'] = BackendAuthentication::getUser()->getUserId(); $locale['language'] = $language; $locale['application'] = $application; $locale['module'] = $module; $locale['type'] = $type; $locale['name'] = $name; $locale['value'] = $translation; $locale['edited_on'] = BackendModel::getUTCDate(); // found a conflict, overwrite it with the imported translation if ($overwriteConflicts && in_array($application . $module . $type . $language . $name, $currentLocale)) { // statistics $statistics['imported']++; // overwrite BackendModel::getDB(true)->update('locale', $locale, 'application = ? AND module = ? AND type = ? AND language = ? AND name = ?', array($application, $module, $type, $language, $name)); } elseif (!in_array($application . $module . $type . $language . $name, $currentLocale)) { // statistics $statistics['imported']++; // insert BackendModel::getDB(true)->insert('locale', $locale); } } } } } // rebuild cache foreach ($possibleApplications as $application) { foreach ($possibleLanguages[$application] as $language) { self::buildCache($language, $application); } } // return statistics return $statistics; }