/** * This should be called when the bean is saved. The bean itself will be passed by reference * @param SugarBean bean - the bean performing the save * @param array params - an array of paramester relevant to the save, most likely will be $_REQUEST */ public function save(&$bean, $params, $field, $properties, $prefix = '') { if (isset($_POST["primary_" . $field . "_collection"])) { $save = false; $value_name = $field . "_values"; $link_field = array(); // populate $link_field from POST foreach ($_POST as $name => $value) { if (strpos($name, $field . "_collection_") !== false) { $num = substr($name, -1); if (is_numeric($num)) { settype($num, 'int'); if (strpos($name, $field . "_collection_extra_") !== false) { $extra_field = substr($name, $field . "_collection_extra_" . $num); $link_field[$num]['extra_field'][$extra_field] = $value; } else { if ($name == $field . "_collection_" . $num) { $link_field[$num]['name'] = $value; } else { if ($name == "id_" . $field . "_collection_" . $num) { $link_field[$num]['id'] = $value; } } } } } } // Set Primary if (isset($_POST["primary_" . $field . "_collection"])) { $primary = $_POST["primary_" . $field . "_collection"]; settype($primary, 'int'); $link_field[$primary]['primary'] = true; } // Create or update record and take care of the extra_field require_once 'data/Link.php'; $class = load_link_class($bean->field_defs[$field]); $link_obj = new $class($bean->field_defs[$field]['relationship'], $bean, $bean->field_defs[$field]); $module = $link_obj->getRelatedModuleName(); foreach ($link_field as $k => $v) { $save = false; $update_fields = array(); $obj = BeanFactory::getBean($module); if (!isset($link_field[$k]['name']) || empty($link_field[$k]['name'])) { // There is no name so it is an empty record -> ignore it! unset($link_field[$k]); break; } if (!isset($link_field[$k]['id']) || empty($link_field[$k]['id']) || isset($_POST[$field . "_new_on_update"]) && $_POST[$field . "_new_on_update"] === 'true') { // Create a new record if (isset($_POST[$field . "_allow_new"]) && ($_POST[$field . "_allow_new"] === 'false' || $_POST[$field . "_allow_new"] === false)) { // Not allow to create a new record so remove from $link_field unset($link_field[$k]); break; } if (!isset($link_field[$k]['id']) || empty($link_field[$k]['id'])) { // There is no ID so it is a new record $save = true; $obj->name = $link_field[$k]['name']; } else { // We duplicate an existing record because new_on_update is set $obj->retrieve($link_field[$k]['id']); $obj->id = ''; $obj->name = $obj->name . '_DUP'; } } else { // id exist so retrieve the data $obj->retrieve($link_field[$k]['id']); } // Update the extra field for the new or the existing record if (isset($v['extra_field']) && is_array($v['extra_field'])) { // Retrieve the changed fields if (isset($_POST["update_fields_{$field}_collection"]) && !empty($_POST["update_fields_{$field}_collection"])) { $JSON = getJSONobj(); $update_fields = $JSON->decode(html_entity_decode($_POST["update_fields_{$field}_collection"])); } // Update the changed fields foreach ($update_fields as $kk => $vv) { if (!isset($_POST[$field . "_allow_update"]) || $_POST[$field . "_allow_update"] !== 'false' && $_POST[$field . "_allow_update"] !== false) { //allow to update the extra_field in the record if (isset($v['extra_field'][$kk]) && $vv == true) { $extra_field_name = str_replace("_" . $field . "_collection_extra_" . $k, "", $kk); if ($obj->{$extra_field_name} != $v['extra_field'][$kk]) { $save = true; $obj->{$extra_field_name} = $v['extra_field'][$kk]; } } } } } // Save the new or updated record if ($save) { if (!$obj->ACLAccess('save')) { ACLController::displayNoAccess(true); sugar_cleanup(true); } $obj->save(); $link_field[$k]['id'] = $obj->id; } } // Save new relationship or delete deleted relationship if (!empty($link_field)) { if ($bean->load_relationship($field)) { $oldvalues = $bean->{$field}->get(true); $role_field = $bean->{$field}->_get_link_table_role_field($bean->{$field}->_relationship_name); foreach ($link_field as $new_v) { if (!empty($new_v['id'])) { if (!empty($role_field)) { if (isset($new_v['primary']) && $new_v['primary']) { $bean->{$field}->add($new_v['id'], array($role_field => 'primary')); } else { $bean->{$field}->add($new_v['id'], array($role_field => 'NULL')); } } else { $bean->{$field}->add($new_v['id'], array()); } } } foreach ($oldvalues as $old_v) { $match = false; foreach ($link_field as $new_v) { if ($new_v['id'] == $old_v['id']) { $match = true; } } if (!$match) { $bean->{$field}->delete($bean->id, $old_v['id']); } } } } } }
/** * Loads all attributes of type link. * * Method searches the implmenting module's vardef file for attributes of type link, and for each attribute * create a similary named variable and load the relationship definition. * * @return Nothing * * Internal function, do not override. */ function load_relationships() { $GLOBALS['log']->debug("SugarBean.load_relationships, Loading all relationships of type link."); $linked_fields = $this->get_linked_fields(); require_once "data/Link.php"; foreach ($linked_fields as $name => $properties) { $class = load_link_class($properties); $this->{$name} = new $class($properties['relationship'], $this, $properties); } }
/** * Loads the request relationship. This method should be called before performing any operations on the related data. * * This method searches the vardef array for the requested attribute's definition. If the attribute is of the type * link then it creates a similary named variable and loads the relationship definition. * * @param string $rel_name relationship/attribute name. * @return nothing. */ function load_relationship($rel_name) { $GLOBALS['log']->debug("SugarBean[{$this->object_name}].load_relationships, Loading relationship (" . $rel_name . ")."); if (empty($rel_name)) { $GLOBALS['log']->error("SugarBean.load_relationships, Null relationship name passed."); return false; } $fieldDefs = $this->getFieldDefinitions(); //find all definitions of type link. if (!empty($fieldDefs[$rel_name])) { //initialize a variable of type Link require_once 'data/Link2.php'; $class = load_link_class($fieldDefs[$rel_name]); if (isset($this->{$rel_name}) && $this->{$rel_name} instanceof $class) { return true; } //if rel_name is provided, search the fieldef array keys by name. if (isset($fieldDefs[$rel_name]['type']) && $fieldDefs[$rel_name]['type'] == 'link') { if ($class == "Link2") { $this->{$rel_name} = new $class($rel_name, $this); } else { $this->{$rel_name} = new $class($fieldDefs[$rel_name]['relationship'], $this, $fieldDefs[$rel_name]); } if (empty($this->{$rel_name}) || method_exists($this->{$rel_name}, "loadedSuccesfully") && !$this->{$rel_name}->loadedSuccesfully()) { unset($this->{$rel_name}); return false; } // keep track of the loaded relationships $this->loaded_relationships[] = $rel_name; return true; } } $GLOBALS['log']->debug("SugarBean.load_relationships, Error Loading relationship (" . $rel_name . ")"); return false; }
/** * @param array $field * * @return string */ protected function getType($field) { $type = array_get($field, 'type', 'string'); switch ($type) { case 'bool': return 'bool'; case 'link': return load_link_class($field); case 'relate': return $this->getBeanByModule(array_get($field, 'module', 'SugarBean')); } return 'string'; }
/** * @param array $layoutDefs * @param SugarBean $bean * @return array legacy LayoutDef */ public function toLegacySubpanelLayoutDefs(array $layoutDefs, SugarBean $bean) { $return = array(); foreach ($layoutDefs as $order => $def) { // no link can't move on if (empty($def['context']['link'])) { continue; } // In most cases we can safely expect a Link2 object. But in cases // where a vardef defines it's own link_class and link_file, we need // to honor that. For example, archived_emails in Accounts. $linkClass = 'Link2'; $linkName = $def['context']['link']; if (isset($bean->field_defs[$linkName])) { $linkClass = load_link_class($bean->field_defs[$linkName]); } $link = new $linkClass($linkName, $bean); $linkModule = $link->getRelatedModuleName(); $legacySubpanelName = $this->toLegacySubpanelName($def); // if we don't have a label at least set the module name as the label // similar to configure shortcut bar $label = isset($def['label']) ? $def['label'] : translate($linkModule); $return[$linkName] = array('order' => $order, 'module' => $linkModule, 'subpanel_name' => $legacySubpanelName, 'sort_order' => 'asc', 'sort_by' => 'id', 'title_key' => $label, 'get_subpanel_data' => $linkName, 'top_buttons' => array(array('widget_class' => 'SubPanelTopButtonQuickCreate'), array('widget_class' => 'SubPanelTopSelectButton', 'mode' => 'MultiSelect'))); if (!empty($def['override_subpanel_list_view'])) { $return[$linkName]['override_subpanel_name'] = $def['override_subpanel_list_view']; } } return array('subpanel_setup' => $return); }
function getModules(&$report_def) { $modules = array(); $modules_hash[$report_def['module']] = 1; $focus = BeanFactory::getBean($report_def['module']); $linked_fields = $focus->get_linked_fields(); foreach ($report_def['links_def'] as $name) { $properties = $linked_fields[$name]; $class = load_link_class($properties); $link = new $class($properties['relationship'], $focus, $properties); $module = $link->getRelatedModuleName(); $modules_hash[$module] = 1; } $modules = array_keys($modules_hash); return $modules; }