Skip to content

Commit 6e32f3a

Browse files
authored
Merge pull request #4 from drupal-modules/bug/cache-integration-config
Use caching of integration config for integration mode [GH-2][GH-3]
2 parents 7e99272 + fa02daf commit 6e32f3a

File tree

3 files changed

+119
-55
lines changed

3 files changed

+119
-55
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@
1919
"url": "https://github.com/queueit/KnownUser.V3.PHP"
2020
}
2121
]
22-
}
22+
}

queueit.admin.inc

Lines changed: 77 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,62 @@
99
* Form builder.
1010
*/
1111
function queueit_settings_form($form, &$form_state) {
12+
$known_user = new QueueitKnownUser();
13+
1214
/* Main configuration */
13-
$form['config'] = array(
14-
'#title' => 'Queue-it Configuration',
15+
$form['config'] = [
16+
'#title' => 'Queue-it configuration',
1517
'#type' => 'fieldset',
16-
);
18+
];
1719
// Implementation type.
1820
// * Integration - Validate a user via integration config.
1921
// * JavaScript - Validate a user via JavaScript on the client side.
2022
// * Code - Specify the configuration in code without using the Trigger/Action paradigm.
21-
$form['config']['queueit_mode'] = array(
23+
$form['config']['queueit_mode'] = [
2224
'#type' => 'radios',
23-
'#title' => t('Queue-it mode.'),
25+
'#title' => t('Queue-it mode'),
2426
'#options' => [
2527
'integration' => 'Integration config',
2628
'js' => 'JavaScript',
2729
'code' => 'Configuration in code',
2830
],
2931
'#description' => t('Select the method used to integrate Queue-it:<br>Integration Config - used to load the configuration from the Go Queue-it platform.<br>JavaScript - protects pages by the queue on the client side.<br>Configuration in code - recommended for testing specific event or when your application server is not allowed to do external GET requests (this is without using the Trigger/Action paradigm).'),
3032
'#default_value' => variable_get('queueit_mode', 'integration'),
31-
);
32-
$form['config']['queueit_debug'] = array(
33+
];
34+
$form['config']['queueit_debug'] = [
3335
'#type' => 'checkbox',
3436
'#title' => t('Enable debugging'),
3537
'#description' => t('Displays Queue-it response on each qualifying page for admin users only.'),
3638
'#default_value' => variable_get('queueit_debug', FALSE),
37-
);
39+
];
40+
/* Integration mode */
41+
$form['integration_config'] = [
42+
'#title' => t('Integration settings'),
43+
'#description' => t("Settings related to <i>Integration config</i> mode as defined in Queue-it configuration store and controlled via the Queue-it Go platform. The configuration file consists of Triggers and Actions to determine which pages to protect and which queues to use."),
44+
'#type' => 'fieldset',
45+
'#collapsible' => TRUE,
46+
'#collapsed' => variable_get('queueit_mode', 'integration') <> 'integration',
47+
'#disabled' => variable_get('queueit_mode', 'integration') <> 'integration',
48+
'#states' => [
49+
'disabled' => [':input[name="queueit_mode"]' => ['!value' => 'integration']],
50+
'collapsed' => [':input[name="queueit_mode"]' => ['!value' => 'integration']],
51+
]
52+
];
53+
$form['integration_config']['config'] = [
54+
'#type' => 'item',
55+
'#prefix' => t('Current configuration:'),
56+
'#markup' => '<pre>' . $known_user->getIntegrationConfig() . '</pre>',
57+
];
58+
$form['integration_config']['refresh'] = [
59+
'#type' => 'submit',
60+
'#value' => t('Refresh'),
61+
'#executes_submit_callback' => FALSE,
62+
'#suffix' => sprintf(t('Last update: %s<br>'), strftime("%c", $known_user->getIntegrationConfigTimestamp()))
63+
. sprintf(t('Endpoint: <a href="%s">%s</a><br>'), $known_user->getIntegrationConfigUrl(), $known_user->getIntegrationConfigUrl())
64+
. t("<br>Use <i>Refresh</i> button to fetch the latest integration config from Queue-it Go platform. The config is cached with a TTL of 5 mins, after which the new config is loaded on any page load. Clicking the <i>Refresh</i> button more than once every 5 seconds will not trigger another fetch."),
65+
];
3866
/* Configuration using code */
39-
$form['event_config'] = array(
67+
$form['event_config'] = [
4068
'#title' => 'Event config',
4169
'#description' => t('When configuration in code is selected, you can specify the following parameters without using the Trigger/Action paradigm. Useful when your application server is not allowed to do external GET requests.'),
4270
'#type' => 'fieldset',
@@ -47,100 +75,100 @@ function queueit_settings_form($form, &$form_state) {
4775
'disabled' => [':input[name="queueit_mode"]' => ['!value' => 'code']],
4876
'collapsed' => [':input[name="queueit_mode"]' => ['!value' => 'code']],
4977
]
50-
);
51-
$form['event_config']['queueit_event_id'] = array(
78+
];
79+
$form['event_config']['queueit_event_id'] = [
5280
'#type' => 'textfield',
5381
'#title' => t('Event ID'),
5482
'#description' => t('Specify ID of the queue to use.'),
5583
'#default_value' => variable_get('queueit_event_id'),
56-
);
57-
$form['event_config']['queueit_queue_domain'] = array(
84+
];
85+
$form['event_config']['queueit_queue_domain'] = [
5886
'#type' => 'textfield',
5987
'#title' => t('Existing domain name of the queue - usually in the format [CustomerId].queue-it.net.'),
6088
'#description' => t('Specify ID of the queue to use.'),
6189
'#default_value' => variable_get('queueit_queue_domain'),
62-
);
63-
$form['event_config']['queueit_cookie_validity'] = array(
90+
];
91+
$form['event_config']['queueit_cookie_validity'] = [
6492
'#type' => 'textfield',
6593
'#title' => t('Validity of the Queue-it session cookie.'),
6694
'#description' => t('Optional. Validity of the Queue-it session cookie. Default is 10 minutes.'),
6795
'#default_value' => variable_get('queueit_cookie_validity'),
6896
'#element_validate' => ['element_validate_integer_positive'],
69-
);
70-
$form['event_config']['queueit_extend_cookie_validity'] = array(
97+
];
98+
$form['event_config']['queueit_extend_cookie_validity'] = [
7199
'#type' => 'checkbox',
72100
'#title' => t('Extended validity of session cookie.'),
73101
'#description' => t('Should the Queue-it session cookie validity time be extended each time the validation runs? By default it is enabled.'),
74102
'#default_value' => variable_get('queueit_extend_cookie_validity', TRUE),
75-
);
76-
$form['event_config']['queueit_layout_name'] = array(
103+
];
104+
$form['event_config']['queueit_layout_name'] = [
77105
'#type' => 'textfield',
78106
'#title' => t('Name of the queue ticket layout.'),
79107
'#description' => t('Optional. E.g. "Default layout by Queue-it. Default is to take what is specified on the Event.'),
80108
'#default_value' => variable_get('queueit_layout_name'),
81-
);
82-
$form['event_config']['queueit_culture_of_layout'] = array(
109+
];
110+
$form['event_config']['queueit_culture_of_layout'] = [
83111
'#type' => 'textfield',
84112
'#title' => t('Culture of the queue ticket layout.'),
85113
'#description' => t('Culture of the queue ticket layout in the format specified <a href="!url">here</a>.',
86114
['!url' => 'https://msdn.microsoft.com/en-us/library/ee825488(v=cs.20).aspx']
87115
),
88116
'#default_value' => variable_get('queueit_culture_of_layout'),
89-
);
117+
];
90118
/* Validation parameters */
91-
$form['validate'] = array(
119+
$form['validate'] = [
92120
'#title' => 'Validation logic',
93121
'#type' => 'fieldset',
94-
);
122+
];
95123
// Exclude Queue-it on specific pages.
96-
$form['validate']['queueit_exclude_pages'] = array(
124+
$form['validate']['queueit_exclude_pages'] = [
97125
'#type' => 'textarea',
98126
'#title' => t('Exclude Queue-it on specific pages.'),
99127
'#default_value' => variable_get('queueit_exclude_pages', QUEUEIT_EXCLUDE),
100128
'#description' => t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. It is recommended to exclude resources and AJAX calls."),
101-
);
102-
$form['validate']['queueit_ignore_post'] = array(
129+
];
130+
$form['validate']['queueit_ignore_post'] = [
103131
'#type' => 'checkbox',
104132
'#title' => t('Ignore queue validation for the POST requests.'),
105133
'#description' => t('Ignores the KnownUser validation for pages sent via HTTP POST request.'),
106134
'#default_value' => variable_get('queueit_ignore_post', TRUE),
107-
);
108-
$form['validate']['queueit_ignore_cli'] = array(
135+
];
136+
$form['validate']['queueit_ignore_cli'] = [
109137
'#type' => 'checkbox',
110138
'#title' => t('Ignore queue validation for the command-line interface.'),
111139
'#description' => t('Ignores the KnownUser validation when invoked via CLI (such as using drush).'),
112140
'#default_value' => variable_get('queueit_ignore_cli', TRUE),
113-
);
141+
];
114142
/* Credentials */
115-
$form['creds'] = array(
143+
$form['creds'] = [
116144
'#title' => 'Queue-it Credentials',
117145
'#type' => 'fieldset',
118-
);
119-
$form['creds']['queueit_customer_id'] = array(
146+
];
147+
$form['creds']['queueit_customer_id'] = [
120148
'#type' => 'textfield',
121149
'#title' => t('Customer ID'),
122150
'#description' => t('Your Queue-it customer ID.'),
123151
'#default_value' => variable_get('queueit_customer_id'),
124152
'#required' => TRUE,
125-
);
126-
$form['creds']['queueit_api_key'] = array(
153+
];
154+
$form['creds']['queueit_api_key'] = [
127155
'#type' => 'textfield',
128156
'#title' => t('API Key'),
129157
'#description' => t('Specify the Api-key which can be supplied through the query string parameter. The key can be found in the GO Queue-it Platform.'),
130158
'#default_value' => variable_get('queueit_api_key'),
131159
'#states' => [
132160
'required' => [':input[name="queueit_mode"]' => ['!value' => 'js']],
133161
]
134-
);
135-
$form['creds']['queueit_secret_key'] = array(
162+
];
163+
$form['creds']['queueit_secret_key'] = [
136164
'#type' => 'textfield',
137165
'#title' => t('Secret key'),
138166
'#description' => t('Your 72 char secret key as specified in Go Queue-it self-service platform.'),
139167
'#default_value' => variable_get('queueit_secret_key'),
140168
'#states' => [
141169
'required' => [':input[name="queueit_mode"]' => ['!value' => 'js']],
142170
]
143-
);
171+
];
144172

145173
return system_settings_form($form);
146174
}
@@ -204,13 +232,13 @@ function queueit_settings_form_validate($form, &$form_state) {
204232
if (!$config) {
205233
drupal_set_message(
206234
t('Cannot fetch the integration configuration from !url.',
207-
['!url' => $known_user->getIntegrationConfigPath()]),
235+
['!url' => $known_user->getIntegrationConfigUrl()]),
208236
'warning');
209237
}
210238
elseif (!json_decode($config)) {
211239
drupal_set_message(
212240
t('Cannot decode the integration configuration from !url.',
213-
['!url' => $known_user->getIntegrationConfigPath()]),
241+
['!url' => $known_user->getIntegrationConfigUrl()]),
214242
'warning');
215243
}
216244
$result = $known_user->validateRequestByIntegrationConfig();
@@ -226,15 +254,21 @@ function queueit_settings_form_validate($form, &$form_state) {
226254

227255
}
228256
catch (\Exception $e) {
229-
drupal_set_message(t('Exception error: ') . $e->getMessage(), 'error');
257+
drupal_set_message(t('Exception error:') . ' ' . $e->getMessage(), 'error');
230258
watchdog_exception('queueit', $e);
231259
form_set_error('queueit_mode', $e->getMessage());
232260
}
233261

