artabro/wire/modules/LanguageSupport/LanguageSupportInstall.php

345 lines
12 KiB
PHP
Raw Permalink Normal View History

2024-08-27 11:35:37 +02:00
<?php namespace ProcessWire;
/**
* Installer and uninstaller for LanguageSupport module
*
* Split off into a seprate class/file because it's only needed once and
* didn't want to keep all this code in the main module that's loaded every request.
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* https://processwire.com
*
* @method void install()
* @method void uninstall()
*
*
*/
class LanguageSupportInstall extends Wire {
/**
* Install the module and related modules
*
*/
public function ___install() {
$configData = array();
if($this->templates->get(LanguageSupport::languageTemplateName))
throw new WireException("There is already a template installed called 'language'");
if($this->fields->get(LanguageSupport::languageFieldName))
throw new WireException("There is already a field installed called 'language'");
$adminPage = $this->pages->get($this->config->adminRootPageID);
$setupPage = $adminPage->child("name=setup");
if(!$setupPage->id) throw new WireException("Unable to locate {$adminPage->path}setup/");
// create the languages parent page
$languagesPage = $this->wire('pages')->newPage('admin');
$languagesPage->parent = $setupPage;
$languagesPage->process = $this->modules->get('ProcessLanguage'); // INSTALL ProcessLanguage module
$this->message("Installed ProcessLanguage");
$languagesPage->name = 'languages';
$languagesPage->title = 'Languages';
$languagesPage->status = Page::statusSystem;
$languagesPage->sort = $setupPage->numChildren;
$languagesPage->save();
$configData['languagesPageID'] = $languagesPage->id;
// create the fieldgroup to be used by the language template
/** @var Fieldgroup $fieldgroup */
$fieldgroup = $this->wire(new Fieldgroup());
$fieldgroup->name = LanguageSupport::languageTemplateName;
$fieldgroup->add($this->fields->get('title'));
$fieldgroup->save();
$this->message("Created fieldgroup: " . LanguageSupport::languageTemplateName . " ($fieldgroup->id)");
$this->addFilesFields($fieldgroup);
// create the template used by Language pages
/** @var Template $template */
$template = $this->wire(new Template());
$template->name = LanguageSupport::languageTemplateName;
$template->fieldgroup = $fieldgroup;
$template->parentTemplates = array($adminPage->template->id);
$template->slashUrls = 1;
$template->pageClass = 'Language';
$template->pageLabelField = 'name';
$template->noGlobal = 1;
$template->noMove = 1;
$template->noTrash = 1;
$template->noUnpublish = 1;
$template->noChangeTemplate = 1;
$template->nameContentTab = 1;
$template->flags = Template::flagSystem;
$template->save();
$this->message("Created Template: " . LanguageSupport::languageTemplateName);
// create the default language page
$default = $this->wire(new Language());
$default->template = $template;
$default->parent = $languagesPage;
$default->name = 'default';
$default->title = 'Default';
$default->status = Page::statusSystem;
$default->save();
$configData['defaultLanguagePageID'] = $default->id;
$configData['otherLanguagePageIDs'] = array(); // non-default language IDs placeholder
$this->message("Created Default Language Page: {$default->path}");
// create the translator page and process
$translatorPage = $this->wire('pages')->newPage('admin');
$translatorPage->parent = $setupPage;
$translatorPage->status = Page::statusHidden | Page::statusSystem;
$translatorPage->process = $this->modules->get('ProcessLanguageTranslator'); // INSTALL ProcessLanguageTranslator
$this->message("Installed ProcessLanguageTranslator");
$translatorPage->name = 'language-translator';
$translatorPage->title = 'Language Translator';
$translatorPage->save();
$configData['languageTranslatorPageID'] = $translatorPage->id;
$this->message("Created Language Translator Page: {$translatorPage->path}");
// save the module config data
$this->modules->saveModuleConfigData('LanguageSupport', $configData);
// install 'language' field that will be added to the user fieldgroup
$field = $this->wire(new Field());
$field->type = $this->modules->get("FieldtypePage");
$field->name = LanguageSupport::languageFieldName;
$field->label = 'Language';
$field->derefAsPage = 1;
$field->parent_id = $languagesPage->id;
$field->labelFieldName = 'title';
$field->inputfield = 'InputfieldRadios';
$field->required = 1;
$field->flags = Field::flagSystem | Field::flagPermanent;
$field->save();
$this->message("Created Langage Field: " . LanguageSupport::languageFieldName);
// make the 'language' field part of the profile fields the user may edit
$profileConfig = $this->modules->getModuleConfigData('ProcessProfile');
$profileConfig['profileFields'][] = 'language';
$this->modules->saveModuleConfigData('ProcessProfile', $profileConfig);
// add to 'user' fieldgroup
$userFieldgroup = $this->templates->get('user')->fieldgroup;
$userFieldgroup->add($field);
$userFieldgroup->save();
$this->message("Added field 'language' to user profile");
// update all users to have the default value set for this field
$n = 0;
foreach($this->users as $user) {
$user->set('language', $default);
$user->save();
$n++;
}
$this->message("Added default language to $n user profiles");
$this->message("Language Support Installed! Click to the 'Setup' menu to begin defining languages.");
}
/**
* @param Fieldgroup $fieldgroup
*
*/
public function addFilesFields($fieldgroup) {
// create the 'language_files_site' field used by the 'language' fieldgroup
/** @var FieldtypeFile $field */
$field = $this->wire('fields')->get('language_files_site');
if(!$field) {
$field = $this->wire(new Field());
$field->type = $this->modules->get("FieldtypeFile");
$field->name = 'language_files_site';
$field->label = 'Site Translation Files';
$field->extensions = 'json';
$field->maxFiles = 0;
$field->inputfieldClass = 'InputfieldFile';
$field->unzip = 1;
$field->flags = Field::flagSystem | Field::flagPermanent;
$field->save();
$this->message("Created field: language_files_site");
}
// update
$field->label = 'Site Translation Files';
$field->description = 'Use this field for translations specific to your site (like files in /site/templates/ for example).';
$field->descriptionRows = 0;
$field->save();
$fieldgroup->add($field);
// create the 'language_files' field used by the 'language' fieldgroup
$field = $this->wire('fields')->get('language_files');
if(!$field) {
$field = $this->wire(new Field());
$field->type = $this->modules->get("FieldtypeFile");
$field->name = 'language_files';
$field->label = 'Core Translation Files';
$field->extensions = 'json';
$field->maxFiles = 0;
$field->inputfieldClass = 'InputfieldFile';
$field->unzip = 1;
$field->flags = Field::flagSystem | Field::flagPermanent;
$field->save();
$this->message("Created field: language_files");
}
// update
$field->label = 'Core Translation Files';
$field->description = 'Use this field for [language packs](http://modules.processwire.com/categories/language-pack/). To delete all files, double-click the trash can for any file, then save.';
$field->descriptionRows = 0;
$field->save();
$fieldgroup->add($field);
$fieldgroup->save();
}
/**
* Uninstall the module and related modules
*
*/
public function ___uninstall() {
$language = $this->wire('user')->language;
if($language && $language->id && !$language->isDefault) throw new WireException("Please switch your language back to the default language before uninstalling");
// uninstall the components 1 by 1
$configData = $this->wire('modules')->getModuleConfigData('LanguageSupport');
$field = $this->fields->get(LanguageSupport::languageFieldName);
if($field) {
$field->flags = Field::flagSystemOverride;
$field->flags = 0;
$userFieldgroup = $this->templates->get('user')->fieldgroup;
if($userFieldgroup) {
$userFieldgroup->remove($field);
$userFieldgroup->save();
$this->message("Removed language field from user profiles");
}
$this->fields->delete($field);
$this->message("Removing field: $field");
}
$deletePageIDs = array(
$configData['defaultLanguagePageID'],
$configData['languageTranslatorPageID'],
$configData['languagesPageID']
);
// remove any language pages that are in the trash
$trashLanguages = $this->wire('pages')->get($this->wire('config')->trashPageID)->find("include=all, template=" . LanguageSupport::languageTemplateName);
foreach($trashLanguages as $p) $deletePageIDs[] = $p->id;
foreach($deletePageIDs as $id) {
$page = $this->pages->get($id);
if(!$page->id) continue;
$page->status = Page::statusSystemOverride;
$page->status = 0;
$this->message("Removing page: {$page->path}");
$this->pages->delete($page, true);
}
$template = $this->templates->get(LanguageSupport::languageTemplateName);
if($template) {
$template->flags = Template::flagSystemOverride;
$template->flags = 0;
$this->message("Removing template: {$template->name}");
$this->templates->delete($template);
}
$fieldgroup = $this->fieldgroups->get(LanguageSupport::languageTemplateName);
if($fieldgroup) {
$this->message("Removing fieldgroup: $fieldgroup");
$this->fieldgroups->delete($fieldgroup);
}
$field = $this->fields->get("language_files");
if($field) {
$field->flags = Field::flagSystemOverride;
$field->flags = 0;
$this->message("Removing field: {$field->name}");
$this->fields->delete($field);
}
$field = $this->fields->get("language_files_site");
if($field) {
$field->flags = Field::flagSystemOverride;
$field->flags = 0;
$this->message("Removing field: {$field->name}");
$this->fields->delete($field);
}
$this->wire('languages', false);
$uninstallModules = array('ProcessLanguage', 'ProcessLanguageTranslator');
foreach($uninstallModules as $name) {
$this->modules->uninstall($name);
$this->message("Uninstalled Module: $name");
}
}
/**
* @return InputfieldWrapper
*
*/
public function getModuleConfigInputfields() {
$modules = $this->wire()->modules;
$install = $this->_('Click to install:') . ' ';
$form = $this->wire(new InputfieldWrapper());
$names = array(
'LanguageSupportFields',
'LanguageSupportPageNames',
'LanguageTabs',
);
$installed = array();
$list = array();
foreach($names as $name) {
if($modules->isInstalled($name)) continue;
$list[$modules->getModuleInstallUrl($name)] = "$install $name";
$installed[$name] = true;
}
$list["../setup/languages/"] =
$this->_('Add and configure new languages');
$title = $this->wire()->fields->get('title');
if($title && strpos($title->type->className(), 'Language') === false) {
$list[$title->editUrl()] =
$this->_('Change the type of your "title" field from "Page Title" to "Page Title (Multi-language)"') . ' *';
}
$list["../setup/field/?fieldtype=FieldtypeText"] =
$this->_('Change the type of any other desired "Text" fields to "Text (Multi-language)"') . ' *';
$list["../setup/field/?fieldtype=FieldtypeTextarea"] =
$this->_('Change the type of any other desired "Textarea" fields to "Textarea (Multi-language)"') . ' *';
if(count($list)) {
$jQueryUI = $modules->get('JqueryUI'); /** @var JqueryUI $jQueryUI */
$jQueryUI->use('modal');
/** @var InputfieldMarkup $f */
$f = $modules->get('InputfieldMarkup');
$f->attr('name', '_next_steps');
$f->label = $this->_('Next steps');
$f->value = "<ul>";
foreach($list as $url => $text) {
$f->value .= "<li><a target='_blank' href='$url'>$text</a></li>";
}
$f->value .= "</ul>";
$f->description =
$this->_('To continue setting up multi-language support, we recommend the following next steps.') . ' ' .
$this->_('The links below will open in a new window/tab. Close each after finishing to return here.');
$f->notes = '*' . $this->_('Install the LanguageSupportFields module before attempting to change text field types.');
$form->add($f);
}
return $form;
}
}