formatElement(OutputFormatter::FC_BEG, "ManagedObjectClassDescriptorList"); // add moc descriptors to output foreach ($mocds as $mocd_id => $mocd) { $fattrs = array ('id' => $mocd_id); $outForm->formatElement(OutputFormatter::FC_BEG, "ManagedObjectClassDescriptor", null, $fattrs); $outForm->formatElement(OutputFormatter::FC_SGL, 'entity', $mocd['extern']); if (isset($mocd['props'])) { $classProps = ClassProperties::fromArray($mocd['props']); } else { $classProps = ClassProperties::fromArray( array (ClassProperty::CP_CREATE, ClassProperty::CP_SET, ClassProperty::CP_DELETE)); } $outForm->formatElement(OutputFormatter::FC_SGL, 'props', $classProps); $outForm->formatElement(OutputFormatter::FC_END); } $outForm->formatElement(OutputFormatter::FC_END); return GenericAdmin::EC_OK; } static function getAttrDescList($mocd, $atdcs, OutputFormatter $outForm) { // initialize result list $outForm->formatElement(OutputFormatter::FC_BEG, "AttributeDescriptorList"); // add attribute descriptors to output foreach ($atdcs as $atdc_id => $atdc) { if ($atdc['moc'] == $mocd['intern']) { $fattrs = array ('id' => $atdc_id); $outForm->formatElement(OutputFormatter::FC_BEG, "AttributeDescriptor", null, $fattrs); $outForm->formatElement(OutputFormatter::FC_SGL, 'entity', $atdc['extern']); $outForm->formatElement(OutputFormatter::FC_SGL, 'props', AttrProperties::fromArray($atdc['props'])); if (isset($atdc['typ_cl'])) { $outForm->formatElement(OutputFormatter::FC_SGL, 'typ_cl', $atdc['typ_cl']); } if (isset($atdc['rel_moc'])) { $outForm->formatElement(OutputFormatter::FC_SGL, 'rel_moc', $atdc['rel_moc']); } $outForm->formatElement(OutputFormatter::FC_END); } } $outForm->formatElement(OutputFormatter::FC_END); return GenericAdmin::EC_OK; } private static function addInstance($mocd, $instance, &$atdcs, OutputFormatter $outForm) { // add instance to output $fattrs = array ('id' => $instance->getId(), 'mod' => $instance->getMod()); $outForm->formatElement(OutputFormatter::FC_BEG, $mocd['extern'], null, $fattrs); // add attributes of instance to output foreach ($atdcs as $atdc) { if ($atdc['moc'] != $mocd['intern']) continue; $props = AttrProperties::fromArray($atdc['props']); if ($props->incl(new AttrProperty(AttrProperty::AP_GET))) { if ($props->incl(new AttrProperty(AttrProperty::AP_LIST))) { $list = $instance->getByName($atdc['intern'], BasePeer::TYPE_FIELDNAME); $outForm->formatElement(OutputFormatter::FC_BEG, $atdc['extern'], count($list)); $sequ_no = 1; foreach ($list as $elem) { $fattrs = array ('no' => $sequ_no++); $outForm->formatElement(OutputFormatter::FC_SGL, 'elm', $elem, $fattrs); } $outForm->formatElement(OutputFormatter::FC_END); } else { if ($props->incl(new AttrProperty(AttrProperty::AP_BOOL))) { if ($instance->getByName($atdc['intern'], BasePeer::TYPE_FIELDNAME)) { $att_val = 'true'; } else { $att_val = 'false'; } } else { $att_val = $instance->getByName($atdc['intern'], BasePeer::TYPE_FIELDNAME); } if (null !== $att_val) { $outForm->formatElement(OutputFormatter::FC_SGL, $atdc['extern'], $att_val); } } } } $outForm->formatElement(OutputFormatter::FC_END); } // evaluation of filter item private static function evalFiltItem($mocd, &$instance, &$atdcs, InputExtractor $filtExtr, $comp_tag) { // get the item attribute id and compare value in single child of the actual item node if ($filtExtr->extractElement(InputExtractor::EC_BEG, $att_id, $comp_val, $dmy_fattrs) == InputExtractor::EC_END) return self::ERF_INV_FILT; if ($filtExtr->extractElement(InputExtractor::EC_CTN, $dmy_elem, $dmy_value, $dmy_fattrs) != InputExtractor::EC_END) return self::ERF_INV_FILT; // get the attribute descriptor $atdc = null; foreach ($atdcs as $test) { if ($test['extern'] == $att_id && $test['moc'] == $mocd['intern']) { $atdc = $test; break; } } // item attribute not in moc => result false if ($atdc == null) return self::EFR_FALSE; // check for matching rules of attribute $props = AttrProperties::fromArray($atdc['props']); if (($comp_tag == FilterTag::FC_EQUAL && !($props->incl(new AttrProperty(AttrProperty::AP_MEQU)))) || ($comp_tag > FilterTag::FC_EQUAL && !($props->incl(new AttrProperty(AttrProperty::AP_MORD))))) return self::EFR_INV_FILT; // item attribute not in instance => result false if (null == ($att_val = $instance->getByName($atdc['intern'], BasePeer::TYPE_FIELDNAME))) return self::EFR_FALSE; // only presence test => result true if ($comp_tag == FilterTag::FC_PRESENT) return self::EFR_TRUE; // compare boolean value / only equality test possible if ($props->incl(new AttrProperty(AttrProperty::AP_BOOL))) { if ($att_val == ($comp_val == 'true')) { return self::EFR_TRUE; } else { return self::EFR_FALSE; } } if (isset($atdc['typ_cl'])) { // compare type class value with help of class method $comp_res = $att_val->compValue($comp_tag, $comp_val); } else { switch ($comp_tag) { case FilterTag::FC_EQUAL: $comp_res = ($att_val == $comp_val); break; case FilterTag::FC_LESS: $comp_res = ($att_val < $comp_val); break; case FilterTag::FC_GREATER: $comp_res = ($att_val > $comp_val); break; } } if ($comp_res) { return self::EFR_TRUE; } else { return self::EFR_FALSE; } } // recursive part of filter evaluation private static function evalFiltNode($mocd, &$instance, &$atdcs, InputExtractor $filtExtr, $res_emp_node) { $res_sub_node = self::EFR_INV_FILT; $node_ctl = InputExtractor::EC_BEG; while (($node_ctl = $filtExtr->extractElement($node_ctl, $elem, $value, $fattrs)) != InputExtractor::EC_END) { $node_tag = FilterTag::toFNodeTagVal($elem); // $res_emp_node indicates exact one sub node required and its now the second turn: invalid filter! if ($res_emp_node == self::EFR_INV_FILT && $res_sub_node != self::EFR_INV_FILT) return self::EFR_INV_FILT; if ($node_tag == FilterTag::FN_ITEM) { if (!(count($fattrs) == 1 && array_key_exists('co', $fattrs))) return self::EFR_INV_FILT; $res_sub_node = self::evalFiltItem($mocd, $instance, $atdcs, $filtExtr, FilterTag::toFCompTagVal($fattrs['co'])); } else { switch ($node_tag) { case FilterTag::FN_AND: $res_emp_sub_node = self::EFR_TRUE; /* result to return on empty AND */ break; case FilterTag::FN_OR: $res_emp_sub_node = self::EFR_FALSE; /* result to return on empty OR */ break; case FilterTag::FN_NOT: $res_emp_sub_node = self::EFR_INV_FILT; /* result to return on empty NOT */ break; } $res_sub_node = self::evalFiltNode($mocd, $instance, $atdcs, $filtExtr, $res_emp_sub_node); } if ($res_sub_node == self::EFR_INV_FILT) return self::EFR_INV_FILT; if ($node_tag == FilterTag::FN_NOT) { if ($res_sub_node == self::EFR_TRUE) { $res_sub_node = self::EFR_FALSE; } else { $res_sub_node = self::EFR_TRUE; } } // $res_emp_node indicates superior node AND resp. OR which leads to possible shortcut below if (($res_sub_node == self::EFR_TRUE && $res_emp_node == self::EFR_FALSE) || ($res_sub_node == self::EFR_FALSE && $res_emp_node == self::EFR_TRUE)) { $filtExtr->toParent(); return $res_sub_node; } } // $res_sub_node indicates whether above loop was empty if ($res_sub_node == self::EFR_INV_FILT) { return $res_emp_node; } else { return $res_sub_node; } } static function getInstanceList($mocd, $atdcs, InputExtractor $filtExtr = null, OutputFormatter $outForm) { // initialize result list $listName = $mocd['extern']."List"; $outForm->formatElement(OutputFormatter::FC_BEG, $listName); // check for name attribute of representation data class $rprClRefl = new ReflectionClass($mocd['intern']); $has_name = $rprClRefl->hasMethod('getName'); // read all instances of class $queryClass = $mocd['intern']."Query"; $queryRefl = new ReflectionClass($queryClass); $queryInst = $queryRefl->newInstance(); $instances = $queryInst->find(); // add instances to output foreach ($instances as $instance) { // exclude 'dummy' instance if ($has_name && $instance->getName() == "null") continue; // possible exlusion of instance by request filter if (null !== $filtExtr) { $filtExtr->toTop(); $efn_res = self::evalFiltNode($mocd, $instance, $atdcs, $filtExtr, self::EFR_INV_FILT /* result if xml-doc has no child */); if ($efn_res == self::EFR_FALSE) { continue; } elseif ($efn_res == self::EFR_INV_FILT) { return GenericAdmin::EC_INV_FILT; } } self::addInstance($mocd, $instance, $atdcs, $outForm); } $outForm->formatElement(OutputFormatter::FC_END); return GenericAdmin::EC_OK; } static function getInstance($mocd_tab, $atdcs, $mocd_id, $id, OutputFormatter $outForm) { // read requested instance of class $mocd = $mocd_tab[$mocd_id]; $queryClass = $mocd['intern']."Query"; $queryRefl = new ReflectionClass($queryClass); $queryInst = $queryRefl->newInstance(); $instance = $queryInst->findPk($id); // check instance against request if ($instance == null) return GenericAdmin::EC_NOSU_INST; // check instance identity (inheritance) $class = get_class($instance); $new_mocd = null; if ($class != $mocd['intern']) { // search for new descriptor foreach ($mocd_tab as $test_mocd) { if ($test_mocd['intern'] == $class) $new_mocd = $test_mocd; } if (!$new_mocd) throw new Exception("Class $class not found in descriptors"); $mocd = $new_mocd; } // add instance to output self::addInstance($mocd, $instance, $atdcs, $outForm); return GenericAdmin::EC_OK; } static function getIdByName($mocd_tab, $mocd_id, $name) { // read requested instance of class $mocd = $mocd_tab[$mocd_id]; $queryClass = $mocd['intern']."Query"; $queryRefl = new ReflectionClass($queryClass); $queryInst = $queryRefl->newInstance(); $instance = $queryInst->findOneByName($name); // check instance against request if ($instance == null) return -1; return $instance->getId(); } static function prepare_new_attribute_value($props, $atdc, $value, &$inpExtr) { // prepare and set the new attribute value if ($props->incl(new AttrProperty(AttrProperty::AP_LIST))) { // extract list attribute value $attr_val = array(); $list_ctl = InputExtractor::EC_BEG; while (($list_ctl = $inpExtr->extractElement($list_ctl, $elem, $value, $fattrs)) != InputExtractor::EC_END) { $attr_val[] = $value; } } elseif ($props->incl(new AttrProperty(AttrProperty::AP_BOOL))) { // set boolean value $attr_val = ($value == 'true'); } elseif ($props->incl(new AttrProperty(AttrProperty::AP_INT))) { // set integer value if (! preg_match('/^-?\d+$/', $value)) throw new Exception("Invalid integer value: ".$value); $attr_val = $value; } elseif ($props->incl(new AttrProperty(AttrProperty::AP_FLOAT))) { // set floating point value if (! preg_match('/^-?\d+\.{0,1}\d*$/', $value)) throw new Exception("Invalid floating point value: ".$value); $attr_val = $value; } elseif ($props->incl(new AttrProperty(AttrProperty::AP_BOOL))) { // set boolean value $attr_val = ($value == 'true'); } elseif (isset($atdc['typ_cl'])) { // convert string to object $typeRefl = new ReflectionClass($atdc['typ_cl']); $attr_val = $typeRefl->newInstance($value); } else { $attr_val = $value; } return $attr_val; } static function setInstance($mocd, $atdcs, InputExtractor $inpExtr) { // extract instance data from request if ($inpExtr->extractElement(InputExtractor::EC_BEG, $elem, $value, $fattrs) != InputExtractor::EC_CTN) return GenericAdmin::EC_INV_REQU; if (!(count($fattrs) == 2 && array_key_exists('id', $fattrs) && array_key_exists('mod', $fattrs))) return GenericAdmin::EC_INV_REQU; if ($elem != $mocd['extern']) return GenericAdmin::EC_INV_REQU; // check class properties for admittance if (isset($mocd['props'])) { $classProps = ClassProperties::fromArray($mocd['props']); if (!($classProps->incl(new ClassProperty(ClassProperty::CP_SET)))) return GenericAdmin::EC_INV_OPER; } // read requested instance of class $queryRefl = new ReflectionClass($mocd['intern']."Query"); $queryInst = $queryRefl->newInstance(); $instance = $queryInst->findPk($fattrs['id']); //$instance = $queryClass::create()->findPk($id); // check instance against request data if ($instance == null) return GenericAdmin::EC_NOSU_INST; if ($instance->getMod() != $fattrs['mod']) return GenericAdmin::EC_MOD_MISM; // extract attributes to set $extr_ctl = InputExtractor::EC_BEG; while (($extr_ctl = $inpExtr->extractElement($extr_ctl, $elem, $value, $fattrs)) != InputExtractor::EC_END) { // get the attribute descriptor $atdc = null; foreach ($atdcs as $test) { if ($test['extern'] == $elem && $test['moc'] == $mocd['intern']) { $atdc = $test; break; } } // check for admissibility of attribute changes if ($atdc == null) return GenericAdmin::EC_INV_OPER; $props = AttrProperties::fromArray($atdc['props']); if (!($props->incl(new AttrProperty(AttrProperty::AP_SET)))) return GenericAdmin::EC_INV_OPER; // prepare and set the new attribute value $attr_val = self::prepare_new_attribute_value($props, $atdc, $value, $inpExtr); $instance->setByName($atdc['intern'], $attr_val, BasePeer::TYPE_FIELDNAME); } $instance->save(); return GenericAdmin::EC_OK; } static function createInstance($mocd, $atdcs, InputExtractor $inpExtr, &$id) { // extract instance data from request if ($inpExtr->extractElement(InputExtractor::EC_BEG, $elem, $value, $fattrs) != InputExtractor::EC_CTN) return GenericAdmin::EC_INV_REQU; if ($elem != $mocd['extern'] || count($fattrs) > 0) return GenericAdmin::EC_INV_REQU; // check class properties for admittance if (isset($mocd['props'])) { $classProps = ClassProperties::fromArray($mocd['props']); if (!($classProps->incl(new ClassProperty(ClassProperty::CP_CREATE)))) return GenericAdmin::EC_INV_OPER; } // create new instance of requested class $reflClass = new ReflectionClass($mocd['intern']); $instance = $reflClass->newInstance(); // extract attributes to set on creation $spat_ids = array (); $post_proc_atts = array (); $extr_ctl = InputExtractor::EC_BEG; while (($extr_ctl = $inpExtr->extractElement($extr_ctl, $elem, $value, $fattrs)) != InputExtractor::EC_END) { // get the attribute descriptor $atdc = null; foreach ($atdcs as $test) { if ($test['extern'] == $elem && $test['moc'] == $mocd['intern']) { $atdc = $test; break; } } // check for admissibility of attribute giving if ($atdc == null) return GenericAdmin::EC_INV_OPER; $props = AttrProperties::fromArray($atdc['props']); if ($props->incl(new AttrProperty(AttrProperty::AP_INIT))) return GenericAdmin::EC_INV_OPER; // check for given name duplicity if ($atdc['intern'] == "name") { if (strlen($value) == 0) return GenericAdmin::EC_ATT_MISS; $queryRefl = new ReflectionClass($mocd['intern']."Query"); $queryInst = $queryRefl->newInstance(); $duplInst = $queryInst->findOneByName($value); if ($duplInst != null) { $id = $duplInst->getId(); return GenericAdmin::EC_DUPL_INST; } } // prepare and set the new attribute value $attr_val = self::prepare_new_attribute_value($props, $atdc, $value, $inpExtr); if ($props->incl(new AttrProperty(AttrProperty::AP_LIST)) && $props->incl(new AttrProperty(AttrProperty::AP_REL))) // store list attributes for later evaluation. The instance // must 1st be created to obtain an id. $post_proc_atts[$atdc['intern']] = $attr_val; else $instance->setByName($atdc['intern'], $attr_val, BasePeer::TYPE_FIELDNAME); $spat_ids[] = $atdc['intern']; } // check for completeness of attributes and provide initial/default values foreach ($atdcs as $atdc) { if ($atdc['moc'] != $mocd['intern']) continue; $att_spd = false; foreach ($spat_ids as $spat_id) { if ($spat_id == $atdc['intern']) { $att_spd = true; break; } } if (!$att_spd) { $props = AttrProperties::fromArray($atdc['props']); if (!($props->incl(new AttrProperty(AttrProperty::AP_INIT)) || $props->incl(new AttrProperty(AttrProperty::AP_DEF)))) throw new Exception("Attribute missing in CREATE: ".$atdc['extern']); if (isset($atdc['typ_cl'])) { // provision of initial/default value $typeRefl = new ReflectionClass($atdc['typ_cl']); $attr_val = $typeRefl->newInstance(null); $instance->setByName($atdc['intern'], $attr_val, BasePeer::TYPE_FIELDNAME); } } } try { // first save to get in id for setting the list attributes $instance->save(); // now the instance has an id. We can set the list attrs. foreach ($post_proc_atts as $att_name => $attr_val) { $instance->setByName($att_name, $attr_val, BasePeer::TYPE_FIELDNAME); } $instance->save(); } catch(Exception $e) { if($e->getCause()->getCode() == 23000) return GenericAdmin::EC_DUPL_INST; else throw $e; } $id = $instance->getId(); return GenericAdmin::EC_OK; } static function deleteInstance($mocd, $id, $mod) { // check class properties for admittance if (isset($mocd['props'])) { $classProps = ClassProperties::fromArray($mocd['props']); if (!($classProps->incl(new ClassProperty(ClassProperty::CP_DELETE)))) return GenericAdmin::EC_INV_OPER; } // read requested instance of class $queryClass = $mocd['intern']."Query"; $queryRefl = new ReflectionClass($queryClass); $queryInst = $queryRefl->newInstance(); $queryMeth = new ReflectionMethod($queryClass, 'findPk'); $instance = $queryMeth->invoke($queryInst, $id); //$instance = $queryClass::create()->findPk($id); // check instance against request if ($instance == null) return GenericAdmin::EC_NOSU_INST; if ($instance->getMod() != $mod) return GenericAdmin::EC_MOD_MISM; // delete instance return $instance->delete(); } }