The data access/service class for Rock.Model.ExceptionLog entity type objects.
Exemple #1
0
        /// <summary> 
        /// Job that updates the JobPulse setting with the current date/time.
        /// This will allow us to notify an admin if the jobs stop running.
        /// 
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // get the job map
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            // delete accounts that have not been confirmed in X hours
            int userExpireHours = Int32.Parse( dataMap.GetString( "HoursKeepUnconfirmedAccounts" ) );
            DateTime userAccountExpireDate = DateTime.Now.Add( new TimeSpan( userExpireHours * -1,0,0 ) );

            UserService userService = new UserService();

            foreach (var user in userService.Queryable().Where(u => u.IsConfirmed == false && u.CreationDate < userAccountExpireDate))
            {
                userService.Delete( user, null );
            }

            userService.Save( null, null );

            // purge exception log
            int exceptionExpireDays = Int32.Parse( dataMap.GetString( "DaysKeepExceptions" ) );
            DateTime exceptionExpireDate = DateTime.Now.Add( new TimeSpan( userExpireHours * -1, 0, 0 ) );

            ExceptionLogService exceptionLogService = new ExceptionLogService();

            foreach ( var exception in exceptionLogService.Queryable().Where( e => e.ExceptionDate < exceptionExpireDate ) )
            {
                exceptionLogService.Delete( exception, null );
            }

            exceptionLogService.Save( null, null );
        }
        /// <summary>
        /// Shows the detail of the exception
        /// </summary>
        /// <param name="exceptionId">The exception identifier.</param>
        public void ShowDetail( int exceptionId )
        {
            ExceptionLog baseException = null;

            if ( exceptionId != 0 )
            {
                baseException = new ExceptionLogService( new RockContext() ).Get( exceptionId );
            }

            //set fields
            if ( baseException == null )
            {
                pnlSummary.Visible = false;
                return;
            }

            // set page title
            lPageTitle.Text = String.Format("Exception Overview").FormatAsHtmlTitle();

            DescriptionList dl = new DescriptionList();

            dl.Add( "Site", baseException.Site != null ? baseException.Site.Name : String.Empty, true );
            if ( baseException.Page != null || !string.IsNullOrWhiteSpace(baseException.PageUrl) )
            {
                dl.Add( "Page", string.Format( "{0} <a href=\"{1}\" class=\"btn btn-link btn-xs\" target=\"_blank\">Visit Page</a>", baseException.Page != null ? baseException.Page.InternalName : baseException.PageUrl.EncodeHtml(), baseException.PageUrl.EncodeHtml() ) );
            }

            //If query string is not empty build query string list
            if ( !String.IsNullOrWhiteSpace( baseException.QueryString ) )
            {
                dl.Add( "Query String", BuildQueryStringList( baseException.QueryString.EncodeHtml() ) );
            }

            if (baseException.CreatedByPersonAlias != null &&  baseException.CreatedByPersonAlias.Person != null)
            {
                dl.Add( "User", baseException.CreatedByPersonAlias.Person.FullName );
            }

            if ( baseException.CreatedDateTime.HasValue )
            {
                dl.Add( "Exception Date", string.Format( "{0:g}", baseException.CreatedDateTime.Value ) );
            }

            lExceptionSummary.Text = dl.Html;

            lCookies.Text = baseException.Cookies;
            lServerVariables.Text = baseException.ServerVariables;
            lFormData.Text = baseException.Form;
            btnShowCookies.Visible = !string.IsNullOrWhiteSpace( baseException.Cookies );
            btnShowVariables.Visible = !string.IsNullOrWhiteSpace( baseException.ServerVariables );
            btnShowFormData.Visible = !string.IsNullOrWhiteSpace( baseException.Form );

            rptExcpetionDetails.DataSource = GetExceptionLogs( baseException ).OrderBy( e => e.Id );
            rptExcpetionDetails.DataBind();

            pnlSummary.Visible = true;
        }
        /// <summary>
        /// Handles the GridRebind event of the gExceptionOccurrences control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void gExceptionOccurrences_GridRebind( object sender, EventArgs e )
        {
            int exceptionID = 0;
            if ( int.TryParse( hfBaseExceptionID.Value, out exceptionID ) )
            {
                ExceptionLogService exceptionService = new ExceptionLogService( new RockContext() );
                ExceptionLog baseException = exceptionService.Get( exceptionID );

                BindExceptionOccurrenceGrid( baseException );
            }
        }
        /// <summary>
        /// Loads the control.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            if ( !Page.IsPostBack )
            {
                //Set Exception Panel visibility to show Exception List
                SetExceptionPanelVisibility( None.Id );
            }

            // get data for graphs
            ExceptionLogService exceptionLogService = new ExceptionLogService( new RockContext() );
            var exceptionList = exceptionLogService.Queryable()
            .Where(x => x.HasInnerException == false && x.CreatedDateTime != null)
            .GroupBy( x => DbFunctions.TruncateTime(x.CreatedDateTime.Value ))
            .Select( eg => new
            {
                DateValue = eg.Key,
                ExceptionCount = eg.Count(),
                UniqueExceptionCount = eg.Select( y => y.ExceptionType ).Distinct().Count()
            } ).OrderBy(eg => eg.DateValue).ToList();

            if ( exceptionList.Count > 1 )
            {

                StringBuilder sbChartData = new StringBuilder();
                //sbChartData.Append( "[['Date', 'Unique Exceptions', 'Total Exceptions']," );
                sbChartData.Append( "data.addColumn('date', 'Date');\n" );
                sbChartData.Append( "data.addColumn('number', 'Unique Exceptions');\n" );
                sbChartData.Append( "data.addColumn('number', 'Total Exceptions');\n" );

                // load datatable
                foreach ( var exception in exceptionList )
                {
                    //sbChartData.Append( String.Format( "['{0}', {1}, {2}],", exception.DateValue.Value.ToShortDateString(), exception.UniqueExceptionCount, exception.ExceptionCount ) );
                    sbChartData.Append( String.Format( "data.addRow([new Date({0}, {1}, {2}), {3}, {4}]);\n", exception.DateValue.Value.Year, (exception.DateValue.Value.Month - 1), exception.DateValue.Value.Day, exception.UniqueExceptionCount, exception.ExceptionCount ) );
                }

                lGraphScript.Text = String.Format( @"

            <script type=""text/javascript"">
                google.load(""visualization"", ""1"", {{ packages: [""corechart""] }});
                google.setOnLoadCallback(drawChart);

                function drawChart() {{
                    var data = new google.visualization.DataTable();
                    {0}

                    var options = {{
                        vAxis: {{ title: 'Exception Count', minValue: 0, titleTextStyle: {{ color: '#515151',  italic: 'false' }} }},
                        backgroundColor: 'transparent',
                        colors: ['#8498ab', '#a4b4c4', '#b9c7d5', '#c6d2df', '#d8e1ea'],
                        hAxis: {{  textStyle: {{ color: '#515151' }}, baselineColor: '#515151' }},
                        legend: {{ position: 'bottom', textStyle: {{ color: '#515151' }} }}
                    }};

                    var chart = new google.visualization.AreaChart(document.getElementById('exception-chart'));
                    chart.draw(data, options);

                    $(window).smartresize(function(){{
                        chart.draw(data, options);
                    }});

                }}

            </script>", sbChartData.ToString() );
            }
            else
            {
                pnlExceptionChart.Visible = false;
            }
        }
        /// <summary>
        /// Loads the control.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            if ( !Page.IsPostBack )
            {
                //Set Exception Panel visibility to show Exception List
                SetExceptionPanelVisibility( None.Id );
            }

            lcExceptions.Options.SetChartStyle( this.ChartStyle );
            lcExceptions.Options.legend = lcExceptions.Options.legend ?? new Legend();
            lcExceptions.Options.legend.show = this.GetAttributeValue( "ShowLegend" ).AsBooleanOrNull();
            lcExceptions.Options.legend.position = this.GetAttributeValue( "LegendPosition" );

            bcExceptions.Options.SetChartStyle( this.ChartStyle );
            bcExceptions.Options.legend = bcExceptions.Options.legend ?? new Legend();
            bcExceptions.Options.legend.show = this.GetAttributeValue( "ShowLegend" ).AsBooleanOrNull();
            bcExceptions.Options.legend.position = this.GetAttributeValue( "LegendPosition" );
            bcExceptions.Options.xaxis = new AxisOptions { mode = AxisMode.categories, tickLength = 0 };
            bcExceptions.Options.series.bars.barWidth = 0.6;
            bcExceptions.Options.series.bars.align = "center";

            bcExceptions.TooltipFormatter = @"
            function(item) {
            var itemDate = new Date(item.series.chartData[item.dataIndex].DateTimeStamp);
            var dateText = itemDate.toLocaleDateString();
            var seriesLabel = item.series.label || ( item.series.labels ? item.series.labels[item.dataIndex] : null );
            var pointValue = item.series.chartData[item.dataIndex].YValue || item.series.chartData[item.dataIndex].YValueTotal || '-';
            return dateText + '<br />' + seriesLabel + ': ' + pointValue;
            }
            ";

            // get data for graphs
            ExceptionLogService exceptionLogService = new ExceptionLogService( new RockContext() );
            var exceptionListCount = exceptionLogService.Queryable()
            .Where( x => x.HasInnerException == false && x.CreatedDateTime != null )
            .GroupBy( x => DbFunctions.TruncateTime( x.CreatedDateTime.Value ) )
            .Count();

            if ( exceptionListCount == 1 )
            {
                // if there is only one x datapoint for the Chart, show it as a barchart
                lcExceptions.Visible = false;
                bcExceptions.Visible = true;
            }
            else
            {
                lcExceptions.Visible = true;
                bcExceptions.Visible = false;
            }
        }
