adamjakab /
SuiteCRM
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | 1 | 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 __construct($_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
|
|||
| 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 { |
||
| 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') { |
||
| 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 | 1 | function _get_link_table_definition($table_name,$def_name) { |
|
| 1056 | 1 | global $dictionary; |
|
| 1057 | |||
| 1058 | /* |
||
| 1059 | * If this method is called statically will throw FATAL error on php7 because of the $this usage |
||
| 1060 | */ |
||
| 1061 | 1 | $staticContext = !isset($this); |
|
| 1062 | 1 | if($staticContext) { |
|
| 1063 | 1 | return null; |
|
| 1064 | } |
||
| 1065 | |||
| 1066 | include_once('modules/TableDictionary.php'); |
||
| 1067 | // first check to see if already loaded - assumes hasn't changed in the meantime |
||
| 1068 | if (isset($dictionary[$table_name][$def_name])) |
||
| 1069 | { |
||
| 1070 | return $dictionary[$table_name][$def_name]; |
||
| 1071 | } |
||
| 1072 | else { |
||
| 1073 | if (isset($dictionary[$this->_relationship_name][$def_name])) { |
||
| 1074 | return ($dictionary[$this->_relationship_name][$def_name]); |
||
| 1075 | } |
||
| 1076 | // 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/' ) ; |
||
| 1077 | $relationshipName = preg_replace( '/_c$/' , '' , $table_name ) ; |
||
| 1078 | |||
| 1079 | $locations = array ( 'metadata/' , 'custom/metadata/' ) ; |
||
| 1080 | |||
| 1081 | foreach ( $locations as $basepath ) |
||
| 1082 | { |
||
| 1083 | $path = $basepath . $relationshipName . 'MetaData.php' ; |
||
| 1084 | |||
| 1085 | if (file_exists($path)) |
||
| 1086 | { |
||
| 1087 | include($path); |
||
| 1088 | if (isset($dictionary[$relationshipName][$def_name])) { |
||
| 1089 | return $dictionary[$relationshipName][$def_name]; |
||
| 1090 | } |
||
| 1091 | } |
||
| 1092 | } |
||
| 1093 | // couldn't find the metadata for the table in either the standard or custom locations |
||
| 1094 | $GLOBALS['log']->debug('Error fetching field defs for join table '.$table_name); |
||
| 1095 | |||
| 1096 | return null; |
||
| 1097 | } |
||
| 1098 | |||
| 1099 | |||
| 1100 | |||
| 1101 | } |
||
| 1102 | /* |
||
| 1103 | * Return the name of the role field for the passed many to many table. |
||
| 1104 | * if there is no role filed : return false |
||
| 1105 | */ |
||
| 1106 | function _get_link_table_role_field($table_name) { |
||
| 1107 | $varDefs = $this->_get_link_table_definition($table_name, 'fields'); |
||
| 1108 | $role_field = false; |
||
| 1109 | if(!empty($varDefs)){ |
||
| 1110 | $role_field = ''; |
||
| 1111 | foreach($varDefs as $v){ |
||
| 1112 | if(strpos($v['name'], '_role') !== false){ |
||
| 1113 | $role_field = $v['name']; |
||
| 1114 | } |
||
| 1115 | } |
||
| 1116 | } |
||
| 1117 | return $role_field; |
||
| 1118 | } |
||
| 1119 | |||
| 1120 | |||
| 1121 | } |
||
| 1122 | ?> |
||
| 1123 |
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.