Deploying Child Pages with Post Install Apex Script

Hi J.,

we are using postinstall class to do multiple task:

  1. assign permission set
  2. populate custom settings
  3. backup existing reference data
  4. insert new reference data
  5. upsert skuid pages
  6. backup skuid page assignments
  7. insert new page assignments
  8. initiate batch apex (if needed)

I used skuid provided code for upserting pages with little modification. i.e. I created private method to process skuid pages like this:

   // private method to upsert pages from static resource (JSON)    private static void RefreshPagesInModule(String module) {
        string[] upsertErrList = new List<string>();
        string[] updateList = new List<string>();
        string[] insertList = new List<string>();
        string insertedPages = '';
        string updatedPages = '';
        string failedPages = '';
        cloupra__Batch__c batch = new cloupra__Batch__c();
        string csvString  = '';
        Attachment att;
        string event;
        
        &#47;&#47; See if a StaticResource containing new pages for this module yet exists      
        StaticResource sr = [
            select Body
            from StaticResource 
            where Name = :(module + 'Pages')
            and ((NamespacePrefix = NULL) OR (NamespacePrefix = :module))
            limit 1
        ];
        
        &#47;&#47; The new Pages for our module that we will be inserting       
        List<skuid__Page__c> newPages
        = (List<skuid__Page__c>) JSON&#46;deserialize(sr&#46;Body&#46;toString(),List<skuid__Page__c>&#46;class);
        List<Schema&#46;SObjectField> layoutFields = new List<Schema&#46;SObjectField>{
            skuid__Page__c&#46;skuid__Layout__c,
            skuid__Page__c&#46;skuid__Layout2__c,
            skuid__Page__c&#46;skuid__Layout3__c,
            skuid__Page__c&#46;skuid__Layout4__c,
            skuid__Page__c&#46;skuid__Layout5__c
        };
        
        for (skuid__Page__c p : newPages) {
            &#47;&#47; Get rid of the Ids so that upsert will proceed           
            p&#46;Id = null;
            &#47;&#47; Ensure that unused Layout fields are set to null         
            for (Schema&#46;Sobjectfield f : layoutFields) {
                if (p&#46;get(f)==null) p&#46;put(f,null);
            }
        }
        
        &#47;&#47; If we have successfully compiled new Pages for this module,        
        &#47;&#47; delete the old ones and replace them with the new&#46;        
        if (newPages != null &amp;&amp; !newPages&#46;isEmpty()) {
            Schema&#46;SObjectField f = skuid__Page__c&#46;skuid__UniqueId__c;
            try {
                event = 'upsert';
                List<Database&#46;UpsertResult> cr = Database&#46;upsert(newPages,f,false);
                integer ndx = 0;
                
                for (Database&#46;UpsertResult r : cr) {
                    
                    if (r&#46;isSuccess()) {
                        &#47;&#47; Operation was successful, so get the ID of the record that was processed
                        &#47;&#47;System&#46;debug('Successfully Inserted record: ' + r&#46;getId() + ' - ' + r);
                        
                        if(r&#46;isCreated()) { 
                            insertList&#46;add(newPages[ndx]&#46;Name);
                            insertedPages += newPages[ndx]&#46;Name + '
';
                        }
                        else {
                            updateList&#46;add(newPages[ndx]&#46;Name);
                            updatedPages += newPages[ndx]&#46;Name + '
';
                        }
                    }
                    else {
                        string errMsg = r&#46;getErrors()[0]&#46;getMessage();
                        errMsg += ',' + newPages[ndx]&#46;Name + '
';
                        upsertErrList&#46;add(errMsg);
                    }
                    ndx++; 
                }
            
            }
            catch (exception e) {
                 system&#46;debug(logginglevel&#46;info, 'upsert error--------- ' + string&#46;valueOf(e));
            }       
        }        
        if(!newPages&#46;isEmpty()) {
            batch&#46;cloupra__Status__c = 'Completed';
            batch&#46;cloupra__Description__c = 'Batch_Creted_By_Post_Install_Script - skuid__Page__c Upsert';
            
            if(!upsertErrList&#46;isEmpty()) {
                batch&#46;cloupra__Status__c = 'Completed (With Errors)';
                
                for(string s: upsertErrList) {
                    csvString = csvString + s;
                }
                
                csvString = 'Error Message,Page Name
' + csvString;
            }
                        
            insert batch;
            
            string feedTitle = 'Page Upsert Result:
';
            string msgBody = 'Upsert Result:
';
            msgBody += newPages&#46;size() + ' pages processed 
';
            msgBody += insertList&#46;size() + ' pages inserted
';
            msgBody += updateList&#46;size() + ' pages updated
';
            msgBody += upsertErrList&#46;size() + ' pages failed

';
            msgBody += 'Inserted Pages:
' + insertedPages + '
';
            msgBody += 'Updated Pages:
' + updatedPages + '
';
            msgBody += 'Failed Pages:
' + csvString;
            
            if(!upsertErrList&#46;isEmpty()) {
                att = new Attachment();
                att&#46;Name = 'Page upsert error result';
                att&#46;Description = msgBody;
                att&#46;Body = blob&#46;valueOf(csvString);
                att&#46;ParentId = batch&#46;Id;
                insert att; 
            }
            
            FeedItem post = new FeedItem();
            post&#46;ParentId = batch&#46;Id;
            post&#46;Body = msgBody;
            post&#46;Type = 'TextPost';
            post&#46;Title = feedTitle;
            insert post;           
        }        
    }

And called this method form OnInstall method like this

   global void onInstall(InstallContext context) {       
     IsRunning = true;
        &#47;&#47; if this is an upgrade
        if(context&#46;isUpgrade() || context&#46;isPush()) {
            &#47;&#47; upsert skuid pages
<b><i>RefreshPagesInModule('Module_Name');</i></b>
                
            &#47;&#47; Assign required permission sets   
            &#47;&#47; This check is to avoid mixed-dml-error in test class         
            
            if(Test&#46;isRunningTest()) {
                User adminuser = [select Id from User where Profile&#46;Name = 'System Administrator' and IsActive = true limit 1];
                System&#46;runAs(adminuser){
                    Utils&#46;AssignPermissionSets();
                }
            }
            else {
                Utils&#46;AssignPermissionSets();
            }            
            
            &#47;&#47; Populate Custom Settings fields
            Utils&#46;PopulateCustomSettings();               
        
            &#47;&#47; Take full backup of clients reference data and save to Documents (PractiFI Backup folder)
            Utils&#46;BackupRefData();              
        
            &#47;&#47;Populate Reference data 
            Utils&#46;InsertNewRefData();
            
            &#47;&#47;Update Content Items for process launch
            Utils&#46;UpdateContentItems();              
            
            
            if(context&#46;previousVersion()&#46;compareTo(new Version(5,10)) < 0) {
                &#47;&#47; Update ProcessSteps
                Utils&#46;UpdateProcessSteps();
                
                &#47;&#47; Update Task Rich Description                
                string updateTaskDescriptions = Database&#46;executeBatch(new BatchableJob(new ChangeTaskDescription()), 200);
            }                     
        }
        IsRunning = false;        
    }

Now when I see the tutorial (which presumably addressed master page issue), it’s a class that was extended from skuid’s global class InstallScript.

I was wondering how could I use this new approach to upsert pages without breaking my postinstall script. Or can I get an idea how I can update my existing method RefreshPagesInModule to handle Master Page issue.

Thanks.