diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index ff99431b221..1bc5fd41012 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -59,16 +59,17 @@ class FormAdmin * @param int $forcecombo Force to use combo box (so no ajax beautify effect) * @param int $multiselect Make the combo a multiselect * @param array $onlykeys Show only the following keys (opposite of $filter) + * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...) * @return string Return HTML select string with list of languages */ - public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array()) + public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array(), $mainlangonly = 0) { // phpcs:enable global $conf, $langs; if (!empty($conf->global->MAIN_DEFAULT_LANGUAGE_FILTER)) $filter[$conf->global->MAIN_DEFAULT_LANGUAGE_FILTER] = 1; - $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12); + $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly); $out=''; @@ -95,21 +96,28 @@ class FormAdmin { $valuetoshow=$value; if ($showcode == 1) $valuetoshow=$key.' - '.$value; - if ($showcode == 2) $valuetoshow=$value.' ('.$key.')'; + if ($showcode == 2) { + if ($mainlangonly) $valuetoshow=$value.' ('.preg_replace('/[_-].*$/', '', $key).')'; + else $valuetoshow=$value.' ('.$key.')'; + } - if ($filter && is_array($filter) && array_key_exists($key, $filter)) { + $keytouse = $key; + if ($mainlangonly) $keytouse = preg_replace('/[_-].*$/', '', $key); + + if ($filter && is_array($filter) && array_key_exists($keytouse, $filter)) { continue; } - if ($onlykeys && is_array($onlykeys) && ! array_key_exists($key, $onlykeys)) { + if ($onlykeys && is_array($onlykeys) && ! array_key_exists($keytouse, $onlykeys)) { continue; } - if ($selected == $key) + + if ($selected == $keytouse) { - $out.= ''.$valuetoshow.''; + $out.= ''.$valuetoshow.''; } else { - $out.= ''.$valuetoshow.''; + $out.= ''.$valuetoshow.''; } } $out.= ''; diff --git a/htdocs/core/class/html.formwebsite.class.php b/htdocs/core/class/html.formwebsite.class.php index 6cd88175a67..7b067fa11d6 100644 --- a/htdocs/core/class/html.formwebsite.class.php +++ b/htdocs/core/class/html.formwebsite.class.php @@ -269,7 +269,15 @@ class FormWebsite $valueforoption = '['.$valpage->type_container.' '.sprintf("%03d", $valpage->id).'] '; $valueforoption .= $valpage->pageurl.' - '.$valpage->title; - if ($website->fk_default_home && $key == $website->fk_default_home) $valueforoption .= ' ('.$langs->trans("HomePage").')'; + if ($website->otherlang) { // If there is alternative lang for this web site, we show the language code + if ($valpage->lang) { + $valueforoption .= ' ('.$valpage->lang.')'; + } + } + if ($website->fk_default_home && $key == $website->fk_default_home) { + //$valueforoption .= ' ('.$langs->trans("HomePage").')'; + $valueforoption .= ' '; + } $out .= ' 0 && $pageid == $key) $out .= ' selected'; // To preselect a value diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index fb9e292ba83..8a244af2f9e 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -764,28 +764,37 @@ class Translate * @param string $langdir Directory to scan * @param integer $maxlength Max length for each value in combo box (will be truncated) * @param int $usecode 1=Show code instead of country name for language variant, 2=Show only code + * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...) * @return array List of languages */ - public function get_available_languages($langdir = DOL_DOCUMENT_ROOT, $maxlength = 0, $usecode = 0) + public function get_available_languages($langdir = DOL_DOCUMENT_ROOT, $maxlength = 0, $usecode = 0, $mainlangonly = 0) { // phpcs:enable global $conf; + $this->load("languages"); + // We scan directory langs to detect available languages $handle = opendir($langdir."/langs"); $langs_available = array(); while ($dir = trim(readdir($handle))) { - if (preg_match('/^[a-z]+_[A-Z]+/i', $dir)) + $regs = array(); + if (preg_match('/^([a-z]+)_([A-Z]+)/i', $dir, $regs)) { - $this->load("languages"); - + // We must keep only main languages + if ($mainlangonly) { + $arrayofspecialmainlanguages = array('en_US', 'sq_AL', 'ar_SA', 'eu_ES', 'bn_DB', 'bs_BA', 'ca_ES', 'zh_TW', 'cs_CZ', 'da_DK', 'et_EE', 'ka_GE', 'el_GR', 'he_IL', 'kn_IN', 'km_KH', 'ko_KR', 'lo_LA', 'nb_NO', 'fa_IR', 'sr_RS', 'sl_SI', 'uk_UA', 'vi_VN'); + if (strtolower($regs[1]) != strtolower($regs[2]) && ! in_array($dir, $arrayofspecialmainlanguages)) continue; + } + // We must keep only languages into MAIN_LANGUAGES_ALLOWED if (!empty($conf->global->MAIN_LANGUAGES_ALLOWED) && !in_array($dir, explode(',', $conf->global->MAIN_LANGUAGES_ALLOWED))) continue; if ($usecode == 2) { $langs_available[$dir] = $dir; } + if ($usecode == 1 || !empty($conf->global->MAIN_SHOW_LANGUAGE_CODE)) { $langs_available[$dir] = $dir.': '.dol_trunc($this->trans('Language_'.$dir), $maxlength); @@ -794,6 +803,9 @@ class Translate { $langs_available[$dir] = $this->trans('Language_'.$dir); } + if ($mainlangonly) { + $langs_available[$dir] = str_replace(' (United States)', '', $langs_available[$dir]); + } } } return $langs_available; diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index f97c6efed1c..05e70f7912d 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -239,15 +239,15 @@ function dolWebsiteOutput($content, $contenttype = 'html', $containerid = '') { global $website; + $content = str_replace('global->MAIN_UMASK)); } + // Save also alias into language subdirectory if we have to + if ($objectpage->lang && in_array($objectpage->lang, explode(',', $object->otherlang))) { + $dirname = dirname($filealias); + $filename = basename($filealias); + $filealias = $dirname.'/'.$objectpage->lang.'/'.$filename; + + $aliascontent = 'id.'.tpl.php\'; '; + $aliascontent .= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n"; + $aliascontent .= '?>'."\n"; + $result = file_put_contents($filealias, $aliascontent); + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($filealias, octdec($conf->global->MAIN_UMASK)); + } + } + return ($result ?true:false); } @@ -85,6 +104,7 @@ function dolSavePageAlias($filealias, $object, $objectpage) * @param Website $object Object website * @param WebsitePage $objectpage Object websitepage * @return boolean True if OK + * @see dolSavePageAlias() */ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) { @@ -101,7 +121,10 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) $tplcontent = ''; $tplcontent .= "isMultiLang()) { // Add myself - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; // Add page "translation of" $translationof = $objectpage->fk_page; if ($translationof) { @@ -135,7 +158,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) $tmpshortlangcode = ''; if ($tmppage->lang) $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; } } } @@ -152,7 +175,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) $tmpshortlangcode = ''; if ($obj->lang) $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; } } } @@ -160,11 +183,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) else dol_print_error($db); } // Add canonical reference - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; // Add manifest.json on homepage $tplcontent .= 'use_manifest) { print \'\'."\n"; } ?>'."\n"; $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= '/ims\', \'\', file_get_contents(DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html")); ?>'."\n"; $tplcontent .= ''."\n"; diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 9e718148794..0b47a28e058 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -44,6 +44,19 @@ ALTER TABLE llx_commande_fournisseur_dispatch_extrafields ADD INDEX idx_commande -- For v12 +UPDATE llx_website SET lang = 'en' WHERE lang like 'en_%'; +UPDATE llx_website SET lang = 'fr' WHERE lang like 'fr_%'; +UPDATE llx_website SET lang = 'es' WHERE lang like 'es_%'; +UPDATE llx_website SET lang = 'de' WHERE lang like 'de_%'; +UPDATE llx_website SET lang = 'it' WHERE lang like 'it_%'; +UPDATE llx_website SET lang = 'pt' WHERE lang like 'pt_%'; +UPDATE llx_website_page SET lang = 'en' WHERE lang like 'en_%'; +UPDATE llx_website_page SET lang = 'fr' WHERE lang like 'fr_%'; +UPDATE llx_website_page SET lang = 'es' WHERE lang like 'es_%'; +UPDATE llx_website_page SET lang = 'de' WHERE lang like 'de_%'; +UPDATE llx_website_page SET lang = 'it' WHERE lang like 'it_%'; +UPDATE llx_website_page SET lang = 'pt' WHERE lang like 'pt_%'; + ALTER TABLE llx_website ADD COLUMN lang varchar(8); ALTER TABLE llx_website ADD COLUMN otherlang varchar(255); diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 525131b2a61..cc56503c638 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -228,6 +228,8 @@ ErrorFieldRequiredForProduct=Field '%s' is required for product %s ProblemIsInSetupOfTerminal=Problem is in setup of terminal %s. ErrorAddAtLeastOneLineFirst=Add at least one line first ErrorRecordAlreadyInAccountingDeletionNotPossible=Error, record is already transferred in accounting, deletion is not possible. +ErrorLanguageMandatoryIfPageSetAsTranslationOfAnother=Error, language is mandatory if you set the page as a translation of another one. +ErrorLanguageOfTranslatedPageIsSameThanThisPage=Error, language of translated page is same than this one. # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index 99c9b6486e0..6185183161b 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -65,7 +65,7 @@ Language_mk_MK=Macedonian Language_mn_MN=Mongolian Language_nb_NO=Norwegian (Bokmål) Language_nl_BE=Dutch (Belgium) -Language_nl_NL=Dutch (Netherlands) +Language_nl_NL=Dutch Language_pl_PL=Polish Language_pt_BR=Portuguese (Brazil) Language_pt_PT=Portuguese diff --git a/htdocs/public/website/index.php b/htdocs/public/website/index.php index f96ab2b0778..81781cbf8ee 100644 --- a/htdocs/public/website/index.php +++ b/htdocs/public/website/index.php @@ -13,6 +13,15 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * + * Note about $_SERVER: + * REQUEST_URI: /test/before_rewrite/script.php/path/info?q=helloword + * PHP_SELF: /test/after_rewrite/script.php/path/info + * QUERY_STRING: q=helloword + * SCRIPT_NAME: /test/after_rewrite/script.php + * PATH_INFO: /path/info + * SCRIPT_FILENAME: /var/www/test/php/script.php + * __FILE__ : /var/www/test/php/script_included.php */ /** @@ -110,7 +119,7 @@ if (empty($pageid)) if (empty($pageid)) { - $array=$objectpage->fetchAll($object->id); + $array=$objectpage->fetchAll($object->id); // TODO Can filter on container of type pages only ? if (is_array($array) && count($array) > 0) { $firstrep=reset($array); diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 927d54f5b29..f41ecfab09b 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -170,6 +170,15 @@ class Website extends CommonObject if (empty($this->date_modification)) { $this->date_modification = $now; } + // Remove spaces and be sure we have main language only + $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en + $tmparray = explode(',', $this->otherlang); + if (is_array($tmparray)) { + foreach($tmparray as $key => $val) { + $tmparray[$key] = preg_replace('/[_-].*$/', '', trim($val)); // en_US or en-US -> en + } + $this->otherlang = join(',', $tmparray); + } // Check parameters if (empty($this->entity)) { @@ -456,6 +465,16 @@ class Website extends CommonObject $this->status = (int) $this->status; } + // Remove spaces and be sure we have main language only + $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en + $tmparray = explode(',', $this->otherlang); + if (is_array($tmparray)) { + foreach($tmparray as $key => $val) { + $tmparray[$key] = preg_replace('/[_-].*$/', '', trim($val)); // en_US or en-US -> en + } + $this->otherlang = join(',', $tmparray); + } + // Check parameters // Put here code to add a control on parameters values @@ -837,7 +856,7 @@ class Website extends CommonObject $this->ref = 'myspecimenwebsite'; $this->description = 'A specimen website'; $this->lang = 'en'; - $this->otherlang = 'fr,es_MX'; + $this->otherlang = 'fr,es'; $this->status = ''; $this->fk_default_home = null; $this->virtualhost = 'http://myvirtualhost'; @@ -1178,7 +1197,11 @@ class Website extends CommonObject // The move is not enough, so we regenerate page $filetpl = $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php'; - dolSavePageContent($filetpl, $object, $objectpagestatic); + $result = dolSavePageContent($filetpl, $object, $objectpagestatic); + if (!$result) { + $this->errors[] = 'Failed to write file '.basename($filetpl); + $error++; + } // Regenerate alternative aliases pages if (is_array($aliasesarray)) @@ -1188,7 +1211,11 @@ class Website extends CommonObject if (trim($aliasshortcuttocreate)) { $filealias = $conf->website->dir_output.'/'.$object->ref.'/'.trim($aliasshortcuttocreate).'.php'; - dolSavePageAlias($filealias, $object, $objectpagestatic); + $result = dolSavePageAlias($filealias, $object, $objectpagestatic); + if (!$result) { + $this->errors[] = 'Failed to write file '.basename($filealias); + $error++; + } } } } diff --git a/htdocs/website/class/websitepage.class.php b/htdocs/website/class/websitepage.class.php index e260ddea3a3..c9fdc81b5bd 100644 --- a/htdocs/website/class/websitepage.class.php +++ b/htdocs/website/class/websitepage.class.php @@ -158,6 +158,9 @@ class WebsitePage extends CommonObject $this->keywords = dol_trunc($this->keywords, 255, 'right', 'utf-8', 1); if ($this->aliasalt) $this->aliasalt = ','.preg_replace('/,+$/', '', preg_replace('/^,+/', '', $this->aliasalt)).','; // content in database must be ',xxx,...,yyy,' + // Remove spaces and be sure we have main language only + $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en + return $this->createCommon($user, $notrigger); } @@ -377,6 +380,22 @@ class WebsitePage extends CommonObject $this->keywords = dol_trunc($this->keywords, 255, 'right', 'utf-8', 1); if ($this->aliasalt) $this->aliasalt = ','.preg_replace('/,+$/', '', preg_replace('/^,+/', '', $this->aliasalt)).','; // content in database must be ',xxx,...,yyy,' + // Remove spaces and be sure we have main language only + $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en + + if ($this->fk_page > 0) { + if (empty($this->lang)) { + $this->error = "ErrorLanguageMandatoryIfPageSetAsTranslationOfAnother"; + return -1; + } + $tmppage = new WebsitePage($this->db); + $tmppage->fetch($this->fk_page); + if ($tmppage->lang == $this->lang) { + $this->error = "ErrorLanguageOfTranslatedPageIsSameThanThisPage"; + return -1; + } + } + return $this->updateCommon($user, $notrigger); } @@ -513,7 +532,8 @@ class WebsitePage extends CommonObject $label .= ''; $label .= ''.$langs->trans('Ref').': '.$this->ref.''; $label .= ''.$langs->trans('ID').': '.$this->id.''; - $label .= ''.$langs->trans('Title').': '.$this->title; + $label .= ''.$langs->trans('Title').': '.$this->title.''; + $label .= ''.$langs->trans('Language').': '.$this->lang; $url = DOL_URL_ROOT.'/website/index.php?websiteid='.$this->fk_website.'&pageid='.$this->id; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index cd00989b339..d6cc3608869 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -860,7 +860,7 @@ if ($action == 'addcontainer') $result = dolSavePageAlias($filealias, $object, $objectpage); if (!$result) { - setEventMessages('Failed to write file '.$filealias, null, 'errors'); + setEventMessages('Failed to write file '.basename($filealias), null, 'errors'); } // Save page of content @@ -1499,8 +1499,9 @@ if ($action == 'updatemeta') { if (trim($tmpaliasalt)) { - $result = dolSavePageAlias($pathofwebsite.'/'.trim($tmpaliasalt).'.php', $object, $objectpage); - if (!$result) setEventMessages('Failed to write file '.$pathofwebsite.'/'.trim($tmpaliasalt).'.php', null, 'errors'); + $filealias = $pathofwebsite.'/'.trim($tmpaliasalt).'.php'; + $result = dolSavePageAlias($filealias, $object, $objectpage); + if (!$result) setEventMessages('Failed to write file '.basename($filealias), null, 'errors'); } } } @@ -1756,7 +1757,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf // Save page alias $result = dolSavePageAlias($filealias, $object, $objectpage); - if (!$result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + if (!$result) setEventMessages('Failed to write file '.basename($filealias), null, 'errors'); // Save page content $result = dolSavePageContent($filetpl, $object, $objectpage); @@ -2702,7 +2703,7 @@ if ($action == 'editcss') $htmltext=''; print $form->textwithpicto($langs->trans('MainLanguage'), $htmltext, 1, 'help', '', 0, 2, 'WEBSITE_LANG'); print ''; - print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : ($object->lang ? $object->lang : '0')), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2); + print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : ($object->lang ? $object->lang : '0')), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1); print ''; print ''; @@ -2861,7 +2862,7 @@ if ($action == 'createsite') print ''; print $langs->trans('MainLanguage'); print ''; - print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : '0'), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2); + print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : '0'), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1); print ''; print ''; @@ -3104,7 +3105,7 @@ if ($action == 'editmeta' || $action == 'createcontainer') foreach($tmparray as $key) { $tmpkey = trim($key); if (strlen($key) == 2) { - $tmpkey = strtolower($key).'_'.strtoupper($tmpkey); + $tmpkey = strtolower($key); } $onlykeys[$tmpkey] = $tmpkey; } @@ -3112,7 +3113,7 @@ if ($action == 'editmeta' || $action == 'createcontainer') if (empty($object->lang) && empty($object->otherlang)) { $onlykeys = null; // We keep full list of languages } - print $formadmin->select_language($pagelang ? $pagelang : '', 'WEBSITE_LANG', 0, null, '1', 0, 0, 'minwidth200', 0, 0, 0, $onlykeys); + print $formadmin->select_language($pagelang ? $pagelang : '', 'WEBSITE_LANG', 0, null, '1', 0, 0, 'minwidth200', 0, 0, 0, $onlykeys, 1); $htmltext = $langs->trans("AvailableLanguagesAreDefinedIntoWebsiteProperties"); print $form->textwithpicto('', $htmltext); print '';