public function Edit($pa_values = null, $pa_options = null) { $o_result_context = new ResultContext($this->request, 'ca_relationship_types', 'basic_search'); $va_cur_result = $o_result_context->getResultList(); $vn_id = $this->request->getParameter('type_id', pInteger); $vn_parent_id = $this->request->getParameter('parent_id', pInteger); // If we're creating a new record we'll need to establish the table_num // from the parent (there's always a parent) if (!$vn_id) { $t_parent = new ca_relationship_types($vn_parent_id); if (!$t_parent->getPrimaryKey()) { $this->postError(1230, _t("Invalid parent"), "RelationshipTypeEditorController->Edit()"); return; } $this->request->setParameter('table_num', $t_parent->get('table_num')); } if (!is_array($va_cur_result) || !in_array($vn_id, $va_cur_result)) { // // Set "results list" navigation to all types in the same level as the currently selected type // $t_instance = new ca_relationship_types(); if (is_array($va_siblings = $t_instance->getHierarchySiblings($this->request->getParameter('type_id', pInteger), array('idsOnly' => true)))) { $o_result_context->setResultList($va_siblings); $o_result_context->saveContext(); } } parent::Edit(); }
/** * 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; }
public function getDisplaysAsXML() { $t_display = new ca_bundle_displays(); /** @var Datamodel $o_dm */ $o_dm = Datamodel::load(); $this->opt_locale = new ca_locales(); $va_displays = $t_display->getBundleDisplays(); $vs_buf = "<displays>\n"; foreach ($va_displays as $vn_i => $va_display_by_locale) { $va_locales = array_keys($va_display_by_locale); $va_info = $va_display_by_locale[$va_locales[0]]; if (!$t_display->load($va_info['display_id'])) { continue; } $vs_buf .= "\t<display code='" . ($va_info['display_code'] && preg_match('!^[A-Za-z0-9_]+$!', $va_info['display_code']) ? $va_info['display_code'] : 'display_' . $va_info['display_id']) . "' type='" . $o_dm->getTableName($va_info['table_num']) . "' system='" . $t_display->get('is_system') . "'>\n"; $vs_buf .= "\t\t<labels>\n"; foreach ($va_display_by_locale as $vn_locale_id => $va_display_info) { if (strlen($this->opt_locale->localeIDToCode($vn_locale_id)) > 0) { $vs_buf .= "\t\t\t<label locale='" . $this->opt_locale->localeIDToCode($vn_locale_id) . "'><name>" . caEscapeForXML($va_display_info['name']) . "</name></label>\n"; } } $vs_buf .= "\t\t</labels>\n"; $va_settings = $t_display->getSettings(); if (sizeof($va_settings) > 0) { $vs_buf .= "\t\t<settings>\n"; foreach ($va_settings as $vs_setting => $vm_val) { if (is_array($vm_val)) { foreach ($vm_val as $vn_i => $vn_val) { $vs_buf .= "\t\t\t<setting name='{$vs_setting}'><![CDATA[" . $vn_val . "]]></setting>\n"; } } else { $vs_buf .= "\t\t\t<setting name='{$vs_setting}'><![CDATA[" . $vm_val . "]]></setting>\n"; } } $vs_buf .= "\t\t</settings>\n"; } // User and group access $va_users = $t_display->getUsers(); if (sizeof($va_users) > 0) { $vs_buf .= "\t\t<userAccess>\n"; foreach ($va_users as $va_user_info) { $vs_buf .= "\t\t\t<permission user='******' access='" . $this->_convertUserGroupAccessToString(intval($va_user_info['access'])) . "'/>\n"; } $vs_buf .= "\t\t</userAccess>\n"; } $va_groups = $t_display->getUserGroups(); if (sizeof($va_groups) > 0) { $vs_buf .= "\t\t<groupAccess>\n"; foreach ($va_groups as $va_group_info) { $vs_buf .= "\t\t\t<permission group='" . $va_group_info["code"] . "' access='" . $this->_convertUserGroupAccessToString(intval($va_group_info['access'])) . "'/>\n"; } $vs_buf .= "\t\t</groupAccess>\n"; } $va_placements = $t_display->getPlacements(); $vs_buf .= "<bundlePlacements>\n"; foreach ($va_placements as $vn_placement_id => $va_placement_info) { $vs_buf .= "\t\t<placement code='" . preg_replace("![^A-Za-z0-9_]+!", "_", $va_placement_info['bundle_name']) . "'><bundle>" . $va_placement_info['bundle_name'] . "</bundle>\n"; $va_settings = caUnserializeForDatabase($va_placement_info['settings']); if (is_array($va_settings)) { $vs_buf .= "<settings>\n"; foreach ($va_settings as $vs_setting => $vm_value) { switch ($vs_setting) { case 'label': if (is_array($vm_value)) { foreach ($vm_value as $vn_locale_id => $vm_locale_specific_value) { if (preg_match("/^[a-z]{2,3}\\_[A-Z]{2,3}\$/", $vn_locale_id)) { // locale code $vs_locale_code = $vn_locale_id; } else { if (!($vs_locale_code = $this->opt_locale->localeIDToCode($vn_locale_id))) { $vs_locale_code = 'en_US'; } } $vs_buf .= "<setting name='label' locale='" . $vs_locale_code . "'>" . caEscapeForXML($vm_locale_specific_value) . "</setting>\n"; } } break; case 'restrict_to_relationship_types': if (is_array($vm_value)) { foreach ($vm_value as $vn_val) { $t_rel_type = new ca_relationship_types($vn_val); if ($t_rel_type->getPrimaryKey()) { $vs_value = $t_rel_type->get('type_code'); $vs_buf .= "\t\t\t\t<setting name='{$vs_setting}'><![CDATA[" . $vs_value . "]]></setting>\n"; } } } break; case 'restrict_to_types': if (is_array($vm_value)) { foreach ($vm_value as $vn_val) { $t_item = new ca_list_items($vn_val); if ($t_item->getPrimaryKey()) { $vs_value = $t_item->get('idno'); $vs_buf .= "\t\t\t\t<setting name='{$vs_setting}'><![CDATA[" . $vs_value . "]]></setting>\n"; } } } break; default: if (is_array($vm_value)) { foreach ($vm_value as $vn_i => $vn_val) { $vs_buf .= "\t\t\t\t<setting name='{$vs_setting}'><![CDATA[" . $vn_val . "]]></setting>\n"; } } else { $vs_buf .= "\t\t\t\t<setting name='{$vs_setting}'><![CDATA[" . $vm_value . "]]></setting>\n"; } break; } } $vs_buf .= "</settings>\n"; } $vs_buf .= "\t\t</placement>\n"; } $vs_buf .= "</bundlePlacements>\n"; $vs_buf .= "\t</display>\n"; } $vs_buf .= "</displays>\n"; return $vs_buf; }
/** * @param array $pa_options Option are * create = create relationship type using parameters if one with the specified type code or type_id doesn't exist already [default=false] * cache = cache relationship types as they are referenced and return cached value if possible [default=true] */ public function getRelationshipTypeID($pm_table_name_or_num, $pm_type_code_or_id, $pn_locale_id = null, $pa_values = null, $pa_options = null) { if (!is_array($pa_options)) { $pa_options = array(); } if (!isset($pa_options['create'])) { $pa_options['create'] = false; } if (!isset($pa_options['cache'])) { $pa_options['cache'] = true; } $pm_type_code_or_id = mb_strtolower($pm_type_code_or_id); if (!is_numeric($pm_table_name_or_num)) { $vn_table_num = $this->getAppDatamodel()->getTableNum($pm_table_name_or_num); } else { $vn_table_num = $pm_table_name_or_num; } if ($pa_options['cache'] && isset(ca_relationship_types::$s_relationship_type_id_cache[$vn_table_num . '/' . $pm_type_code_or_id])) { return ca_relationship_types::$s_relationship_type_id_cache[$vn_table_num . '/' . $pm_type_code_or_id]; } if (is_numeric($pm_type_code_or_id)) { if ($va_relationships = $this->getRelationshipInfo($pm_table_name_or_num)) { if (isset($va_relationships[$pm_type_code_or_id])) { return ca_relationship_types::$s_relationship_type_id_cache[$vn_table_num . '/' . $pm_type_code_or_id] = $pm_type_code_or_id; } } } else { if ($va_relationships = $this->getRelationshipInfo($pm_table_name_or_num, $pm_type_code_or_id)) { foreach ($va_relationships as $vn_type_id => $va_type_info) { if ($va_type_info['type_code'] == $pm_type_code_or_id) { return ca_relationship_types::$s_relationship_type_id_cache[$vn_table_num . '/' . $pm_type_code_or_id] = $vn_type_id; } } } } if (isset($pa_options['create']) && $pa_options['create'] && $pn_locale_id && is_array($pa_values)) { $t_rel = new ca_relationship_types(); $t_rel->setMode(ACCESS_WRITE); $t_rel->set('type_code', $pm_type_code_or_id); $t_rel->set('table_num', $vn_table_num); $t_rel->set('sub_type_left_id', isset($pa_values['sub_type_left_id']) ? (int) $pa_values['sub_type_left_id'] : null); $t_rel->set('sub_type_right_id', isset($pa_values['sub_type_right_id']) ? (int) $pa_values['sub_type_right_id'] : null); $t_rel->set('parent_id', isset($pa_values['parent_id']) ? (int) $pa_values['parent_id'] : null); $t_rel->set('rank', isset($pa_values['rank']) ? (int) $pa_values['rank'] : 0); $t_rel->set('is_default', isset($pa_values['is_default']) ? (int) $pa_values['is_default'] : 0); $t_rel->insert(); if ($t_rel->numErrors()) { $this->errors = $t_rel->errors; return false; } if (!isset($pa_values['typename_reverse']) || !$pa_values['typename_reverse']) { $pa_values['typename_reverse'] = $pa_values['typename']; } $t_rel->addLabel(array('typename' => isset($pa_values['typename']) ? $pa_values['typename'] : $pm_type_code_or_id, 'typename_reverse' => isset($pa_values['typename_reverse']) ? $pa_values['typename_reverse'] : $pm_type_code_or_id, 'description' => isset($pa_values['description']) ? $pa_values['description'] : '', 'description_reverse' => isset($pa_values['description_reverse']) ? $pa_values['description_reverse'] : ''), $pn_locale_id, null, true); if ($t_rel->numErrors()) { $this->errors = $t_rel->errors; return false; } return ca_relationship_types::$s_relationship_type_id_cache[$vn_table_num . '/' . $pm_type_code_or_id] = $t_rel->getPrimaryKey(); } return null; }
public function getUIsAsDOM() { $t_list = new ca_lists(); $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"); $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); $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); $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 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"]); $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) { if ($vs_value === 0 || $vs_value === "0") { // caExcapeForXML mangles zero values for some reason -> catch them here. $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; }
/** * 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; }
/** * * @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; }
/** * Fetch the type code for a given relationship type id (primary key value) * @param $pn_type_id * @return Array|bool|mixed|null|string */ function caGetRelationshipTypeCode($pn_type_id) { if (CompositeCache::contains($pn_type_id, 'RelationshipIDsToCodes')) { return CompositeCache::fetch($pn_type_id, 'RelationshipIDsToCodes'); } $t_rel_types = new ca_relationship_types($pn_type_id); if (!$t_rel_types->getPrimaryKey()) { return false; } $vs_code = $t_rel_types->get('type_code'); CompositeCache::save($pn_type_id, $vs_code, 'RelationshipIDsToCodes'); return $vs_code; }