AI OnAI Off
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);