Index: core/admin_templates/languages/email_message_edit.tpl =================================================================== --- core/admin_templates/languages/email_message_edit.tpl (revision 13140) +++ core/admin_templates/languages/email_message_edit.tpl (working copy) @@ -45,8 +45,8 @@ - - + + @@ -56,8 +56,8 @@ - - + + Index: core/admin_templates/languages/phrase_edit.tpl =================================================================== --- core/admin_templates/languages/phrase_edit.tpl (revision 13128) +++ core/admin_templates/languages/phrase_edit.tpl (working copy) @@ -53,6 +53,10 @@ + + + + @@ -63,29 +67,21 @@ - - - - - + - - - - - + Index: core/admin_templates/languages/phrase_list.tpl =================================================================== --- core/admin_templates/languages/phrase_list.tpl (revision 13128) +++ core/admin_templates/languages/phrase_list.tpl (working copy) @@ -1,5 +1,5 @@ - + @@ -10,20 +10,14 @@ //do not rename - this function is used in default grid for double click! function edit() { - set_hidden_field('remove_specials[phrases.st]', 1); - std_edit_item('phrases.st', 'languages/phrase_edit'); + Application.SetVar('m_lang', ''); + std_edit_item('phrases', 'languages/phrase_edit'); } var a_toolbar = new ToolBar(); a_toolbar.AddButton( new ToolBarButton('new_item', '::', function() { - var $phrase = prompt('Enter Phrase name:', ''); - if (!$phrase) { - return ; - } - - $url_mask = ''; - direct_edit('phrases', $url_mask.replace('#PHRASE_NAME#', $phrase)); + std_precreate_item('phrases', 'languages/phrase_edit'); } ) ); @@ -31,7 +25,7 @@ a_toolbar.AddButton( new ToolBarButton('edit', '::', edit) ); a_toolbar.AddButton( new ToolBarButton('delete', '', function() { - std_delete_items('phrases.st') + std_delete_items('phrases') } ) ); @@ -45,14 +39,14 @@ a_toolbar.Render(); - +
- + \ No newline at end of file Index: core/admin_templates/regional/email_messages_edit.tpl =================================================================== --- core/admin_templates/regional/email_messages_edit.tpl (revision 13140) +++ core/admin_templates/regional/email_messages_edit.tpl (working copy) @@ -30,6 +30,7 @@ +
Index: core/admin_templates/regional/languages_edit_email_events.tpl =================================================================== --- core/admin_templates/regional/languages_edit_email_events.tpl (revision 13128) +++ core/admin_templates/regional/languages_edit_email_events.tpl (working copy) @@ -12,6 +12,7 @@ function edit() { + Application.SetVar('regional', 1); std_edit_temp_item('emailevents', 'regional/email_messages_edit'); } Index: core/admin_templates/regional/languages_edit_phrases.tpl =================================================================== --- core/admin_templates/regional/languages_edit_phrases.tpl (revision 13128) +++ core/admin_templates/regional/languages_edit_phrases.tpl (working copy) @@ -12,6 +12,7 @@ function edit() { + Application.SetVar('regional', 1); std_edit_temp_item('phrases', 'regional/phrases_edit'); } @@ -40,6 +41,7 @@ a_toolbar.AddButton( new ToolBarButton('new_item', '::', function() { + Application.SetVar('regional', 1); std_new_item('phrases', 'regional/phrases_edit') } ) ); Index: core/admin_templates/regional/phrases_edit.tpl =================================================================== --- core/admin_templates/regional/phrases_edit.tpl (revision 13128) +++ core/admin_templates/regional/phrases_edit.tpl (working copy) @@ -62,30 +62,25 @@ + - - - - + + - + - - - - - + Index: core/install/install_data.sql =================================================================== --- core/install/install_data.sql (revision 13140) +++ core/install/install_data.sql (working copy) @@ -239,38 +239,38 @@ INSERT INTO ItemTypes VALUES (1, 'In-Portal', 'c', 'Category', 'Name', 'CreatedById', NULL, NULL, 'la_ItemTab_Categories', 1, 'admin/category/addcategory.php', 'clsCategory', 'Category'); INSERT INTO ItemTypes VALUES (6, 'In-Portal', 'u', 'PortalUser', 'Login', 'PortalUserId', NULL, NULL, '', 0, '', 'clsPortalUser', 'User'); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.ADD', NULL, 1, 0, NULL, 'Core:Users', 'Add User', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.ADD', NULL, 1, 1, NULL, 'Core:Users', 'Add User', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.APPROVE', NULL, 1, 0, NULL, 'Core:Users', 'Approve User', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.APPROVE', NULL, 1, 1, NULL, 'Core:Users', 'Approve User', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.VALIDATE', NULL, 1, 0, NULL, 'Core:Users', 'Validate User', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.VALIDATE', NULL, 1, 1, NULL, 'Core:Users', 'Validate User', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.DENY', NULL, 1, 0, NULL, 'Core:Users', 'Deny User', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.DENY', NULL, 1, 1, NULL, 'Core:Users', 'Deny User', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.PSWD', NULL, 1, 1, NULL, 'Core:Users', 'Forgot Password', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.PSWD', NULL, 1, 0, NULL, 'Core:Users', 'Forgot Password', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.ADD.PENDING', NULL, 1, 0, NULL, 'Core:Users', 'Add Pending User', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.ADD.PENDING', NULL, 1, 1, NULL, 'Core:Users', 'Add Pending User', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD', NULL, 1, 0, NULL, 'Core:Category', 'Add Category', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD.PENDING', NULL, 1, 0, NULL, 'Core:Category', 'Add Pending Category', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD.PENDING', NULL, 1, 1, NULL, 'Core:Category', 'Add Pending Category', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD', NULL, 1, 1, NULL, 'Core:Category', 'Add Category', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'CATEGORY.APPROVE', NULL, 1, 0, NULL, 'Core:Category', 'Approve Category', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'CATEGORY.DENY', NULL, 1, 0, NULL, 'Core:Category', 'Deny Category', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.SUBSCRIBE', NULL, 1, 0, NULL, 'Core:Users', 'User subscribed', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.SUBSCRIBE', NULL, 1, 1, NULL, 'Core:Users', 'User subscribed', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.UNSUBSCRIBE', NULL, 1, 0, NULL, 'Core:Users', 'User unsubscribed', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.UNSUBSCRIBE', NULL, 1, 1, NULL, 'Core:Users', 'User unsubscribed', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.SUGGEST', NULL, 1, 0, NULL, 'Core:Users', 'Suggest to a friend', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.SUGGEST', NULL, 1, 1, NULL, 'Core:Users', 'Suggest to a friend', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.PSWDC', NULL, 1, 0, NULL, 'Core:Users', 'Password Confirmation', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRED', NULL, 1, 0, NULL, 'Core:Users', 'Membership expired', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRED', NULL, 1, 0, NULL, 'Core:Users', 'Membership expired', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRATION.NOTICE', NULL, 1, 0, NULL, 'Core:Users', 'Membership expiration notice', 0); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRATION.NOTICE', NULL, 1, 0, NULL, 'Core:Users', 'Membership expiration notice', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'COMMON.FOOTER', NULL, 1, 0, NULL, 'Core', 'Common Footer Template', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'FORM.SUBMITTED', NULL, 1, 0, NULL, 'Core:Category', 'This e-mail is sent to a user after filling in the Contact Us form', 1); -INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, l1_Description, Type) VALUES(DEFAULT, 'FORM.SUBMITTED', NULL, 1, 0, NULL, 'Core:Category', 'This e-mail is sent to a user after filling in the Contact Us form', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.ADD', NULL, 1, 0, NULL, 'Core:Users', 'Add User', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.ADD', NULL, 1, 1, NULL, 'Core:Users', 'Add User', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.APPROVE', NULL, 1, 0, NULL, 'Core:Users', 'Approve User', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.APPROVE', NULL, 1, 1, NULL, 'Core:Users', 'Approve User', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.VALIDATE', NULL, 1, 0, NULL, 'Core:Users', 'Validate User', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.VALIDATE', NULL, 1, 1, NULL, 'Core:Users', 'Validate User', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.DENY', NULL, 1, 0, NULL, 'Core:Users', 'Deny User', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.DENY', NULL, 1, 1, NULL, 'Core:Users', 'Deny User', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.PSWD', NULL, 1, 1, NULL, 'Core:Users', 'Forgot Password', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.PSWD', NULL, 1, 0, NULL, 'Core:Users', 'Forgot Password', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.ADD.PENDING', NULL, 1, 0, NULL, 'Core:Users', 'Add Pending User', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.ADD.PENDING', NULL, 1, 1, NULL, 'Core:Users', 'Add Pending User', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD', NULL, 1, 0, NULL, 'Core:Category', 'Add Category', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD.PENDING', NULL, 1, 0, NULL, 'Core:Category', 'Add Pending Category', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD.PENDING', NULL, 1, 1, NULL, 'Core:Category', 'Add Pending Category', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'CATEGORY.ADD', NULL, 1, 1, NULL, 'Core:Category', 'Add Category', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'CATEGORY.APPROVE', NULL, 1, 0, NULL, 'Core:Category', 'Approve Category', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'CATEGORY.DENY', NULL, 1, 0, NULL, 'Core:Category', 'Deny Category', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.SUBSCRIBE', NULL, 1, 0, NULL, 'Core:Users', 'User subscribed', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.SUBSCRIBE', NULL, 1, 1, NULL, 'Core:Users', 'User subscribed', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.UNSUBSCRIBE', NULL, 1, 0, NULL, 'Core:Users', 'User unsubscribed', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.UNSUBSCRIBE', NULL, 1, 1, NULL, 'Core:Users', 'User unsubscribed', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.SUGGEST', NULL, 1, 0, NULL, 'Core:Users', 'Suggest to a friend', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.SUGGEST', NULL, 1, 1, NULL, 'Core:Users', 'Suggest to a friend', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.PSWDC', NULL, 1, 0, NULL, 'Core:Users', 'Password Confirmation', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRED', NULL, 1, 0, NULL, 'Core:Users', 'Membership expired', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRED', NULL, 1, 0, NULL, 'Core:Users', 'Membership expired', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRATION.NOTICE', NULL, 1, 0, NULL, 'Core:Users', 'Membership expiration notice', 0); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'USER.MEMBERSHIP.EXPIRATION.NOTICE', NULL, 1, 0, NULL, 'Core:Users', 'Membership expiration notice', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'COMMON.FOOTER', NULL, 1, 0, NULL, 'Core', 'Common Footer Template', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'FORM.SUBMITTED', NULL, 1, 0, NULL, 'Core:Category', 'This e-mail is sent to a user after filling in the Contact Us form', 1); +INSERT INTO Events (EventId, Event, ReplacementTags, Enabled, FrontEndOnly, FromUserId, Module, Description, Type) VALUES(DEFAULT, 'FORM.SUBMITTED', NULL, 1, 0, NULL, 'Core:Category', 'This e-mail is sent to a user after filling in the Contact Us form', 0); INSERT INTO IdGenerator VALUES ('100'); Index: core/install/install_schema.sql =================================================================== --- core/install/install_schema.sql (revision 13140) +++ core/install/install_schema.sql (working copy) @@ -112,11 +112,7 @@ FrontEndOnly tinyint(3) unsigned NOT NULL DEFAULT '0', FromUserId int(11) DEFAULT NULL, Module varchar(40) NOT NULL DEFAULT '', - l1_Description text, - l2_Description text, - l3_Description text, - l4_Description text, - l5_Description text, + Description text, `Type` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (EventId), KEY `Type` (`Type`), @@ -185,18 +181,20 @@ CREATE TABLE Phrase ( Phrase varchar(255) NOT NULL DEFAULT '', PhraseKey varchar(255) NOT NULL DEFAULT '', - Translation text, + l1_Translation text, + l2_Translation text, + l3_Translation text, + l4_Translation text, + l5_Translation text, PhraseType int(11) NOT NULL DEFAULT '0', PhraseId int(11) NOT NULL AUTO_INCREMENT, - LanguageId int(11) NOT NULL DEFAULT '0', LastChanged int(10) unsigned DEFAULT NULL, LastChangeIP varchar(15) NOT NULL DEFAULT '', Module varchar(30) NOT NULL DEFAULT 'In-Portal', PRIMARY KEY (PhraseId), - UNIQUE KEY LanguageId_2 (LanguageId,Phrase), - KEY LanguageId (LanguageId), KEY Phrase_Index (Phrase), - KEY PhraseKey (PhraseKey) + KEY PhraseKey (PhraseKey), + KEY l1_Translation (l1_Translation(5)) ); CREATE TABLE PhraseCache ( Index: core/install/upgrades.php =================================================================== --- core/install/upgrades.php (revision 13140) +++ core/install/upgrades.php (working copy) @@ -1327,6 +1327,12 @@ function Upgrade_5_1_0_B1($mode) { if ($mode == 'before') { + // create multilingual fields for phrases and email events + $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); + $ml_helper->createFields('phrases'); + $ml_helper->createFields('emailevents'); + + // migrate email events $table_structure = $this->Conn->Query('DESCRIBE ' . TABLE_PREFIX . 'Events', 'Field'); if (!array_key_exists('Headers', $table_structure)) { @@ -1336,42 +1342,91 @@ $this->Conn->Query($sql); } - // create multilingual Subject and Template fields - $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); - $ml_helper->createFields('emailevents'); + if ($this->Conn->TableFound(TABLE_PREFIX . 'EmailMessage')) { + $email_message_helper =& $this->Application->recallObject('EmailMessageHelper'); + /* @var $email_message_helper EmailMessageHelper */ - $email_message_helper =& $this->Application->recallObject('EmailMessageHelper'); - /* @var $email_message_helper EmailMessageHelper */ + for ($language_id = 1; $language_id <= $ml_helper->languageCount; $language_id++) { + if (!$ml_helper->LanguageFound($language_id)) { + continue; + } + $sql = 'SELECT EmailMessageId, Template, EventId + FROM ' . TABLE_PREFIX . 'EmailMessage + WHERE LanguageId = ' . $language_id; + $translations = $this->Conn->Query($sql, 'EventId'); + + foreach ($translations as $event_id => $translation_data) { + $parsed = $email_message_helper->parseTemplate($translation_data['Template']); + + $fields_hash = Array ( + 'l' . $language_id . '_Subject' => $parsed['Subject'], + 'l' . $language_id . '_Body' => $parsed['Body'], + ); + + if ($parsed['Headers']) { + $fields_hash['Headers'] = $parsed['Headers']; + } + + $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'Events', 'EventId = ' . $event_id); + + $sql = 'DELETE FROM ' . TABLE_PREFIX . 'EmailMessage + WHERE EmailMessageId = ' . $translation_data['EmailMessageId']; + $this->Conn->Query($sql); + } + } + } + + // migrate phrases + $temp_table = $this->Application->GetTempName(TABLE_PREFIX . 'Phrase'); + + $sqls = Array ( + 'DROP TABLE IF EXISTS ' . $temp_table, + 'CREATE TABLE ' . $temp_table . ' LIKE ' . TABLE_PREFIX . 'Phrase', + 'ALTER TABLE ' . $temp_table . ' DROP LanguageId, DROP Translation', + 'ALTER IGNORE TABLE ' . $temp_table . ' DROP INDEX LanguageId_2', + 'ALTER TABLE ' . $temp_table . ' DROP PhraseId', + 'ALTER TABLE ' . $temp_table . ' ADD PhraseId INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST', + ); + + foreach ($sqls as $sql) { + $this->Conn->Query($sql); + } + + $already_added = Array (); + $primary_language_id = $this->Application->GetDefaultLanguageId(); + for ($language_id = 1; $language_id <= $ml_helper->languageCount; $language_id++) { if (!$ml_helper->LanguageFound($language_id)) { continue; } - $sql = 'SELECT EmailMessageId, Template, EventId - FROM ' . TABLE_PREFIX . 'EmailMessage + $sql = 'SELECT Phrase, PhraseKey, Translation AS l' . $language_id . '_Translation, PhraseType, LastChanged, LastChangeIP, Module + FROM ' . TABLE_PREFIX . 'Phrase WHERE LanguageId = ' . $language_id; - $translations = $this->Conn->Query($sql, 'EventId'); + $phrases = $this->Conn->Query($sql, 'Phrase'); - foreach ($translations as $event_id => $translation_data) { - $parsed = $email_message_helper->parseTemplate($translation_data['Template']); - - $fields_hash = Array ( - 'l' . $language_id . '_Subject' => $parsed['Subject'], - 'l' . $language_id . '_Body' => $parsed['Body'], - ); - - if ($parsed['Headers']) { - $fields_hash['Headers'] = $parsed['Headers']; + foreach ($phrases as $phrase => $fields_hash) { + if (array_key_exists($phrase, $already_added)) { + $this->Conn->doUpdate($fields_hash, $temp_table, 'PhraseId = ' . $already_added[$phrase]); } + else { + $this->Conn->doInsert($fields_hash, $temp_table); + $already_added[$phrase] = $this->Conn->getInsertID(); + } + } - $this->Conn->doUpdate($fields_hash, TABLE_PREFIX . 'Events', 'EventId = ' . $event_id); - - $sql = 'DELETE FROM ' . TABLE_PREFIX . 'EmailMessage - WHERE EmailMessageId = ' . $translation_data['EmailMessageId']; + // in case some phrases were found in this language, but not in primary language -> copy them + if ($language_id != $primary_language_id) { + $sql = 'UPDATE ' . $temp_table . ' + SET l' . $primary_language_id . '_Translation = l' . $language_id . '_Translation + WHERE l' . $primary_language_id . '_Translation IS NULL'; $this->Conn->Query($sql); } } + + $this->Conn->Query('DROP TABLE IF EXISTS ' . TABLE_PREFIX . 'Phrase'); + $this->Conn->Query('RENAME TABLE ' . $temp_table . ' TO ' . TABLE_PREFIX . 'Phrase'); } } } \ No newline at end of file Index: core/install/upgrades.sql =================================================================== --- core/install/upgrades.sql (revision 13140) +++ core/install/upgrades.sql (working copy) @@ -1636,6 +1636,8 @@ FROM <%TABLE_PREFIX%>Permissions WHERE Permission = 'in-portal:configemail.edit'; +ALTER TABLE Events ADD l1_Description text; + UPDATE Events e SET e.l1_Description = ( SELECT p.Translation @@ -1643,5 +1645,8 @@ WHERE (p.Phrase = e.Description) AND (p.LanguageId = 1) ); -ALTER TABLE Events DROP Description; +UPDATE Events SET Description = l1_Description; +ALTER TABLE Events DROP l1_Description; + DELETE FROM Phrase WHERE Phrase LIKE 'la_event_%'; +DELETE FROM PersistantSessionData WHERE VariableName = 'phrases_columns_.'; Index: core/kernel/languages/phrases_cache.php =================================================================== --- core/kernel/languages/phrases_cache.php (revision 13128) +++ core/kernel/languages/phrases_cache.php (working copy) @@ -92,7 +92,7 @@ } // now we use admin phrase editing template even on front-end - $this->_phraseEditTemplate = 'regional/phrases_edit'; + $this->_phraseEditTemplate = 'languages/phrase_edit'; } /** @@ -158,9 +158,9 @@ return; } - $sql = 'SELECT Translation, PhraseKey + $sql = 'SELECT l' . $this->LanguageId . '_Translation, PhraseKey FROM ' . TABLE_PREFIX . 'Phrase - WHERE (LanguageId = ' . $this->LanguageId . ') AND PhraseId IN (' . implode(',', $ids) . ')'; + WHERE PhraseId IN (' . implode(',', $ids) . ')'; $this->Phrases = $this->Conn->GetCol($sql, 'PhraseKey'); /*foreach($phrases as $phrase => $tanslation) @@ -233,7 +233,7 @@ if ($this->_editExisting && $allow_editing && !array_key_exists($label, $this->_missingPhrases)) { // option to change translation for Labels - $edit_url = 'javascript:translate_phrase(\'' . addslashes($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnPrepareUpdate\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});'; + $edit_url = 'javascript:translate_phrase(\'' . addslashes($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnPreparePhrase\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});'; $translated_label = '<' . $this->_translateHtmlTag . ' href="' . $edit_url . '" name="cms-translate-phrase" title="Edit translation">' . $translated_label . '_translateHtmlTag . '>'; if ($this->fromTag) { @@ -260,16 +260,16 @@ $language_id = $use_admin ? $this->AdminLanguageId : $this->LanguageId; - $sql = 'SELECT PhraseId, Translation + $sql = 'SELECT PhraseId, l' . $language_id . '_Translation FROM ' . TABLE_PREFIX . 'Phrase - WHERE (LanguageId = ' . $language_id . ') AND (PhraseKey = ' . $this->Conn->qstr($label) . ')'; + WHERE (PhraseKey = ' . $this->Conn->qstr($label) . ') AND (l' . $language_id . '_Translation IS NOT NULL)'; $res = $this->Conn->GetRow($sql); if ($res === false || count($res) == 0) { $translation = '!' . $label . '!'; if ($this->_editMissing && $allow_editing) { - $edit_url = 'javascript:translate_phrase(\'' . addslashes($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnNew\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});'; + $edit_url = 'javascript:translate_phrase(\'' . addslashes($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnPreparePhrase\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});'; $translation = '<' . $this->_translateHtmlTag . ' href="' . $edit_url . '" name="cms-translate-phrase" title="Translate">!' . $label . '!_translateHtmlTag . '>'; if ($this->fromTag) { @@ -286,7 +286,7 @@ } $cache_key = ($allow_editing ? '' : 'NE:') . $label; - $this->Phrases[$cache_key] = $res['Translation']; + $this->Phrases[$cache_key] = $res['l' . $language_id . '_Translation']; array_push($this->Ids, $res['PhraseId']); $this->Ids = array_unique($this->Ids); // just to make sure Index: core/units/email_events/email_events_config.php =================================================================== --- core/units/email_events/email_events_config.php (revision 13140) +++ core/units/email_events/email_events_config.php (working copy) @@ -119,8 +119,6 @@ ), ), - 'PopulateMlFields' => true, - 'Fields' => Array ( 'EventId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'Event' => Array ('type' => 'string', 'not_null' => 1, 'unique' => Array ('Type'), 'required' => 1, 'default' => ''), @@ -168,11 +166,7 @@ 'formatter' => 'kOptionsFormatter', 'options' => Array (), 'not_null' => 1, 'required' => 1, 'default' => '' ), - 'Description' => Array ( - 'type' => 'string', - 'formatter' => 'kMultiLanguage', - 'not_null' => 1, 'default' => '', 'db_type' => 'text', - ), + 'Description' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'Type' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Text_Admin', 0 => 'la_Text_User'), 'use_phrases' => 1, Index: core/units/email_events/email_events_event_handler.php =================================================================== --- core/units/email_events/email_events_event_handler.php (revision 13140) +++ core/units/email_events/email_events_event_handler.php (working copy) @@ -648,15 +648,22 @@ $fields['Module']['options'] = $options; $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); - // make grid on "Email Events" tab in "Regional" section show columns of editable language, not admin language - $language_id = $this->Application->GetVar('lang_id'); - - if ($language_id) { - $grids = $this->Application->getUnitOption($event->Prefix, 'Grids'); - // used by column picker to track column position - $grids['Default']['Fields']['Description']['formatter_renamed'] = true; - array_rename_key($grids['Default']['Fields'], 'Description', 'l' . $language_id . '_Description'); - $this->Application->setUnitOption($event->Prefix, 'Grids', $grids); + if ($this->Application->GetVar('regional')) { + $this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true); } } + + /** + * Prepare temp tables and populate it + * with items selected in the grid + * + * @param kEvent $event + */ + function OnEdit(&$event) + { + parent::OnEdit($event); + + // use language from grid, instead of primary language used by default + $event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang')); + } } \ No newline at end of file Index: core/units/helpers/country_states_helper.php =================================================================== --- core/units/helpers/country_states_helper.php (revision 13128) +++ core/units/helpers/country_states_helper.php (working copy) @@ -50,12 +50,13 @@ return ; } - $sql = 'SELECT p.Translation as DestName, sd.DestAbbr + $language_id = $this->Application->GetVar('m_lang'); + + $sql = 'SELECT p.l' . $language_id . '_Translation as DestName, sd.DestAbbr FROM ' . TABLE_PREFIX . 'StdDestinations AS sd LEFT JOIN ' . TABLE_PREFIX . 'Phrase AS p ON p.Phrase = sd.DestName - WHERE DestType = 2 AND DestParentId = ' . $country_id . ' AND LanguageId = ' . $this->Application->GetVar('m_lang') . ' - ORDER BY Translation'; - + WHERE DestType = 2 AND DestParentId = ' . $country_id . ' + ORDER BY l' . $language_id . '_Translation'; $country_states[$country_abbr] = $this->Conn->GetCol($sql, 'DestAbbr'); } @@ -72,7 +73,9 @@ */ function CheckState($state_name, $country_code) { - if( !$this->CountryHasStates($country_code) ) return $state_name; + if (!$this->CountryHasStates($country_code)) { + return $state_name; + } $sql = 'SELECT sdStates.DestAbbr FROM '.TABLE_PREFIX.'StdDestinations AS sdStates @@ -80,10 +83,9 @@ LEFT JOIN '.TABLE_PREFIX.'StdDestinations AS sdCountries ON sdStates.DestParentId = sdCountries.DestId WHERE (sdStates.DestType = 2) AND (sdStates.DestParentId = sdCountries.DestId) AND - (p.LanguageId = %1$s) AND (sdCountries.DestAbbr = %2$s) AND ( - (LOWER(sdStates.DestAbbr) = %3$s) OR (LOWER(sdStates.DestAbbr2) = %3$s) OR (LOWER(sdStates.DestName) = %3$s) OR (LOWER(p.Translation) = %3$s) + (LOWER(sdStates.DestAbbr) = %3$s) OR (LOWER(sdStates.DestAbbr2) = %3$s) OR (LOWER(sdStates.DestName) = %3$s) OR (LOWER(p.l%1$s_Translation) = %3$s) )'; $state_name = trim( mb_strtolower($state_name) ); Index: core/units/helpers/email_message_helper.php =================================================================== --- core/units/helpers/email_message_helper.php (revision 13140) +++ core/units/helpers/email_message_helper.php (working copy) @@ -10,7 +10,7 @@ */ function parseTemplate($text) { - $ret = Array (); + $ret = Array ('Subject' => '', 'Headers' => '', 'Body' => ''); $headers = Array(); $lines = explode("\n", $text); @@ -31,7 +31,7 @@ $ret['Headers'] = implode("\n", $headers); $message_body = ''; - while ((list($line_id,$line) = each($lines))) { + while ((list($line_id, $line) = each($lines))) { $message_body .= $line; } Index: core/units/helpers/language_import_helper.php =================================================================== --- core/units/helpers/language_import_helper.php (revision 13140) +++ core/units/helpers/language_import_helper.php (working copy) @@ -161,8 +161,8 @@ // copy data from temp tables to live foreach ($this->_languages as $language_id) { - $this->_performUpgrade($language_id, 'phrases', 'PhraseKey'); - $this->_performUpgrade_v2($language_id, 'emailevents', 'EventId', Array ('l%s_Subject', 'Headers', 'l%s_Body')); + $this->_performUpgrade($language_id, 'phrases', 'PhraseKey', Array ('l%s_Translation')); + $this->_performUpgrade($language_id, 'emailevents', 'EventId', Array ('l%s_Subject', 'Headers', 'l%s_Body')); } $this->_initImportTables(true); @@ -192,15 +192,8 @@ $phrase_types = explode('|', substr($phrase_types, 1, -1) ); $module_ids = explode('|', substr($module_ids, 1, -1) ); - $this->events_hash = array_flip($this->events_hash); - - $lang_table = $this->Application->getUnitOption('lang','TableName'); - $phrases_table = $this->Application->getUnitOption('phrases','TableName'); - $events_table = $this->Application->getUnitOption('emailevents','TableName'); - $phrase_tpl = "\t\t\t".'%s'."\n"; $event_tpl = "\t\t\t".'%s'."\n"; - $sql = 'SELECT * FROM %s WHERE LanguageId = %s'; $ret = ''."\n"; $export_fields = $this->_getExportFields(); @@ -208,68 +201,88 @@ $email_message_helper =& $this->Application->recallObject('EmailMessageHelper'); /* @var $email_message_helper EmailMessageHelper */ - foreach ($language_ids as $language_id) { - // languages - $row = $this->Conn->GetRow( sprintf($sql, $lang_table, $language_id) ); + // get languages + $sql = 'SELECT * + FROM ' . $this->Application->getUnitOption('lang','TableName') . ' + WHERE LanguageId IN (' . implode(',', $language_ids) . ')'; + $languages = $this->Conn->Query($sql, 'LanguageId'); + + // get phrases + $phrase_modules = $module_ids; + array_push($phrase_modules, ''); // for old language packs without module + + $phrase_modules = array_map(Array (&$this->Conn, 'qstr'), $phrase_modules); + + $sql = 'SELECT * + FROM ' . $this->Application->getUnitOption('phrases','TableName') . ' + WHERE PhraseType IN (' . implode(',', $phrase_types) . ') AND Module IN (' . implode(',', $phrase_modules) . ') + ORDER BY Phrase'; + $phrases = $this->Conn->Query($sql, 'PhraseId'); + + // email events + $module_sql = preg_replace('/(.*),/U', 'INSTR(Module,\'\\1\') OR ', implode(',', $module_ids) . ','); + + $sql = 'SELECT * + FROM ' . $this->Application->getUnitOption('emailevents','TableName') . ' + WHERE ' . substr($module_sql, 0, -4) . ' + ORDER BY `Event`, `Type`'; + $events = $this->Conn->Query($sql, 'EventId'); + + foreach ($languages as $language_id => $language_info) { + // language $ret .= "\t" . '_exportEncoding == 'base64' ? base64_encode($row['FilenameReplacements']) : ''; + // filename replacements + $ret .= "\t\t" . ''; + $replacements = $language_info['FilenameReplacements']; + $ret .= $this->_exportEncoding == 'base64' ? base64_encode($replacements) : ''; $ret .= '' . "\n"; // phrases - $phrases_sql = 'SELECT * FROM '.$phrases_table.' WHERE LanguageId = %s AND PhraseType IN (%s) AND Module IN (%s) ORDER BY Phrase'; - if( in_array('In-Portal',$module_ids) ) array_push($module_ids, ''); // for old language packs - $rows = $this->Conn->Query( sprintf($phrases_sql,$language_id, implode(',',$phrase_types), '\''.implode('\',\'',$module_ids).'\'' ) ); - if($rows) - { - $ret .= "\t\t".''."\n"; - foreach($rows as $row) - { - $data = $this->_exportEncoding == 'base64' ? base64_encode($row['Translation']) : ''; - $ret .= sprintf($phrase_tpl, $row['Phrase'], $row['Module'], $row['PhraseType'], $data ); + if ($phrases) { + $ret .= "\t\t" . '' . "\n"; + foreach ($phrases as $phrase_id => $phrase) { + $translation = $phrase['l' . $language_id . '_Translation']; + + if (!$translation) { + // phrase is not translated on given language + continue; + } + + $data = $this->_exportEncoding == 'base64' ? base64_encode($translation) : ''; + $ret .= sprintf($phrase_tpl, $phrase['Phrase'], $phrase['Module'], $phrase['PhraseType'], $data); } - $ret .= "\t\t".''."\n"; + $ret .= "\t\t" . '' . "\n"; } // email events - if ( in_array('In-Portal',$module_ids) ) { - unset( $module_ids[array_search('',$module_ids)] ); // for old language packs - } + $ret .= "\t\t" . '' . "\n"; - $module_sql = preg_replace('/(.*),/U', 'INSTR(Module,\'\\1\') OR ', implode(',', $module_ids).','); - $module_sql = substr($module_sql, 0, -4); - - $ret .= "\t\t".''."\n"; - - $event_sql = ' SELECT * - FROM ' . $events_table . ' - WHERE ' . $module_sql . ' - ORDER BY `Event`, `Type`'; - $rows = $this->Conn->Query($event_sql); - - foreach ($rows as $row) { + foreach ($events as $event_id => $event) { $fields_hash = Array ( - 'Headers' => $row['Headers'], - 'Subject' => $row['l' . $language_id . '_Subject'], - 'Body' => $row['l' . $language_id . '_Body'], + 'Headers' => $event['Headers'], + 'Subject' => $event['l' . $language_id . '_Subject'], + 'Body' => $event['l' . $language_id . '_Body'], ); $template = $email_message_helper->buildTemplate($fields_hash); - list($event_name, $event_type) = explode('_', $this->events_hash[ $row['EventId'] ] ); + if (!$template) { + // email event is not translated on given language + continue; + } + $data = $this->_exportEncoding == 'base64' ? base64_encode($template) : ''; - $ret .= sprintf($event_tpl, $row['MessageType'], $event_name, $event_type, $data); + $ret .= sprintf($event_tpl, $event['MessageType'], $event['Event'], $event['Type'], $data); } - $ret .= "\t\t".''."\n"; - - $ret .= "\t".''."\n"; + $ret .= "\t\t" . '' . "\n"; + $ret .= "\t" . '' . "\n"; } $ret .= ''; @@ -295,59 +308,12 @@ * @param int $language_id * @param string $prefix * @param string $unique_field - */ - function _performUpgrade($language_id, $prefix, $unique_field) - { - $live_records = $this->_getTableData($language_id, $prefix, $unique_field, false); - $temp_records = $this->_getTableData($language_id, $prefix, $unique_field, true); - - if ($this->import_mode == LANG_OVERWRITE_EXISTING) { - // remove existing records before copy - $common_records = array_intersect($temp_records, $live_records); - if ($common_records) { - $live_records = array_diff($live_records, $common_records); // remove overlaping records - $common_records = array_map(Array(&$this->Conn, 'qstr'), $common_records); - - $sql = 'DELETE FROM ' . $this->Application->getUnitOption($prefix, 'TableName') . ' - WHERE (LanguageId = ' . $language_id . ') AND (' . $unique_field . ' IN (' . implode(',', $common_records) . '))'; - $this->Conn->Query($sql); - } - } - - $temp_records = array_diff($temp_records, $live_records); - - if (!$temp_records) { - // no new records found in temp table while comparing it to live table - return ; - } - - $temp_records = array_map(Array(&$this->Conn, 'qstr'), $temp_records); - - $sql = 'INSERT INTO ' . $this->Application->getUnitOption($prefix, 'TableName') . ' - SELECT * - FROM ' . $this->_tables[$prefix] . ' - WHERE (LanguageId = ' . $language_id . ')'; - - if ($live_records) { - // subsctract live records from temp table during coping - $sql .= ' AND (' . $unique_field . ' IN (' . implode(',', $temp_records) . '))'; - } - - $this->Conn->Query($sql); - } - - /** - * Performs upgrade of given language pack part - * - * @param int $language_id - * @param string $prefix - * @param string $unique_field * @param string $data_fields */ - function _performUpgrade_v2($language_id, $prefix, $unique_field, $data_fields) + function _performUpgrade($language_id, $prefix, $unique_field, $data_fields) { - $live_records = $this->_getTableData_v2($language_id, $prefix, $unique_field, $data_fields[0], false); - $temp_records = $this->_getTableData_v2($language_id, $prefix, $unique_field, $data_fields[0], true); + $live_records = $this->_getTableData($language_id, $prefix, $unique_field, $data_fields[0], false); + $temp_records = $this->_getTableData($language_id, $prefix, $unique_field, $data_fields[0], true); if (!$temp_records) { // no data for given language @@ -416,31 +382,8 @@ * @param bool $temp_mode * @return Array */ - function _getTableData($language_id, $prefix, $unique_field, $temp_mode = false) + function _getTableData($language_id, $prefix, $unique_field, $data_field, $temp_mode = false) { - $table_name = $this->Application->getUnitOption($prefix, 'TableName'); - - if ($temp_mode) { - $table_name = $this->Application->GetTempName($table_name, 'prefix:' . $prefix); - } - - $sql = 'SELECT ' . $unique_field . ' - FROM ' . $table_name . ' - WHERE LanguageId = ' . $language_id; - return $this->Conn->GetCol($sql); - } - - /** - * Returns data from given table used for language pack upgrade - * - * @param int $language_id - * @param string $prefix - * @param string $unique_field - * @param bool $temp_mode - * @return Array - */ - function _getTableData_v2($language_id, $prefix, $unique_field, $data_field, $temp_mode = false) - { $data_field = sprintf($data_field, $language_id); $table_name = $this->Application->getUnitOption($prefix, 'TableName'); @@ -514,11 +457,15 @@ $this->Conn->Query( sprintf($sql, $temp_table) ); if (!$drop_only) { - $sql = 'CREATE TABLE %s SELECT * FROM %s WHERE 0'; - $this->Conn->Query( sprintf($sql, $temp_table, $table) ); + $sql = 'CREATE TABLE ' . $temp_table . ' SELECT * FROM ' . $table . ' WHERE 0'; + $this->Conn->Query($sql); $sql = 'ALTER TABLE %1$s CHANGE %2$s %2$s INT(11) NOT NULL DEFAULT "0"'; $this->Conn->Query( sprintf($sql, $temp_table, $idfield) ); + + $unique_field = $prefix == 'phrases' ? 'PhraseKey' : 'EventId'; + $sql = 'ALTER TABLE ' . $temp_table . ' ADD UNIQUE (' . $unique_field . ')'; + $this->Conn->Query($sql); } return $temp_table; @@ -669,28 +616,50 @@ */ function _processPhrases(&$phrase_node, $language_id, $language_encoding) { + static $other_translations = Array (); + + if ($this->Application->isDebugMode()) { + $this->Application->Debugger->profileStart('L[' . $language_id . ']P', 'Language: ' . $language_id . '; Phrases Import'); + } + do { + $phrase_key = mb_strtoupper($phrase_node->Attributes['LABEL']); + $fields_hash = Array ( - 'LanguageId' => $language_id, 'Phrase' => $phrase_node->Attributes['LABEL'], - 'PhraseKey' => mb_strtoupper($phrase_node->Attributes['LABEL']), + 'PhraseKey' => $phrase_key, 'PhraseType' => $phrase_node->Attributes['TYPE'], 'Module' => array_key_exists('MODULE', $phrase_node->Attributes) ? $phrase_node->Attributes['MODULE'] : 'Core', 'LastChanged' => adodb_mktime(), 'LastChangeIP' => $this->ip_address, - 'Translation' => $phrase_node->Data, ); + $translation = $phrase_node->Data; + if (array_key_exists($fields_hash['PhraseType'], $this->phrase_types_allowed)) { if ($language_encoding != 'plain') { - $fields_hash['Translation'] = base64_decode($fields_hash['Translation']); + $translation = base64_decode($translation); } - $this->Conn->doInsert($fields_hash, $this->_tables['phrases'], 'INSERT', false); + if (array_key_exists($phrase_key, $other_translations)) { + $other_translations[$phrase_key]['l' . $language_id . '_Translation'] = $translation; + } + else { + $other_translations[$phrase_key] = Array ( + 'l' . $language_id . '_Translation' => $translation + ); + } + + $fields_hash = array_merge($fields_hash, $other_translations[$phrase_key]); + $this->Conn->doInsert($fields_hash, $this->_tables['phrases'], 'REPLACE', false); } } while (($phrase_node =& $phrase_node->NextSibling())); - $this->Conn->doInsert($fields_hash, $this->_tables['phrases'], 'INSERT'); + if ($this->Application->isDebugMode()) { + $this->Application->Debugger->profileFinish('L[' . $language_id . ']P', 'Language: ' . $language_id . '; Phrases Import'); + } + + $this->Conn->doInsert($fields_hash, $this->_tables['phrases'], 'REPLACE'); } /** @@ -702,8 +671,12 @@ */ function _processEvents(&$event_node, $language_id, $language_encoding) { - static $events_added = Array (); + static $other_translations = Array (); + if ($this->Application->isDebugMode()) { + $this->Application->Debugger->profileStart('L[' . $language_id . ']E', 'Language: ' . $language_id . '; Events Import'); + } + $email_message_helper =& $this->Application->recallObject('EmailMessageHelper'); /* @var $email_message_helper EmailMessageHelper */ @@ -724,23 +697,36 @@ 'Event' => $event_node->Attributes['EVENT'], 'Type' => $event_node->Attributes['TYPE'], 'MessageType' => $event_node->Attributes['MESSAGETYPE'], - 'l' . $language_id . '_Subject' => $parsed['Subject'], - 'l' . $language_id . '_Body' => $parsed['Body'], ); - if ($parsed['Headers']) { - $fields_hash['Headers'] = $parsed['Headers']; + if (array_key_exists($event_id, $other_translations)) { + $other_translations[$event_id]['l' . $language_id . '_Subject'] = $parsed['Subject']; + $other_translations[$event_id]['l' . $language_id . '_Body'] = $parsed['Body']; } + else { + $other_translations[$event_id] = Array ( + 'l' . $language_id . '_Subject' => $parsed['Subject'], + 'l' . $language_id . '_Body' => $parsed['Body'], + ); + } - if (!in_array($event_id, $events_added)) { - $events_added[] = $event_id; - $this->Conn->doInsert($fields_hash, $this->_tables['emailevents']); + if ($parsed['Headers']) { + $other_translations[$event_id]['Headers'] = $parsed['Headers']; } - else { - $this->Conn->doUpdate($fields_hash, $this->_tables['emailevents'], 'EventId = ' . $event_id); + elseif (!$parsed['Headers'] && !array_key_exists('Headers', $other_translations[$event_id])) { + $other_translations[$event_id]['Headers'] = $parsed['Headers']; } + + $fields_hash = array_merge($fields_hash, $other_translations[$event_id]); + $this->Conn->doInsert($fields_hash, $this->_tables['emailevents'], 'REPLACE', false); } } while (($event_node =& $event_node->NextSibling())); + + if ($this->Application->isDebugMode()) { + $this->Application->Debugger->profileFinish('L[' . $language_id . ']E', 'Language: ' . $language_id . '; Events Import'); + } + + $this->Conn->doInsert($fields_hash, $this->_tables['emailevents'], 'REPLACE'); } /** Index: core/units/languages/languages_config.php =================================================================== --- core/units/languages/languages_config.php (revision 13140) +++ core/units/languages/languages_config.php (working copy) @@ -136,7 +136,6 @@ ), 'TableName' => TABLE_PREFIX.'Language', - 'SubItems' => Array('phrases',/*'emailmessages'*/), 'FilterMenu' => Array( 'Groups' => Array( Index: core/units/languages/languages_event_handler.php =================================================================== --- core/units/languages/languages_event_handler.php (revision 13140) +++ core/units/languages/languages_event_handler.php (working copy) @@ -195,19 +195,6 @@ $pending_actions[$src_language] = $dst_language; $this->Application->StoreVar($var_name, serialize($pending_actions)); - - if ($object->IsTempTable()) { - // 2. phrases import - $phrases_live = $this->Application->getUnitOption('phrases','TableName'); - $phrases_temp = $this->Application->GetTempName($phrases_live, 'prefix:phrases'); - - $sql = 'INSERT INTO ' . $phrases_temp . '(Phrase, PhraseKey, Translation, PhraseType, PhraseId, LanguageId, LastChanged, LastChangeIP, Module) - SELECT Phrase, PhraseKey, Translation, PhraseType, 0-PhraseId, ' . $dst_language . ', ' . adodb_mktime() . ', "", Module - FROM ' . $phrases_live . ' - WHERE LanguageId = ' . $src_language; - $this->Conn->Query($sql); - } - $object->SetDBField('CopyLabels', 0); } } @@ -234,14 +221,14 @@ // create multilingual columns for phrases & email events table first (actual for 6+ language) $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); -// $ml_helper->createFields('phrases'); + $ml_helper->createFields('phrases'); $ml_helper->createFields('emailevents'); foreach ($pending_actions as $src_language => $dst_language) { // phrases import - /*$sql = 'UPDATE ' . $this->Application->getUnitOption('phrases', 'TableName') . ' + $sql = 'UPDATE ' . $this->Application->getUnitOption('phrases', 'TableName') . ' SET l' . $dst_language . '_Translation = l' . $src_language . '_Translation'; - $this->Conn->Query($sql);*/ + $this->Conn->Query($sql); // events import $sql = 'UPDATE ' . $this->Application->getUnitOption('emailevents', 'TableName') . ' @@ -511,38 +498,11 @@ continue; } - $this->_addMissingPhrase($source_id, $target_id); + $sql = 'UPDATE ' . TABLE_PREFIX . 'Phrase + SET l' . $target_id . '_Translation = l' . $source_id . '_Translation + WHERE (l' . $target_id . '_Translation IS NULL) OR (l' . $target_id . '_Translation = "")'; + $this->Conn->Query($sql); } } } - - /** - * Copy missing phrases from $from_lang to $to_lang - * - * @param int $from_lang - * @param int $to_lang - */ - function _addMissingPhrase($from_lang, $to_lang) - { - $tmp_name = TABLE_PREFIX . 'PhraseCopy_' . $this->Application->GetSID(); - $q = 'CREATE TABLE ' . $tmp_name . ' - SELECT - source.Phrase, - source.PhraseKey, - source.Translation, - source.PhraseType, - NULL As PhraseId, - ' . $to_lang . ' AS LanguageId, - source.LastChanged, - source.LastChangeIP, - source.Module - FROM ' . TABLE_PREFIX . 'Phrase source - WHERE source.LanguageId = ' . $from_lang . ' - AND source.Phrase NOT IN (SELECT Phrase FROM ' . TABLE_PREFIX . 'Phrase target WHERE target.LanguageId = ' . $to_lang . ')'; - $this->Conn->Query($q); - - $this->Conn->Query('INSERT INTO ' . TABLE_PREFIX . 'Phrase SELECT * FROM ' . $tmp_name); - $this->Conn->Query('DROP TABLE ' . $tmp_name); - } - } \ No newline at end of file Index: core/units/phrases/phrase_tp.php =================================================================== --- core/units/phrases/phrase_tp.php (revision 13128) +++ core/units/phrases/phrase_tp.php (working copy) @@ -15,20 +15,6 @@ class PhraseTagProcessor extends kDBTagProcessor { /** - * Determines, that hidden field with language id should be shown - * - * @param Array $params - * @return bool - */ - function ShowHiddenLanguage($params) - { - $simple_mode = $this->Application->GetVar('simple_mode'); - $phrases_label = $this->Application->GetVar('phrases_label'); - - return $simple_mode || !$phrases_label; - } - - /** * Determines, that we can close phrase editing form without parent window refreshing * * @param Array $params Index: core/units/phrases/phrases_config.php =================================================================== --- core/units/phrases/phrases_config.php (revision 13128) +++ core/units/phrases/phrases_config.php (working copy) @@ -17,29 +17,6 @@ $config = Array ( 'Prefix' => 'phrases', - 'Clones' => Array ( - 'phrases-single' => Array ( - 'ForeignKey' => false, - 'ParentTableKey' => false, - 'ParentPrefix' => false, - - 'Sections' => Array ( - // "Phrases" - 'in-portal:phrases' => Array ( - 'parent' => 'in-portal:site', - 'icon' => 'phrases_labels', - 'label' => 'la_title_Phrases', - 'url' => Array ('t' => 'languages/phrase_list', 'pass' => 'm'), - 'permissions' => Array ('view', 'add', 'edit', 'delete'), -// 'perm_prefix' => 'lang', - 'priority' => 4, -// 'show_mode' => smSUPER_ADMIN, - 'type' => stTREE, - ), - ), - ) - ), - 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'PhrasesEventHandler', 'file' => 'phrases_event_handler.php', 'build_event' => 'OnBuild'), @@ -67,32 +44,47 @@ 'phrase_edit' => Array ( 'prefixes' => Array ('phrases'), 'format' => '#phrases_status# #phrases_titlefield#', 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), - ), + ), // for separate phrases list 'phrases_list_st' => Array ( - 'prefixes' => Array ('phrases.st_List'), 'format' => "!la_title_Phrases!", + 'prefixes' => Array ('phrases_List'), 'format' => "!la_title_Phrases!", 'toolbar_buttons' => Array ('new_item', 'edit', 'delete', 'view', 'dbl-click'), - ), + ), 'phrase_edit_single' => Array ( 'prefixes' => Array ('phrases'), 'format' => '#phrases_status# #phrases_titlefield#', 'toolbar_buttons' => Array ('select', 'cancel', 'reset_edit', 'prev', 'next'), - ), + ), ), + 'Sections' => Array ( + // "Phrases" + 'in-portal:phrases' => Array ( + 'parent' => 'in-portal:site', + 'icon' => 'phrases_labels', + 'label' => 'la_title_Phrases', + 'url' => Array ('t' => 'languages/phrase_list', 'pass' => 'm'), + 'permissions' => Array ('view', 'add', 'edit', 'delete'), +// 'perm_prefix' => 'lang', + 'priority' => 4, +// 'show_mode' => smSUPER_ADMIN, + 'type' => stTREE, + ), + ), + 'FilterMenu' => Array ( 'Groups' => Array ( Array ('mode' => 'AND', 'filters' => Array ('show_front', 'show_admin', 'show_both'), 'type' => WHERE_FILTER), - Array ('mode' => 'AND', 'filters' => Array ('translated', 'not_translated'), 'type' => WHERE_FILTER), + Array ('mode' => 'AND', 'filters' => Array ('translated', 'not_translated'), 'type' => HAVING_FILTER), ), 'Filters' => Array ( 'show_front' => Array ('label' =>'la_PhraseType_Front', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 0'), 'show_admin' => Array ('label' => 'la_PhraseType_Admin', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 1'), 'show_both' => Array ('label' => 'la_PhraseType_Both', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 2'), 's1' => Array (), - 'translated' => Array ('label' => 'la_PhraseTranslated', 'on_sql' => '', 'off_sql' => '%1$s.Translation = pri.Translation'), - 'not_translated' => Array ('label' => 'la_PhraseNotTranslated', 'on_sql' => '', 'off_sql' => '%1$s.Translation != pri.Translation'), + 'translated' => Array ('label' => 'la_PhraseTranslated', 'on_sql' => '', 'off_sql' => 'CurrentTranslation IS NULL'), + 'not_translated' => Array ('label' => 'la_PhraseNotTranslated', 'on_sql' => '', 'off_sql' => 'CurrentTranslation IS NOT NULL'), ) ), @@ -100,21 +92,13 @@ 'CalculatedFields' => Array ( '' => Array ( - 'PrimaryTranslation' => 'pri.Translation', + 'PrimaryTranslation' => 'l%4$s_Translation', + 'CurrentTranslation' => 'l%5$s_Translation', ), - - 'st' => Array ( - 'PackName' => 'lang.PackName', - ), ), 'ListSQLs' => Array( - '' => ' SELECT %1$s.* %2$s - FROM %1$s - LEFT JOIN ' . TABLE_PREFIX . 'Phrase pri ON (%1$s.Phrase = pri.Phrase) AND (pri.LanguageId = 1)', - 'st' => 'SELECT %1$s.* %2$s - FROM %1$s - LEFT JOIN ' . TABLE_PREFIX . 'Language lang ON (%1$s.LanguageId = lang.LanguageId)', + '' => 'SELECT %1$s.* %2$s FROM %1$s', ), 'ListSortings' => Array ( @@ -123,60 +107,54 @@ ) ), - 'ForeignKey' => 'LanguageId', - 'ParentTableKey' => 'LanguageId', - 'ParentPrefix' => 'lang', - 'AutoDelete' => true, - 'AutoClone' => true, - 'Fields' => Array ( + 'PhraseId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'Phrase' => Array ( 'type' => 'string', - 'required' => 1, 'unique' => Array ('LanguageId'), + 'required' => 1, 'unique' => Array (), 'not_null' => 1, 'default' => '' ), 'PhraseKey' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), - 'Translation' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'required' => 1, 'using_fck' => 1, 'default' => NULL), + 'Translation' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'required' => 1, 'using_fck' => 1, 'default' => NULL, 'db_type' => 'text'), 'PhraseType' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_PhraseType_Front', 1 => 'la_PhraseType_Admin', 2 => 'la_PhraseType_Both'), 'use_phrases' => 1, 'not_null' => 1, 'required' => 1, 'default' => 0 ), - 'PhraseId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - - 'LanguageId' => Array ( - 'type' => 'int', - 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Language ORDER BY LocalName', 'option_key_field' => 'LanguageId', 'option_title_field' => 'LocalName', - 'not_null' => 1, 'default' => 0 - ), - 'LastChanged' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => NULL), 'LastChangeIP' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'Module' => Array ( 'type' => 'string', 'formatter' => 'kOptionsFormatter', 'options' => Array ('' => ''), 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Modules WHERE (Loaded = 1) AND (Name <> "In-Portal") ORDER BY LoadOrder', 'option_key_field' => 'Name', 'option_title_field' => 'Name', - 'not_null' => 1, 'default' => 'Core' + 'not_null' => 1, 'required' => 1, 'default' => 'Core' ), ), 'VirtualFields' => Array ( 'PrimaryTranslation' => Array ('type' => 'string', 'default' => ''), + 'CurrentTranslation' => Array ('type' => 'string', 'default' => ''), + + // for language pack import/export 'LangFile' => Array ( 'type' => 'string', 'formatter' => 'kUploadFormatter', 'max_size' => MAX_UPLOAD_SIZE, 'upload_dir' => WRITEBALE_BASE . '/', 'max_len' => 255, 'default' => '' ), - 'ImportOverwrite' => Array ('type' => 'int', 'default' => 0), - 'DoNotEncode' => Array (), - 'PackName' => Array ( - 'type' => 'string', - 'formatter' => 'kOptionsFormatter', - 'options_sql' => 'SELECT %s FROM ' . TABLE_PREFIX . 'Language ORDER BY PackName', 'option_title_field' => 'PackName', 'option_key_field' => 'PackName', + 'ImportOverwrite' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'default' => 0 ), + 'DoNotEncode' => Array ( + 'type' => 'int', + 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Yes', 0 => 'la_No'), 'use_phrases' => 1, + 'default' => 0 + ), ), 'Grids' => Array ( + // used on "Phrases" tab in language editing in "Regional" section 'Default' => Array ( 'Icons' => Array ( 'default' => 'icon16_item.png', @@ -186,7 +164,7 @@ 'Fields' => Array ( 'PhraseId' => Array ('title' => 'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 50), 'Phrase' => Array ('title' => 'la_col_Label', 'data_block' => 'grid_checkbox_td', 'width' => 200), - 'Translation' => Array ('title' => 'la_col_Phrase', 'width' => 200), + 'CurrentTranslation' => Array ('title' => 'la_col_Phrase', 'width' => 200), 'PrimaryTranslation' => Array ('title' => 'la_col_PrimaryValue', 'width' => 200), 'PhraseType' => Array ('title' => 'la_col_PhraseType', 'filter_block' => 'grid_options_filter', 'width' => 60), 'LastChanged' => Array ('title' => 'la_col_Modified', 'filter_block' => 'grid_date_range_filter', 'width' => 150), @@ -194,6 +172,7 @@ ), ), + // used on "Labels & Phrases" section 'Phrases' => Array ( 'Icons' => Array ( 'default' => 'icon16_item.png', @@ -203,8 +182,7 @@ 'Fields' => Array ( 'PhraseId' => Array ('title' => 'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'width' => 50), 'Phrase' => Array ('title' => 'la_col_Label', 'filter_block' => 'grid_like_filter', 'width' => 170), - 'Translation' => Array ('title' => 'la_col_Phrase', 'filter_block' => 'grid_like_filter', 'width' => 180), - 'PackName' => Array ('title' => 'la_col_Language', 'filter_block' => 'grid_options_filter', 'width' => 95), + 'CurrentTranslation' => Array ('title' => 'la_col_Phrase', 'filter_block' => 'grid_like_filter', 'width' => 180), 'PhraseType' => Array ('title' => 'la_col_Location', 'filter_block' => 'grid_options_filter', 'width' => 80), 'LastChanged' => Array ('title' => 'la_col_Modified', 'filter_block' => 'grid_date_range_filter', 'width' => 145), 'Module' => Array ('title' => 'la_col_Module', 'filter_block' => 'grid_options_filter', 'width' => 100), Index: core/units/phrases/phrases_event_handler.php =================================================================== --- core/units/phrases/phrases_event_handler.php (revision 13128) +++ core/units/phrases/phrases_event_handler.php (working copy) @@ -32,7 +32,7 @@ if ($event->Special == 'import') { $object->setRequired('LangFile', true); $object->setRequired('Phrase', false); - $object->setRequired('Translation', false); + $object->setRequired('l' . $this->Application->GetVar('m_lang') . '_Translation', false); // allow multiple phrase types to be selected during import $field_options = $object->GetFieldOptions('PhraseType'); @@ -65,14 +65,51 @@ $permissions = Array ( 'OnItemBuild' => Array('self' => true, 'subitem' => true), - 'OnNew' => Array('self' => true, 'subitem' => true), - 'OnPrepareUpdate' => Array('self' => true, 'subitem' => true), + 'OnPreparePhrase' => Array('self' => true, 'subitem' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** + * Prepares phrase for translation + * + * @param kEvent $event + */ + function OnPreparePhrase(&$event) + { + $label = $this->Application->GetVar($event->getPrefixSpecial() . '_label'); + + if (!$label) { + return ; + } + + // we got label, try to get it's ID then if any + $phrase_id = $this->_getPhraseId($label); + + if ($phrase_id) { + $event->SetRedirectParam($event->getPrefixSpecial(true) . '_id', $phrase_id); + $event->SetRedirectParam('pass', 'm,' . $event->getPrefixSpecial()); + } + else { + $event->CallSubEvent('OnNew'); + } + + if ($this->Application->GetVar('simple_mode')) { + $event->SetRedirectParam('simple_mode', 1); + } + } + + function _getPhraseId($phrase) + { + $sql = 'SELECT ' . $this->Application->getUnitOption($this->Prefix, 'IDField') . ' + FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . ' + WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) ); + + return $this->Conn->GetOne($sql); + } + + /** * Forces new label in case if issued from get link * * @param kEvent $event @@ -80,53 +117,45 @@ function OnNew(&$event) { parent::OnNew($event); - $label = $this->Application->GetVar('phrases_label'); - $object =& $event->getObject( $label ? Array('live_table' => true, 'skip_autoload' => true) : Array('skip_autoload' => true) ); + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $label = $this->Application->GetVar($event->getPrefixSpecial() . '_label'); + if ($label) { + // phrase is created in language, used to display phrases $object->SetDBField('Phrase', $label); - // phrase is created in language, used to display phrases - $object->SetDBField('LanguageId', $this->Application->GetVar('m_lang')); - $object->SetDBField('PhraseType', 1); - - $primary_language = $this->Application->GetDefaultLanguageId(); - $live_table = $this->Application->getUnitOption($event->Prefix, 'TableName'); - $sql = 'SELECT Translation FROM %s WHERE Phrase = %s'; - $primary_value = $this->Conn->GetOne( sprintf($sql, $live_table, $this->Conn->qstr($label) ) ); - $object->SetDBField('PrimaryTranslation', $primary_value); + $object->SetDBField('PhraseType', 1); // admin + $object->SetDBField('PrimaryTranslation', $this->_getPrimaryTranslation($label)); } + // set module from cookie $last_module = $this->Application->GetVar('last_module'); + if ($last_module) { $object->SetDBField('Module', $last_module); } - if ($event->Special == 'export' || $event->Special == 'import') { + if (($event->Special == 'export') || ($event->Special == 'import')) { $object->SetDBField('PhraseType', '|0|1|2|'); - $modules = $this->Conn->GetCol('SELECT Name FROM '.TABLE_PREFIX.'Modules'); - $object->SetDBField('Module', '|'.implode('|', $modules).'|' ); + $object->SetDBField('Module', '|' . implode('|', array_keys($this->Application->ModuleInfo)) . '|' ); } } /** - * Prepares existing phrase editing + * Returns given phrase translation on primary language * - * @param kEvent $event + * @param string $phrase + * @return string */ - function OnPrepareUpdate(&$event) + function _getPrimaryTranslation($phrase) { - $language_id = $this->Application->GetVar('m_lang'); - $label = $this->Application->GetVar('phrases_label'); + $sql = 'SELECT l' . $this->Application->GetDefaultLanguageId() . '_Translation + FROM ' . $this->Application->getUnitOption($this->Prefix, 'TableName') . ' + WHERE PhraseKey = ' . $this->Conn->qstr( mb_strtoupper($phrase) ); - $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); - $label_idfield = $this->Application->getUnitOption($event->Prefix, 'IDField'); - - $sql = 'SELECT ' . $label_idfield . ' - FROM ' . $table_name . ' - WHERE Phrase = '.$this->Conn->qstr($label).' AND LanguageId = '.(int)$language_id; - $this->Application->SetVar($event->getPrefixSpecial() . '_id', $this->Conn->GetOne($sql)); - - $event->redirect = false; + return $this->Conn->GetOne($sql); } /** @@ -156,8 +185,27 @@ { parent::OnBeforeItemCreate($event); - $this->_setPhraseKey($event); - $this->_setLastUpdated($event); + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $primary_language_id = $this->Application->GetDefaultLanguageId(); + + if (!$object->GetDBField('l' . $primary_language_id . '_Translation')) { + // no translation on primary language -> try to copy from other language + $src_languages = Array ('lang_id', 'm_lang'); // editable language, theme language + + foreach ($src_languages as $src_language) { + $src_language = $this->Application->GetVar($src_language); + $src_value = $src_language ? $object->GetDBField('l' . $src_language . '_Translation') : false; + + if ($src_value) { + $object->SetDBField('l' . $primary_language_id . '_Translation', $src_value); + break; + } + } + } + + $this->_phraseChanged($event); } /** @@ -169,33 +217,21 @@ { parent::OnBeforeItemUpdate($event); - $this->_setPhraseKey($event); - $this->_setLastUpdated($event); + $this->_phraseChanged($event); } /** - * Set's phrase key, used for phrase updating and loading + * Set's phrase key and last change info, used for phrase updating and loading * * @param kEvent $event */ - function _setPhraseKey(&$event) + function _phraseChanged(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $object->SetDBField('PhraseKey', mb_strtoupper($object->GetDBField('Phrase'))); - } - /** - * Save phrase change date & ip translation was made from - * - * @param kEvent $event - */ - function _setLastUpdated(&$event) - { - $object =& $event->getObject(); - /* @var $object kDBItem */ - if ($object->GetOriginalField('Translation') != $object->GetDBField('Translation')) { $object->SetDBField('LastChanged_date', adodb_mktime() ); $object->SetDBField('LastChanged_time', adodb_mktime() ); @@ -219,6 +255,78 @@ $fields['Module']['default'] = 'Custom'; $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); } + + // make sure, that PrimaryTranslation column always refrers to primary language column + $language_id = $this->Application->GetVar('lang_id'); + + if (!$language_id) { + $language_id = $this->Application->GetVar('m_lang'); + } + + $primary_language_id = $this->Application->GetDefaultLanguageId(); + $calculated_fields = $this->Application->getUnitOption($event->Prefix, 'CalculatedFields'); + + foreach ($calculated_fields[''] as $field_name => $field_expression) { + $field_expression = str_replace('%5$s', $language_id, $field_expression); + $field_expression = str_replace('%4$s', $primary_language_id, $field_expression); + + $calculated_fields[''][$field_name] = $field_expression; + } + + $this->Application->setUnitOption($event->Prefix, 'CalculatedFields', $calculated_fields); + + if ($this->Application->GetVar('regional')) { + $this->Application->setUnitOption($event->Prefix, 'PopulateMlFields', true); + } } + /** + * Saves changes & changes language + * + * @param kEvent $event + */ + function OnPreSaveAndChangeLanguage(&$event) + { + $label = $this->Application->GetVar($event->getPrefixSpecial() . '_label'); + + if ($label && !$this->UseTempTables($event)) { + $phrase_id = $this->_getPhraseId($label); + + if ($phrase_id) { + $event->CallSubEvent('OnUpdate'); + $event->SetRedirectParam('opener', 's'); + } + else { + $event->CallSubEvent('OnCreate'); + $event->SetRedirectParam('opener', 's'); + } + + if ($event->status != erSUCCESS) { + return ; + } + + $event->SetRedirectParam($event->getPrefixSpecial() . '_event', 'OnPreparePhrase'); + $event->SetRedirectParam('pass_events', true); + } + + if ($this->Application->GetVar('simple_mode')) { + $event->SetRedirectParam('simple_mode', 1); + } + + parent::OnPreSaveAndChangeLanguage($event); + } + + /** + * Prepare temp tables and populate it + * with items selected in the grid + * + * @param kEvent $event + */ + function OnEdit(&$event) + { + parent::OnEdit($event); + + // use language from grid, instead of primary language used by default + $event->SetRedirectParam('m_lang', $this->Application->GetVar('m_lang')); + } } \ No newline at end of file Index: core/units/users/users_config.php =================================================================== --- core/units/users/users_config.php (revision 13128) +++ core/units/users/users_config.php (working copy) @@ -362,23 +362,24 @@ 'Street' => Array('type' => 'string', 'default' => null), 'Street2' => Array('type' => 'string', 'not_null' => '1', 'default' => ''), 'City' => Array('type' => 'string','default' => null), - 'State' => Array('type' => 'string', 'formatter'=>'kOptionsFormatter', - 'options' => Array(), - 'option_key_field'=>'DestAbbr','option_title_field'=>'Translation', - 'not_null' => '1','default' => ''), + 'State' => Array( + 'type' => 'string', + 'formatter' => 'kOptionsFormatter', 'options' => Array(), + 'not_null' => 1, + 'default' => '' + ), 'Zip' => Array('type' => 'string','default' => null), - 'Country' => Array('type' => 'string', 'formatter'=>'kOptionsFormatter', - 'options_sql'=>'SELECT %1$s - FROM '.TABLE_PREFIX.'StdDestinations - LEFT JOIN '.TABLE_PREFIX.'Phrase - ON '.TABLE_PREFIX.'Phrase.Phrase = '.TABLE_PREFIX.'StdDestinations.DestName - WHERE - DestType=1 - AND - LanguageId = %2$s - ORDER BY Translation', - 'option_key_field'=>'DestAbbr','option_title_field'=>'Translation', - 'not_null' => '1','default' => ''), + 'Country' => Array( + 'type' => 'string', + 'formatter' => 'kOptionsFormatter', + 'options_sql' => ' SELECT %1$s + FROM '.TABLE_PREFIX.'StdDestinations + LEFT JOIN '.TABLE_PREFIX.'Phrase ON '.TABLE_PREFIX.'Phrase.Phrase = '.TABLE_PREFIX.'StdDestinations.DestName + WHERE DestType = 1 + ORDER BY l%2$s_Translation', + 'option_key_field' => 'DestAbbr', 'option_title_field' => 'l%2$s_Translation', + 'not_null' => 1, 'default' => '' + ), 'ResourceId' => Array('type' => 'int','not_null' => 1, 'default' => 0), 'Status' => Array('type' => 'int', 'formatter'=>'kOptionsFormatter', 'options'=>Array(1=>'la_Enabled', 0=>'la_Disabled', 2=>'la_Pending'), 'use_phrases'=>1, 'not_null' => '1','default' => 1), 'Modified' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#'),