diff --git a/include/class.page.php b/include/class.page.php index c533617d6126b04668d5927bf43cacf875c34cb8..5eea8eacd32cb941d0b094f757bc2cf3e79e7ce3 100644 --- a/include/class.page.php +++ b/include/class.page.php @@ -70,8 +70,13 @@ class Page { function getBody() { return $this->ht['body']; } + function getLocalBody() { + $tag = $this->getTranslateTag('body'); + $T = CustomDataTranslation::translateArticle($tag); + return $T != $tag ? $T : $this->getBody(); + } function getBodyWithImages() { - return Format::viewableImages($this->getBody(), ROOT_PATH.'image.php'); + return Format::viewableImages($this->getLocalBody(), ROOT_PATH.'image.php'); } function getNotes() { @@ -102,6 +107,15 @@ class Page { return $this->ht['topics']; } + function getTranslateTag($subtag) { + return _H(sprintf('page.%s.%s', $subtag, $this->id)); + } + function getLocal($subtag) { + $tag = $this->getTranslateTag($subtag); + $T = CustomDataTranslation::translate($tag); + return $T != $tag ? $T : $this->ht[$subtag]; + } + function update($vars, &$errors) { if(!$vars['isactive'] && $this->isInUse()) { @@ -261,8 +275,8 @@ class Page { if($id) { $sql='UPDATE '.PAGE_TABLE.' SET '.$sql.' WHERE id='.db_input($id); - if(db_query($sql)) - return true; + if (db_query($sql)) + return $this->saveTranslations($vars, $errors); $errors['err']=sprintf(__('Unable to update %s.'), __('this site page')); @@ -284,5 +298,44 @@ class Page { return false; } + + function saveTranslations($vars, &$errors) { + global $thisstaff; + + $tag = $this->getTranslateTag('body'); + $translations = CustomDataTranslation::allTranslations($tag,'article'); + foreach ($translations as $t) { + foreach ($vars['trans'] as $lang=>$content) { + if (strcasecmp($lang, $t->lang) !== 0) + continue; + $content = Format::sanitize($content); + unset($vars['trans'][$lang]); + if ($content == $t->text) + continue; + $t->text = $content; + $t->agent_id = $thisstaff->getId(); + if (!$t->save()) + return false; + } + } + // New translations (?) + foreach ($vars['trans'] as $lang=>$content) { + $content = Format::sanitize($content); + if (!$content) + continue; + $t = CustomDataTranslation::create(array( + 'type' => 'article', + 'object_hash' => $tag, + 'lang' => $lang, + 'text' => $content, + 'revision' => 1, + 'agent_id' => $thisstaff->getId(), + 'updated' => new SqlFunction('NOW'), + )); + if (!$t->save()) + return false; + } + return true; + } } ?> diff --git a/include/class.translation.php b/include/class.translation.php index 4900bae82dc1d98c8721024785a0d3fe3884e58f..c4e606fdb0250039eacb3b89a15ea75b2416ce8b 100644 --- a/include/class.translation.php +++ b/include/class.translation.php @@ -902,7 +902,7 @@ class CustomDataTranslation extends VerySimpleModel { return $_cache[$locale] = $mo; } - static function translate($msgid, $locale=false, $cache=true) { + static function translate($msgid, $locale=false, $cache=true, $type='phrase') { global $thisstaff, $thisclient; if (!$locale @@ -914,6 +914,12 @@ class CustomDataTranslation extends VerySimpleModel { elseif (is_object($locale) && method_exists($locale, 'getLanguage')) $locale = $locale->getLanguage(); + else + $locale = Internationalization::getDefaultLanguage(); + + // Perhaps a slight optimization would be to check if the selected + // locale is also the system primary. If so, short-circuit + if ($locale) { if ($cache) { $mo = static::getTranslation($locale); @@ -921,7 +927,7 @@ class CustomDataTranslation extends VerySimpleModel { $msgid = $mo[$msgid]->text; } elseif ($p = static::lookup(array( - 'type' => 'phrase', + 'type' => $type, 'lang' => $locale, 'object_hash' => $msgid ))) { @@ -931,9 +937,13 @@ class CustomDataTranslation extends VerySimpleModel { return $msgid; } - static function allTranslations($msgid) { + static function translateArticle($msgid, $locale=false) { + return static::translate($msgid, $locale, false, 'article'); + } + + static function allTranslations($msgid, $type='phrase') { return static::objects()->filter(array( - 'type' => 'phrase', + 'type' => $type, 'object_hash' => $msgid ))->all(); } @@ -1025,9 +1035,6 @@ function _dcnpgettext($domain, $context, $singular, $plural, $category, $n) { function _H($tag) { return substr(md5($tag), -16); } -function _C(Translatable $object) { - return $objet->getLocalName(); -} interface Translatable { function getTranslationTag(); diff --git a/include/staff/page.inc.php b/include/staff/page.inc.php index 49f2cbea471ad5fa51e3cd9fa18092b076581070..714f8ce724d16da403b6f0fdc5679eea9843b554 100644 --- a/include/staff/page.inc.php +++ b/include/staff/page.inc.php @@ -15,8 +15,19 @@ if($page && $_REQUEST['a']!='add'){ $info=$page->getHashtable(); $info['body'] = Format::viewableImages($page->getBody()); $info['notes'] = Format::viewableImages($info['notes']); + $trans['name'] = $page->getTranslateTag('name'); $slug = Format::slugify($info['name']); $qstr.='&id='.$page->getId(); + $translations = CustomDataTranslation::allTranslations( + $page->getTranslateTag('body'), 'article'); + foreach ($cfg->getSecondaryLanguages() as $tag) { + foreach ($translations as $t) { + if (strcasecmp($t->lang, $tag) === 0) { + $info['trans'][$tag] = Format::viewableImages($t->text); + break; + } + } + } }else { $title=__('Add New Page'); $action='add'; @@ -50,7 +61,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php echo __('Name'); ?>: </td> <td> - <input type="text" size="40" name="name" value="<?php echo $info['name']; ?>"> + <input type="text" size="40" name="name" value="<?php echo $info['name']; ?>" + data-translate-tag="<?php echo $trans['name']; ?>"/> <span class="error">* <?php echo $errors['name']; ?></span> </td> </tr> @@ -96,30 +108,66 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </td> </tr> <tr> - <th colspan="2"> - <em><?php echo __( - '<b>Page body</b>: Ticket variables are only supported in thank-you pages.' - ); ?><font class="error">* <?php echo $errors['body']; ?></font></em> - </th> - </tr> - <tr> - <td colspan=2 style="padding-left:3px;"> - <textarea name="body" cols="21" rows="12" style="width:98%;" class="richtext draft" + <td colspan="2"> + <ul class="tabs"> + <li><a class="active" href="#content"><?php echo __('Page Content'); ?></a></li> + <li><a href="#notes"><?php echo __('Internal Notes'); ?></a></li> + </ul> + <div class="tab_content active" id="content"> +<?php if ($page && ($langs = $cfg->getSecondaryLanguages())) { ?> + <div class="banner"> + <span class="pull-left"> + <i class="icon-globe icon-large"></i> + <?php echo __('This content is translatable'); ?> + </span> + <span class="pull-right"> + <?php echo __('View'); ?>: + <select onchange="javascript: +$('option', this).each(function(){$($(this).val()).hide()}); +$($('option:selected', this).val()).show(); "> + <option value="#reference-text"><?php echo + Internationalization::getLanguageDescription($cfg->getPrimaryLanguage()); + ?> — <?php echo __('Primary'); ?></option> +<?php foreach ($langs as $tag) { ?> + <option value="#translation-<?php echo $tag; ?>"><?php echo + Internationalization::getLanguageDescription($tag); + ?></option> +<?php } ?> + </select> + </span> + </div> + <div class="clear"></div> +<?php } ?> + <div id="reference-text" + lang="<?php echo $cfg->getPrimaryLanguage(); ?>"> + <textarea name="body" cols="21" rows="12" style="width:98%;" class="richtext draft" <?php list($draft, $attrs) = Draft::getDraftAndDataAttrs('page', $info['id'], $info['body']); echo $attrs; ?>><?php echo $draft ?: $info['body']; ?></textarea> - </td> - </tr> - <tr> - <th colspan="2"> - <em><strong><?php echo __('Internal Notes'); ?></strong>: - <?php echo __("be liberal, they're internal"); ?></em> - </th> - </tr> - <tr> - <td colspan=2> - <textarea class="richtext no-bar" name="notes" cols="21" - rows="8" style="width: 80%;"><?php echo $info['notes']; ?></textarea> + </div> + +<?php if ($langs && $page) { + foreach ($langs as $tag) { ?> + <div id="translation-<?php echo $tag; ?>" style="display:none" lang="<?php echo $tag; ?>"> + <textarea name="trans[<?php echo $tag; ?>]" cols="21" rows="12" + style="width:98%;" class="richtext" + ><?php echo $info['trans'][$tag]; ?></textarea> + </div> +<?php } +} ?> + + <div class="error" style="margin: 5px 0"><?php echo $errors['body']; ?></div> + <div id="msg_info"><em><i class="icon-info-sign"></i> <?php + echo __( + 'Ticket variables are only supported in thank-you pages.' + ); ?></em></div> + </div> + <div class="tab_content" style="display:none" id="notes"> + <em><strong><?php echo __('Internal Notes'); ?></strong>: + <?php echo __("be liberal, they're internal"); ?></em> + <textarea class="richtext no-bar" name="notes" cols="21" + rows="8" style="width: 80%;"><?php echo $info['notes']; ?></textarea> + </div> </td> </tr> </tbody> diff --git a/scp/css/scp.css b/scp/css/scp.css index 2fe63818d17da1f6514482d6b93a69b27c96791b..dab7b3a6774a12e81708d1f8184bb44c15fbe699 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -67,6 +67,8 @@ div#header a { color: #555; } +.banner { margin: 0; padding: 5px 5px 11px; margin-bottom: 10px; color: #444; border: 1px solid #444; background-color: #ddd; border-radius: 4px; } + #msg_info, .info-banner { margin: 0; padding: 5px; margin-bottom: 10px; color: #3a87ad; border: 1px solid #bce8f1; background-color: #d9edf7; }