Exemple #6
0
        /// <summary>
        /// Logs the error.
        /// </summary>
        /// <param name="ex">The ex.</param>
        /// <param name="parentException">The parent exception.</param>
        /// <param name="status">The status.</param>
        /// <param name="context">The context.</param>
        private void LogError( Exception ex, int parentException, string status, System.Web.HttpContext context )
        {
            try
            {
                // get the current user
                Rock.Model.UserLogin user = Rock.Model.UserService.GetCurrentUser();

                // save the exception info to the db
                ExceptionLogService service = new ExceptionLogService();
                ExceptionLog exceptionLog = new ExceptionLog(); ;

                exceptionLog.ParentId = parentException;
                exceptionLog.ExceptionDate = DateTime.Now;

                if ( ex.InnerException != null )
                    exceptionLog.HasInnerException = true;

                exceptionLog.Description = ex.Message;
                exceptionLog.StackTrace = ex.StackTrace;
                exceptionLog.Source = ex.Source;
                exceptionLog.StatusCode = status;

                if ( context.Items["Rock:SiteId"] != null )
                    exceptionLog.SiteId = Int32.Parse( context.Items["Rock:SiteId"].ToString() );

                if ( context.Items["Rock:PageId"] != null )
                    exceptionLog.PageId = Int32.Parse( context.Items["Rock:PageId"].ToString() );

                exceptionLog.ExceptionType = ex.GetType().Name;
                exceptionLog.PageUrl = context.Request.RawUrl;

                exceptionLog.QueryString = context.Request.QueryString.ToString();

                // write cookies
                StringBuilder cookies = new StringBuilder();
                cookies.Append( "<table class=\"cookies\">" );

                foreach ( string cookie in context.Request.Cookies )
                    cookies.Append( "<tr><td><b>" + cookie + "</b></td><td>" + context.Request.Cookies[cookie].Value + "</td></tr>" );

                cookies.Append( "</table>" );
                exceptionLog.Cookies = cookies.ToString();

                // write form items
                StringBuilder formItems = new StringBuilder();
                cookies.Append( "<table class=\"formItems\">" );

                foreach ( string formItem in context.Request.Form )
                    cookies.Append( "<tr><td><b>" + formItem + "</b></td><td>" + context.Request.Form[formItem].ToString() + "</td></tr>" );

                cookies.Append( "</table>" );
                exceptionLog.Form = formItems.ToString();

                // write server vars
                StringBuilder serverVars = new StringBuilder();
                cookies.Append( "<table class=\"server-variables\">" );

                foreach ( string serverVar in context.Request.ServerVariables )
                    serverVars.Append( "<tr><td><b>" + serverVar + "</b></td><td>" + context.Request.ServerVariables[serverVar].ToString() + "</td></tr>" );

                cookies.Append( "</table>" );
                exceptionLog.ServerVariables = serverVars.ToString();

                if ( user != null )
                    exceptionLog.CreatedByPersonId = user.PersonId;

                service.Add( exceptionLog, null );
                service.Save( exceptionLog, null );

                //  log inner exceptions
                if ( ex.InnerException != null )
                    LogError( ex.InnerException, exceptionLog.Id, status, context );

            }
            catch ( Exception )
            {
                // if you get an exception while logging an exception I guess you're hosed...
                try
                {
                    EventLog.WriteEntry( "Rock", string.Format( "Exception in Global.LogError(): {0}", ex.Message ), EventLogEntryType.Error );
                }
                catch
                {
                }
            }
        }
            /// <summary>
            /// Called before the save operation is executed.
            /// </summary>
            protected override void PreSave()
            {
                HistoryChanges = new History.HistoryChangeList();

                switch (State)
                {
                case EntityContextState.Added:
                {
                    // Get the authentication provider entity type
                    var entityType = EntityTypeCache.Get(Entity.EntityTypeId ?? 0);
                    var change     = HistoryChanges.AddChange(History.HistoryVerb.Add, History.HistoryChangeType.Record, "Authentication Provider").SetNewValue(entityType?.FriendlyName);

                    // Don't log Pin Authentication user names.
                    var isUserNameSensitive = (entityType?.Guid == Rock.SystemGuid.EntityType.AUTHENTICATION_PIN.AsGuid()) ? true : false;

                    if (isUserNameSensitive)
                    {
                        change.SetCaption("User Account");
                    }

                    History.EvaluateChange(HistoryChanges, "User Login", string.Empty, Entity.UserName, isUserNameSensitive);
                    History.EvaluateChange(HistoryChanges, "Is Confirmed", null, Entity.IsConfirmed);
                    History.EvaluateChange(HistoryChanges, "Is Password Change Required", null, Entity.IsPasswordChangeRequired);
                    History.EvaluateChange(HistoryChanges, "Is Locked Out", null, Entity.IsLockedOut);

                    break;
                }

                case EntityContextState.Modified:
                {
                    var entityType = EntityTypeCache.Get(Entity.EntityTypeId ?? 0);

                    // Don't log Pin Authentication user names.
                    var isUserNameSensitive = (entityType?.Guid == Rock.SystemGuid.EntityType.AUTHENTICATION_PIN.AsGuid()) ? true : false;

                    History.EvaluateChange(HistoryChanges, "User Login", OriginalValues[nameof(UserLogin.UserName)].ToStringSafe(), Entity.UserName, isUserNameSensitive);
                    History.EvaluateChange(HistoryChanges, "Is Confirmed", OriginalValues[nameof(UserLogin.IsConfirmed)].ToStringSafe().AsBooleanOrNull(), Entity.IsConfirmed);
                    History.EvaluateChange(HistoryChanges, "Is Password Change Required", OriginalValues[nameof(UserLogin.IsPasswordChangeRequired)].ToStringSafe().AsBooleanOrNull(), Entity.IsPasswordChangeRequired);
                    History.EvaluateChange(HistoryChanges, "Is Locked Out", OriginalValues[nameof(UserLogin.IsLockedOut)].ToStringSafe().AsBooleanOrNull(), Entity.IsLockedOut);
                    History.EvaluateChange(HistoryChanges, "Password", OriginalValues[nameof(UserLogin.Password)].ToStringSafe(), Entity.Password, true);

                    // Did the provider type change?
                    int?origEntityTypeId = OriginalValues[nameof(UserLogin.EntityTypeId)].ToStringSafe().AsIntegerOrNull();
                    int?entityTypeId     = Entity.EntityType != null ? Entity.EntityType.Id : Entity.EntityTypeId;
                    if (!entityTypeId.Equals(origEntityTypeId))
                    {
                        var origProviderType = EntityTypeCache.Get(origEntityTypeId ?? 0)?.FriendlyName;
                        var providerType     = EntityTypeCache.Get(Entity.EntityTypeId ?? 0)?.FriendlyName;
                        History.EvaluateChange(HistoryChanges, "User Login", origProviderType, providerType);
                    }

                    // Change the caption if this is a sensitive user account
                    if (HistoryChanges.Count > 0 && isUserNameSensitive)
                    {
                        var change = HistoryChanges.FirstOrDefault();
                        change.SetCaption("User Account");
                    }

                    break;
                }

                case EntityContextState.Deleted:
                {
                    // By this point EF has stripped out some of the data we need to save history
                    // Reload the data using a new context.
                    RockContext newRockContext = new RockContext();
                    var         userLogin      = new UserLoginService(newRockContext).Get(Entity.Id);
                    if (userLogin != null && userLogin.PersonId != null)
                    {
                        try
                        {
                            var entityType          = EntityTypeCache.Get(userLogin.EntityTypeId ?? 0);
                            var isUserNameSensitive = (entityType?.Guid == Rock.SystemGuid.EntityType.AUTHENTICATION_PIN.AsGuid()) ? true : false;

                            if (!isUserNameSensitive)
                            {
                                HistoryChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "User Login").SetOldValue(userLogin.UserName);
                                HistoryService.SaveChanges(newRockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_ACTIVITY.AsGuid(), userLogin.PersonId.Value, HistoryChanges, Entity.UserName, typeof(UserLogin), Entity.Id, true, userLogin.ModifiedByPersonAliasId, null);
                            }
                            else
                            {
                                HistoryChanges.AddChange(History.HistoryVerb.Delete, History.HistoryChangeType.Record, "Authentication Provider").SetOldValue(entityType?.FriendlyName).SetCaption("User Account");
                                HistoryService.SaveChanges(newRockContext, typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON_ACTIVITY.AsGuid(), userLogin.PersonId.Value, HistoryChanges, entityType?.FriendlyName, typeof(UserLogin), Entity.Id, true, userLogin.ModifiedByPersonAliasId, null);
                            }
                        }
                        catch (Exception ex)
                        {
                            // Just log the problem and move on...
                            ExceptionLogService.LogException(ex);
                        }
                    }

                    HistoryChanges.Clear();
                    return;
                }
                }

                base.PreSave();
            }
        /// <summary>
        /// Gets the related exception logs
        /// </summary>
        /// <param name="baseException">The base exception.</param>
        /// <returns>List of Exception Detail Summary objects</returns>
        private List<ExceptionLog> GetExceptionLogs( ExceptionLog baseException )
        {
            List<ExceptionLog> exceptionList = new List<ExceptionLog>();
            ExceptionLogService svc = new ExceptionLogService( new RockContext() );

            //load the base exception
            exceptionList.Add( baseException );

            //get the parentID
            int? parentId = baseException.ParentId;

            //loop through exception hierarchy (parent, grandparent, etc)
            while ( parentId != null && parentId > 0 )
            {
                var exception = svc.Get( (int)parentId );

                if ( exception != null )
                {
                    exceptionList.Add( exception );
                }

                parentId = exception.ParentId;
            }

            //get inner exceptions
            if ( baseException.HasInnerException != null &&  (bool)baseException.HasInnerException )
            {
                exceptionList.AddRange( svc.GetByParentId( baseException.Id ) );
            }

            return exceptionList;
        }
        /// <summary>
        /// Schedules the Job to run immediately using the Quartz Scheduler
        /// and waits for the job to finish.
        /// Returns <c>false</c> with an <c>out</c> <paramref name="errorMessage"/> if the job is already running as a RunNow job or if an exception occurs.
        /// NOTE: This will take at least 10 seconds to ensure the Quartz scheduler successfully started the job, plus any additional time that might
        /// still be needed to complete the job.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <param name="errorMessage">The error message.</param>
        /// <returns></returns>
        public bool RunNow(ServiceJob job, out string errorMessage)
        {
            // use a new RockContext instead of using this.Context so we can SaveChanges without affecting other RockContext's with pending changes.
            var rockContext = new RockContext();

            errorMessage = string.Empty;
            try
            {
                // create a scheduler specific for the job
                var scheduleConfig = new NameValueCollection();

                var jobId = job.Id;

                var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40);
                scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName);
                var schedulerFactory = new StdSchedulerFactory(scheduleConfig);
                var sched            = new StdSchedulerFactory(scheduleConfig).GetScheduler();

                if (sched.IsStarted)
                {
                    // the job is currently running as a RunNow job
                    errorMessage = "Job already running as a RunNow job";
                    return(false);
                }

                // Check if another scheduler is running this job
                try
                {
                    var otherSchedulers = new StdSchedulerFactory()
                                          .AllSchedulers
                                          .Where(s => s.SchedulerName != runNowSchedulerName);

                    foreach (var scheduler in otherSchedulers)
                    {
                        var isAlreadyRunning = scheduler.GetCurrentlyExecutingJobs()
                                               .Where(j =>
                                                      j.JobDetail.Description == jobId.ToString() &&
                                                      j.JobDetail.ConcurrentExectionDisallowed)
                                               .Any();

                        if (isAlreadyRunning)
                        {
                            // A job with that Id is already running and ConcurrentExectionDisallowed is true
                            errorMessage = $" Scheduler '{scheduler.SchedulerName}' is already executing job Id '{jobId}' (name: {job.Name})";
                            System.Diagnostics.Debug.WriteLine($"{RockDateTime.Now.ToString()} {errorMessage}");
                            return(false);
                        }
                    }
                }
                catch
                {
                    // Was blank in the RunJobNowTransaction (intentional?)
                }

                // create the quartz job and trigger
                var jobDetail  = new ServiceJobService(rockContext).BuildQuartzJob(job);
                var jobDataMap = jobDetail.JobDataMap;

                if (jobDataMap != null)
                {
                    // Force the <string, string> dictionary so that within Jobs, it is always okay to use
                    // JobDataMap.GetString(). This mimics Rock attributes always being stored as strings.
                    // If we allow non-strings, like integers, then JobDataMap.GetString() throws an exception.
                    jobDetail.JobDataMap.PutAll(jobDataMap.ToDictionary(kvp => kvp.Key, kvp => ( object )kvp.Value));
                }

                var jobTrigger = TriggerBuilder.Create()
                                 .WithIdentity(job.Guid.ToString(), job.Name)
                                 .StartNow()
                                 .Build();

                // schedule the job
                sched.ScheduleJob(jobDetail, jobTrigger);

                // set up the listener to report back from the job when it completes
                sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                // start the scheduler
                sched.Start();

                // Wait 10secs to give scheduler to start the job.
                // If we don't do this, the scheduler might Shutdown thinking there are no running jobs
                Task.Delay(10 * 1000).Wait();

                // stop the scheduler when done with job
                sched.Shutdown(true);

                return(true);
            }
            catch (Exception ex)
            {
                // create a friendly error message
                ExceptionLogService.LogException(ex, null);
                errorMessage          = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message);
                job.LastStatusMessage = errorMessage;
                job.LastStatus        = "Error Loading Job";
                rockContext.SaveChanges();

                var jobHistoryService = new ServiceJobHistoryService(rockContext);
                var jobHistory        = new ServiceJobHistory
                {
                    ServiceJobId  = job.Id,
                    StartDateTime = RockDateTime.Now,
                    StopDateTime  = RockDateTime.Now,
                    Status        = job.LastStatus,
                    StatusMessage = job.LastStatusMessage
                };

                jobHistoryService.Add(jobHistory);
                rockContext.SaveChanges();

                return(false);
            }
        }
Exemple #10
0
        /// <summary>
        /// Gets the Linq expression for the DataViewFilter.
        /// </summary>
        /// <param name="filteredEntityType">The object type of the filtered entity.</param>
        /// <param name="serviceInstance">A <see cref="System.Object"/> that contains the service reference.</param>
        /// <param name="parameter">A <see cref="System.Linq.Expressions.ParameterExpression"/> containing the parameter for the expression.</param>
        /// <param name="errorMessages">A <see cref="System.Collections.Generic.List{String}"/> that contains any error/exception messages that are returned.</param>
        /// <returns></returns>
        public virtual Expression GetExpression(Type filteredEntityType, IService serviceInstance, ParameterExpression parameter, List <string> errorMessages)
        {
            switch (ExpressionType)
            {
            case FilterExpressionType.Filter:

                if (this.EntityTypeId.HasValue)
                {
                    var entityType = Rock.Web.Cache.EntityTypeCache.Read(this.EntityTypeId.Value);
                    if (entityType != null)
                    {
                        var component = Rock.Reporting.DataFilterContainer.GetComponent(entityType.Name);
                        if (component != null)
                        {
                            try
                            {
                                return(component.GetExpression(filteredEntityType, serviceInstance, parameter, this.Selection));
                            }
                            catch (SystemException ex)
                            {
                                ExceptionLogService.LogException(ex, System.Web.HttpContext.Current);
                                errorMessages.Add(string.Format("{0}: {1}", component.FormatSelection(filteredEntityType, this.Selection), ex.Message));
                            }
                        }
                    }
                }
                return(null);

            case FilterExpressionType.GroupAll:
            case FilterExpressionType.GroupAnyFalse:

                Expression andExp = null;
                foreach (var filter in this.ChildFilters)
                {
                    Expression exp = filter.GetExpression(filteredEntityType, serviceInstance, parameter, errorMessages);
                    if (exp != null)
                    {
                        if (andExp == null)
                        {
                            andExp = exp;
                        }
                        else
                        {
                            andExp = Expression.AndAlso(andExp, exp);
                        }
                    }
                }

                if (ExpressionType == FilterExpressionType.GroupAnyFalse &&
                    andExp != null)
                {
                    // If only one of the conditions must be false, invert the expression so that it becomes the logical equivalent of "NOT ALL".
                    andExp = Expression.Not(andExp);
                }

                return(andExp);

            case FilterExpressionType.GroupAny:
            case FilterExpressionType.GroupAllFalse:

                Expression orExp = null;
                foreach (var filter in this.ChildFilters)
                {
                    Expression exp = filter.GetExpression(filteredEntityType, serviceInstance, parameter, errorMessages);
                    if (exp != null)
                    {
                        if (orExp == null)
                        {
                            orExp = exp;
                        }
                        else
                        {
                            orExp = Expression.OrElse(orExp, exp);
                        }
                    }
                }

                if (ExpressionType == FilterExpressionType.GroupAllFalse &&
                    orExp != null)
                {
                    // If all of the conditions must be false, invert the expression so that it becomes the logical equivalent of "NOT ANY".
                    orExp = Expression.Not(orExp);
                }

                return(orExp);
            }

            return(null);
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            if ( !Page.IsPostBack )
            {
                //show the detail
                int? exceptionId = PageParameter( "ExceptionId" ).AsIntegerOrNull();
                if (!exceptionId.HasValue)
                {
                    Guid? exceptionGuid = PageParameter( "ExceptionGuid" ).AsGuidOrNull();
                    if (exceptionGuid.HasValue)
                    {
                        exceptionId = new ExceptionLogService( new RockContext() ).Queryable().Where( a => a.Guid == exceptionGuid.Value ).Select( a => a.Id ).FirstOrDefault();
                    }
                }

                ShowDetail( exceptionId ?? 0 );
            }
        }
Exemple #12
0
        /// <summary> 
        /// Job that executes routine Rock cleanup tasks
        /// 
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void  Execute(IJobExecutionContext context)
        {
            
            // get the job map
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            // delete accounts that have not been confirmed in X hours
            int userExpireHours = Int32.Parse( dataMap.GetString( "HoursKeepUnconfirmedAccounts" ) );
            DateTime userAccountExpireDate = DateTime.Now.Add( new TimeSpan( userExpireHours * -1,0,0 ) );

            var userLoginService = new UserLoginService();

            foreach (var user in userLoginService.Queryable().Where(u => u.IsConfirmed == false && u.CreationDateTime < userAccountExpireDate).ToList() )
            {
                userLoginService.Delete( user, null );
                userLoginService.Save( user, null );
            }

            // purge exception log
            int exceptionExpireDays = Int32.Parse( dataMap.GetString( "DaysKeepExceptions" ) );
            DateTime exceptionExpireDate = DateTime.Now.Add( new TimeSpan( exceptionExpireDays * -1, 0, 0, 0 ) );

            ExceptionLogService exceptionLogService = new ExceptionLogService();

            foreach ( var exception in exceptionLogService.Queryable().Where( e => e.ExceptionDateTime < exceptionExpireDate ).ToList() )
            {
                exceptionLogService.Delete( exception, null );
                exceptionLogService.Save( exception, null );
            }

            // purge audit log
            int auditExpireDays = Int32.Parse( dataMap.GetString( "AuditLogExpirationDays" ) );
            DateTime auditExpireDate = DateTime.Now.Add( new TimeSpan( auditExpireDays * -1, 0, 0, 0 ) );
            AuditService auditService = new AuditService();
            foreach( var audit in auditService.Queryable().Where( a => a.DateTime < auditExpireDate ).ToList() )
            {
                auditService.Delete( audit, null );
                auditService.Save( audit, null );
            }

            // clean the cached file directory

            //get the attributes
            string cacheDirectoryPath = dataMap.GetString( "BaseCacheDirectory" );
            int cacheExpirationDays = int.Parse( dataMap.GetString( "DaysKeepCachedFiles" ) );
            DateTime cacheExpirationDate = DateTime.Now.Add( new TimeSpan( cacheExpirationDays * -1, 0, 0, 0 ) );

            //if job is being run by the IIS scheduler and path is not null
            if ( context.Scheduler.SchedulerName == "RockSchedulerIIS" && !String.IsNullOrEmpty( cacheDirectoryPath ) )
            {
                //get the physical path of the cache directory
                cacheDirectoryPath = System.Web.Hosting.HostingEnvironment.MapPath( cacheDirectoryPath );
            }

            //if directory is not blank and cache expiration date not in the future
            if ( !String.IsNullOrEmpty( cacheDirectoryPath ) && cacheExpirationDate <= DateTime.Now )
            {
                //Clean cache directory
                CleanCacheDirectory( cacheDirectoryPath, cacheExpirationDate );
            }

            // clean out any temporary binary files
            BinaryFileService binaryFileService = new BinaryFileService();
            foreach( var binaryFile in binaryFileService.Queryable().Where( bf => bf.IsTemporary == true ).ToList() )
            {
                if ( binaryFile.LastModifiedDateTime < DateTime.Now.AddDays(-1) )
                {
                    binaryFileService.Delete( binaryFile, null );
                    binaryFileService.Save( binaryFile, null );
                }
            }

        }
