1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-10 08:44:46 +02:00

Various updates primarily aimed at simplifying the check for presence of LanguageSupportPageNames module

This commit is contained in:
Ryan Cramer
2021-10-04 11:13:25 -04:00
parent f61feb56fd
commit 3cf1ba5cab
18 changed files with 173 additions and 113 deletions

View File

@@ -351,10 +351,12 @@ class MarkupQA extends Wire {
if(!preg_match_all($re, $value, $matches)) return;
$replacements = array();
$languages = $this->wire('languages');
$languages = $this->wire()->languages;
$debug = $this->debug();
$config = $this->wire()->config;
$pages = $this->wire()->pages;
if($languages && !$this->wire('modules')->isInstalled('LanguageSupportPageNames')) $languages = null;
if($languages && !$languages->hasPageNames()) $languages = null;
foreach($matches[3] as $key => $path) {
@@ -370,7 +372,7 @@ class MarkupQA extends Wire {
// scheme and hostname present
/** @noinspection PhpUnusedLocalVariableInspection */
list($x, $host) = explode('//', $href);
if($host != $this->wire('config')->httpHost && !in_array($host, $this->wire('config')->httpHosts)) {
if($host != $config->httpHost && !in_array($host, $config->httpHosts)) {
$counts['external']++;
if($debug) $this->message("MarkupQA sleepLinks skipping because hostname: $host");
// external hostname, which we will skip over
@@ -415,11 +417,11 @@ class MarkupQA extends Wire {
'allowUrlSegments' => true,
'useHistory' => true
);
$page = $this->wire()->pages->getByPath($path, $getByPathOptions);
$page = $pages->getByPath($path, $getByPathOptions);
if(!$page->id) {
// if not found try again with non-urlSegment partial matching
$getByPathOptions['allowUrlSegments'] = false;
$page = $this->wire()->pages->getByPath($path, $getByPathOptions);
$page = $pages->getByPath($path, $getByPathOptions);
}
$pageID = $page->id;
@@ -430,7 +432,7 @@ class MarkupQA extends Wire {
if($languages) {
/** @var Language $language */
$language = $this->wire('modules')->get('LanguageSupportPageNames')->getPagePathLanguage($path, $page);
$language = $languages->pageNames()->getPagePathLanguage($path, $page);
$pwid = !$language || $language->isDefault() ? $pageID : "$pageID-$language";
} else {
$language = null;

View File

@@ -2586,8 +2586,7 @@ class PageFinder extends Wire {
}
}
if($langNames) {
/** @var LanguageSupportPageNames $module */
$module = $modules->getModule('LanguageSupportPageNames');
$module = $this->languages->pageNames();
if($module) $selectorValue = $module->updatePath($selectorValue);
}
$parts = explode('/', rtrim($selectorValue, '/'));
@@ -3369,8 +3368,8 @@ class PageFinder extends Wire {
*/
protected function supportsLanguagePageNames() {
if($this->supportsLanguagePageNames === null) {
$modules = $this->wire()->modules;
$this->supportsLanguagePageNames = $this->languages && $modules->isInstalled('LanguageSupportPageNames');
$languages = $this->languages;
$this->supportsLanguagePageNames = $languages && $languages->hasPageNames();
}
return $this->supportsLanguagePageNames;
}

View File

@@ -636,7 +636,7 @@ class PageTraversal {
$options = is_array($options) ? array_merge($defaults, $options) : $defaults;
$sanitizer = $page->wire()->sanitizer;
$input = $page->wire()->input;
$modules = $page->wire()->modules;
$languages = $page->wire()->languages;
$language = null;
$url = null;
@@ -665,7 +665,7 @@ class PageTraversal {
}
}
if($options['language'] && $modules->isInstalled('LanguageSupportPageNames')) {
if($options['language'] && $languages && $languages->hasPageNames()) {
if(!is_object($options['language'])) {
$options['language'] = null;
} else if(!$options['language'] instanceof Page) {
@@ -699,10 +699,8 @@ class PageTraversal {
}
if((int) $options['pageNum'] > 1) {
$prefix = '';
if($language) {
/** @var LanguageSupportPageNames $lsp */
$lsp = $modules->get('LanguageSupportPageNames');
$prefix = $lsp ? $lsp->get("pageNumUrlPrefix$language") : '';
if($language && $languages && $languages->hasPageNames()) {
$prefix = $languages->pageNames()->get("pageNumUrlPrefix$language");
}
if(!strlen($prefix)) $prefix = $config->pageNumUrlPrefix;
$url = rtrim($url, '/') . '/' . $prefix . ((int) $options['pageNum']);
@@ -788,7 +786,7 @@ class PageTraversal {
}
// include other language URLs
if($languages && $modules->isInstalled('LanguageSupportPageNames')) {
if($languages && $languages->hasPageNames()) {
foreach($languages as $language) {
if(!$language->isDefault() && !$page->get("status$language")) continue;
$urls[$language->name] = $page->localUrl($language);

View File

@@ -1219,7 +1219,7 @@ class Pages extends Wire {
* 'response' => 200, // one of 200, 301, 302, 404, 414
* 'type' => 'ok', // response type name
* 'errors' => [], // array of error messages indexed by error name
* 'redirect` => '/redirect/path/', // suggested path to redirect to or blank
* 'redirect' => '/redirect/path/', // suggested path to redirect to or blank
* 'page' => [
* 'id' => 123, // ID of the page that was found
* 'parent_id' => 456,

View File

@@ -391,7 +391,7 @@ class PagesExportImport extends Wire {
}
// include multi-language page names and statuses when applicable
if($languages && $this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
if($languages && $languages->hasPageNames()) {
foreach($languages as $language) {
if($language->isDefault()) continue;
$settings["name_$language->name"] = $page->get("name$language->id");
@@ -542,8 +542,10 @@ class PagesExportImport extends Wire {
throw new WireException('Invalid array provided to arrayToPage() method');
}
/** @var Config $config */
$config = $this->wire('config');
$config = $this->wire()->config;
$pages = $this->wire()->pages;
$languages = $this->wire()->languages;
$fields = $this->wire()->fields;
$defaults = array(
'id' => 0, // ID that new Page should use, or update, if it already exists. (0=create new). Sets update=true.
@@ -573,8 +575,6 @@ class PagesExportImport extends Wire {
$errors = array(); // fatal errors
$warnings = array(); // non-fatal warnings
$messages = array(); // informational
$pages = $this->wire('pages');
$languages = $this->wire('languages');
$missingFields = array();
if($options['id']) {
@@ -623,7 +623,7 @@ class PagesExportImport extends Wire {
if(count($options['fieldNames']) && !in_array($name, $options['fieldNames'])) continue;
if(isset($options['replaceFields'][$name])) $name = $options['replaceFields'][$name];
$field = $this->wire('fields')->get($name);
$field = $fields->get($name);
if(!$field) {
if(is_array($value) && !count($value)) continue;

View File

@@ -1378,11 +1378,12 @@ class PagesLoader extends Wire {
$id = (int) $id;
if(!$id || $id < 0) return '';
$languages = $this->wire('languages');
if($languages && !$this->wire('modules')->isInstalled('LanguageSupportPageNames')) $languages = null;
$languages = $this->wire()->languages;
if($languages && !$languages->hasPageNames()) $languages = null;
$language = $options['language'];
$languageID = 0;
$homepageID = (int) $this->wire('config')->rootPageID;
$homepageID = (int) $this->wire()->config->rootPageID;
if(!empty($language) && $languages) {
if(is_string($language) || is_int($language)) $language = $languages->get($language);
@@ -1548,8 +1549,9 @@ class PagesLoader extends Wire {
$path = $sanitizer->pagePathName($path, Sanitizer::toAscii);
$pathParts = explode('/', trim($path, '/'));
$_pathParts = $pathParts;
$languages = $options['useLanguages'] ? $this->wire()->languages : null;
if($languages && !$modules->isInstalled('LanguageSupportPageNames')) $languages = null;
if($languages && !$languages->hasPageNames()) $languages = null;
$langKeys = array(':name' => 'name');
if($languages) foreach($languages as $language) {

View File

@@ -613,8 +613,8 @@ class PagesNames extends Wire {
);
$options = array_merge($defaults, $options);
$languages = $options['multilang'] || $options['language'] ? $this->wire('languages') : null;
if($languages && !$this->wire('modules')->isInstalled('LanguageSupportPageNames')) $languages = null;
$languages = $options['multilang'] || $options['language'] ? $this->wire()->languages : null;
if($languages && !$languages->hasPageNames()) $languages = null;
if($this->wire('config')->pageNameCharset == 'UTF8') {
$name = $this->wire('sanitizer')->pageName($name, Sanitizer::toAscii);

View File

@@ -1245,7 +1245,7 @@ class PagesPathFinder extends Wire {
$this->useLanguages = array();
return array();
}
if(!$this->wire()->modules->isInstalled('LanguageSupportPageNames')) {
if(!$languages->hasPageNames()) {
$this->useLanguages = array();
return array();
}

View File

@@ -75,8 +75,8 @@ class PagesTrash extends Wire {
$page->name = ($name . "_" . $page->name);
// do the same for other languages, if present
$languages = $this->wire('languages');
if($languages && $this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
$languages = $this->wire()->languages;
if($languages && $languages->hasPageNames()) {
foreach($languages as $language) {
if($language->isDefault()) continue;
$langName = $page->get("name$language->id");
@@ -153,9 +153,8 @@ class PagesTrash extends Wire {
'namePrevious' => '',
);
/** @var Languages|array $languages */
$languages = $this->wire('languages');
if(!$languages || !$this->wire('modules')->isInstalled('LanguageSupportPageNames')) $languages = array();
$languages = $this->wire()->languages;
if(!$languages || !$languages->hasPageNames()) $languages = array();
// initialize name properties in $info for each language
foreach($languages as $language) {

View File

@@ -736,7 +736,8 @@ class LanguageSupport extends WireData implements Module, ConfigurableModule {
if($field == 'name') {
// set page name
if(!$this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
$languages = $this->wire()->languages;
if($languages && !$languages->hasPageNames()) {
throw new WireException("Please install LanguageSupportPageNames module before attempting to set multi-language names/paths/URLs.");
}
if($language->isDefault()) {

View File

@@ -1331,9 +1331,7 @@ class LanguageSupportPageNames extends WireData implements Module, ConfigurableM
$modules = $this->wire()->modules;
$config = $this->wire()->config;
/** @var LanguageSupportPageNames $module */
$module = $modules->get('LanguageSupportPageNames');
$module->checkModuleVersion(true);
$this->checkModuleVersion(true);
$defaultUrlPrefix = $config->get('_pageNumUrlPrefix|pageNumUrlPrefix');

View File

@@ -18,13 +18,14 @@
*
* #pw-body
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
* @property LanguageTabs|null $tabs Current LanguageTabs module instance, if installed #pw-internal
* @property Language $default Get default language
* @property Language $getDefault Get default language (alias of $default)
* @property LanguageSupport $support Instance of LanguageSupport module #pw-internal
* @property LanguageSupportPageNames|false $pageNames Instance of LanguageSupportPageNames module or false if not installed 3.0.186+ #pw-internal
*
* @method added(Page $language) Hook called when Language is added #pw-hooker
* @method deleted(Page $language) Hook called when Language is deleted #pw-hooker
@@ -98,10 +99,14 @@ class Languages extends PagesType {
protected $editableCache = array();
/**
* @var LanguageSupportPageNames|null|false
* LanguageSupportPageNames module instance or boolean install state
*
* Populated as a cache by the pageNames() or hasPageNames() methods
*
* @var LanguageSupportPageNames|null|bool
*
*/
protected $languageSupportPageNames = null;
protected $pageNames = null;
/**
* Construct
@@ -613,19 +618,41 @@ class Languages extends PagesType {
/**
* Get LanguageSupportPageNames module if installed, false if not
*
* @return LanguageSupportPageNames|bool
* @return LanguageSupportPageNames|false
* @since 3.0.186
*
*/
public function pageNames() {
if($this->languageSupportPageNames === null) {
// null when not known, true when previously detected as installed but instance not yet loaded
if($this->pageNames === null || $this->pageNames === true) {
$modules = $this->wire()->modules;
if($modules->isInstalled('LanguageSupportPageNames')) {
$this->languageSupportPageNames = $modules->getModule('LanguageSupportPageNames');
// installed: load instance
$this->pageNames = $modules->getModule('LanguageSupportPageNames');
} else {
$this->languageSupportPageNames = false;
// not installed
$this->pageNames = false;
}
}
return $this->languageSupportPageNames;
// object instance or boolean false
return $this->pageNames;
}
/**
* Is LanguageSupportPageNames installed?
*
* @return bool
* @since 3.0.186
*
*/
public function hasPageNames() {
// if previously identified as installed or instance loaded, return true
if($this->pageNames) return true;
// if previously identified as NOT installed, return false
if($this->pageNames=== false) return false;
// populate with installed status boolean and return it
$this->pageNames = $this->wire()->modules->isInstalled('LanguageSupportPageNames');
return $this->pageNames;
}
/**
@@ -771,9 +798,18 @@ class Languages extends PagesType {
*
*/
public function __get($key) {
if($key === 'tabs') return $this->wire()->modules->get('LanguageSupport')->getLanguageTabs();
if($key === 'default') return $this->getDefault();
if($key === 'support') return $this->wire()->modules->get('LanguageSupport');
if($key === 'tabs') {
$ls = $this->wire()->modules->get('LanguageSupport'); /** @var LanguageSupport $ls */
return $ls->getLanguageTabs();
} else if($key === 'default') {
return $this->getDefault();
} else if($key === 'support') {
return $this->wire()->modules->get('LanguageSupport');
} else if($key === 'pageNames') {
return $this->pageNames();
} else if($key === 'hasPageNames') {
return $this->hasPageNames();
}
return parent::__get($key);
}

View File

@@ -98,8 +98,8 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
*/
protected function getLanguages() {
if($this->getVersion() < 2) return false;
if(!$this->wire('modules')->isInstalled('LanguageSupportPageNames')) return false;
return $this->wire('languages');
$languages = $this->wire()->languages;
return $languages && $languages->hasPageNames() ? $languages : false;
}
/**
@@ -265,11 +265,9 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
'virtual' => true,
);
/** @var WireDatabasePDO $database */
$database = $this->wire('database');
/** @var Sanitizer $sanitizer */
$sanitizer = $this->wire('sanitizer');
$database = $this->wire()->database;
$sanitizer = $this->wire()->sanitizer;
$languages = $this->wire()->languages;
$paths = array();
$options = is_array($options) ? array_merge($defaults, $options) : $defaults;
@@ -278,7 +276,7 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
$options['language'] = null;
$allowLanguage = false;
} else {
$allowLanguage = $this->wire('languages') && $this->wire('modules')->isInstalled('LanguageSupportPageNames');
$allowLanguage = $languages && $languages->hasPageNames();
}
$language = $options['language'] && $allowLanguage ? $this->getLanguage($options['language']) : null;
@@ -529,7 +527,7 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
$languages = $this->getLanguages();
$age = time() - $page->created;
if($page->template == 'admin' || $this->wire('pages')->cloning || $age < $this->minimumAge) return;
if($page->template->name === 'admin' || $this->wire()->pages->cloning || $age < $this->minimumAge) return;
// note that the paths we store have no trailing slash
@@ -626,11 +624,10 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
}
$languages = $this->getLanguages();
if($languages) {
$languagePageNames = $languages ? $languages->pageNames() : null;
if($languagePageNames) {
// the LanguageSupportPageNames may change the original requested path, so we ask it for the original
/** @var LanguageSupportPageNames $lspn */
$lspn = $this->wire()->modules->get('LanguageSupportPageNames');
$path = $lspn->getRequestPath();
$path = $languagePageNames->getRequestPath();
$path = $path ? $this->wire()->sanitizer->pagePathName($path) : $event->arguments(1);
} else {
$path = $event->arguments(1);
@@ -743,20 +740,23 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
"LEFT JOIN pages ON $table.pages_id=pages.id " .
"WHERE " . implode(' OR ', $wheres);
$query = $database->prepare($sql);
try {
$query = $database->prepare($sql);
foreach($binds as $bindKey => $bindValue) {
$query->bindValue(":$bindKey", $bindValue);
}
$query->execute();
$rowCount = $query->rowCount();
if(!$rowCount) {
$query->closeCursor();
return $result;
} catch(\Exception $e) {
if(!$this->checkTableSchema()) throw $e;
$rowCount = 0;
$query = null;
}
if(!$rowCount || $query) return $result;
$rows = array();
$pathCounts = array();
$matchRow = null;
@@ -899,10 +899,9 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
));
if($page->id) {
// found a page
if($languages) {
/** @var LanguageSupportPageNames $lspn */
$lspn = $this->wire()->modules->get('LanguageSupportPageNames');
$language = $lspn->getPagePathLanguage($path, $page);
$languagePageNames = $languages ? $languages->pageNames() : null;
if($languagePageNames) {
$language = $languagePageNames->getPagePathLanguage($path, $page);
if($language) $page->setQuietly('_language', $language);
}
} else if($level < self::maxSegments) {
@@ -975,6 +974,31 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
return $path;
}
/**
* Check table schema and update as needed
*
* @return bool True if schema updated, false if not
*
*/
protected function checkTableSchema() {
$database = $this->wire()->database;
$table = self::dbTableName;
$updated = false;
if(!$database->columnExists($table, 'language_id')) {
try {
$database->exec("ALTER TABLE $table ADD language_id INT UNSIGNED DEFAULT 0");
$this->message("Added 'language_id' column to table $table", Notice::debug);
$updated = true;
} catch(\Exception $e) {
$this->error($e->getMessage(), Notice::superuser | Notice::log);
}
}
return $updated;
}
/**
* Install
*
@@ -1013,24 +1037,9 @@ class PagePathHistory extends WireData implements Module, ConfigurableModule {
*
*/
public function ___upgrade($fromVersion, $toVersion) {
if($fromVersion == 1) {
$messagePrefix = "PagePathHistory v$fromVersion => v$toVersion: ";
$database = $this->wire('database');
$table = self::dbTableName;
try {
$database->exec("ALTER TABLE $table ADD language_id INT UNSIGNED DEFAULT 0");
$message = "Added 'language_id' column";
$error = false;
} catch(\Exception $e) {
$error = true;
$message = $e->getMessage();
}
$message = $messagePrefix . $message;
$error ? $this->error($message) : $this->message($message);
if($fromVersion != $toVersion) {
$this->checkTableSchema();
$this->message("PagePathHistory v$fromVersion => v$toVersion");
}
}

View File

@@ -545,7 +545,7 @@ class PagePaths extends WireData implements Module, ConfigurableModule {
$languages = $this->wire()->languages;
if(!$languages) {
$this->languages = false;
} else if($this->wire()->modules->isInstalled('LanguageSupportPageNames')) {
} else if($languages->hasPageNames()) {
$this->languages = $languages;
} else {
$this->languages = false;
@@ -652,29 +652,43 @@ class PagePaths extends WireData implements Module, ConfigurableModule {
$session = $this->wire()->session;
$input = $this->wire()->input;
$numPages = 0;
$numRows = -1;
if($input->requestMethod('POST')) {
if($input->post('_rebuild')) $session->setFor($this, 'rebuild', true);
$numPages = 0;
$eta = 0;
} else {
$numPages = $this->wire()->pages->count("id>0, include=all");
$eta = ($numPages / 1000) * 1.1;
if($session->getFor($this, 'rebuild')) {
$session->removeFor($this, 'rebuild');
$timer = Debug::timer();
$this->rebuild();
$elapsed = Debug::timer($timer);
$this->message(sprintf($this->_('Completed rebuild in %d seconds'), $elapsed), Notice::noGroup);
} else {
$table = self::dbTableName;
try {
$query = $this->wire()->database->prepare("SELECT COUNT(*) FROM $table");
$query->execute();
$numRows = (int) $query->fetchColumn();
} catch(\Exception $e) {
}
}
}
$f = $inputfields->InputfieldCheckbox;
$f->attr('name', '_rebuild');
$f->label = sprintf($this->_('Rebuild page paths index for %d pages'), $numPages);
$f->label2 = $this->_('Rebuild now');
$f->description = sprintf($this->_('Estimated rebuild time is roughly %01.1f seconds.'), $eta);
if($numPages) $f->description =
$this->_('Estimated rebuild time is up to 5 seconds per 1000 pages.') . ' ' .
sprintf($this->_('There are %d pages to process.'), $numPages);
if($numRows > 0) {
$f->notes = sprintf($this->_('There are currently %d rows stored by this module (path paths and versions of path paths).'), $numRows);
} else if($numRows === 0 && $input->requestMethod('GET')) {
$this->warning($this->_('Please choose the “rebuild now” option to create your page paths index.'));
}
$inputfields->add($f);
}

View File

@@ -190,8 +190,10 @@ class ProcessPageClone extends Process {
'n' => $n
);
if($this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
foreach($this->wire('languages') as $language) {
$languages = $this->wire()->languages;
if($languages && $languages->hasPageNames()) {
foreach($languages as $language) {
if($language->isDefault()) continue;
$value = $page->get("name$language");
if(!strlen($value)) continue;
@@ -243,7 +245,7 @@ class ProcessPageClone extends Process {
$titleUseLanguages = $title
&& $page->template->fieldgroup->hasField($title)
&& $title->getInputfield($page)->getSetting('useLanguages');
$nameUseLanguages = $this->wire('modules')->isInstalled('LanguageSupportPageNames');
$nameUseLanguages = $languages->hasPageNames();
if($titleUseLanguages) $titleField->useLanguages = true;
if($nameUseLanguages) $nameField->useLanguages = true;
foreach($languages as $language) {

View File

@@ -444,7 +444,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
// optional language GET var
$languages = $this->wire()->languages;
if($languages) {
$this->hasLanguagePageNames = $this->modules->isInstalled('LanguageSupportPageNames');
$this->hasLanguagePageNames = $languages->hasPageNames();
if($this->hasLanguagePageNames) {
$languageID = (int) $this->input->get('language');
if($languageID > 0) {
@@ -1491,7 +1491,7 @@ class ProcessPageEdit extends Process implements WirePageEditor, ConfigurableMod
'virtual' => true
));
$multilang = $languages && $modules->isInstalled('LanguageSupportPageNames');
$multilang = $languages && $languages->hasPageNames();
$slashUrls = $this->page->template->slashUrls;
$deleteIDs = array();
$rootUrl = $this->wire('config')->urls->root;

View File

@@ -648,8 +648,7 @@ class ProcessPageLister extends Process implements ConfigurableModule {
$template = $this->template;
$customFields = array();
$languages = $this->wire('languages'); /** @var Languages $languages */
$modules = $this->wire('modules'); /** @var @var Modules $modules */
$languagePageNames = $languages && $modules->isInstalled('LanguageSupportPageNames') && method_exists($this, '___executeSave');
$languagePageNames = $languages && $languages->hasPageNames() && method_exists($this, '___executeSave');
$asmParents = array('name', 'path', 'url', 'httpUrl');
$asmParentValueSuffix = ' …';
@@ -1363,7 +1362,7 @@ class ProcessPageLister extends Process implements ConfigurableModule {
$hooks = $this->wire('hooks');
if($languages && $p->template->noLang) $languages = null;
$langPageNames = $languages && $this->wire('modules')->isInstalled('LanguageSupportPageNames');
$langPageNames = $languages && $languages->hasPageNames();
$subname = '';
$fullname = $name;

View File

@@ -345,8 +345,9 @@ class ProcessProfile extends Process implements ConfigurableModule, WirePageEdit
$user->name = $userName;
if($this->wire()->modules->isInstalled('LanguageSupportPageNames')) {
foreach($this->wire()->languages as $language) {
$languages = $this->wire()->languages;
if($languages && $languages->hasPageNames()) {
foreach($languages as $language) {
if(!$language->isDefault()) $user->set("name$language->id", $userName);
}
}