public static ValidationResult Validate(PublishSchedule publishSchedule)
        {
            ValidationResult result = new ValidationResult
            {
                IsValid = true
            };

            if (publishSchedule == null)
            {
                result.ValidationErrors.Add("Null reference");
                result.IsValid = false;

                return result;
            }

            if (!IsFutureDate(publishSchedule.PublishDate))
            {
                result.ValidationErrors.Add("Please select future date.");
                result.IsValid = false;
            }

            if (publishSchedule.TargetDatabases == null || !publishSchedule.TargetDatabases.Any())
            {
                result.ValidationErrors.Add("Please select at least one publish target.");
                result.IsValid = false;
            }

            if (publishSchedule.Unpublish)
            {
                return result;
            }

            if (publishSchedule.TargetLanguages == null || !publishSchedule.TargetLanguages.Any())
            {
                result.ValidationErrors.Add("Please select at least one publish language.");
                result.IsValid = false;
            }

            if (publishSchedule.PublishMode == PublishMode.Unknown)
            {
                result.ValidationErrors.Add("Unknow publish mode.");
                result.IsValid = false;
            }

            if (!IsPublishableItem(publishSchedule.ItemToPublish, publishSchedule.PublishDate))
            {
                result.ValidationErrors.Add("Item is not publishable at that time.");
                result.IsValid = false;
            }

            return result;
        }
        /// <summary>
        /// Handles a click on the OK button. Save the new publishing schedules
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The arguments.</param>
        protected override void OnOK(object sender, EventArgs args)
        {
            Assert.ArgumentNotNull(sender, "sender");
            Assert.ArgumentNotNull(args, "args");

            foreach (string key in Context.ClientPage.ClientRequest.Form.Keys)
            {
                if (key != null && key.StartsWith("dt_", StringComparison.InvariantCulture))
                {
                    string id = StringUtil.Mid(key, 3, 38);

                    DateTimePicker dtEditPicker = AllSchedules.FindControl("dt_" + id) as DateTimePicker;

                    Assert.IsNotNull(dtEditPicker, "dtEditPicker");

                    DateTime dateTime = DateUtil.IsoDateToDateTime(dtEditPicker.Value);
                    PublishSchedule publishSchedule = new PublishSchedule(_database.GetItem(new ID(id)));

                    //Scheudled time has changed
                    if (publishSchedule.PublishDate != dateTime)
                    {
                        publishSchedule.PublishDate = dateTime;

                        ValidationResult validationResult = ScheduledPublishValidator.Validate(publishSchedule);
                        if (!validationResult.IsValid)
                        {
                            SheerResponse.Alert(string.Join(Environment.NewLine, validationResult.ValidationErrors));
                            return;
                        }

                        _scheduledPublishRepo.UpdatePublishSchedule(publishSchedule);
                    }
                }
                else if (key != null && key.StartsWith("del_", StringComparison.InvariantCulture))
                {
                    string id = StringUtil.Mid(key, 4, 38);
                    Checkbox deleteCheckbox = AllSchedules.FindControl("del_" + id) as Checkbox;

                    Assert.IsNotNull(deleteCheckbox, "deleteCheckbox");

                    bool doDelete = deleteCheckbox.Checked;
                    if (doDelete)
                    {
                        Item publishOption = _database.GetItem(new ID(id));
                        _scheduledPublishRepo.DeleteItem(publishOption);
                    }
                }
            }

            base.OnOK(sender, args);
        }
        /// <summary>
        /// Sets 'IsPublished' field of already published schedule to 'true'
        /// </summary>
        /// <param name="publishSchedule">Publish Schedule</param>
        private void MarkAsPublished(PublishSchedule publishSchedule)
        {
            if (publishSchedule == null)
            {
                return;
            }

            publishSchedule.IsPublished = true;

            _scheduledPublishRepo.UpdatePublishSchedule(publishSchedule);
        }
        /// <summary>
        /// Modifies an existing <see cref="T:ScheduledPublish.Models.PublishSchedule"/> publish schedule item in Sitecore.
        /// </summary>
        /// <param name="publishSchedule">A <see cref="T:ScheduledPublish.Models.PublishSchedule"/> publish schedule according to which to modify the Sitecore item.</param>
        public void UpdatePublishSchedule(PublishSchedule publishSchedule)
        {
            if (publishSchedule.InnerItem == null)
            {
                Log.Error("Scheduled Publish: Scheduled Update Failed. Item is null.", new object());
                return;
            }

            string action = publishSchedule.Unpublish ? Constants.UNPUBLISH_TEXT : Constants.PUBLISH_TEXT;

            try
            {
                using (new SecurityDisabler())
                {
                    publishSchedule.InnerItem.Editing.BeginEdit();

                    publishSchedule.InnerItem[PublishSchedule.SchedulerEmailId] = publishSchedule.SchedulerEmail;
                    publishSchedule.InnerItem[PublishSchedule.UnpublishId] = publishSchedule.Unpublish ? "1" : string.Empty;
                    if (publishSchedule.ItemToPublish != null)
                    {
                        publishSchedule.InnerItem[PublishSchedule.ItemToPublishId] = publishSchedule.ItemToPublish.Paths.FullPath;
                    }
                    publishSchedule.InnerItem[PublishSchedule.PublishModeId] = publishSchedule.PublishMode.ToString();
                    publishSchedule.InnerItem[PublishSchedule.PublishChildrenId] = publishSchedule.PublishChildren ? "1" : string.Empty;
                    publishSchedule.InnerItem[PublishSchedule.TargetLanguagesId] = string.Join("|",
                        publishSchedule.TargetLanguages.Select(x => x.Name));
                    publishSchedule.InnerItem[PublishSchedule.SourceDatabaseId] = publishSchedule.SourceDatabase.Name;
                    publishSchedule.InnerItem[PublishSchedule.TargetDatabasesId] = string.Join("|", publishSchedule.TargetDatabases.Select(x => x.Name));
                    publishSchedule.InnerItem[PublishSchedule.IsPublishedId] = publishSchedule.IsPublished ? "1" : string.Empty;

                    DateTime oldPublishDate =
                        DateUtil.IsoDateToDateTime(publishSchedule.InnerItem[PublishSchedule.PublishDateId]);
                    publishSchedule.InnerItem[PublishSchedule.PublishDateId] = DateUtil.ToIsoDate(publishSchedule.PublishDate);

                    publishSchedule.InnerItem.Editing.AcceptChanges();
                    publishSchedule.InnerItem.Editing.EndEdit();

                    if (oldPublishDate != publishSchedule.PublishDate)
                    {
                        Item newFolder = GetOrCreateFolder(publishSchedule.PublishDate);
                        publishSchedule.InnerItem.MoveTo(newFolder);
                    }

                    Log.Info(
                        string.Format("Scheduled Publish: Updated Publish Schedule: {0}: {1} {2} {3}",
                            action,
                            publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.Name : Constants.WEBSITE_PUBLISH_TEXT,
                            publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.ID.ToString() : Constants.WEBSITE_PUBLISH_TEXT,
                            DateTime.Now), new object());
                }
            }
            catch (Exception ex)
            {
                Log.Error(
                    string.Format("Scheduled Publish: Failed updating Publish Schedule: {0}: {1} {2} {3}",
                        action,
                        publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.Name : Constants.WEBSITE_PUBLISH_TEXT,
                        publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.ID.ToString() : Constants.WEBSITE_PUBLISH_TEXT,
                        ex), new object());
            }
        }
        /// <summary>
        /// Creates a <see cref="T:ScheduledPublish.Models.PublishSchedule"/> publish schedule item in Sitecore.
        /// </summary>
        /// <param name="publishSchedule">A <see cref="T:ScheduledPublish.Models.PublishSchedule"/> publish schedule to create an item for.</param>
        public void CreatePublishSchedule(PublishSchedule publishSchedule)
        {
            string action = publishSchedule.Unpublish ? Constants.UNPUBLISH_TEXT : Constants.PUBLISH_TEXT;

            try
            {
                using (new SecurityDisabler())
                {
                    TemplateItem publishOptionsTemplate = _database.GetTemplate(Constants.PUBLISH_SCHEDULE_TEMPLATE_ID);
                    string publishOptionsName = BuildPublishScheduleName(publishSchedule.ItemToPublish);
                    Item optionsFolder = GetOrCreateFolder(publishSchedule.PublishDate);
                    Item publishOptionsItem = optionsFolder.Add(publishOptionsName, publishOptionsTemplate);

                    publishOptionsItem.Editing.BeginEdit();

                    publishOptionsItem[PublishSchedule.SchedulerEmailId] = publishSchedule.SchedulerEmail;
                    publishOptionsItem[PublishSchedule.UnpublishId] = publishSchedule.Unpublish ? "1" : string.Empty;
                    if (publishSchedule.ItemToPublish != null)
                    {
                        publishOptionsItem[PublishSchedule.ItemToPublishId] = publishSchedule.ItemToPublish.Paths.FullPath;
                    }
                    publishOptionsItem[PublishSchedule.PublishModeId] = publishSchedule.PublishMode.ToString();
                    publishOptionsItem[PublishSchedule.PublishChildrenId] = publishSchedule.PublishChildren ? "1" : string.Empty;
                    publishOptionsItem[PublishSchedule.TargetLanguagesId] =
                        string.Join("|", publishSchedule.TargetLanguages.Select(x => x.Name));
                    publishOptionsItem[PublishSchedule.SourceDatabaseId] = publishSchedule.SourceDatabase.Name;
                    publishOptionsItem[PublishSchedule.TargetDatabasesId] = string.Join("|", publishSchedule.TargetDatabases.Select(x => x.Name));
                    publishOptionsItem[PublishSchedule.PublishDateId] = DateUtil.ToIsoDate(publishSchedule.PublishDate);

                    publishOptionsItem.Editing.AcceptChanges();
                    publishOptionsItem.Editing.EndEdit();

                    Log.Info(
                        string.Format("Scheduled Publish: Created Publish Schedule: {0}: {1} {2} {3}",
                            action,
                            publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.Name : Constants.WEBSITE_PUBLISH_TEXT,
                            publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.ID.ToString() : Constants.WEBSITE_PUBLISH_TEXT,
                            DateTime.Now), new object());
                }
            }
            catch (Exception ex)
            {
                Log.Error(
                    string.Format("Scheduled Publish: Failed creating Publish Schedule: {0}: {1} {2} {3}",
                        action,
                        publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.Name : Constants.WEBSITE_PUBLISH_TEXT,
                        publishSchedule.ItemToPublish != null ? publishSchedule.ItemToPublish.ID.ToString() : Constants.WEBSITE_PUBLISH_TEXT,
                        ex), new object());
            }
        }
        /// <summary>
        /// Handles item publish.
        /// </summary>
        /// <param name="publishSchedule">A <see cref="ScheduledPublish.Models.PublishSchedule"/> schedule to publish.</param>
        /// <returns>A <see cref="T:Sitecore.Handle"/> publish handle.</returns>
        private static Handle PublishItem(PublishSchedule publishSchedule)
        {
            if (publishSchedule.ItemToPublish == null)
            {
                Log.Error("Scheduled Publish: Scheduled Publish Task didn't execute because PublishSchedule.ItemToPublish is null", new object());
                return null;
            }

            Handle handle = null;

            try
            {
                if (publishSchedule.Unpublish)
                {
                    using (new SecurityDisabler())
                    {
                        publishSchedule.ItemToPublish.Editing.BeginEdit();
                        publishSchedule.ItemToPublish.Publishing.NeverPublish = true;
                        publishSchedule.ItemToPublish.Editing.AcceptChanges();
                        publishSchedule.ItemToPublish.Editing.EndEdit();
                    }
                }

                handle = PublishManager.PublishItem(
                    publishSchedule.ItemToPublish,
                    publishSchedule.TargetDatabases.ToArray(),
                    publishSchedule.TargetLanguages.ToArray(),
                    publishSchedule.PublishChildren,
                    publishSchedule.PublishMode == PublishMode.Smart);

                WaitPublish(handle);

                if (publishSchedule.Unpublish)
                {
                    using (new SecurityDisabler())
                    {
                        publishSchedule.ItemToPublish.Editing.BeginEdit();
                        publishSchedule.ItemToPublish.Publishing.NeverPublish = false;
                        publishSchedule.ItemToPublish.Editing.AcceptChanges();
                        publishSchedule.ItemToPublish.Editing.EndEdit();
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(
                    string.Format("Scheduled Publish: Scheduled Publish Task failed for {0} {1} {2}",
                                   publishSchedule.ItemToPublish.Name,
                                   publishSchedule.ItemToPublish.ID,
                                   ex), new object());
            }

            return handle;
        }
 /// <summary>
 /// Handles the publish action.
 /// </summary>
 /// <param name="publishSchedule"></param>
 /// <returns>A <see cref="T:Sitecore.Handle"/> publish handle.</returns>
 public static Handle Publish(PublishSchedule publishSchedule)
 {
     return publishSchedule.ItemToPublish != null
         ? PublishItem(publishSchedule)
         : PublishWebsite(publishSchedule);
 }
        /// <summary>
        /// Handles website publish.
        /// </summary>
        /// <param name="publishSchedule">A <see cref="ScheduledPublish.Models.PublishSchedule"/> schedule to publish.</param>
        /// <returns>A <see cref="T:Sitecore.Handle"/> publish handle.</returns>
        private static Handle PublishWebsite(PublishSchedule publishSchedule)
        {
            Handle handle = null;

            try
            {
                switch (publishSchedule.PublishMode)
                {
                    case PublishMode.Smart:
                        {
                            handle = PublishManager.PublishSmart(
                                publishSchedule.SourceDatabase,
                                publishSchedule.TargetDatabases.ToArray(),
                                publishSchedule.TargetLanguages.ToArray());
                            break;
                        }
                    case PublishMode.Full:
                        {
                            handle = PublishManager.Republish(
                                publishSchedule.SourceDatabase,
                                publishSchedule.TargetDatabases.ToArray(),
                                publishSchedule.TargetLanguages.ToArray());
                            break;
                        }
                    case PublishMode.Incremental:
                        {
                            handle = PublishManager.PublishIncremental(
                                publishSchedule.SourceDatabase,
                                publishSchedule.TargetDatabases.ToArray(),
                                publishSchedule.TargetLanguages.ToArray());
                            break;
                        }
                    default:
                        {
                            Log.Error("Scheduled Publish: Scheduled Publish Task didn't execute because invalid PublishMode", new object());
                            break;
                        }
                }

                WaitPublish(handle);
            }
            catch (Exception ex)
            {
                Log.Error(
                    string.Format("Scheduled Publish: Scheduled Publish Task failed for Website Publish in {0} Mode {1}",
                                   publishSchedule.PublishMode,
                                   ex), new object());
            }

            return handle;
        }
        /// <summary>
        /// Handles a click on the OK button. Creates a task for publishing the selected item.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The arguments.</param>
        protected override void OnOK(object sender, EventArgs args)
        {
            Assert.ArgumentNotNull(sender, "sender");
            Assert.ArgumentNotNull(args, "args");

            using (new LanguageSwitcher(LanguageManager.DefaultLanguage))
            {
                PublishSchedule publishSchedule = new PublishSchedule
                {
                    ItemToPublish = InnerItem,
                    PublishDate = SelectedPublishDate,
                    SourceDatabase = _database,
                    TargetDatabases = SelectedTargets,
                    TargetLanguages = SelectedLanguages,
                    Unpublish = Unpublish,
                    PublishMode = SmartPublish.Checked ? PublishMode.Smart : PublishMode.Full,
                    PublishChildren = PublishChildren.Checked,
                    PublishRelatedItems = PublishRelatedItems.Checked,
                    SchedulerUsername = Context.User.Name,
                    IsPublished = false
                };

                if (Unpublish)
                {
                    publishSchedule.TargetLanguages = LanguageManager.GetLanguages(_database);
                }

                ValidationResult validationResult = ScheduledPublishValidator.Validate(publishSchedule);
                if (!validationResult.IsValid)
                {
                    SheerResponse.Alert(string.Join(Environment.NewLine, validationResult.ValidationErrors));
                    return;
                }

                _scheduledPublishRepo.CreatePublishSchedule(publishSchedule);
            }
            base.OnOK(sender, args);
        }
        /// <summary>
        /// Handles a click on the OK button. Creates a task for publishing the selected item.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The arguments.</param>
        protected override void OnOK(object sender, EventArgs args)
        {
            Assert.ArgumentNotNull(sender, "sender");
            Assert.ArgumentNotNull(args, "args");

            PublishSchedule publishSchedule = new PublishSchedule
            {
                ItemToPublish = InnerItem,
                PublishDate = SelectedPublishDate,
                SourceDatabase = _database,
                TargetDatabases = SelectedTargets,
                TargetLanguages = SelectedLanguages,
                Unpublish = Unpublish,
                PublishMode = SmartPublish.Checked ? PublishMode.Smart : PublishMode.Full,
                PublishChildren = PublishChildren.Checked,
                SchedulerEmail = Context.User.Profile.Email,
                IsPublished = false
            };

            ValidationResult validationResult = ScheduledPublishValidator.Validate(publishSchedule);
            if (!validationResult.IsValid)
            {
                SheerResponse.Alert(string.Join(Environment.NewLine, validationResult.ValidationErrors));
                return;
            }

            _scheduledPublishRepo.CreatePublishSchedule(publishSchedule);

            base.OnOK(sender, args);
        }