Skip to content

Commit 469f201

Browse files
committed
Merge branch 'release/2.0.0'
2 parents 12a72e8 + 12111a3 commit 469f201

File tree

7 files changed

+135
-56
lines changed

7 files changed

+135
-56
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
All notable changes to the REDCap CSS Injector module will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
## [2.0.0] - 2024-05-24
6+
### Changed
7+
- Apply CSS to survey, data entry, and all via checkboxes (@ChemiKyle, @saipavan10-git, @pbchase, #11, #17)
8+
- Bump framework version to 15 replace recursive logic in _getFormattedSettings with getSubSettings (@ChemiKyle, #16, #17)
9+
510
## [1.1.2] - 2023-12-11
611
### Changed
712
- Use null coalesce in _getFormattedSettings (@ChemiKyle)

ExternalModule.php

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,24 @@ class ExternalModule extends AbstractExternalModule {
1717
/**
1818
* @inheritdoc
1919
*/
20-
function redcap_data_entry_form_top($project_id, $record = null, $instrument, $event_id, $group_id = null, $repeat_instance = 1) {
21-
$this->applyStyles('data_entry', $instrument);
20+
public function redcap_every_page_top($project_id) {
21+
// Determine page type
22+
$type = '';
23+
$instrument = '';
24+
if (strtolower(PAGE)==="dataentry/index.php"
25+
&& isset($_GET['id']) && $_GET['id']!==''
26+
&& isset($_GET['page']) && $_GET['page']!=='') {
27+
$type = 'data_entry';
28+
$instrument = $_GET['page'];
29+
} else if (strtolower(PAGE)==="surveys/index.php"
30+
&& isset($_GET['id']) && $_GET['id']!==''
31+
&& isset($_GET['page']) && $_GET['page']!=='') {
32+
$type = 'survey';
33+
$instrument = $_GET['page'];
34+
} else {
35+
$type = "other";
36+
}
37+
$this->applyStyles($type, $instrument);
2238
}
2339

2440
/**
@@ -44,7 +60,18 @@ function applyStyles($type, $form) {
4460
}
4561

4662
foreach ($settings['styles'] as $row) {
47-
if (!empty($row['style_enabled']) && in_array($row['style_type'], ['all', $type]) && (!array_filter($row['style_forms']) || in_array($form, $row['style_forms']))) {
63+
if (!(bool)$row['style_enabled']) { continue; }
64+
65+
if ($type == 'other' && (bool)$row['other']) {
66+
echo '<style>' . strip_tags($row['style_code']) . '</style>';
67+
}
68+
else if (
69+
(!(bool)array_filter($row['style_forms']) || in_array($form, $row['style_forms'])) &&
70+
(
71+
($type == 'data_entry' && (bool)$row['data_entry']) ||
72+
($type == 'survey' && (bool)$row['survey'])
73+
)
74+
) {
4875
echo '<style>' . strip_tags($row['style_code']) . '</style>';
4976
}
5077
}
@@ -61,15 +88,15 @@ function applyStyles($type, $form) {
6188
* The formatted settings.
6289
*/
6390
function getFormattedSettings($project_id = null) {
64-
$settings = $this->getConfig();
91+
$settings = $this->framework->getConfig();
6592

6693
if ($project_id) {
6794
$settings = $settings['project-settings'];
68-
$values = $this->getProjectSettings($project_id);
95+
$values = $this->framework->getProjectSettings($project_id);
6996
}
7097
else {
7198
$settings = $settings['system-settings'];
72-
$values = $this->getSystemSettings();
99+
$values = $this->framework->getSystemSettings();
73100
}
74101

75102
return $this->_getFormattedSettings($settings, $values);
@@ -90,18 +117,7 @@ protected function _getFormattedSettings($settings, $values, $inherited_deltas =
90117
}
91118

92119
if ($setting['type'] == 'sub_settings') {
93-
$value = $value ?? [];
94-
$deltas = array_keys($value);
95-
$value = [];
96-
97-
foreach ($deltas as $delta) {
98-
$sub_deltas = array_merge($inherited_deltas, [$delta]);
99-
$value[$delta] = $this->_getFormattedSettings($setting['sub_settings'], $values, $sub_deltas);
100-
}
101-
102-
if (empty($setting['repeatable'])) {
103-
$value = $value[0];
104-
}
120+
$value = $this->framework->getSubSettings($key);
105121
}
106122

107123
$formatted[$key] = $value;

README.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,102 @@ Allows administrators to inject CSS into surveys and data entry forms.
33

44
[![DOI](https://zenodo.org/badge/141312467.svg)](https://zenodo.org/badge/latestdoi/141312467)
55

6+
> **Important:** Version 2.0.0 of this module is a breaking change. If you are upgrading from a version prior to 2.0.0, please review this [section](#migration-from-version-1xx-to-200) of the README for changes to the configuration. If you are new to this module, you can ignore this section.
7+
68
## Prerequisites
79
- REDCap >= 8.0.3
810

911
## Easy Installation
1012
- Obtain this module from the Consortium [REDCap Repo](https://redcap.vanderbilt.edu/consortium/modules/index.php) from the Control Center.
1113

14+
1215
## Manual Installation
1316
- Clone this repo into `<redcap-root>/modules/redcap_css_injector_v<version_number>` .
1417
- Go to **Control Center > Manage External Modules** and enable REDCap CSS Injector.
1518

1619
## Configuration
1720
Access **Manage External Modules** section of your project, and then click on CSS Injector configuration button.
1821

19-
In the configuration form, you can either create a global style for your project or define multiple styles for different contexts. Each context is defined by choosing a list of forms/instruments and/or limiting the scope to surveys or data entries.
22+
In the configuration form, you can either create a global style for your project or define multiple styles for different contexts. Each context is defined by choosing a list of forms/instruments and/or limiting the scope to surveys or data entries or other pages in the project. You can also define a style for all pages in the project by selecting all three checkboxes.
2023

2124
The configuration form also provides an enable/disable switch for each one of your styles. Make sure to enable your styles.
2225

2326
If more than one style is applied to the same page, the CSS rules are applied in the order of appearance in the configuration form.
2427

25-
![Configuration screen](img/config.png)
28+
![Configuration screen](img/config_v2.png)
29+
30+
31+
## Migration from version 1.X.X to 2.0.0
32+
33+
If you are upgrading from a version prior to 2.0.0, you will need to reconfigure your styles. To make this easier, we have a MySQL query that will help you migrate your current styles to the new configuration format. Your administrator will need to run this query on the REDCap database.
34+
35+
36+
```sql
37+
START TRANSACTION;
38+
39+
CREATE UNIQUE INDEX redcap_external_module_settings_UK1
40+
on redcap_external_module_settings (external_module_id, project_id, `key`);
41+
42+
INSERT INTO redcap_external_module_settings (external_module_id, project_id, `key`, type, value)
43+
SELECT
44+
s.external_module_id,
45+
s.project_id,
46+
k.`key`,
47+
'json-array',
48+
(
49+
SELECT
50+
JSON_ARRAYAGG(
51+
CASE
52+
WHEN JSON_UNQUOTE(JSON_EXTRACT(s2.value, CONCAT('$[', jt.idx - 1, ']'))) = 'all' THEN CAST(TRUE AS JSON)
53+
WHEN JSON_UNQUOTE(JSON_EXTRACT(s2.value, CONCAT('$[', jt.idx - 1, ']'))) = k.`key` THEN CAST(TRUE AS JSON)
54+
ELSE CAST(FALSE AS JSON)
55+
END
56+
)
57+
FROM
58+
redcap_external_module_settings s2
59+
CROSS JOIN JSON_TABLE(
60+
s2.value,
61+
'$[*]' COLUMNS(
62+
idx FOR ORDINALITY
63+
)
64+
) AS jt
65+
WHERE
66+
s2.external_module_id = s.external_module_id
67+
AND s2.project_id = s.project_id
68+
AND s2.`key` = 'style_type'
69+
) AS new_value
70+
FROM
71+
redcap_external_module_settings s
72+
CROSS JOIN (
73+
SELECT 'survey' AS `key`
74+
UNION ALL
75+
SELECT 'data_entry' AS `key`
76+
UNION ALL
77+
SELECT 'other' AS `key`
78+
) k
79+
WHERE
80+
s.`key` = 'style_type'
81+
AND s.external_module_id IN (
82+
SELECT external_module_id
83+
FROM redcap_external_modules
84+
WHERE directory_prefix = 'redcap_css_injector'
85+
)
86+
GROUP BY
87+
s.external_module_id,
88+
s.project_id,
89+
k.`key`;
90+
91+
DROP INDEX redcap_external_module_settings_UK1 on redcap_external_module_settings;
92+
93+
COMMIT;
94+
```
95+
96+
> **Note:**
97+
This query requires MySQL 8.0 or later.
98+
99+
If you run this query shortly before upgrading CSS Injector, the migrated settings will be in place for the module upgrade. The module will start working correctly immediately. You can run the script after the module upgrade, but the module will have no effect until you either run the settings migration script or set the _Apply to survey pages / data entry pages / other project pages_ checkboxes manually.
100+
101+
The query should be run in against the MySQL database of your REDCap instance. After running the query, you should see a message saying that some rows were inserted. The module will start working immediately. In the project home page go to the **External Module > Manage** and click on the REDCap CSS Injector configure button. You should see your styles migrated to the new configuration format.
26102

27103
## Sample CSS
28104

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.2
1+
2.0.0

config.json

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,11 @@
22
"name": "REDCap CSS Injector",
33
"namespace": "CSSInjector\\ExternalModule",
44
"description": "Allow administrators to inject CSS into surveys and data entry forms. <strong><a href=\"https://github.com/ctsit/redcap_css_injector\">See full documentation here</a></strong>.",
5-
"permissions": [
6-
"redcap_data_entry_form_top",
7-
"redcap_survey_page_top"
8-
],
5+
"framework-version": 15,
96
"authors": [
107
{
11-
"name": "Philip Chase",
12-
"email": "pbc@ufl.edu",
13-
"institution": "University of Florida - CTSI"
14-
},
15-
{
16-
"name": "Taryn Stoffs",
17-
"email": "tls@ufl.edu",
18-
"institution": "University of Florida - CTSI"
19-
},
20-
{
21-
"name": "Kyle Chesney",
22-
"email": "kyle.chesney@ufl.edu",
8+
"name": "University of Florida CTS-IT",
9+
"email": "CTSIT-REDCAP-MODULE-SUPPO@LISTS.UFL.EDU",
2310
"institution": "University of Florida - CTSI"
2411
}
2512
],
@@ -36,24 +23,19 @@
3623
"type": "checkbox"
3724
},
3825
{
39-
"name": "Apply to",
40-
"key": "style_type",
41-
"type": "radio",
42-
"required": true,
43-
"choices": [
44-
{
45-
"value": "all",
46-
"name": "All"
47-
},
48-
{
49-
"value": "survey",
50-
"name": "Surveys"
51-
},
52-
{
53-
"value": "data_entry",
54-
"name": "Data entries"
55-
}
56-
]
26+
"name": "Apply to survey pages",
27+
"key": "survey",
28+
"type": "checkbox"
29+
},
30+
{
31+
"name": "Apply to data entry pages",
32+
"key": "data_entry",
33+
"type": "checkbox"
34+
},
35+
{
36+
"name": "Apply to all other project pages",
37+
"key": "other",
38+
"type": "checkbox"
5739
},
5840
{
5941
"name": "Apply to the following forms (leave blank to apply to all forms)",
@@ -72,6 +54,6 @@
7254
}
7355
],
7456
"compatibility": {
75-
"redcap-version-min": "8.0.3"
57+
"redcap-version-min": "14.0.2"
7658
}
7759
}

img/config.png

-97 KB
Binary file not shown.

img/config_v2.png

225 KB
Loading

0 commit comments

Comments
 (0)