EmailTemplate PrepareEmailForEventOrganizer(EventRegistrationResult result,
                                                    IEventRegistrationCommand command,
                                                    Action <IGraffitiEmailContext> alterations)
        {
            IGraffitiEmailContext context = _emailContext;

            context.Put("request", HttpContext.Current.Request);
            context.Put("events", new EventMacros());
            context.Put("name", HttpUtility.HtmlEncode(command.Name));
            context.Put("attendeeEMail", HttpUtility.HtmlEncode(command.AttendeeEmail));
            context.Put("event", result.Post);
            context.Put("isCcToAttendee", false);
            context.Put("isOnWaitingList", result.OnWaitingList);
            context.Put("isAlreadyRegistered", result.AlreadyRegistered);

            if (alterations != null)
            {
                alterations(context);
            }

            return(new EmailTemplate
            {
                Subject = _repository.Configuration.RegistrationMailSubject,
                Context = context.ToEmailTemplateToolboxContext(),
                TemplateName = _registrationEmailTemplate,
                From = null,
                To = result.Post[_repository.Configuration.RegistrationRecipientField]
            });
        }
        protected override void Establish_context()
        {
            base.Establish_context();

            _command = MockRepository.GenerateMock <IEventRegistrationCommand>();
            CommandFactory.Stub(x => x.EventRegistration(null, null, null, true))
            .IgnoreArguments()
            .Return(_command);

            _result = MockRepository.GenerateMock <IHttpResponse>();
            _command.Stub(x => x.Execute()).Return(_result);
        }
		protected override void Establish_context()
		{
			base.Establish_context();

			_command = MockRepository.GenerateMock<IEventRegistrationCommand>();
			CommandFactory.Stub(x => x.EventRegistration(null, null, null, true))
				.IgnoreArguments()
				.Return(_command);

			_result = MockRepository.GenerateMock<IHttpResponse>();
			_command.Stub(x => x.Execute()).Return(_result);
		}
        EmailTemplate PrepareEmailForAttendee(EventRegistrationResult result, IEventRegistrationCommand command)
        {
            if (!command.SendConfirmationToAttendee)
            {
                return(null);
            }

            EmailTemplate template = PrepareEmailForEventOrganizer(result,
                                                                   command,
                                                                   context => context.Put("isCcToAttendee", true));

            // Send from the site's e-mail address.
            template.From = null;
            template.To   = command.AttendeeEmail;

            return(template);
        }
        public IEventRegistrationResultList RegisterForEvents(IEventRegistrationCommand command)
        {
            EventRegistrationResultList results = new EventRegistrationResultList();

            foreach (int eventId in command.EventsToRegister)
            {
                try
                {
                    var result = RegisterAttendeeForEvent(eventId, command);
                    results.Add(result);

                    SendEmail(PrepareEmailForEventOrganizer(result, command, null));
                    SendEmail(PrepareEmailForAttendee(result, command));
                }
                catch (Exception ex)
                {
                    Logger.Error(Create.New.LogMessage().WithTitle("Could not process registration for event {0}", eventId), ex);
                }
            }

            return(results);
        }
		public IEventRegistrationResultList RegisterForEvents(IEventRegistrationCommand command)
		{
			EventRegistrationResultList results = new EventRegistrationResultList();

			foreach (int eventId in command.EventsToRegister)
			{
				try
				{
					var result = RegisterAttendeeForEvent(eventId, command);
					results.Add(result);

					SendEmail(PrepareEmailForEventOrganizer(result, command, null));
					SendEmail(PrepareEmailForAttendee(result, command));
				}
				catch (Exception ex)
				{
					Logger.Error(Create.New.LogMessage().WithTitle("Could not process registration for event {0}", eventId), ex);
				}
			}

			return results;
		}
        EventRegistrationResult RegisterAttendeeForEvent(int eventId, IEventRegistrationCommand command)
        {
            try
            {
                Logger.Info(Create.New.LogMessage()
                            .WithTitle("Event registration received")
                            .WithMessage("From: {0}", command.AttendeeEmail));

                Post post = _repository.GetById(eventId);

                Logger.Info(Create.New.LogMessage()
                            .WithTitle("Processing event registration for event {0}", eventId)
                            .WithMessage("From: {0}, Recipient: {1}",
                                         command.AttendeeEmail,
                                         post[_repository.Configuration.RegistrationRecipientField]));

                // Only a single thread can work with posts such that two threads don't mess with the number of received
                // registrations. This does not prevent the CMS itself to work with the post, though.
                lock (PostLock)
                {
                    if (!post.RegistrationPossible(_repository.Configuration.RegistrationListField,
                                                   _repository.Configuration.MaximumNumberOfRegistrationsField,
                                                   _repository.Configuration.EarliestRegistrationField,
                                                   _repository.Configuration.LatestRegistrationField,
                                                   _repository.Configuration.StartDateField,
                                                   _clock))
                    {
                        Logger.Warn(Create.New
                                    .LogMessage()
                                    .WithTitle(
                                        "Received a registration for an event for which registration has been disabled. Event ID {0}",
                                        eventId));
                        return(EventRegistrationResult.NotAllowedFor(post));
                    }

                    var entries = EmailLines.Matches(post[_repository.Configuration.RegistrationListField] ?? String.Empty);

                    string[] lines = new string[entries.Count + 1];
                    for (int i = 0; i < entries.Count; i++)
                    {
                        lines[i] = entries[i].Groups["Email"].Value;
                    }

                    if (Array.Exists(lines, l => l != null && l.Equals(command.AttendeeEmail, StringComparison.OrdinalIgnoreCase)))
                    {
                        return(EventRegistrationResult.AlreadyRegisteredFor(post));
                    }

                    lines[entries.Count] = command.AttendeeEmail;

                    post[_repository.Configuration.RegistrationListField] = String.Join(Environment.NewLine, lines);

                    int numberOfRegistations        = lines.Length;
                    int maximumNumberOfRegistations = post[_repository.Configuration.MaximumNumberOfRegistrationsField]
                                                      .ToInt(int.MaxValue);

                    _repository.Save(post);

                    return(EventRegistrationResult.SuccessfullyRegisteredFor(post, numberOfRegistations > maximumNumberOfRegistations));
                }
            }
            catch (Exception ex)
            {
                Logger.Error(Create.New.LogMessage().WithTitle("Could not process registration for event ID {0}", eventId), ex);
                return(EventRegistrationResult.Error());
            }
        }
		EmailTemplate PrepareEmailForEventOrganizer(EventRegistrationResult result,
		                                            IEventRegistrationCommand command,
		                                            Action<IGraffitiEmailContext> alterations)
		{
			IGraffitiEmailContext context = _emailContext;
			context.Put("request", HttpContext.Current.Request);
			context.Put("events", new EventMacros());
			context.Put("name", HttpUtility.HtmlEncode(command.Name));
			context.Put("attendeeEMail", HttpUtility.HtmlEncode(command.AttendeeEmail));
			context.Put("event", result.Post);
			context.Put("isCcToAttendee", false);
			context.Put("isOnWaitingList", result.OnWaitingList);
			context.Put("isAlreadyRegistered", result.AlreadyRegistered);

			if (alterations != null)
			{
				alterations(context);
			}

			return new EmailTemplate
			       {
			       	Subject = _repository.Configuration.RegistrationMailSubject,
			       	Context = context.ToEmailTemplateToolboxContext(),
			       	TemplateName = _registrationEmailTemplate,
			       	From = null,
			       	To = result.Post[_repository.Configuration.RegistrationRecipientField]
			       };
		}
		EventRegistrationResult RegisterAttendeeForEvent(int eventId, IEventRegistrationCommand command)
		{
			try
			{
				Logger.Info(Create.New.LogMessage()
				            	.WithTitle("Event registration received")
				            	.WithMessage("From: {0}", command.AttendeeEmail));

				Post post = _repository.GetById(eventId);

				Logger.Info(Create.New.LogMessage()
				            	.WithTitle("Processing event registration for event {0}", eventId)
				            	.WithMessage("From: {0}, Recipient: {1}",
				            	             command.AttendeeEmail,
				            	             post[_repository.Configuration.RegistrationRecipientField]));

				// Only a single thread can work with posts such that two threads don't mess with the number of received 
				// registrations. This does not prevent the CMS itself to work with the post, though.
				lock (PostLock)
				{
					if (!post.RegistrationPossible(_repository.Configuration.RegistrationListField,
					                               _repository.Configuration.MaximumNumberOfRegistrationsField,
					                               _repository.Configuration.EarliestRegistrationField,
					                               _repository.Configuration.LatestRegistrationField,
					                               _repository.Configuration.StartDateField,
												   _clock))
					{
						Logger.Warn(Create.New
						            	.LogMessage()
						            	.WithTitle(
						            	"Received a registration for an event for which registration has been disabled. Event ID {0}",
						            	eventId));
						return EventRegistrationResult.NotAllowedFor(post);
					}

					var entries = EmailLines.Matches(post[_repository.Configuration.RegistrationListField] ?? String.Empty);

					string[] lines = new string[entries.Count + 1];
					for (int i = 0; i < entries.Count; i++)
					{
						lines[i] = entries[i].Groups["Email"].Value;
					}

					if (Array.Exists(lines, l => l != null && l.Equals(command.AttendeeEmail, StringComparison.OrdinalIgnoreCase)))
					{
						return EventRegistrationResult.AlreadyRegisteredFor(post);
					}

					lines[entries.Count] = command.AttendeeEmail;

					post[_repository.Configuration.RegistrationListField] = String.Join(Environment.NewLine, lines);

					int numberOfRegistations = lines.Length;
					int maximumNumberOfRegistations = post[_repository.Configuration.MaximumNumberOfRegistrationsField]
						.ToInt(int.MaxValue);

					_repository.Save(post);

					return EventRegistrationResult.SuccessfullyRegisteredFor(post, numberOfRegistations > maximumNumberOfRegistations);
				}
			}
			catch (Exception ex)
			{
				Logger.Error(Create.New.LogMessage().WithTitle("Could not process registration for event ID {0}", eventId), ex);
				return EventRegistrationResult.Error();
			}
		}
		EmailTemplate PrepareEmailForAttendee(EventRegistrationResult result, IEventRegistrationCommand command)
		{
			if (!command.SendConfirmationToAttendee)
			{
				return null;
			}

			EmailTemplate template = PrepareEmailForEventOrganizer(result,
			                                                       command,
			                                                       context => context.Put("isCcToAttendee", true));

			// Send from the site's e-mail address.
			template.From = null;
			template.To = command.AttendeeEmail;

			return template;
		}