abstractrelationship.php
来自「SugarCRM5.1 开源PHP客户关系管理系统」· PHP 代码 · 共 494 行 · 第 1/2 页
PHP
494 行
<?phpif(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');/********************************************************************************* * SugarCRM is a customer relationship management program developed by * SugarCRM, Inc. Copyright (C) 2004 - 2007 SugarCRM Inc. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 3 as published by the * Free Software Foundation with the addition of the following permission added * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see http://www.gnu.org/licenses or write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU General Public License version 3. * * In accordance with Section 7(b) of the GNU General Public License version 3, * these Appropriate Legal Notices must retain the display of the "Powered by * SugarCRM" logo. If the display of the logo is not reasonably feasible for * technical reasons, the Appropriate Legal Notices must display the words * "Powered by SugarCRM". *********************************************************************************//* * A mechanism to dynamically define new Relationships between modules * This differs from the classes in modules/Relationships and data/Link in that they contain the implementation for pre-defined Relationships * Those classes use the metadata in the dictionary and layout definitions to implement the relationships; this class allows you to manage and manipulate that metadata */class AbstractRelationship{ protected $definition ; // enough information to rebuild this relationship /* * These are the elements that fully define any Relationship * Any subclass of AbstractRelationship uses an array with a subset of the following keys as metadata to describe the Relationship it will implement * The base set of keys are those used in the Relationships table * Defined as Public as MBRelationship uses these to read the _POST data */ public static $definitionKeys = array ( // atttributes of this relationship - here in the definition so they are preserved across saves and loads 'readonly' , // a readonly relationship cannot be Built by subclasses of AbstractRelationships 'deleted' , // a deleted relationship will not be built, and if it had been built previously the built relationship will be removed 'relationship_only' , // means that we won't build any UI components for this relationship - required while the Subpanel code is restricted to one subpanel only from any module, and probably useful afterwards also for developers to build relationships for new code - it's a feature! // keys not found in Relationships table 'label' , // optional 'lhs_subpanel' , // subpanel FROM the lhs_module to display on the rhs_module detail view 'rhs_subpanel' , // subpanel FROM the rhs_module to display on the lhs_module detail view // keys from Relationships table 'relationship_name' , 'lhs_module' , 'lhs_table' , 'lhs_key' , 'rhs_module' , 'rhs_table' , 'rhs_key' , 'join_table' , 'join_key_lhs' , 'join_key_rhs' , 'relationship_type' , 'relationship_role_column' , 'relationship_role_column_value' , 'reverse' ) ; /* * Relationship_role_column and relationship_role_column_value: * These two values define an additional condition on the relationship. If present, the value in relationship_role_column in the relationship table must equal relationship_role_column_value * Any update to the relationship made using a link field tied to the relationship (as is proper) will automatically (in Link.php) add in the relationship_role_column_value * The relationship table must of course contain a column with the name given in relationship_role_column * * relationship_role_column and relationship_role_column_value are here implemented in a slightly less optimized form than in the standard OOB application * In the OOB application, multiple relationships can, and do, share the same relationship table. Therefore, each variant of the relationship does not require its own table * Here for simplicity in implementation each relationship has its own unique table. Therefore, the relationship_role_column in these tables will only contain the value relationship_role_column_value * In the OOB relationships, the relationship_role_column will contain any of the relationship_role_column_values from the relationships that share the table * TODO: implement this optimization * */ /* * Constructor * @param string $definition Definition array for this relationship. Parameters are given in self::keys */ function __construct ($definition) { // set any undefined attributes to the default value foreach ( array ( 'readonly' , 'deleted' , 'relationship_only' ) as $key ) if (! isset ( $definition [ $key ] )) $definition [ $key ] = false ; foreach ( self::$definitionKeys as $key ) { $this->$key = isset ( $definition [ $key ] ) ? $definition [ $key ] : '' ; } $this->definition = $definition ; } /* * Get the unique name of this relationship * @return string The unique name (actually just that given to the constructor) */ public function getName () { return isset ( $this->definition [ 'relationship_name' ] ) ? $this->definition [ 'relationship_name' ] : null ; } public function setName ($relationshipName) { $this->relationship_name = $this->definition [ 'relationship_name' ] = $relationshipName ; } /* * Is this relationship readonly or not? * @return boolean True if cannot be changed; false otherwise */ public function readonly () { return $this->definition [ 'readonly' ] ; } public function setReadonly () { $this->readonly = $this->definition [ 'readonly' ] = true ; } /* * Has this relationship been deleted? A deleted relationship does not get built, and is no longer visible in the list of relationships * @return boolean True if it has been deleted; false otherwise */ public function deleted () { return $this->definition [ 'deleted' ] ; } public function delete () { $this->deleted = $this->definition [ 'deleted' ] = true ; } public function getType () { return $this->relationship_type ; } public function relationship_only () { return $this->definition [ 'relationship_only' ] ; } public function setRelationship_only () { $this->relationship_only = $this->definition [ 'relationship_only' ] = true ; } /* * Get a complete description of this relationship, sufficient to pass back to a constructor to reestablish the relationship * Each subclass must provide enough information in $this->definition for its constructor * Used by UndeployedRelationships to save out a set of AbstractRelationship descriptions * The format is the same as the schema for the Relationships table for convenience, and is defined in self::keys. That is, * `relationship_name`, `lhs_module`, `lhs_table`, `lhs_key`, `rhs_module`, `rhs_table`,`rhs_key`, `join_table`, `join_key_lhs`, `join_key_rhs`, `relationship_type`, `relationship_role_column`, `relationship_role_column_value`, `reverse`, * @return array Set of parameters to pass to an AbstractRelationship constructor - must contain at least ['relationship_type']='OneToOne' or 'OneToMany' or 'ManyToMany' */ function getDefinition () { return $this->definition ; } /* * BUILD methods called during the build */ /* * Define the labels to be added to the module for the new relationships * @return array An array of system value => display value */ function buildLabels () { $labelDefinitions = array ( ) ; if (!$this->relationship_only) { $labelDefinitions [] = array ( 'module' => $this->rhs_module , 'system_label' => 'LBL_' . strtoupper ( $this->relationship_name . '_FROM_' . $this->lhs_module ) . '_TITLE' , 'display_label' => /*'*' .*/ ucfirst ( $this->lhs_module ) ) ; $labelDefinitions [] = array ( 'module' => $this->lhs_module , 'system_label' => 'LBL_' . strtoupper ( $this->relationship_name . '_FROM_' . $this->rhs_module ) . '_TITLE' , 'display_label' => /*'*' .*/ ucfirst ( $this->rhs_module ) ) ; } return $labelDefinitions ; } /* * GET methods called by the BUILD methods of the subclasses to construct the relationship metadata */ /* * Build a description of a Subpanel that can be turned into an actual Subpanel by saveSubpanelDefinition in the implementation * Note that we assume that the subpanel name we are given is valid - that is, a subpanel definition by that name exists, and that a module won't have attempt to define multiple subpanels with the same name * Among the elements we construct is get_subpanel_data which is used as follows in SugarBean: * $related_field_name = $this_subpanel->get_data_source_name(); * $parentbean->load_relationship($related_field_name); * @param string $sourceModule Name of the source module for this field * @param string $relationshipName Name of the relationship * @param string $subpanelName Name of the subpanel provided by the sourceModule */ protected function getSubpanelDefinition ($relationshipName , $sourceModule , $subpanelName) { $subpanelDefinition = array ( ) ; $subpanelDefinition [ 'order' ] = 100 ; $subpanelDefinition [ 'module' ] = $sourceModule ; $subpanelDefinition [ 'subpanel_name' ] = $subpanelName ; $subpanelDefinition [ 'title_key' ] = 'LBL_' . strtoupper ( $relationshipName . '_FROM_' . $sourceModule ) . '_TITLE' ; $subpanelDefinition [ 'get_subpanel_data' ] = $relationshipName ; // name of the RELATIONSHIP AND OF THE LINK field- see SugarBean->get_union_related_list() which calls loadRelationship(); // add_subpanel_data appears now to be deprecated// $relationshipMetaData = $this->getRelationshipMetaData ( MB_MANYTOMANY ) ;// $properties = $relationshipMetaData [ 'relationships' ] [ $relationshipName ] ; // $subpanelDefinition [ 'add_subpanel_data' ] = ($sourceModule == $properties [ 'lhs_module' ]) ? $properties [ 'join_key_lhs' ] : $properties [ 'join_key_rhs' ] ; // name of the join_key_ in the relationship definition for the module that is the SOURCE of the subpanel return array ( $subpanelDefinition ); } /* * Construct a link field for the vardefs for use in Subpanels * The link fields are the mechanism by which the subpanel accesses the relationship data * The subpanel code seems to require that the name of this linkfield matches the name of the relationship for get_subpanel_data to work correctly * @param string $sourceModule Name of the source module for this field * @param string $relationshipName Name of the relationship */ protected function getLinkFieldDefinition ($sourceModule , $relationshipName) { $vardef = array ( ) ; $vardef [ 'name' ] = $relationshipName ; // must match relationshipName for subpanel get_subpanel_data to work $vardef [ 'type' ] = 'link' ; $vardef [ 'relationship' ] = $relationshipName ; $vardef [ 'source' ] = 'non-db' ;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?