mirror of
https://github.com/processwire/processwire.git
synced 2025-08-12 17:54:44 +02:00
Add support for custom configuration of what Fieldtype/Inputfield settings may be overridden for field/template context. Appears only in $config->advanced mode. You can see it when editing a field (ProcessField) on the "Overrides" tab. Related to processwire/processwire-requests#145
This commit is contained in:
@@ -31,6 +31,7 @@
|
|||||||
* @property array $viewRoles Role IDs with view access, applicable only if access control is enabled. #pw-group-access
|
* @property array $viewRoles Role IDs with view access, applicable only if access control is enabled. #pw-group-access
|
||||||
* @property array|null $orderByCols Columns that WireArray values are sorted by (default=null), Example: "sort" or "-created". #pw-internal
|
* @property array|null $orderByCols Columns that WireArray values are sorted by (default=null), Example: "sort" or "-created". #pw-internal
|
||||||
* @property int|null $paginationLimit Used by paginated WireArray values to indicate limit to use during load. #pw-internal
|
* @property int|null $paginationLimit Used by paginated WireArray values to indicate limit to use during load. #pw-internal
|
||||||
|
* @property array $allowContexts Names of settings that are custom configured to be allowed for context. #pw-group-properties
|
||||||
*
|
*
|
||||||
* Common Inputfield properties that Field objects store:
|
* Common Inputfield properties that Field objects store:
|
||||||
* @property int|bool|null $required Whether or not this field is required during input #pw-group-properties
|
* @property int|bool|null $required Whether or not this field is required during input #pw-group-properties
|
||||||
@@ -351,6 +352,7 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
else if($key == 'flags') return $this->settings['flags'];
|
else if($key == 'flags') return $this->settings['flags'];
|
||||||
|
|
||||||
$value = parent::get($key);
|
$value = parent::get($key);
|
||||||
|
if($key === 'allowContexts' && !is_array($value)) $value = array();
|
||||||
if(is_array($this->trackGets)) $this->trackGets($key);
|
if(is_array($this->trackGets)) $this->trackGets($key);
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
@@ -916,6 +918,7 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
if($fieldgroupContext) {
|
if($fieldgroupContext) {
|
||||||
$allowContext = $this->type->getConfigAllowContext($this);
|
$allowContext = $this->type->getConfigAllowContext($this);
|
||||||
if(!is_array($allowContext)) $allowContext = array();
|
if(!is_array($allowContext)) $allowContext = array();
|
||||||
|
$allowContext = array_merge($allowContext, $this->allowContexts);
|
||||||
} else {
|
} else {
|
||||||
$allowContext = array();
|
$allowContext = array();
|
||||||
}
|
}
|
||||||
@@ -926,6 +929,8 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
if(!$fieldgroupContext) $inputfields->head = $this->_('Field type details');
|
if(!$fieldgroupContext) $inputfields->head = $this->_('Field type details');
|
||||||
$inputfields->attr('title', $this->_('Details'));
|
$inputfields->attr('title', $this->_('Details'));
|
||||||
$inputfields->attr('id+name', 'fieldtypeConfig');
|
$inputfields->attr('id+name', 'fieldtypeConfig');
|
||||||
|
$remainingNames = array();
|
||||||
|
foreach($allowContext as $name) $remainingNames[$name] = $name;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$fieldtypeInputfields = $this->type->getConfigInputfields($this);
|
$fieldtypeInputfields = $this->type->getConfigInputfields($this);
|
||||||
@@ -940,7 +945,19 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
foreach($fieldtypeInputfields as $inputfield) {
|
foreach($fieldtypeInputfields as $inputfield) {
|
||||||
if($fieldgroupContext && !in_array($inputfield->name, $allowContext)) continue;
|
if($fieldgroupContext && !in_array($inputfield->name, $allowContext)) continue;
|
||||||
$inputfields->append($inputfield);
|
$inputfields->append($inputfield);
|
||||||
|
unset($remainingNames[$inputfield->name]);
|
||||||
}
|
}
|
||||||
|
// now capture those that may have been stuck in a fieldset
|
||||||
|
if($fieldgroupContext) {
|
||||||
|
foreach($remainingNames as $name) {
|
||||||
|
if($inputfields->getChildByName($name)) continue;
|
||||||
|
$inputfield = $fieldtypeInputfields->getChildByName($name);
|
||||||
|
if(!$inputfield) continue;
|
||||||
|
$inputfields->append($inputfield);
|
||||||
|
unset($remainingNames[$inputfield->name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch(\Exception $e) {
|
} catch(\Exception $e) {
|
||||||
$this->trackException($e, false, true);
|
$this->trackException($e, false, true);
|
||||||
}
|
}
|
||||||
@@ -955,11 +972,15 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
if($inputfield) {
|
if($inputfield) {
|
||||||
if($fieldgroupContext) {
|
if($fieldgroupContext) {
|
||||||
$allowContext = array('visibility', 'collapsed', 'columnWidth', 'required', 'requiredIf', 'showIf');
|
$allowContext = array('visibility', 'collapsed', 'columnWidth', 'required', 'requiredIf', 'showIf');
|
||||||
$allowContext = array_merge($allowContext, $inputfield->getConfigAllowContext($this));
|
$allowContext = array_merge($allowContext, $this->allowContexts, $inputfield->getConfigAllowContext($this));
|
||||||
} else {
|
} else {
|
||||||
$allowContext = array();
|
$allowContext = array();
|
||||||
$inputfields->head = $this->_('Input field settings');
|
$inputfields->head = $this->_('Input field settings');
|
||||||
}
|
}
|
||||||
|
$remainingNames = array();
|
||||||
|
foreach($allowContext as $name) {
|
||||||
|
$remainingNames[$name] = $name;
|
||||||
|
}
|
||||||
$inputfields->attr('title', $this->_('Input'));
|
$inputfields->attr('title', $this->_('Input'));
|
||||||
$inputfields->attr('id+name', 'inputfieldConfig');
|
$inputfields->attr('id+name', 'inputfieldConfig');
|
||||||
$inputfieldInputfields = $inputfield->getConfigInputfields();
|
$inputfieldInputfields = $inputfield->getConfigInputfields();
|
||||||
@@ -974,6 +995,16 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
foreach($inputfieldInputfields as $i) {
|
foreach($inputfieldInputfields as $i) {
|
||||||
if($fieldgroupContext && !in_array($i->name, $allowContext)) continue;
|
if($fieldgroupContext && !in_array($i->name, $allowContext)) continue;
|
||||||
$inputfields->append($i);
|
$inputfields->append($i);
|
||||||
|
unset($remainingNames[$i->name]);
|
||||||
|
}
|
||||||
|
if($fieldgroupContext) {
|
||||||
|
foreach($remainingNames as $name) {
|
||||||
|
if($inputfields->getChildByName($name)) continue;
|
||||||
|
$inputfield = $inputfieldInputfields->getChildByName($name);
|
||||||
|
if(!$inputfield) continue;
|
||||||
|
$inputfields->append($inputfield);
|
||||||
|
unset($remainingNames[$inputfield->name]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -911,7 +911,8 @@ class ProcessField extends Process implements ConfigurableModule {
|
|||||||
if(!$fieldgroup->hasFieldContext($field->name, $this->contextNamespace)) continue;
|
if(!$fieldgroup->hasFieldContext($field->name, $this->contextNamespace)) continue;
|
||||||
$allChanges[$fieldgroup->name] = $this->getContextChanges($form, $field, $fieldgroup);
|
$allChanges[$fieldgroup->name] = $this->getContextChanges($form, $field, $fieldgroup);
|
||||||
}
|
}
|
||||||
if(!count($allChanges)) return;
|
|
||||||
|
if(!count($allChanges) && !$this->wire('config')->advanced) return;
|
||||||
|
|
||||||
$tab = $this->wire(new InputfieldWrapper());
|
$tab = $this->wire(new InputfieldWrapper());
|
||||||
$tab->attr('title', $this->_('Overrides'));
|
$tab->attr('title', $this->_('Overrides'));
|
||||||
@@ -933,6 +934,7 @@ class ProcessField extends Process implements ConfigurableModule {
|
|||||||
}
|
}
|
||||||
$tab->add($f);
|
$tab->add($f);
|
||||||
|
|
||||||
|
if(count($allChanges)) {
|
||||||
/** @var MarkupAdminDataTable $table */
|
/** @var MarkupAdminDataTable $table */
|
||||||
$table = $this->wire('modules')->get('MarkupAdminDataTable');
|
$table = $this->wire('modules')->get('MarkupAdminDataTable');
|
||||||
$table->setEncodeEntities(false);
|
$table->setEncodeEntities(false);
|
||||||
@@ -942,7 +944,7 @@ class ProcessField extends Process implements ConfigurableModule {
|
|||||||
$header[] = $this->_x('Setting', 'context-thead');
|
$header[] = $this->_x('Setting', 'context-thead');
|
||||||
$header[] = $this->_x('Original', 'context-thead');
|
$header[] = $this->_x('Original', 'context-thead');
|
||||||
$header[] = $this->_x('Override', 'context-thead');
|
$header[] = $this->_x('Override', 'context-thead');
|
||||||
$header[] = "<i class='fa fa-trash-o override-select-all'></i>";
|
$header[] = "<i class='fa fa-fw fa-lg fa-trash override-select-all'></i>";
|
||||||
$table->headerRow($header);
|
$table->headerRow($header);
|
||||||
|
|
||||||
$sanitizer = $this->wire('sanitizer');
|
$sanitizer = $this->wire('sanitizer');
|
||||||
@@ -969,6 +971,79 @@ class ProcessField extends Process implements ConfigurableModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$f->value = $table->render();
|
$f->value = $table->render();
|
||||||
|
} else {
|
||||||
|
$f->value = '<p>' . $this->_('There are currently no settings being overridden by template.') . '</p>';
|
||||||
|
$f->collapsed = Inputfield::collapsedYes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow the following configuration only for advanced mode
|
||||||
|
if(!$this->wire('config')->advanced) return;
|
||||||
|
|
||||||
|
/** @var InputfieldCheckboxes $field */
|
||||||
|
$field = $this->modules->get('InputfieldCheckboxes');
|
||||||
|
$field->attr('name', 'allowContexts');
|
||||||
|
$field->label = $this->_('Allowed overrides');
|
||||||
|
$field->icon = 'sliders';
|
||||||
|
$field->description =
|
||||||
|
$this->_('Checked settings will appear as configuration options when editing this field within the context of a particular template.') . ' ' .
|
||||||
|
$this->_('**Warning:** doing this for settings beyond those specified by the module author may not always work, or may cause problems.');
|
||||||
|
$field->table = true;
|
||||||
|
$field->thead =
|
||||||
|
$this->_('Label') . '|' .
|
||||||
|
$this->_('Name') . '|' .
|
||||||
|
$this->_('Type');
|
||||||
|
|
||||||
|
$tabNames = array(
|
||||||
|
'fieldtypeConfig' => $this->_('Details:'),
|
||||||
|
'inputfieldConfig' => $this->_('Input:')
|
||||||
|
);
|
||||||
|
$exclusions = array(
|
||||||
|
'collapsed',
|
||||||
|
'showIf',
|
||||||
|
'required',
|
||||||
|
'requiredIf',
|
||||||
|
'columnWidth',
|
||||||
|
'visibility',
|
||||||
|
'themeOffset',
|
||||||
|
'themeBorder',
|
||||||
|
'themeColor',
|
||||||
|
);
|
||||||
|
|
||||||
|
$fieldtypeNames = $this->field->type->getConfigAllowContext($this->field);
|
||||||
|
if(!is_array($fieldtypeNames)) $fieldtypeNames = array();
|
||||||
|
$dummyPage = $this->wire('pages')->get("/"); // only using this to satisfy param requirement
|
||||||
|
$inputfieldNames = $this->field->getInputfield($dummyPage)->getConfigAllowContext($this->field);
|
||||||
|
if(!is_array($inputfieldNames)) $inputfieldNames = array();
|
||||||
|
$alwaysSelected = array_merge($fieldtypeNames, $inputfieldNames);
|
||||||
|
$allowContexts = $this->field->get('allowContexts');
|
||||||
|
$alwaysSelected = array_diff($alwaysSelected, $allowContexts);
|
||||||
|
$qty = 0;
|
||||||
|
|
||||||
|
foreach($tabNames as $tabName => $tabLabel) {
|
||||||
|
/** @var InputfieldWrapper $tabInputfield */
|
||||||
|
$tabInputfield = $form->getChildByName($tabName);
|
||||||
|
if(!$tabInputfield) continue;
|
||||||
|
foreach($tabInputfield->getAll() as $f) {
|
||||||
|
$name = $f->name;
|
||||||
|
if(strpos($name, '_') === 0) continue;
|
||||||
|
if(in_array($name, $exclusions)) continue;
|
||||||
|
if($f instanceof InputfieldWrapper || $f instanceof InputfieldMarkup || $f instanceof InputfieldHidden) continue;
|
||||||
|
$typeName = str_replace('Inputfield', '', $f->className());
|
||||||
|
$label = str_replace('|', ' ', "$tabLabel $f->label") .
|
||||||
|
"| [span.detail] $name [/span] " .
|
||||||
|
"| [span.detail] $typeName [/span]";
|
||||||
|
if(in_array($name, $alwaysSelected)) {
|
||||||
|
$field->addOption($name, $label, array('checked' => 'checked', 'disabled' => 'disabled'));
|
||||||
|
$allowContexts[] = $name;
|
||||||
|
} else {
|
||||||
|
$field->addOption($name, $label);
|
||||||
|
$qty++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$field->attr('value', $allowContexts);
|
||||||
|
if($qty) $tab->append($field);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user