Test Failed
Push — CI ( 0f01dd...c95a04 )
by Adam
55:13
created

Link::Link()   F

Complexity

Conditions 18
Paths 3072

Size

Total Lines 64
Code Lines 37

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 64
rs 2.8531
cc 18
eloc 37
nc 3072
nop 5

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
7
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41
/*********************************************************************************
42
43
* Description:  Defines the base class for new data type, Relationship, methods in the class will
44
* be used to manipulate relationship between object instances.
45
* Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
46
* All Rights Reserved.
47
* Contributor(s): ______________________________________..
48
********************************************************************************/
49
50
51
class Link {
52
53
	/* Private variables.*/
54
	var $_log;
55
	var $_relationship_name; //relationship this attribute is tied to.
56
	var $_bean; //stores a copy of the bean.
57
	var $_relationship= '';
58
	var $_bean_table_name;
59
	var $_bean_key_name='id';
60
	private $relationship_fields = array();
61
	var $_db;
62
	var $_swap_sides = false;
63
	var $_rhs_key_override = false;
64
	var $_bean_filter_field = '';
65
66
	//if set to true role column will not be added to the filter criteria.
67
	var $ignore_role_filter=false;
68
	//if set to true distinct clause will be added to the select list.
69
	var $add_distinct=false;
70
	//value of this variable dictates the action to be taken when a duplicate relationship record is found.
71
	//1-ignore,2-update,3-delete.
72
	//var $when_dup_relationship_found=2; // deprecated - only used by Queues, which is also no longer used
73
74
	// a value for duplicate variable is stored by the _relatinship_exists method.
75
	var $_duplicate_key;
76
	var $_duplicate_where;
77
78
	/* Parameters:
79
	 * 		$_rel_name: use this relationship key.
80
	 * 		$_bean: reference of the bean that instantiated this class.
81
	 * 		$_fieldDef: vardef entry for the field.
82
	 * 		$_table_name: optional, fetch from the bean's table name property.
83
	 * 		$_key_name: optional, name of the primary key column for _table_name
84
	 */
85
	function Link($_rel_name, &$_bean, $fieldDef, $_table_name='', $_key_name=''){
86
		global $dictionary;
87
        require_once("modules/TableDictionary.php");
88
        $GLOBALS['log']->debug("Link Constructor, relationship name: ".$_rel_name);
89
		$GLOBALS['log']->debug("Link Constructor, Table name: ".$_table_name);
90
		$GLOBALS['log']->debug("Link Constructor, Key name: ".$_key_name);
91
92
        $this->_relationship_name=$_rel_name;
93
		$this->relationship_fields = (!empty($fieldDef['rel_fields']))?$fieldDef['rel_fields']: array();
94
		$this->_bean=&$_bean;
95
		$this->_relationship=new Relationship();
96
		//$this->_relationship->retrieve_by_string_fields(array('relationship_name'=>$this->_relationship_name));
97
		$this->_relationship->retrieve_by_name($this->_relationship_name);
98
99
		$this->_db = DBManagerFactory::getInstance();
100
101
102
		//Following behavior is tied to a property(ignore_role) value in the vardef. It alters the values of 2 properties, ignore_role_filter and add_distinct.
103
		//the property values can be altered again before any requests are made.
104
		if (!empty($fieldDef) && is_array($fieldDef)) {
105
			if (array_key_exists('ignore_role', $fieldDef)) {
106
				if ($fieldDef['ignore_role'] == true) {
107
					$this->ignore_role_filter=true;
108
					$this->add_distinct=true;
109
				}
110
			}
111
		}
112
113
		$this->_bean_table_name=(!empty($_table_name)) ? $_table_name : $_bean->table_name;
114
		if (!empty($key_name)) {
0 ignored issues
show
Bug introduced by
The variable $key_name does not exist. Did you mean $_key_name?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
115
			$this->_bean_key_name=$_key_name;
116
		} else {
117
118
			if ($this->_relationship->lhs_table != $this->_relationship->rhs_table) {
119
120
				if ($_bean->table_name == $this->_relationship->lhs_table)
121
					$this->_bean_key_name=$this->_relationship->lhs_key;
122
123
				if ($_bean->table_name == $this->_relationship->rhs_table)
124
					$this->_bean_key_name=$this->_relationship->rhs_key;
125
126
			}
127
		}
128
129
		if ($this->_relationship->lhs_table == $this->_relationship->rhs_table && isset($fieldDef['side']) && $fieldDef['side'] == 'right'){
130
		    $this->_swap_sides = true;
131
		}
132
133
		if (!empty($fieldDef['rhs_key_override'])) {
134
			$this->_rhs_key_override = true;
135
		}
136
		if (!empty($fieldDef['bean_filter_field'])) {
137
			$this->_bean_filter_field = $fieldDef['bean_filter_field'];
138
		}
139
140
		//default to id if not set.
141
		if (empty($this->_bean_key_name))$this->_bean_key_name='id';
142
143
		$GLOBALS['log']->debug("Link Constructor, _bean_table_name: ".$this->_bean_table_name);
144
		$GLOBALS['log']->debug("Link Constructor, _bean_key_name: ".$this->_bean_key_name);
145
		if (!empty($this->_relationship->id)) $GLOBALS['log']->debug("Link Constructor, relationship record found.");
146
		else $GLOBALS['log']->debug("Link Constructor, No relationship record.") ;
147
148
	}
149
150
    function loadedSuccesfully() {
151
        return !empty($this->_relationship->id);
152
    }
153
154
	/* This method will return the following based on cardinality of the relationship.
155
	 *  # one-to-many, many-to-many: empty array if not data is found else array of keys.
156
	 *  # if many-to-many and $role set to true : empty array if not data is found else
157
	 *  array of array which contain id+other fields.
158
	 *  # many-to-one, one-to-one: null if no linked data is found, else key value.
159
	 *
160
	 * For a self referencing relationship the function will behave as if the user is trying
161
	 * to access the child records. To get to the parent records use the getParent() method.
162
	 */
163
    function get($role = false) {
164
        if($role){
165
            $role_field = $this->_get_link_table_role_field($this->_relationship_name);
166
            if($role_field !== false){
167
                $query = $this->getQuery(false, array(),0, "", false, "", $role_field);
168
            }else{
169
                return array();
170
            }
171
        }else{
172
            $query = $this->getQuery();
173
        }
174
        $result = $this->_db->query($query, true);
175
        $list = Array();
176
        while($row = $this->_db->fetchByAssoc($result))
177
        {
178
            if($role){
179
                $list[] = $row;
180
            }else{
181
                $list[] = $row['id'];
182
            }
183
        }
184
        return $list;
185
    }
186
187
	function getRelatedTableName() {
188
189
		$bean_is_lhs=$this->_get_bean_position();
190
		if (!isset($bean_is_lhs)) {
191
			$GLOBALS['log']->debug("Invalid relationship parameters. Exiting..");
192
			return null;
193
		}
194
195
		if ($bean_is_lhs) {
196
			return $this->_relationship->rhs_table;
197
		} else {
198
			return $this->_relationship->lhs_table;
199
		}
200
	}
201
202
	function getRelatedModuleName() {
203
204
		$bean_is_lhs=$this->_get_bean_position();
205
		if (!isset($bean_is_lhs)) {
206
			$GLOBALS['log']->debug("Invalid relationship parameters. Exiting..");
207
			return null;
208
		}
209
210
		if ($bean_is_lhs) {
211
			return $this->_relationship->rhs_module;
212
		} else {
213
			return $this->_relationship->lhs_module;
214
		}
215
	}
216
217
218
	function getRelatedFields(){
219
		return $this->relationship_fields;
220
	}
221
222
	function getRelatedField($name){
223
		return (!empty($this->relationship_fields[$name]))? $this->relationship_fields[$name]: null;
224
	}
225
226
	function getRelationshipObject() {
227
	   return $this->_relationship;
228
	}
229
230
	function _get_bean_position() {
231
		//current beans module and table are on the left side or the right side.
232
		$position = false;
233
		if ($this->_relationship->lhs_table == $this->_bean_table_name &&  $this->_relationship->lhs_key == $this->_bean_key_name) {
234
			$position =  true;
235
236
		}
237
		if ($this->_relationship->rhs_table == $this->_bean_table_name &&  $this->_relationship->rhs_key == $this->_bean_key_name) {
238
			$position =  false;
239
		}
240
241
		if($this->_swap_sides){
242
			return 	!$position;
243
		}
244
		return $position;
245
	}
246
247
	function _is_self_relationship() {
248
		if ($this->_relationship->lhs_table == $this->_relationship->rhs_table) {
249
			return true;
250
		}
251
		return false;
252
	}
253
254
	function getJoin($params, $return_array =false)
255
	{
256
		$join_type= ' INNER JOIN ';
257
			if(isset($params['join_type'])){
258
					$join_type = $params['join_type'];
259
			}
260
		$id = -1;
261
		$join = '';
262
		$bean_is_lhs=$this->_get_bean_position();
263
264
		if ($this->_relationship->relationship_type=='one-to-one' or $this->_relationship->relationship_type=='many-to-one' or
265
   			($this->_relationship->relationship_type=='one-to-many' && !$bean_is_lhs))
266
		{
267
			if ($bean_is_lhs) {
268
			    $table = $this->_relationship->rhs_table;
269
			    $key = $this->_relationship->rhs_key;
270
                // check right table alias
271
			    $other_table = (empty($params['left_join_table_alias']) ? $this->_relationship->lhs_table : $params['left_join_table_alias']);
272
			    $other_key = $this->_relationship->lhs_key;
273
			} else {
274
			    $key = $this->_relationship->lhs_key;
275
			    $table = $this->_relationship->lhs_table;
276
277
				if ( ! empty($params['join_table_alias']))
278
				{
279
			    	$table_with_alias = $table. " ".$params['join_table_alias'];
280
			    	$table = $params['join_table_alias'];
281
				}
282
			    $other_table = (empty($params['right_join_table_alias']) ? $this->_relationship->rhs_table : $params['right_join_table_alias']);
283
			    $other_key = $this->_relationship->rhs_key;
284
			}
285
286
		    $join = $join_type . ' '. $table_with_alias . " ON\n".$table.'.'.$key.'= '.$other_table.'.'.$other_key ." AND ". $table.".deleted=0\n";
287
288
		}
289
		if ($this->_relationship->relationship_type == 'one-to-many' && $bean_is_lhs) {
290
291
			    $table = $this->_relationship->rhs_table;
292
			    $key = $this->_relationship->rhs_key;
293
			    $other_table = (empty($params['left_join_table_alias']) ? $this->_relationship->lhs_table : $params['left_join_table_alias']);
294
			    $other_key = $this->_relationship->lhs_key;
295
					if ( ! empty($params['join_table_alias']))
296
					{
297
			    	$table_with_alias = $table. " ".$params['join_table_alias'];
298
			    	$table = $params['join_table_alias'];
299
					}
300
301
			    $join = $join_type . ' '.$table_with_alias . " ON\n".$table.'.'.$key.'= '.$other_table.'.'.$other_key ." AND ". $table.".deleted=0\n";
302
303
		}
304
305
		if ($this->_relationship->relationship_type=='many-to-many' )
306
		{
307
			if ( ! empty($params['join_table_alias']))
308
			{
309
		   		$table_with_alias = $this->_relationship->join_table. " ".$params['join_table_alias'];
310
		   		$table = $params['join_table_alias'];
311
				$rel_table_with_alias =
312
					$this->_relationship->join_table. " ".
313
					$params['join_table_link_alias'];
314
				$rel_table = $params['join_table_link_alias'];
315
			}
316
317
			if ( $bean_is_lhs )
318
			{
319
                $other_table = (empty($params['left_join_table_alias']) ? $this->_relationship->lhs_table : $params['left_join_table_alias']);
320
				$join .= $join_type . ' '.$rel_table_with_alias.' ON '.$other_table.".".$this->_relationship->lhs_key."=".$rel_table.".".$this->_relationship->join_key_lhs."  AND ".$rel_table.".deleted=0\n";
321
			} else
322
			{
323
                $other_table = (empty($params['right_join_table_alias']) ? $this->_relationship->rhs_table : $params['right_join_table_alias']);
324
				$join .= $join_type . ' '.$rel_table_with_alias.' ON '.$other_table.".".$this->_relationship->rhs_key."=".$rel_table.".".$this->_relationship->join_key_rhs."  AND ".$rel_table.".deleted=0\n";
325
			}
326
			if (!empty($this->_relationship->relationship_role_column) && !$this->ignore_role_filter)
327
			{
328
				$join.=" AND ".$rel_table.'.'.$this->_relationship->relationship_role_column;
329
				//role column value.
330
				if (empty($this->_relationship->relationship_role_column_value))
331
				{
332
					$join.=' IS NULL';
333
				} else {
334
					$join.= "='".$this->_relationship->relationship_role_column_value."'";
335
				}
336
				$join.= "\n";
337
			}
338
			if ( ! empty($params['join_table_alias']))
339
			{
340
				if ( $bean_is_lhs )
341
				{
342
			  	  $table_with_alias = $this->_relationship->rhs_table. " ".$params['join_table_alias'];
343
				} else {
344
			  	  $table_with_alias = $this->_relationship->lhs_table. " ".$params['join_table_alias'];
345
				}
346
			   	$table = $params['join_table_alias'];
347
			}
348
349
			if ( $bean_is_lhs )
350
			{
351
				if($this->_rhs_key_override){
352
					$join .= $join_type . ' '.$table_with_alias.' ON '.$table.".".$this->_relationship->rhs_key."=".$rel_table.".".$this->_relationship->join_key_rhs." AND ".$table.".deleted=0";
353
				}else{
354
              	 	$join .= $join_type . ' '.$table_with_alias.' ON '.$table.".".$this->_relationship->lhs_key."=".$rel_table.".".$this->_relationship->join_key_rhs." AND ".$table.".deleted=0";
355
				}
356
			} else {
357
                $join .= $join_type . ' '.$table_with_alias.' ON '.$table.".".$this->_relationship->rhs_key."=".$rel_table.".".$this->_relationship->join_key_lhs." AND ".$table.".deleted=0";
358
			}
359
                $join.= "\n";
360
		}
361
362
		if($return_array){
363
			$ret_arr = array();
364
			$ret_arr['join'] = $join;
365
			$ret_arr['type'] = $this->_relationship->relationship_type;
366
			if ( $bean_is_lhs ){
367
368
				$ret_arr['rel_key'] = 	$this->_relationship->join_key_rhs;
369
			}else{
370
371
				$ret_arr['rel_key'] = 	$this->_relationship->join_key_lhs;
372
			}
373
			return $ret_arr;
374
		}
375
		return $join;
376
	}
377
378
379
	function _add_deleted_clause($deleted=0,$add_and='',$prefix='') {
380
381
		if (!empty($prefix)) $prefix.='.';
382
		if (!empty($add_and)) $add_and=' '.$add_and.' ';
383
384
		if ($deleted==0)  return $add_and.$prefix.'deleted=0';
385
		if ($deleted==1) return $add_and.$prefix.'deleted=1';
386
		else return '';
387
	}
388
389
	function _add_optional_where_clause($optional_array, $add_and='',$prefix='') {
390
391
		if (!empty($prefix)) $prefix.='.';
392
		if (!empty($add_and)) $add_and=' '.$add_and.' ';
393
394
		if(!empty($optional_array)){
395
			return $add_and.$prefix."".$optional_array['lhs_field']."".$optional_array['operator']."'".$optional_array['rhs_value']."'";
396
		}
397
		return '';
398
	//end function _add_optional_where_clause
399
	}
400
401
402
403
	function getQuery($return_as_array=false, $sort_array = array(),$deleted=0, $optional_where="", $return_join = false, $bean_filter="", $role="", $for_subpanels = false){
404
405
		$select='';
406
		$from='';
407
		$join = '';
408
		$where='';
409
		$join_tables = array();
410
		$bean_is_lhs=$this->_get_bean_position();
411
412
		if (!isset($bean_is_lhs)) {
413
			$GLOBALS['log']->debug("Invalid relationship parameters. Exiting..");
414
			return null;
415
		}
416
417
		if (empty($bean_filter)) {
418
			if(!empty($this->_bean_filter_field)){
419
				$bean_filter_field = $this->_bean_filter_field;
420
				$bean_filter="= '".$this->_bean->$bean_filter_field."'";
421
			}else{
422
				$bean_filter="= '".$this->_bean->id."'";
423
			}
424
		}
425
426
		$GLOBALS['log']->debug("getQuery, Bean is LHS: ".$bean_is_lhs);
427
		$GLOBALS['log']->debug("getQuery, Relationship type=".$this->_relationship->relationship_type);
428
		$GLOBALS['log']->debug("getQuery, Relationship role column name=".$this->_relationship->relationship_role_column);
429
430
		if ($this->_relationship->relationship_type=='one-to-one' or $this->_relationship->relationship_type=='many-to-one' or
431
		     ($this->_relationship->relationship_type=='one-to-many' && !$bean_is_lhs)) {
432
433
			$GLOBALS['log']->debug("Processing one-to-one,many-to-one,one-to-many.");
434
435
			if ($this->add_distinct) {
436
				$select='SELECT DISTINCT id';
437
			} else {
438
				$select='SELECT id';
439
			}
440
441
			if ($bean_is_lhs) {
442
			    $from= 'FROM '.$this->_relationship->rhs_table;
443
			    $where='WHERE '.$this->_relationship->rhs_table.'.'.$this->_relationship->rhs_key.$bean_filter;
444
			    if (!empty($this->_relationship->relationship_role_column) && !$this->ignore_role_filter) {
445
			    	$where.=" AND ".$this->_relationship->rhs_table.'.'.$this->_relationship->relationship_role_column;
446
447
			    	//role column value.
448
			    	if (empty($this->_relationship->relationship_role_column_value)) {
449
			    		$where.=' IS NULL';
450
			    	} else {
451
			    		$where.= "='".$this->_relationship->relationship_role_column_value."'";
452
			    	}
453
			    }
454
455
			    //add deleted clause - but not if we're dealing with a Custom table which will lack the 'deleted' field
456
                if(substr_count($this->_relationship->rhs_table, '_cstm') == 0)
457
			     $where.=$this->_add_deleted_clause($deleted,'AND',$this->_relationship->rhs_table );
458
459
				if($optional_where!=""){
460
				//process optional where
461
					$where.=$this->_add_optional_where_clause($optional_where,'AND');
462
				}
463
464
465
			}
466
			else {
467
			    $from= 'FROM '.$this->_relationship->lhs_table;
468
			    $where='WHERE '.$this->_relationship->lhs_table.'.'.$this->_relationship->lhs_key."= '".$this->_bean->{$this->_relationship->rhs_key}."'";
469
			    //added deleted clause.
470
			    $where.=$this->_add_deleted_clause($deleted,'AND', $this->_relationship->lhs_table);
471
472
473
				if($optional_where!=""){
474
				//process optional where
475
					$where.=$this->_add_optional_where_clause($optional_where,'AND');
476
				}
477
478
			}
479
		}
480
		if ($this->_relationship->relationship_type == 'one-to-many' && $bean_is_lhs) {
481
482
			$GLOBALS['log']->debug("Processing one-to-many.");
483
484
			if ($this->add_distinct) {
485
				$select='SELECT DISTINCT '.$this->_relationship->rhs_table.'.id';
486
			} else {
487
				$select='SELECT '.$this->_relationship->rhs_table.'.id';
488
			}
489
			$from= 'FROM '.$this->_relationship->rhs_table;
490
		    $where='WHERE '.$this->_relationship->rhs_table.'.'.$this->_relationship->rhs_key.$bean_filter;
491
		    if (!empty($this->_relationship->relationship_role_column) && !$this->ignore_role_filter) {
492
		    	$where.=" AND ".$this->_relationship->rhs_table.'.'.$this->_relationship->relationship_role_column;
493
		    	//role column value.
494
		    	if (empty($this->_relationship->relationship_role_column_value)) {
495
		    		$where.=' IS NULL';
496
		    	} else {
497
		    		$where.= "='".$this->_relationship->relationship_role_column_value."'";
498
		    	}
499
		    }
500
501
            //add deleted clause - but not if we're dealing with a Custom table which will lack the 'deleted' field
502
            if(substr_count($this->_relationship->rhs_table, '_cstm') == 0)
503
		        $where.=$this->_add_deleted_clause($deleted,'AND',$this->_relationship->rhs_table);
504
505
			if($optional_where!=""){
506
			//process optional where
507
				$where.=$this->_add_optional_where_clause($optional_where,'AND');
508
			}
509
510
		}
511
512
		if ($this->_relationship->relationship_type=='many-to-many' ) {
513
			$GLOBALS['log']->debug("Processing many-to-many.");
514
515
			$swap = !$for_subpanels && $this->_swap_sides;
516
			if (($bean_is_lhs && !$swap) || (!$bean_is_lhs && $swap)) {
517
				if ($this->add_distinct) {
518
					$select="SELECT DISTINCT ".$this->_relationship->rhs_table.".id";
519
				} else {
520
					$select="SELECT ".$this->_relationship->rhs_table.".id";
521
				}
522
523
			    $from= 'FROM '.$this->_relationship->rhs_table;
524
			    $subjoin=' INNER JOIN '.$this->_relationship->join_table.' ON ('.$this->_relationship->rhs_table.".".$this->_relationship->rhs_key."=".$this->_relationship->join_table.".".$this->_relationship->join_key_rhs." AND ".$this->_relationship->join_table.".".$this->_relationship->join_key_lhs.$bean_filter;
525
				$join_tables[] = $this->_relationship->join_table;
526
			    if (!empty($this->_relationship->relationship_role_column) && !$this->ignore_role_filter) {
527
			    	$subjoin.=" AND ".$this->_relationship->join_table.'.'.$this->_relationship->relationship_role_column;
528
529
			    	//role column value.
530
			    	if (empty($this->_relationship->relationship_role_column_value)) {
531
			    		$subjoin.=' IS NULL';
532
			    	} else {
533
			    		$subjoin.= "='".$this->_relationship->relationship_role_column_value."'";
534
			    	}
535
			    }
536
			    $subjoin.=')';
537
			   $join .= $subjoin;
538
			    $from .= $subjoin;
539
540
541
				//add deleted clause.
542
				if ($deleted == 0 or $deleted==1) {
543
			    	$where.=' WHERE '.$this->_add_deleted_clause($deleted,'',$this->_relationship->join_table).$this->_add_deleted_clause($deleted,'AND',$this->_relationship->rhs_table);
544
				}
545
546
547
				if($optional_where!=""){
548
				//process optional where
549
					$where.=$this->_add_optional_where_clause($optional_where,'AND', $this->_relationship->rhs_table);
550
				}
551
552
553
			}
554
			else {
555
				if ($this->add_distinct) {
556
					$select="SELECT DISTINCT ".$this->_relationship->lhs_table.".id";
557
				} else {
558
					$select="SELECT ".$this->_relationship->lhs_table.".id";
559
				}
560
561
			    $from= 'FROM '.$this->_relationship->lhs_table;
562
			    $subjoin=' INNER JOIN '.$this->_relationship->join_table.' ON ('.$this->_relationship->lhs_table.".".$this->_relationship->lhs_key."=".$this->_relationship->join_table.".".$this->_relationship->join_key_lhs." AND ".$this->_relationship->join_table.".".$this->_relationship->join_key_rhs.$bean_filter;
563
			    $join_tables[] = $this->_relationship->join_table;
564
			    if (!empty($this->_relationship->relationship_role_column) && !$this->ignore_role_filter) {
565
			    	$subjoin.=" AND ".$this->_relationship->relationship_role_column;
566
567
			    	//role column value.
568
			    	if (empty($this->_relationship->relationship_role_column_value)) {
569
			    		$subjoin.=' IS NULL';
570
			    	} else {
571
			    		$subjoin.= "='".$this->_relationship->relationship_role_column_value."'";
572
			    	}
573
			    }
574
				$subjoin.=')';
575
				$join .= $subjoin;
576
			    $from .= $subjoin;
577
				//add deleted clause.
578
				if ($deleted == 0 or $deleted==1) {
579
			    	$where.=' WHERE '.$this->_add_deleted_clause($deleted,'',$this->_relationship->join_table).$this->_add_deleted_clause($deleted,'AND',$this->_relationship->lhs_table);
580
				}
581
582
583
				if($optional_where!=""){
584
				//process optional where
585
					$where.=$this->_add_optional_where_clause($optional_where,'AND', $this->_relationship->lhs_table);
586
				}
587
588
			}
589
		    if (!empty($role)){
590
                $select.=", ".$this->_relationship->join_table.".".$role;
591
            }
592
		}
593
		if ($return_as_array) {
594
			$query_as_array['select']=$select;
595
			$query_as_array['from']=$from;
596
			$query_as_array['where']=$where;
597
			if($return_join){
598
					$query_as_array['join'] = $join;
599
					$query_as_array['join_tables'] = $join_tables;
600
			}
601
			return $query_as_array;
602
		}
603
		else {
604
			$query = $select.' '.$from.' '.$where;
605
			$GLOBALS['log']->debug("Link Query=".$query);
606
			return $query;
607
		}
608
	}
609
610
	function getBeans($template, $sort_array = array(), $begin_index = 0, $end_index = -1, $deleted=0, $optional_where="") {
611
		$query = $this->getQuery(false,array(), $deleted, $optional_where); //get array of IDs
612
		return $this->_bean->build_related_list($query, $template);
613
	}
614
615
	function _add_one_to_many_table_based($key,$bean_is_lhs) {
616
617
		if ($bean_is_lhs) {
618
			$set_key_value=$this->_bean->id;
619
			$where_key_value=$key;
620
		}
621
		else {
622
			$set_key_value=$key;
623
			$where_key_value=$this->_bean->id;
624
		}
625
626
		$query= 'UPDATE '.$this->_relationship->rhs_table;
627
		$query.=' SET '.$this->_relationship->rhs_table.'.'.$this->_relationship->rhs_key."='".$set_key_value."'";
628
629
		//add role column to the query.
630
		if (!empty($this->_relationship->relationship_role_column)) {
631
			$query.=' ,'.$this->_relationship->relationship_role_column."='".$this->_relationship->relationship_role_column_value."'";
632
		}
633
		$query.=' WHERE '.$this->_relationship->rhs_table.".id='".$where_key_value."'";
634
635
		$GLOBALS['log']->fatal("Relationship Query ".$query);
636
637
		$result=$this->_db->query($query, true);
638
	}
639
640
	/* handles many to one*/
641
	function _add_many_to_one_bean_based($key) {
642
643
		//make a copy of this bean to avoid recursion.
644
		$bean=new $this->_bean->object_name;
645
		$bean->retrieve($this->_bean->id);
646
647
	   	$bean->{$this->_relationship->lhs_key}=$key;
648
649
	   	//set relationship role.
650
	   	if (!empty($this->_relationship->relationship_role_column)) {
651
	   		$bean->{$this->_relationship->relationship_role_column}=$this->_relationship->relationship_role_column_value;
652
	   	}
653
	   	$GLOBALS['log']->fatal("Adding many to one bean based {$bean->module_dir} {$bean->id}");
654
	   	$bean->save();
655
	}
656
657
658
	/* use this function to create link between 2 objects
659
	 * 1:1 will be treated like 1 to many.
660
	 * todo handle self referencing relationships
661
	 * the function also allows for setting of values for additional field in the table being
662
	 * updated to save the relationship, in case of many-to-many relationships this would be the join table.
663
	 * the values should be passed as key value pairs with column name as the key name and column value as key value.
664
	 */
665
	function add($rel_keys,$additional_values=array()) {
666
667
		if (!isset($rel_keys) or empty($rel_keys)) {
668
			$GLOBALS['log']->fatal("Link.add, Null key passed, no-op, returning... ");
669
			return;
670
		}
671
672
		//check to ensure that we do in fact have an id on the bean.
673
		if(empty($this->_bean->id)){
674
			$GLOBALS['log']->fatal("Link.add, No id on the bean... ");
675
			return;
676
		}
677
678
		if (!is_array($rel_keys)) {
679
			$keys[]=$rel_keys;
680
		} else {
681
			$keys=$rel_keys;
682
		}
683
684
		$bean_is_lhs=$this->_get_bean_position();
685
		if (!isset($bean_is_lhs)) {
686
			$GLOBALS['log']->fatal("Invalid relationship parameters. Exiting..");
687
			return null;
688
		}
689
		//if multiple keys are passed then check for unsupported relationship types.
690
		if (count($keys) > 1) {
691
			if (($this->_relationship->relationship_type == 'one-to-one')
692
				or ($this->_relationship->relationship_type == 'one-to-many' and !$bean_is_lhs)
693
				or ($this->_relationship->relationship_type == 'many-to-one')) {
694
					$GLOBALS['log']->fatal("Invalid parameters passed to function, the relationship does not support addition of multiple records.");
695
					return;
696
				}
697
		}
698
        $GLOBALS['log']->debug("Relationship type = {$this->_relationship->relationship_type}");
699
        foreach($keys as $key) {
700
701
			//fetch the related record using the key and update.
702
			if ($this->_relationship->relationship_type=='one-to-one' || $this->_relationship->relationship_type == 'one-to-many' ) {
703
                $this->_add_one_to_many_table_based($key,$bean_is_lhs);
704
			}
705
706
			//updates the bean passed to the instance....
707
			//todo remove this case.
708
			if ($this->_relationship->relationship_type=='many-to-one') {
709
				$this->_add_many_to_one_bean_based($key);
710
		    }
711
712
		    //insert record in the link table.
713
			if ($this->_relationship->relationship_type=='many-to-many' ) {
714
                //replace existing relationships for one-to-one
715
                if(!empty($GLOBALS['dictionary'][$this->_relationship_name]['true_relationship_type']) &&
716
					($GLOBALS['dictionary'][$this->_relationship_name]['true_relationship_type'] == 'one-to-one'))
717
                {
718
                    //Remove all existing links with either bean.
719
                    $old_rev = isset($this->_relationship->reverse) ? false : $this->_relationship->reverse;
720
                    $this->_relationship->reverse = true;
721
                    $this->delete($key);
722
                    $this->delete($this->_bean->id);
723
                    $this->_relationship->reverse = $old_rev;
724
                }
725
726
				//Swap the bean positions for self relationships not coming from subpanels.
727
				//such as one-to-many relationship fields generated in studio/MB
728
				$swap = !isset($_REQUEST['subpanel_id']) && $this->_swap_sides;
729
				//add keys from the 2 tables to the additional keys array..
730
				if (($bean_is_lhs && !$swap) || (!$bean_is_lhs && $swap)) {
731
					$additional_values[$this->_relationship->join_key_lhs]=$this->_bean->id;
732
					$additional_values[$this->_relationship->join_key_rhs]=$key;
733
				} else {
734
					$additional_values[$this->_relationship->join_key_rhs]=$this->_bean->id;
735
					$additional_values[$this->_relationship->join_key_lhs]=$key;
736
				}
737
				//add the role condition.
738
				if (!empty($this->_relationship->relationship_role_column) && !empty($this->_relationship->relationship_role_column_value)) {
739
					$additional_values[$this->_relationship->relationship_role_column]=$this->_relationship->relationship_role_column_value;
740
				}
741
				//add deleted condition.
742
				$additional_values['deleted']=0;
743
744
				$this->_add_many_to_many($additional_values);
745
746
				//reverse will be set to true only for self-referencing many-to-many relationships.
747
				if ($this->_is_self_relationship() && !empty($GLOBALS['dictionary'][$this->_relationship_name]) &&
748
					!empty($GLOBALS['dictionary'][$this->_relationship_name]['true_relationship_type']) &&
749
					$GLOBALS['dictionary'][$this->_relationship_name]['true_relationship_type'] == 'many-to-many' ||
750
				(!empty($this->_relationship->reverse) && $this->_relationship->reverse == true )){
751
					//swap key values;
752
					$temp=$additional_values[$this->_relationship->join_key_lhs];
753
					$additional_values[$this->_relationship->join_key_lhs]=$additional_values[$this->_relationship->join_key_rhs];
754
					$additional_values[$this->_relationship->join_key_rhs]=$temp;
755
756
					$this->_add_many_to_many($additional_values);
757
				}
758
			}
759
            $custom_logic_arguments = array();
760
            $custom_reverse_arguments = array();
761
            $custom_logic_arguments['related_id'] = $key;
762
            $custom_logic_arguments['id'] =  $this->_bean->id;
763
            $custom_reverse_arguments['related_id'] = $this->_bean->id;
764
            $custom_reverse_arguments['id'] = $key;
765
            if($bean_is_lhs) {
766
                $custom_logic_arguments['module'] = $this->_relationship->lhs_module;
767
                $custom_logic_arguments['related_module'] = $this->_relationship->rhs_module;
768
                $custom_reverse_arguments['module'] = $this->_relationship->rhs_module;
769
                $custom_reverse_arguments['related_module'] = $this->_relationship->lhs_module;
770
            } else {
771
                $custom_logic_arguments['related_module'] = $this->_relationship->lhs_module;
772
                $custom_reverse_arguments['related_module'] = $this->_relationship->rhs_module;
773
                $custom_logic_arguments['module'] = $this->_relationship->rhs_module;
774
                $custom_reverse_arguments['module'] = $this->_relationship->lhs_module;
775
            }
776
            /**** CALL IT FROM THE MAIN BEAN FIRST ********/
777
            $this->_bean->call_custom_logic('after_relationship_add', $custom_logic_arguments);
778
            /**** NOW WE HAVE TO CALL THE LOGIC HOOK THE OTHER WAY SINCE IT TAKES TWO FOR A RELATIONSHIP****/
779
            global $beanList;
780
            if ( isset($beanList[$custom_logic_arguments['related_module']]) ) {
781
                $class = $beanList[$custom_logic_arguments['related_module']];
782
                if ( !empty($class) ) {
783
                    $rbean = new $class();
784
                    $rbean->id = $key;
785
                    $rbean->call_custom_logic('after_relationship_add', $custom_reverse_arguments);
786
                }
787
            }
788
		}
789
	}
790
791
	function _add_many_to_many($add_values) {
792
793
		//add date modified.
794
		$add_values['date_modified']=  $GLOBALS['timedate']->nowDb();
795
796
		//check whether duplicate exist or not.
797
		if ($this->relationship_exists($this->_relationship->join_table,$add_values)) {
798
799
/*			switch($this->when_dup_relationship_found) {
800
801
				case 1: //do nothing.
802
					$GLOBALS['log']->debug("Executing default option, no action.");
803
					break;
804
805
				case 3: //delete the record first, then create a new entry.
806
					$this->_delete_row($this->_relationship->join_table,$this->_duplicate_key);
807
					$this->_insert_row($add_values);
808
					break;
809
810
				default:
811
				case 2: //update the record.
812
*/					$this->_update_row($add_values,$this->_relationship->join_table,$this->_duplicate_where);
813
/*					break;
814
			}*/
815
816
		} else {
817
			$this->_insert_row($add_values);
818
		}
819
	}
820
821
	function _delete_row($table_name,$key) {
822
		$query="UPDATE $table_name SET deleted=1, date_modified='" .$GLOBALS['timedate']->nowDb()."' WHERE id='".$this->_db->quote($key)."'";
823
		$GLOBALS['log']->debug("Relationship Delete Statement :".$query);
824
825
		$result=$this->_db->query($query, true);
826
	}
827
828
	function _update_row(&$value_array,$table_name,$where) {
829
830
		$query='UPDATE '.$table_name.' SET ';
831
		$delimiter='';
832
		foreach ($value_array as $key=>$value) {
833
			$query.=$delimiter.$key."='".$this->_db->quote($value)."' ";
834
			$delimiter=",";
835
		}
836
		$query.=$where;
837
		$GLOBALS['log']->debug("Relationship Update Statement :".$query);
838
839
		$result=$this->_db->query($query, true);
840
	}
841
842
	function _insert_row(&$value_array) {
843
		//add key column
844
		$value_array['id']= create_guid();
845
846
		$columns_list='';
847
		$values_list='';
848
		$delimiter='';
849
		foreach ($value_array as $key=>$value) {
850
			$columns_list.=$delimiter.$key;
851
			$values_list .=$delimiter."'".$this->_db->quote($value)."'";
852
			$delimiter=",";
853
		}
854
		$insert_string='INSERT into '.$this->_relationship->join_table.' ('.$columns_list.') VALUES ('.$values_list.')';
855
		$GLOBALS['log']->debug("Relationship Insert String :".$insert_string);
856
857
		$result=$this->_db->query($insert_string, true);
858
	}
859
860
861
862
	/* This method operates on all related record, takes action based on cardinality of the relationship.
863
	 * one-to-one, one-to-many: update the rhs table's parent id with null
864
	 * many-to-one: update the lhs table's parent-id with null.
865
	 * many-to-many: delete rows from the link table. related table must have deleted and date_modified column.
866
	 * If related_id is null, the methods assumes that the parent bean (whose id is passed) is being deleted.
867
	 * If both id and related_id are passed, the method unlinks a single relationship.
868
	 * parameters: id of the bean being deleted.
869
	 *
870
	 */
871
	function delete($id,$related_id='') {
872
		$GLOBALS['log']->debug(sprintf("delete called with these parameter values. id=%s, related_id=%s",$id,$related_id));
873
874
		$_relationship=&$this->_relationship;
875
		$_bean=&$this->_bean;
876
877
		$bean_is_lhs=$this->_get_bean_position();
878
		if (!isset($bean_is_lhs)) {
879
			$GLOBALS['log']->debug("Invalid relationship parameters. Exiting..");
880
			return null;
881
		}
882
	    if ($_relationship->relationship_type=='one-to-many' or $_relationship->relationship_type=='one-to-one' ) {
883
    		if ($bean_is_lhs) {
884
    			//update rhs_table set rhs_key = null, relation_column_name = null where rhs_key= this_bean_id
885
    			$query='UPDATE '.$_relationship->rhs_table.' SET '.$_relationship->rhs_key."=NULL, date_modified='".$GLOBALS['timedate']->nowDb()."'";
886
887
    			if (!empty($_relationship->relationship_role_column) && !empty($_relationship->relationship_role_column_value)) {
888
    				$query.=','.$_relationship->relationship_role_column."= NULL ";
889
    				$query.=' WHERE '.$_relationship->relationship_role_column."= '".$_relationship->relationship_role_column_value."' AND ";
890
    			} else {
891
    				$query.=' WHERE ';
892
    			}
893
    			$query.=$_relationship->rhs_key."= '".$id."' ";
894
895
    			//restrict to one row if related_id is passed.
896
    			if (!empty($related_id)) {
897
    				$query.=" AND ".$_relationship->rhs_table.".id='".$related_id."'";
898
    			}
899
900
    		}
901
    		else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
902
    			//do nothing because the row that stores the relationship keys is being deleted.
903
    			//todo log an error message here.
904
    			//if this is the case and related_id is passed then log a message asking the user
905
    			//to clear the relationship using the bean.
906
    		}
907
	    }
908
909
		if ($_relationship->relationship_type=='many-to-one') {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
910
    		//do nothing because the row that stores the relationship keys is being deleted.
911
			//todo log an error message here.
912
   			//if this is the case and related_id is passed then log a message asking the user
913
   			//to clear the relationship using the bean.
914
		}
915
916
		if ($_relationship->relationship_type=='many-to-many' ) {
917
			$use_bean_is_lhs = isset($_REQUEST['ajaxSubpanel']) || $this->_swap_sides !== true;
918
    		$query='UPDATE '.$_relationship->join_table." SET deleted=1, date_modified='".$GLOBALS['timedate']->nowDb()."'";
919
    		if ($bean_is_lhs && $use_bean_is_lhs) {
920
    			if (!empty($this->_relationship->reverse) && ($this->_relationship->reverse == true or $this->_relationship->reverse == 1)){
921
    				if (empty($related_id)) {
922
    					$query.=" WHERE (".$_relationship->join_key_lhs."= '". $id ."' or ".$_relationship->join_key_rhs."='". $id ."')" ;
923
    				} else {
924
    					$query.=" WHERE (".$_relationship->join_key_lhs."= '". $id ."' AND ".$_relationship->join_key_rhs."='".$related_id."') OR (".$_relationship->join_key_rhs."='". $id ."' AND ".$_relationship->join_key_lhs."='".$related_id."')";
925
    				}
926
    			} else {
927
    				if (empty($related_id)) {
928
    					$query.=" WHERE ".$_relationship->join_key_lhs."= '". $id ."'";
929
    				} else {
930
    					$query.=" WHERE ".$_relationship->join_key_lhs."= '". $id ."' AND ".$_relationship->join_key_rhs."= '". $related_id."'";
931
    				}
932
    			}
933
    		} else {
934
                if (!empty($this->_relationship->reverse) && ($this->_relationship->reverse == true or $this->_relationship->reverse == 1)) {
935
                    if (empty($related_id)) {
936
                        $query.=" WHERE (".$_relationship->join_key_rhs."= '". $id ."' or ".$_relationship->join_key_lhs."='". $id ."')" ;
937
                    } else {
938
                        $query.=" WHERE (".$_relationship->join_key_rhs."= '". $id ."' AND ".$_relationship->join_key_lhs."='".$related_id."') OR (".$_relationship->join_key_lhs."='". $id ."' AND ".$_relationship->join_key_rhs."='".$related_id."')";
939
                    }
940
                } else {
941
                     if (empty($related_id)) {
942
                        $query.=" WHERE ".$_relationship->join_key_rhs."= '". $id ."'" ;
943
                     } else {
944
                        $query.=" WHERE ".$_relationship->join_key_rhs."= '". $id ."' AND ".$_relationship->join_key_lhs."= '". $related_id."'" ;
945
                     }
946
                }
947
    			if (!empty($_relationship->relationship_role_column) && !empty($_relationship->relationship_role_column_value)) {
948
    				$query.=' AND '.$_relationship->relationship_role_column."= '".$_relationship->relationship_role_column_value."'";
949
    			}
950
    		}
951
		}
952
		//if query string is not empty execute it.
953
		if (isset($query)) {
954
            $GLOBALS['log']->fatal('Link.Delete:Delete Query: '.$query);
955
			$this->_db->query($query,true);
956
		}
957
		$custom_logic_arguments = array();
958
		$custom_logic_arguments['id'] = $id;
959
		$custom_logic_arguments['related_id'] = $related_id;
960
		$custom_reverse_arguments = array();
961
		$custom_reverse_arguments['related_id'] = $id;
962
		$custom_reverse_arguments['id'] = $related_id;
963
		if($bean_is_lhs) {
964
			$custom_logic_arguments['module'] = $this->_relationship->lhs_module;
965
			$custom_logic_arguments['related_module'] = $this->_relationship->rhs_module;
966
			$custom_reverse_arguments['module'] = $this->_relationship->lhs_module;
967
			$custom_reverse_arguments['related_module'] = $this->_relationship->rhs_module;
968
		} else {
969
			$custom_logic_arguments['module'] = $this->_relationship->rhs_module;
970
			$custom_logic_arguments['related_module'] = $this->_relationship->lhs_module;
971
			$custom_reverse_arguments['module'] = $this->_relationship->lhs_module;
972
			$custom_reverse_arguments['related_module'] = $this->_relationship->rhs_module;
973
		}
974
975
        if (empty($this->_bean->id)) {
976
            $this->_bean->retrieve($id);//!$bean_is_lhs || empty($related_id) ? $id : $related_id);
977
        }
978
        $this->_bean->call_custom_logic('after_relationship_delete', $custom_logic_arguments);
979
		//NOW THE REVERSE WAY SINCE A RELATIONSHIP TAKES TWO
980
		global $beanList;
981
		if ( isset($beanList[$custom_logic_arguments['related_module']]) ) {
982
            $class = $beanList[$custom_logic_arguments['related_module']];
983
            if ( !empty($class) ) {
984
                $rbean = new $class();
985
                $rbean->retrieve(empty($related_id) ? $id : $related_id);
986
                $rbean->call_custom_logic('after_relationship_delete', $custom_reverse_arguments);
987
            }
988
        }
989
	}
