London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!
AI OnAI Off
London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!
private static Classes.PublishTimeTable _publishTimeTable;
public static Classes.PublishTimeTable PublishTimeTable
{
get
{
return _publishTimeTable;
}
}
In Application_Start I added init code
_publishTimeTable = new Solution.Classes.PublishTimeTable(Global.EPConfig.CachePolicyTimeout);
In an eventhandler for SavingPage I added the following lines
if(e.Page.WorkPageID == 0)
{
_publishTimeTable.AddPublishDate(e.Page.StartPublish);
}
else
{
_publishTimeTable.AddDelayedPublishDate(e.Page.StartPublish);
}
_publishTimeTable.AddPublishDate(e.Page.StopPublish);
The I created two classes to do the time table work for me.
PublishTimeTable.cs
///
/// Summary description for PublisTimeTable.
///
public class PublishTimeTable
{
private DateTime MAXDATE = DateTime.MaxValue; //.Parse("9999-12-31 23:59:59");
private TimeCollection _timeCollection;
private int _cacheTimeout = 0;
private bool _isActive = false;
public TimeCollection PublishOccasions
{
get
{
return _timeCollection;
}
}
public bool IsActive
{
get
{
return _isActive;
}
}
public PublishTimeTable(int cacheTimeout)
{
_cacheTimeout = cacheTimeout;
_timeCollection = new TimeCollection();
BuildPublishTimeTable();
}
public DateTime GetNextTimeout()
{
DateTime now = DateTime.Now;
if(_isActive)
{
return CheckPublishOccasions(now);
}
else
{
return now.AddSeconds(_cacheTimeout);
}
}
public bool AddPublishDate(DateTime publishDate)
{
if(DateTime.Now.CompareTo(publishDate) < 1 && publishDate.CompareTo(MAXDATE) < 0)
{
_timeCollection.Add(publishDate);
_isActive = true;
return true;
}
else
{
return false;
}
}
public bool AddDelayedPublishDate(DateTime publishDate)
{
if(AddPublishDate(publishDate))
{
AddPublishDate(publishDate.AddMinutes(-1));
AddPublishDate(publishDate.AddMinutes(1));
return true;
}
else
{
return false;
}
}
private DateTime CheckPublishOccasions(DateTime now)
{
DateTime nextTimeout = now.AddSeconds(_cacheTimeout);
int count = _timeCollection.Count;
for(int index = count - 1; index >= 0; index--)
{
if(_timeCollection[index].CompareTo(now) < 1)
{
try
{
_timeCollection.RemoveAt(index);
}
catch
{}
}
else if(_timeCollection[index].CompareTo(nextTimeout) < 1)
{
nextTimeout = _timeCollection[index];
}
}
_isActive = _timeCollection.Count > 0;
return nextTimeout;
}
private void BuildPublishTimeTable()
{
// Future start publish
EPiServer.PropertyCriteria upCommingPublish = new EPiServer.PropertyCriteria();
upCommingPublish.Condition = EPiServer.Filters.CompareCondition.GreaterThan;
upCommingPublish.Type = EPiServer.Core.PropertyDataType.Date;
upCommingPublish.Name = "PageStartPublish";
upCommingPublish.Value = DateTime.Now.ToString();
upCommingPublish.Required = true;
AddPagePublishDates(upCommingPublish);
// Future stop publish
upCommingPublish.Name = "PageStopPublish";
AddPagePublishDates(upCommingPublish);
}
private void AddPagePublishDates(EPiServer.Core.PageDataCollection pages)
{
for(int index = 0; index < pages.Count; index++)
{
if(!_timeCollection.Contains(pages[index].StartPublish))
{
_timeCollection.Add(pages[index].StartPublish);
_isActive = true;
}
}
}
private void AddPagePublishDates(EPiServer.PropertyCriteria upCommingPublish)
{
EPiServer.PropertyCriteriaCollection publishCriteria = new EPiServer.PropertyCriteriaCollection();
publishCriteria.Add(upCommingPublish);
AddPagePublishDates(EPiServer.Global.EPDataFactory.FindPagesWithCriteria(Global.EPConfig.StartPage, publishCriteria, EPiServer.Security.AccessControlList.NoAccess));
}
public override string ToString()
{
StringBuilder toString = new StringBuilder(base.ToString());
foreach(DateTime occasion in _timeCollection)
{
toString.AppendFormat("{0}{1}", Environment.NewLine, occasion);
}
return toString.ToString();
}
}
and a time collection
TimeCollection.cs
///
/// Summary description for TimeCollection.
///
public class TimeCollection : CollectionBase
{
public TimeCollection()
{
}
public DateTime this[int index]
{
get
{
return (DateTime)List[index];
}
set
{
List[index] = value;
}
}
public int Add(DateTime value)
{
return List.Add(value);
}
public int IndexOf(DateTime value)
{
return List.IndexOf(value);
}
public void Insert(int index, DateTime value)
{
List.Insert(index, value);
}
public void Remove(DateTime value)
{
List.Remove(value);
}
public void RemoveAt(int index)
{
List.RemoveAt(index);
}
public bool Contains(DateTime value)
{
// If value is not of type DateTime, this will return false.
return List.Contains(value);
}
}
protected override void SetCachePolicy()
{
base.SetCachePolicy();
if(Global.PublishTimeTable.IsActive)
{
base.Response.Cache.SetExpires(Global.PublishTimeTable.GetNextTimeout());
}
}
It seems to work fine, but I'm having some trouble with time-sync, so delayed publish only works if I start the job manually in Admin.
if(e.Page.WorkPageID == 0)
{
_publishTimeTable.AddPublishDate(e.Page.StartPublish);
}
else
{
_publishTimeTable.AddDelayedPublishDate(e.Page.StartPublish);
}
_publishTimeTable.AddPublishDate(e.Page.StopPublish);
is replaced by
_publishTimeTable.AddPublishDate(e.Page.StartPublish);
_publishTimeTable.AddPublishDate(e.Page.StopPublish);