niobi-8.x-2.0-alpha4/modules/niobi_form/modules/niobi_app/src/Plugin/views/field/NumericReviewScore.php
modules/niobi_form/modules/niobi_app/src/Plugin/views/field/NumericReviewScore.php
<?php
namespace Drupal\niobi_app\Plugin\views\field;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\ResultRow;
use Drupal\views_add_button\ViewsAddButtonUtilities;
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
/**
* Defines a views field plugin.
*
* @ingroup views_field_handlers
*
* @ViewsField("niobi_app_numeric_review_score")
*/
class NumericReviewScore extends FieldPluginBase {
/**
* {@inheritdoc}
*/
public function query() {
// Leave empty to avoid a query on this field.
}
/**
* Define the available options.
*
* @return array
* Array of available options for views_add_button form.
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['report_type'] = ['default' => 'sum'];
$options['exclude_fields'] = ['default' => ''];
$options['require_fields'] = ['default' => ''];
$options['allowed_forms'] = ['default' => ''];
return $options;
}
/**
* Provide the options form.
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['report_type'] = [
'#type' => 'select',
'#title' => t('Report Type'),
'#description' => t('What report data to show.'),
'#options' => [
'sum' => 'Sum of All Numeric Scores on all applicable review forms.',
'avg' => 'Average of Numeric Scores on all applicable review forms.',
'list' => 'List of Numeric Scores for each applicable review form.',
'count' => 'Count of submitted applicable review forms.',
'fields' => 'List of field keys found and used for scoring.',
],
'#default_value' => $this->options['report_type'],
];
$form['exclude_fields'] = [
'#type' => 'textfield',
'#title' => t('Keys of fields to exclude from the report'),
'#description' => t('If these keys are found in the webform we are using for scoring, do not include their values.'),
'#default_value' => $this->options['exclude_fields'],
];
$form['require_fields'] = [
'#type' => 'textfield',
'#title' => t('Use only these fields for the report'),
'#description' => t('Instead of excluding fields, you may instead require only the listed fields. Overrides the exclude field. Leave blank to use all non-excluded fields.'),
'#default_value' => $this->options['require_fields'],
];
$form['allowed_forms'] = [
'#type' => 'textfield',
'#title' => t('Score These Forms'),
'#description' => t('Instead of using the workflow stage entity reference, use the listed forms. Use webform form keys.'),
'#default_value' => $this->options['allowed_forms'],
];
$form['style_settings']['#attributes']['style'] = 'display:none;';
$form['element_type_enable']['#attributes']['style'] = 'display:none;';
$form['element_type']['#attributes']['style'] = 'display:none;';
$form['element_class_enable']['#attributes']['style'] = 'display:none;';
$form['element_class']['#attributes']['style'] = 'display:none;';
$form['element_label_type_enable']['#attributes']['style'] = 'display:none;';
$form['element_label_type']['#attributes']['style'] = 'display:none;';
$form['element_label_class_enable']['#attributes']['style'] = 'display:none;';
$form['element_label_class']['#attributes']['style'] = 'display:none;';
$form['element_wrapper_type_enable']['#attributes']['style'] = 'display:none;';
$form['element_wrapper_type']['#attributes']['style'] = 'display:none;';
$form['element_wrapper_class_enable']['#attributes']['style'] = 'display:none;';
$form['element_wrapper_class']['#attributes']['style'] = 'display:none;';
$form['element_default_classes']['#attributes']['style'] = 'display:none;';
$form['alter']['#attributes']['style'] = 'display:none;';
$form['empty_field_behavior']['#attributes']['style'] = 'display:none;';
$form['empty']['#attributes']['style'] = 'display:none;';
$form['empty_zero']['#attributes']['style'] = 'display:none;';
$form['hide_empty']['#attributes']['style'] = 'display:none;';
$form['hide_alter_empty']['#attributes']['style'] = 'display:none;';
}
/**
* {@inheritdoc}
*/
public function render(ResultRow $values) {
/* @var $application \Drupal\niobi_app\Entity\NiobiApplication */
$application = $values->_entity;
$status = $application->getCurrentApplicationStatus();
$review_forms = $application->getCurrentApplicationStage()->getReviewForms(TRUE);
if (in_array($status, ['decision', 'review'])) {
// Get the valid webforms for scoring.
$webforms = [];
if (!empty($this->options['allowed_forms'])) {
$form_ids = explode(',', $this->options['allowed_forms']);
foreach ($form_ids as $form_id) {
$webforms[trim($form_id)] = trim($form_id);
}
}
else {
foreach ($review_forms as $review_form) {
/* @var $webform \Drupal\webform\Entity\Webform */
/* @var $review_form \Drupal\niobi_form\Entity\NiobiForm */
$webform = $review_form->getWebform();
if ($webform) {
$webforms[$webform->id()] = $webform->id();
}
}
}
// Now, filter the submissions
$review_subs = $application->getReviewSubmissions();
$score_subs = [];
foreach ($review_subs as $sub) {
/* @var $sub \Drupal\webform\Entity\WebformSubmission */
$sub_form = !empty($sub) ? $sub->getWebform() : FALSE;
$id = !empty($sub_form) ? $sub_form->id() : 0;
if (isset($webforms[$id])) {
$score_subs[$sub->id()] = $sub;
}
}
// Generate the report
return ['#markup' => $this->generateScoreReport($this->options['report_type'], $score_subs)];
}
else {
return ['#markup' => t('The application must have an "In Review" or "Decision Pending" status to have a reviewer score')];
}
}
/**
* @param $option_key
* @return array
*/
public function getList($option_key) {
if (!empty($this->options[$option_key])) {
$list = [];
$fields = explode(',', $this->options[$option_key]);
foreach ($fields as $field) {
$list[trim($field)] = trim($field);
}
return $list;
}
else {
return [];
}
}
/**
* @return array
*/
public function getExclusionList() {
return $this->getList('exclude_fields');
}
/**
* @return array
*/
public function getRequireList() {
return $this->getList('require_fields');
}
public function getScoreForSubmission($sub, $exclude = [], $require = []) {
$exclude = $exclude ? $exclude : $this->getExclusionList();
$require = $require ? $require : $this->getRequireList();
$score = 0;
/* @var $sub \Drupal\webform\Entity\WebformSubmission */
$sub_data = $sub->getData();
foreach ($sub_data as $field => $data) {
$include = FALSE;
if (!empty($require)) {
if (in_array($field, $require)) {
$include = TRUE;
}
}
if (!empty($exclude)) {
if (!in_array($field, $exclude)) {
$include = TRUE;
}
}
if ($include) {
if (is_numeric($data)) {
$score += $data;
}
// Grid elements are arrays of numbers.
elseif (is_array($data)) {
foreach ($data as $d) {
if (is_numeric($d)) {
$score += $d;
}
}
}
}
}
return $score;
}
public function generateScoreReport($report_type, $subs) {
$ret = '';
$exclude = $this->getExclusionList();
switch($report_type) {
case 'sum':
$score = 0;
foreach ($subs as $sub) {
$score += $this->getScoreForSubmission($sub, $exclude);
}
$ret = $score;
break;
case 'avg':
if (!empty($subs)) {
$score = 0;
foreach ($subs as $sub) {
$score += $this->getScoreForSubmission($sub, $exclude);
}
$ret = round($score/count($subs), 2);
}
break;
case 'list':
foreach ($subs as $sub) {
/* @var $sub \Drupal\webform\Entity\WebformSubmission */
$webform = $sub->getWebform();
$author = $sub->getOwner();
if (!empty($webform) && !empty($author)) {
$ret .= $author->getAccountName() . ', ' . $webform->label() . ': ' . $this->getScoreForSubmission($sub, $exclude) . '<br>';
}
}
break;
case 'count':
$ret = count($subs);
break;
case 'fields':
$field_list = [];
foreach ($subs as $sub) {
/* @var $sub \Drupal\webform\Entity\WebformSubmission */
$sub_data = $sub->getData();
foreach ($sub_data as $field => $data) {
if (is_numeric($data) && !in_array($field, $exclude) && !in_array($field, $field_list)) {
$field_list[] = $field;
}
}
}
$ret = implode('<br>', $field_list);
break;
}
if (empty($subs) && empty($ret)) {
return t('No reviews found for this application');
}
return $ret;
}
}
