📄 metrics.pm
字号:
################################################################################ Copyright (c) 2003 Jason Remillard. All rights reserved.## This program is free software; you can redistribute it and modify it under# the terms of the GPL.# Model object for handling metric data.package Codestriker::Model::Metrics;use strict;use Encode qw(decode_utf8);use Codestriker::DB::DBI;sub new { my ($class, $topicid) = @_; my $self = {}; $self->{topicmetrics} = undef; $self->{topicid} = $topicid; $self->{usermetrics} = {}; $self->{topichistoryrows} = undef; bless $self, $class; return $self;}# Sets the topic metrics values. The values are passed in as an# array. The array must be in the same order returned by# get_topic_metric(). Metrics that are bad are silently not stored.sub set_topic_metrics { my ($self,@metric_values) = @_; my @metrics = $self->get_topic_metrics(); for (my $index = 0; $index < scalar(@metrics); ++$index) { next if ($metrics[$index]->{enabled} == 0); die "error: not enough metrics" if (scalar(@metric_values) == 0); my $value = shift @metric_values; if ($self->_verify_metric($metrics[$index], $value) eq '') { $metrics[$index]->{value} = $value; } }}# Verifies that all of the topic metrics are well formed and valid. It will# return a non-empty string if a problem is found.sub verify_topic_metrics { my ($self,@metric_values) = @_; my $msg = ''; my @metrics = $self->get_topic_metrics(); for (my $index = 0; $index < scalar(@metrics); ++$index) { next if ($metrics[$index]->{enabled} == 0); # Disabled values may be in the database (somebody turned off # the metrics). However, they are not paramters so the index # between the paramters and the metrics objects will not # match. my $value = shift @metric_values; $msg .= $self->_verify_metric($metrics[$index], $value); } return $msg;}# Returns the topic metrics as a collection of references to# hashs. The hash that is returned has the same keys as the# metrics_schema hash, plus a value key. If the user has not entered a# value, it will be set to an empty string.sub get_topic_metrics { my $self = shift; my @topic_metrics; if (defined($self->{topicmetrics})) { # The topic metrics have already been loaded from the # database, just return the cached data. @topic_metrics = @{$self->{topicmetrics}}; } else { my @stored_metrics = (); if (defined($self->{topicid})) { # Obtain a database connection. my $dbh = Codestriker::DB::DBI->get_connection(); my $select_topic_metrics = $dbh->prepare_cached('SELECT topicmetric.metric_name, topicmetric.value ' . 'FROM topicmetric ' . 'WHERE topicmetric.topicid = ?'); $select_topic_metrics->execute($self->{topicid}); @stored_metrics = @{$select_topic_metrics->fetchall_arrayref()}; # Close the connection, and check for any database errors. Codestriker::DB::DBI->release_connection($dbh, 1); } # Match the configured metrics to the metrics in the database. If # the configured metric is found in the database, it is removed # from the stored_metric list to find any data that is in the # database, but is not configured. foreach my $metric_schema (Codestriker::get_metric_schema()) { if ($metric_schema->{scope} eq 'topic') { my $metric = { # This is the topic metric. name => $metric_schema->{name}, description => $metric_schema->{description}, value => '', filter => $metric_schema->{filter}, enabled => $metric_schema->{enabled}, in_database => 0 }; for (my $index = 0; $index < scalar(@stored_metrics); ++$index) { my $stored_metric = $stored_metrics[$index]; if ($stored_metric->[0] eq $metric_schema->{name}) { $metric->{value} = $stored_metric->[1]; $metric->{in_database} = 1; splice @stored_metrics, $index, 1; last; } } if ($metric_schema->{enabled} || $metric->{in_database}) { push @topic_metrics, $metric; } } } # Add in any metrics that are in the database but not # currently configured. The system should display the # metrics, but not let the user modify them. for (my $index = 0; $index < scalar(@stored_metrics); ++$index) { my $stored_metric = $stored_metrics[$index]; # This is the topic metric. my $metric = { name => $stored_metric->[0], description => '', value => $stored_metric->[1], # User can not change the metric, not configured. enabled => 0, in_database => 1 }; push @topic_metrics, $metric; } push @topic_metrics, $self->_get_built_in_topic_metrics(); $self->{topicmetrics} = \@topic_metrics; } return @topic_metrics;}# Get just the list of users that have actually looked at the review. This is# used on the main page to out users that are not doing the reviews when invited.sub get_list_of_actual_topic_participants { my ($self) = @_; my $dbh = Codestriker::DB::DBI->get_connection(); my $actual_user_list_ref = $dbh->selectall_arrayref( 'SELECT DISTINCT LOWER(email) FROM topicviewhistory ' . 'WHERE topicid = ?',{}, $self->{topicid}); my @actual_user_list = (); foreach my $user ( @$actual_user_list_ref ) { push @actual_user_list,$user->[0] if defined $user->[0] && $user->[0] ne ""; } # Close the connection, and check for any database errors. Codestriker::DB::DBI->release_connection($dbh, 1); return @actual_user_list;}# Get a list of users that have metric data for this topic. People can# look at the topic even if they were not invited, so if somebody touches the# topic, they will appear in this list. Using this function rather than the# invite list from the topic will insure that people don't get missed from# the metric data.sub get_complete_list_of_topic_participants { my ($self) = @_; my $dbh = Codestriker::DB::DBI->get_connection(); my @metric_user_list = @{ $dbh->selectall_arrayref(' SELECT distinct LOWER(email) from participant WHERE topicid = ?',{}, $self->{topicid})}; push @metric_user_list, @{ $dbh->selectall_arrayref(' SELECT LOWER(author) FROM topic WHERE id = ?',{}, $self->{topicid})}; push @metric_user_list, @{ $dbh->selectall_arrayref(' SELECT DISTINCT LOWER(email) FROM topicusermetric WHERE topicid = ?',{}, $self->{topicid})}; push @metric_user_list, @{ $dbh->selectall_arrayref( 'SELECT DISTINCT LOWER(author) FROM commentdata, commentstate ' . 'WHERE commentstate.topicid = ? AND commentstate.id = commentdata.commentstateid ', { }, $self->{topicid})}; push @metric_user_list, @{ $dbh->selectall_arrayref( 'SELECT DISTINCT LOWER(email) FROM topicviewhistory ' . 'WHERE topicid = ? AND email IS NOT NULL',{}, $self->{topicid})}; # remove the duplicates. my %metric_user_hash; foreach my $user (@metric_user_list) { $metric_user_hash{$user->[0]} = 1; } # Need to sort the empty user name last so that the template parameters # that are done by index don't start at 1, and therefor not allow users # to save the metrics. @metric_user_list = sort { return 1 if ( $a eq ""); return -1 if ( $b eq ""); return $a cmp $b; } keys %metric_user_hash; # Close the connection, and check for any database errors. Codestriker::DB::DBI->release_connection($dbh, 1); return @metric_user_list;}# Sets the metrics for a specific user, both authors and reviewers. cc's don't# get metrics. The metrics are sent in as an array, that must in the same# order as the get_user_metric() call returns them. Metrics that are bad are# silently not stored.sub set_user_metric { my ($self, $user, @metric_values) = @_; my @metrics = $self->get_user_metrics($user); for (my $index = 0; $index < scalar(@metrics); ++$index) { next if ($metrics[$index]->{enabled} == 0); die "error: not enough metrics" if (scalar(@metric_values) == 0); # Disabled values may be in the database (somebody turned off # the metrics). However, they are not paramters so the index # between the paramters and the metrics objects will not # match. my $value = shift @metric_values; if ($self->_verify_metric($metrics[$index], $value) eq '') { $metrics[$index]->{value} = $value } }}# Verifies that all of the user metrics are well formed and valid inputs. If a# problem is found the function will return a non-empty string.sub verify_user_metrics { my ($self, $user, @metric_values) = @_; my $msg = ''; my @metrics = $self->get_user_metrics($user); for (my $index = 0; $index < scalar(@metrics); ++$index) { next if ($metrics[$index]->{enabled} == 0); # Disabled values may be in the database (somebody turned off # the metrics). However, they are not paramters so the index # between the paramters and the metrics objects will not # match. my $value = shift @metric_values; $msg .= $self->_verify_metric($metrics[$index], $value); } return $msg;}# Returns the user metrics as a collection of references to hashs. The# hash that is returned has the same keys as the metrics_schema hash,# plus a value key. If the user has not entered a value, it will be# set to an empty string.sub get_user_metrics { my ($self, $username) = @_; my @user_metrics; if (exists($self->{usermetrics}->{$username})) { # If the metrics for this user has already been loaded from # the database, return the cached result of that load. @user_metrics = @{$self->{usermetrics}->{$username}}; } else { my @stored_metrics = (); if (defined($self->{topicid})) { # Obtain a database connection. my $dbh = Codestriker::DB::DBI->get_connection(); # Get all of the user outputs for this topic regardless of # the user. my $selected_all_user_metrics = $dbh->prepare_cached('SELECT DISTINCT metric_name ' . 'FROM topicusermetric ' . 'WHERE topicid = ? ' . 'ORDER BY metric_name'); $selected_all_user_metrics->execute($self->{topicid}); @stored_metrics = @{$selected_all_user_metrics->fetchall_arrayref()};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -