Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/recyclebin paging #2472

Merged
merged 6 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 13 additions & 36 deletions src/Commands/RecycleBin/GetRecycleBinItem.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System;
using Microsoft.SharePoint.Client;
using PnP.PowerShell.Commands.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Management.Automation;
using Microsoft.SharePoint.Client;

using PnP.PowerShell.Commands.Base.PipeBinds;

namespace PnP.PowerShell.Commands.RecycleBin
{
Expand Down Expand Up @@ -44,7 +42,6 @@ protected override void ExecuteCmdlet()
}
else
{

if (ParameterSpecified(nameof(RowLimit)))
{
RecycleBinItemState recycleBinStage;
Expand All @@ -61,51 +58,31 @@ protected override void ExecuteCmdlet()
break;
}

if (FirstStage.IsPresent || SecondStage.IsPresent)
{
RecycleBinItemCollection items = ClientContext.Site.GetRecycleBinItems(null, RowLimit, false, RecycleBinOrderBy.DeletedDate, recycleBinStage);
ClientContext.Load(items);
ClientContext.ExecuteQueryRetry();

List<RecycleBinItem> recycleBinItemList = items.ToList();
WriteObject(recycleBinItemList, true);
}
else
{
ClientContext.Site.Context.Load(ClientContext.Site.RecycleBin, r => r.IncludeWithDefaultProperties(RetrievalExpressions));
ClientContext.Site.Context.ExecuteQueryRetry();

List<RecycleBinItem> recycleBinItemList = ClientContext.Site.RecycleBin.ToList();
recycleBinItemList = recycleBinItemList.Take(RowLimit).ToList();
WriteObject(recycleBinItemList, true);
}


List<RecycleBinItem> recycleBinItemList = RecycleBinUtility.GetRecycleBinItems(ClientContext, RowLimit, recycleBinStage);
WriteObject(recycleBinItemList, true);
}
else
{
ClientContext.Site.Context.Load(ClientContext.Site.RecycleBin, r => r.IncludeWithDefaultProperties(RetrievalExpressions));
ClientContext.Site.Context.ExecuteQueryRetry();

List<RecycleBinItem> recycleBinItemList = ClientContext.Site.RecycleBin.ToList();

List<RecycleBinItem> recycleBinItemList;
switch (ParameterSetName)
{
case ParameterSet_FIRSTSTAGE:
WriteObject(
recycleBinItemList.Where(i => i.ItemState == RecycleBinItemState.FirstStageRecycleBin), true);
recycleBinItemList = RecycleBinUtility.GetRecycleBinItems(ClientContext, RowLimit, RecycleBinItemState.FirstStageRecycleBin);
WriteObject(recycleBinItemList, true);
break;
case ParameterSet_SECONDSTAGE:
WriteObject(
recycleBinItemList.Where(i => i.ItemState == RecycleBinItemState.SecondStageRecycleBin),
true);
recycleBinItemList = RecycleBinUtility.GetRecycleBinItems(ClientContext, RowLimit, RecycleBinItemState.SecondStageRecycleBin);
WriteObject(recycleBinItemList, true);
break;
default:
recycleBinItemList = RecycleBinUtility.GetRecycleBinItems(ClientContext, RowLimit);
WriteObject(recycleBinItemList, true);
break;
}
}
}
}


}
}
65 changes: 65 additions & 0 deletions src/Commands/Utilities/RecycleBinUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Microsoft.SharePoint.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;

namespace PnP.PowerShell.Commands.Utilities
{
internal static class RecycleBinUtility
{
internal static List<RecycleBinItem> GetRecycleBinItems(ClientContext ctx, int? rowLimit = null, RecycleBinItemState recycleBinStage = RecycleBinItemState.None)
{
var recycleBinItems = new List<RecycleBinItem>();
string pagingInfo = null;
RecycleBinItemCollection items;

// This part is only here to make debugging easier if you ever run into issues with this code :)
//ctx.Load(ctx.Site.RecycleBin);
//ctx.ExecuteQueryRetry();
//var totalRecyclebinContentsCount = ctx.Site.RecycleBin.Count;

do
{
// We don't actually know what the List View Threshold for the Recycle Bin is, so we'll use the safe number (5000) and implement paging.
int iterationRowLimit;
if (rowLimit.HasValue && rowLimit.Value >= 5000)
{
// Subtract this page's count from the rowLimit (we don't want duplicates or go out of bounds)
if (rowLimit.HasValue) rowLimit -= 5000;

iterationRowLimit = 5000;
}
else if (rowLimit.HasValue && rowLimit.Value > 0 && rowLimit.Value < 5000)
{
iterationRowLimit = rowLimit.Value;
}
else // rowLimit was not set, just fetch a "whole page"
{
iterationRowLimit = 5000;
}

items = ctx.Site.GetRecycleBinItems(pagingInfo, iterationRowLimit, false, RecycleBinOrderBy.DefaultOrderBy, recycleBinStage);
ctx.Load(items);
ctx.ExecuteQueryRetry();
recycleBinItems.AddRange(items.ToList());

// Paging magic (if needed)
// Based on this work our good friends at Portiva did ❤
// https://www.portiva.nl/portiblog/blogs-cat/paging-through-sharepoint-recycle-bin
if (items.Count > 0)
{
var nextId = items.Last().Id;
//var nextTitle = items.Last().Title;
var nextTitle = WebUtility.UrlEncode(items.Last().Title);
//var deletionTime = items.Last().DeletedDate;
pagingInfo = $"id={nextId}&title={nextTitle}"; // &searchValue=${deletionTime}
}
}
while (items?.Count == 5000); // if items had 5000 items, there might be more since that's the page size we're using

return recycleBinItems;
}
}
}