Results 1 to 7 of 7

Thread: How to create dynamic views based on record content - upgrade safe

  1. #1
    edg
    edg is offline Sugar Community Member
    Join Date
    Feb 2007
    Location
    Atlanta, GA
    Posts
    46

    Post How to create dynamic views based on record content - upgrade safe

    I've not seen this topic raised directly in the forums and actually inquired about how to change the view based on the content of a record at SugarCon. Originally this was thought to be a SugarController issue - and would likely require modifications that were not upgrade safe. This is not the case. It's actually a very simple modification to preDisplay() in the MVC views and overloading this methods is fully supported in custom/include/MVC/View/views.

    The core issue prohibiting this functionality is that Sugar predefines the metadata file name and flag variables in preDisplay() rather than accept them as parameters from the child class overload.

    For example, let's say you want different displays for Accounts based on account type. To do this, you need only to create a different metadata file based on the account_type field and tell Sugar to load it prior to processing. To make this happen - say for detail views, you first must create a new view class in custom/include/MVC/View/views.


    PHP Code - based on Version 5.2.0d (Build 5604):
    Code:
    /*
       Modification of core view detail to override preDisplay functionality
    */
    require_once('include/MVC/View/views/view.detail.php');
    class CustomViewDetail extends ViewDetail{
    
     function CustomViewDetail(){
        parent::ViewDetail();
       }
    
     // Modified to allow override based on record content
    
     function preDisplay($foundViewDefs = false, $metadataFile = null){
    
      // core version of this function hardcodes definitions for variables, 
      // we allow them to be passed from the child object
    
      $GLOBALS['log']->debug(sprintf("preDisplay Detail Variables [%][%s]", $foundViewDefs, $metadataFile));
    
      // validate parameters
      if($foundViewDefs && is_null($metadataFile)) $foundViewDefs = false;
      elseif(!$foundViewDefs && !is_null($metadataFile)) $foundViewDefs = true;
    
      // extra test to validate file passed
      if($foundViewDefs && !file_exists($metadataFile)) $foundViewDefs = false;
      if (!$foundViewDefs) {
        // Resume original code
    
        if(file_exists('custom/modules/' . $this->module . '/metadata/detailviewdefs.php')){
          $metadataFile = 'custom/modules/' . $this->module . '/metadata/detailviewdefs.php';
          $foundViewDefs = true;
        }else{
          if(file_exists('custom/modules/'.$this->module.'/metadata/metafiles.php')){
            require_once('custom/modules/'.$this->module.'/metadata/metafiles.php');
            if(!empty($metafiles[$this->module]['detailviewdefs'])){
              $metadataFile = $metafiles[$this->module]['detailviewdefs'];
              $foundViewDefs = true;
            }
          }elseif(file_exists('modules/'.$this->module.'/metadata/metafiles.php')){
            require_once('modules/'.$this->module.'/metadata/metafiles.php');
            if(!empty($metafiles[$this->module]['detailviewdefs'])){
              $metadataFile = $metafiles[$this->module]['detailviewdefs'];
              $foundViewDefs = true;
            }
          }
        }
        $GLOBALS['log']->debug("CUSTOM metadatafile=". $metadataFile);
        if(!$foundViewDefs && file_exists('modules/'.$this->module.'/metadata/detailviewdefs.php')){
            $metadataFile = 'modules/'.$this->module.'/metadata/detailviewdefs.php';
        }
    
        $this->dv = new DetailView2();
        $this->dv->ss =&  $this->ss;
        $this->dv->setup($this->module, $this->bean, $metadataFile, 'include/DetailView/DetailView.tpl'
    
      } // end $foundViewDefs test
     }
    }
    Now, with a quick custom view.detail.php in Accounts, you can select the view definition file based on content. In my example, I'm appending the account_type name to the viewdetaildefs file name and storing the custom definiton file in custom/modules/Accounts/metadata. The Account specific view.detail.php file is in custom/modules/accounts/views.

    PHP Code:
    Code:
    <?php
    
    require_once('custom/include/MVC/View/views/view.detail.php');
    class AccountsViewDetail extends CustomViewDetail{
     function AccountsViewDetail(){
       parent::CustomViewDetail();
     }
    
     function preDisplay(){
      // declare the variables here instead.
      $metadataFile = null;
      $foundViewDefs = false;
    
      if(isset($this->bean->account_type)){
        $fname = 'custom/modules/' . $this->module . '/metadata/detailviewdefs_' . $this->bean->account_type . '.php';
        $GLOBALS['log']->debug("Accounts Detail File: " . $fname);
        if(file_exists($fname)) {
          $metadataFile = $fname;
          $foundViewDefs = true;
        }
      }
      parent::preDisplay($foundViewDefs, $metadataFile);
    }
    
    ?>
    In the above example, the file custom/modules/Accounts/metadata/detailviewdefs_Customer.php is the source of the view definition for Customers. All other standard customizations can then be applied including separate labels for the view (in this case by adding a customer views language file to custom/Extension/modules/Accounts/Ext/Language and repairing the extensions).

    If you follow the example for edits and lists, you can dynamically modify the view definition for any module based on virtually any content or relationship or other logic as necessary.
    Last edited by edg; 2009-05-09 at 09:12 AM. Reason: typo and BB code insert

  2. #2
    cyclope's Avatar
    cyclope is offline Senior Member
    Join Date
    Jul 2009
    Location
    Ukraine, Kyiv
    Posts
    69

    Default Re: How to create dynamic views based on record content - upgrade safe

    GR8!!!!!
    I think - I will try it tomorrow - looks perfectly
    Andrey Morskoy
    Analog-Company, LLC

    http://www.analog-company.com
    email: a.morskoy@analog-company.com
    skype: amorskoy

    SugarCRM outsourcing
    System Administration outsourcing
    Debian consulting

    One problem to be solved - one dream to be achieved
    One client to be involved - one friend to be found
    One difficulty to be discovered - one interesting day begun

  3. #3
    SugarDev.net is offline Sugar Community Member
    Join Date
    Feb 2008
    Posts
    1,401

    Default Re: How to create dynamic views based on record content - upgrade safe

    Great idea.

    Your proposed code is:
    PHP Code:
    /*
       Modification of core view detail to override preDisplay functionality
    */
    require_once('include/MVC/View/views/view.detail.php');
    class 
    CustomViewDetail extends ViewDetail{

     function 
    CustomViewDetail(){
        
    parent::ViewDetail();
       }

     
    // Modified to allow override based on record content

     
    function preDisplay($foundViewDefs false$metadataFile null){

      
    // core version of this function hardcodes definitions for variables, 
      // we allow them to be passed from the child object

      
    $GLOBALS['log']->debug(sprintf("preDisplay Detail Variables [%][%s]"$foundViewDefs$metadataFile));

      
    // validate parameters
      
    if($foundViewDefs && is_null($metadataFile)) $foundViewDefs false;
      elseif(!
    $foundViewDefs && !is_null($metadataFile)) $foundViewDefs true;

      
    // extra test to validate file passed
      
    if($foundViewDefs && !file_exists($metadataFile)) $foundViewDefs false;
      if (!
    $foundViewDefs) {
        
    // Resume original code

        
    if(file_exists('custom/modules/' $this->module '/metadata/detailviewdefs.php')){
          
    $metadataFile 'custom/modules/' $this->module '/metadata/detailviewdefs.php';
          
    $foundViewDefs true;
        }else{
          if(
    file_exists('custom/modules/'.$this->module.'/metadata/metafiles.php')){
            require_once(
    'custom/modules/'.$this->module.'/metadata/metafiles.php');
            if(!empty(
    $metafiles[$this->module]['detailviewdefs'])){
              
    $metadataFile $metafiles[$this->module]['detailviewdefs'];
              
    $foundViewDefs true;
            }
          }elseif(
    file_exists('modules/'.$this->module.'/metadata/metafiles.php')){
            require_once(
    'modules/'.$this->module.'/metadata/metafiles.php');
            if(!empty(
    $metafiles[$this->module]['detailviewdefs'])){
              
    $metadataFile $metafiles[$this->module]['detailviewdefs'];
              
    $foundViewDefs true;
            }
          }
        }
        
    $GLOBALS['log']->debug("CUSTOM metadatafile="$metadataFile);
        if(!
    $foundViewDefs && file_exists('modules/'.$this->module.'/metadata/detailviewdefs.php')){
            
    $metadataFile 'modules/'.$this->module.'/metadata/detailviewdefs.php';
        }

        
    $this->dv = new DetailView2();
        
    $this->dv->ss =&  $this->ss;
        
    $this->dv->setup($this->module$this->bean$metadataFile'include/DetailView/DetailView.tpl'

      
    // end $foundViewDefs test
     
    }

    This is a very interesting feature. However adding this as a method parameter seems a bit quick n dirty . Also, overriding these methods holds the risk of the method changing with an upgrade which can still render your installation unusable despite the fact that it is upgrade-safe (I've seen it happen). It may be better to leave the original methods alone. I'm proposing the "detailviewdefs.php" name be made by using a class attribute like this:

    PHP Code:
    <?php
    require_once('include/DetailView/DetailView2.php');

    class 
    ViewDetail extends SugarView{
        var 
    $type ='detail';
        var 
    $dv;
        var 
    $metafile//new line
        
         
    function ViewDetail(){
             
    $this->options['show_subpanels'] = true;
             
    parent::SugarView();
         }

    //Override me!
    function setMetafile() {

    }

         function 
    preDisplay(){
             
    $metadataFile null;
             
    $foundViewDefs false;
                   
    $this->setMetafile(); //new line
             
    if(file_exists('custom/modules/' $this->module '/metadata/'.$this->metafile.'.php')){ //changed line, use this for every mention of "detailviewdefs" in this method.
                 
    $metadataFile 'custom/modules/' $this->module '/metadata/detailviewdefs.php';
                 
    $foundViewDefs true;
             }else{
                 if(
    file_exists('custom/modules/'.$this->module.'/metadata/metafiles.php')){
                    require_once(
    'custom/modules/'.$this->module.'/metadata/metafiles.php');
                    if(!empty(
    $metafiles[$this->module]['detailviewdefs'])){
                        
    $metadataFile $metafiles[$this->module]['detailviewdefs'];
                        
    $foundViewDefs true;
                    }
                }elseif(
    file_exists('modules/'.$this->module.'/metadata/metafiles.php')){
                    require_once(
    'modules/'.$this->module.'/metadata/metafiles.php');
                    if(!empty(
    $metafiles[$this->module]['detailviewdefs'])){
                        
    $metadataFile $metafiles[$this->module]['detailviewdefs'];
                        
    $foundViewDefs true;
                    }
                }
             }
             
    $GLOBALS['log']->debug("metadatafile="$metadataFile);
            if(!
    $foundViewDefs && file_exists('modules/'.$this->module.'/metadata/detailviewdefs.php')){
                    
    $metadataFile 'modules/'.$this->module.'/metadata/detailviewdefs.php';
             }

            
    $this->dv = new DetailView2();
            
    $this->dv->ss =&  $this->ss;
            
    $this->dv->setup($this->module$this->bean$metadataFile'include/DetailView/DetailView.tpl');         
         }     
         
         function 
    display(){
            if(empty(
    $this->bean->id)){
                global 
    $app_strings;
                
    sugar_die($app_strings['ERROR_NO_RECORD']);
            }                
            
    $this->dv->process();
            echo 
    $this->dv->display();
         }

    }
    Developers go here
    Businesses go there (Dutch)

    Modules:
    SugarDev.net Developer Tools | Config | Dutch Language Pack
    "Nothing gets fixed unless there is a bug"

  4. #4
    leenuxwu is offline Senior Member
    Join Date
    Jun 2009
    Location
    Guangzhou,China
    Posts
    188

    Default Re: How to create dynamic views based on record content - upgrade safe

    Wow!! Just so cool!! What an amazing work

  5. #5
    erop is offline Sugar Community Member
    Join Date
    Jan 2005
    Location
    Moscow, Russia
    Posts
    107

    Default Re: How to create dynamic views based on record content - upgrade safe

    Quote Originally Posted by SugarDev.net View Post
    Great idea.

    PHP Code:
    <?php
         
    function preDisplay(){
             
    $metadataFile null;
             
    $foundViewDefs false;
                   
    $this->setMetafile(); //new line
             
    if(file_exists('custom/modules/' $this->module '/metadata/'.$this->metafile.'.php')){ //changed line, use this for every mention of "detailviewdefs" in this method.
                 
    $metadataFile 'custom/modules/' $this->module '/metadata/detailviewdefs.php';
                 
    $foundViewDefs true;
             }
    }
    I guess you meant here the following code:
    PHP Code:
    $metadataFile 'custom/modules/' $this->module '/metadata/'.$this->metafile.'.php' 
    But my main question is: Have you really managed to load viewdefs dynamically when Developer Mode is OFF? In this thread http://www.sugarcrm.com/forums/showthread.php?t=66789 John Mertic answered that loading different viewdefs is a problem due to caching mechanism.
    I tested SugarDev.net' approach and have to say I faced with the same issue: this works only when Developer Mode is ON. Please clarify this situation confirming (or not) you managed this working with DevMode OFF.
    Thank you!

  6. #6
    LauraDiaz is offline Member
    Join Date
    Jan 2011
    Posts
    5

    Default Re: How to create dynamic views based on record content - upgrade safe

    Hi,
    I've been trying for days to make my custom activities module, which have an activity type field, to navigate dynamically to an specific edit view depending of which is the activity type. Everything as you do with the activity Type.
    I have followed the instructions on the post, but as I am a newbie in SugarCRM and with no php experience, I think I'm not naming or saving the files in the right place.

    I get a white screen with no information whenever I click on the listview. It should be supposed to navigate to the view named detailviewdefs_other.php, for instance if the activity type is Other.

    what I've done is:
    • create a view.detail.php (with the first code in your post) in custom/include/MVC/View/views
    • create a view.detail.php (with the second code in the post) in /custom/modules/<moduleName>/views
    • create some files in /custom/modules/<moduleName>/metadata like detailviewdefs_other.php, detailviewdefs_retailAudit.php


    So could please anybody tell me if I'm doing anything wrong? I'm pretty desperate.
    I apologize if this sounds quite stupid

    Thanks in advance, Laura

  7. #7
    mangesh1757 is offline Sugar Community Member
    Join Date
    Jan 2010
    Location
    India
    Posts
    226

    Default Re: How to create dynamic views based on record content - upgrade safe

    Hi erop,

    If thats the case you can clear cache which will pick-up metadefs as per the logic on fly rather than from cache folder, using following code,

    //Starts : Clearing cache
    $mod_strings = return_module_language('en_us', 'Administration');
    require_once('modules/Administration/QuickRepairAndRebuild.php');
    $clear_cache=new RepairAndClear();
    $clear_cache->repairAndClearAll(array('clearTpls'),array('Con ta cts'),false,false);
    $mod_strings = return_module_language('en_us', 'Contacts');
    //Ends : Clearing cache

    Refer Post No.#10 link : http://www.sugarcrm.com/forums/showt...ighlight=cache

    Thanks.
    Mangesh1757
    mangesh1757@gmail.com
    India.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Campaign with dynamic content
    By Seb57070 in forum Help
    Replies: 1
    Last Post: 2009-04-10, 04:47 PM
  2. Very Dynamic Views
    By bonioboy in forum Developer Help
    Replies: 6
    Last Post: 2009-01-07, 04:57 PM
  3. send a dynamic value when creating a new record
    By meeric in forum Developer Help
    Replies: 1
    Last Post: 2008-10-09, 09:50 AM
  4. Replies: 0
    Last Post: 2008-05-27, 02:08 PM
  5. Replies: 4
    Last Post: 2007-02-02, 08:55 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •