/** * Determines if a portal user "owns" a record * @param SugarBean $bean */ protected function isPortalOwner(SugarBean $bean) { if (empty($bean->id) || $bean->new_with_id) { // New record, they are the owner. $bean->portal_owner = true; } // Cache portal owner on bean so that we aren't loading Contacts for each ACL check // Performance Bug58133 if (!isset($bean->portal_owner)) { switch ($bean->module_dir) { case 'Contacts': $bean->portal_owner = $bean->id == $_SESSION['contact_id']; break; // Cases & Bugs work the same way, so handily enough we can share the code. // Cases & Bugs work the same way, so handily enough we can share the code. case 'Cases': case 'Bugs': $bean->load_relationship('contacts'); $rows = $bean->contacts->query(array('where' => array('lhs_field' => 'id', 'operator' => '=', 'rhs_value' => $GLOBALS['db']->quote($_SESSION['contact_id'])))); $bean->portal_owner = count($rows) > 0; break; default: // Unless we know how to find the "owner", they can't own it. $bean->portal_owner = false; } } return $bean->portal_owner; }
/** * Create merge query depending on the modules being merged * @param SugarBean $seed Object being queried * @param string $merge_module Module being merged * @param string $key ID of the record in module being merged */ function get_merge_query($seed, $merge_module, $key) { $selQuery = array('Contacts' => array('Accounts' => 'SELECT contacts.first_name, contacts.last_name, contacts.id, contacts.date_entered FROM contacts LEFT JOIN accounts_contacts ON contacts.id=accounts_contacts.contact_id AND (accounts_contacts.deleted is NULL or accounts_contacts.deleted=0)', 'Opportunities' => 'SELECT contacts.first_name, contacts.last_name, contacts.id, contacts.date_entered FROM contacts LEFT JOIN opportunities_contacts ON contacts.id=opportunities_contacts.contact_id AND (opportunities_contacts.deleted is NULL or opportunities_contacts.deleted=0)', 'Cases' => 'SELECT contacts.first_name, contacts.last_name, contacts.id, contacts.date_entered FROM contacts LEFT JOIN contacts_cases ON contacts.id=contacts_cases.contact_id AND (contacts_cases.deleted is NULL or contacts_cases.deleted=0)', 'Bugs' => 'SELECT contacts.first_name, contacts.last_name, contacts.id, contacts.date_entered FROM contacts LEFT JOIN contacts_bugs ON contacts.id=contacts_bugs.contact_id AND (contacts_bugs.deleted is NULL or contacts_bugs.deleted=0)', 'Quotes' => 'SELECT contacts.first_name, contacts.last_name, contacts.id, contacts.date_entered FROM contacts LEFT JOIN quotes_contacts ON contacts.id=quotes_contacts.contact_id AND (quotes_contacts.deleted is NULL or quotes_contacts.deleted=0)'), 'Opportunities' => array("Accounts" => 'SELECT opportunities.id, opportunities.name FROM opportunities LEFT JOIN accounts_opportunities ON opportunities.id = accounts_opportunities.opportunity_id AND (accounts_opportunities.deleted is NULL or accounts_opportunities.deleted=0)'), 'Accounts' => array("Opportunities" => 'SELECT accounts.id, accounts.name FROM accounts LEFT JOIN accounts_opportunities ON accounts.id = accounts_opportunities.account_id AND (accounts_opportunities.deleted is NULL or accounts_opportunities.deleted=0)')); $whereQuery = array('Contacts' => array('Accounts' => 'accounts_contacts.contact_id = contacts.id AND accounts_contacts.account_id = ', 'Opportunities' => 'opportunities_contacts.contact_id = contacts.id AND opportunities_contacts.opportunity_id = ', 'Cases' => 'contacts_cases.contact_id = contacts.id AND contacts_cases.case_id = ', 'Bugs' => 'contacts_bugs.contact_id = contacts.id AND contacts_bugs.bug_id = ', 'Quotes' => 'quotes_contacts.contact_id = contacts.id AND quotes_contacts.quote_id = '), 'Opportunities' => array('Accounts' => 'accounts_opportunities.opportunity_id = opportunities.id AND accounts_opportunities.account_id = '), 'Accounts' => array('Opportunities' => 'accounts_opportunities.account_id = accounts.id AND accounts_opportunities.opportunity_id = ')); $relModule = $seed->module_dir; $select = ""; if (!empty($selQuery[$relModule][$merge_module])) { $select = $selQuery[$relModule][$merge_module]; } else { $lowerRelModule = strtolower($relModule); if ($seed->load_relationship($lowerRelModule)) { $params = array('join_table_alias' => 'r1', 'join_table_link_alias' => 'r2', 'join_type' => 'LEFT JOIN'); $join = $seed->{$lowerRelModule}->getJoin($params); $select = "SELECT {$seed->table_name}.* FROM {$seed->table_name} {$join}"; } } if (empty($select)) { $select = "SELECT contacts.first_name, contacts.last_name, contacts.id, contacts.date_entered FROM contacts"; } if (empty($whereQuery[$relModule][$merge_module])) { $select .= " WHERE {$seed->table_name}.id = '{$seed->db->quote($key)}'"; } else { $select .= " WHERE " . $whereQuery[$relModule][$merge_module] . "'{$seed->db->quote($key)}'"; } $select .= " ORDER BY {$seed->table_name}.date_entered"; return $select; }
/** * @param SugarBean $lhs SugarBean left side bean to add to the relationship. * @param SugarBean $rhs SugarBean right side bean to add to the relationship. * @param array $additionalFields key=>value pairs of fields to save on the relationship * * @return bool true if successful */ public function add($lhs, $rhs, $additionalFields = []) { $lhsLinkName = $this->lhsLink; //In a one to one, any existing links from both sides must be removed first. //one2Many will take care of the right side, so we'll do the left. $lhs->load_relationship($lhsLinkName); $this->removeAll($lhs->{$lhsLinkName}); return parent::add($lhs, $rhs, $additionalFields); }
/** * Gets related module name from a rel link * @param SugarBean $focus * @return string */ protected function getRelatedModuleName($focus) { $relate_to = null; if (!empty($_REQUEST['relate_to'])) { $rel_link = $_REQUEST['relate_to']; if (!$focus->load_relationship($rel_link)) { //Try to find the link in this bean based on the relationship foreach ($focus->field_defs as $key => $def) { if (isset($def['type']) && $def['type'] == 'link' && isset($def['relationship']) && $def['relationship'] == $rel_link) { $rel_link = $key; if ($focus->load_relationship($rel_link)) { break; } } } } if ($focus->{$rel_link}) { $relate_to = $focus->{$rel_link}->getRelatedModuleName(); } } return $relate_to; }
/** * This function is used to popluate an fields on the relationship from the request * * @param $api ServiceBase The API class of the request, used in cases where the API changes how security is applied * @param $args array The arguments array passed in from the API * @param $primaryBean SugarBean The near side of the link * @param $linkName string What is the name of the link field that you want to get the related fields for * * @return array A list of the related fields pulled out of the $args array */ protected function getRelatedFields(ServiceBase $api, $args, SugarBean $primaryBean, $linkName, $seed = null) { $relatedData = array(); if (!empty($primaryBean->{$linkName}) || $primaryBean->load_relationship($linkName)) { $otherLink = $primaryBean->{$linkName}->getLinkForOtherSide(); if ($seed instanceof SugarBean) { foreach ($args as $field => $value) { if (empty($seed->field_defs[$field]['rname_link']) || empty($seed->field_defs[$field]['link']) || $seed->field_defs[$field]['link'] != $otherLink) { continue; } $relatedData[$seed->field_defs[$field]['rname_link']] = $value; } } } return $relatedData; }
protected function getLinkField($fieldName) { if ((empty($this->context->{$fieldName}) || !is_a($this->context->{$fieldName}, "Link2")) && !$this->context->load_relationship($fieldName)) { throw new Exception("Unable to load relationship {$fieldName}"); } if (empty($this->context->{$fieldName})) { throw new Exception("Relationship {$fieldName} was not set"); } if (SugarBean::inOperation('delete')) { // if we are in a delete operation, always re-fetch the relationships beans // as one of the could have changed and we want the freshest set from the db $this->context->{$fieldName}->beans = null; $this->context->{$fieldName}->resetLoaded(); } elseif (isset($this->context->{$fieldName}->beans)) { return $this->context->{$fieldName}->beans; } $beans = $this->context->{$fieldName}->getBeans(); return $beans; }
function set_relationships(SugarBean $record, SugarBean $bean, $params = array()) { $record_vardefs = $record->getFieldDefinitions(); require_once 'modules/Relationships/Relationship.php'; if (isset($params['rel'])) { foreach ($params['rel'] as $key => $field) { if ($field == '' || $params['rel_value'][$key] == '') { continue; } switch ($params['rel_value_type'][$key]) { case 'Field': $data = $bean->field_defs[$params['rel_value'][$key]]; if ($data['type'] == 'relate' && isset($data['id_name'])) { $params['rel_value'][$key] = $data['id_name']; } $rel_id = $bean->{$params}['rel_value'][$key]; break; default: $rel_id = $params['rel_value'][$key]; break; } $def = $record_vardefs[$field]; if ($def['type'] == 'link' && !empty($def['relationship'])) { $record->load_relationship($field); $record->{$field}->add($rel_id); } } } }
/** * Helper for processing record activities. * @param SugarBean $bean */ public function processRecord(SugarBean $bean) { if ($bean->load_relationship('activities')) { $bean->activities->add($this); } }
/** * Executes logic specific for the field being updated * * @param string $field_name * @param SugarBean $source_object */ function execute_special_logic($field_name, SugarBean $source_object) { if ($field_name === 'team_id') { // when Team ID is updated, remove all previously associated teams if ($source_object->load_relationship('teams')) { $source_object->teams->replace(array(), array(), false); } $source_object->team_set_id = null; } if (SugarAutoLoader::requireWithCustom('modules/' . $source_object->module_dir . '/SaveOverload.php')) { perform_save($source_object); } }
private function getEmailsFromParams(SugarBean $bean, $params) { $emails = array(); //backward compatible if (isset($params['email_target_type']) && !is_array($params['email_target_type'])) { $email = ''; switch ($params['email_target_type']) { case 'Email Address': $params['email'] = array($params['email']); break; case 'Specify User': $params['email'] = array($params['email_user_id']); break; case 'Related Field': $params['email'] = array($params['email_target']); break; } $params['email_target_type'] = array($params['email_target_type']); $params['email_to_type'] = array('to'); } //end backward compatible if (isset($params['email_target_type'])) { foreach ($params['email_target_type'] as $key => $field) { switch ($field) { case 'Email Address': if (trim($params['email'][$key]) != '') { $emails[$params['email_to_type'][$key]][] = $params['email'][$key]; } break; case 'Specify User': $user = new User(); $user->retrieve($params['email'][$key]); $user_email = $user->emailAddress->getPrimaryAddress($user); if (trim($user_email) != '') { $emails[$params['email_to_type'][$key]][] = $user_email; $emails['template_override'][$user_email] = array('Users' => $user->id); } break; case 'Users': $users = array(); switch ($params['email'][$key][0]) { case 'security_group': if (file_exists('modules/SecurityGroups/SecurityGroup.php')) { require_once 'modules/SecurityGroups/SecurityGroup.php'; $security_group = new SecurityGroup(); $security_group->retrieve($params['email'][$key][1]); $users = $security_group->get_linked_beans('users', 'User'); $r_users = array(); if ($params['email'][$key][2] != '') { require_once 'modules/ACLRoles/ACLRole.php'; $role = new ACLRole(); $role->retrieve($params['email'][$key][2]); $role_users = $role->get_linked_beans('users', 'User'); foreach ($role_users as $role_user) { $r_users[$role_user->id] = $role_user->name; } } foreach ($users as $user_id => $user) { if ($params['email'][$key][2] != '' && !isset($r_users[$user->id])) { unset($users[$user_id]); } } break; } //No Security Group module found - fall through. //No Security Group module found - fall through. case 'role': require_once 'modules/ACLRoles/ACLRole.php'; $role = new ACLRole(); $role->retrieve($params['email'][$key][2]); $users = $role->get_linked_beans('users', 'User'); break; case 'all': default: global $db; $sql = "SELECT id from users WHERE status='Active' AND portal_only=0 "; $result = $db->query($sql); while ($row = $db->fetchByAssoc($result)) { $user = new User(); $user->retrieve($row['id']); $users[$user->id] = $user; } break; } foreach ($users as $user) { $user_email = $user->emailAddress->getPrimaryAddress($user); if (trim($user_email) != '') { $emails[$params['email_to_type'][$key]][] = $user_email; $emails['template_override'][$user_email] = array('Users' => $user->id); } } break; case 'Related Field': $emailTarget = $params['email'][$key]; $relatedFields = array_merge($bean->get_related_fields(), $bean->get_linked_fields()); $field = $relatedFields[$emailTarget]; if ($field['type'] == 'relate') { $linkedBeans = array(); $idName = $field['id_name']; $id = $bean->{$idName}; $linkedBeans[] = BeanFactory::getBean($field['module'], $id); } else { if ($field['type'] == 'link') { $relField = $field['name']; if (isset($field['module']) && $field['module'] != '') { $rel_module = $field['module']; } else { if ($bean->load_relationship($relField)) { $rel_module = $bean->{$relField}->getRelatedModuleName(); } } $linkedBeans = $bean->get_linked_beans($relField, $rel_module); } else { $linkedBeans = $bean->get_linked_beans($field['link'], $field['module']); } } if ($linkedBeans) { foreach ($linkedBeans as $linkedBean) { $rel_email = $linkedBean->emailAddress->getPrimaryAddress($linkedBean); if (trim($rel_email) != '') { $emails[$params['email_to_type'][$key]][] = $rel_email; $emails['template_override'][$rel_email] = array($linkedBean->module_dir => $linkedBean->id); } } } break; case 'Record Email': $recordEmail = $bean->emailAddress->getPrimaryAddress($bean); if ($recordEmail == '' && isset($bean->email1)) { $recordEmail = $bean->email1; } if (trim($recordEmail) != '') { $emails[$params['email_to_type'][$key]][] = $recordEmail; } break; } } } return $emails; }
function build_report_query_join($name, SugarBean $module, $type, $query = array()) { if (!isset($query['join'][$name])) { switch ($type) { case 'custom': $query['join'][$name] = 'LEFT JOIN ' . $module->get_custom_table_name() . ' ' . $name . ' ON ' . $module->table_name . '.id = ' . $name . '.id_c '; break; case 'relationship': if ($module->load_relationship($name)) { $params['join_type'] = 'LEFT JOIN'; $params['join_table_alias'] = $name; $join = $module->{$name}->getJoin($params, true); $query['join'][$name] = $join['join']; $query['select'][] = $join['select'] . " AS '" . $name . "_id'"; } break; default: break; } } return $query; }
/** * @param array $subpanel_list * @param array $subpanel_def * @param SugarBean $parentbean * @param string $order_by * * @return array */ protected static function build_sub_queries_for_union($subpanel_list, $subpanel_def, $parentbean, $order_by) { global $layout_edit_mode, $beanFiles, $beanList; $subqueries = []; foreach ($subpanel_list as $this_subpanel) { if (!$this_subpanel->isDatasourceFunction() || $this_subpanel->isDatasourceFunction() && isset($this_subpanel->_instance_properties['generate_select']) && $this_subpanel->_instance_properties['generate_select'] == true) { //the custom query function must return an array with if ($this_subpanel->isDatasourceFunction()) { $shortcut_function_name = $this_subpanel->get_data_source_name(); $parameters = $this_subpanel->get_function_parameters(); if (!empty($parameters)) { //if the import file function is set, then import the file to call the custom function from if (is_array($parameters) && isset($parameters['import_function_file'])) { //this call may happen multiple times, so only require if function does not exist if (!function_exists($shortcut_function_name)) { require_once $parameters['import_function_file']; } //call function from required file $query_array = $shortcut_function_name($parameters); } else { //call function from parent bean $query_array = $parentbean->{$shortcut_function_name}($parameters); } } else { $query_array = $parentbean->{$shortcut_function_name}(); } } else { $related_field_name = $this_subpanel->get_data_source_name(); if (!$parentbean->load_relationship($related_field_name)) { unset($parentbean->{$related_field_name}); continue; } $query_array = $parentbean->{$related_field_name}->getSubpanelQuery([], true); } $table_where = preg_replace('/^\\s*WHERE/i', '', $this_subpanel->get_where()); $where_definition = preg_replace('/^\\s*WHERE/i', '', $query_array['where']); if (!empty($table_where)) { if (empty($where_definition)) { $where_definition = $table_where; } else { $where_definition .= ' AND ' . $table_where; } } $submodulename = $this_subpanel->_instance_properties['module']; $submoduleclass = $beanList[$submodulename]; //require_once($beanFiles[$submoduleclass]); /** @var SugarBean $submodule */ $submodule = new $submoduleclass(); $subwhere = $where_definition; $list_fields = $this_subpanel->get_list_fields(); foreach ($list_fields as $list_key => $list_field) { if (isset($list_field['usage']) && $list_field['usage'] == 'display_only') { unset($list_fields[$list_key]); } } if (!$subpanel_def->isCollection() && isset($list_fields[$order_by]) && isset($submodule->field_defs[$order_by]) && (!isset($submodule->field_defs[$order_by]['source']) || $submodule->field_defs[$order_by]['source'] == 'db')) { $order_by = $submodule->table_name . '.' . $order_by; } $table_name = $this_subpanel->table_name; $panel_name = $this_subpanel->name; $params = []; $params['distinct'] = $this_subpanel->distinct_query(); $params['joined_tables'] = $query_array['join_tables']; $params['include_custom_fields'] = !$subpanel_def->isCollection(); $params['collection_list'] = $subpanel_def->get_inst_prop_value('collection_list'); // use single select in case when sorting by relate field $singleSelect = $submodule->is_relate_field($order_by); $subquery = $submodule->create_new_list_query('', $subwhere, $list_fields, $params, 0, '', true, $parentbean, $singleSelect); $subquery['select'] = $subquery['select'] . " , '{$panel_name}' panel_name "; $subquery['from'] = $subquery['from'] . $query_array['join']; $subquery['query_array'] = $query_array; $subquery['params'] = $params; $subqueries[] = $subquery; } } return $subqueries; }
/** * Assign user's private team to an email * @param SugarBean $email Email object * @param string $userid User ID */ static function assignUserTeam($email, $userid) { if (empty($userid)) { return null; } $teamid = User::staticGetPrivateTeamID($userid); if (empty($teamid)) { return null; } if (empty($email->teams)) { $email->load_relationship('teams'); } $GLOBALS['log']->debug("Assigning {$email->id} to user {$userid} team {$teamid}"); $email->teams->add($teamid, array(), false); return $teamid; }
/** * @param SugarBean $parentBean * @param array $repeatDateTimeArray * @return array events saved */ protected function saveRecurring(SugarBean $parentBean, array $repeatDateTimeArray) { // Load the user relationship so the child events that are created will // have the users added via bean->save (which has special auto-accept // logic) if ($parentBean->load_relationship('users')) { $parentBean->users_arr = $parentBean->users->get(); } return CalendarUtils::saveRecurring($parentBean, $repeatDateTimeArray); }
/** * Process all after create operations: * copy_rel_from - Copies relationships from a specified record. The relationship that should be copied is specified * in the vardef. * * @param $args * @param SugarBean $bean */ protected function processAfterCreateOperations($args, SugarBean $bean) { $this->requireArgs($args, array('module')); global $dictionary; $afterCreateKey = 'after_create'; $copyRelationshipsFromKey = 'copy_rel_from'; $module = $args['module']; $objectName = BeanFactory::getObjectName($module); if (array_key_exists($afterCreateKey, $args) && array_key_exists($copyRelationshipsFromKey, $args[$afterCreateKey]) && array_key_exists($afterCreateKey, $dictionary[$objectName]) && array_key_exists($copyRelationshipsFromKey, $dictionary[$objectName][$afterCreateKey])) { $relationshipsToCopy = $dictionary[$objectName][$afterCreateKey][$copyRelationshipsFromKey]; $beanCopiedFrom = BeanFactory::getBean($module, $args[$afterCreateKey][$copyRelationshipsFromKey]); foreach ($relationshipsToCopy as $linkName) { $bean->load_relationship($linkName); $beanCopiedFrom->load_relationship($linkName); $beanCopiedFrom->{$linkName}->getBeans(); $bean->{$linkName}->add($beanCopiedFrom->{$linkName}->beans); } } }
function build_report_query_join($name, $alias, $parentAlias, SugarBean $module, $type, $query = array(), SugarBean $rel_module = null) { if (!isset($query['join'][$alias])) { switch ($type) { case 'custom': $query['join'][$alias] = 'LEFT JOIN ' . $this->db->quoteIdentifier($module->get_custom_table_name()) . ' ' . $this->db->quoteIdentifier($name) . ' ON ' . $module->table_name . '.id = ' . $this->db->quoteIdentifier($name) . '.id_c '; break; case 'relationship': if ($module->load_relationship($name)) { $params['join_type'] = 'LEFT JOIN'; if ($module->{$name}->relationship_type != 'one-to-many') { if ($module->{$name}->getSide() == REL_LHS) { $params['right_join_table_alias'] = $this->db->quoteIdentifier($alias); $params['join_table_alias'] = $this->db->quoteIdentifier($alias); $params['left_join_table_alias'] = $this->db->quoteIdentifier($parentAlias); } else { $params['right_join_table_alias'] = $this->db->quoteIdentifier($parentAlias); $params['join_table_alias'] = $this->db->quoteIdentifier($alias); $params['left_join_table_alias'] = $this->db->quoteIdentifier($alias); } } else { $params['right_join_table_alias'] = $this->db->quoteIdentifier($parentAlias); $params['join_table_alias'] = $this->db->quoteIdentifier($alias); $params['left_join_table_alias'] = $this->db->quoteIdentifier($parentAlias); } $linkAlias = $parentAlias . "|" . $alias; $params['join_table_link_alias'] = $this->db->quoteIdentifier($linkAlias); $join = $module->{$name}->getJoin($params, true); $query['join'][$alias] = $join['join']; if ($rel_module != null) { $query['join'][$alias] .= $this->build_report_access_query($rel_module, $name); } $query['select'][] = $join['select'] . " AS '" . $alias . "_id'"; } break; default: break; } } return $query; }
/** * Returns an array of IDs for records associated via the specified link. * * @param SugarBean $bean * @param string $link The name of the link from which to load related records. * @param array $submittedData The submitted data for this request * @return array */ protected function getInvitees(SugarBean $bean, $link, $submittedData) { $invites = array(); if ($bean->load_relationship($link)) { $invites = $bean->{$link}->get(); } if (isset($submittedData[$link]['add'])) { foreach ($submittedData[$link]['add'] as $id) { if (is_array($id)) { $id = $id['id']; } $invites[] = $id; } } if (isset($submittedData[$link]['delete'])) { foreach ($submittedData[$link]['delete'] as $id) { if (is_array($id)) { $id = $id['id']; } $idx = array_search($id, $invites); array_splice($invites, $idx, 1); } } return $invites; }
/** * This function handles turning the API's version of a teamset into what we actually store * @param SugarBean $bean - the bean performing the save * @param array $params - an array of paramester relevant to the save, which will be an array passed up to the API * @param string $fieldName - The name of the field to save (the vardef name, not the form element name) * @param array $properties - Any properties for this field */ public function apiSave(SugarBean $bean, array $params, $fieldName, $properties) { // Find the primary team id, or the first one, if nothing is set to primary $teamList = $params[$fieldName]; $ret = $this->fixupTeamList($teamList); $teamIds = $ret['teamIds']; $primaryTeamId = $ret['primaryTeamId']; if (count($teamIds) == 0) { // There are no teams being set, set the defaults and move on $bean->setDefaultTeam(); return; } if (empty($primaryTeamId)) { // They didn't specify a primary team, so I'm just going to set it to the first one $primaryTeamId = $teamIds[0]; } $bean->team_id = $primaryTeamId; if ($bean->load_relationship('teams')) { $bean->teams->replace($teamIds, array(), false); } }
/** * @param SugarBean $lhs * @param SugarBean $rhs * * @return bool */ public function remove($lhs, $rhs) { $lhsLinkName = $this->lhsLink; if (!$lhs instanceof SugarBean) { Log::fatal("LHS is not a SugarBean object"); return false; } if (!$rhs instanceof SugarBean) { Log::fatal("RHS is not a SugarBean object"); return false; } if (empty($lhs->{$lhsLinkName}) && !$lhs->load_relationship($lhsLinkName)) { Log::fatal("could not load LHS {$lhsLinkName}"); return false; } if (empty($_SESSION['disable_workflow']) || $_SESSION['disable_workflow'] != "Yes") { if (!empty($lhs->{$lhsLinkName})) { $lhs->{$lhsLinkName}->load(); $this->callBeforeDelete($lhs, $rhs, $lhsLinkName); } } $dataToRemove = [$this->def['join_key_lhs'] => $lhs->id, $this->def['join_key_rhs'] => $rhs->id]; $this->removeRow($dataToRemove); if ($this->self_referencing) { $this->removeSelfReferencing($lhs, $rhs); } if (empty($_SESSION['disable_workflow']) || $_SESSION['disable_workflow'] != "Yes") { if (!empty($lhs->{$lhsLinkName})) { $lhs->{$lhsLinkName}->load(); $this->callAfterDelete($lhs, $rhs, $lhsLinkName); } } return true; }
/** * Add a join based on a link from the target bean * * @param SugarBean $bean * @param string $link_name * @param array $options * * @return SugarQuery */ public function joinSubpanel($bean, $link_name, $options = array()) { //Force a unique join table alias for self referencing relationships and multiple joins against the same table $alias = !empty($options['joinTableAlias']) ? $options['joinTableAlias'] : $this->getJoinTableAlias($link_name); $joinType = !empty($options['joinType']) ? $options['joinType'] : 'INNER'; $ignoreRole = !empty($options['ignoreRole']) ? $options['ignoreRole'] : false; if (!$bean->load_relationship($link_name)) { throw new SugarApiExceptionInvalidParameter("Unable to load link {$link_name}"); } $joinParams = array('joinTableAlias' => $alias, 'joinType' => $joinType, 'ignoreRole' => $ignoreRole, 'reverse' => true, 'includeCustom' => true); if (!empty($options['myAlias'])) { $joinParams['myAlias'] = $options['myAlias']; } $bean->{$link_name}->buildJoinSugarQuery($this, $joinParams); $this->join[$alias]->addLinkName($link_name); $this->join[$alias]->on()->equals($alias . '.id', $bean->id); $this->links[$link_name] = $this->join[$alias]; return $this->join[$alias]; }
/** * Find links with wrong relationship. * @param DefinitionObject $fieldDefs * @param SugarBean $seed * @return array Wrong relationships. */ protected function checkFieldsRelationships($fieldDefs, $seed) { $wrongRelations = array(); foreach ($fieldDefs as $fieldnm => $field) { // Check for bad links if ($field['type'] == 'link') { $seed->load_relationship($field['name']); $wRel = false; if (empty($seed->{$field}['name'])) { $wRel = true; } else { if ($this->checkRelationshipDef($field['name'], $seed)) { // Need to delete cache of TableDictionary to avoid inclusion of deleted files. if (file_exists('custom/application/Ext/TableDictionary/tabledictionary.ext.php')) { SugarAutoLoader::unlink('custom/application/Ext/TableDictionary/tabledictionary.ext.php'); } SugarRelationshipFactory::deleteCache(); SugarRelationshipFactory::rebuildCache(); unset($seed->{$field}['name']); $seed->load_relationship($field['name']); } $relModule = $seed->{$field}['name']->getRelatedModuleName(); $relBean = $this->getBean($relModule); if (empty($relBean)) { $wRel = true; } } if ($wRel) { if (!empty($field['relationship'])) { $wrongRelations[] = $field['relationship']; } $fieldDefs->setWrongDef($fieldnm); } } } return $wrongRelations; }
/** * Creates sorting specification from the given set of links and ORDER BY expression * * @param SugarBean $bean Primary bean * @param array $links Collection link definitions * @param array $orderBy ORDER BY expression * * @return array The sorting specification * @throws SugarApiExceptionError */ protected function getSortSpec(SugarBean $bean, array $links, $orderBy) { $linkData = array(); foreach ($links as $definition) { $linkName = $definition['name']; if (!$bean->load_relationship($linkName)) { throw new SugarApiExceptionError(sprintf('Unable to load link %s on module %s', $linkName, $bean->module_name)); } $relatedModule = $bean->{$linkName}->getRelatedModuleName(); $relatedBean = BeanFactory::getBean($relatedModule); if (isset($definition['field_map'])) { $fieldMap = $definition['field_map']; } else { $fieldMap = array(); } $linkData[$linkName] = array($relatedBean, $fieldMap); } $spec = array(); foreach ($orderBy as $alias => $direction) { $isNumeric = null; $map = array(); foreach ($linkData as $linkName => $data) { /** @var SugarBean $relatedBean */ list($relatedBean, $fieldMap) = $data; if (isset($fieldMap[$alias])) { $field = $fieldMap[$alias]; } else { $field = $alias; } $fieldDef = $relatedBean->getFieldDefinition($field); if (!$fieldDef) { // do not display alias since it may come from API arguments throw new SugarApiExceptionError('Unable to load field definition'); } $type = $relatedBean->db->getFieldType($fieldDef); if ($type) { $isFieldNumeric = $relatedBean->db->isNumericType($type); } else { // assume field is varchar in case type is not specified $isFieldNumeric = false; } if (isset($fieldDef['sort_on'])) { if ($isFieldNumeric && count($fieldDef['sort_on']) > 1) { throw new SugarApiExceptionError('Cannot use "sort_on" more than one columns for numeric fields in collections'); } $map[$linkName] = (array) $fieldDef['sort_on']; } else { $map[$linkName] = array($field); } if ($isNumeric === null) { $isNumeric = $isFieldNumeric; } elseif ($isNumeric != $isFieldNumeric) { throw new SugarApiExceptionError(sprintf('Alias %s points to both string and numeric fields', $field)); } } $spec[] = array('map' => $map, 'is_numeric' => $isNumeric, 'direction' => $direction); } return $spec; }
/** * Gets sidecar subpanel layout defs in the BWC format * * @param Array $components Existing sidecar subpanel layout * @param SugarBean $bean The bean that the subpanels are being scraped for * @return array */ protected function getSidecarSubpanelDefsAsLegacy(array $components, SugarBean $bean) { $return = array(); // Used in keeping uniqueness of link name based keys $counter = 0; foreach ($components as $component) { // We can only really do this if there is a label and a link if (isset($component['label']) && isset($component['context']['link'])) { // The link is used as an index and a module finder $link = $component['context']['link']; // If there is a module on the link field, we are good if (!empty($bean->field_defs[$link]['module'])) { $def['module'] = $bean->field_defs[$link]['module']; } else { // If there isn't a module then we need to load the // relationship to get the related module $bean->load_relationship($link); if (!empty($bean->{$link})) { $relMod = $bean->{$link}->getRelatedModuleName(); if (!empty($relMod)) { $def['module'] = $relMod; } } } // If a module was found then proceed to set the def if (!empty($def['module'])) { // Add the title key in $def['title_key'] = $component['label']; // Make sure we are not overriding this index if (isset($return[$bean->module_dir]['subpanel_setup'][$link])) { // this is actually meaningless in the scope of // things so manipulating this isn't a world changer $link .= '_' . ++$counter; } // Set the new def into the expected $return[$bean->module_dir]['subpanel_setup'][$link] = $def; } } } return $return; }
/** * @static * @param SugarBean $focus * @param String $formula * @return array of related modules used in the formula */ public static function getLinkedModulesFromFormula($focus, $formula) { global $dictionary, $beanList; $links = self::getLinkFieldsForModule($focus->module_name, $focus->object_name); $relMods = array(); if (!empty($links)) { foreach ($links as $name => $def) { //Look through all calculated fields for uses of this link field if (preg_match('/\\W\\$' . $name . '\\W/', $formula)) { $focus->load_relationship($name); $relMod = $focus->{$name}->getRelatedModuleName(); if (!empty($beanList[$relMod])) { $relMods[$relMod] = $beanList[$relMod]; } } } } return $relMods; }