-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathExternalModule.php
143 lines (124 loc) · 4.88 KB
/
ExternalModule.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
namespace PreventPastOrFutureDates\ExternalModule;
use ExternalModules\AbstractExternalModule;
abstract class Page
{
const DATA_ENTRY = 'DataEntry/index.php';
const ONLINE_DESIGNER = 'Design/online_designer.php';
const SURVEY = 'surveys/index.php';
const SURVEY_THEME = 'Surveys/theme_view.php';
}
abstract class ResourceType
{
const CSS = 'css';
const HTML = 'html';
const JS = 'js';
}
abstract class Validate
{
static $date_validations = [
'date_dmy',
'date_mdy',
'date_ymd',
'datetime_dmy',
'datetime_mdy',
'datetime_ymd',
'datetime_seconds_dmy',
'datetime_seconds_mdy',
'datetime_seconds_ymd',
];
// TODO: Pass in global variables and provide init function
static function hasProjectID(): bool
{
return isset($project_id);
}
// TODO: Pass in global variables and provide init function
static function hasRecordID(): bool
{
return isset($_GET['id']);
}
static function pageIs(string $page): bool
{
return PAGE == $page;
}
static function pageIsIn(array $pages): bool
{
return in_array(PAGE, $pages);
}
}
class ExternalModule extends AbstractExternalModule
{
public $futureDateTag = "@PREVENT-FUTUREDATE";
public $pastDateTag = "@PREVENT-PASTDATE";
function containsFutureDateTag(?string $tags): bool
{
return (isset($tags)) ? in_array($this->futureDateTag, explode(' ', $tags)) : false;
}
function containsPastDateTag(?string $tags): bool
{
return (isset($tags)) ? in_array($this->pastDateTag, explode(' ', $tags)) : false;
}
// Given $Proj->metadata[$field_name] return whether the field
// is a text field and has date validation applied
function isDateTypeField(array $field): bool
{
$isTextField = $field['element_type'] == 'text';
$hasDateValidation = in_array($field['element_validation_type'], Validate::$date_validations);
return $isTextField && $hasDateValidation;
}
function includeSource(string $resourceType, string $path)
{
switch ($resourceType) {
case ResourceType::CSS:
echo '<link href="' . $this->getUrl($path) . '" rel="stylesheet">';
break;
case ResourceType::HTML:
include($path);
break;
case ResourceType::JS:
echo '<script src="' . $this->getUrl($path) . '"></script>';
break;
default:
break;
}
}
/*
* Note: min and max validations set on the field do not prevent entering past or future dates.
* $element_validation_min = $field['element_validation_min'];
* $element_validation_max = $field['element_validation_max'];
**/
function redcap_every_page_top($project_id)
{
if (Validate::pageIs(Page::ONLINE_DESIGNER) && $project_id) {
$this->initializeJavascriptModuleObject();
$this->tt_addToJavascriptModuleObject('futureDateTag', $this->futureDateTag);
$this->tt_addToJavascriptModuleObject('pastDateTag', $this->pastDateTag);
$this->includeSource(ResourceType::JS, 'js/addActionTags.js');
} else if (Validate::pageIsIn(array(Page::DATA_ENTRY, Page::SURVEY, Page::SURVEY_THEME)) && isset($_GET['id'])) {
global $Proj;
$instrument = $_GET['page'];
$preventFutureDateFields = [];
$preventPastDateFields = [];
// Iterate through all fields and search for date fields with @PREVENT-FUTUREDATE or @PREVENT-PASTDATE
// and add them to an array to pass to JS to apply date restrictions. If both tags are added then no
// restrictions will be applied.
$Proj->forms[$instrument]['fields'] ??= [];
foreach (array_keys($Proj->forms[$instrument]['fields']) as $field_name) {
$field = $Proj->metadata[$field_name];
if ($this->isDateTypeField($field)) {
$action_tags = $field['misc'];
if ($this->containsFutureDateTag($action_tags) && !$this->containsPastDateTag($action_tags)) {
array_push($preventFutureDateFields, $field_name);
}
if ($this->containsPastDateTag($action_tags) && !$this->containsFutureDateTag($action_tags)) {
array_push($preventPastDateFields, $field_name);
}
}
}
$this->initializeJavascriptModuleObject();
$this->tt_addToJavascriptModuleObject('preventFutureDateFields', json_encode($preventFutureDateFields));
$this->tt_addToJavascriptModuleObject('preventPastDateFields', json_encode($preventPastDateFields));
$this->includeSource(ResourceType::JS, 'js/preventPastOrFutureDates.js');
}
}
}