/** * Converts list of relationships type codes and/or numeric ids to an id-only list */ private function _getRelationshipTypeIDs($pa_relationship_types, $pm_relationship_table_or_id) { $t_rel_type = new ca_relationship_types(); $va_type_list = $pa_relationship_types; foreach ($va_type_list as $vn_i => $vm_type) { if (!trim($vm_type)) { unset($pa_relationship_types[$vn_i]); continue; } if (!is_numeric($vm_type)) { // try to translate item_value code into numeric id if (!($vn_type_id = $t_rel_type->getRelationshipTypeID($pm_relationship_table_or_id, $vm_type))) { unset($pa_relationship_types[$vn_i]); continue; } unset($pa_relationship_types[$vn_i]); $pa_relationship_types[] = $vn_type_id; } else { if (!$t_rel_type->load($vm_type)) { unset($pa_relationship_types[$vn_i]); continue; } $vn_type_id = $t_rel_type->getPrimaryKey(); } $va_ids = $t_rel_type->getHierarchy($vn_type_id, array('idsOnly' => true)); if (is_array($va_ids)) { foreach ($va_ids as $vn_id) { $pa_relationship_types[] = $vn_id; } } } return $pa_relationship_types; }
/** * Returns an associative array of relationship types for the relationship * organized by the sub_type_id specified by $ps_orientation. If $ps_orientation is the name of the "right" table * then sub_type_left_id is used for keys in the array, if $ps_orientation is the name of the "left" table * then sub_type_right_id is used for keys. * * For example, for ca_objects_x_entities, if $ps_orientation is ca_objects then then sub_type_right_id is * used as the key; if ca_entities is passed then sub_type_left_id is used; if a table name is passed that * is not either side of the relation then an empty array is returned * */ public function getRelationshipTypesBySubtype($ps_orientation, $pn_type_id, $pa_options = null) { unset($pa_options['request']); if (!$this->hasField('type_id')) { return array(); } $vs_left_table_name = $this->getLeftTableName(); $vs_right_table_name = $this->getRightTableName(); $vb_dont_include_subtypes_in_type_restriction = caGetOptions('dont_include_subtypes_in_type_restriction', $pa_options, false); $o_db = $this->getDb(); $t_rel_type = new ca_relationship_types(); $vs_restrict_to_relationship_type_sql = ''; if (isset($pa_options['restrict_to_relationship_types']) && $pa_options['restrict_to_relationship_types']) { if (!is_array($pa_options['restrict_to_relationship_types'])) { $pa_options['restrict_to_relationship_types'] = array($pa_options['restrict_to_relationship_types']); } if (sizeof($pa_options['restrict_to_relationship_types'])) { $va_restrict_to_type_list = array(); foreach ($pa_options['restrict_to_relationship_types'] as $vs_type_code) { if (!strlen(trim($vs_type_code))) { continue; } $va_criteria = array('table_num' => $this->tableNum()); if (is_numeric($vs_type_code)) { $va_criteria['type_id'] = (int) $vs_type_code; } else { $va_criteria['type_code'] = $vs_type_code; } if ($t_rel_type->load($va_criteria)) { $va_restrict_to_type_list[] = "(crt.hier_left >= " . $t_rel_type->get('hier_left') . " AND crt.hier_right <= " . $t_rel_type->get('hier_right') . ")"; } } if (sizeof($va_restrict_to_type_list)) { $vs_restrict_to_relationship_type_sql = " AND (" . join(' OR ', $va_restrict_to_type_list) . ")"; } } } $qr_res = $o_db->query("\n\t\t\t\tSELECT *\n\t\t\t\tFROM ca_relationship_types crt\n\t\t\t\tINNER JOIN ca_relationship_type_labels AS crtl ON crt.type_id = crtl.type_id\n\t\t\t\tWHERE\n\t\t\t\t\t(crt.table_num = ?)\n\t\t\t\t\t{$vs_restrict_to_relationship_type_sql}\n\t\t\t", $this->tableNum()); // Support hierarchical subtypes - if the subtype restriction is a type with parents then include those as well // Allows subtypes to "inherit" bindings from parent types $t_list_item = new ca_list_items($pn_type_id); if (!$vb_dont_include_subtypes_in_type_restriction) { if (!is_array($va_ancestor_ids = $t_list_item->getHierarchyAncestors(null, array('idsOnly' => true, 'includeSelf' => true)))) { $va_ancestor_ids = array(); } // remove hierarchy root from ancestor list, otherwise invalid bindings // from root nodes (which are not "real" rel types) may be inherited array_pop($va_ancestor_ids); } else { $va_ancestor_ids = array($pn_type_id); } $va_types = array(); $va_parent_ids = array(); $vn_l = 0; $vn_root_id = $t_rel_type->load(array('parent_id' => null, 'table_num' => $this->tableNum())) ? $t_rel_type->getPrimaryKey() : null; $va_hier = array(); if ($vs_left_table_name === $vs_right_table_name) { // ---------------------------------------------------------------------------------------- // self relationship while ($qr_res->nextRow()) { $va_row = $qr_res->getRow(); $vn_parent_id = $va_row['parent_id']; $va_hier[$vn_parent_id][] = $va_row['type_id']; // skip type if it has a subtype set and it's not in our list $vs_subtype_orientation = null; $vs_subtype = null; if ($va_row['sub_type_left_id'] && !in_array($va_row['sub_type_left_id'], $va_ancestor_ids)) { // not left if ($va_row['sub_type_right_id'] && !in_array($va_row['sub_type_right_id'], $va_ancestor_ids)) { // not left and not right continue; } else { // not left and right $vs_subtype = $va_row['sub_type_left_id']; $vs_subtype_orientation = "left"; } } else { if ($va_row['sub_type_left_id'] && in_array($va_row['sub_type_left_id'], $va_ancestor_ids)) { // left if ($va_row['sub_type_right_id'] && in_array($va_row['sub_type_right_id'], $va_ancestor_ids)) { // left and right $vs_subtype = $va_row['sub_type_right_id']; $vs_subtype_orientation = ""; } else { // left and not right $vs_subtype_orientation = "right"; $vs_subtype = $va_row['sub_type_right_id']; } } } if (!$vs_subtype) { $vs_subtype = 'NULL'; } switch ($vs_subtype_orientation) { case 'left': $va_tmp = $va_row; $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']); $va_tmp['typename'] = $va_tmp['typename_reverse']; unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $va_types[$vn_parent_id][$vs_subtype][$vs_key][$va_row['type_id']][$va_row['locale_id']] = $va_tmp; break; case 'right': $va_tmp = $va_row; $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']); unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $va_types[$vn_parent_id][$vs_subtype][$vs_key][$va_row['type_id']][$va_row['locale_id']] = $va_tmp; break; default: $va_tmp = $va_row; if (trim($va_tmp['typename']) == trim($va_tmp['typename_reverse'])) { // // If the sides of the self-relationship are the same then treat it like a normal relationship type: one entry in the // list and a plain type_id value // unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $va_tmp['direction'] = null; $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']); $va_types[$vn_parent_id][$vs_subtype][$vs_key][$va_row['type_id']][$va_row['locale_id']] = $va_tmp; } else { // // If each side of the self-relationship type are different then add both to the list with special type_id values that // indicate the directionality of the typename (ltor = left to right = "typename"; rtor = right to left = "typename_reverse") // $va_tmp = $va_row; unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename']); $va_tmp['direction'] = 'ltor'; $va_types[$vn_parent_id][$vs_subtype][$vs_key]['ltor_' . $va_row['type_id']][$va_row['locale_id']] = $va_tmp; $va_tmp = $va_row; $va_tmp['typename'] = $va_tmp['typename_reverse']; unset($va_tmp['typename_reverse']); // we pass the typename adjusted for direction in 'typename', so there's no need to include typename_reverse in the returned values $vs_key = strlen($va_tmp['rank']) > 0 ? sprintf("%08d", (int) $va_tmp['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_tmp['typename_reverse']); $va_tmp['direction'] = 'rtol'; $va_types[$vn_parent_id][$vs_subtype][$vs_key]['rtol_' . $va_row['type_id']][$va_row['locale_id']] = $va_tmp; } break; } } $va_types = $this->_processRelationshipHierarchy($vn_root_id, $va_hier, $va_types, 1); $va_processed_types = array('_type_map' => array()); $va_subtype_lookups = array(); foreach ($va_types as $vs_subtype => $va_types_by_subtype) { $va_types_by_locale = array(); foreach ($va_types_by_subtype as $vs_key => $va_types_by_key) { foreach ($va_types_by_key as $vs_k => $va_v) { foreach ($va_v as $vs_k2 => $vs_v2) { $va_types_by_locale[$vs_k][$vs_k2] = $vs_v2; } } } if (!$vb_dont_include_subtypes_in_type_restriction) { // include mapping from parent type used in restriction to child types that inherit the binding if ($vs_subtype != 'NULL' && (!isset($va_subtype_lookups[$vs_subtype]) || !$va_subtype_lookups[$vs_subtype])) { $va_children = $t_list_item->getHierarchyChildren($vs_subtype, array('idsOnly' => true)); foreach ($va_children as $vn_child) { $va_processed_types['_type_map'][$vn_child] = $vs_subtype; } $va_subtype_lookups[$vs_subtype] = true; } } $va_processed_types[$vs_subtype] = caExtractValuesByUserLocale($va_types_by_locale, null, null, array('returnList' => true)); } } else { // ---------------------------------------------------------------------------------------- // regular relationship if (!in_array($ps_orientation, array($vs_left_table_name, $vs_right_table_name))) { return array(); } while ($qr_res->nextRow()) { $va_row = $qr_res->getRow(); $vn_parent_id = $va_row['parent_id']; $va_hier[$vn_parent_id][] = $va_row['type_id']; if ($ps_orientation == $vs_left_table_name) { // right-to-left // expand subtype $va_subtypes_to_check = $va_row['sub_type_left_id'] > 0 ? caMakeTypeIDList($vs_left_table_name, array($va_row['sub_type_left_id'])) : null; // skip type if it has a subtype set and it's not in our list if (!(!$va_subtypes_to_check || sizeof(array_intersect($va_subtypes_to_check, $va_ancestor_ids)))) { continue; } $vs_subtype = $va_row['sub_type_right_id']; $vs_key = strlen($va_row['rank']) > 0 ? sprintf("%08d", (int) $va_row['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename']); } else { // left-to-right // expand subtype $va_subtypes_to_check = $va_row['sub_type_right_id'] > 0 ? caMakeTypeIDList($vs_right_table_name, array($va_row['sub_type_right_id'])) : null; // skip type if it has a subtype set and it's not in our list if (!(!$va_subtypes_to_check || sizeof(array_intersect($va_subtypes_to_check, $va_ancestor_ids)))) { continue; } $vs_subtype = $va_row['sub_type_left_id']; $va_row['typename'] = $va_row['typename_reverse']; $vs_key = strlen($va_row['rank']) > 0 ? sprintf("%08d", (int) $va_row['rank']) . preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename_reverse']) : preg_replace('![^A-Za-z0-9_]+!', '_', $va_row['typename_reverse']); } unset($va_row['typename_reverse']); // we pass the typename adjusted for direction in '_display', so there's no need to include typename_reverse in the returned values if (!$vs_subtype) { $vs_subtype = 'NULL'; } $vn_type_id = $va_row['type_id']; $va_types[$vn_parent_id][$vs_subtype][$vs_key][$vn_type_id][$va_row['locale_id']] = $va_row; } $va_types = $this->_processRelationshipHierarchy($vn_root_id, $va_hier, $va_types, 1); $va_processed_types = array('_type_map' => array()); $va_subtype_lookups = array(); foreach ($va_types as $vs_subtype => $va_types_by_subtype) { $va_types_by_locale = array(); foreach ($va_types_by_subtype as $vs_key => $va_types_by_key) { foreach ($va_types_by_key as $vn_locale_id => $va_t) { if (!is_array($va_types_by_locale[$vn_locale_id])) { $va_types_by_locale[$vn_locale_id] = array(); } $va_types_by_locale[$vn_locale_id] += $va_t; } } if (!$vb_dont_include_subtypes_in_type_restriction) { // include mapping from parent type used in restriction to child types that inherit the binding if ($vs_subtype != 'NULL' && (!isset($va_subtype_lookups[$vs_subtype]) || !$va_subtype_lookups[$vs_subtype])) { $va_children = $t_list_item->getHierarchyChildren($vs_subtype, array('idsOnly' => true)); foreach ($va_children as $vn_child) { $va_processed_types['_type_map'][$vn_child] = $vs_subtype; } $va_subtype_lookups[$vs_subtype] = true; } } $va_processed_types[$vs_subtype] = caExtractValuesByUserLocale($va_types_by_locale, null, null, array('returnList' => true)); } } return $va_processed_types; }
public function getUIsAsDOM() { $t_list = new ca_lists(); $t_rel_type = new ca_relationship_types(); $vo_uis = $this->opo_dom->createElement("userInterfaces"); $qr_uis = $this->opo_db->query("SELECT * FROM ca_editor_uis ORDER BY ui_id"); while ($qr_uis->nextRow()) { $vo_ui = $this->opo_dom->createElement("userInterface"); $t_ui = new ca_editor_uis($qr_uis->get("ui_id")); $vs_type = $this->opo_dm->getTableName($qr_uis->get("editor_type")); if (strlen($vs_code = $qr_uis->get("editor_code")) > 0) { $vo_ui->setAttribute("code", $this->makeIDNO($vs_code)); } else { $vo_ui->setAttribute("code", "standard_{$vs_type}_ui"); } $vo_ui->setAttribute("type", $vs_type); // labels $vo_labels = $this->opo_dom->createElement("labels"); $qr_ui_labels = $this->opo_db->query("SELECT * FROM ca_editor_ui_labels WHERE ui_id=?", $qr_uis->get("ui_id")); if ($qr_ui_labels->numRows() > 0) { while ($qr_ui_labels->nextRow()) { if ($vs_locale = $this->opt_locale->localeIDToCode($qr_ui_labels->get("locale_id"))) { $vo_label = $this->opo_dom->createElement("label"); $vo_label->setAttribute("locale", $vs_locale); $vo_label->appendChild($this->opo_dom->createElement("name", caEscapeForXML($qr_ui_labels->get("name")))); $vo_labels->appendChild($vo_label); } } } else { $vo_label = $this->opo_dom->createElement("label"); $vo_label->setAttribute("locale", "en_US"); $vo_label->appendChild($this->opo_dom->createElement("name", caEscapeForXML($vs_code))); $vo_labels->appendChild($vo_label); } $vo_ui->appendChild($vo_labels); // type restrictions $va_ui_type_restrictions = $t_ui->getTypeRestrictions(); if (sizeof($va_ui_type_restrictions) > 0) { $vo_ui_type_restrictions = $this->opo_dom->createElement("typeRestrictions"); $vo_ui->appendChild($vo_ui_type_restrictions); foreach ($va_ui_type_restrictions as $va_restriction) { $vo_restriction = $this->opo_dom->createElement("restriction"); $vo_ui_type_restrictions->appendChild($vo_restriction); /** @var BaseModelWithAttributes $t_instance */ $t_instance = $this->opo_dm->getInstanceByTableNum($va_restriction["table_num"]); if ($t_instance instanceof BaseRelationshipModel) { $t_rel_type->load($va_restriction["type_id"]); $vo_restriction->setAttribute("type", $t_rel_type->get('type_code')); } else { $vs_type_code = $t_instance->getTypeListCode(); $va_item = $t_list->getItemFromListByItemID($vs_type_code, $va_restriction["type_id"]); $vo_restriction->setAttribute("type", $va_item["idno"]); } } } // User and group access $va_users = $t_ui->getUsers(); if (sizeof($va_users) > 0) { $vo_user_access = $this->opo_dom->createElement("userAccess"); $vo_ui->appendChild($vo_user_access); foreach ($va_users as $va_user_info) { $vo_permission = $this->opo_dom->createElement("permission"); $vo_user_access->appendChild($vo_permission); $vo_permission->setAttribute("user", $va_user_info["user_name"]); $vo_permission->setAttribute("access", $this->_convertUserGroupAccessToString(intval($va_user_info['access']))); } } $va_groups = $t_ui->getUserGroups(); if (sizeof($va_groups) > 0) { $vo_group_access = $this->opo_dom->createElement("groupAccess"); $vo_ui->appendChild($vo_group_access); foreach ($va_groups as $va_group_info) { $vo_permission = $this->opo_dom->createElement("permission"); $vo_group_access->appendChild($vo_permission); $vo_permission->setAttribute("group", $va_group_info["code"]); $vo_permission->setAttribute("access", $this->_convertUserGroupAccessToString(intval($va_group_info['access']))); } } // screens $vo_screens = $this->opo_dom->createElement("screens"); $qr_screens = $this->opo_db->query("SELECT * FROM ca_editor_ui_screens WHERE parent_id IS NOT NULL AND ui_id=? ORDER BY rank,screen_id", $qr_uis->get("ui_id")); while ($qr_screens->nextRow()) { $t_screen = new ca_editor_ui_screens($qr_screens->get("screen_id")); $vo_screen = $this->opo_dom->createElement("screen"); if ($vs_idno = $qr_screens->get("idno")) { $vo_screen->setAttribute("idno", $this->makeIDNO($vs_idno)); } $vo_screen->setAttribute("default", $qr_screens->get("is_default")); $vo_labels = $this->opo_dom->createElement("labels"); $qr_screen_labels = $this->opo_db->query("SELECT * FROM ca_editor_ui_screen_labels WHERE screen_id=?", $qr_screens->get("screen_id")); if ($qr_ui_labels->numRows() > 0) { while ($qr_screen_labels->nextRow()) { if ($vs_locale = $this->opt_locale->localeIDToCode($qr_screen_labels->get("locale_id"))) { $vo_label = $this->opo_dom->createElement("label"); $vo_label->setAttribute("locale", $vs_locale); $vo_label->appendChild($this->opo_dom->createElement("name", caEscapeForXML($qr_screen_labels->get("name")))); if (strlen(trim($qr_screen_labels->get("description"))) > 0) { $vo_label->appendChild($this->opo_dom->createElement("description", caEscapeForXML($qr_screen_labels->get("description")))); } $vo_labels->appendChild($vo_label); } } } else { $vo_label = $this->opo_dom->createElement("label"); $vo_label->setAttribute("locale", "en_US"); $vo_label->appendChild($this->opo_dom->createElement("name", caEscapeForXML($vs_code))); $vo_labels->appendChild($vo_label); } $vo_screen->appendChild($vo_labels); if (is_array($t_screen->getTypeRestrictions()) && sizeof($t_screen->getTypeRestrictions()) > 0) { $vo_type_restrictions = $this->opo_dom->createElement("typeRestrictions"); foreach ($t_screen->getTypeRestrictions() as $va_restriction) { $vo_type_restriction = $this->opo_dom->createElement("restriction"); $t_instance = $this->opo_dm->getInstanceByTableNum($va_restriction["table_num"]); if ($t_instance instanceof BaseRelationshipModel) { $t_rel_type->load($va_restriction["type_id"]); $vo_type_restriction->setAttribute("type", $t_rel_type->get('type_code')); } else { $vs_type_code = $t_instance->getTypeListCode(); $va_item = $t_list->getItemFromListByItemID($vs_type_code, $va_restriction["type_id"]); $vo_type_restriction->setAttribute("type", $va_item["idno"]); } $vo_type_restrictions->appendChild($vo_type_restriction); } $vo_screen->appendChild($vo_type_restrictions); } $vo_placements = $this->opo_dom->createElement("bundlePlacements"); $va_placements = $t_screen->getPlacementsInScreen(); if (is_array($va_placements)) { foreach ($va_placements as $va_placement) { $vo_placement = $this->opo_dom->createElement("placement"); $vo_placements->appendChild($vo_placement); $vo_placement->setAttribute("code", $this->makeIDNO($va_placement["placement_code"])); $vo_placement->appendChild($this->opo_dom->createElement("bundle", caEscapeForXML($va_placement["bundle"]))); if (is_array($va_placement["settings"])) { $vo_settings = $this->opo_dom->createElement("settings"); foreach ($va_placement["settings"] as $vs_setting => $va_values) { if (is_null($va_values)) { continue; } if (!is_array($va_values)) { $va_values = array($va_values); } // account for legacy settings if ($vs_setting == "restrict_to_type") { $vs_setting = "restrict_to_types"; } foreach ($va_values as $vs_key => $vs_value) { switch ($vs_setting) { case 'restrict_to_types': $t_item = new ca_list_items($vs_value); if ($t_item->getPrimaryKey()) { $vs_value = $t_item->get('idno'); } break; case 'restrict_to_lists': $t_list = new ca_lists($vs_value); if ($t_list->getPrimaryKey()) { $vs_value = $t_list->get('list_code'); } break; case 'restrict_to_relationship_types': $t_rel_type = new ca_relationship_types($vs_value); if ($t_rel_type->getPrimaryKey()) { $vs_value = $t_rel_type->get('type_code'); } break; } if (strlen($vs_value) > 0) { // caEscapeForXML mangles zero values for some reason -> catch them here. if ($vs_value === 0 || $vs_value === "0") { $vs_setting_val = $vs_value; } else { $vs_setting_val = caEscapeForXML($vs_value); } $vo_setting = @$this->opo_dom->createElement("setting", $vs_setting_val); $vo_setting->setAttribute("name", $vs_setting); if ($vs_setting == "label" || $vs_setting == "add_label" || $vs_setting == "description") { if (preg_match("/^[a-z]{2,3}\\_[A-Z]{2,3}\$/", $vs_key)) { $vo_setting->setAttribute("locale", $vs_key); } else { continue; } } $vo_settings->appendChild($vo_setting); } } } $vo_placement->appendChild($vo_settings); } } } $vo_screen->appendChild($vo_placements); $vo_screens->appendChild($vo_screen); } $vo_ui->appendChild($vo_screens); $vo_uis->appendChild($vo_ui); } return $vo_uis; }
/** * * @return string HTML to display after update */ public function updateRelationshipTypes() { $t_locale = new ca_locales(); $o_config = Configuration::load(); $pn_locale_id = $t_locale->loadLocaleByCode($o_config->get('locale_default')); // default locale_id $o_db = new Db(); $o_dm = Datamodel::load(); $va_tables = $o_dm->getTableNames(); foreach ($va_tables as $vs_table) { if (!preg_match('!_x_!', $vs_table)) { continue; } require_once __CA_MODELS_DIR__ . "/{$vs_table}.php"; if (!($t_table = new $vs_table())) { continue; } $vs_pk = $t_table->primaryKey(); $vn_table_num = $t_table->tableNum(); // Create root ca_relationship_types row for table $t_root = new ca_relationship_types(); if (!$t_root->load(array('type_code' => 'root_for_table_' . $vn_table_num))) { $t_root->logChanges(false); $t_root->setMode(ACCESS_WRITE); $t_root->set('table_num', $vn_table_num); $t_root->set('type_code', 'root_for_table_' . $vn_table_num); $t_root->set('rank', 1); $t_root->set('is_default', 0); $t_root->set('parent_id', null); $t_root->insert(); if ($t_root->numErrors()) { $this->opa_error_messages[] = _t("Could not create root for relationship %1: %2", $vs_table, join('; ', $t_root->getErrors())); continue; } $t_root->addLabel(array('typename' => 'Root for table ' . $vn_table_num, 'typename_reverse' => 'Root for table ' . $vn_table_num), $pn_locale_id, null, true); if ($t_root->numErrors()) { $this->opa_error_messages[] = _t("Could not add label to root for relationship %1: %2", $vs_table, join('; ', $t_root->getErrors())); } } $vn_root_id = $t_root->getPrimaryKey(); // Move existing types under root $qr_types = $o_db->query("\n\t\t\t\t\tUPDATE ca_relationship_types\n\t\t\t\t\tSET parent_id = ?, hier_type_id = ?\n\t\t\t\t\tWHERE\n\t\t\t\t\t\t(table_num = ?) AND (type_id <> ?)\n\t\t\t\t", (int) $vn_root_id, (int) $vn_root_id, (int) $vn_table_num, (int) $vn_root_id); } $t_root->rebuildAllHierarchicalIndexes(); return sizeof($this->opa_error_messages) ? false : true; }