Ejemplo n.º 1
0
 public function prepareObject(TypeInterface $controller, $parent = null)
 {
     $config = $controller->getConfig();
     $class = $config['storage'];
     $object = new $class();
     if (null !== $parent) {
         $baseclass = \midcom_helper_reflector::resolve_baseclass($class);
         $reflector = new \midgard_reflection_property($baseclass);
         $up_property = \midgard_object_class::get_property_up($baseclass);
         if (!empty($up_property)) {
             $target_property = $reflector->get_link_target($up_property);
             $target_class = $reflector->get_link_name($up_property);
             if (\midcom_helper_reflector::resolve_baseclass($parent) === $target_class) {
                 $object->{$up_property} = $parent->{$target_property};
             }
         }
         $parent_property = \midgard_object_class::get_property_parent($baseclass);
         if (!empty($parent_property)) {
             $target_property = $reflector->get_link_target($parent_property);
             $target_class = $reflector->get_link_name($parent_property);
             if (\midcom_helper_reflector::resolve_baseclass($parent) === $target_class) {
                 $object->{$parent_property} = $parent->{$target_property};
             } else {
                 $object->{$parent_property} = $parent->{$parent_property};
             }
         }
     }
     return $object;
 }
Ejemplo n.º 2
0
 /**
  * Get the target properties and return an array that is used e.g. in copying
  *
  * @param mixed $object     MgdSchema object or MidCOM db object
  * @return array            id, parent property, class and label of the object
  */
 public static function get_target_properties($object)
 {
     $mgdschema_class = midcom_helper_reflector::resolve_baseclass($object);
     $mgdschema_object = new $mgdschema_class($object->guid);
     static $targets = array();
     // Return the cached results
     if (isset($targets[$mgdschema_class])) {
         return $targets[$mgdschema_class];
     }
     // Empty result set for the current class
     $target = array('id' => null, 'parent' => '', 'class' => $mgdschema_class, 'label' => '', 'reflector' => new midcom_helper_reflector($object));
     // Try to get the parent property for determining, which property should be
     // used to point the parent of the new object. Attachments are a special case.
     if (!midcom::get('dbfactory')->is_a($object, 'midcom_db_attachment')) {
         $parent_property = midgard_object_class::get_property_parent($mgdschema_object);
     } else {
         $parent_property = 'parentobject';
     }
     // Get the class label
     $target['label'] = $target['reflector']->get_label_property();
     // Try once more to get the parent property, but now try up as a backup
     if (!$parent_property) {
         $up_property = midgard_object_class::get_property_up($mgdschema_object);
         if (!$up_property) {
             throw new midcom_error('Failed to get the parent property for copying');
         }
         $target['parent'] = $up_property;
     } else {
         $target['parent'] = $parent_property;
     }
     // Cache the results
     $targets[$mgdschema_class] = $target;
     return $targets[$mgdschema_class];
 }
Ejemplo n.º 3
0
 /**
  * Gets a list of link properties and the links target info
  *
  * Link info key specification
  *     'class' string link target class name
  *     'target' string link target property (of target class)
  *     'parent' boolean link is link to "parent" in object tree
  *     'up' boolean link is link to "up" in object tree
  *
  * @return array multidimensional array keyed by property, values are arrays with link info (or false in case of failure)
  */
 public function get_link_properties()
 {
     // Return cached results if we have them
     static $cache = array();
     if (isset($cache[$this->mgdschema_class])) {
         return $cache[$this->mgdschema_class];
     }
     debug_add("Starting analysis for class {$this->mgdschema_class}");
     // Shorthands
     $ref =& $this->_mgd_reflector;
     $obj =& $this->_dummy_object;
     // Get property list and start checking (or abort on error)
     $properties = get_object_vars($obj);
     if (empty($properties)) {
         debug_add("Could not list object properties, aborting", MIDCOM_LOG_ERROR);
         return false;
     }
     $links = array();
     $parent_property = midgard_object_class::get_property_parent($obj);
     $up_property = midgard_object_class::get_property_up($obj);
     foreach ($properties as $property => $dummy) {
         if ($property == 'guid') {
             // GUID, even though of type MGD_TYPE_GUID, is never a link
             continue;
         }
         if (!$ref->is_link($property) && $ref->get_midgard_type($property) != MGD_TYPE_GUID) {
             continue;
         }
         debug_add("Processing property '{$property}'");
         $linkinfo = array('class' => null, 'target' => null, 'parent' => false, 'up' => false, 'type' => $ref->get_midgard_type($property));
         if (!empty($parent_property) && $parent_property === $property) {
             debug_add("Is 'parent' property");
             $linkinfo['parent'] = true;
         }
         if (!empty($up_property) && $up_property === $property) {
             debug_add("Is 'up' property");
             $linkinfo['up'] = true;
         }
         $type = $ref->get_link_name($property);
         debug_add("get_link_name returned '{$type}'");
         if (!empty($type)) {
             $linkinfo['class'] = $type;
         }
         unset($type);
         $target = $ref->get_link_target($property);
         debug_add("get_link_target returned '{$target}'");
         if (!empty($target)) {
             $linkinfo['target'] = $target;
         } elseif ($linkinfo['type'] == MGD_TYPE_GUID) {
             $linkinfo['target'] = 'guid';
         }
         unset($target);
         $links[$property] = $linkinfo;
         unset($linkinfo);
     }
     debug_print_r("Links for {$this->mgdschema_class}: ", $links);
     $cache[$this->mgdschema_class] = $links;
     return $links;
 }
