Whenever the page is locked, its version is added. Therefore, you can use Event Handler
to listen to item:versionAdded
event. On the triggering of this event, script can be executed in the background to create and lock datasource item versions as well, whenever the page item is locked.
- In order to listen to
item:versionAdded
event, you need to add the following patch:
<configuration xmlns:patch="https://www.sitecore.net/xmlconfig/">
<sitecore>
<events>
<event name="item:versionAdded">
<handler type="Spe.Integrations.Tasks.ScriptedItemEventHandler, Spe" method="OnEvent" />
</event>
</events>
</sitecore>
</configuration>
- Thereafter, you can add the script to be executed to lock datasource items at the path
Event Handlers -> Item -> VersionAdded
as below.
- Inside the powershell script item, attach below snippet that reads the datasource items located on the page and then uses workflow helper method to lock and create the new versions of datasource items.
# Locks items depending on the user context
function LockItem {
param([Sitecore.Data.Items.Item]$item , [bool]$isAdmin)
Write-Log "Item with ID: $($item.ID) is locked"
if ($isAdmin){
$item.Locking.Lock();
} elseif ($item.Access.CanWrite() -AND !$item.Locking.IsLocked() -AND !$item.Locking.HasLock()){
[Sitecore.Context]::Workflow.StartEditing($item)
}
}
try{
$isAdmin = [Sitecore.Context]::User.IsAdministrator
Write-Log "Current User is Admin : $($isAdmin)"
$item = $eventArgs.Parameters[0]
$language = $item.Language.Name
Write-Log "Item with ID: $($item.ID) with version number $($item.Version.Number) and language $($language) was added"
# Get Site Context
$instance = [Sitecore.DependencyInjection.ServiceLocator]::ServiceProvider
$siteInfo = $instance.GetType().GetMethod('GetService').Invoke($instance, [Sitecore.XA.Foundation.Multisite.ISiteInfoResolver]).GetSiteInfo($item)
$siteContext = New-Object Sitecore.Sites.SiteContext $siteInfo
New-UsingBlock(New-Object Sitecore.Sites.SiteContextSwitcher $siteContext) {
$defaultLayout = Get-LayoutDevice "Default"
# Read the Final Layout
$renderings = Get-Rendering -Item $item -Device $defaultLayout -FinalLayout
$datasourceItems = @()
if($renderings -ne $null -AND $renderings.Count -gt 0){
foreach($rendering in $renderings){
$datasource = $rendering.Datasource
if($datasource -ne $null -AND ![string]::IsNullOrEmpty($datasource)){
# Fetch Datasource Item Path in SXA including local datasources
$datasourceArgs = [Sitecore.Pipelines.ResolveRenderingDatasource.ResolveRenderingDatasourceArgs]::new($datasource)
$datasourceArgs.CustomData["contextItem"] = $item
[Sitecore.Pipelines.CorePipeline]::Run("resolveRenderingDatasource", $datasourceArgs)
# Fetch Item from ID/Path
$datasourceArgsDataSource = $datasourceArgs.Datasource
$datasourceID = [System.Guid]::empty
if ([guid]::TryParse($datasourceArgsDataSource, [System.Management.Automation.PSReference]$datasourceID)){
$datasourceItem = Get-Item -Path "master:" -ID $datasourceArgsDataSource -Language $language
}else{
$datasourceItem = Get-Item -Path $datasourceArgsDataSource -Language $language
}
# Avoid Traversing Duplicate Items
if($datasourceItems -notcontains $datasourceItem.ID.ToString()){
# Helper function to Lock Item
LockItem $datasourceItem $isAdmin
$datasourceItems += $datasourceItem.ID.ToString()
}
}
}
}
else{
Write-Log "Item with ID: $($item.ID) is not a page item"
}
}
} catch [System.Exception] {
Write-Log $_
}
Using the above approach, datasource items will be locked automatically whenever the page item is locked.
You can find more details on Event handlers here:
https://doc.sitecorepowershell.com/modules/integration-points/event-handlers
Let me know in case you have any doubts. Hope this helps!!!