Exemple #13
0
        /// <summary>
        /// Returns a list of each person and their GroupRequiremnt status for this group requirement
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="personQry">The person qry.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="groupRoleId">The group role identifier.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">No dataview assigned to Group Requirement Type: " + this.GroupRequirementType.Name</exception>
        public IEnumerable <PersonGroupRequirementStatus> PersonQueryableMeetsGroupRequirement(RockContext rockContext, IQueryable <Person> personQry, int groupId, int?groupRoleId)
        {
            if ((this.GroupRoleId != null) && (groupRoleId != null) && (this.GroupRoleId != groupRoleId))
            {
                // if this GroupRequirement is for a specific role, the groupRole we are checking for is something different
                var result = personQry.ToList().Select(a =>
                                                       new PersonGroupRequirementStatus
                {
                    PersonId              = a.Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = MeetsGroupRequirement.NotApplicable
                });

                return(result);
            }

            if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Dataview)
            {
                if (this.GroupRequirementType.DataViewId.HasValue)
                {
                    var errorMessages           = new List <string>();
                    var personService           = new PersonService(rockContext);
                    var paramExpression         = personService.ParameterExpression;
                    var dataViewWhereExpression = this.GroupRequirementType.DataView.GetExpression(personService, paramExpression, out errorMessages);
                    var dataViewQry             = personService.Get(paramExpression, dataViewWhereExpression);

                    IQueryable <Person> warningDataViewQry = null;
                    if (this.GroupRequirementType.WarningDataViewId.HasValue)
                    {
                        var warningDataViewWhereExpression = this.GroupRequirementType.WarningDataView.GetExpression(personService, paramExpression, out errorMessages);
                        warningDataViewQry = personService.Get(paramExpression, warningDataViewWhereExpression);
                    }

                    if (dataViewQry != null)
                    {
                        var personWithRequirements = from p in personQry
                                                     join d in dataViewQry on p equals d into oj
                                                     from d in oj.DefaultIfEmpty()
                                                     select new { PersonId = p.Id, Included = d != null, WarningIncluded = false };

                        // if a Warning Database was specified, set the WarningIncluded flag to true if they are included in the Warning Dataview
                        if (warningDataViewQry != null)
                        {
                            personWithRequirements = personWithRequirements.Select(a => new
                            {
                                a.PersonId,
                                a.Included,
                                WarningIncluded = warningDataViewQry.Any(w => w.Id == a.PersonId)
                            });
                        }

                        var result = personWithRequirements.ToList().Select(a =>
                                                                            new PersonGroupRequirementStatus
                        {
                            PersonId              = a.PersonId,
                            GroupRequirement      = this,
                            MeetsGroupRequirement = a.Included
                                    ? (a.WarningIncluded ? MeetsGroupRequirement.MeetsWithWarning : MeetsGroupRequirement.Meets)
                                    : MeetsGroupRequirement.NotMet
                        });

                        return(result);
                    }
                }
                else
                {
                    throw new Exception("No dataview assigned to Group Requirement Type: " + this.GroupRequirementType.Name);
                }
            }
            else if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Sql)
            {
                // if requirement set on GroupType, this.Group is null
                var targetGroup = this.Group ?? new GroupService(rockContext).Get(groupId);

                string formattedSql        = this.GroupRequirementType.SqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(targetGroup));
                string warningFormattedSql = this.GroupRequirementType.WarningSqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(targetGroup));
                try
                {
                    var tableResult = DbService.GetDataTable(formattedSql, System.Data.CommandType.Text, null);
                    if (tableResult.Columns.Count > 0)
                    {
                        IEnumerable <int> personIds        = tableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                        IEnumerable <int> warningPersonIds = null;

                        // if a Warning SQL was specified, get a list of PersonIds that should have a warning with their status
                        if (!string.IsNullOrWhiteSpace(warningFormattedSql))
                        {
                            var warningTableResult = DbService.GetDataTable(warningFormattedSql, System.Data.CommandType.Text, null);
                            if (warningTableResult.Columns.Count > 0)
                            {
                                warningPersonIds = warningTableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                            }
                        }

                        var result = personQry.Select(a => a.Id).ToList().Select(a => new PersonGroupRequirementStatus
                        {
                            PersonId              = a,
                            GroupRequirement      = this,
                            MeetsGroupRequirement = personIds.Contains(a)
                                    ? ((warningPersonIds != null && warningPersonIds.Contains(a))
                                        ? MeetsGroupRequirement.MeetsWithWarning
                                        : MeetsGroupRequirement.Meets
                                       )
                                    : MeetsGroupRequirement.NotMet,
                        });

                        return(result);
                    }
                }
                catch (Exception ex)
                {
                    // Exception occurred (probably due to bad SQL)
                    ExceptionLogService.LogException(ex, System.Web.HttpContext.Current);

                    var result = personQry.Select(a => a.Id).ToList().Select(a => new PersonGroupRequirementStatus
                    {
                        PersonId              = a,
                        GroupRequirement      = this,
                        MeetsGroupRequirement = MeetsGroupRequirement.Error
                    });

                    return(result);
                }
            }
            else
            {
                // manual
                var groupMemberRequirementQry = new GroupMemberRequirementService(rockContext).Queryable().Where(a => a.GroupMember.GroupId == groupId && a.GroupRequirementId == this.Id && a.RequirementMetDateTime.HasValue);

                var result = personQry.ToList().Select(a =>
                                                       new PersonGroupRequirementStatus
                {
                    PersonId              = a.Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = groupMemberRequirementQry.Any(r => r.GroupMember.PersonId == a.Id) ? MeetsGroupRequirement.Meets : MeetsGroupRequirement.NotMet
                });

                return(result);
            }

            // shouldn't happen
            return(null);
        }
        /// <summary>
        /// Registers any entity-based block types that are not currently registered in Rock.
        /// </summary>
        /// <param name="refreshAll">if set to <c>true</c> will refresh name, category, and description for all block types (not just the new ones)</param>
        private static void RegisterEntityBlockTypes(bool refreshAll = false)
        {
            var rockBlockTypes = Reflection.FindTypes(typeof(Blocks.IRockBlockType));

            List <Type> registeredTypes;

            using (var rockContext = new RockContext())
            {
                registeredTypes = new BlockTypeService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(b => b.EntityTypeId.HasValue && !string.IsNullOrEmpty(b.EntityType.AssemblyName))
                                  .ToList()
                                  .Select(b => Type.GetType(b.EntityType.AssemblyName, false))
                                  .Where(b => b != null)
                                  .ToList();
            }

            // Get the Block Entity Type
            int?blockEntityTypeId = EntityTypeCache.Get(typeof(Block)).Id;

            // for each BlockType
            foreach (var type in rockBlockTypes.Values)
            {
                if (refreshAll || !registeredTypes.Any(t => t == type))
                {
                    // Attempt to load the control
                    try
                    {
                        using (var rockContext = new RockContext())
                        {
                            var entityTypeId     = EntityTypeCache.Get(type, true, rockContext).Id;
                            var blockTypeService = new BlockTypeService(rockContext);
                            var blockType        = blockTypeService.Queryable()
                                                   .FirstOrDefault(b => b.EntityTypeId == entityTypeId);

                            if (blockType == null)
                            {
                                // Create new BlockType record and save it
                                blockType = new BlockType();
                                blockType.EntityTypeId = entityTypeId;
                                blockTypeService.Add(blockType);
                            }

                            // Update Name, Category, and Description based on block's attribute definitions
                            blockType.Name = Reflection.GetDisplayName(type) ?? string.Empty;
                            if (string.IsNullOrWhiteSpace(blockType.Name))
                            {
                                blockType.Name = type.FullName;
                            }

                            if (blockType.Name.Length > 100)
                            {
                                blockType.Name = blockType.Name.Truncate(100);
                            }

                            blockType.Category    = Rock.Reflection.GetCategory(type) ?? string.Empty;
                            blockType.Description = Rock.Reflection.GetDescription(type) ?? string.Empty;

                            rockContext.SaveChanges();

                            // Update the attributes used by the block
                            Rock.Attribute.Helper.UpdateAttributes(type, blockEntityTypeId, "BlockTypeId", blockType.Id.ToString(), rockContext);
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"RegisterEntityBlockTypes failed for {type.FullName} with exception: {ex.Message}");
                        ExceptionLogService.LogException(new Exception(string.Format("Problem processing block with path '{0}'.", type.FullName), ex), null);
                    }
                }
            }
        }
        /// <summary>
        /// Registers any block types that are not currently registered in Rock.
        /// </summary>
        /// <param name="physWebAppPath">A <see cref="System.String" /> containing the physical path to Rock on the server.</param>
        /// <param name="page">The <see cref="System.Web.UI.Page" />.</param>
        /// <param name="refreshAll">if set to <c>true</c> will refresh name, category, and description for all block types (not just the new ones)</param>
        public static void RegisterBlockTypes(string physWebAppPath, System.Web.UI.Page page, bool refreshAll = false)
        {
            // Dictionary for block types.  Key is path, value is friendly name
            var list = new Dictionary <string, string>();

            RegisterEntityBlockTypes(refreshAll);

            // Find all the blocks in the Blocks folder...
            FindAllBlocksInPath(physWebAppPath, list, "Blocks");

            // Now do the exact same thing for the Plugins folder...
            FindAllBlocksInPath(physWebAppPath, list, "Plugins");

            // Get a list of the BlockTypes already registered (via the path)
            var registeredPaths = new List <string>();

            using (var rockContext = new RockContext())
            {
                registeredPaths = new BlockTypeService(rockContext)
                                  .Queryable().AsNoTracking()
                                  .Where(b => !string.IsNullOrEmpty(b.Path))
                                  .Select(b => b.Path)
                                  .ToList();
            }

            // Get the Block Entity Type
            int?blockEntityTypeId = EntityTypeCache.Get(typeof(Block)).Id;

            // for each BlockType
            foreach (string path in list.Keys)
            {
                if (refreshAll || !registeredPaths.Any(b => b.Equals(path, StringComparison.OrdinalIgnoreCase)))
                {
                    // Attempt to load the control
                    try
                    {
                        var blockCompiledType = System.Web.Compilation.BuildManager.GetCompiledType(path);
                        if (blockCompiledType != null && typeof(Web.UI.RockBlock).IsAssignableFrom(blockCompiledType))
                        {
                            using (var rockContext = new RockContext())
                            {
                                var blockTypeService = new BlockTypeService(rockContext);
                                var blockType        = blockTypeService.Queryable()
                                                       .FirstOrDefault(b => b.Path == path);
                                if (blockType == null)
                                {
                                    // Create new BlockType record and save it
                                    blockType      = new BlockType();
                                    blockType.Path = path;
                                    blockTypeService.Add(blockType);
                                }

                                Type controlType = blockCompiledType;

                                // Update Name, Category, and Description based on block's attribute definitions
                                blockType.Name = Reflection.GetDisplayName(controlType) ?? string.Empty;
                                if (string.IsNullOrWhiteSpace(blockType.Name))
                                {
                                    // Parse the relative path to get the name
                                    var nameParts = list[path].Split('/');
                                    for (int i = 0; i < nameParts.Length; i++)
                                    {
                                        if (i == nameParts.Length - 1)
                                        {
                                            nameParts[i] = Path.GetFileNameWithoutExtension(nameParts[i]);
                                        }
                                        nameParts[i] = nameParts[i].SplitCase();
                                    }
                                    blockType.Name = string.Join(" > ", nameParts);
                                }
                                if (blockType.Name.Length > 100)
                                {
                                    blockType.Name = blockType.Name.Truncate(100);
                                }
                                blockType.Category    = Rock.Reflection.GetCategory(controlType) ?? string.Empty;
                                blockType.Description = Rock.Reflection.GetDescription(controlType) ?? string.Empty;

                                rockContext.SaveChanges();

                                // Update the attributes used by the block
                                Rock.Attribute.Helper.UpdateAttributes(controlType, blockEntityTypeId, "BlockTypeId", blockType.Id.ToString(), rockContext);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"RegisterBlockTypes failed for {path} with exception: {ex.Message}");
                        ExceptionLogService.LogException(new Exception(string.Format("Problem processing block with path '{0}'.", path), ex), null);
                    }
                }
            }
        }
        /// <summary>
        /// Builds the base query for the Exception List grid data
        /// </summary>
        /// <returns>IQueryable containing filtered ExceptionLog records</returns>
        private IQueryable<ExceptionLog> BuildBaseExceptionListQuery()
        {
            ExceptionLogService exceptionLogService = new ExceptionLogService( new RockContext() );
            IQueryable<ExceptionLog> query = exceptionLogService.Queryable();

            int siteId;
            if ( int.TryParse( fExceptionList.GetUserPreference( "Site" ), out siteId ) && siteId > 0 )
            {
                query = query.Where( e => e.SiteId == siteId );
            }

            int pageId;
            if ( int.TryParse( fExceptionList.GetUserPreference( "Page" ), out pageId ) && pageId > 0 )
            {
                query = query.Where( e => e.PageId == pageId );
            }

            int userPersonID;
            if ( int.TryParse( fExceptionList.GetUserPreference( "User" ), out userPersonID ) && userPersonID > 0 )
            {
                query = query.Where( e => e.CreatedByPersonAlias != null && e.CreatedByPersonAlias.PersonId == userPersonID );
            }

            string statusCode = fExceptionList.GetUserPreference( "Status Code" );
            if ( !String.IsNullOrEmpty( statusCode ) )
            {
                query = query.Where( e => e.StatusCode == statusCode );
            }

            DateTime startDate;
            if ( DateTime.TryParse( fExceptionList.GetUserPreference( "Start Date" ), out startDate ) )
            {
                startDate = startDate.Date;
                query = query.Where( e => e.CreatedDateTime.HasValue && e.CreatedDateTime.Value >= startDate );
            }

            DateTime endDate;
            if ( DateTime.TryParse( fExceptionList.GetUserPreference( "End Date" ), out endDate ) )
            {
                endDate = endDate.Date.AddDays( 1 );
                query = query.Where( e => e.CreatedDateTime.HasValue && e.CreatedDateTime.Value < endDate );
            }

            //Only look for inner exceptions
            query = query.Where( e => e.HasInnerException == null || e.HasInnerException == false );

            return query;
        }
Exemple #17
0
            protected override void PreSave()
            {
                if (Entry.State == EntityContextState.Deleted)
                {
                    if (Entity.StorageProvider != null)
                    {
                        Entity.BinaryFileTypeId = Entry.OriginalValues[nameof(Entity.BinaryFileTypeId)].ToString().AsInteger();

                        try
                        {
                            Entity.StorageProvider.DeleteContent(Entity);
                        }
                        catch (Exception ex)
                        {
                            // If an exception occurred while trying to delete provider's file, log the exception, but continue with the delete.
                            ExceptionLogService.LogException(ex);
                        }

                        Entity.BinaryFileTypeId = null;
                    }
                }
                else
                {
                    if (Entity.BinaryFileType == null && Entity.BinaryFileTypeId.HasValue)
                    {
                        Entity.BinaryFileType = new BinaryFileTypeService(( RockContext )DbContext).Get(Entity.BinaryFileTypeId.Value);
                    }

                    if (Entity.MimeType.StartsWith("image/"))
                    {
                        try
                        {
                            using (Bitmap bm = new Bitmap(Entity.ContentStream))
                            {
                                if (bm != null)
                                {
                                    Entity.Width  = bm.Width;
                                    Entity.Height = bm.Height;
                                }
                            }
                            Entity.ContentStream.Seek(0, SeekOrigin.Begin);

                            if (!Entity.IsTemporary)
                            {
                                var BinaryFileType = Entity.BinaryFileType;

                                if (BinaryFileType.MaxHeight.HasValue &&
                                    BinaryFileType.MaxHeight != 0 &&
                                    BinaryFileType.MaxWidth.HasValue &&
                                    BinaryFileType.MaxWidth != 0)
                                {
                                    ResizeSettings settings      = new ResizeSettings();
                                    MemoryStream   resizedStream = new MemoryStream();
                                    if (BinaryFileType.MaxWidth.Value < Entity.Width || BinaryFileType.MaxHeight < Entity.Height)
                                    {
                                        settings.Add("mode", "max");
                                        if (BinaryFileType.MaxHeight < Entity.Height && BinaryFileType.MaxWidth < Entity.Width)
                                        {
                                            if (BinaryFileType.MaxHeight >= BinaryFileType.MaxWidth)
                                            {
                                                settings.Add("height", BinaryFileType.MaxHeight.Value.ToString());
                                            }
                                            if (BinaryFileType.MaxHeight <= BinaryFileType.MaxWidth)
                                            {
                                                settings.Add("width", BinaryFileType.MaxWidth.Value.ToString());
                                            }
                                        }
                                        else if (BinaryFileType.MaxHeight < Entity.Height)
                                        {
                                            settings.Add("height", BinaryFileType.MaxHeight.Value.ToString());
                                        }
                                        else
                                        {
                                            settings.Add("width", BinaryFileType.MaxWidth.Value.ToString());
                                        }
                                        ImageBuilder.Current.Build(Entity.ContentStream, resizedStream, settings);
                                        Entity.ContentStream = resizedStream;

                                        using (Bitmap bm = new Bitmap(Entity.ContentStream))
                                        {
                                            if (bm != null)
                                            {
                                                Entity.Width  = bm.Width;
                                                Entity.Height = bm.Height;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception) { }   // if the file is an invalid photo keep moving
                    }

                    if (Entry.State == EntityContextState.Added)
                    {
                        // when a file is saved (unless it is getting Deleted/Saved), it should use the StoredEntityType that is associated with the BinaryFileType
                        if (Entity.BinaryFileType != null)
                        {
                            // Persist the storage type
                            Entity.StorageEntityTypeId = Entity.BinaryFileType.StorageEntityTypeId;

                            // Persist the storage type's settings specific to this binary file type
                            var settings = new Dictionary <string, string>();
                            if (Entity.BinaryFileType.Attributes == null)
                            {
                                Entity.BinaryFileType.LoadAttributes();
                            }
                            foreach (var attributeValue in Entity.BinaryFileType.AttributeValues)
                            {
                                settings.Add(attributeValue.Key, attributeValue.Value.Value);
                            }
                            Entity.StorageEntitySettings = settings.ToJson();

                            if (Entity.StorageProvider != null)
                            {
                                // save the file to the provider's new storage medium, and if the medium returns a filesize, save that value.
                                long?outFileSize = null;
                                Entity.StorageProvider.SaveContent(Entity, out outFileSize);
                                if (outFileSize.HasValue)
                                {
                                    Entity.FileSize = outFileSize;
                                }

                                Entity.Path = Entity.StorageProvider.GetPath(Entity);
                            }
                        }
                    }


                    else if (Entry.State == EntityContextState.Modified)
                    {
                        // when a file is saved (unless it is getting Deleted/Added),
                        // it should use the StorageEntityType that is associated with the BinaryFileType
                        if (Entity.BinaryFileType != null)
                        {
                            // if the storage provider changed, or any of its settings specific
                            // to the binary file type changed, delete the original provider's content
                            if (Entity.StorageEntityTypeId.HasValue && Entity.BinaryFileType.StorageEntityTypeId.HasValue)
                            {
                                var settings = new Dictionary <string, string>();
                                if (Entity.BinaryFileType.Attributes == null)
                                {
                                    Entity.BinaryFileType.LoadAttributes();
                                }
                                foreach (var attributeValue in Entity.BinaryFileType.AttributeValues)
                                {
                                    settings.Add(attributeValue.Key, attributeValue.Value.Value);
                                }
                                string settingsJson = settings.ToJson();

                                if (Entity.StorageProvider != null && (
                                        Entity.StorageEntityTypeId.Value != Entity.BinaryFileType.StorageEntityTypeId.Value ||
                                        Entity.StorageEntitySettings != settingsJson))
                                {
                                    var ms = new MemoryStream();
                                    Entity.ContentStream.Position = 0;
                                    Entity.ContentStream.CopyTo(ms);
                                    Entity.ContentStream.Dispose();

                                    // Delete the current provider's storage
                                    Entity.StorageProvider.DeleteContent(Entity);

                                    // Set the new storage provider with its settings
                                    Entity.StorageEntityTypeId   = Entity.BinaryFileType.StorageEntityTypeId;
                                    Entity.StorageEntitySettings = settingsJson;

                                    Entity.ContentStream = new MemoryStream();
                                    ms.Position          = 0;
                                    ms.CopyTo(Entity.ContentStream);
                                    Entity.ContentStream.Position = 0;
                                    Entity.FileSize = Entity.ContentStream.Length;
                                }
                            }
                        }

                        if (Entity.ContentIsDirty && Entity.StorageProvider != null)
                        {
                            /*
                             * SK - 12/11/2021
                             * Path should always be reset in case when there is any change in Storage Provider from previous value. Otherwise new storage provider may still be refering the older path.
                             */
                            Entity.Path = null;
                            long?fileSize = null;
                            Entity.StorageProvider.SaveContent(Entity, out fileSize);

                            Entity.FileSize = fileSize;
                            Entity.Path     = Entity.StorageProvider.GetPath(Entity);
                        }
                    }
                }

                base.PreSave();
            }
Exemple #18
0
        /// <summary>
        /// Ensures that each Metric that has EnableAnalytics has a SQL View for it, and also deletes any AnalyticsFactMetric** views that no longer have metric (based on Metric.Name)
        /// </summary>
        public void EnsureMetricAnalyticsViews()
        {
            string analyticMetricViewsPrefix = "AnalyticsFactMetric";
            string getAnalyticMetricViewsSQL = string.Format(
                @"SELECT 
    OBJECT_NAME(sm.object_id) [view_name]
    ,sm.DEFINITION [view_definition]
FROM sys.sql_modules AS sm
JOIN sys.objects AS o ON sm.object_id = o.object_id
WHERE o.type = 'V'
    AND OBJECT_NAME(sm.object_id) LIKE '{0}%'",
                analyticMetricViewsPrefix);

            var dataTable = DbService.GetDataTable(getAnalyticMetricViewsSQL, System.Data.CommandType.Text, null);
            var databaseAnalyticMetricViews = dataTable.Rows.OfType <DataRow>()
                                              .Select(row => new
            {
                ViewName       = row["view_name"] as string,
                ViewDefinition = row["view_definition"] as string
            }).ToList();

            var metricsWithAnalyticsEnabled = this.Queryable().Where(a => a.EnableAnalytics).Include(a => a.MetricPartitions).AsNoTracking().ToList();

            var metricViewNames       = metricsWithAnalyticsEnabled.Select(a => $"{analyticMetricViewsPrefix}{a.Title.RemoveSpecialCharacters()}").ToList();
            var orphanedDatabaseViews = databaseAnalyticMetricViews.Where(a => !metricViewNames.Contains(a.ViewName)).ToList();

            // DROP any Metric Analytic Views that are orphaned.  In other words, there are views named 'AnalyticsFactMetric***' that don't have a metric.
            // This could happen if Metric.EnableAnalytics changed from True to False, Metric Title changed, or if a Metric was deleted.
            foreach (var orphanedView in orphanedDatabaseViews)
            {
                this.Context.Database.ExecuteSqlCommand($"DROP VIEW [{orphanedView.ViewName}]");
            }

            // Make sure that each Metric with EnableAnalytics=True has a SQL View and that the View Definition is correct
            foreach (var metric in metricsWithAnalyticsEnabled)
            {
                string metricViewName         = $"{analyticMetricViewsPrefix}{metric.Title.RemoveSpecialCharacters()}";
                var    metricEntityPartitions = metric.MetricPartitions.Where(a => a.EntityTypeId.HasValue).OrderBy(a => a.Order).ThenBy(a => a.Label).Select(a => new
                {
                    a.Label,
                    a.EntityTypeId
                });

                var           viewPartitionSELECTClauses   = metricEntityPartitions.Select(a => $"      ,pvt.[{a.EntityTypeId}] as [{a.Label}Id]").ToList().AsDelimited("\n");
                List <string> partitionEntityLookupSELECTs = new List <string>();
                List <string> partitionEntityLookupJOINs   = new List <string>();
                foreach (var metricPartition in metricEntityPartitions)
                {
                    var metricPartitionEntityType = EntityTypeCache.Read(metricPartition.EntityTypeId.Value);
                    if (metricPartitionEntityType != null)
                    {
                        var tableAttribute = metricPartitionEntityType.GetEntityType().GetCustomAttribute <TableAttribute>();
                        if (tableAttribute != null)
                        {
                            if (metricPartitionEntityType.Id == EntityTypeCache.GetId <DefinedValue>())
                            {
                                partitionEntityLookupSELECTs.Add($"j{metricPartition.EntityTypeId}.Value [{metricPartition.Label.RemoveSpecialCharacters()}Name]");
                            }
                            else if (metricPartitionEntityType.GetEntityType().GetProperty("Name") != null)
                            {
                                partitionEntityLookupSELECTs.Add($"j{metricPartition.EntityTypeId}.Name [{metricPartition.Label.RemoveSpecialCharacters()}Name]");
                            }

                            partitionEntityLookupJOINs.Add($"LEFT JOIN [{tableAttribute.Name}] j{metricPartition.EntityTypeId} ON p.{metricPartition.Label.RemoveSpecialCharacters()}Id = j{metricPartition.EntityTypeId}.Id");
                        }
                    }
                }

                var viewPIVOTInClauses = metricEntityPartitions.Select(a => $"  [{a.EntityTypeId}]").ToList().AsDelimited(",\n");
                if (string.IsNullOrEmpty(viewPIVOTInClauses))
                {
                    // This metric only has the default partition, and with no EntityTypeId, so put in a dummy Pivot Clause
                    viewPIVOTInClauses = "[0]";
                }

                var viewJoinsSELECT = partitionEntityLookupSELECTs.Select(a => $"  ,{a}").ToList().AsDelimited("\n");
                var viewJoinsFROM   = partitionEntityLookupJOINs.AsDelimited("\n");

                var viewDefinition = $@"
/*
<auto-generated>
    This view was generated by the Rock's MetricService.EnsureMetricAnalyticsViews() which gets called when a Metric is saved.
    Changes to this view definition will be lost when the view is regenerated.
    NOTE: Any Views with the prefix '{analyticMetricViewsPrefix}' are assumed to be Code Generated and may be deleted if there isn't a Metric associated with it
</auto-generated>
<doc>
	<summary>
        This VIEW helps present the data for the {metric.Title} metric. 
	</summary>
</doc>
*/
CREATE VIEW [{metricViewName}] AS
SELECT p.*
{viewJoinsSELECT} 
FROM (
    SELECT pvt.Id
      ,cast(pvt.MetricValueDateTime AS DATE) AS [MetricValueDateTime]
      ,pvt.YValue
{viewPartitionSELECTClauses}
    FROM (
        SELECT 
	      mv.Id
          ,mv.YValue
          ,mv.MetricValueDateTime
          ,mvp.EntityId
          ,mp.EntityTypeId
        FROM MetricValue mv
        JOIN MetricValuePartition mvp ON mvp.MetricValueId = mv.Id
        JOIN MetricPartition mp ON mvp.MetricPartitionId = mp.Id
        WHERE mv.MetricId = {metric.Id}
        ) src
    pivot(min(EntityId) FOR EntityTypeId IN ({viewPIVOTInClauses})) pvt
) p
{viewJoinsFROM}
";

                var databaseViewDefinition = databaseAnalyticMetricViews.Where(a => a.ViewName == metricViewName).FirstOrDefault();
                try
                {
                    if (databaseViewDefinition != null)
                    {
                        if (databaseViewDefinition.ViewDefinition != viewDefinition)
                        {
                            // view already exists, but something has changed, so drop and recreate it
                            this.Context.Database.ExecuteSqlCommand($"DROP VIEW [{metricViewName}]");
                            this.Context.Database.ExecuteSqlCommand(viewDefinition);
                        }
                    }
                    else
                    {
                        this.Context.Database.ExecuteSqlCommand(viewDefinition);
                    }
                }
                catch (Exception ex)
                {
                    // silently log the exception
                    ExceptionLogService.LogException(new Exception("Error creating Analytics view for " + metric.Title, ex), System.Web.HttpContext.Current);
                }
            }
        }
Exemple #19
0
        /// <summary> 
        /// Job that executes routine Rock cleanup tasks
        /// 
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute( IJobExecutionContext context )
        {
            var rockContext = new Rock.Data.RockContext();

            // get the job map
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            // delete accounts that have not been confirmed in X hours
            int? userExpireHours = dataMap.GetString( "HoursKeepUnconfirmedAccounts" ).AsIntegerOrNull();
            if ( userExpireHours.HasValue )
            {
                DateTime userAccountExpireDate = RockDateTime.Now.Add( new TimeSpan( userExpireHours.Value * -1, 0, 0 ) );

                var userLoginService = new UserLoginService(rockContext);

                foreach ( var user in userLoginService.Queryable().Where( u => u.IsConfirmed == false && ( u.CreatedDateTime ?? DateTime.MinValue ) < userAccountExpireDate ).ToList() )
                {
                    userLoginService.Delete( user );
                }

                rockContext.SaveChanges();
            }

            // purge exception log
            int? exceptionExpireDays = dataMap.GetString( "DaysKeepExceptions" ).AsIntegerOrNull();
            if ( exceptionExpireDays.HasValue )
            {
                DateTime exceptionExpireDate = RockDateTime.Now.Add( new TimeSpan( exceptionExpireDays.Value * -1, 0, 0, 0 ) );

                ExceptionLogService exceptionLogService = new ExceptionLogService( rockContext );

                foreach ( var exception in exceptionLogService.Queryable().Where( e => e.CreatedDateTime.HasValue && e.CreatedDateTime < exceptionExpireDate ).ToList() )
                {
                    exceptionLogService.Delete( exception );
                }

                rockContext.SaveChanges();
            }

            // purge audit log
            int? auditExpireDays = dataMap.GetString( "AuditLogExpirationDays" ).AsIntegerOrNull();
            if ( auditExpireDays.HasValue )
            {
                DateTime auditExpireDate = RockDateTime.Now.Add( new TimeSpan( auditExpireDays.Value * -1, 0, 0, 0 ) );
                AuditService auditService = new AuditService(rockContext);
                foreach ( var audit in auditService.Queryable().Where( a => a.DateTime < auditExpireDate ).ToList() )
                {
                    auditService.Delete( audit );
                }

                rockContext.SaveChanges();
            }

            // clean the cached file directory

            // get the attributes
            string cacheDirectoryPath = dataMap.GetString( "BaseCacheDirectory" );
            int? cacheExpirationDays = dataMap.GetString( "DaysKeepCachedFiles" ).AsIntegerOrNull();
            if ( cacheExpirationDays.HasValue )
            {
                DateTime cacheExpirationDate = RockDateTime.Now.Add( new TimeSpan( cacheExpirationDays.Value * -1, 0, 0, 0 ) );

                // if job is being run by the IIS scheduler and path is not null
                if ( context.Scheduler.SchedulerName == "RockSchedulerIIS" && !string.IsNullOrEmpty( cacheDirectoryPath ) )
                {
                    // get the physical path of the cache directory
                    cacheDirectoryPath = System.Web.Hosting.HostingEnvironment.MapPath( cacheDirectoryPath );
                }

                // if directory is not blank and cache expiration date not in the future
                if ( !string.IsNullOrEmpty( cacheDirectoryPath ) && cacheExpirationDate <= RockDateTime.Now )
                {
                    // Clean cache directory
                    CleanCacheDirectory( cacheDirectoryPath, cacheExpirationDate );
                }
            }

            // clean out any temporary binary files
            BinaryFileService binaryFileService = new BinaryFileService(rockContext);
            foreach ( var binaryFile in binaryFileService.Queryable().Where( bf => bf.IsTemporary == true ).ToList() )
            {
                if ( binaryFile.ModifiedDateTime < RockDateTime.Now.AddDays( -1 ) )
                {
                    binaryFileService.Delete( binaryFile );
                }
            }
            rockContext.SaveChanges();

            // Add any missing person aliases
            PersonService personService = new PersonService(rockContext);
            foreach ( var person in personService.Queryable( "Aliases" )
                .Where( p => !p.Aliases.Any() )
                .Take( 300 ) )
            {
                person.Aliases.Add( new PersonAlias { AliasPersonId = person.Id, AliasPersonGuid = person.Guid } );
            }

            rockContext.SaveChanges();

            // Add any missing metaphones
            int namesToProcess = dataMap.GetString( "MaxMetaphoneNames" ).AsInteger();
            if ( namesToProcess > 0 )
            {
                var firstNameQry = personService.Queryable().Select( p => p.FirstName );
                var nickNameQry = personService.Queryable().Select( p => p.NickName );
                var lastNameQry = personService.Queryable().Select( p => p.LastName );
                var nameQry = firstNameQry.Union( nickNameQry.Union( lastNameQry ) );

                var metaphones = rockContext.Metaphones;
                var existingNames = metaphones.Select( m => m.Name ).Distinct();

                // Get the names that have not yet been processed
                var namesToUpdate = nameQry
                    .Where( n => !existingNames.Contains( n ) )
                    .Take( namesToProcess )
                    .ToList();

                foreach ( string name in namesToUpdate )
                {
                    string mp1 = string.Empty;
                    string mp2 = string.Empty;
                    Rock.Utility.DoubleMetaphone.doubleMetaphone( name, ref mp1, ref mp2 );

                    var metaphone = new Metaphone();
                    metaphone.Name = name;
                    metaphone.Metaphone1 = mp1;
                    metaphone.Metaphone2 = mp2;

                    metaphones.Add( metaphone );
                }

                rockContext.SaveChanges();
            }
        }
            protected override void PreSave()
            {
                if (Entry.State == EntityContextState.Deleted)
                {
                    if (Entity.StorageProvider != null)
                    {
                        Entity.BinaryFileTypeId = Entry.OriginalValues[nameof(Entity.BinaryFileTypeId)].ToString().AsInteger();

                        try
                        {
                            Entity.StorageProvider.DeleteContent(Entity);
                        }
                        catch (Exception ex)
                        {
                            // If an exception occurred while trying to delete provider's file, log the exception, but continue with the delete.
                            ExceptionLogService.LogException(ex);
                        }

                        Entity.BinaryFileTypeId = null;
                    }
                }
                else
                {
                    if (Entity.BinaryFileType == null && Entity.BinaryFileTypeId.HasValue)
                    {
                        Entity.BinaryFileType = new BinaryFileTypeService(( RockContext )DbContext).Get(Entity.BinaryFileTypeId.Value);
                    }

                    if (Entity.MimeType.StartsWith("image/"))
                    {
                        try
                        {
                            using (Bitmap bm = new Bitmap(Entity.ContentStream))
                            {
                                if (bm != null)
                                {
                                    Entity.Width  = bm.Width;
                                    Entity.Height = bm.Height;
                                }
                            }
                            Entity.ContentStream.Seek(0, SeekOrigin.Begin);

                            var binaryFileType                   = Entity.BinaryFileType;
                            var binaryFileTypeMaxHeight          = binaryFileType.MaxHeight ?? 0;
                            var binaryFileTypeMaxWidth           = binaryFileType.MaxWidth ?? 0;
                            var binaryFileTypeMaxHeightIsValid   = binaryFileTypeMaxHeight > 0;
                            var binaryFileTypeMaxWidthIsValid    = binaryFileTypeMaxWidth > 0;
                            var binaryFileTypeDimensionsAreValid = binaryFileTypeMaxHeightIsValid && binaryFileTypeMaxWidthIsValid;

                            ResizeSettings settings      = new ResizeSettings();
                            MemoryStream   resizedStream = new MemoryStream();
                            if ((binaryFileTypeMaxWidthIsValid && binaryFileTypeMaxWidth < Entity.Width) ||
                                (binaryFileTypeMaxHeightIsValid && binaryFileTypeMaxHeight < Entity.Height))
                            {
                                /* How to handle aspect-ratio conflicts between the image and width+height.
                                 *   'pad' adds whitespace,
                                 *   'crop' crops minimally,
                                 *   'carve' uses seam carving,
                                 *   'stretch' loses aspect-ratio, stretching the image.
                                 *   'max' behaves like maxwidth/maxheight
                                 */

                                settings.Add("mode", "max");

                                // Height and width are both set.
                                if (binaryFileTypeDimensionsAreValid)
                                {
                                    // A valid max height and width but the max height is greater or equal than the width.
                                    if (binaryFileTypeMaxHeight >= binaryFileTypeMaxWidth)
                                    {
                                        settings.Add("height", binaryFileTypeMaxHeight.ToString());
                                    }

                                    // A valid max height and width but the max height is less or equal the width.
                                    else if (binaryFileTypeMaxHeight <= binaryFileTypeMaxWidth)
                                    {
                                        settings.Add("width", binaryFileTypeMaxWidth.ToString());
                                    }
                                }
                                else
                                {
                                    // A valid max height but less than the binary file height.
                                    if (binaryFileTypeMaxHeightIsValid && binaryFileTypeMaxHeight < Entity.Height)
                                    {
                                        settings.Add("height", binaryFileTypeMaxHeight.ToString());
                                    }
                                    else
                                    {
                                        // A Valid max width.
                                        settings.Add("width", binaryFileTypeMaxWidth.ToString());
                                    }
                                }

                                if (settings.HasKeys())
                                {
                                    ImageBuilder.Current.Build(Entity.ContentStream, resizedStream, settings);
                                    Entity.ContentStream = resizedStream;

                                    using (Bitmap bm = new Bitmap(Entity.ContentStream))
                                    {
                                        if (bm != null)
                                        {
                                            Entity.Width  = bm.Width;
                                            Entity.Height = bm.Height;
                                        }
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            RockLogger.Log.Error(RockLogDomains.Core, ex, "Error trying to resize the file {0}.", Entity?.FileName);
                        }
                    }

                    if (Entry.State == EntityContextState.Added)
                    {
                        // when a file is saved (unless it is getting Deleted/Saved), it should use the StoredEntityType that is associated with the BinaryFileType
                        if (Entity.BinaryFileType != null)
                        {
                            // Persist the storage type
                            Entity.StorageEntityTypeId = Entity.BinaryFileType.StorageEntityTypeId;

                            // Persist the storage type's settings specific to this binary file type
                            var settings = new Dictionary <string, string>();
                            if (Entity.BinaryFileType.Attributes == null)
                            {
                                Entity.BinaryFileType.LoadAttributes();
                            }
                            foreach (var attributeValue in Entity.BinaryFileType.AttributeValues)
                            {
                                settings.Add(attributeValue.Key, attributeValue.Value.Value);
                            }
                            Entity.StorageEntitySettings = settings.ToJson();

                            if (Entity.StorageProvider != null)
                            {
                                // save the file to the provider's new storage medium, and if the medium returns a filesize, save that value.
                                long?outFileSize = null;
                                Entity.StorageProvider.SaveContent(Entity, out outFileSize);
                                if (outFileSize.HasValue)
                                {
                                    Entity.FileSize = outFileSize;
                                }

                                Entity.Path = Entity.StorageProvider.GetPath(Entity);
                            }
                            else
                            {
                                throw new Rock.Web.FileUploadException("A storage provider has not been registered for this file type or the current storage provider is inactive.", System.Net.HttpStatusCode.BadRequest);
                            }
                        }
                    }


                    else if (Entry.State == EntityContextState.Modified)
                    {
                        // when a file is saved (unless it is getting Deleted/Added),
                        // it should use the StorageEntityType that is associated with the BinaryFileType
                        if (Entity.BinaryFileType != null)
                        {
                            // if the storage provider changed, or any of its settings specific
                            // to the binary file type changed, delete the original provider's content
                            if (Entity.StorageEntityTypeId.HasValue && Entity.BinaryFileType.StorageEntityTypeId.HasValue)
                            {
                                var settings = new Dictionary <string, string>();
                                if (Entity.BinaryFileType.Attributes == null)
                                {
                                    Entity.BinaryFileType.LoadAttributes();
                                }
                                foreach (var attributeValue in Entity.BinaryFileType.AttributeValues)
                                {
                                    settings.Add(attributeValue.Key, attributeValue.Value.Value);
                                }
                                string settingsJson = settings.ToJson();

                                if (Entity.StorageProvider != null && (
                                        Entity.StorageEntityTypeId.Value != Entity.BinaryFileType.StorageEntityTypeId.Value ||
                                        Entity.StorageEntitySettings != settingsJson))
                                {
                                    var ms = new MemoryStream();
                                    Entity.ContentStream.Position = 0;
                                    Entity.ContentStream.CopyTo(ms);
                                    Entity.ContentStream.Dispose();

                                    // Delete the current provider's storage
                                    Entity.StorageProvider.DeleteContent(Entity);

                                    // Set the new storage provider with its settings
                                    Entity.StorageEntityTypeId   = Entity.BinaryFileType.StorageEntityTypeId;
                                    Entity.StorageEntitySettings = settingsJson;

                                    Entity.ContentStream = new MemoryStream();
                                    ms.Position          = 0;
                                    ms.CopyTo(Entity.ContentStream);
                                    Entity.ContentStream.Position = 0;
                                    Entity.FileSize = Entity.ContentStream.Length;
                                }
                            }
                        }

                        if (Entity.ContentIsDirty && Entity.StorageProvider != null)
                        {
                            /*
                             * SK - 12/11/2021
                             * Path should always be reset in case when there is any change in Storage Provider from previous value. Otherwise new storage provider may still be refering the older path.
                             */
                            Entity.Path = null;
                            long?fileSize = null;
                            Entity.StorageProvider.SaveContent(Entity, out fileSize);

                            Entity.FileSize = fileSize;
                            Entity.Path     = Entity.StorageProvider.GetPath(Entity);
                        }
                    }
                }

                base.PreSave();
            }
        /// <summary>
        /// Gets the Linq expression for the DataViewFilter.
        /// </summary>
        /// <param name="filteredEntityType">Type of the filtered entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameter">The parameter.</param>
        /// <param name="dataViewFilterOverrides">The data view filter overrides.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public virtual Expression GetExpression(Type filteredEntityType, IService serviceInstance, ParameterExpression parameter, DataViewFilterOverrides dataViewFilterOverrides, List <string> errorMessages)
        {
            switch (ExpressionType)
            {
            case FilterExpressionType.Filter:

                if (this.EntityTypeId.HasValue)
                {
                    var entityType = EntityTypeCache.Get(this.EntityTypeId.Value);
                    if (entityType != null)
                    {
                        var component = Rock.Reporting.DataFilterContainer.GetComponent(entityType.Name);
                        if (component != null)
                        {
                            try
                            {
                                string selection;     // A formatted string representing the filter settings: FieldName, <see cref="ComparisonType">Comparison Type</see>, (optional) Comparison Value(s)
                                var    dataViewFilterOverride = dataViewFilterOverrides?.GetOverride(this.Guid);
                                if (dataViewFilterOverride != null)
                                {
                                    if (dataViewFilterOverride.IncludeFilter == false)
                                    {
                                        return(null);
                                    }
                                    else
                                    {
                                        selection = dataViewFilterOverride.Selection;
                                    }
                                }
                                else
                                {
                                    selection = this.Selection;
                                }

                                if (component is IDataFilterWithOverrides)
                                {
                                    return((component as IDataFilterWithOverrides).GetExpressionWithOverrides(filteredEntityType, serviceInstance, parameter, dataViewFilterOverrides, selection));
                                }
                                else
                                {
                                    return(component.GetExpression(filteredEntityType, serviceInstance, parameter, selection));
                                }
                            }
                            catch (SystemException ex)
                            {
                                ExceptionLogService.LogException(ex, System.Web.HttpContext.Current);
                                errorMessages.Add(string.Format("{0}: {1}", component.FormatSelection(filteredEntityType, this.Selection), ex.Message));
                            }
                        }
                    }
                }
                return(null);

            case FilterExpressionType.GroupAll:
            case FilterExpressionType.GroupAnyFalse:

                Expression andExp = null;
                foreach (var filter in this.ChildFilters)
                {
                    Expression exp = filter.GetExpression(filteredEntityType, serviceInstance, parameter, dataViewFilterOverrides, errorMessages);
                    if (exp != null)
                    {
                        if (andExp == null)
                        {
                            andExp = exp;
                        }
                        else
                        {
                            andExp = Expression.AndAlso(andExp, exp);
                        }
                    }
                }

                if (ExpressionType == FilterExpressionType.GroupAnyFalse &&
                    andExp != null)
                {
                    // If only one of the conditions must be false, invert the expression so that it becomes the logical equivalent of "NOT ALL".
                    andExp = Expression.Not(andExp);
                }

                return(andExp);

            case FilterExpressionType.GroupAny:
            case FilterExpressionType.GroupAllFalse:

                Expression orExp = null;
                foreach (var filter in this.ChildFilters)
                {
                    Expression exp = filter.GetExpression(filteredEntityType, serviceInstance, parameter, dataViewFilterOverrides, errorMessages);
                    if (exp != null)
                    {
                        if (orExp == null)
                        {
                            orExp = exp;
                        }
                        else
                        {
                            orExp = Expression.OrElse(orExp, exp);
                        }
                    }
                }

                if (ExpressionType == FilterExpressionType.GroupAllFalse &&
                    orExp != null)
                {
                    // If all of the conditions must be false, invert the expression so that it becomes the logical equivalent of "NOT ANY".
                    orExp = Expression.Not(orExp);
                }

                return(orExp);
            }

            return(null);
        }
Exemple #22
0
        /// <summary>
        /// Recursively logs exception and any children.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> to log.</param>
        /// <param name="log">The parent <see cref="Rock.Model.ExceptionLog"/> of the exception being logged. This value is nullable.</param>
        /// <param name="isParent">A <see cref="System.Boolean"/> flag indicating if this Exception is a parent exception. This value is
        ///     <c>true</c> if the exception that is being logged is a parent exception, otherwise <c>false</c>.
        /// </param>
        private static void LogExceptions(Exception ex, ExceptionLog log, bool isParent)
        {
            // First, attempt to log exception to the database.
            try
            {
                ExceptionLog exceptionLog;

                // If this is a recursive call and not the originating exception being logged,
                // attempt to clone the initial one, and populate it with Exception Type and Message
                // from the inner exception, while retaining the contextual information from where
                // the exception originated.
                if (!isParent)
                {
                    exceptionLog = log.Clone(false);

                    if (exceptionLog != null)
                    {
                        // Populate with inner exception type, message and update whether or not there is another inner exception.
                        exceptionLog.ExceptionType     = ex.GetType().ToString();
                        exceptionLog.Description       = ex.Message;
                        exceptionLog.HasInnerException = ex.InnerException != null;

                        // Ensure EF properly recognizes this as a new record.
                        exceptionLog.Id       = 0;
                        exceptionLog.Guid     = Guid.NewGuid();
                        exceptionLog.ParentId = log.Id;
                    }
                }
                else
                {
                    exceptionLog = log;
                }

                // The only reason this should happen is if the `log.Clone()` operation failed. Compiler sugar.
                if (exceptionLog == null)
                {
                    return;
                }

                // Write ExceptionLog record to database.
                var exceptionLogService = new ExceptionLogService();
                exceptionLogService.Add(exceptionLog, exceptionLog.CreatedByPersonId);
                exceptionLogService.Save(exceptionLog, exceptionLog.CreatedByPersonId);

                // Recurse if inner exception is found
                if (exceptionLog.HasInnerException.GetValueOrDefault(false))
                {
                    LogExceptions(ex.InnerException, exceptionLog, false);
                }
            }
            catch (Exception)
            {
                // If logging the exception fails, write the exception to a file
                try
                {
                    string directory = AppDomain.CurrentDomain.BaseDirectory;
                    directory = Path.Combine(directory, "App_Data", "Logs");

                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }

                    string filePath = Path.Combine(directory, "RockExceptions.csv");
                    File.AppendAllText(filePath, string.Format("{0},{1},\"{2}\"\r\n", DateTime.Now.ToString(), ex.GetType(), ex.Message));
                }
                catch
                {
                    // failed to write to database and also failed to write to log file, so there is nowhere to log this error
                }
            }
        }
Exemple #23
0
        /// <summary>
        /// Returns a list of each person and their GroupRequirement status for this group requirement
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="personQry">The person qry.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="groupRoleId">The group role identifier.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">No dataview assigned to Group Requirement Type: " + this.GroupRequirementType.Name</exception>
        public IEnumerable <PersonGroupRequirementStatus> PersonQueryableMeetsGroupRequirement(RockContext rockContext, IQueryable <Person> personQry, int groupId, int?groupRoleId)
        {
            if ((this.GroupRoleId != null) && (groupRoleId != null) && (this.GroupRoleId != groupRoleId))
            {
                // if this GroupRequirement is for a specific role, the groupRole we are checking for is something different
                var result = personQry.Select(p => p.Id).ToList().Select(a =>
                                                                         new PersonGroupRequirementStatus
                {
                    PersonId              = Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = MeetsGroupRequirement.NotApplicable
                });

                return(result);
            }

            if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Dataview)
            {
                var        personService               = new PersonService(rockContext);
                var        paramExpression             = personService.ParameterExpression;
                List <int> warningDataViewPersonIdList = null;
                if (this.GroupRequirementType.WarningDataViewId.HasValue)
                {
                    var warningDataViewWhereExpression = this.GroupRequirementType.WarningDataView.GetExpression(personService, paramExpression);
                    warningDataViewPersonIdList = personService.Get(paramExpression, warningDataViewWhereExpression).Where(a => personQry.Any(p => p.Id == a.Id)).Select(a => a.Id).ToList();
                }

                if (this.GroupRequirementType.DataViewId.HasValue)
                {
                    var dataViewWhereExpression = this.GroupRequirementType.DataView.GetExpression(personService, paramExpression);
                    var dataViewQry             = personService.Get(paramExpression, dataViewWhereExpression);
                    if (dataViewQry != null)
                    {
                        var personWithRequirementsQuery = from p in personQry
                                                          join d in dataViewQry on p.Id equals d.Id into oj
                                                          from d in oj.DefaultIfEmpty()
                                                          select new { PersonId = p.Id, Included = d != null };

                        var personWithRequirementsList = personWithRequirementsQuery.Select(p => new { PersonId = p.PersonId, Included = p.Included }).ToList();

                        var result = personWithRequirementsList.Select(a =>
                        {
                            var personGroupRequirementStatus = new PersonGroupRequirementStatus
                            {
                                PersonId         = a.PersonId,
                                GroupRequirement = this
                            };

                            var hasWarning = warningDataViewPersonIdList?.Contains(a.PersonId) == true;

                            if (a.Included)
                            {
                                if (hasWarning)
                                {
                                    personGroupRequirementStatus.MeetsGroupRequirement = MeetsGroupRequirement.MeetsWithWarning;
                                }
                                else
                                {
                                    personGroupRequirementStatus.MeetsGroupRequirement = MeetsGroupRequirement.Meets;
                                }
                            }
                            else
                            {
                                personGroupRequirementStatus.MeetsGroupRequirement = MeetsGroupRequirement.NotMet;
                            }

                            return(personGroupRequirementStatus);
                        }
                                                                       );

                        return(result);
                    }
                }
                else
                {
                    var personWithIdRequirements = personQry.Select(p => p.Id);

                    var result = personWithIdRequirements.ToList().Select(a =>
                                                                          new PersonGroupRequirementStatus
                    {
                        PersonId              = a,
                        GroupRequirement      = this,
                        MeetsGroupRequirement = warningDataViewPersonIdList.Contains(a) == true ? MeetsGroupRequirement.MeetsWithWarning : MeetsGroupRequirement.Meets
                    });

                    return(result);
                }
            }
            else if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Sql)
            {
                // if requirement set on GroupType, this.Group is null
                var    targetGroup      = this.Group ?? new GroupService(rockContext).Get(groupId);
                var    personQryIdList  = personQry.Select(a => a.Id).ToList();
                Person personMergeField = null;
                if (personQryIdList.Count == 1)
                {
                    var personId = personQryIdList[0];
                    personMergeField = new PersonService(rockContext).GetNoTracking(personId);
                }

                string formattedSql        = this.GroupRequirementType.SqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(targetGroup, personMergeField));
                string warningFormattedSql = this.GroupRequirementType.WarningSqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(targetGroup, personMergeField));
                try
                {
                    var tableResult = DbService.GetDataTable(formattedSql, System.Data.CommandType.Text, null);
                    if (tableResult.Columns.Count > 0)
                    {
                        IEnumerable <int> personIds        = tableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                        IEnumerable <int> warningPersonIds = null;

                        // if a Warning SQL was specified, get a list of PersonIds that should have a warning with their status
                        if (!string.IsNullOrWhiteSpace(warningFormattedSql))
                        {
                            var warningTableResult = DbService.GetDataTable(warningFormattedSql, System.Data.CommandType.Text, null);
                            if (warningTableResult.Columns.Count > 0)
                            {
                                warningPersonIds = warningTableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                            }
                        }

                        var result = personQryIdList.Select(a => new PersonGroupRequirementStatus
                        {
                            PersonId              = a,
                            GroupRequirement      = this,
                            MeetsGroupRequirement = personIds.Contains(a)
                                    ? ((warningPersonIds != null && warningPersonIds.Contains(a))
                                        ? MeetsGroupRequirement.MeetsWithWarning
                                        : MeetsGroupRequirement.Meets
                                       )
                                    : MeetsGroupRequirement.NotMet,
                        });

                        return(result);
                    }
                }
                catch (Exception ex)
                {
                    // Exception occurred (probably due to bad SQL)
                    ExceptionLogService.LogException(ex, System.Web.HttpContext.Current);

                    var result = personQry.Select(a => a.Id).ToList().Select(a => new PersonGroupRequirementStatus
                    {
                        PersonId              = a,
                        GroupRequirement      = this,
                        MeetsGroupRequirement = MeetsGroupRequirement.Error,
                        CalculationException  = ex
                    });

                    return(result);
                }
            }
            else
            {
                // manual
                var groupMemberRequirementQry = new GroupMemberRequirementService(rockContext).Queryable().Where(a => a.GroupMember.GroupId == groupId && a.GroupRequirementId == this.Id && a.RequirementMetDateTime.HasValue);

                var result = personQry.ToList().Select(a =>
                                                       new PersonGroupRequirementStatus
                {
                    PersonId              = a.Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = groupMemberRequirementQry.Any(r => r.GroupMember.PersonId == a.Id) ? MeetsGroupRequirement.Meets : MeetsGroupRequirement.NotMet
                });

                return(result);
            }

            // shouldn't happen
            return(null);
        }
Exemple #24
0
        /// <summary>
        /// Recursively logs exception and any children.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> to log.</param>
        /// <param name="log">The parent <see cref="Rock.Model.ExceptionLog"/> of the exception being logged. This value is nullable.</param>
        /// <param name="isParent">A <see cref="System.Boolean"/> flag indicating if this Exception is a parent exception. This value is
        ///     <c>true</c> if the exception that is being logged is a parent exception, otherwise <c>false</c>.
        /// </param>
        private static void LogExceptions(Exception ex, ExceptionLog log, bool isParent)
        {
            bool logToFile = AlwaysLogToFile;

            // First, attempt to log exception to the database.
            try
            {
                ExceptionLog exceptionLog;

                // If this is a recursive call and not the originating exception being logged,
                // attempt to clone the initial one, and populate it with Exception Type and Message
                // from the inner exception, while retaining the contextual information from where
                // the exception originated.
                if (!isParent)
                {
                    exceptionLog = log.Clone(false);

                    if (exceptionLog != null)
                    {
                        // Populate with inner exception type, message and update whether or not there is another inner exception.
                        exceptionLog.ExceptionType     = ex.GetType().ToString();
                        exceptionLog.Description       = ex.Message;
                        exceptionLog.Source            = ex.Source;
                        exceptionLog.StackTrace        = ex.StackTrace;
                        exceptionLog.HasInnerException = ex.InnerException != null;

                        // Ensure EF properly recognizes this as a new record.
                        exceptionLog.Id       = 0;
                        exceptionLog.Guid     = Guid.NewGuid();
                        exceptionLog.ParentId = log.Id;
                    }
                }
                else
                {
                    exceptionLog = log;
                }

                // The only reason this should happen is if the `log.Clone()` operation failed. Compiler sugar.
                if (exceptionLog == null)
                {
                    return;
                }

                // Write ExceptionLog record to database.
                using (var rockContext = new Rock.Data.RockContext())
                {
                    var exceptionLogService = new ExceptionLogService(rockContext);
                    exceptionLogService.Add(exceptionLog);

                    // make sure to call the regular SaveChanges so that CreatedBy,CreatedByDateTime, etc get set properly. If any of the post processing happens to also create an exception, we can just log to the exception file instead
                    rockContext.SaveChanges();
                }

                // Recurse if inner exception is found
                if (exceptionLog.HasInnerException.GetValueOrDefault(false))
                {
                    LogExceptions(ex.InnerException, exceptionLog, false);
                }

                if (ex is AggregateException)
                {
                    // if an AggregateException occurs, log the exceptions individually
                    var aggregateException = (ex as AggregateException);
                    foreach (var innerException in aggregateException.InnerExceptions)
                    {
                        LogExceptions(innerException, exceptionLog, false);
                    }
                }
            }
            catch (Exception)
            {
                // If logging the exception fails, write the exceptions to a file
                logToFile = true;
            }

            if (logToFile)
            {
                try
                {
                    string directory = AppDomain.CurrentDomain.BaseDirectory;
                    directory = Path.Combine(directory, "App_Data", "Logs");

                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }

                    string filePath = Path.Combine(directory, "RockExceptions.csv");
                    string when     = RockDateTime.Now.ToString();
                    while (ex != null)
                    {
                        File.AppendAllText(filePath, string.Format("{0},{1},\"{2}\",\"{3}\"\r\n", when, ex.GetType(), ex.Message, ex.StackTrace));
                        ex = ex.InnerException;
                    }
                }
                catch
                {
                    // failed to write to database and also failed to write to log file, so there is nowhere to log this error
                }
            }
        }
        /// <summary>
        /// Loads the control.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad( EventArgs e )
        {
            base.OnLoad( e );

            if ( !Page.IsPostBack )
            {
                //Set Exception Panel visibility to show Exception List
                SetExceptionPanelVisibility( None.Id );
            }

            lcExceptions.Options.SetChartStyle( this.ChartStyle );
            lcExceptions.Options.legend = lcExceptions.Options.legend ?? new Legend();
            lcExceptions.Options.legend.show = this.GetAttributeValue( "ShowLegend" ).AsBooleanOrNull();
            lcExceptions.Options.legend.position = this.GetAttributeValue( "LegendPosition" );

            // get data for graphs
            ExceptionLogService exceptionLogService = new ExceptionLogService( new RockContext() );
            var exceptionList = exceptionLogService.Queryable()
            .Where(x => x.HasInnerException == false && x.CreatedDateTime != null)
            .GroupBy( x => DbFunctions.TruncateTime(x.CreatedDateTime.Value ))
            .Select( eg => new
            {
                DateValue = eg.Key,
                ExceptionCount = eg.Count(),
                UniqueExceptionCount = eg.Select( y => y.ExceptionType ).Distinct().Count()
            } ).OrderBy(eg => eg.DateValue).ToList();

            if ( exceptionList.Count == 1 )
            {
                // if there is only one datapoint for the Chart, the yaxis labeling gets messed up, plus the graph wouldn't be useful anyways
                lcExceptions.Visible = false;
            }
        }
Exemple #26
0
            /// <summary>
            /// Called after the save operation has been executed
            /// </summary>
            /// <remarks>
            /// This method is only called if <see cref="M:Rock.Data.EntitySaveHook`1.PreSave" /> returns
            /// without error.
            /// </remarks>
            protected override void PostSave()
            {
                var rockContext = ( RockContext )this.RockContext;

                if (HistoryChanges != null)
                {
                    foreach (var historyItem in HistoryChanges)
                    {
                        int personId = historyItem.PersonId > 0 ? historyItem.PersonId : Entity.PersonId;

                        // if GroupId is 0, it is probably a Group that wasn't saved yet, so get the GroupId from historyItem.Group.Id instead
                        if (historyItem.GroupId == 0)
                        {
                            historyItem.GroupId = historyItem.Group?.Id;
                        }

                        var changes = HistoryService.GetChanges(
                            typeof(Person),
                            Rock.SystemGuid.Category.HISTORY_PERSON_GROUP_MEMBERSHIP.AsGuid(),
                            personId,
                            historyItem.PersonHistoryChangeList,
                            historyItem.Caption,
                            typeof(Group),
                            historyItem.GroupId,
                            Entity.ModifiedByPersonAliasId,
                            rockContext.SourceOfChange);

                        if (changes.Any())
                        {
                            Task.Run(async() =>
                            {
                                // Wait 1 second to allow all post save actions to complete
                                await Task.Delay(1000);
                                try
                                {
                                    using (var insertRockContext = new RockContext())
                                    {
                                        insertRockContext.BulkInsert(changes);
                                    }
                                }
                                catch (SystemException ex)
                                {
                                    ExceptionLogService.LogException(ex, null);
                                }
                            });
                        }

                        var groupMemberChanges = HistoryService.GetChanges(
                            typeof(GroupMember),
                            Rock.SystemGuid.Category.HISTORY_GROUP_CHANGES.AsGuid(),
                            Entity.Id,
                            historyItem.GroupMemberHistoryChangeList,
                            historyItem.Caption,
                            typeof(Group),
                            historyItem.GroupId,
                            Entity.ModifiedByPersonAliasId,
                            rockContext.SourceOfChange);

                        if (groupMemberChanges.Any())
                        {
                            Task.Run(async() =>
                            {
                                // Wait 1 second to allow all post save actions to complete
                                await Task.Delay(1000);
                                try
                                {
                                    using (var insertRockContext = new RockContext())
                                    {
                                        insertRockContext.BulkInsert(groupMemberChanges);
                                    }
                                }
                                catch (SystemException ex)
                                {
                                    ExceptionLogService.LogException(ex, null);
                                }
                            });
                        }
                    }
                }

                base.PostSave();

                // if this is a GroupMember record on a Family, ensure that AgeClassification, PrimaryFamily,
                // GivingLeadId, and GroupSalution is updated
                // NOTE: This is also done on Person.PostSaveChanges in case Birthdate changes
                var groupTypeFamilyRoleIds = GroupTypeCache.GetFamilyGroupType()?.Roles?.Select(a => a.Id).ToList();

                if (groupTypeFamilyRoleIds?.Any() == true)
                {
                    if (groupTypeFamilyRoleIds.Contains(Entity.GroupRoleId))
                    {
                        PersonService.UpdatePersonAgeClassification(Entity.PersonId, rockContext);
                        PersonService.UpdatePrimaryFamily(Entity.PersonId, rockContext);
                        PersonService.UpdateGivingLeaderId(Entity.PersonId, rockContext);


                        GroupService.UpdateGroupSalutations(Entity.GroupId, rockContext);

                        if (_preSaveChangesOldGroupId.HasValue && _preSaveChangesOldGroupId.Value != Entity.GroupId)
                        {
                            // if person was moved to a different family, the old family will need its GroupSalutations updated
                            GroupService.UpdateGroupSalutations(_preSaveChangesOldGroupId.Value, rockContext);
                        }
                    }
                }

                if (State == EntityContextState.Added || State == EntityContextState.Modified)
                {
                    if (Entity.Group != null && Entity.Person != null)
                    {
                        if (Entity.Group?.IsSecurityRoleOrSecurityGroupType() == true)
                        {
                            /* 09/27/2021 MDP
                             *
                             * If this GroupMember record results in making this Person having a higher AccountProtectionProfile level,
                             * update the Person's AccountProtectionProfile.
                             * Note: If this GroupMember record could result in making this Person having a *lower* AccountProtectionProfile level,
                             * don't lower the AccountProtectionProfile here, because other rules have to be considered before
                             * lowering the AccountProtectionProfile level. So we'll let the RockCleanup job take care of making sure the
                             * AccountProtectionProfile is updated after factoring in all the rules.
                             *
                             */

                            if (Entity.Group.ElevatedSecurityLevel >= Utility.Enums.ElevatedSecurityLevel.Extreme &&
                                Entity.Person.AccountProtectionProfile < Utility.Enums.AccountProtectionProfile.Extreme)
                            {
                                Entity.Person.AccountProtectionProfile = Utility.Enums.AccountProtectionProfile.Extreme;
                                rockContext.SaveChanges();
                            }
                            else if (Entity.Group.ElevatedSecurityLevel >= Utility.Enums.ElevatedSecurityLevel.High &&
                                     Entity.Person.AccountProtectionProfile < Utility.Enums.AccountProtectionProfile.High)
                            {
                                Entity.Person.AccountProtectionProfile = Utility.Enums.AccountProtectionProfile.High;
                                rockContext.SaveChanges();
                            }
                        }
                    }
                }
            }
        /// <summary>
        /// Recursively logs exception and any children.
        /// </summary>
        /// <param name="ex">The <see cref="System.Exception"/> to log.</param>
        /// <param name="log">The parent <see cref="Rock.Model.ExceptionLog"/> of the exception being logged. This value is nullable.</param>
        /// <param name="isParent">A <see cref="System.Boolean"/> flag indicating if this Exception is a parent exception. This value is 
        ///     <c>true</c> if the exception that is being logged is a parent exception, otherwise <c>false</c>.
        /// </param>
        private static void LogExceptions( Exception ex, ExceptionLog log, bool isParent )
        {
            // First, attempt to log exception to the database.
            try
            {
                ExceptionLog exceptionLog;

                // If this is a recursive call and not the originating exception being logged,
                // attempt to clone the initial one, and populate it with Exception Type and Message
                // from the inner exception, while retaining the contextual information from where
                // the exception originated.
                if ( !isParent )
                {
                    exceptionLog = log.Clone( false );

                    if ( exceptionLog != null )
                    {
                        // Populate with inner exception type, message and update whether or not there is another inner exception.
                        exceptionLog.ExceptionType = ex.GetType().ToString();
                        exceptionLog.Description = ex.Message;
                        exceptionLog.Source = ex.Source;
                        exceptionLog.StackTrace = ex.StackTrace;
                        exceptionLog.HasInnerException = ex.InnerException != null;

                        // Ensure EF properly recognizes this as a new record.
                        exceptionLog.Id = 0;
                        exceptionLog.Guid = Guid.NewGuid();
                        exceptionLog.ParentId = log.Id;
                    }
                }
                else
                {
                    exceptionLog = log;
                }

                // The only reason this should happen is if the `log.Clone()` operation failed. Compiler sugar.
                if ( exceptionLog == null )
                {
                    return;
                }

                // Write ExceptionLog record to database.
                var rockContext = new Rock.Data.RockContext();
                var exceptionLogService = new ExceptionLogService( rockContext );
                exceptionLogService.Add( exceptionLog );
                rockContext.SaveChanges();

                // Recurse if inner exception is found
                if ( exceptionLog.HasInnerException.GetValueOrDefault( false ) )
                {
                    LogExceptions( ex.InnerException, exceptionLog, false );
                }

                if (ex is AggregateException)
                {
                    // if an AggregateException occurs, log the exceptions individually
                    var aggregateException = ( ex as AggregateException );
                    foreach ( var innerException in aggregateException.InnerExceptions )
                    {
                        LogExceptions( innerException, exceptionLog, false );
                    }
                }
            }
            catch ( Exception )
            {
                // If logging the exception fails, write the exceptions to a file
                try
                {
                    string directory = AppDomain.CurrentDomain.BaseDirectory;
                    directory = Path.Combine( directory, "App_Data", "Logs" );

                    if ( !Directory.Exists( directory ) )
                    {
                        Directory.CreateDirectory( directory );
                    }

                    string filePath = Path.Combine( directory, "RockExceptions.csv" );
                    string when = RockDateTime.Now.ToString();
                    while ( ex != null )
                    {
                        File.AppendAllText( filePath, string.Format( "{0},{1},\"{2}\"\r\n", when, ex.GetType(), ex.Message ) );
                        ex = ex.InnerException;
                    }
                }
                catch
                {
                    // failed to write to database and also failed to write to log file, so there is nowhere to log this error
                }
            }
        }
Exemple #28
0
            /// <summary>
            /// Called before the save operation is executed.
            /// </summary>
            protected override void PreSave()
            {
                var    rockContext = ( RockContext )this.RockContext;
                string errorMessage;

                if (State != EntityContextState.Deleted &&
                    Entity.IsArchived == false &&
                    Entity.GroupMemberStatus != GroupMemberStatus.Inactive)
                {
                    if (!Entity.ValidateGroupMembership(rockContext, out errorMessage))
                    {
                        var ex = new GroupMemberValidationException(errorMessage);
                        ExceptionLogService.LogException(ex);
                        throw ex;
                    }
                }

                var updateGroupMemberMsg = new UpdateGroupMember.Message
                {
                    State             = State,
                    GroupId           = Entity.GroupId,
                    PersonId          = Entity.PersonId,
                    GroupMemberStatus = Entity.GroupMemberStatus,
                    GroupMemberRoleId = Entity.GroupRoleId,
                    IsArchived        = Entity.IsArchived
                };

                if (Entity.Group != null)
                {
                    updateGroupMemberMsg.GroupTypeId = Entity.Group.GroupTypeId;
                }

                // If this isn't a new group member, get the previous status and role values
                if (State == EntityContextState.Modified)
                {
                    updateGroupMemberMsg.PreviousGroupMemberStatus = ( GroupMemberStatus )OriginalValues[nameof(GroupMember.GroupMemberStatus)].ToStringSafe().ConvertToEnum <GroupMemberStatus>();
                    updateGroupMemberMsg.PreviousGroupMemberRoleId = OriginalValues[nameof(GroupMember.GroupRoleId)].ToStringSafe().AsInteger();
                    updateGroupMemberMsg.PreviousIsArchived        = OriginalValues[nameof(GroupMember.IsArchived)].ToStringSafe().AsBoolean();
                }

                // If this isn't a deleted group member, get the group member guid
                if (State != EntityContextState.Deleted)
                {
                    updateGroupMemberMsg.GroupMemberGuid = Entity.Guid;
                }

                updateGroupMemberMsg.Send();

                int?oldPersonId = null;
                int?newPersonId = null;

                int?oldGroupId = null;
                int?newGroupId = null;

                switch (State)
                {
                case EntityContextState.Added:
                {
                    oldPersonId = null;
                    newPersonId = Entity.PersonId;

                    oldGroupId = null;
                    newGroupId = Entity.GroupId;

                    if (!Entity.DateTimeAdded.HasValue)
                    {
                        Entity.DateTimeAdded = RockDateTime.Now;
                    }

                    // if this is a new record, but is saved with IsActive=False, set the InactiveDateTime if it isn't set already
                    if (Entity.GroupMemberStatus == GroupMemberStatus.Inactive)
                    {
                        Entity.InactiveDateTime = Entity.InactiveDateTime ?? RockDateTime.Now;
                    }

                    break;
                }

                case EntityContextState.Modified:
                {
                    oldPersonId = OriginalValues[nameof(GroupMember.PersonId)].ToStringSafe().AsIntegerOrNull();
                    newPersonId = Entity.PersonId;

                    oldGroupId = OriginalValues[nameof(GroupMember.GroupId)].ToStringSafe().AsIntegerOrNull();
                    newGroupId = Entity.GroupId;

                    var originalStatus = OriginalValues[nameof(GroupMember.GroupMemberStatus)].ToStringSafe().ConvertToEnum <GroupMemberStatus>();

                    // IsActive was modified, set the InactiveDateTime if it changed to Inactive, or set it to NULL if it changed to Active
                    if (originalStatus != Entity.GroupMemberStatus)
                    {
                        if (Entity.GroupMemberStatus == GroupMemberStatus.Inactive)
                        {
                            // if the caller didn't already set InactiveDateTime, set it to now
                            Entity.InactiveDateTime = Entity.InactiveDateTime ?? RockDateTime.Now;
                        }
                        else
                        {
                            Entity.InactiveDateTime = null;
                        }
                    }

                    break;
                }

                case EntityContextState.Deleted:
                {
                    oldPersonId = Entity.PersonId;
                    newPersonId = null;

                    oldGroupId = Entity.GroupId;
                    newGroupId = null;

                    break;
                }
                }

                Group group = Entity.Group;

                if (group == null)
                {
                    group = new GroupService(rockContext).Get(Entity.GroupId);
                }

                if (group != null)
                {
                    string oldGroupName = group.Name;
                    if (oldGroupId.HasValue && oldGroupId.Value != group.Id)
                    {
                        var oldGroup = new GroupService(rockContext).Get(oldGroupId.Value);
                        if (oldGroup != null)
                        {
                            oldGroupName = oldGroup.Name;
                        }
                    }

                    HistoryChanges = new List <HistoryItem>();
                    if (newPersonId.HasValue)
                    {
                        HistoryChanges.Add(new HistoryItem()
                        {
                            PersonId = newPersonId.Value,
                            Caption  = group.Name,
                            GroupId  = group.Id,
                            Group    = group
                        });
                    }

                    if (oldPersonId.HasValue)
                    {
                        HistoryChanges.Add(new HistoryItem()
                        {
                            PersonId = oldPersonId.Value,
                            Caption  = oldGroupName,
                            GroupId  = oldGroupId
                        });
                    }

                    if (newPersonId.HasValue && newGroupId.HasValue &&
                        (!oldPersonId.HasValue || oldPersonId.Value != newPersonId.Value || !oldGroupId.HasValue || oldGroupId.Value != newGroupId.Value))
                    {
                        // New Person in group
                        var historyItem = HistoryChanges.First(h => h.PersonId == newPersonId.Value && h.GroupId == newGroupId.Value);

                        historyItem.PersonHistoryChangeList.AddChange(History.HistoryVerb.AddedToGroup, History.HistoryChangeType.Record, $"'{group.Name}' Group");
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Role", ( int? )null, Entity.GroupRole, Entity.GroupRoleId, rockContext);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Note", string.Empty, Entity.Note);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Status", null, Entity.GroupMemberStatus);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Communication Preference", null, Entity.CommunicationPreference);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Guest Count", ( int? )null, Entity.GuestCount);

                        var addedMemberPerson = Entity.Person ?? new PersonService(rockContext).Get(Entity.PersonId);

                        // add the Person's Name as ValueName and Caption (just in case the groupmember record is deleted later)
                        historyItem.GroupMemberHistoryChangeList.AddChange(History.HistoryVerb.AddedToGroup, History.HistoryChangeType.Record, $"{addedMemberPerson?.FullName}").SetCaption($"{addedMemberPerson?.FullName}");
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Role", ( int? )null, Entity.GroupRole, Entity.GroupRoleId, rockContext);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Note", string.Empty, Entity.Note);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Status", null, Entity.GroupMemberStatus);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Communication Preference", null, Entity.CommunicationPreference);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Guest Count", ( int? )null, Entity.GuestCount);
                    }

                    if (newPersonId.HasValue && oldPersonId.HasValue && oldPersonId.Value == newPersonId.Value &&
                        newGroupId.HasValue && oldGroupId.HasValue && oldGroupId.Value == newGroupId.Value)
                    {
                        // Updated same person in group
                        var historyItem = HistoryChanges.First(h => h.PersonId == newPersonId.Value && h.GroupId == newGroupId.Value);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Role", OriginalValues["GroupRoleId"].ToStringSafe().AsIntegerOrNull(), Entity.GroupRole, Entity.GroupRoleId, rockContext);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Note", OriginalValues["Note"].ToStringSafe(), Entity.Note);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Status", OriginalValues["GroupMemberStatus"].ToStringSafe().ConvertToEnum <GroupMemberStatus>(), Entity.GroupMemberStatus);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Communication Preference", OriginalValues["CommunicationPreference"].ToStringSafe().ConvertToEnum <CommunicationType>(), Entity.CommunicationPreference);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Guest Count", OriginalValues["GuestCount"].ToStringSafe().AsIntegerOrNull(), Entity.GuestCount);
                        History.EvaluateChange(historyItem.PersonHistoryChangeList, $"{historyItem.Caption} Archived", OriginalValues["IsArchived"].ToStringSafe().AsBoolean(), Entity.IsArchived);

                        // If the groupmember was Archived, make sure it is the first GroupMember History change (since they get summarized when doing a HistoryLog and Timeline
                        bool origIsArchived = OriginalValues[nameof(GroupMember.IsArchived)].ToStringSafe().AsBoolean();

                        if (origIsArchived != Entity.IsArchived)
                        {
                            var memberPerson = Entity.Person ?? new PersonService(rockContext).Get(Entity.PersonId);
                            if (Entity.IsArchived == true)
                            {
                                // GroupMember changed to Archived
                                historyItem.GroupMemberHistoryChangeList.AddChange(History.HistoryVerb.RemovedFromGroup, History.HistoryChangeType.Record, $"{memberPerson?.FullName}").SetCaption($"{memberPerson?.FullName}");
                            }
                            else
                            {
                                // GroupMember changed to Not archived
                                historyItem.GroupMemberHistoryChangeList.AddChange(History.HistoryVerb.AddedToGroup, History.HistoryChangeType.Record, $"{memberPerson?.FullName}").SetCaption($"{memberPerson?.FullName}");
                            }
                        }

                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Role", OriginalValues[nameof(GroupMember.GroupRoleId)].ToStringSafe().AsIntegerOrNull(), Entity.GroupRole, Entity.GroupRoleId, rockContext);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Note", OriginalValues[nameof(GroupMember.Note)].ToStringSafe(), Entity.Note);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Status", OriginalValues[nameof(GroupMember.GroupMemberStatus)].ToStringSafe().ConvertToEnum <GroupMemberStatus>(), Entity.GroupMemberStatus);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Communication Preference", OriginalValues[nameof(GroupMember.CommunicationPreference)].ToStringSafe().ConvertToEnum <CommunicationType>(), Entity.CommunicationPreference);
                        History.EvaluateChange(historyItem.GroupMemberHistoryChangeList, $"Guest Count", OriginalValues[nameof(GroupMember.GuestCount)].ToStringSafe().AsIntegerOrNull(), Entity.GuestCount);
                    }

                    if (oldPersonId.HasValue && oldGroupId.HasValue &&
                        (!newPersonId.HasValue || newPersonId.Value != oldPersonId.Value || !newGroupId.HasValue || newGroupId.Value != oldGroupId.Value))
                    {
                        // Removed a person/groupmember in group
                        var historyItem = HistoryChanges.First(h => h.PersonId == oldPersonId.Value && h.GroupId == oldGroupId.Value);

                        historyItem.PersonHistoryChangeList.AddChange(History.HistoryVerb.RemovedFromGroup, History.HistoryChangeType.Record, $"{oldGroupName} Group");

                        var deletedMemberPerson = Entity.Person ?? new PersonService(rockContext).Get(Entity.PersonId);

                        historyItem.GroupMemberHistoryChangeList.AddChange(History.HistoryVerb.RemovedFromGroup, History.HistoryChangeType.Record, $"{deletedMemberPerson?.FullName}").SetCaption($"{deletedMemberPerson?.FullName}");
                    }

                    // process universal search indexing if required
                    var groupType = GroupTypeCache.Get(group.GroupTypeId);
                    if (groupType != null && groupType.IsIndexEnabled)
                    {
                        var processEntityTypeIndexMsg = new ProcessEntityTypeIndex.Message
                        {
                            EntityTypeId = groupType.Id,
                            EntityId     = group.Id
                        };

                        processEntityTypeIndexMsg.Send();
                    }
                }

                _preSaveChangesOldGroupId = oldGroupId;

                base.PreSave();
            }
        /// <summary>
        /// Builds the base query for the Exception List grid data
        /// </summary>
        /// <returns>IQueryable containing filtered ExceptionLog records</returns>
        private IQueryable<ExceptionLog> BuildBaseExceptionListQuery( RockContext rockContext )
        {
            ExceptionLogService exceptionLogService = new ExceptionLogService( rockContext );
            IQueryable<ExceptionLog> query = exceptionLogService.Queryable();

            int siteId;
            if ( int.TryParse( fExceptionList.GetUserPreference( "Site" ), out siteId ) && siteId > 0 )
            {
                query = query.Where( e => e.SiteId == siteId );
            }

            int pageId;
            if ( int.TryParse( fExceptionList.GetUserPreference( "Page" ), out pageId ) && pageId > 0 )
            {
                query = query.Where( e => e.PageId == pageId );
            }

            int userPersonID;
            if ( int.TryParse( fExceptionList.GetUserPreference( "User" ), out userPersonID ) && userPersonID > 0 )
            {
                query = query.Where( e => e.CreatedByPersonAlias != null && e.CreatedByPersonAlias.PersonId == userPersonID );
            }

            string statusCode = fExceptionList.GetUserPreference( "Status Code" );
            if ( !String.IsNullOrEmpty( statusCode ) )
            {
                query = query.Where( e => e.StatusCode == statusCode );
            }

            var dateRange = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues( fExceptionList.GetUserPreference( "Date Range" ) );

            if ( dateRange.Start.HasValue )
            {
                query = query.Where( e => e.CreatedDateTime.HasValue && e.CreatedDateTime.Value >= dateRange.Start.Value );
            }

            if ( dateRange.End.HasValue )
            {
                query = query.Where( e => e.CreatedDateTime.HasValue && e.CreatedDateTime.Value < dateRange.End.Value );
            }

            //Only look for inner exceptions
            query = query.Where( e => e.HasInnerException == null || e.HasInnerException == false );

            return query;
        }
