diff --git a/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php b/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php index b0cded4d0..67ce12c62 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php +++ b/src/opnsense/mvc/app/models/OPNsense/Base/BaseModel.php @@ -111,15 +111,17 @@ abstract class BaseModel /** * fetch reflection class (cached by field type) * @param $classname classname to construct - * @return array - * @throws ModelException + * @return BaseField type class + * @throws ModelException when unable to parse field type + * @throws \ReflectionException when unable to create class */ private function getNewField($classname) { if (self::$internalCacheReflectionClasses === null) { self::$internalCacheReflectionClasses = array(); } - if (!isset(self::$internalCacheReflectionClasses[$classname])) { + $classname_idx = str_replace("\\", "_", $classname); + if (!isset(self::$internalCacheReflectionClasses[$classname_idx])) { $is_derived_from_basefield = false; if (class_exists($classname)) { $field_rfcls = new \ReflectionClass($classname); @@ -136,9 +138,9 @@ abstract class BaseModel // class found, but of wrong type. raise an exception. throw new ModelException("class ".$field_rfcls->name." of wrong type in model definition"); } - self::$internalCacheReflectionClasses[$classname] = $field_rfcls; + self::$internalCacheReflectionClasses[$classname_idx] = $field_rfcls; } - return self::$internalCacheReflectionClasses[$classname]; + return self::$internalCacheReflectionClasses[$classname_idx]; } /** @@ -165,7 +167,22 @@ abstract class BaseModel $xmlNodeType = $xmlNode->attributes()["type"]; if (!empty($xmlNodeType)) { // construct field type object - $field_rfcls = $this->getNewField("OPNsense\\Base\\FieldTypes\\".$xmlNodeType); + if (strpos($xmlNodeType, "\\") !== false) { + // application specific field type contains path separator + if (strpos($xmlNodeType, ".\\") === 0) { + // use current namespace (.\Class) + $namespace = explode("\\" , get_class($this)); + array_pop($namespace); + $namespace = implode("\\", $namespace); + $classname = str_replace(".\\",$namespace."\\FieldTypes\\", (string)$xmlNodeType); + } else { + $classname = (string)$xmlNodeType; + } + $field_rfcls = $this->getNewField($classname); + } else { + // standard field type + $field_rfcls = $this->getNewField("OPNsense\\Base\\FieldTypes\\".$xmlNodeType); + } } else { // no type defined, so this must be a standard container (without content) $field_rfcls = $this->getNewField('OPNsense\Base\FieldTypes\ContainerField');