/** * Get a list of all fields attached to the model. Filters all fieldnames * that are listed on the blacklist. * * @see Opus_Model_Abstract::_internalFields * @return array List of fields */ public function describe() { $result = $this->model->describe(); // ensure sort order by removing all sorted fields from output // and put sort order list on top of the result $sortorder = array_intersect($this->sortorder, $result); $result = array_diff($result, $sortorder); $result = array_merge($sortorder, $result); $result = array_diff($result, $this->blacklist); return $result; }
/** * Recursively populates model's fields from an Xml DomElement. * * @param Opus_Model_Abstract $model The model to be populated. * @param DOMElement $element The DomElement holding the field names and values. * @return Opus_Model_Abstract $model The populated model. */ protected function _populateModelFromXml(Opus_Model_Abstract $model, DOMElement $element) { $fieldList = $model->describe(); // Internal fields exist as attributes foreach ($element->attributes as $field) { // Implement adding values to multi-value internal fields. // This is implemented in store-procedure, not here // multi-value internal fields should hold values concatenated because they have only one field in database // ignore unknown attributes if (true === in_array($field->nodeName, $fieldList)) { $callname = 'set' . $field->name; if ($field->value === '') { $model->{$callname}(null); } else { $model->{$callname}($field->value); } } } // External fields exist as child elements foreach ($element->childNodes as $externalField) { $fieldName = $externalField->nodeName; if (in_array($fieldName, $fieldList) === false) { throw new Opus_Model_Exception('Field ' . $fieldName . ' not defined'); } else { $modelclass = $model->getField($fieldName)->getValueModelClass(); } $submodel = $this->_createModelFromElement($externalField, $modelclass); $submodel = $this->_populateModelFromXml($submodel, $externalField); $callname = 'add' . $externalField->nodeName; $model->{$callname}($submodel); } return $model; }
/** * Update the field values of this model by using * another model instance having the same fields. * * All fields of the given Model that also occur in the * the targeted Model (this instance) are used for update. * * To exclude fields from updating consider using a * Opus_Model_Filter decorator for the given update model. * * @return void */ public function updateFrom(Opus_Model_Abstract $model) { // use all available fields for update foreach ($model->describe() as $fieldname) { // find corresponding field to update $myfield = $this->_getField($fieldname); if (null !== $myfield) { // update the field $fieldvalue = $model->getField($fieldname)->getValue(); $myfield->setValue($fieldvalue); } } }
/** * Recursively populates model's fields from an Xml DomElement. * * @param Opus_Model_Abstract $model The model to be populated. * @param DOMElement $element The DomElement holding the field names and values. * @return Opus_Model_Abstract $model The populated model. */ protected function _populateModelFromXml(Opus_Model_Abstract $model, DOMElement $element) { $fieldList = $model->describe(); // fields exist as child elements foreach ($element->childNodes as $fieldNode) { // skip non-element nodes if (XML_ELEMENT_NODE !== $fieldNode->nodeType) { continue; } $fieldName = $fieldNode->nodeName; $fieldValue = $fieldNode->nodeValue; if (in_array($fieldName, $fieldList) === false) { throw new Opus_Model_Exception('Field ' . $fieldName . ' not defined. Model class: ' . get_class($model)); } else { $fieldObj = $model->getField($fieldName); $modelclass = $fieldObj->getValueModelClass(); // determine accessor function if (true === $fieldObj->hasMultipleValues()) { $accessor = 'add'; } else { $accessor = 'set'; } // omit setting values if XML node has no child nodes // neither XML_ELEMENT_TEXT nor XML_ELEMENT_NODE if (true === $fieldNode->hasChildNodes()) { if (null !== $modelclass) { $submodel = $this->_createModelFromElement($fieldNode, $modelclass); $callname = $accessor . $fieldName; // TODO better handling of accessor methods if ('add' === $accessor) { // if we add values then we need to do this on the returned model $tempModel = $model->{$callname}($submodel); $this->_populateModelFromXml($tempModel, $fieldNode); } else { // setting of values should be done on submodel $model->{$callname}($submodel); $this->_populateModelFromXml($submodel, $fieldNode); } } else { $callname = $accessor . $fieldName; $model->{$callname}($fieldValue); } } } } return $model; }