Exemple #30
0
        /// <summary>
        /// Shows the detail of the exception
        /// </summary>
        /// <param name="itemKey">Item Key (should be ExceptionId in this instance).</param>
        /// <param name="itemKeyValue">Item key value (should be ExceptionId).</param>
        public void ShowDetail( string itemKey, int itemKeyValue )
        {
            //if item key is not ExceptionId return
            if ( !itemKey.Equals( "ExceptionId" ) )
            {
                return;
            }

            //Get exception
            var baseException = new ExceptionLogService().Get( itemKeyValue );

            //set fields
            if ( baseException == null )
            {
                return;
            }

            DescriptionList dl = new DescriptionList();

            dl.Add( "Site", baseException.Site != null ? baseException.Site.Name : String.Empty, true );
            dl.Add( "Page", baseException.Page != null ? string.Format( "{0} <a href=\"{1}\" class=\"btn btn-mini\" target=\"_blank\"><i class=\"fa fa-arrow-right\"></i></a>", baseException.Page.InternalName, baseException.PageUrl ) : String.Empty, true );

            //If query string is not empty build query string list
            if ( !String.IsNullOrWhiteSpace( baseException.QueryString ) )
            {
                dl.Add( "Query String", BuildQueryStringList( baseException.QueryString ) );
            }


            dl.Add( "User", baseException.CreatedByPersonId != null ? baseException.CreatedByPerson.FullName : "Anonymous" );
            dl.Add( "Exception Date", string.Format( "{0:g}", baseException.ExceptionDateTime ) );
            lExceptionSummary.Text = dl.Html;

            lCookies.Text = baseException.Cookies;
            lServerVariables.Text = baseException.ServerVariables;

            //check to see if Show Cookies attribute is true
            if( Convert.ToBoolean( GetAttributeValue( "ShowCookies" ) ) )
            {
                //if so check check box and register script to show cookies div
                chkShowCookies.Checked = true;
                ScriptManager.RegisterStartupScript( upExcpetionDetail, upExcpetionDetail.GetType(), "ShowCookiesOnLoad" + DateTime.Now.Ticks, "$(\"#divCookies\").css(\"display\", \"inherit\");", true );
            }
            else
            {
                chkShowCookies.Checked = false;
            }

            //check to see if show server variables attribute is checked
            if ( Convert.ToBoolean( GetAttributeValue( "ShowServerVariables" ) ) )
            {
                chkShowServerVariables.Checked = true;
                ScriptManager.RegisterStartupScript( upExcpetionDetail, upExcpetionDetail.GetType(), "ShowServerVariablesOnLoad" + DateTime.Now.Ticks, "$(\"#divServerVariables\").css(\"display\", \"inherit\");", true );
            }
            else
            {
                chkShowServerVariables.Checked = false;
            }

            rptExcpetionDetails.DataSource = GetExceptionLogs( baseException ).OrderBy( e => e.Id );
            rptExcpetionDetails.DataBind();

            pnlSummary.Visible = true;
        }
        /// <summary>
        /// Binds the exception occurrence grid.
        /// </summary>
        /// <param name="baseException">Exception to base the occurrence grid off of.</param>
        private void BindExceptionOccurrenceGrid( ExceptionLog baseException )
        {
            ExceptionLogService exceptionService = new ExceptionLogService( new RockContext() );

            var query = exceptionService.Queryable()
                .Where( e => e.HasInnerException == null || e.HasInnerException == false )
                .Where( e => e.SiteId == baseException.SiteId )
                .Where( e => e.PageId == baseException.PageId )
                .Where( e => e.Description == baseException.Description )
                .Select( e => new
                    {
                        Id = e.Id,
                        CreatedDateTime = e.CreatedDateTime,
                        FullName = ( e.CreatedByPersonAlias != null &&
                            e.CreatedByPersonAlias.Person != null ) ?
                            e.CreatedByPersonAlias.Person.LastName + ", " + e.CreatedByPersonAlias.Person.NickName : "",
                        Description = e.Description
                    } ).OrderBy(e => e.CreatedDateTime);

            if ( gExceptionOccurrences.SortProperty == null )
            {
                gExceptionOccurrences.DataSource = query.OrderByDescending( e => e.CreatedDateTime ).ToList();
            }
            else
            {
                gExceptionOccurrences.DataSource = query.Sort( gExceptionOccurrences.SortProperty ).ToList();
            }

            gExceptionOccurrences.DataBind();
        }
        /// <summary>
        /// Binds the exception occurrence grid.
        /// </summary>
        /// <param name="baseException">Exception to base the occurrence grid off of.</param>
        private void BindExceptionOccurrenceGrid( ExceptionLog baseException )
        {
            ExceptionLogService exceptionService = new ExceptionLogService( new RockContext() );
            string url = String.Format( "{0}?ExceptionId=", LinkedPageUrl( "DetailPage" ) );

            var query = exceptionService.Queryable()
                .Where( e => e.HasInnerException == null || e.HasInnerException == false )
                .Where( e => e.Description.Substring( 0, 28 ) == baseException.Description.Substring( 0, 28 ) )
                .Select( e => new
                {
                    Id = e.Id,
                    CreatedDateTime = e.CreatedDateTime,
                    PageName = e.Page.InternalName ?? e.PageUrl,
                    FullName = ( e.CreatedByPersonAlias != null &&
                            e.CreatedByPersonAlias.Person != null ) ?
                            e.CreatedByPersonAlias.Person.LastName + ", " + e.CreatedByPersonAlias.Person.NickName : "",
                    Description = "<a href='" + url + e.Id + "'>" + e.Description + "</a>"
                } ).OrderBy( e => e.CreatedDateTime );

            if ( gExceptionOccurrences.SortProperty == null )
            {
                query = query.OrderByDescending( e => e.CreatedDateTime );
            }
            else
            {
                query = query.Sort( gExceptionOccurrences.SortProperty );
            }

            gExceptionOccurrences.EntityTypeId = EntityTypeCache.Read<ExceptionLog>().Id;
            gExceptionOccurrences.SetLinqDataSource( query );
            gExceptionOccurrences.DataBind();
        }
        /// <summary>
        /// Loads the exception occurrences panel
        /// </summary>
        /// <param name="exceptionId">The Id of the base exception for the grid</param>
        private void LoadExceptionOccurrences( int exceptionId )
        {
            //get the base exception
            ExceptionLogService exceptionService = new ExceptionLogService( new RockContext() );
            ExceptionLog exception = exceptionService.Get( exceptionId );

            //set the summary fields for the base exception
            if ( exception != null )
            {
                if ( Page.IsPostBack && Page.IsAsync )
                {
                    this.AddHistory( "Exception", exceptionId.ToString(), string.Format( "Exception Occurrences {0}", exception.Description ) );
                }
                hfBaseExceptionID.Value = exceptionId.ToString();

                var descriptionList = new Rock.Web.DescriptionList();

                // set detail title with formating
                lDetailTitle.Text = String.Format( "Occurrences of {0}", exception.ExceptionType ).FormatAsHtmlTitle();

                if ( !string.IsNullOrEmpty( exception.ExceptionType ) )
                {
                    descriptionList.Add( "Type", exception.ExceptionType );
                }

                if ( exception.Site != null )
                {
                    descriptionList.Add( "Site", exception.Site.Name );
                }

                if ( exception.Page != null )
                {
                    descriptionList.Add( "Page", exception.Page.InternalName );
                }

                lblMainDetails.Text = descriptionList.Html;

                //Load the occurrences for the selected exception
                BindExceptionOccurrenceGrid( exception );
            }
        }
