diff --git a/src/mibew/install/dbinfo.php b/src/mibew/install/dbinfo.php
index 59d8cb0f..8e71aeb3 100644
--- a/src/mibew/install/dbinfo.php
+++ b/src/mibew/install/dbinfo.php
@@ -125,6 +125,16 @@ $dbtables = array(
"translation" => "text",
),
+ // Contains locales info
+ "${mysqlprefix}locale" => array(
+ // Artificial primary key
+ "localeid" => "int NOT NULL auto_increment PRIMARY KEY",
+ // Locale code
+ "code" => "varchar(5) NOT NULL",
+ // Indicates if a locale is enabled or not.
+ "enabled" => "tinyint NOT NULL DEFAULT 0",
+ ),
+
// Contains localized mail templates
"${mysqlprefix}mailtemplate" => array(
// Artificial primary key
diff --git a/src/mibew/install/index.php b/src/mibew/install/index.php
index 4ff3b475..533ec5dc 100644
--- a/src/mibew/install/index.php
+++ b/src/mibew/install/index.php
@@ -402,6 +402,27 @@ function add_mail_templates($link){
}
}
+function add_locales($link)
+{
+ global $mysqlprefix;
+
+ $localesresult = mysql_query("select code from ${mysqlprefix}locale", $link);
+ $existlocales = array();
+ for ($i = 0; $i < mysql_num_rows($localesresult); $i++) {
+ $existlocales[] = mysql_result($localesresult, $i, 'code');
+ }
+ $locales = discover_locales();
+ foreach ($locales as $locale) {
+ if (in_array($locale, $existlocales)) {
+ // Do not add locales twice.
+ continue;
+ }
+ $query = "insert into ${mysqlprefix}locale (code, enabled) values ('"
+ . mysql_real_escape_string($locale, $link) . "', 1)";
+ mysql_query($query, $link);
+ }
+}
+
function get_yml_file_content($file)
{
$yaml = new \Symfony\Component\Yaml\Parser();
@@ -443,6 +464,7 @@ function check_status()
return;
}
+ add_locales($link);
add_canned_messages($link);
add_mail_templates($link);
diff --git a/src/mibew/libs/classes/Mibew/Controller/Localization/AbstractController.php b/src/mibew/libs/classes/Mibew/Controller/Localization/AbstractController.php
new file mode 100644
index 00000000..f2e1f386
--- /dev/null
+++ b/src/mibew/libs/classes/Mibew/Controller/Localization/AbstractController.php
@@ -0,0 +1,50 @@
+attributes->get('_route');
+
+ $tabs[getlocal('page_localization.tab.translation')] = ($route != 'translations')
+ ? $this->generateUrl('translations')
+ : '';
+
+ $tabs[getlocal('page_localization.tab.locale')] = ($route != 'locales')
+ ? $this->generateUrl('locales')
+ : '';
+
+ return $tabs;
+ }
+}
diff --git a/src/mibew/libs/classes/Mibew/Controller/Localization/LocaleController.php b/src/mibew/libs/classes/Mibew/Controller/Localization/LocaleController.php
new file mode 100644
index 00000000..1381af62
--- /dev/null
+++ b/src/mibew/libs/classes/Mibew/Controller/Localization/LocaleController.php
@@ -0,0 +1,134 @@
+getOperator();
+ $page = array(
+ // Use errors list stored in the request. We need to do so to have
+ // an ability to pass the request from other actions.
+ 'errors' => $request->attributes->get('errors', array()),
+ );
+
+ $fs_locales = discover_locales();
+ $locale_names = get_locale_names();
+ $available_locales = get_available_locales();
+
+ $locales_list = array();
+ foreach($fs_locales as $locale) {
+ $locales_list[] = array(
+ 'code' => $locale,
+ 'name' => (isset($locale_names[$locale]) ? $locale_names[$locale] : $locale),
+ 'isDisabled' => !in_array($locale, $available_locales),
+ );
+ }
+
+ $page['localesList'] = $locales_list;
+ $page['title'] = getlocal('page_locales.title');
+ $page['menuid'] = 'translation';
+ $page = array_merge($page, prepare_menu($operator));
+ $page['tabs'] = $this->buildTabs($request);
+
+ return $this->render('locales', $page);
+ }
+
+ /**
+ * Enables a locale.
+ *
+ * @param Request $request Incoming request.
+ * @return \Symfony\Component\HttpFoundation\Response A response object.
+ * @throws NotFoundException If the locale which should be enabled is not
+ * found.
+ */
+ public function enableAction(Request $request)
+ {
+ csrf_check_token($request);
+
+ $locale = $request->attributes->get('locale');
+
+ // Check if locale exists.
+ if (!in_array($locale, discover_locales())) {
+ throw new NotFoundException();
+ }
+
+ // Enable locale if it is needed and redirect the operator to the
+ // locales page.
+ if (!in_array($locale, get_available_locales())) {
+ enable_locale($locale);
+ }
+
+ return $this->redirect($this->generateUrl('locales'));
+ }
+
+ /**
+ * Disables a locale.
+ *
+ * @param Request $request Incoming request.
+ * @return \Symfony\Component\HttpFoundation\Response A response object.
+ * @throws NotFoundException If the locale which should be disabled is not
+ * found.
+ */
+ public function disableAction(Request $request)
+ {
+ csrf_check_token($request);
+
+ $locale = $request->attributes->get('locale');
+ $errors = array();
+
+ // Check if locale exists.
+ if (!in_array($locale, discover_locales())) {
+ throw new NotFoundException();
+ }
+
+ // Disable locale if we can do so.
+ $available_locales = get_available_locales();
+ if (in_array($locale, $available_locales)) {
+ if (count($available_locales) > 1) {
+ disable_locale($locale);
+ } else {
+ $errors[] = getlocal('page_locales.cannot_disable_all');
+ }
+ }
+
+ if (count($errors) != 0) {
+ // Something went wrong. Re-render locales list.
+ $request->attributes->set('errors', $errors);
+
+ return $this->indexAction($request);
+ }
+
+ return $this->redirect($this->generateUrl('locales'));
+ }
+}
diff --git a/src/mibew/libs/classes/Mibew/Controller/TranslationController.php b/src/mibew/libs/classes/Mibew/Controller/Localization/TranslationController.php
similarity index 98%
rename from src/mibew/libs/classes/Mibew/Controller/TranslationController.php
rename to src/mibew/libs/classes/Mibew/Controller/Localization/TranslationController.php
index 39c309f0..73a4df50 100644
--- a/src/mibew/libs/classes/Mibew/Controller/TranslationController.php
+++ b/src/mibew/libs/classes/Mibew/Controller/Localization/TranslationController.php
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-namespace Mibew\Controller;
+namespace Mibew\Controller\Localization;
use Symfony\Component\HttpFoundation\Request;
@@ -115,6 +115,7 @@ class TranslationController extends AbstractController
$page['title'] = getlocal('page.translate.title');
$page['menuid'] = 'translation';
$page = array_merge($page, prepare_menu($operator));
+ $page['tabs'] = $this->buildTabs($request);
return $this->render('translations', $page);
}
diff --git a/src/mibew/libs/common/locale.php b/src/mibew/libs/common/locale.php
index 2d4d0b91..85267998 100644
--- a/src/mibew/libs/common/locale.php
+++ b/src/mibew/libs/common/locale.php
@@ -63,17 +63,51 @@ function locale_pattern_check($locale)
function get_available_locales()
{
- $list = array();
- $folder = MIBEW_FS_ROOT . '/locales';
- if ($handle = opendir($folder)) {
- while (false !== ($file = readdir($handle))) {
- if (locale_pattern_check($file) && is_dir("$folder/$file")) {
- $list[] = $file;
- }
- }
- closedir($handle);
+ if (installation_in_progress()) {
+ // We cannot get info from database during installation, thus we only
+ // can use discovered locales as available locales.
+ // TODO: Remove this workaround after installation will be rewritten.
+ return discover_locales();
+ }
+
+ // Get list of enabled locales from the database.
+ $rows = Database::getInstance()->query(
+ "SELECT code FROM {locale} WHERE enabled = 1",
+ array(),
+ array('return_rows' => Database::RETURN_ALL_ROWS)
+ );
+ $enabled_locales = array();
+ foreach ($rows as $row) {
+ $enabled_locales[] = $row['code'];
+ }
+
+ $fs_locales = discover_locales();
+
+ return array_intersect($fs_locales, $enabled_locales);
+}
+
+/**
+ * Returns list of all locales that are present in the file system.
+ *
+ * @return array List of locales codes.
+ */
+function discover_locales()
+{
+ static $list = null;
+
+ if (is_null($list)) {
+ $list = array();
+ $folder = MIBEW_FS_ROOT . '/locales';
+ if ($handle = opendir($folder)) {
+ while (false !== ($file = readdir($handle))) {
+ if (locale_pattern_check($file) && is_dir("$folder/$file")) {
+ $list[] = $file;
+ }
+ }
+ closedir($handle);
+ }
+ sort($list);
}
- sort($list);
return $list;
}
@@ -836,3 +870,59 @@ function save_message($locale, $key, $value)
);
}
}
+
+/**
+ * Enables specified locale.
+ *
+ * @param string $locale Locale code according to RFC 5646.
+ */
+function enable_locale($locale)
+{
+ $db = Database::getInstance();
+
+ // Check if the locale exists in the database
+ list($count) = $db->query(
+ "SELECT COUNT(*) FROM {locale} WHERE code = :code",
+ array(':code' => $locale),
+ array(
+ 'return_rows' => Database::RETURN_ONE_ROW,
+ 'fetch_type' => Database::FETCH_NUM,
+ )
+ );
+
+ if ($count == 0) {
+ // The locale does not exist in the database. Create it.
+ $db->query(
+ "INSERT INTO {locale} (code, enabled) VALUES (:code, :enabled)",
+ array(
+ ':code' => $locale,
+ ':enabled' => 1,
+ )
+ );
+ } else {
+ // The locale exists in the database. Update it.
+ $db->query(
+ "UPDATE {locale} SET enabled = :enabled WHERE code = :code",
+ array(
+ ':enabled' => 1,
+ ':code' => $locale,
+ )
+ );
+ }
+}
+
+/**
+ * Disables specified locale.
+ *
+ * @param string $locale Locale code according to RFC 5646.
+ */
+function disable_locale($locale)
+{
+ Database::getInstance()->query(
+ "UPDATE {locale} SET enabled = :enabled WHERE code = :code",
+ array(
+ ':enabled' => 0,
+ ':code' => $locale,
+ )
+ );
+}
diff --git a/src/mibew/libs/routing.yml b/src/mibew/libs/routing.yml
index 6dc0f3ee..b81f0d80 100644
--- a/src/mibew/libs/routing.yml
+++ b/src/mibew/libs/routing.yml
@@ -323,6 +323,32 @@ invite:
_controller: Mibew\Controller\InvitationController::inviteAction
_access_check: Mibew\AccessControl\Check\LoggedInCheck
+## Locales
+locale_disable:
+ path: /operator/locale/{locale}/disable
+ defaults:
+ _controller: Mibew\Controller\Localization\LocaleController::disableAction
+ _access_check: Mibew\AccessControl\Check\PermissionsCheck
+ _access_permissions: [CAN_ADMINISTRATE]
+ requirements:
+ locale: "[a-z\-]{2,5}"
+
+locale_enable:
+ path: /operator/locale/{locale}/enable
+ defaults:
+ _controller: Mibew\Controller\Localization\LocaleController::enableAction
+ _access_check: Mibew\AccessControl\Check\PermissionsCheck
+ _access_permissions: [CAN_ADMINISTRATE]
+ requirements:
+ locale: "[a-z\-]{2,5}"
+
+locales:
+ path: /operator/locale
+ defaults:
+ _controller: Mibew\Controller\Localization\LocaleController::indexAction
+ _access_check: Mibew\AccessControl\Check\PermissionsCheck
+ _access_permissions: [CAN_ADMINISTRATE]
+
## Log in
login:
path: /operator/login
@@ -588,7 +614,7 @@ style_preview:
translation_edit:
path: /operator/translation/{string_id}/edit
defaults:
- _controller: Mibew\Controller\TranslationController::showEditFormAction
+ _controller: Mibew\Controller\Localization\TranslationController::showEditFormAction
_access_check: Mibew\AccessControl\Check\PermissionsCheck
_access_permissions: [CAN_ADMINISTRATE]
requirements:
@@ -598,7 +624,7 @@ translation_edit:
translation_edit_save:
path: /operator/translation/{string_id}/edit
defaults:
- _controller: Mibew\Controller\TranslationController::submitEditFormAction
+ _controller: Mibew\Controller\Localization\TranslationController::submitEditFormAction
_access_check: Mibew\AccessControl\Check\PermissionsCheck
_access_permissions: [CAN_ADMINISTRATE]
requirements:
@@ -608,7 +634,7 @@ translation_edit_save:
translations:
path: /operator/translation
defaults:
- _controller: Mibew\Controller\TranslationController::indexAction
+ _controller: Mibew\Controller\Localization\TranslationController::indexAction
_access_check: Mibew\AccessControl\Check\PermissionsCheck
_access_permissions: [CAN_ADMINISTRATE]
diff --git a/src/mibew/locales/en/translation.po b/src/mibew/locales/en/translation.po
index f9f08ceb..4cea7308 100644
--- a/src/mibew/locales/en/translation.po
+++ b/src/mibew/locales/en/translation.po
@@ -679,7 +679,7 @@ msgstr "Your translation is saved."
msgid "page.translate.one"
msgstr "Enter your translation."
msgid "page.translate.title"
-msgstr "Localization wizard"
+msgstr "Translations"
msgid "page_agent.cannot_modify"
msgstr "You are not allowed to change this person's profile."
msgid "page_agent.clear_avatar"
@@ -790,6 +790,26 @@ msgid "page_group.tab.main"
msgstr "General"
msgid "page_group.tab.members"
msgstr "Members"
+msgid "page_locales.actions"
+msgstr "Modify"
+msgid "page_locales.cannot_disable_all"
+msgstr "You cannot disable all locales."
+msgid "page_locales.code"
+msgstr "Code"
+msgid "page_locales.disable.locale"
+msgstr "disable"
+msgid "page_locales.enable.locale"
+msgstr "enable"
+msgid "page_locales.intro"
+msgstr "On this page you can configure locales which are used in the system"
+msgid "page_locales.name"
+msgstr "Name"
+msgid "page_locales.title"
+msgstr "Locales"
+msgid "page_localization.tab.locale"
+msgstr "Locales"
+msgid "page_localization.tab.translation"
+msgstr "Translations"
msgid "page_login.error"
msgstr "Entered login/password is incorrect"
msgid "page_login.operator.disabled"
diff --git a/src/mibew/styles/pages/default/templates_src/server_side/locales.handlebars b/src/mibew/styles/pages/default/templates_src/server_side/locales.handlebars
new file mode 100644
index 00000000..35068c1d
--- /dev/null
+++ b/src/mibew/styles/pages/default/templates_src/server_side/locales.handlebars
@@ -0,0 +1,64 @@
+{{#extends "_layout"}}
+ {{#override "menu"}}{{> _menu}}{{/override}}
+
+ {{#override "content"}}
+ {{l10n "page_locales.intro"}}
+
+
+
+
+ {{> _errors}}
+
+ {{> _tabs}}
+
+
{{l10n "page_locales.code"}} | +{{l10n "page_locales.name"}} | +{{l10n "page_locales.actions"}} | +
---|---|---|
+ {{code}} + | + ++ {{name}} + | + ++ {{#if isDisabled}} + {{l10n "page_locales.enable.locale"}} + {{else}} + {{l10n "page_locales.disable.locale"}} + {{/if}} + | +