PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/Relationships/RelationshipHandler.php

https://bitbucket.org/allexblacker/suitecrm
PHP | 435 lines | 205 code | 120 blank | 110 comment | 47 complexity | 768709f7701aacf346debdd94315206c MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.1
  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. * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
  7. * Copyright (C) 2011 - 2014 Salesagility Ltd.
  8. *
  9. * This program is free software; you can redistribute it and/or modify it under
  10. * the terms of the GNU Affero General Public License version 3 as published by the
  11. * Free Software Foundation with the addition of the following permission added
  12. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  13. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  14. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  15. *
  16. * This program is distributed in the hope that it will be useful, but WITHOUT
  17. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  18. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  19. * details.
  20. *
  21. * You should have received a copy of the GNU Affero General Public License along with
  22. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  23. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  24. * 02110-1301 USA.
  25. *
  26. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  27. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  28. *
  29. * The interactive user interfaces in modified source and object code versions
  30. * of this program must display Appropriate Legal Notices, as required under
  31. * Section 5 of the GNU Affero General Public License version 3.
  32. *
  33. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  34. * these Appropriate Legal Notices must retain the display of the "Powered by
  35. * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
  36. * reasonably feasible for technical reasons, the Appropriate Legal Notices must
  37. * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM".
  38. ********************************************************************************/
  39. class RelationshipHandler extends Relationship {
  40. var $db; //Database link by reference
  41. var $base_module; //name of module
  42. var $base_bean; //actual object
  43. var $base_vardef_field; //base's vardef field name of relationship with rel1
  44. var $rel1_module; //name of related module
  45. var $rel1_bean; //actual related object
  46. var $rel1_relationship_name; //Relationship name between base and rel1
  47. var $rel1_vardef_field; //rel1's vardef field name of relationship with rel2
  48. var $rel1_vardef_field_base; //rel1's vardef field name of relationship with base
  49. var $rel2_module; //name of related related module
  50. var $rel2_bean; //actual related related object
  51. var $rel2_relationship_name; //Relationship name between rel1 and rel2
  52. var $rel2_vardef_field; //rel2's vardef field name of relationship with rel1
  53. var $base_array; //Info array
  54. var $rel1_array; //Info array
  55. var $rel2_array; //Info array
  56. /*
  57. info arrays contain:
  58. 'slabel' -> singular module name in correct language
  59. 'plabel' -> plural module name in correct language
  60. */
  61. ///////////////////////////Setup and populate functions//////////////////////////////
  62. function __construct(& $db, $base_module=""){
  63. $this->db = $db;
  64. $this->base_module = $base_module;
  65. //end function RelationshipHandler
  66. }
  67. /**
  68. * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
  69. */
  70. function RelationshipHandler(& $db, $base_module=""){
  71. $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
  72. if(isset($GLOBALS['log'])) {
  73. $GLOBALS['log']->deprecated($deprecatedMessage);
  74. }
  75. else {
  76. trigger_error($deprecatedMessage, E_USER_DEPRECATED);
  77. }
  78. self::__construct( $db, $base_module);
  79. }
  80. function set_rel_vardef_fields($base_vardef_field, $rel1_vardef_field=""){
  81. $this->base_vardef_field = $base_vardef_field;
  82. $this->rel1_vardef_field = $rel1_vardef_field;
  83. //end function set_rel_vardef_fields
  84. }
  85. function set_rel_relationship_names($build_rel2=false){
  86. $this->rel1_relationship_name = $this->base_bean->field_defs[$this->base_vardef_field]['relationship'];
  87. if($build_rel2==true){
  88. $this->rel2_relationship_name = $this->rel1_bean->field_defs[$this->rel1_vardef_field]['relationship'];
  89. }
  90. //end function set_rel_relationship_names
  91. }
  92. ///////////////////////////////END Setup and populate functions/////////////////////
  93. /*
  94. set the build_rel2 to true if you want the rel2 info array as well
  95. This function will build all the relationship info it can based on values set in the setup functions
  96. When you use the info arrays (rel1_array) or (rel2_array), make sure you always check for empty values
  97. */
  98. function build_info($build_rel2=false){
  99. if($this->base_bean == null){
  100. $this->base_bean = get_module_info($this->base_module);
  101. }
  102. if(empty($this->rel1_bean)){
  103. $this->build_rel1_info();
  104. $this->rel1_module = $this->rel1_bean->module_dir;
  105. }
  106. if($build_rel2==true && $this->rel2_bean==""){
  107. $this->build_rel2_info();
  108. $this->rel2_module = $this->rel2_bean->module_dir;
  109. }
  110. //translate the module titles to the proper language
  111. $this->build_module_labels($build_rel2);
  112. //end function build_info
  113. }
  114. function build_rel1_info(){
  115. $this->rel1_bean = $this->trace_relationship_module($this->base_module, $this->base_vardef_field);
  116. //end function build_rel1_info
  117. }
  118. function build_rel2_info(){
  119. $this->rel2_bean = $this->trace_relationship_module($this->base_module, $this->base_vardef_field, $this->rel1_vardef_field);
  120. //end function build_rel1_info
  121. }
  122. /*
  123. Translates the module names to their singular and plural label and puts them in
  124. the info arrays. Does it for base, rel1, and rel2 if specified
  125. */
  126. function build_module_labels($build_rel2=false){
  127. global $app_list_strings;
  128. ///Base Module Labels
  129. if(!empty($app_list_strings['moduleList'][$this->base_bean->module_dir])){
  130. $this->base_array['plabel'] = $app_list_strings['moduleList'][$this->base_bean->module_dir];
  131. } else {
  132. $this->base_array['plabel'] = $this->base_bean->module_dir;
  133. }
  134. if(!empty($app_list_strings['moduleListSingular'][$this->base_bean->module_dir])){
  135. $this->base_array['slabel'] = $app_list_strings['moduleListSingular'][$this->base_bean->module_dir];
  136. } else {
  137. $this->base_array['slabel'] = $this->base_bean->object_name;
  138. }
  139. ///Rel1 Module Labels
  140. if(!empty($app_list_strings['moduleList'][$this->rel1_bean->module_dir])){
  141. $this->rel1_array['plabel'] = $app_list_strings['moduleList'][$this->rel1_bean->module_dir];
  142. } else {
  143. $this->rel1_array['plabel'] = $this->rel1_bean->module_dir;
  144. }
  145. if(!empty($app_list_strings['moduleListSingular'][$this->rel1_bean->module_dir])){
  146. $this->rel1_array['slabel'] = $app_list_strings['moduleListSingular'][$this->rel1_bean->module_dir];
  147. } else {
  148. $this->rel1_array['slabel'] = $this->rel1_bean->object_name;
  149. }
  150. //Rel2 Module Labels
  151. if($build_rel2==true){
  152. if(!empty($app_list_strings['moduleList'][$this->rel2_bean->module_dir])){
  153. $this->rel2_array['plabel'] = $app_list_strings['moduleList'][$this->rel2_bean->module_dir];
  154. } else {
  155. $this->rel2_array['plabel'] = $this->rel2_bean->module_dir;
  156. }
  157. if(!empty($app_list_strings['moduleListSingular'][$this->rel2_bean->module_dir])){
  158. $this->rel2_array['slabel'] = $app_list_strings['moduleListSingular'][$this->rel2_bean->module_dir];
  159. } else {
  160. $this->rel2_array['slabel'] = $this->rel2_bean->module_dir;
  161. }
  162. //end if build_rel2 is true
  163. }
  164. //end function buld_module_lables
  165. }
  166. function build_related_list($type="base"){
  167. //type can be base, rel1
  168. $target_list = "";
  169. if($type=="base"){
  170. $target_list = $this->base_bean->get_linked_beans($this->base_vardef_field, $this->rel1_bean->object_name);
  171. //Possibility exists that this is a new relationship, so capture via relationship fields
  172. if(empty($target_list)){
  173. $target_list = search_filter_rel_info($this->base_bean, $this->rel1_bean->module_dir, $this->base_vardef_field);
  174. //end if the target list is empty
  175. }
  176. }
  177. if($type=="rel1"){
  178. $target_list = $this->rel1_bean->get_linked_beans($this->rel1_vardef_field, $this->rel2_bean->object_name);
  179. //Possibility exists that this is a new relationship, so capture via relationship fields
  180. if(empty($target_list)){
  181. $target_list = search_filter_rel_info($this->rel1_bean, $this->rel2_bean->module_dir, $this->rel1_vardef_field);
  182. //end if the target list is empty
  183. }
  184. }
  185. return $target_list;
  186. //end function build_related_list
  187. }
  188. ///////BEGIN Functions to find relationships/////////////////////////////////
  189. function get_relationship_information(& $target_bean, $get_upstream_rel_field_name = false){
  190. $target_module_name = $target_bean->module_dir;
  191. $current_module_name = $this->base_module;
  192. //Look for downstream connection
  193. $rel_array = $this->retrieve_by_sides($current_module_name, $target_module_name, $this->db);
  194. //Does a downstream relationship exist
  195. if($rel_array!=null){
  196. if($rel_array['relationship_type']=="many-to-many"){
  197. $joinKeyLHS = $rel_array['join_key_lhs'];
  198. $target_bean->$joinKeyLHS = $this->base_bean->id;
  199. if($rel_array['relationship_role_column']!=""){
  200. $relRole = $rel_array['relationship_role_column'];
  201. $target_bean->$relRole = $rel_array['relationship_role_column_value'];
  202. }
  203. //end if many-to-many
  204. }
  205. if($rel_array['relationship_type']=="one-to-many"){
  206. $RHSKey = $rel_array['rhs_key'];
  207. $target_bean->$RHSKey = $this->base_bean->id;
  208. if($rel_array['relationship_role_column']!=""){
  209. $relRole = $rel_array['relationship_role_column'];
  210. $target_bean->$relRole = $rel_array['relationship_role_column_value'];
  211. }
  212. //end if one-to-many
  213. }
  214. return;
  215. //end if downstream relationship exists
  216. }
  217. //Look for upstream connection
  218. $rel_array = $this->retrieve_by_sides($target_module_name, $current_module_name, $this->db);
  219. //Does an upstream relationship exist
  220. if($rel_array!=null){
  221. if($rel_array['relationship_type']=="many-to-many"){
  222. $joinKeyRHS = $rel_array['join_key_rhs'];
  223. $target_bean->$joinKeyRHS = $this->base_bean->id;
  224. if($rel_array['relationship_role_column']!=""){
  225. $relRole = $rel_array['relationship_role_column'];
  226. $target_bean->$relRole = $rel_array['relationship_role_column_value'];
  227. }
  228. //end if many-to-many
  229. }
  230. if($rel_array['relationship_type']=="one-to-many"){
  231. $RHSKey = $rel_array['rhs_key'];
  232. $target_bean->$RHSKey = $this->base_bean->id;
  233. if($rel_array['relationship_role_column']!=""){
  234. $relRole = $rel_array['relationship_role_column'];
  235. $target_bean->$relRole = $rel_array['relationship_role_column_value'];
  236. }
  237. //end if one-to-many
  238. }
  239. ///Fill additional id field if necessary
  240. if(($id_name = $this->traverse_rel_meta($current_module_name, $target_bean, $rel_array['relationship_name'])) != null){
  241. $target_bean->$id_name = $this->base_bean->id;
  242. if($get_upstream_rel_field_name) {
  243. $target_bean->new_rel_relname = $id_name;
  244. $target_bean->new_rel_id = $this->base_bean->id;
  245. }
  246. }
  247. //end if an upstream relationship exists
  248. }
  249. //end function get_relationship_information
  250. }
  251. function traverse_rel_meta($base_module, & $target_bean, $target_rel_name){
  252. $id_name = null;
  253. //returns name of variable to store id in
  254. //if none exists, then returns null
  255. foreach($target_bean->field_defs as $field_array){
  256. if(!empty($field_array['relationship']) && $field_array['relationship']==$target_rel_name){
  257. $id_name = $this->get_id_name($target_bean, $field_array['name']);
  258. return $id_name;
  259. //end if rel name match
  260. }
  261. //end foreach field def
  262. }
  263. return null;
  264. //end function traverse_rel_meta
  265. }
  266. function get_id_name(& $target_bean, $field_name){
  267. foreach($target_bean->relationship_fields as $target_id => $rel_name){
  268. if($rel_name == $field_name){
  269. //relationship id found
  270. return $target_id;
  271. //end if match
  272. }
  273. //end foreach
  274. }
  275. return null;
  276. //end function get_id_name
  277. }
  278. ///////////////////////////END functions to find relationships //////////////////////
  279. function process_by_rel_bean($rel1_module){
  280. $this->rel1_relationship_name = $this::retrieve_by_modules($this->base_module, $rel1_module, $this->db);
  281. $this->rel1_module = $rel1_module;
  282. $this->rel1_bean = get_module_info($this->rel1_module);
  283. //end function process_by_rel_bean
  284. }
  285. function get_rel1_vardef_field_base($field_defs){
  286. foreach($field_defs as $field_array){
  287. if(!empty($field_array['relationship']) && $field_array['relationship']==$this->rel1_relationship_name){
  288. $this->rel1_vardef_field_base = $field_array['name'];
  289. //end if rel name match
  290. }
  291. //end foreach field def
  292. }
  293. return null;
  294. //end get_rel1_vardef_field_base
  295. }
  296. function get_farthest_reach(){
  297. if($this->rel1_vardef_field!=""){
  298. //the farthest reach is rel2
  299. $this->build_info(true);
  300. return $this->rel2_bean;
  301. }
  302. //the farthest reach is rel1
  303. $this->build_info(false);
  304. return $this->rel1_bean;
  305. //end function get_farthest_reach
  306. }
  307. //end class RelationshipHandler
  308. }
  309. ?>