234262
if (!empty($result) && $result) {
235-
drupal_set_message(t('Configuration successfully validated.'), 'status');
263+
$op = $form_state['triggering_element']['#value'];
264+
if ($op == 'Refresh' && $known_user->getIntegrationConfig(5)) {
265+
drupal_set_message(t('Configuration successfully refreshed.'), 'status');
266+
}
267+
else {
268+
drupal_set_message(t('Configuration successfully validated.'), 'status');
269+
}
236270
}
237271
else {
238272
drupal_set_message(t('Configuration not valid. Please verify your configuration.'), 'warning');
239273
}
240-
}
274+
}

src/classes/QueueitKnownUser.php

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public function getSecretKey() {
175175
/**
176176
* Get the integration config URL.
177177
*/
178-
public function getIntegrationConfigPath() {
178+
public function getIntegrationConfigUrl() {
179179
return sprintf("http://%s.%s%s/%s",
180180
$this->getCustomerId(),
181181
self::QI_API_DOMAIN,
@@ -185,22 +185,52 @@ public function getIntegrationConfigPath() {
185185
}
186186

187187
/**
188-
* Retrieve the integration config.
188+
* Get the integration config.
189189
*
190-
* @return string
191-
* Returns plain JSON content.
190+
* By default load the config from the variable.
191+
* Otherwise, pull it from the Queue-it Go platform (every 5 minutes).
192+
*
193+
* @param int $ttl
194+
* Maximum time to cache config in seconds.
195+
* Default is 5 minutes (300 seconds).
196+
* @param bool $json
197+
* Sets config format. By default in JSON format.
198+
* Otherwise as an array.
199+
*
200+
* @return string|array
201+
* Returns config, in JSON format by default.
202+
* If $json is set to FALSE, return in an array format.
192203
*/
193-
public function getIntegrationConfig() {
204+
public function getIntegrationConfig($ttl = 300, $json = TRUE) {
194205
// Ignore fetching on invalid configuration.
195206
if (!$this->validateConfig()) {
196-
return NULL;
207+
return FALSE;
197208
}
198-
199-
// Get the auto-generated config file published on Queue-it Go platform.
200-
// URL: https://[your-customer-id].queue-it.net/status/integrationconfig/[your-customer-id]
201-
// @todo: Consider caching the config to minimalize external requests.
202-
return file_get_contents($this->getIntegrationConfigPath());
209+
$last_pull = variable_get('queueit_last_pull', 0);
210+
$config_arr = variable_get('queueit_config', []);
211+
$config_json = json_encode($config_arr);
212+
if (REQUEST_TIME - $last_pull > $ttl) {
213+
// Get the auto-generated config file published on Queue-it Go platform.
214+
// URL: https://[your-customer-id].queue-it.net/status/integrationconfig/[your-customer-id]
215+
$config_json = file_get_contents($this->getIntegrationConfigUrl());
216+
// Convert plain JSON to array.
217+
$config_arr = json_decode($config_json, TRUE);
218+
if (!empty($config_arr)) {
219+
variable_set('queueit_config', $config_arr);
220+
variable_set('queueit_last_pull', REQUEST_TIME);
221+
}
222+
}
223+
return $json ? $config_json : $config_arr;
203224
}
204225

226+
/**
227+
* Get the datetime of the last integration config update.
228+
*
229+
* @return int
230+
* Returns timestamp of the last integration config pull.
231+
*/
232+
public function getIntegrationConfigTimestamp() {
233+
return variable_get('queueit_last_pull', 0);
234+
}
205235

206236
}

0 commit comments

Comments
 (0)