IcingaObjectFieldLoader: cleanup, improve handling

This commit is contained in:
Thomas Gelf 2017-01-13 15:24:50 +01:00
parent 721db342ea
commit 9b6eda4e97

View File

@ -11,14 +11,22 @@ use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Objects\DirectorDatafield; use Icinga\Module\Director\Objects\DirectorDatafield;
use Icinga\Module\Director\Objects\IcingaService; use Icinga\Module\Director\Objects\IcingaService;
use stdClass; use stdClass;
use Zend_Db_Select as ZfSelect;
use Zend_Form_Element as ZfElement; use Zend_Form_Element as ZfElement;
class IcingaObjectFieldLoader class IcingaObjectFieldLoader
{ {
protected $form; protected $form;
/** @var IcingaObject */
protected $object; protected $object;
/** @var \Icinga\Module\Director\Db */
protected $connection;
/** @var \Zend_Db_Adapter_Abstract */
protected $db;
protected $fields; protected $fields;
protected $elements; protected $elements;
@ -29,6 +37,8 @@ class IcingaObjectFieldLoader
public function __construct(IcingaObject $object) public function __construct(IcingaObject $object)
{ {
$this->object = $object; $this->object = $object;
$this->connection = $object->getConnection();
$this->db = $this->connection->getDbAdapter();
} }
public function addFieldsToForm(QuickForm $form) public function addFieldsToForm(QuickForm $form)
@ -45,16 +55,16 @@ class IcingaObjectFieldLoader
$fields = array(); $fields = array();
foreach ($objects as $object) { foreach ($objects as $object) {
foreach ($this->prepareObjectFields($object) as $varname => $field) { foreach ($this->prepareObjectFields($object) as $varname => $field) {
$varname = $field->varname; $varname = $field->get('varname');
if (array_key_exists($varname, $fields)) { if (array_key_exists($varname, $fields)) {
if ($field->datatype !== $fields[$varname]->datatype) { if ($field->get('datatype') !== $fields[$varname]->datatype) {
unset($fields[$varname]); unset($fields[$varname]);
} }
continue; continue;
} }
$fields[$field->varname] = $field; $fields[$varname] = $field;
} }
} }
@ -66,13 +76,15 @@ class IcingaObjectFieldLoader
/** /**
* Set a list of values * Set a list of values
* *
* Works in a failsafe way, when a field does not exist the value will be * Works in a fail-safe way, when a field does not exist the value will be
* silently ignored * silently ignored
* *
* @param array $values key/value pairs with variable names and their value * @param array $values key/value pairs with variable names and their value
* @param String $prefix An optional prefix that would be stripped from keys * @param string $prefix An optional prefix that would be stripped from keys
* *
* @return self * @return IcingaObjectFieldLoader
*
* @throws IcingaException
*/ */
public function setValues($values, $prefix = null) public function setValues($values, $prefix = null)
{ {
@ -321,6 +333,9 @@ class IcingaObjectFieldLoader
return $elements; return $elements;
} }
/**
* @param IcingaObject $object
*/
protected function setValuesFromObject(IcingaObject $object) protected function setValuesFromObject(IcingaObject $object)
{ {
foreach ($object->getVars() as $k => $v) { foreach ($object->getVars() as $k => $v) {
@ -360,6 +375,8 @@ class IcingaObjectFieldLoader
} }
} }
} }
// TODO -> filters!
} }
return $fields; return $fields;
@ -371,15 +388,14 @@ class IcingaObjectFieldLoader
* Follows the inheritance logic, resolves all fields and keeps the most * Follows the inheritance logic, resolves all fields and keeps the most
* specific ones. Returns a list of fields indexed by variable name * specific ones. Returns a list of fields indexed by variable name
* *
* @param IcingaObject $object
*
* @return DirectorDatafield[] * @return DirectorDatafield[]
*/ */
protected function loadResolvedFieldsForObject($object) protected function loadResolvedFieldsForObject(IcingaObject $object)
{ {
$result = $this->loadDataFieldsForObjects( $result = $this->loadDataFieldsForObject(
array_merge( $object
$object->templateResolver()->fetchResolvedParents(),
array($object)
)
); );
$fields = array(); $fields = array();
@ -393,36 +409,61 @@ class IcingaObjectFieldLoader
} }
/** /**
* Fetches fields for a given List of objects from the database
*
* Gives a list indexed by object id, with each entry being a list of that
* objects DirectorDatafield instances indexed by variable name
*
* @param IcingaObject[] $objectList List of objects * @param IcingaObject[] $objectList List of objects
* *
* @return Array * @return array
*/ */
protected function loadDataFieldsForObjects($objectList) protected function getIdsForObjectList($objectList)
{ {
$ids = array(); $ids = array();
$objects = array();
foreach ($objectList as $object) { foreach ($objectList as $object) {
if ($object->hasBeenLoadedFromDb()) { if ($object->hasBeenLoadedFromDb()) {
$ids[] = $object->id; $ids[] = $object->get('id');
$objects[$object->id] = $object;
} }
} }
if (empty($ids)) { return $ids;
}
public function fetchFieldDetailsForObject(IcingaObject $object)
{
if (! $object->hasBeenLoadedFromDb()) {
//return array();
}
$pathIds = $object->templateResolver()->listInheritancePathIds();
return $this->fetchFieldDetailsForIds(
array_unique($pathIds)
);
}
/***
* @param $objectIds
*
* @return \stdClass[]
*/
protected function fetchFieldDetailsForIds($objectIds)
{
if (empty($objectIds)) {
return array(); return array();
} }
$connection = $object->getConnection(); $query = $this->prepareSelectForIds($objectIds);
$db = $connection->getDbAdapter(); return $this->db->fetchAll($query);
}
/**
* @param array $ids
*
* @return ZfSelect
*/
protected function prepareSelectForIds(array $ids)
{
$object = $this->object;
$idColumn = 'f.' . $object->getShortTableName() . '_id'; $idColumn = 'f.' . $object->getShortTableName() . '_id';
$query = $db->select()->from( $query = $this->db->select()->from(
array('df' => 'director_datafield'), array('df' => 'director_datafield'),
array( array(
'object_id' => $idColumn, 'object_id' => $idColumn,
@ -440,23 +481,36 @@ class IcingaObjectFieldLoader
'df.id = f.datafield_id', 'df.id = f.datafield_id',
array() array()
)->where($idColumn . ' IN (?)', $ids) )->where($idColumn . ' IN (?)', $ids)
->order('df.caption ASC'); ->order('df.caption ASC');
$res = $db->fetchAll($query); return $query;
}
/**
* Fetches fields for a given List of objects from the database
*
* Gives a list indexed by object id, with each entry being a list of that
* objects DirectorDatafield instances indexed by variable name
*
* @param IcingaObject[] $objectList List of objects
*
* @return array
*/
public function loadDataFieldsForObject(IcingaObject $object)
{
$res = $this->fetchFieldDetailsForObject($object);
$result = array(); $result = array();
foreach ($res as $r) { foreach ($res as $r) {
$id = $r->object_id; $id = $r->object_id;
unset($r->object_id); unset($r->object_id);
$r->object = $objects[$id];
if (! array_key_exists($id, $result)) { if (! array_key_exists($id, $result)) {
$result[$id] = new stdClass; $result[$id] = new stdClass;
} }
$result[$id]->{$r->varname} = DirectorDatafield::fromDbRow( $result[$id]->{$r->varname} = DirectorDatafield::fromDbRow(
$r, $r,
$connection $this->connection
); );
} }