/** * Saves the content of a form editing new or existing records. It returns the same form + status messages rendered into the current view, inherited from ActionController * * @param array $pa_options Array of options passed through to _initView and saveBundlesForScreen() */ public function Save($pa_options = null) { if (!is_array($pa_options)) { $pa_options = array(); } list($t_subject, $t_ui, $vn_parent_id, $vn_above_id) = $this->_initView(array_merge($pa_options, array('loadSubject' => true))); if (!$t_subject) { $this->postError(1220, _t('Invalid table %1', $this->ops_table_name), "BaseInterstitalController->Edit()"); return false; } if (!is_array($pa_options)) { $pa_options = array(); } // // Is record of correct type? // $va_restrict_to_types = null; if ($t_subject->getAppConfig()->get('perform_type_access_checking')) { $va_restrict_to_types = caGetTypeRestrictionsForUser($this->ops_table_name, array('access' => __CA_BUNDLE_ACCESS_EDIT__)); } if (is_array($va_restrict_to_types) && !in_array($t_subject->get('type_id'), $va_restrict_to_types)) { $this->response->setRedirect($this->request->config->get('error_display_url') . '/n/2560?r=' . urlencode($this->request->getFullUrlPath())); return; } $pn_placement_id = $this->request->getParameter('placement_id', pInteger); // placement_id of bundle that launched interstitial editor $ps_primary_table = $this->request->getParameter('primary', pString); $pn_primary_id = $this->request->getParameter('primary_id', pInteger); // Make sure request isn't empty if (!sizeof($_POST)) { $va_response = array('status' => 20, 'id' => null, 'table' => $t_subject->tableName(), 'type_id' => null, 'display' => null, 'errors' => array(_t("Cannot save using empty request. Are you using a bookmark?") => _t("Cannot save using empty request. Are you using a bookmark?"))); $this->view->setVar('response', $va_response); $this->render('interstitial/interstitial_result_json.php'); return; } // Set type name for display if (!($vs_type_name = $t_subject->getTypeName())) { $vs_type_name = $t_subject->getProperty('NAME_SINGULAR'); } # trigger "BeforeSaveItem" hook $this->opo_app_plugin_manager->hookBeforeSaveItem(array('id' => null, 'table_num' => $t_subject->tableNum(), 'table_name' => $t_subject->tableName(), 'instance' => $t_subject, 'is_insert' => true)); $t_placement = new ca_editor_ui_bundle_placements($pn_placement_id); $pa_bundle_settings = $t_placement->getSettings(); $va_opts = array_merge($pa_options, array('ui_instance' => $t_ui)); $vb_save_rc = $t_subject->saveBundlesForScreen($this->request->getParameter('screen', pString), $this->request, $va_opts); $this->view->setVar('t_ui', $t_ui); $vs_message = _t("Saved changes to %1", $vs_type_name); // // Regenerate display template for bundle that launched the interstitial editor so it will reflect any changes // $vs_related_table = $t_placement->getEditorType(); $vs_template = caGetBundleDisplayTemplate($t_subject, $vs_related_table, $pa_bundle_settings); $qr_rel_items = caMakeSearchResult($t_subject->tableName(), array($t_subject->getPrimaryKey())); // // Handle case of self relationships where we need to figure out which direction things are going in // $va_bundle_values = array_shift(caProcessRelationshipLookupLabel($qr_rel_items, $t_subject, array('template' => $vs_template, 'primaryIDs' => array($ps_primary_table => array($pn_primary_id))))); if ($t_subject->hasField('type_id')) { if (method_exists($t_subject, "isSelfRelationship") && $t_subject->isSelfRelationship()) { $vn_left_id = $t_subject->get($t_subject->getLeftTableFieldName()); $vn_right_id = $t_subject->get($t_subject->getRightTableFieldName()); $va_bundle_values['relationship_typename'] = $t_subject->getRelationshipTypename($vn_left_id == $pn_primary_id ? 'ltol' : 'rtol'); } else { $va_bundle_values['relationship_typename'] = $t_subject->getRelationshipTypename($t_subject->getLeftTableFieldName() == $vs_related_table ? 'rtol' : 'ltor'); } $va_bundle_values['relationship_type_code'] = $t_subject->getRelationshipTypeCode(); } // // Report errors // $va_errors = $this->request->getActionErrors(); // all errors from all sources $va_general_errors = $this->request->getActionErrors('general'); // just "general" errors - ones that are not attached to a specific part of the form if (sizeof($va_errors) - sizeof($va_general_errors) > 0) { $va_error_list = array(); $vb_no_save_error = false; foreach ($va_errors as $o_e) { $va_error_list[$o_e->getErrorDescription()] = $o_e->getErrorDescription() . "\n"; switch ($o_e->getErrorNumber()) { case 1100: // duplicate/invalid idno if (!$vn_subject_id) { // can't save new record if idno is not valid (when updating everything but idno is saved if it is invalid) $vb_no_save_error = true; } break; } } } else { $this->opo_result_context->invalidateCache(); } $this->opo_result_context->saveContext(); # trigger "SaveItem" hook $this->opo_app_plugin_manager->hookSaveItem(array('id' => $vn_subject_id, 'table_num' => $t_subject->tableNum(), 'table_name' => $t_subject->tableName(), 'instance' => $t_subject, 'is_insert' => true)); $vn_id = $t_subject->getPrimaryKey(); $va_response = array('status' => sizeof($va_error_list) ? 10 : 0, 'id' => $vn_id, 'table' => $t_subject->tableName(), 'type_id' => method_exists($t_subject, "getTypeID") ? $t_subject->getTypeID() : null, 'display' => 'relation', 'bundleDisplay' => $va_bundle_values, 'errors' => $va_error_list); $this->view->setVar('response', $va_response); $this->render('interstitial/interstitial_result_json.php'); }
public function savePlacementsFromHTMLForm($po_request, $ps_form_prefix, $ps_placement_code) { if ($vs_bundles = $po_request->getParameter("{$ps_placement_code}{$ps_form_prefix}displayBundleList", pString)) { $va_bundles = explode(';', $vs_bundles); $t_screen = new ca_editor_ui_screens($this->getPrimaryKey()); $va_placements = $t_screen->getPlacements(array('user_id' => $po_request->getUserID())); // remove deleted bundles foreach ($va_placements as $vn_placement_id => $va_bundle_info) { if (!in_array($va_bundle_info['bundle_name'] . '_' . $va_bundle_info['placement_id'], $va_bundles)) { $t_screen->removePlacement($va_bundle_info['placement_id'], array('user_id' => $po_request->getUserID())); if ($t_screen->numErrors()) { $this->errors = $t_screen->errors; return false; } } } $va_locale_list = ca_locales::getLocaleList(array('index_by_code' => true)); $va_available_bundles = $t_screen->getAvailableBundles(); foreach ($va_bundles as $vn_i => $vs_bundle) { // get settings if (preg_match('!^(.*)_([\\d]+)$!', $vs_bundle, $va_matches)) { $vn_placement_id = (int) $va_matches[2]; $vs_bundle = $va_matches[1]; } else { $vn_placement_id = null; } $vs_bundle_proc = str_replace(".", "_", $vs_bundle); $va_settings = array(); foreach ($_REQUEST as $vs_key => $vs_val) { if (preg_match("!^{$vs_bundle_proc}_([\\d]+)_(.*)\$!", $vs_key, $va_matches)) { // is this locale-specific? if (preg_match('!(.*)_([a-z]{2}_[A-Z]{2})$!', $va_matches[2], $va_locale_matches)) { $vn_locale_id = isset($va_locale_list[$va_locale_matches[2]]) ? (int) $va_locale_list[$va_locale_matches[2]]['locale_id'] : 0; // NOTE: we set keys for both locale_id (which how other placement-using editor like ca_search_forms and // ca_bundle_displays do) *AND* the locale code (eg. "en_US"). This is because the settings created in profile and // in pre v1.1 systems are keyed by code, not locale_id. There's nothing wrong with using code - it's just as unique as the locale_id // and it's convenient to use both interchangeably in any event. // $va_settings[(int) $va_matches[1]][$va_locale_matches[1]][$vn_locale_id] = $va_settings[(int) $va_matches[1]][$va_locale_matches[1]][$va_locale_matches[2]] = $vs_val; } else { $va_settings[(int) $va_matches[1]][$va_matches[2]] = $vs_val; } } } if ($vn_placement_id === 0) { $t_screen->addPlacement($vs_bundle, $vs_bundle . ($vn_i + 1), $va_settings[$vn_placement_id], $vn_i + 1, array('user_id' => $po_request->getUserID(), 'additional_settings' => $va_available_bundles[$vs_bundle]['settings'])); if ($t_screen->numErrors()) { $this->errors = $t_screen->errors; return false; } } else { $t_placement = new ca_editor_ui_bundle_placements($vn_placement_id, $va_available_bundles[$vs_bundle]['settings']); $t_placement->setMode(ACCESS_WRITE); $t_placement->set('rank', $vn_i + 1); if (is_array($va_settings[$vn_placement_id])) { foreach ($t_placement->getAvailableSettings() as $vs_setting => $va_setting_info) { $vs_val = isset($va_settings[$vn_placement_id][$vs_setting]) ? $va_settings[$vn_placement_id][$vs_setting] : null; $t_placement->setSetting($vs_setting, $vs_val); } } $t_placement->update(); if ($t_placement->numErrors()) { $this->errors = $t_placement->errors; return false; } } } } return true; }
/** * Returns a list of ui id, screen id and placement id for a given setting key (editor_code/screen_idno/placement_code) * @param string $ps_key * @return array|bool */ public static function resolveHideIfSelectedKey($ps_key) { if (CompositeCache::contains($ps_key, 'ListAttrHideIfSelected')) { return CompositeCache::fetch($ps_key, 'ListAttrHideIfSelected'); } $va_tmp = explode('/', $ps_key); if (!sizeof($va_tmp) == 3) { return false; } // ui $t_ui = new ca_editor_uis(); if (!$t_ui->load(array('editor_code' => $va_tmp[0]))) { return false; } // screen $t_screen = new ca_editor_ui_screens(); if (!$t_screen->load(array('ui_id' => $t_ui->getPrimaryKey(), 'idno' => $va_tmp[1]))) { return false; } // placement $t_placement = new ca_editor_ui_bundle_placements(); if (!$t_placement->load(array('screen_id' => $t_screen->getPrimaryKey(), 'placement_code' => $va_tmp[2]))) { return false; } $va_ret = array($t_screen->getPrimaryKey(), $t_placement->getPrimaryKey()); CompositeCache::save($ps_key, $va_ret, 'ListAttrHideIfSelected'); return $va_ret; }
/** * */ public function loadBundles() { list($vn_subject_id, $t_subject) = $this->_initView(); if (!$this->_checkAccess($t_subject)) { return false; } $ps_bundle_name = $this->request->getParameter("bundle", pString); $pn_placement_id = $this->request->getParameter("placement_id", pInteger); $pn_start = (int) $this->request->getParameter("start", pInteger); if (!($pn_limit = $this->request->getParameter("limit", pInteger))) { $pn_limit = null; } $t_placement = new ca_editor_ui_bundle_placements($pn_placement_id); $this->response->addContent(json_encode($t_subject->getBundleFormValues($ps_bundle_name, "{$pn_placement_id}", $t_placement->get('settings'), array('start' => $pn_start, 'limit' => $pn_limit, 'request' => $this->request, 'contentOnly' => true)))); }
/** * Returns content for a bundle or the inspector. Used to dynamically and selectively * reload an editing form. */ public function reload() { list($vn_subject_id, $t_subject) = $this->_initView(); if (!$this->_checkAccess($t_subject)) { return false; } $ps_bundle = $this->request->getParameter("bundle", pString); $pn_placement_id = $this->request->getParameter("placement_id", pInteger); switch ($ps_bundle) { case '__inspector__': $this->response->addContent($this->info(array($t_subject->primaryKey() => $vn_subject_id, 'type_id' => $this->request->getParameter("type_id", pInteger)))); break; default: $t_placement = new ca_editor_ui_bundle_placements($pn_placement_id); if (!$t_placement->getPrimaryKey()) { $this->response->setRedirect($this->request->config->get('error_display_url') . '/n/2580?r=' . urlencode($this->request->getFullUrlPath())); return; } if ($t_placement->get('bundle_name') != $ps_bundle) { $this->response->setRedirect($this->request->config->get('error_display_url') . '/n/2580?r=' . urlencode($this->request->getFullUrlPath())); return; } $this->response->addContent($t_subject->getBundleFormHTML($ps_bundle, $pn_placement_id, $t_placement->get('settings'), array('request' => $this->request, 'contentOnly' => true), $vs_label)); break; } }