/[drupal]/contributions/modules/dbcron/dbcron.module
ViewVC logotype

Contents of /contributions/modules/dbcron/dbcron.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.5 - (show annotations) (download) (as text)
Mon Apr 17 06:38:46 2006 UTC (3 years, 7 months ago) by jaza
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +20 -22 lines
File MIME type: text/x-php
Removed call to node_validate_title(), and got rid of trailing spaces.
1 <?php
2 // $Id: dbcron.module,v 1.4 2006/04/13 15:49:31 unconed Exp $
3
4 /**
5 * @file
6 * Runs a set of user-defined SQL queries at regular intervals using cron.
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12 function dbcron_help($section) {
13 switch ($section) {
14 case 'admin/modules#description':
15 return t('Runs a set of user-defined SQL queries at regular intervals using cron.');
16 case 'admin/dbcron':
17 return t('<p>The DB cron module allows you to create and manage a set of SQL queries. Each query is run at a regular interval using the cron system, and you can specify a different interval for each query. To create a new query, click the <em>add</em> link on this page. If you have existing queries, you will see them listed on this page, and you can modify them if you wish.</p>');
18 case 'admin/help#dbcron':
19 return t('<p>The DB cron module allows you to create and manage a set of SQL queries. Each query is run at a regular interval using the cron system, and you can specify a different interval for each query. As this module allows you to directly run SQL queries on your site\'s database, it should only be accessible to advanced users who have a sound knowledge of the Drupal database schema, and who are competent in ANSI SQL. Do not give inexperienced or non-trustworthy users the \'administer cron queries\' permission under any circumstances!</p>');
20 }
21 }
22
23 /**
24 * Implementation of hook_perm().
25 */
26 function dbcron_perm() {
27 return array('administer cron queries');
28 }
29
30 /**
31 * Implementation of hook_menu().
32 */
33 function dbcron_menu($may_cache) {
34 $items = array();
35
36 if ($may_cache) {
37 $items[] = array(
38 'path' => 'admin/dbcron',
39 'title' => t('cron queries'),
40 'callback' => 'dbcron_admin',
41 'access' => user_access('administer cron queries'),
42 );
43 $items[] = array(
44 'path' => 'admin/dbcron/edit',
45 'title' => t('edit'),
46 'callback' => 'dbcron_edit',
47 'access' => user_access('administer cron queries'),
48 'type' => MENU_CALLBACK,
49 );
50 $items[] = array(
51 'path' => 'admin/dbcron/delete',
52 'title' => t('delete'),
53 'callback' => 'dbcron_delete_confirm',
54 'access' => user_access('administer cron queries'),
55 'type' => MENU_CALLBACK,
56 );
57 $items[] = array(
58 'path' => 'admin/dbcron/list',
59 'title' => t('list'),
60 'type' => MENU_DEFAULT_LOCAL_TASK,
61 'weight' => -10,
62 );
63 $items[] = array(
64 'path' => 'admin/dbcron/add',
65 'title' => t('add'),
66 'callback' => 'dbcron_edit',
67 'access' => user_access('administer cron queries'),
68 'type' => MENU_LOCAL_TASK,
69 );
70 }
71
72 return $items;
73 }
74
75 /**
76 * Implementation of hook_cron().
77 *
78 * Runs all cron queries that are due to run when this hook is fired. If any
79 * queries have multiple parts, the multiple parts are broken up and run
80 * separately. Each query has its execution speed timed, and this speed (along
81 * with the current time) is saved to the database after execution.
82 */
83 function dbcron_cron() {
84 static $reset;
85
86 $leeway = (int)variable_get('dbcron_interval_leeway', 10);
87 $result = db_query('SELECT * FROM {dbcron} WHERE (%d - last_run >= (run_interval - %d)) AND run_interval > 0', time(), $leeway);
88
89 if (!isset($reset)) {
90 $reset = FALSE;
91 }
92
93 while ($dq = db_fetch_object($result)) {
94 $queries = preg_split('/;(\n|\r)/', $dq->body);
95
96 timer_start('dbcron');
97 foreach ($queries as $query) {
98 $query = preg_replace('/\n|\r/', '', $query);
99 if (!empty($query)) {
100 db_query($query);
101
102 if (!$reset && variable_get('dbcron_search_reset', 0)) {
103 search_wipe();
104 $reset = TRUE;
105 }
106 }
107 }
108 $timer = timer_stop('dbcron');
109 $speed = (int)$timer['time'];
110
111 db_query('UPDATE {dbcron} SET last_run = %d, exec_speed = %d WHERE dqid = %d', time(), $speed, $dq->dqid);
112 }
113 }
114
115 /**
116 * Implementation of hook_settings().
117 */
118 function dbcron_settings() {
119 $form = array();
120 $options = array(0 => t('None'), 5 => format_interval(5), 10 => format_interval(10), 15 => format_interval(15), 20 => format_interval(20), 30 => format_interval(30), 60 => format_interval(60));
121
122 $form['dbcron_interval_leeway'] = array(
123 '#type' => 'select',
124 '#title' => t('Leeway in cron run intervals'),
125 '#default_value' => variable_get('dbcron_interval_leeway', 10),
126 '#options' => $options,
127 '#description' => t('The amount of leeway (in seconds) to be given to each cron query when determining (from its running interval) if it\'s time for the query to run.')
128 );
129
130 $options = array(
131 1 => t('Enabled'),
132 0 => t('Disabled'),
133 );
134 $form['dbcron_search_reset'] = array(
135 '#type' => 'radios',
136 '#title' => t('Reset search index on cron run'),
137 '#default_value' => variable_get('dbcron_search_reset', 0),
138 '#options' => $options,
139 '#description' => t('If enabled, the site\'s search index will be reset every time a cron query is executed. Useful for cron queries that clear the site\'s content.')
140 );
141
142 return $form;
143 }
144
145 /**
146 * Menu callback; return a listing of all defined cron queries.
147 */
148 function dbcron_admin() {
149 $sql = 'SELECT dqid, title, run_interval, last_run, exec_speed FROM {dbcron}';
150 $header = array(
151 array('data' => t('Title'), 'field' => 'title', 'sort' => 'asc'),
152 array('data' => t('Interval'), 'field' => 'run_interval'),
153 array('data' => t('Last run'), 'field' => 'last_run'),
154 array('data' => t('Last exec speed'), 'field' => 'exec_speed'),
155 array('data' => t('Operations'), 'colspan' => '2')
156 );
157 $sql .= tablesort_sql($header);
158 $result = pager_query($sql, 50);
159
160 $destination = drupal_get_destination();
161 while ($data = db_fetch_object($result)) {
162 $rows[] = array($data->title, ($data->run_interval ? format_interval($data->run_interval) : t('Never')), ($data->last_run ? format_date($data->last_run) : t('N/A')), ($data->exec_speed ? $data->exec_speed . 'ms' : t('N/A')), l(t('edit'), "admin/dbcron/edit/$data->dqid", array(), $destination), l(t('delete'), "admin/dbcron/delete/$data->dqid", array(), $destination));
163 }
164
165 if (!$rows) {
166 $rows[] = array(array('data' => t('No cron queries available.'), 'colspan' => '6'));
167 }
168
169 $output = theme('table', $header, $rows);
170 $output .= theme('pager', NULL, 50, 0);
171 return $output;
172 }
173
174 /**
175 * Menu callback; handles pages for creating and editing cron queries.
176 */
177 function dbcron_edit($dqid = 0) {
178 if ($dqid) {
179 $dq = dbcron_load($dqid);
180 drupal_set_title($dq->title);
181 $output = dbcron_form(dbcron_load($dqid));
182 }
183 else {
184 $output = dbcron_form();
185 }
186
187 return $output;
188 }
189
190 /**
191 * Menu callback; confirms deleting a cron query
192 **/
193 function dbcron_delete_confirm($dqid) {
194 $output = '';
195 $dq = dbcron_load($dqid);
196 if (user_access('administer cron queries')) {
197 $form['dqid'] = array(
198 '#type' => 'value',
199 '#value' => $dqid,
200 );
201 $output = confirm_form('dbcron_delete_confirm', $form,
202 t('Are you sure you want to delete cron query %title?', array('%title' => theme('placeholder', $dq->title))),
203 $_GET['destination'] ? $_GET['destination'] : 'admin/dbcron', t('This action cannot be undone.'),
204 t('Delete'), t('Cancel') );
205 }
206
207 return $output;
208 }
209
210 /**
211 * Execute cron query deletion
212 **/
213 function dbcron_delete_confirm_submit($form_id, $form_values) {
214 if ($form_values['confirm']) {
215 dbcron_delete($form_values['dqid']);
216 drupal_goto('admin/dbcron');
217 }
218 }
219
220 /**
221 * Post-confirmation; delete a cron query.
222 */
223 function dbcron_delete($dqid = 0) {
224 db_query('DELETE FROM {dbcron} WHERE dqid = %d', $dqid);
225 drupal_set_message(t('The cron query has been deleted.'));
226 }
227
228 /**
229 * Save a new or existing cron query to the database.
230 */
231 function dbcron_save_query($dq) {
232 $period = _dbcron_get_run_intervals();
233 $run_interval = $period[$dq->run_interval];
234
235 if ($dq->dqid) {
236 db_query("UPDATE {dbcron} SET title = '%s', body = '%s', run_interval = %d, last_run = 0 WHERE dqid = %d", $dq->title, $dq->body, $run_interval, $dq->dqid);
237 }
238 else {
239 db_query("INSERT INTO {dbcron} (title, body, run_interval) VALUES ('%s', '%s', %d)", $dq->title, $dq->body, $run_interval);
240 }
241 }
242
243 /**
244 * Return a form for editing or creating an individual cron query.
245 */
246 function dbcron_form($dq = '') {
247 if (is_array($dq)) {
248 $dq = (object)$dq;
249 }
250
251 $form['title'] = array(
252 '#type' => 'textfield',
253 '#title' => t('Title'),
254 '#default_value' => $dq->title,
255 '#maxlength' => 128,
256 '#description' => t('Specify a unique title for this cron query. The title is simply used to help you identify the query on the overview page.'),
257 '#required' => TRUE,
258 );
259 $form['body'] = array(
260 '#type' => 'textarea',
261 '#title' => t('Query'),
262 '#default_value' => $dq->body,
263 '#description' => t('Enter the actual query here. Ensure that you have tested the query thoroughly, as it will be run regularly, and will result in numerous errors if it has problems. If you wish to run multiple queries, separate each query with a semicolon followed by a new line, and then each query will be run separately. Ensure that all table names are wrapped in curly brackets (e.g. <em>{users}</em>, not <em>users</em>), especially if your site uses database prefixing.'),
264 '#rows' => 20,
265 '#required' => TRUE,
266 );
267
268 $period = _dbcron_get_run_intervals('form');
269 $period_vals = array_flip(_dbcron_get_run_intervals());
270 $form['run_interval'] = array(
271 '#type' => 'select',
272 '#title' => t('Running interval'),
273 '#default_value' => $period_vals[$dq->run_interval],
274 '#options' => $period,
275 '#description' => t('Select the interval at which you would like this query to run. Note that if your site\'s cron runs less often than the interval that you specify, then the query will only run as often as your cron does. Set to \'never\' to disable this query, if you wish to leave it in the system and possibly re-enable it at a later date. Requires crontab.'),
276 );
277
278 if ($dq->dqid) {
279 $form['dqid'] = array(
280 '#type' => 'hidden',
281 '#value' => $dq->dqid,
282 );
283 $form['submit'] = array(
284 '#type' => 'submit',
285 '#value' => t('Update query'),
286 );
287 }
288 else {
289 $form['submit'] = array(
290 '#type' => 'submit',
291 '#value' => t('Create new query'),
292 );
293 }
294
295 return drupal_get_form('dbcron_form', $form);
296 }
297
298 /**
299 * Verify that a cron query is valid.
300 */
301 function dbcron_form_validate($form_id, $edit) {
302 $dq = _dbcron_edit_into_object($edit);
303
304 if (db_result(db_query("SELECT COUNT(run_interval) FROM {dbcron} WHERE dqid != %d AND title = '%s'", $dq->dqid, $dq->title))) {
305 form_set_error('title', t('The title %title is already in use.', array('%title' => theme('placeholder', $dq->title))));
306 }
307 }
308
309 /**
310 * Save a cron query to the database.
311 */
312 function dbcron_form_submit($form_id, $edit) {
313 $dq = _dbcron_edit_into_object($edit);
314
315 dbcron_save_query($dq);
316
317 drupal_set_message(t('The cron query has been saved.'));
318 drupal_goto('admin/dbcron');
319 }
320
321 /**
322 * Fetch a specific cron query from the database.
323 */
324 function dbcron_load($dqid) {
325 return db_fetch_object(db_query('SELECT * FROM {dbcron} WHERE dqid = %d', $dqid));
326 }
327
328 /**
329 * Transform an array of edit values for a cron query into an object.
330 *
331 * @param $edit
332 * The array of values, as returned by form interfaces.
333 *
334 * @return
335 * Equivalent values in an object.
336 */
337 function _dbcron_edit_into_object($edit) {
338 $dq = new stdClass();
339 $dq->title = $edit['title'];
340 $dq->body = $edit['body'];
341 $dq->run_interval = $edit['run_interval'];
342 $dq->dqid = $edit['dqid'];
343
344 return $dq;
345 }
346
347 /**
348 * Get an associative array of all the running intervals.
349 */
350 function _dbcron_get_run_intervals($type = NULL) {
351 $period = array(300, 600, 900, 1800, 2700, 3600, 7200, 10800, 21600, 32400, 43200, 64800, 86400, 172800, 259200, 432000, 604800);
352
353 if ($type == 'form') {
354 $period = drupal_map_assoc($period, 'format_interval');
355 return array_merge(array(0 => t('Never')), $period);
356 }
357 else {
358 return array_merge(array(0 => 0), $period);
359 }
360 }

  ViewVC Help
Powered by ViewVC 1.1.2