abstractrelationship.php

来自「SugarCRM5.1 开源PHP客户关系管理系统」· PHP 代码 · 共 494 行 · 第 1/2 页

PHP
494
字号
        return $vardef ;    }           /*     * Construct a second link id field for the relationship for use in Views     * It is used in two places:     * 1. During display of a detail or edit view:     *    - the editview.tpl for Relate fields requires that a field with the same name as the relate field's id_name exists     *    - it is loaded in SugarBean->fill_in_link_field while SugarBean processes the relate fields in fill_in_relationship_fields     * 2. During the save from an edit view:     *    - SugarBean->save_relationship_changes() relies on this link field to save the relate field changes     * @param string $sourceModule      Name of the source module for this field     * @param string $relationshipName  Name of the relationship     */    protected function getDummyFieldDefinition ($sourceModule , $relationshipName)    {        $vardef = array ( ) ;        $relationshipMetaData = $this->getRelationshipMetaData ( MB_MANYTOMANY ) ;        $properties = $relationshipMetaData [ 'relationships' ] [ $relationshipName ] ;        $vardef [ 'name' ] = ($sourceModule == $properties [ 'lhs_module' ]) ? $properties [ 'join_key_lhs' ] : $properties [ 'join_key_rhs' ] ; // must match the id_name field value in the relate field definition        $vardef [ 'type' ] = 'link' ;        $vardef [ 'relationship' ] = $relationshipName ;        $vardef [ 'source' ] = 'non-db' ;        return $vardef ;    }    /*     * Construct a relate field for the vardefs     * The relate field is the element that is shown in the UI     * @param string $sourceModule      Name of the source module for this field     * @param string $relationshipName  Name of the relationship     * @param string $moduleType        Optional - "Types" of the module - array of SugarObject types such as "file" or "basic"     */    protected function getRelateFieldDefinition ($sourceModule , $relationshipName , $moduleTypes = null )    {                   $vardef = array ( ) ;        $vardef [ 'name' ] = $relationshipName . "_name" ;        $vardef [ 'type' ] = 'relate' ;        $vardef [ 'link' ] = $relationshipName ; // the name of the link field that points to the relationship        $vardef [ 'source' ] = 'non-db' ;        $vardef [ 'vname' ] = 'LBL_' . strtoupper ( $relationshipName . '_FROM_' . $sourceModule ) . '_TITLE' ;        $vardef [ 'save' ] = true; // the magic value to tell SugarBean to save this relate field even though it is not listed in the $relationship_fields array                $relationshipMetaData = $this->getRelationshipMetaData ( MB_MANYTOMANY ) ;        $properties = $relationshipMetaData [ 'relationships' ] [ $relationshipName ] ;                // id_name matches the join_key_ column in the relationship table for the sourceModule - that is, the column in the relationship table containing the id of the corresponding field in the source module's table (vardef['table'])        $vardef [ 'id_name' ] = ($sourceModule == $properties [ 'lhs_module' ]) ? $properties [ 'join_key_lhs' ] : $properties [ 'join_key_rhs' ] ;        $vardef [ 'table' ] = ($sourceModule == $properties [ 'lhs_module' ]) ? $properties [ 'lhs_table' ] : $properties [ 'rhs_table' ] ;        $vardef [ 'module' ] = $sourceModule ;        //$vardef [ 'join_name' ] = $properties [ 'join_table' ] ; // this is used in SugarBean->create_new_list_query() as the name of the join_table_alias and defaults to jt.<count> - the default is fine; only might specify if doing multiple joins on the same table; most uses in the vardefs are mistaken                // for custom modules of type 'file'; here we must test for the type rather than the name as of course a custom module can take any name...        if ( ! is_null ($moduleTypes) && is_array( $moduleTypes ) && in_array( 'file' , $moduleTypes ) )        {            $vardef [ 'rname' ] = 'document_name' ;        }        else            switch ( strtolower( $sourceModule ) )            {                case 'prospects' :                    $vardef [ 'rname' ] = 'account_name' ;                    break ;                case 'documents' :                    $vardef [ 'rname' ] = 'document_name' ;                    break ;                case 'kbdocuments' :                    $vardef [ 'rname' ] = 'kbdocument_name' ;                    break ;                case 'leads' :                case 'contacts' :                     // special handling as these modules lack a name column in the database; instead 'name' refers to a non-db field that concatenates first_name and last_name                    // luckily, the relate field mechanism can handle this with an equivalent additional db_concat_fields entry                    $vardef [ 'rname' ] = 'last_name' ;                    $vardef [ 'db_concat_fields' ] = array( 0 =>'first_name', 1 =>'last_name') ;                    break ;                default :                   // OOB modules: accounts, bugs, calls, campaigns, cases, contracts, emails, meetings, notes, opportunities, products, product_templates, project, project_task, quotes, schedulers, tasks                   // custom modules: basic, chance, company, issue, person                   $vardef [ 'rname' ] = 'name' ;             }                        return $vardef ;    }    /*     * Construct the contents of the Relationships MetaData entry in the dictionary for a generic relationship     * The entry we build will have three sections:     * 1. relationships: the relationship definition     * 2. table: name of the join table for this many-to-many relationship     * 3. fields: fields within the join table     * 4. indicies: indicies on the join table     * @param string $relationshipType  Cardinality of the relationship, for example, MB_ONETOONE or MB_ONETOMANY or MB_MANYTOMANY     */    function getRelationshipMetaData ($relationshipType)    {        $relationshipName = $this->definition [ 'relationship_name' ] ;        $lhs_module = $this->definition [ 'lhs_module' ] ;        $rhs_module = $this->definition [ 'rhs_module' ] ;                $lhs_table = $this->getTablename ( $lhs_module ) ;        $rhs_table = $this->getTablename ( $rhs_module ) ;                $properties = array ( ) ;                // first define section 1, the relationship element of the metadata entry                $rel_properties = array ( ) ;        $rel_properties [ 'lhs_module' ] = $lhs_module ;        $rel_properties [ 'lhs_table' ] = $lhs_table ;        $rel_properties [ 'lhs_key' ] = 'id' ;        $rel_properties [ 'rhs_module' ] = $rhs_module ;        $rel_properties [ 'rhs_table' ] = $rhs_table ;        $rel_properties [ 'rhs_key' ] = 'id' ;                $rel_properties [ 'relationship_type' ] = MB_MANYTOMANY ; // for now set this type to many-to-many regardless of the real type - enforce cardinality through the relate fields and subpanels        $rel_properties [ 'join_table' ] = $this->getValidColumnName ( $relationshipName ) ;        // a and b are in case the module relates to itself        $rel_properties [ 'join_key_lhs' ] = $this->getValidColumnName ( $lhs_module ) . "_ida" ;        $rel_properties [ 'join_key_rhs' ] = $this->getValidColumnName ( $rhs_module ) . "_idb" ;        // set the extended properties if they exist = for now, many-to-many definitions do not have to contain a role_column even if role_column_value is set; we'll just create a likely name if missing        if (isset ( $this->definition [ 'relationship_role_column_value' ] ))        {            if (! isset ( $this->definition [ 'relationship_role_column' ] ))                $this->definition [ 'relationship_role_column' ] = 'relationship_role_column' ;            $rel_properties [ 'relationship_role_column' ] = $this->definition [ 'relationship_role_column' ] ;            $rel_properties [ 'relationship_role_column_value' ] = $this->definition [ 'relationship_role_column_value' ] ;        }                $properties [ 'relationships' ] [ $relationshipName ] = $rel_properties ;                // construct section 2, the name of the join table                $properties [ 'table' ] = $rel_properties [ 'join_table' ] ;                // now construct section 3, the fields in the join table                $properties [ 'fields' ] [] = array ( 'name' => 'id' , 'type' => 'varchar' , 'len' => 36 ) ;        $properties [ 'fields' ] [] = array ( 'name' => 'date_modified' , 'type' => 'datetime' ) ;        $properties [ 'fields' ] [] = array ( 'name' => 'deleted' , 'type' => 'bool' , 'len' => '1' , 'default' => '0' , 'required' => true ) ;        $properties [ 'fields' ] [] = array ( 'name' => $rel_properties [ 'join_key_lhs' ] , 'type' => 'varchar' , 'len' => 36 ) ;        $properties [ 'fields' ] [] = array ( 'name' => $rel_properties [ 'join_key_rhs' ] , 'type' => 'varchar' , 'len' => 36 ) ;        if (strtolower ( $rhs_module ) == 'documents')        {            $properties [ 'fields' ] [] = array ( 'name' => 'document_revision_id' , 'type' => 'varchar' , 'len' => '36' ) ;        }        // if we have an extended relationship condition, then add in the corresponding relationship_role_column to the relationship (join) table        // for now this is restricted to extended relationships that can be specified by a varchar        if (isset ( $this->definition [ 'relationship_role_column_value' ] ))        {            $properties [ 'fields' ] [] = array ( 'name' => $this->definition [ 'relationship_role_column' ] , 'type' => 'varchar' ) ;        }        // finally, wrap up with section 4, the indices on the join table                $indexBase = $this->getValidColumnName ( $relationshipName ) ;        $properties [ 'indices' ] [] = array ( 'name' => $indexBase . 'spk' , 'type' => 'primary' , 'fields' => array ( 'id' ) ) ;        $properties [ 'indices' ] [] = array ( 'name' => $indexBase . '_ida1' , 'type' => 'index' , 'fields' => array ( $rel_properties [ 'join_key_lhs' ] ) ) ;        $properties [ 'indices' ] [] = array ( 'name' => $indexBase . '_idb2' , 'type' => 'index' , 'fields' => array ( $rel_properties [ 'join_key_rhs' ] ) ) ;        switch ($relationshipType)        {            case MB_ONETOONE:                $alternateKeys = array () ;                break;            case MB_ONETOMANY :                $alternateKeys = array ( $rel_properties [ 'join_key_rhs' ] ) ;                break;            default:                $alternateKeys = array ( $rel_properties [ 'join_key_lhs' ] , $rel_properties [ 'join_key_rhs' ] ) ;        }        if (count($alternateKeys)>0)            $properties [ 'indices' ] [] = array ( 'name' => $indexBase . '_alt' , 'type' => 'alternate_key' , 'fields' => $alternateKeys ) ; // type must be set to alternate_key for Link.php to correctly update an existing record rather than inserting a copy - it uses the fields in this array as the keys to check if a duplicate record already exists                return $properties ;    }            /*     * UTILITY methods     */        /*     * Method to build a name for a relationship between a module and an Activities submodule     * Used primarily in UndeployedRelationships to ensure that the subpanels we construct for Activities get their data from the correct relationships     * @param string $activitiesSubModuleName Name of the activities submodule, such as Tasks     */    function getActivitiesSubModuleRelationshipName ( $activitiesSubModuleName )    {        return $this->lhs_module . "_" . strtolower ( $activitiesSubModuleName ) ;    }    /*     * Return a version of $proposed that can be used as a column name in any of our supported databases     * Practically this means no longer than 25 characters as the smallest identifier length for our supported DBs is 30 chars for Oracle plus we add on at least four characters in some places (for indicies for example)     * TODO: Ideally this should reside in DBHelper as it is such a common db function...     * @param string $name Proposed name for the column     * @return string Valid column name trimmed to right length and with invalid characters removed     */    static function getValidColumnName ($name)    {        require_once 'modules/ModuleBuilder/parsers/constants.php' ;                // first strip any invalid characters - all but alphanumerics and -        $name = preg_replace ( '/[^\w-]+/i', '', $name ) ;        $len = strlen ( $name ) ;        if ($len > (MB_MAXDBIDENTIFIERLENGTH - 5))            $name = substr ( $name, 0, 11 ) . substr ( $name, 11 - MB_MAXDBIDENTIFIERLENGTH + 5 ) ;        return strtolower ( $name ) ;    }    /*     * Tidy up any provided relationship type - convert all the variants of a name to the canonical type - for example, One To Many = MB_ONETOMANY     * @param string $type Relationship type     * @return string Canonical type     */    static function parseRelationshipType ($type)    {        $type = strtolower ( $type ) ;        $type = preg_replace ( '/[^\w]+/i', '', strtolower ( $type ) ) ;        $canonicalTypes = array ( ) ;        foreach ( array ( MB_ONETOONE , MB_ONETOMANY , MB_MANYTOMANY ) as $canonicalType )        {            if ($type == preg_replace ( '/[^\w]+/i', '', strtolower ( $canonicalType ) ))                return $canonicalType ;        }        // ok, we give up...        return MB_MANYTOMANY ;    }    /*     * Return the name of a module's standard (non-cstm) table in the database     * @param string $moduleName    Name of the module for which we are to find the table     * @return string Tablename     */    protected function getTablename ($moduleName)    {        // Check the moduleName exists in the beanList before calling get_module_info - Activities is the main culprit here        if (isset ( $GLOBALS [ 'beanList' ] [ $moduleName ] ))        {            $module = get_module_info ( $moduleName ) ;            return $module->table_name ;        }        return strtolower ( $moduleName ) ;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?