Ejemplo n.º 4
0
 /**
  * Resolves the "root level" classes, used by get_root_classes()
  *
  * @return array of classnames (or false on critical failure)
  */
 private static function _resolve_root_classes()
 {
     $root_exceptions_notroot = midcom_baseclasses_components_configuration::get('midcom.helper.reflector', 'config')->get('root_class_exceptions_notroot');
     // Safety against misconfiguration
     if (!is_array($root_exceptions_notroot)) {
         debug_add("config->get('root_class_exceptions_notroot') did not return array, invalid configuration ??", MIDCOM_LOG_ERROR);
         $root_exceptions_notroot = array();
     }
     $root_classes = array();
     foreach (midcom_connection::get_schema_types() as $schema_type) {
         if (substr($schema_type, 0, 2) == '__') {
             continue;
         }
         if (in_array($schema_type, $root_exceptions_notroot)) {
             // Explicitly specified to not be root class, skip all heuristics
             continue;
         }
         // Class extensions mapping
         $schema_type = midcom_helper_reflector::class_rewrite($schema_type);
         // Make sure we only add classes once
         if (in_array($schema_type, $root_classes)) {
             // Already listed
             continue;
         }
         $parent = midgard_object_class::get_property_parent($schema_type);
         if (!empty($parent)) {
             // type has parent set, thus cannot be root type
             continue;
         }
         $dba_class = midcom::get('dbclassloader')->get_midcom_class_name_for_mgdschema_object($schema_type);
         if (!$dba_class) {
             // Not a MidCOM DBA object, skip
             continue;
         }
         $root_classes[] = $schema_type;
     }
     unset($root_exceptions_notroot);
     $root_exceptions_forceroot = midcom_baseclasses_components_configuration::get('midcom.helper.reflector', 'config')->get('root_class_exceptions_forceroot');
     // Safety against misconfiguration
     if (!is_array($root_exceptions_forceroot)) {
         debug_add("config->get('root_class_exceptions_forceroot') did not return array, invalid configuration ??", MIDCOM_LOG_ERROR);
         $root_exceptions_forceroot = array();
     }
     if (!empty($root_exceptions_forceroot)) {
         foreach ($root_exceptions_forceroot as $schema_type) {
             if (!class_exists($schema_type)) {
                 // Not a valid class
                 debug_add("Type {$schema_type} has been listed to always be root class, but the class does not exist", MIDCOM_LOG_WARN);
                 continue;
             }
             if (in_array($schema_type, $root_classes)) {
                 // Already listed
                 continue;
             }
             $root_classes[] = $schema_type;
         }
     }
     usort($root_classes, 'strnatcmp');
     return $root_classes;
 }
