artabro/wire/modules/Inputfield/InputfieldPageName/InputfieldPageName.module
2024-08-27 11:35:37 +02:00

355 lines
11 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php namespace ProcessWire;
/**
* An Inputfield for handling ProcessWire "name" fields
*
* @property Page|null $parentPage
* @property Page|null $editPage
* @property string $sanitizeMethod Default = 'pageName'
* @property string $languageSupportLabel
* @property bool|int $slashUrls whether a trailing slash should be shown in the URL preview (default=1)
*
* optional checkbox associated with the input, for use with language support
* @property string $checkboxName Leave blank to disable
* @property string $checkboxLabel
* @property string $checkboxValue
* @property string $checkboxSuffix
* @property bool $checkboxChecked
*
*/
class InputfieldPageName extends InputfieldName implements ConfigurableModule {
public static function getModuleInfo() {
return array(
'title' => 'Page Name',
'version' => 106,
'summary' => 'Text input validated as a ProcessWire Page name field',
'permanent' => true,
);
}
public static $defaultReplacements = array(
'æ' => 'ae',
'å' => 'a',
'ä' => 'a',
'ã' => 'a',
'ß' => 'ss',
'ö' => 'o',
'ü' => 'u',
'đ' => 'dj',
'ж' => 'zh',
'х' => 'kh',
'ц' => 'tc',
'ч' => 'ch',
'ш' => 'sh',
'щ' => 'shch',
'ю' => 'iu',
'я' => 'ia',
':' => '-',
',' => '-',
'à' => 'a',
'á' => 'a',
'â' => 'a',
'è' => 'e',
'é' => 'e',
'ë' => 'e',
'ê' => 'e',
'ě' => 'e',
'ì' => 'i',
'í' => 'i',
'ï' => 'i',
'î' => 'i',
'ı' => 'i',
'İ' => 'i',
'ğ' => 'g',
'õ' => 'o',
'ò' => 'o',
'ó' => 'o',
'ô' => 'o',
'ø' => 'o',
'ù' => 'u',
'ú' => 'u',
'û' => 'u',
'ů' => 'u',
'ñ' => 'n',
'ç' => 'c',
'č' => 'c',
'ć' => 'c',
'Ç' => 'c',
'ď' => 'd',
'ĺ' => 'l',
'ľ' => 'l',
'ń' => 'n',
'ň' => 'n',
'ŕ' => 'r',
'ř' => 'r',
'š' => 's',
'ş' => 's',
'Ş' => 's',
'ť' => 't',
'ý' => 'y',
'ž' => 'z',
'а' => 'a',
'б' => 'b',
'в' => 'v',
'г' => 'g',
'д' => 'd',
'е' => 'e',
'ё' => 'e',
'з' => 'z',
'и' => 'i',
'й' => 'i',
'к' => 'k',
'л' => 'l',
'м' => 'm',
'н' => 'n',
'о' => 'o',
'п' => 'p',
'р' => 'r',
'с' => 's',
'т' => 't',
'у' => 'u',
'ф' => 'f',
'ы' => 'y',
'э' => 'e',
'ę' => 'e',
'ą' => 'a',
'ś' => 's',
'ł' => 'l',
'ż' => 'z',
'ź' => 'z',
);
/**
* Whether or not the system has LanguageSupportPageNames module installed
*
* @var bool
*
*/
protected $hasLanguagePageNames = false;
public function init() {
parent::init();
$this->label = $this->_('Name'); // Field label for 'Name'
$this->icon = 'angle-double-right';
$this->set('editPage', null); // page being edited, when available
$this->set('parentPage', null); // parent of page being edited, when available
$this->set('languageSupportLabel', '');
$this->set('slashUrls', 1); // whether a trailing slash should be shown in the URL preview
// disable autocomplete for page name with custom attribute value
$this->attr('autocomplete', 'pw-page-name');
// optional checkbox associated with the input, for use with language support
$this->set('checkboxName', ''); // leave blank to disable
$this->set('checkboxLabel', '');
$this->set('checkboxValue', '');
$this->set('checkboxChecked', false);
$this->set('checkboxSuffix', '');
if($this->wire('config')->pageNameCharset === 'UTF8') {
// no need to indicate input limitations
$this->set('sanitizeMethod', 'pageNameUTF8');
$this->description = '';
} else {
$this->description = $this->_("Any combination of letters (a-z), numbers (0-9), dashes or underscores (no spaces)."); // Field description describing what characters are allowed
$this->set('sanitizeMethod', 'pageName');
}
$this->hasLanguagePageNames = $this->wire()->modules->isInstalled('LanguageSupportPageNames');
$this->removeClass('InputfieldNoBorder', 'wrapClass');
}
public function ___render() {
$config = $this->wire()->config;
$url = '';
$out = '';
$box = '';
$user = $this->wire()->user;
$languages = $this->wire()->languages;
$sanitizer = $this->wire()->sanitizer;
$editable = $this->attr('disabled') ? false : true;
$template = $this->editPage ? $this->editPage->template : null;
$noLang = $template && $template->noLang;
if($this->parentPage) {
if($noLang && $languages && !$user->language->isDefault()) {
// if noLang active for page edited by non-default user, ensure we use default language url
$languages->setDefault();
$url = $this->parentPage->path;
$languages->unsetDefault();
} else {
$url = $this->parentPage->path;
}
if($this->hasLanguagePageNames && $this->parentPage->id == $config->rootPageID) {
if($user->language->isDefault()) {
$parentName = $this->parentPage->name;
if(!trim($url, '/')) $url = ($parentName === Pages::defaultRootName ? "" : $parentName);
}
}
}
if($noLang) $languages = false;
if($editable && $languages && $this->hasLanguagePageNames && !$languages->editable($user->language)) $editable = false;
if($this->languageSupportLabel) {
if($this->checkboxName) {
$checked = $this->checkboxChecked ? " checked='checked'" : '';
$disabled = $editable ? '' : " disabled='disabled'";
$name = $sanitizer->entities($this->checkboxName);
$value = $sanitizer->entities($this->checkboxValue);
$label = $sanitizer->entities($this->checkboxLabel);
$adminTheme = $this->wire()->adminTheme;
$checkboxClass = $adminTheme ? $adminTheme->getClass('input-checkbox') : '';
$box =
"<label class='checkbox detail'>" .
"<input type='checkbox' class='$checkboxClass' name='$name{$this->checkboxSuffix}' value='$value'$checked$disabled /> $label" .
"</label>";
}
$label = $sanitizer->entities($this->languageSupportLabel);
if(!$editable) $label = "<s>$label</s>";
$id = $sanitizer->entities($this->attr('id'));
$out .= "<div class='LanguageSupport'>" .
"<label for='$id' class='LanguageSupportLabel detail'>$label</label>";
}
$value = $this->attr('value');
$link = '';
$slashUrls = (int) $this->slashUrls;
if(strlen($value) && $this->hasLanguagePageNames) {
$link = trim($url, '/') . "/$value" . ($slashUrls ? '/' : '');
$link = $config->urls->root . ltrim($link, '/');
$link = "<a href='$link'>";
}
$p = "\n<p id='{$this->id}_path' data-slashUrls='$slashUrls' class='InputfieldPageNameURL'>";
if($link) $p .= $link;
$p .= rtrim($url, '/') . "/<strong></strong>";
if($link) $p .= "</a>";
$p .= "</p>";
$out .= $p;
$disabled = $this->attr('disabled');
if(!$editable) $this->attr('disabled', 'disabled');
$out .= parent::___render();
if(!$editable && !$disabled) $this->removeAttr('disabled'); // restore previous state
if($this->languageSupportLabel) $out .= $box . "</div>";
// make the replacements part of the JS config
$charset = $config->pageNameCharset;
if($charset == 'UTF8') {
$replacements = array(':' => '-', ',' => '-');
$whitelist = $this->config->pageNameWhitelist;
} else {
$replacements = empty($this->replacements) ? self::$defaultReplacements : $this->replacements;
$whitelist = '';
}
$config->js($this->className(), array(
'replacements' => $replacements,
'charset' => $charset,
'whitelist' => $whitelist
));
return $out;
}
public function ___processInput(WireInputData $input) {
if($this->attr('disabled')) return $this;
$languages = $this->wire()->languages;
if($this->editPage && $this->editPage->template->noLang) $languages = false;
if($languages && $this->hasLanguagePageNames) {
$user = $this->wire()->user;
if(!$languages->editable($user->language)) return $this;
$return = parent::___processInput($input);
$process = $this->wire()->process;
if($process instanceof WirePageEditor && $process->getPage()->id == $this->wire()->config->rootPageID) {
if(!strlen($this->attr('value'))) {
$this->attr('value', Pages::defaultRootName);
}
}
} else {
$return = parent::___processInput($input);
}
return $return;
}
static public function replacementStringToArray($str) {
$r = preg_split('/[\r\n]+/', $str);
$a = array();
foreach($r as $value) {
if(!strpos($value, '=')) continue;
list($k, $v) = explode('=', $value);
$a[trim($k)] = trim($v);
}
return $a;
}
static public function replacementArrayToString(array $a) {
$str = '';
foreach($a as $k => $v) $str .= "$k=$v\n";
return rtrim($str);
}
public function getModuleConfigInputfields(array $data) {
$modules = $this->wire()->modules;
$fields = $this->wire(new InputfieldWrapper());
if($this->wire()->config->pageNameCharset === 'UTF8') {
$this->message($this->_('Character replacements configuration is disabled because $config->pageNameCharset is UTF8.'));
return $fields;
}
$modules->addHookBefore('saveModuleConfigData', null, 'InputfieldPageName_saveModuleConfigData');
$name = 'replacements';
if(empty($data[$name])) $data[$name] = self::$defaultReplacements;
if(is_array($data[$name])) {
// data already in right save format, but need it to be a string for editing
$replacements = self::replacementArrayToString($data[$name]);
} else {
// data is a string so they must have just saved, but we want to save the array version instead
$replacements = $data[$name];
$data[$name] = self::replacementStringToArray($replacements);
}
/** @var InputfieldTextarea $field */
$field = $modules->get("InputfieldTextarea");
$field->attr('name', $name);
$field->attr('value', $replacements);
$field->attr('rows', 15);
$field->label = $this->_('Character replacements');
$field->description = $this->_('Enter the replacements that will occur when a user is entering characters into a page name field. Enter one replacement per line in key=value format. Meaning, on each new line, enter the character(s) you want to replace followed by an equals sign "=" and the ascii character(s) you want to replace with.'); // Character replacements description
$field->notes = $this->_('The replacement value for each must be one or more of: a-z, 0-9, dash, underscore or period.'); // Character replacements notes
$fields->append($field);
return $fields;
}
/**
* Get default replacements setting
*
* @return array
* @since 3.0.170
*
*/
public static function getDefaultReplacements() {
return self::$defaultReplacements;
}
}
function InputfieldPageName_saveModuleConfigData(HookEvent $event) {
$arguments = $event->arguments;
if($arguments[0] != 'InputfieldPageName') return;
$data = $arguments[1];
$name = 'replacements';
if(!is_array($data[$name])) $data[$name] = InputfieldPageName::replacementStringToArray($data[$name]);
$arguments[1] = $data;
$event->arguments = $arguments;
}