mirror of
https://github.com/processwire/processwire.git
synced 2025-08-13 10:15:28 +02:00
Add support for Fieldtypes to specify that a Field should use a custom class that extends the Field class, rather than always using the "Field" class.
This commit is contained in:
@@ -616,7 +616,7 @@ class Field extends WireData implements Saveable, Exportable {
|
|||||||
|
|
||||||
} else if(is_string($type)) {
|
} else if(is_string($type)) {
|
||||||
$typeStr = $type;
|
$typeStr = $type;
|
||||||
$fieldtypes = $this->wire('fieldtypes');
|
$fieldtypes = $this->wire('fieldtypes'); /** @var Fieldtypes $fieldtypes */
|
||||||
if(!$type = $fieldtypes->get($type)) {
|
if(!$type = $fieldtypes->get($type)) {
|
||||||
$this->error("Fieldtype '$typeStr' does not exist");
|
$this->error("Fieldtype '$typeStr' does not exist");
|
||||||
return $this;
|
return $this;
|
||||||
|
@@ -155,6 +155,45 @@ class Fields extends WireSaveableItems {
|
|||||||
return $this->wire(new Field());
|
return $this->wire(new Field());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an item and populate with given data
|
||||||
|
*
|
||||||
|
* @param array $a Associative array of data to populate
|
||||||
|
* @return Saveable|Wire
|
||||||
|
* @throws WireException
|
||||||
|
* @since 3.0.147
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function makeItem(array $a = array()) {
|
||||||
|
|
||||||
|
if(empty($a['type'])) return parent::makeItem($a);
|
||||||
|
|
||||||
|
/** @var Fieldtypes $fieldtypes */
|
||||||
|
$fieldtypes = $this->wire('fieldtypes');
|
||||||
|
if(!$fieldtypes) return parent::makeItem($a);
|
||||||
|
|
||||||
|
/** @var Fieldtype $fieldtype */
|
||||||
|
$fieldtype = $fieldtypes->get($a['type']);
|
||||||
|
if(!$fieldtype) return parent::makeItem($a);
|
||||||
|
|
||||||
|
$class = $fieldtype->getFieldClass($a);
|
||||||
|
if(empty($class) || $class === 'Field') return parent::makeItem($a);
|
||||||
|
|
||||||
|
if(strpos($class, "\\") === false) $class = wireClassName($class, true);
|
||||||
|
if(!class_exists($class)) return parent::makeItem($a);
|
||||||
|
|
||||||
|
$field = new $class();
|
||||||
|
$this->wire($field);
|
||||||
|
|
||||||
|
foreach($a as $key => $value) {
|
||||||
|
$field->$key = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$field->resetTrackChanges(true);
|
||||||
|
|
||||||
|
return $field;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per WireSaveableItems interface, return all available Field instances
|
* Per WireSaveableItems interface, return all available Field instances
|
||||||
*
|
*
|
||||||
|
@@ -605,7 +605,7 @@ abstract class Fieldtype extends WireData implements Module {
|
|||||||
*
|
*
|
||||||
* #pw-internal
|
* #pw-internal
|
||||||
*
|
*
|
||||||
* @param array Field $field
|
* @param Field $field
|
||||||
* @return array
|
* @return array
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -813,6 +813,21 @@ abstract class Fieldtype extends WireData implements Module {
|
|||||||
return $schema;
|
return $schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get class name to use Field objects of this type (must be class that extends Field class)
|
||||||
|
*
|
||||||
|
* Return blank if default class (Field) should be used.
|
||||||
|
*
|
||||||
|
* @param array $a Field data from DB (if needed)
|
||||||
|
* @return string Return class name or blank to use default Field class
|
||||||
|
* @since 3.0.147
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function getFieldClass(array $a = array()) {
|
||||||
|
if($a) {} // ignore
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns verbose array of database schema information
|
* Returns verbose array of database schema information
|
||||||
*
|
*
|
||||||
|
@@ -49,10 +49,11 @@ class Fieldtypes extends WireArray {
|
|||||||
if($this->preloaded) return;
|
if($this->preloaded) return;
|
||||||
$debug = $this->isAPI && $this->wire('config')->debug;
|
$debug = $this->isAPI && $this->wire('config')->debug;
|
||||||
if($debug) Debug::timer('Fieldtypes.preload');
|
if($debug) Debug::timer('Fieldtypes.preload');
|
||||||
foreach($this->data as $key => $module) {
|
$modules = $this->wire('modules'); /** @var Modules $modules */
|
||||||
|
foreach($this->data as $moduleName => $module) {
|
||||||
if($module instanceof ModulePlaceholder) {
|
if($module instanceof ModulePlaceholder) {
|
||||||
$fieldtype = $this->wire('modules')->get($module->className());
|
$fieldtype = $modules->getModule($moduleName);
|
||||||
$this->data[$key] = $fieldtype;
|
$this->data[$moduleName] = $fieldtype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($debug) Debug::saveTimer('Fieldtypes.preload');
|
if($debug) Debug::saveTimer('Fieldtypes.preload');
|
||||||
@@ -130,11 +131,12 @@ class Fieldtypes extends WireArray {
|
|||||||
if(strpos($key, 'Fieldtype') !== 0) $key = "Fieldtype" . ucfirst($key);
|
if(strpos($key, 'Fieldtype') !== 0) $key = "Fieldtype" . ucfirst($key);
|
||||||
|
|
||||||
if(!$fieldtype = parent::get($key)) {
|
if(!$fieldtype = parent::get($key)) {
|
||||||
$fieldtype = $this->wire('modules')->get($key);
|
$fieldtype = $this->wire('modules')->getModule($key);
|
||||||
|
if($fieldtype) $this->set($key, $fieldtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($fieldtype instanceof ModulePlaceholder) {
|
if($fieldtype instanceof ModulePlaceholder) {
|
||||||
$fieldtype = $this->wire('modules')->get($fieldtype->className());
|
$fieldtype = $this->wire('modules')->getModule($fieldtype->className());
|
||||||
if($fieldtype) $this->set($key, $fieldtype);
|
if($fieldtype) $this->set($key, $fieldtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,6 +42,25 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
|
|||||||
*/
|
*/
|
||||||
abstract public function makeBlankItem();
|
abstract public function makeBlankItem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make an item and populate with given data
|
||||||
|
*
|
||||||
|
* @param array $a Associative array of data to populate
|
||||||
|
* @return Saveable|Wire
|
||||||
|
* @throws WireException
|
||||||
|
* @since 3.0.147
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function makeItem(array $a = array()) {
|
||||||
|
$item = $this->makeBlankItem();
|
||||||
|
$this->wire($item);
|
||||||
|
foreach($a as $key => $value) {
|
||||||
|
$item->$key = $value;
|
||||||
|
}
|
||||||
|
$item->resetTrackChanges(true);
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the name of the table that this DAO stores item records in
|
* Return the name of the table that this DAO stores item records in
|
||||||
*
|
*
|
||||||
@@ -163,6 +182,7 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
|
|||||||
*/
|
*/
|
||||||
protected function ___load(WireArray $items, $selectors = null) {
|
protected function ___load(WireArray $items, $selectors = null) {
|
||||||
|
|
||||||
|
/** @var WireDatabasePDO $database */
|
||||||
$database = $this->wire('database');
|
$database = $this->wire('database');
|
||||||
$sql = $this->getLoadQuery($selectors)->getQuery();
|
$sql = $this->getLoadQuery($selectors)->getQuery();
|
||||||
|
|
||||||
@@ -170,21 +190,20 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
|
|||||||
$query->execute();
|
$query->execute();
|
||||||
|
|
||||||
while($row = $query->fetch(\PDO::FETCH_ASSOC)) {
|
while($row = $query->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
$item = $this->makeBlankItem();
|
if(isset($row['data'])) {
|
||||||
$this->wire($item);
|
if($row['data']) {
|
||||||
foreach($row as $field => $value) {
|
$row['data'] = $this->decodeData($row['data']);
|
||||||
if($field == 'data') {
|
} else {
|
||||||
if($value) $value = $this->decodeData($value);
|
unset($row['data']);
|
||||||
else continue;
|
|
||||||
}
|
}
|
||||||
$item->$field = $value;
|
|
||||||
}
|
}
|
||||||
$item->setTrackChanges(true);
|
$item = $this->makeItem($row);
|
||||||
$items->add($item);
|
if($item) $items->add($item);
|
||||||
}
|
}
|
||||||
$query->closeCursor();
|
|
||||||
|
|
||||||
|
$query->closeCursor();
|
||||||
$items->setTrackChanges(true);
|
$items->setTrackChanges(true);
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -200,6 +200,21 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get class name to use Field objects of this type (must be class that extends Field class)
|
||||||
|
*
|
||||||
|
* Return blank if default class (Field) should be used.
|
||||||
|
*
|
||||||
|
* @param array $a Field data from DB (if needed)
|
||||||
|
* @return string Return class name or blank to use default Field class
|
||||||
|
* @since 3.0.147
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function getFieldClass(array $a = array()) {
|
||||||
|
require_once(dirname(__FILE__) . '/RepeaterField.php');
|
||||||
|
return 'RepeaterField';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the class used for repeater Page objects
|
* Get the class used for repeater Page objects
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,5 @@
|
|||||||
|
<?php namespace ProcessWire;
|
||||||
|
|
||||||
|
class RepeaterField extends Field {
|
||||||
|
// example of custom class for Field object (not yet put to use in this case)
|
||||||
|
}
|
Reference in New Issue
Block a user