Wednesday, September 16, 2015

How to override Managed package functionality


SFDC documentation team have great job on describing what is Managed package, how to use it, what are limitation of it etc. The one area which is not very clear is how to override the functionality in Managed package. To some extend it also gives a perception to new developer that we cannot override functionality. This is not 100% true. If the package is designed to accept customization then it should allow developers to extend or override the functionality in Managed package.
Let’s see what are the ways to extend or override the functionally.  

1)      Override the Buttons & Links action: IF package developer creates a buttons and links using setup UI then those button and actions can be override by just selecting new action. For example you have new Clone button in your manage package and it is pointing to MyPKG__Clone page.  Then you can just edit it’s action and point it to MyClonePage (your own VF page).



Limitation: If bottom is created using VF tags then it can’t override using this method.

2)      Override the page layout: IF package developer creates a VF page using <Apex:Detial> tag then it uses standard page layouts as per profile. So you can use standard edit layout screen from Setup->Your object->page layout screen then click edit. This will allow developers to add new fields sections etc. to VF page.

3)      Use Global Components: You can use Global Components from managed package in your VF page and add new functionality around the Global Components.

4)      Use Global interfaces / Classes / Extension: You can use global interfaces / Classes / Extension and their global properties in any installed org. Global keyword make your code accessible from any apex code. Let’s take look as one of such example.

a.       Create controller extension class:
Global class myControllerExtension {
    private final Account acct;
   
    global myControllerExtension(ApexPages.StandardController stdController) {
        this.acct = (Account)stdController.getRecord();
    }


    global String getGreeting() {
        return 'Hello ' + acct.name + ' (' + acct.id + ')' +' <br/> This text is from myControllerExtension';
    }
}
b.      Create VF page that use standard controller and extension we created above:
<apex:page standardController="Account" extensions="myControllerExtension">
    {!greeting} <p/>
    <apex:form >
        <apex:inputField value="{!account.name}"/> <p/>
        <apex:commandButton value="Save" action="{!save}"/>
    </apex:form>
</apex:page>
c.       Write test class
@isTest
Public class TestmyControllerExtension {
    public static testMethod void testMyControllerExtension() {
        Test.startTest();
        Account a = new Account();
        a.name  = 'Cybage';
        Insert a;
        PageReference pageRef = Page.GlobalTest;
        Test.setCurrentPage(pageRef);
        // Add parameters to page URL
        ApexPages.currentPage().getParameters().put('Id', a.Id);
        ApexPages.StandardController stdacc = new ApexPages.StandardController(a);
        myControllerExtension obj = new myControllerExtension(stdAcc);
        String msg = obj.getGreeting();
        System.assertEquals('Hello ' + a.name + ' (' + a.id + ')' +' <br/> This text is from myControllerExtension', msg );
        Test.stopTest();
    }
}
d.      Create manage package
e.      Log into other org and install the package created above
f.        Create your own VF page and use extension from package
<apex:page standardController="Account" extensions="AtulDev.myControllerExtension">
  {!greeting} <p/>
    <apex:form >
        <apex:inputField value="{!account.name}"/> <p/>
        <apex:commandButton value="Save" action="{!save}"/>
    </apex:form>
</apex:page>
g.       Create new extension to override the method from installed extension
h.       
Public class myControllerExtension_1 {
    private final Account acct;
    Public myControllerExtension_1(ApexPages.StandardController stdController) {
        this.acct = (Account)stdController.getRecord();
    }
    Public String getGreeting() {
        return 'Hello ' + acct.name + ' (' + acct.id + ')' +' <br/> This text is from override by New Extention';
    }
}
i.         Create VF page that used override extension:
<apex:page standardController="Account" extensions="myControllerExtension_1, AtulDev.myControllerExtension">
  {!greeting} <p/>
    <apex:form >
        <apex:inputField value="{!account.name}"/> <p/>
        <apex:commandButton value="Save" action="{!save}"/>
    </apex:form>
</apex:page>  


Conclusion: The general perception is that we cannot override anything that is written in mange package. This is not 100% true.