Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
279 lines (249 sloc) 8.73 KB
<?php
/**
* ProcessWire General site settings module
*
* Allows to set global site settings
*
* by Piotr Markiewicz (pmarki)
*
* ProcessWire 2.8.x (development), Copyright 2016 by Ryan Cramer
* https://processwire.com
*
*
*/
class ProcessGeneralSettings extends Process implements Module, ConfigurableModule {
public static function getModuleInfo() {
return array(
'title' => __('General site settings', __FILE__),
'summary' => __('Module that stores global site settings', __FILE__),
'version' => 113,
'permanent' => false,
'autoload' => true,
'icon' => 'sliders',
'page' => array(
'name' => 'general_settings',
'parent' => 'setup',
'title' => 'General settings',
),
);
}
protected static $defaults = array(
'global' => 'settings',
'settings' => '{"0":{"api":"title","label":"Your site title","type":"Text","width":"100","description":"","select":""}}',
);
public function init() {
//load styles for backend
if ($this->wire('user')->isLoggedin() && $this->input->get('name') == __CLASS__) {
$root = $this->config->urls->siteModules . __CLASS__;
$this->config->styles->prepend($root . '/' . 'SettingsStyles.css');
$this->config->scripts->add($root . '/' . 'SettingsJS.js');
}
//register wire 'global'
if (isset($this->data['global'])) {
$this->wire($this->data['global'], $this);
}
if (!isset($this->data['settings'])) {
parent::init();
return;
}
//set api as key with value as value
//it makes it callable $settings->key
$langData = array();
$data = json_decode($this->data['settings'], true);
foreach ($data as $key => $field) {
if (!isset($field['api'])) continue;
$value = (isset($field['value']) ? $field['value'] : '');
if ($field['type'] == 'Textarea') {
$value = nl2br($value);
}
if ($this->user->language) {
//if api ends with language name: site_name_polish, add its value to langData array
//so if user language is polish calling site_name will return its polish value
if (strpos($field['api'], '_'.$this->user->language->name) !== false) {
//$api without language suffix - site_title
$api = str_replace('_'.$this->user->language->name, '', $field['api']);
foreach ($data as $k => $f) {
if ($f['api'] === $api) {
$langData[$api] = $field['value'];
}
}
}
}
$this->set($field['api'], $value);
}
foreach ($langData as $key => $value) {
$this->set($key, $value);
}
parent::init();
}
public function ___execute() {
if ($this->input->post('submit_save')) {
return $this->renderForm($this->saveValues());
//wire('session')->redirect(wire('page')->url);
} else {
return $this->renderForm();
}
}
/**
* Render all settings with basic markup
*
* @return string markup
*
*/
public function render() {
$out = '<p>';
foreach (json_decode($this->data['settings'], true) as $key => $field) {
if (isset($field['api']) && $field['type'] != 'Fieldset') {
$v = (isset($field['value'])) ? $field['value'] : '';
$out .= $this->wire('sanitizer')->entities($field['label'])
. ' ('. $field['api'] . ') => '
. nl2br($this->wire('sanitizer')->entities($v)) . '<br>';
}
}
return $out .'</p>';
}
/**
* Render form for admin page
*
* @return string form markup
*
*/
protected function renderForm($settings=null) {
if (!isset($this->data['settings'])) {
return 'Create settings in module configuration first.';
}
$data = $this->data;
$attrs = json_decode( $settings ?:$data['settings'], true);
if ($attrs === null) {
return 'Error decoding settings data.';
}
$form = $this->modules->get('InputfieldForm');
$form->attr('id', 'SettingsModule');
$form->attr('action', $this->wire('page')->url );
$parent = $form;
foreach ($attrs as $fset) {
$field = $this->modules->get('Inputfield'.$fset['type']);
$value = (isset($fset['value']) ? $fset['value'] : '');
if (!$field) {
$this->message('Unable to find field type ' .$fset['type']);
continue;
}
//set attrbs for all type of fields
$field->label =$fset['label'];
$field->columnWidth = (intval($fset['width']) >=10) ? $fset['width'] : 100;
if ($fset['type'] == 'Checkbox') {
$field->uncheckedValue = '0';
if($value === '1') {
$field->setAttribute('checked', 'checked');
}
}
if ($fset['type'] == 'URL') {
$field->set('noRelative', 1);
}
if ($fset['type'] == 'Select' || $fset['type'] == 'Radios') {
foreach (explode(',', trim($fset['select'], ',')) as $label) {
//value, label, attr
$v = $this->wire('sanitizer')->name($label);
if ($value == $v) {
$field->addOption($v, $label, array('selected' => 1));
} else {
$field->addOption($v, $label);
}
}
}
if ($fset['type'] == 'Integer') {
$field->setAttribute('type', 'number');
}
//fieldset or normal field
if ($fset['type'] == 'Fieldset') {
$field->description = $fset['description'];
$field->addClass('fset_red');
$parent = $field;
$form->append($field);
} else {
$field->attr('name', $fset['api']);
$field->notes = $fset['description'];
$field->attr('value', $value);
$parent->append($field);
}
}
$f = $this->modules->get('InputfieldSubmit');
$f->attr('name', 'submit_save');
$f->attr('value', $this->_('Save'));
$f->addClass('head_button_clone');
$f->icon = 'save';
$form->add($f);
return $form->render();
}
/**
* Save values provided by user to module config data
*
*/
protected function saveValues() {
$old = $this->data;
$data = json_decode($old['settings'], true);
$new = array();
foreach ($data as $key => $field) {
$new[$key] = $field;
$new[$key]['value'] = $this->wire('input')->{$field['api']};
}
$old['settings'] = json_encode($new);
wire('modules')->saveModuleConfigData($this, $old);
$this->message('Site settings saved');
return $old['settings'];
}
static public function getModuleConfigInputfields(array $data) {
$data = array_merge(self::$defaults, $data);
$options = array();
$values = array();
$json = (isset( $data['settings'] )) ? json_decode($data['settings'], true) : '';
foreach ($json as $key => $value) {
if ($value['type'] == 'Fieldset') {
$options[$value['api']] ='-- '. $value['label'] . ' -- ' . $value['width'] . '%';
} else {
$options[$value['api']] = $value['label'] . ' ('. $value['api'] .') - ' . $value['width'] . '%';
}
$values[] = $value['api'];
}
$order = array();
$fields = new InputfieldWrapper();
$modules = wire('modules');
$field = $modules->get("InputfieldMarkup");
$field->label = __("Help", __FILE__);
$help = ('<b>API variable</b> - Any combination of letters (a-z), numbers (0-9) and underscores (no spaces).
You can call it in template files to output a value ($settings->site_name will return "My site").
<br>IMPORTANT: take care to not overload ProcessWire properties ($page, $user, etc.). It must be unique across all settings.<br>
<b>Label</b> - descriptive name for a backend user<br>
<b>Description</b> - longer explanation shown as notes in ProcessWire backend<br>
<b>Width</b> - field width in %, set between 10 and 100<br>
<b>Options for select or radios</b> - this will be used as names and labels, the best one word only');
$field->entityEncodeText = false;
$field->entityEncodeLabel = false;
$field->attr('value', $help);
$field->collapsed = Inputfield::collapsedYes;
$fields->append($field);
$field = $modules->get("InputfieldText");
$field->attr('name', 'global');
$field->label = __("Global name", __FILE__);
$field->attr('value', $data['global']);
$field->description = __('Use to call settings property in frontend ($settings->property).', __FILE__);
$field->notes = __("After changing make sure to change it in your template files.", __FILE__);
$field->collapsed = Inputfield::collapsedYes;
$fields->append($field);
$field = wire('modules')->get("InputfieldTextarea");
$field->attr('name', 'settings');
$field->attr('id', 'settings');
$field->label = __("Json data", __FILE__);
$field->attr('value', $data['settings']);
$field->columnWidth = 34;
$fields->append($field);
$field = $modules->get("InputfieldAsmSelect");
$field->attr('name', 'order');
$field->attr('id', 'ASMOrder');
$field->label = __("Settings", __FILE__);
$field->addOptions($options);
$field->attr('value', $values);
$fields->append($field);
return $fields;
}
}