Exemple #34
0
        /// <summary>
        /// Pres the save.
        /// </summary>
        /// <param name="dbContext">The database context.</param>
        /// <param name="entry">The entry.</param>
        public override void PreSaveChanges(DbContext dbContext, System.Data.Entity.Infrastructure.DbEntityEntry entry)
        {
            if (entry.State == System.Data.Entity.EntityState.Deleted)
            {
                if (StorageProvider != null)
                {
                    this.BinaryFileTypeId = entry.OriginalValues["BinaryFileTypeId"].ToString().AsInteger();

                    try
                    {
                        StorageProvider.DeleteContent(this);
                    }
                    catch (Exception ex)
                    {
                        // If an exception occurred while trying to delete provider's file, log the exception, but continue with the delete.
                        ExceptionLogService.LogException(ex);
                    }

                    this.BinaryFileTypeId = null;
                }
            }
            else
            {
                if (BinaryFileType == null && BinaryFileTypeId.HasValue)
                {
                    BinaryFileType = new BinaryFileTypeService(( RockContext )dbContext).Get(BinaryFileTypeId.Value);
                }

                if (this.MimeType.StartsWith("image/"))
                {
                    try
                    {
                        using (Bitmap bm = new Bitmap(this.ContentStream))
                        {
                            if (bm != null)
                            {
                                this.Width  = bm.Width;
                                this.Height = bm.Height;
                            }
                        }
                        ContentStream.Seek(0, SeekOrigin.Begin);

                        if (!IsTemporary)
                        {
                            if (BinaryFileType.MaxHeight.HasValue &&
                                BinaryFileType.MaxHeight != 0 &&
                                BinaryFileType.MaxWidth.HasValue &&
                                BinaryFileType.MaxWidth != 0)
                            {
                                ResizeSettings settings      = new ResizeSettings();
                                MemoryStream   resizedStream = new MemoryStream();
                                if (BinaryFileType.MaxWidth.Value < Width || BinaryFileType.MaxHeight < Height)
                                {
                                    settings.Add("mode", "max");
                                    if (BinaryFileType.MaxHeight < Height && BinaryFileType.MaxWidth < Width)
                                    {
                                        if (BinaryFileType.MaxHeight >= BinaryFileType.MaxWidth)
                                        {
                                            settings.Add("height", BinaryFileType.MaxHeight.Value.ToString());
                                        }
                                        if (BinaryFileType.MaxHeight <= BinaryFileType.MaxWidth)
                                        {
                                            settings.Add("width", BinaryFileType.MaxWidth.Value.ToString());
                                        }
                                    }
                                    else if (BinaryFileType.MaxHeight < Height)
                                    {
                                        settings.Add("height", BinaryFileType.MaxHeight.Value.ToString());
                                    }
                                    else
                                    {
                                        settings.Add("width", BinaryFileType.MaxWidth.Value.ToString());
                                    }
                                    ImageBuilder.Current.Build(this.ContentStream, resizedStream, settings);
                                    ContentStream = resizedStream;

                                    using (Bitmap bm = new Bitmap(this.ContentStream))
                                    {
                                        if (bm != null)
                                        {
                                            this.Width  = bm.Width;
                                            this.Height = bm.Height;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception) { }   // if the file is an invalid photo keep moving
                }

                if (entry.State == System.Data.Entity.EntityState.Added)
                {
                    // when a file is saved (unless it is getting Deleted/Saved), it should use the StoredEntityType that is associated with the BinaryFileType
                    if (BinaryFileType != null)
                    {
                        // Persist the storage type
                        StorageEntityTypeId = BinaryFileType.StorageEntityTypeId;

                        // Persist the storage type's settings specific to this binary file type
                        var settings = new Dictionary <string, string>();
                        if (BinaryFileType.Attributes == null)
                        {
                            BinaryFileType.LoadAttributes();
                        }
                        foreach (var attributeValue in BinaryFileType.AttributeValues)
                        {
                            settings.Add(attributeValue.Key, attributeValue.Value.Value);
                        }
                        StorageEntitySettings = settings.ToJson();

                        if (StorageProvider != null)
                        {
                            // save the file to the provider's new storage medium, and if the medium returns a filesize, save that value.
                            long?outFileSize = null;
                            StorageProvider.SaveContent(this, out outFileSize);
                            if (outFileSize.HasValue)
                            {
                                FileSize = outFileSize;
                            }

                            Path = StorageProvider.GetPath(this);
                        }
                    }
                }


                else if (entry.State == System.Data.Entity.EntityState.Modified)
                {
                    // when a file is saved (unless it is getting Deleted/Added),
                    // it should use the StorageEntityType that is associated with the BinaryFileType
                    if (BinaryFileType != null)
                    {
                        // if the storage provider changed, or any of its settings specific
                        // to the binary file type changed, delete the original provider's content
                        if (StorageEntityTypeId.HasValue && BinaryFileType.StorageEntityTypeId.HasValue)
                        {
                            var settings = new Dictionary <string, string>();
                            if (BinaryFileType.Attributes == null)
                            {
                                BinaryFileType.LoadAttributes();
                            }
                            foreach (var attributeValue in BinaryFileType.AttributeValues)
                            {
                                settings.Add(attributeValue.Key, attributeValue.Value.Value);
                            }
                            string settingsJson = settings.ToJson();

                            if (StorageProvider != null && (
                                    StorageEntityTypeId.Value != BinaryFileType.StorageEntityTypeId.Value ||
                                    StorageEntitySettings != settingsJson))
                            {
                                var ms = new MemoryStream();
                                ContentStream.Position = 0;
                                ContentStream.CopyTo(ms);
                                ContentStream.Dispose();

                                // Delete the current provider's storage
                                StorageProvider.DeleteContent(this);

                                // Set the new storage provider with its settings
                                StorageEntityTypeId   = BinaryFileType.StorageEntityTypeId;
                                StorageEntitySettings = settingsJson;

                                ContentStream = new MemoryStream();
                                ms.Position   = 0;
                                ms.CopyTo(ContentStream);
                                ContentStream.Position = 0;
                                FileSize = ContentStream.Length;
                            }
                        }
                    }

                    if (_contentIsDirty && StorageProvider != null)
                    {
                        long?fileSize = null;
                        StorageProvider.SaveContent(this, out fileSize);

                        FileSize = fileSize;
                        Path     = StorageProvider.GetPath(this);
                    }
                }
            }

            base.PreSaveChanges(dbContext, entry);
        }