Ejemplo n.º 5
0
 /**
  * Get the GUID of the object's parent. This is done by reading up or parent
  * property values, which will give us the parent's ID. Since the ID => GUID relation
  * won't change, the corresponding GUID is then stored in an in-request static cache
  */
 public static function get_parent_guid_uncached_static($object_guid, $class_name)
 {
     static $parent_mapping = array();
     $class_name = midcom::get('dbclassloader')->get_mgdschema_class_name_for_midcom_class($class_name);
     $reflector = new midgard_reflection_property($class_name);
     $up_property = midgard_object_class::get_property_up($class_name);
     if (!empty($up_property)) {
         $target_property = $reflector->get_link_target($up_property);
         // Up takes precedence over parent
         $mc = new midgard_collector($class_name, 'guid', $object_guid);
         $mc->set_key_property($up_property);
         $mc->execute();
         $link_values = $mc->list_keys();
         if (!empty($link_values)) {
             list($link_value, $dummy) = each($link_values);
             unset($mc, $link_values, $dummy);
             if (!empty($link_value)) {
                 if (!array_key_exists($class_name, $parent_mapping)) {
                     $parent_mapping[$class_name] = array();
                 }
                 if (array_key_exists($link_value, $parent_mapping[$class_name])) {
                     return $parent_mapping[$class_name][$link_value];
                 }
                 $mc2 = new midgard_collector($class_name, $target_property, $link_value);
                 $mc2->set_key_property('guid');
                 $mc2->execute();
                 $guids = $mc2->list_keys();
                 if (!is_array($guids)) {
                     unset($mc2, $guids, $link_value);
                     $parent_mapping[$class_name][$link_value] = null;
                     return $parent_mapping[$class_name][$link_value];
                 }
                 list($parent_guid, $dummy) = each($guids);
                 $parent_mapping[$class_name][$link_value] = $parent_guid;
                 unset($mc2, $guids, $link_value, $dummy);
                 return $parent_guid;
             }
         } else {
             unset($mc, $link_values);
         }
     }
     $parent_property = midgard_object_class::get_property_parent($class_name);
     if (!empty($parent_property) && $reflector->get_link_target($parent_property)) {
         $target_property = $reflector->get_link_target($parent_property);
         $target_class = $reflector->get_link_name($parent_property);
         $mc = new midgard_collector($class_name, 'guid', $object_guid);
         $mc->set_key_property($parent_property);
         $mc->execute();
         $link_values = $mc->list_keys();
         if (!empty($link_values)) {
             list($link_value, $dummy) = each($link_values);
             unset($mc, $link_values, $dummy);
             if (!empty($link_value)) {
                 if (!array_key_exists($target_class, $parent_mapping)) {
                     $parent_mapping[$target_class] = array();
                 }
                 if (array_key_exists($link_value, $parent_mapping[$target_class])) {
                     return $parent_mapping[$target_class][$link_value];
                 }
                 $mc2 = new midgard_collector($target_class, $target_property, $link_value);
                 $mc2->set_key_property('guid');
                 $mc2->execute();
                 $guids = $mc2->list_keys();
                 if (!is_array($guids)) {
                     unset($mc2, $guids, $link_value);
                     $parent_mapping[$target_class][$link_value] = null;
                     return $parent_mapping[$target_class][$link_value];
                 }
                 list($parent_guid, $dummy) = each($guids);
                 $parent_mapping[$target_class][$link_value] = $parent_guid;
                 unset($mc2, $guids, $link_value, $dummy);
                 return $parent_guid;
             }
         } else {
             unset($mc, $link_values);
         }
     }
     // FIXME: Handle GUID linking
     return null;
 }
Ejemplo n.º 6
0
 private function getChildTypes($midgard_class)
 {
     $mgdschemas = $this->getTypes();
     $child_types = array();
     foreach ($mgdschemas as $mgdschema) {
         if ($mgdschema == 'midgard_attachment' || $mgdschema == 'midgard_parameter') {
             continue;
         }
         $link_properties = array('parent' => \midgard_object_class::get_property_parent($mgdschema), 'up' => \midgard_object_class::get_property_up($mgdschema));
         $ref = new \midgard_reflection_property($mgdschema);
         foreach ($link_properties as $type => $property) {
             $link_class = $ref->get_link_name($property);
             if (empty($link_class) && $ref->get_midgard_type($property) === MGD_TYPE_GUID) {
                 $child_types[] = $mgdschema;
                 continue;
             }
             if ($link_class == $parent_class) {
                 $child_types[] = $mgdschema;
             }
         }
     }
     return $child_types;
 }