public function __construct($object, &$request_data) { parent::__construct(); $this->_object = $object; $this->_object_path = $this->get_object_path(); $this->_request_data =& $request_data; $this->root_types = midcom_helper_reflector_tree::get_root_classes(); if (array_key_exists('current_type', $this->_request_data)) { $this->expanded_root_types[] = $this->_request_data['current_type']; } else { if (isset($this->_object)) { $object = $this->_object; if (!empty($this->_object_path)) { $object = midcom::get('dbfactory')->get_object_by_guid($this->_object_path[0]); } foreach ($this->root_types as $root_type) { if (is_a($object, $root_type) || midcom_helper_reflector::is_same_class($root_type, $object->__midcom_class_name__)) { $this->expanded_root_types[] = $root_type; break; } } } } }
/** * Get the MgdSchema root classes * * @return array containing class name and translated name */ public static function get_root_classes() { static $root_classes = array(); // Return cached results if (!empty($root_classes)) { return $root_classes; } // Initialize the returnable array $root_classes = array(); // Get the classes $classes = midcom_helper_reflector_tree::get_root_classes(); // Get the translated name foreach ($classes as $class) { $ref = new midcom_helper_reflector($class); $root_classes[$class] = $ref->get_class_label(); } asort($root_classes); return $root_classes; }
/** * Creates a QB instance for get_root_objects and count_root_objects * * @access private */ function &_root_objects_qb(&$deleted) { $schema_type =& $this->mgdschema_class; $root_classes = midcom_helper_reflector_tree::get_root_classes(); if (!in_array($schema_type, $root_classes)) { debug_add("Type {$schema_type} is not a \"root\" type", MIDCOM_LOG_ERROR); $x = false; return $x; } if ($deleted) { $qb = new midgard_query_builder($schema_type); } else { // Figure correct MidCOM DBA class to use and get midcom QB $qb = false; $midcom_dba_classname = midcom::get('dbclassloader')->get_midcom_class_name_for_mgdschema_object($this->_dummy_object); if (empty($midcom_dba_classname)) { debug_add("MidCOM DBA does not know how to handle {$schema_type}", MIDCOM_LOG_ERROR); $x = false; return $x; } if (!midcom::get('dbclassloader')->load_mgdschema_class_handler($midcom_dba_classname)) { debug_add("Failed to load the handling component for {$midcom_dba_classname}, cannot continue.", MIDCOM_LOG_ERROR); $x = false; return $x; } $qb_callback = array($midcom_dba_classname, 'new_query_builder'); if (!is_callable($qb_callback)) { debug_add("Static method {$midcom_dba_classname}::new_query_builder() is not callable", MIDCOM_LOG_ERROR); $x = false; return $x; } $qb = call_user_func($qb_callback); } // Sanity-check if (!$qb) { debug_add("Could not get QB for type '{$schema_type}'", MIDCOM_LOG_ERROR); $x = false; return $x; } // Deleted constraints if ($deleted) { $qb->include_deleted(); $qb->add_constraint('metadata.deleted', '<>', 0); } // Figure out constraint to use to get root level objects $upfield = midgard_object_class::get_property_up($schema_type); if (!empty($upfield)) { $ref =& $this->_mgd_reflector; $uptype = $ref->get_midgard_type($upfield); switch ($uptype) { case MGD_TYPE_STRING: case MGD_TYPE_GUID: $qb->add_constraint($upfield, '=', ''); break; case MGD_TYPE_INT: case MGD_TYPE_UINT: $qb->add_constraint($upfield, '=', 0); break; default: debug_add("Do not know how to handle upfield '{$upfield}' has type {$uptype}", MIDCOM_LOG_ERROR); return false; } } return $qb; }
/** * Helper to resolve the base value for the incrementing suffix and for the name. * * @see midcom_helper_reflector_nameresolver::generate_unique_name() * @param string $current_name the "current name" of the object (might not be the actual name value see the title logic in generate_unique_name()) * @param string $extension The file extension, when working with attachments * @return array first key is the resolved $i second is the $base_name, which is $current_name without numeric suffix */ private function _generate_unique_name_resolve_i($current_name, $extension) { if (preg_match('/(.*?)-([0-9]{3,})' . $extension . '$/', $current_name, $name_matches)) { // Name already has i and base parts, split them. $i = (int) $name_matches[2]; $base_name = (string) $name_matches[1]; unset($name_matches); } else { // Defaults $i = 1; $base_name = $current_name; } // Look for siblings with similar names and see if they have higher i. midcom::get('auth')->request_sudo('midcom.helper.reflector'); $parent = midcom_helper_reflector_tree::get_parent($this->_object); // TODO: Refactor to reduce duplicate code with _name_is_unique_check_siblings if ($parent && !empty($parent->guid)) { // We have parent, check siblings $parent_resolver = new midcom_helper_reflector_tree($parent); $sibling_classes = $parent_resolver->get_child_classes(); if (!in_array('midgard_attachment', $sibling_classes)) { $sibling_classes[] = 'midgard_attachment'; } foreach ($sibling_classes as $schema_type) { $dummy = new $schema_type(); $child_name_property = midcom_helper_reflector::get_name_property($dummy); unset($dummy); if (empty($child_name_property)) { // This sibling class does not use names continue; } $resolver = midcom_helper_reflector_tree::get($schema_type); $qb =& $resolver->_child_objects_type_qb($schema_type, $parent, false); if (!is_object($qb)) { continue; } $qb->add_constraint($child_name_property, 'LIKE', "{$base_name}-%" . $extension); // Do not include current object in results, this is the easiest way if (!empty($this->_object->guid)) { $qb->add_constraint('guid', '<>', $this->_object->guid); } $qb->add_order('name', 'DESC'); // One result should be enough $qb->set_limit(1); $siblings = $qb->execute(); if (empty($siblings)) { // we don't care about fatal qb errors here continue; } $sibling = $siblings[0]; $sibling_name = $sibling->{$child_name_property}; if (preg_match('/(.*?)-([0-9]{3,})' . $extension . '$/', $sibling_name, $name_matches)) { // Name already has i and base parts, split them. $sibling_i = (int) $name_matches[2]; if ($sibling_i >= $i) { $i = $sibling_i + 1; } unset($sibling_i, $name_matches); } } unset($parent, $parent_resolver, $sibling_classes, $schema_type, $child_name_property, $sibling, $sibling_name); } else { unset($parent); // No parent, we might be a root level class $is_root_class = false; $root_classes = midcom_helper_reflector_tree::get_root_classes(); foreach ($root_classes as $schema_type) { if (midcom::get('dbfactory')->is_a($this->_object, $schema_type)) { $is_root_class = true; } } if (!$is_root_class) { // This should not happen, logging error and returning true (even though it's potentially dangerous) midcom::get('auth')->drop_sudo(); debug_add("Object #{$this->_object->guid} has no valid parent but is not listed in the root classes, don't know what to do, letting higher level decide", MIDCOM_LOG_ERROR); unset($root_classes, $is_root_class); return array($i, $base_name); } else { // TODO: Refactor to reduce duplicate code with _name_is_unique_check_roots foreach ($root_classes as $schema_type) { $dummy = new $schema_type(); $child_name_property = midcom_helper_reflector::get_name_property($dummy); unset($dummy); if (empty($child_name_property)) { // This sibling class does not use names continue; } $resolver =& midcom_helper_reflector_tree::get($schema_type); $deleted = false; $qb =& $resolver->_root_objects_qb($deleted); if (!$qb) { continue; } unset($deleted); $qb->add_constraint($child_name_property, 'LIKE', "{$base_name}-%" . $extension); // Do not include current object in results, this is the easiest way if (!empty($this->_object->guid)) { $qb->add_constraint('guid', '<>', $this->_object->guid); } $qb->add_order($child_name_property, 'DESC'); // One result should be enough $qb->set_limit(1); $siblings = $qb->execute(); if (empty($siblings)) { // we dont' care about fatal qb errors here continue; } $sibling = $siblings[0]; $sibling_name = $sibling->{$child_name_property}; if (preg_match('/(.*?)-([0-9]{3,})' . $extension . '$/', $sibling_name, $name_matches)) { // Name already has i and base parts, split them. $sibling_i = (int) $name_matches[2]; if ($sibling_i >= $i) { $i = $sibling_i + 1; } unset($sibling_i, $name_matches); } } unset($root_classes, $schema_type, $child_name_property, $sibling, $sibling_name); } } midcom::get('auth')->drop_sudo(); return array($i, $base_name); }