990
991
	function relationship_exists($table_name, $join_key_values) {
992
993
		//find the key values for the table.
994
		$dup_keys=$this->_get_alternate_key_fields($table_name);
995
		if (empty($dup_keys)) {
996
			$GLOBALS['log']->debug("No alternate key define, skipping duplicate check..");
997
			return false;
998
		}
999
1000
		$delimiter='';
1001
		$this->_duplicate_where=' WHERE ';
1002
		foreach ($dup_keys as $field) {
1003
			//look for key in  $join_key_values, if found add to filter criteria else abort duplicate checking.
1004
			if (isset($join_key_values[$field])) {
1005
1006
				$this->_duplicate_where .= $delimiter.' '.$field."='".$join_key_values[$field]."'";
1007
				$delimiter='AND';
1008
			} else {
1009
				$GLOBALS['log']->error('Duplicate checking aborted, Please supply a value for this column '.$field);
1010
				return false;
1011
			}
1012
		}
1013
		//add deleted check.
1014
		$this->_duplicate_where .= $delimiter.' deleted=0';
1015
1016
		$query='SELECT id FROM '.$table_name.$this->_duplicate_where;
1017
1018
		$GLOBALS['log']->debug("relationship_exists query(".$query.')');
1019
1020
		$result=$this->_db->query($query, true);
1021
		$row = $this->_db->fetchByAssoc($result);
1022
1023
		if ($row == null) {
1024
			return false;
1025
		}
1026
		else {
1027
			$this->_duplicate_key=$row['id'];
1028
			return true;
1029
		}
1030
	}
