Lightning Experience can be enabled for custom profile only. For the standard profiles its by default enabled. But there are few standard profiles as well where this setting is even not present.
So, we will use the metadata which will enable this setting for applicable profiles. For this solution, we are using MetadataService class.
We need following three additional classes-
1. ProfileWrapper
2. MetadataServiceUse
3. UpdateProfileBatch
ProfileWrapper
public class ProfileWrapper { //public cls_attributes attributes; public String Id; //00e2x000000I5N0AAK public String Name; //System Administrator public String CreatedDate; //2020-03-29T06:30:13.000+0000 public String CreatedById; //0052x000000thcaAAA public String LastModifiedDate; //2020-09-07T05:56:31.000+0000 public String LastModifiedById; //0052x000000thcaAAA //public cls_Description Description; public cls_Metadata Metadata; public String FullName; //Admin public class cls_Metadata { public boolean custom; } public static ProfileWrapper parse(String json){ return (ProfileWrapper) System.JSON.deserialize(json, ProfileWrapper .class); } }
MetadataServiceUse
public with sharing class MetadataServiceUse { public static MetadataService.MetadataPort createService() { MetadataService.MetadataPort service = new MetadataService.MetadataPort(); service.SessionHeader = new MetadataService.SessionHeader_element(); service.SessionHeader.sessionId = UserInfo.getSessionId(); return service; } public class MetadataServiceUseException extends Exception { } /** * Example helper method to interpret a SaveResult, throws an exception if errors are found **/ public static void handleSaveResults(MetadataService.SaveResult saveResult) { // Nothing to see? if(saveResult==null || saveResult.success) return; // Construct error message and throw an exception if(saveResult.errors!=null) { List<String> messages = new List<String>(); messages.add( (saveResult.errors.size()==1 ? 'Error ' : 'Errors ') + 'occured processing component ' + saveResult.fullName + '.'); for(MetadataService.Error error : saveResult.errors) messages.add( error.message + ' (' + error.statusCode + ').' + ( error.fields!=null && error.fields.size()>0 ? ' Fields ' + String.join(error.fields, ',') + '.' : '' ) ); if(messages.size()>0) throw new MetadataServiceUseException (String.join(messages, ' ')); } if(!saveResult.success) throw new MetadataServiceUseException ('Request failed with no specified error.'); } /** * NOTE: Consider using Permission Sets, these can also be created and assignd with DML in Apex **/ public static void updateLightningExperienceUserPermission(String fullName) { MetadataService.MetadataPort service = createService(); MetadataService.Profile admin = new MetadataService.Profile(); admin.fullName = fullName; admin.custom = false; MetadataService.ProfileUserPermission proUserPermission = new MetadataService.ProfileUserPermission(); proUserPermission.name = 'LightningExperienceUser'; proUserPermission.enabled = true; admin.userPermissions = new MetadataService.ProfileUserPermission[] {proUserPermission}; List<MetadataService.SaveResult> results = service.updateMetadata( new MetadataService.Metadata[] { admin }); handleSaveResults(results[0]); } }
UpdateProfileBatch
public class UpdateProfileBatch implements Database.Batchable < sObject > , Database.AllowsCallouts { public Database.QueryLocator start(Database.BatchableContext BC) { return Database.getQueryLocator('Select Id from Profile'); } public void execute( Database.BatchableContext BC, List < sObject > scope) { for (sObject p: scope) { HttpRequest req = new HttpRequest(); req.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionID()); req.setHeader('Content-Type', 'application/json'); String domainUrl = URL.getSalesforceBaseUrl().toExternalForm(); system.debug('********domainUrl:' + domainUrl); req.setEndpoint(domainUrl + '/services/data/v40.0/tooling/sobjects/Profile/' + p.get('Id')); req.setMethod('GET'); Http h = new Http(); HttpResponse res = h.send(req); ProfileWrapper wrapper = null; if (res.getStatusCode() == 200) { wrapper = (ProfileWrapper) ProfileWrapper.parse(res.getBody()); system.debug('FullName***' + wrapper.FullName + '***' + wrapper.Metadata); if (wrapper.Metadata.custom) { MetadataServiceUse.updateLightningExperienceUserPermission(wrapper.FullName); } else { system.debug('You can not modify the permission Lightning Experience User for a Standard Profile'); } } else { system.assert(false, res.getBody() + ' There is some error. Batch need to rerun'); } } } public void finish(Database.BatchableContext BC) { } }
Then execute following statement in developer console in anonymous window-
Database.executeBatch(new UpdateProfileBatch(), 1);
Check ‘Apex Job’ for batch completion. If batch job is completed without any error, it means this setting ‘Lightning Experience User’ has been applied to all applicable profiles.
Check below links for more information on Lightning experience rollout-
https://help.salesforce.com/articleView?id=lex_enable_users.htm&type=5