2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4 * SugarCRM is a customer relationship management program developed by
5 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Affero General Public License version 3 as published by the
9 * Free Software Foundation with the addition of the following permission added
10 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19 * You should have received a copy of the GNU Affero General Public License along with
20 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU Affero General Public License version 3.
31 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34 * technical reasons, the Appropriate Legal Notices must display the words
35 * "Powered by SugarCRM".
36 ********************************************************************************/
46 class RelationshipHandler extends Relationship {
48 var $db; //Database link by reference
50 var $base_module; //name of module
51 var $base_bean; //actual object
52 var $base_vardef_field; //base's vardef field name of relationship with rel1
54 var $rel1_module; //name of related module
55 var $rel1_bean; //actual related object
56 var $rel1_relationship_name; //Relationship name between base and rel1
57 var $rel1_vardef_field; //rel1's vardef field name of relationship with rel2
58 var $rel1_vardef_field_base; //rel1's vardef field name of relationship with base
60 var $rel2_module; //name of related related module
61 var $rel2_bean; //actual related related object
62 var $rel2_relationship_name; //Relationship name between rel1 and rel2
63 var $rel2_vardef_field; //rel2's vardef field name of relationship with rel1
66 var $base_array; //Info array
67 var $rel1_array; //Info array
68 var $rel2_array; //Info array
75 'slabel' -> singular module name in correct language
76 'plabel' -> plural module name in correct language
83 ///////////////////////////Setup and populate functions//////////////////////////////
85 function RelationshipHandler(& $db, $base_module=""){
88 $this->base_module = $base_module;
90 //end function RelationshipHandler
93 function set_rel_vardef_fields($base_vardef_field, $rel1_vardef_field=""){
95 $this->base_vardef_field = $base_vardef_field;
96 $this->rel1_vardef_field = $rel1_vardef_field;
98 //end function set_rel_vardef_fields
102 function set_rel_relationship_names($build_rel2=false){
104 $this->rel1_relationship_name = $this->base_bean->field_defs[$this->base_vardef_field]['relationship'];
106 if($build_rel2==true){
107 $this->rel2_relationship_name = $this->rel1_bean->field_defs[$this->rel1_vardef_field]['relationship'];
110 //end function set_rel_relationship_names
116 ///////////////////////////////END Setup and populate functions/////////////////////
120 set the build_rel2 to true if you want the rel2 info array as well
121 This function will build all the relationship info it can based on values set in the setup functions
122 When you use the info arrays (rel1_array) or (rel2_array), make sure you always check for empty values
124 function build_info($build_rel2=false){
125 if($this->base_bean == null){
126 $this->base_bean = get_module_info($this->base_module);
129 if(empty($this->rel1_bean)){
130 $this->build_rel1_info();
131 $this->rel1_module = $this->rel1_bean->module_dir;
134 if($build_rel2==true && $this->rel2_bean==""){
135 $this->build_rel2_info();
136 $this->rel2_module = $this->rel2_bean->module_dir;
139 //translate the module titles to the proper language
140 $this->build_module_labels($build_rel2);
142 //end function build_info
145 function build_rel1_info(){
147 $this->rel1_bean = $this->trace_relationship_module($this->base_module, $this->base_vardef_field);
149 //end function build_rel1_info
152 function build_rel2_info(){
154 $this->rel2_bean = $this->trace_relationship_module($this->base_module, $this->base_vardef_field, $this->rel1_vardef_field);
156 //end function build_rel1_info
160 Translates the module names to their singular and plural label and puts them in
161 the info arrays. Does it for base, rel1, and rel2 if specified
164 function build_module_labels($build_rel2=false){
165 global $app_list_strings;
167 ///Base Module Labels
168 if(!empty($app_list_strings['moduleList'][$this->base_bean->module_dir])){
169 $this->base_array['plabel'] = $app_list_strings['moduleList'][$this->base_bean->module_dir];
171 $this->base_array['plabel'] = $this->base_bean->module_dir;
173 if(!empty($app_list_strings['moduleListSingular'][$this->base_bean->module_dir])){
174 $this->base_array['slabel'] = $app_list_strings['moduleListSingular'][$this->base_bean->module_dir];
176 $this->base_array['slabel'] = $this->base_bean->object_name;
179 ///Rel1 Module Labels
180 if(!empty($app_list_strings['moduleList'][$this->rel1_bean->module_dir])){
181 $this->rel1_array['plabel'] = $app_list_strings['moduleList'][$this->rel1_bean->module_dir];
183 $this->rel1_array['plabel'] = $this->rel1_bean->module_dir;
186 if(!empty($app_list_strings['moduleListSingular'][$this->rel1_bean->module_dir])){
187 $this->rel1_array['slabel'] = $app_list_strings['moduleListSingular'][$this->rel1_bean->module_dir];
189 $this->rel1_array['slabel'] = $this->rel1_bean->object_name;
194 if($build_rel2==true){
196 if(!empty($app_list_strings['moduleList'][$this->rel2_bean->module_dir])){
197 $this->rel2_array['plabel'] = $app_list_strings['moduleList'][$this->rel2_bean->module_dir];
199 $this->rel2_array['plabel'] = $this->rel2_bean->module_dir;
201 if(!empty($app_list_strings['moduleListSingular'][$this->rel2_bean->module_dir])){
202 $this->rel2_array['slabel'] = $app_list_strings['moduleListSingular'][$this->rel2_bean->module_dir];
204 $this->rel2_array['slabel'] = $this->rel2_bean->module_dir;
206 //end if build_rel2 is true
209 //end function buld_module_lables
216 function build_related_list($type="base"){
217 //type can be base, rel1
222 $target_list = $this->base_bean->get_linked_beans($this->base_vardef_field, $this->rel1_bean->object_name);
223 //Possibility exists that this is a new relationship, so capture via relationship fields
224 if(empty($target_list)){
225 $target_list = search_filter_rel_info($this->base_bean, $this->rel1_bean->module_dir, $this->base_vardef_field);
226 //end if the target list is empty
231 $target_list = $this->rel1_bean->get_linked_beans($this->rel1_vardef_field, $this->rel2_bean->object_name);
233 //Possibility exists that this is a new relationship, so capture via relationship fields
234 if(empty($target_list)){
235 $target_list = search_filter_rel_info($this->rel1_bean, $this->rel2_bean->module_dir, $this->rel1_vardef_field);
236 //end if the target list is empty
242 //end function build_related_list
248 ///////BEGIN Functions to find relationships/////////////////////////////////
250 function get_relationship_information(& $target_bean, $get_upstream_rel_field_name = false){
252 $target_module_name = $target_bean->module_dir;
253 $current_module_name = $this->base_module;
255 //Look for downstream connection
256 $rel_array = $this->retrieve_by_sides($current_module_name, $target_module_name, $this->db);
259 //Does a downstream relationship exist
260 if($rel_array!=null){
261 if($rel_array['relationship_type']=="many-to-many"){
262 $target_bean->$rel_array['join_key_lhs'] = $this->base_bean->id;
263 if($rel_array['relationship_role_column']!=""){
264 $target_bean->$rel_array['relationship_role_column'] = $rel_array['relationship_role_column_value'];
266 //end if many-to-many
269 if($rel_array['relationship_type']=="one-to-many"){
270 $target_bean->$rel_array['rhs_key'] = $this->base_bean->id;
271 if($rel_array['relationship_role_column']!=""){
272 $target_bean->$rel_array['relationship_role_column'] = $rel_array['relationship_role_column_value'];
278 //end if downstream relationship exists
283 //Look for upstream connection
284 $rel_array = $this->retrieve_by_sides($target_module_name, $current_module_name, $this->db);
286 //Does an upstream relationship exist
287 if($rel_array!=null){
288 if($rel_array['relationship_type']=="many-to-many"){
289 $target_bean->$rel_array['join_key_rhs'] = $this->base_bean->id;
290 if($rel_array['relationship_role_column']!=""){
291 $target_bean->$rel_array['relationship_role_column'] = $rel_array['relationship_role_column_value'];
293 //end if many-to-many
296 if($rel_array['relationship_type']=="one-to-many"){
297 $this->$rel_array['rhs_key'] = $this->base_bean->id;
298 if($rel_array['relationship_role_column']!=""){
299 $this->$rel_array['relationship_role_column'] = $rel_array['relationship_role_column_value'];
305 ///Fill additional id field if necessary
306 if(($id_name = $this->traverse_rel_meta($current_module_name, $target_bean, $rel_array['relationship_name'])) != null){
307 $target_bean->$id_name = $this->base_bean->id;
308 if($get_upstream_rel_field_name) {
309 $target_bean->new_rel_relname = $id_name;
310 $target_bean->new_rel_id = $this->base_bean->id;
314 //end if an upstream relationship exists
317 //end function get_relationship_information
320 function traverse_rel_meta($base_module, & $target_bean, $target_rel_name){
323 //returns name of variable to store id in
324 //if none exists, then returns null
325 foreach($target_bean->field_defs as $field_array){
327 if(!empty($field_array['relationship']) && $field_array['relationship']==$target_rel_name){
329 $id_name = $this->get_id_name($target_bean, $field_array['name']);
331 //end if rel name match
334 //end foreach field def
339 //end function traverse_rel_meta
343 function get_id_name(& $target_bean, $field_name){
345 foreach($target_bean->relationship_fields as $target_id => $rel_name){
347 if($rel_name == $field_name){
348 //relationship id found
356 //end function get_id_name
359 ///////////////////////////END functions to find relationships //////////////////////
362 function process_by_rel_bean($rel1_module){
364 $this->rel1_relationship_name = $this->retrieve_by_modules($this->base_module, $rel1_module, $this->db);
365 $this->rel1_module = $rel1_module;
366 $this->rel1_bean = get_module_info($this->rel1_module);
368 //end function process_by_rel_bean
372 function get_rel1_vardef_field_base($field_defs){
373 foreach($field_defs as $field_array){
375 if(!empty($field_array['relationship']) && $field_array['relationship']==$this->rel1_relationship_name){
377 $this->rel1_vardef_field_base = $field_array['name'];
378 //end if rel name match
381 //end foreach field def
387 //end get_rel1_vardef_field_base
391 function get_farthest_reach(){
393 if($this->rel1_vardef_field!=""){
394 //the farthest reach is rel2
395 $this->build_info(true);
396 return $this->rel2_bean;
399 //the farthest reach is rel1
400 $this->build_info(false);
401 return $this->rel1_bean;
403 //end function get_farthest_reach
406 //end class RelationshipHandler