1031
1032
	/* returns array of keys for duplicate checking, first check for an index of type alternate_key, if not found searches for
1033
	 * primary key.
1034
	 *
1035
	 */
1036
	function _get_alternate_key_fields($table_name) {
1037
		$alternateKey=null;
1038
		$indices=Link::_get_link_table_definition($table_name,'indices');
1039
		if (!empty($indices)) {
1040
			foreach ($indices as $index) {
1041
                if ( isset($index['type']) && $index['type'] == 'alternate_key' ) {
1042
                    return $index['fields'];
1043
                }
1044
			}
1045
		}
1046
		$relationships=Link::_get_link_table_definition($table_name,'relationships');
1047
		if (!empty($relationships)) {//bug 32623, when the relationship is built in old version, there is no alternate_key. we have to use join_key_lhs and join_key_lhs.
1048
			if(!empty($relationships[$this->_relationship_name]) && !empty($relationships[$this->_relationship_name]['join_key_lhs']) && !empty($relationships[$this->_relationship_name]['join_key_rhs'])) {
1049
				return array($relationships[$this->_relationship_name]['join_key_lhs'], $relationships[$this->_relationship_name]['join_key_rhs']);
1050
			}
1051
		}
1052
	}
1053
1054
	/*
1055
	 */
1056
	function _get_link_table_definition($table_name,$def_name) {
1057
	    global $dictionary;
1058
1059
		include_once('modules/TableDictionary.php');
1060
	    // first check to see if already loaded - assumes hasn't changed in the meantime
1061
        if (isset($dictionary[$table_name][$def_name]))
1062
        {
1063
            return $dictionary[$table_name][$def_name];
1064
        }
1065
        else {
1066
 			if (isset($dictionary[$this->_relationship_name][$def_name])) {
1067
 				return ($dictionary[$this->_relationship_name][$def_name]);
1068
 			}
1069
            // custom metadata is found in custom/metadata (naturally) and the naming follows the convention $relationship_name_c, and $relationship_name = $table_name$locations = array( 'metadata/' , 'custom/metadata/' ) ;
1070
            $relationshipName = preg_replace( '/_c$/' , '' , $table_name ) ;
1071
1072
            $locations = array ( 'metadata/' , 'custom/metadata/' ) ;
1073
1074
            foreach ( $locations as $basepath )
1075
            {
1076
                $path = $basepath . $relationshipName . 'MetaData.php' ;
1077
1078
                if (file_exists($path))
1079
                {
1080
                    include($path);
1081
                    if (isset($dictionary[$relationshipName][$def_name])) {
1082
                        return $dictionary[$relationshipName][$def_name];
1083
                    }
1084
                }
1085
            }
1086
            // couldn't find the metadata for the table in either the standard or custom locations
1087
            $GLOBALS['log']->debug('Error fetching field defs for join table '.$table_name);
1088
1089
            return null;
1090
        }
1091
1092
1093
1094
	}
1095
    /*
1096
     * Return the name of the role field for the passed many to many table.
1097
     * if there is no role filed : return false
1098
     */
1099
    function _get_link_table_role_field($table_name) {
1100
        $varDefs = $this->_get_link_table_definition($table_name, 'fields');
1101
        $role_field = false;
1102
        if(!empty($varDefs)){
1103
            $role_field = '';
1104
            foreach($varDefs as $v){
1105
                if(strpos($v['name'], '_role') !== false){
1106
                    $role_field = $v['name'];
1107
                }
1108
            }
1109
        }
1110
        return $role_field;
1111
    }
1112
1113
1114
}
1115
?>
1116