first commit
[step2_drupal.git] / signup / signup.install
blobebb4a031bc71ba905e69e33b75f77ee7805ad93d
1 <?php
2 // $Id: signup.install,v 1.24.2.2 2008/12/19 01:00:35 dww Exp $
5 /**
6  * Implementation of hook_schema().
7  */
8 function signup_schema() {
9   $schema['signup'] = array(
10     'description' => t('Signup module per-node settings.'),
11     'fields' => array(
12       'nid' => array(
13         'description' => t('Primary key: node ID'),
14         'type' => 'int',
15         'unsigned' => TRUE,
16         'not null' => TRUE,
17         'default' => 0,
18       ),
19       'forwarding_email' => array(
20         'description' => t('Email address to send signup notifications to.'),
21         'type' => 'varchar',
22         'length' => 64,
23         'not null' => TRUE,
24         'default' => '',
25       ),
26       'send_confirmation' => array(
27         'description' => t('Boolean indicating whether confirmation emails should be sent.'),
28         'type' => 'int',
29         'not null' => TRUE,
30         'default' => 0,
31       ),
32       'confirmation_email' => array(
33         'description' => t('Email template to send to users when they signup.'),
34         'type' => 'text',
35         'size' => 'big',
36         'not null' => TRUE,
37       ),
38       'send_reminder' => array(
39         'description' => t('Boolean indicating whether reminder emails should be sent. This is set to 0 once the reminders are sent.'),
40         'type' => 'int',
41         'not null' => TRUE,
42         'default' => 0,
43       ),
44       'reminder_days_before' => array(
45         'description' => t('Number of days before the start of a time-based node when the reminder emails should be sent.'),
46         'type' => 'int',
47         'unsigned' => TRUE,
48         'not null' => TRUE,
49         'default' => 0,
50       ),
51       'reminder_email' => array(
52         'description' => t('Email template to send to users to remind them about a signup.'),
53         'type' => 'text',
54         'size' => 'big',
55         'not null' => TRUE,
56       ),
57       'close_in_advance_time' => array(
58         'description' => t('Number of hours before the start of a time-based node when signups should automatically be closed. This column is not currently used and the behavior is controlled by a site-wide setting.  See http://drupal.org/node/290249 for more information.'),
59         'type' => 'int',
60         'unsigned' => TRUE,
61         'not null' => TRUE,
62         'default' => 0,
63       ),
64       'close_signup_limit' => array(
65         'description' => t('Maximum number of users who can signup before signups are closed. If set to 0, there is no limit.'),
66         'type' => 'int',
67         'unsigned' => TRUE,
68         'not null' => TRUE,
69         'default' => 0,
70       ),
71       'status' => array(
72         'description' => t('Boolean indicating if signups are open (1) or closed (0) for the given node'),
73         'type' => 'int',
74         'not null' => TRUE,
75         'default' => 1,
76       ),
77     ),
78     'primary key' => array('nid'),
79   );
81   $schema['signup_log'] = array(
82     'description' => t('Records information for each user who signs up for a node.'),
83     'fields' => array(
84       'sid' => array(
85         'description' => t('Primary key: signup ID'),
86         'type' => 'serial',
87         'size' => 'normal',
88         'unsigned' => TRUE,
89         'not null' => TRUE,
90       ),
91       'uid' => array(
92         'description' => t('Key: the user ID of the user who signed up.'),
93         'type' => 'int',
94         'unsigned' => TRUE,
95         'not null' => TRUE,
96         'default' => 0,
97       ),
98       'nid' => array(
99         'description' => t('Key: the node ID of the node the user signed up for.'),
100         'type' => 'int',
101         'unsigned' => TRUE,
102         'not null' => TRUE,
103         'default' => 0,
104       ),
105       'anon_mail' => array(
106         'description' => t('The email address for an anonymous user who signed up, or an empty string for authenticated users.'),
107         'type' => 'varchar',
108         'length' => 255,
109         'not null' => TRUE,
110         'default' => '',
111       ),
112       'signup_time' => array(
113         'description' => t('Integer timestamp of when the user signed up for the node.'),
114         'type' => 'int',
115         'unsigned' => TRUE,
116         'not null' => TRUE,
117         'default' => 0,
118       ),
119       'form_data' => array(
120         'description' => t('Serialized string of additional signup form values.  See theme_signup_user_form() from theme/signup.theme for more information.'),
121         'type' => 'text',
122         'size' => 'big',
123         'not null' => TRUE,
124       ),
125       'attended' => array(
126         'description' => t('Did this user actually attend the node they signed up for?'),
127         'type' => 'int',
128         'size' => 'tiny',
129       ),
130     ),
131     'primary key' => array('sid'),
132     'indexes' => array(
133       'uid' => array('uid'),
134       'nid' => array('nid'),
135     ),
136   );
138   return $schema;
142  * Implementation of hook_install().
144  * This will automatically install the database tables for the Signup
145  * module for both the MySQL and PostgreSQL databases.
147  * If you are using another database, you will have to install the
148  * tables by hand, using the queries below as a reference.
150  * Note that the curly braces around table names are a drupal-specific
151  * feature to allow for automatic database table prefixing, and will
152  * need to be removed.
153  */
154 function signup_install() {
155   // Create tables.
156   drupal_install_schema('signup');
157   signup_insert_default_signup_info();
160 function signup_uninstall() {
161   // Remove tables.
162   drupal_uninstall_schema('signup');
164   $variables = db_query("SELECT name FROM {variable} WHERE name LIKE 'signup%%'");
165   while ($variable = db_fetch_object($variables)) {
166     variable_del($variable->name);
167   }
171  * Helper method to insert the default signup information into the
172  * {signup} table (stored in a row for nid 0).  These are the default
173  * settings for new signup-enabled nodes.
174  */
175 function signup_insert_default_signup_info() {
176   return db_query("INSERT INTO {signup} (nid, forwarding_email,
177     send_confirmation, confirmation_email,
178     send_reminder, reminder_days_before, reminder_email,
179     close_in_advance_time, close_signup_limit, status) VALUES (0, '',
180     1, 'Enter your default confirmation email message here',
181     1, 1, 'Enter your default reminder email message here',
182     0, 0, 1)");
186  * UTF8 table update
187  */
188 function signup_update_1() {
189   return _system_update_utf8(array('signup', 'signup_log'));
192 function signup_update_2() {
193   $ret = array();
194   $ret[] = update_sql("ALTER TABLE {signup} DROP permissions");
195   return $ret;
198 function signup_update_3() {
199   $ret = array();
200   switch ($GLOBALS['db_type']) {
201     case 'mysql':
202     case 'mysqli':
203       $ret[] = update_sql("ALTER TABLE {signup_log} ADD anon_mail VARCHAR( 255 ) NOT NULL default '' AFTER nid;");
204       $ret[] = update_sql("ALTER TABLE {signup_log} DROP INDEX uid_nid;");
205       $ret[] = update_sql("ALTER TABLE {signup_log} ADD INDEX (uid);");
206       $ret[] = update_sql("ALTER TABLE {signup_log} ADD INDEX (nid);");
207       break;
209     case 'pgsql':
210       db_add_column($ret, 'signup_log', 'anon_mail', 'text', array('not null' => TRUE, 'default' => "''"));
211       $ret[] = update_sql("DROP INDEX {signup_log}_uid_nid_idx;");
212       $ret[] = update_sql("CREATE INDEX {signup_log}_uid_idx ON {signup_log}(uid);");
213       $ret[] = update_sql("CREATE INDEX {signup_log}_nid_idx ON {signup_log}(nid);");
214       break;
215   }
216   return $ret;
220  * Rename the signup permissions.
221  * See http://drupal.org/node/69283 for details.
222  * Also, remove the 'signup_user_view' setting in favor of a permission.
223  * See http://drupal.org/node/69367 for details.
224  */
225 function signup_update_4() {
226   $ret = array();
228   // Setup arrays holding regexps to match and the corresponding
229   // strings to replace them with, for use with preg_replace().
230   $old_perms = array(
231     '/allow signups/',
232     '/admin signups/',
233     '/admin own signups/',
234   );
235   $new_perms = array(
236     'sign up for content',
237     'administer all signups',
238     'administer signups for own content',
239   );
241   // Now, loop over all the roles, and do the necessary transformations.
242   $query = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
243   while ($role = db_fetch_object($query)) {
244     $fixed_perm = preg_replace($old_perms, $new_perms, $role->perm);
245     if ($role->rid == 2 && variable_get('signup_user_view', 0)) {
246       // The setting is currently enabled, so add the new permission to
247       // the "authenticated user" role as a reasonable default.
248       if (!strpos($fixed_perm, 'view all signups')) {
249         $fixed_perm .= ', view all signups';
250         drupal_set_message(t('The old %signup_user_view setting was enabled on your site, so the %view_all_signups permission has been added to the %authenticated_user role. Please consider customizing what roles have this permission on the !access_control page.', array('%signup_user_view' => t('Users can view signups'), '%view_all_signups' => 'view all signups', '%authenticated_user' => 'Authenticated user', '!access_control' => l(t('Access control'), '/admin/user/access'))));
251       }
252     }
253     $ret[] = update_sql("UPDATE {permission} SET perm = '$fixed_perm' WHERE rid = $role->rid");
254   }
256   // Remove the stale setting from the {variable} table in the DB.
257   variable_del('signup_user_view');
258   drupal_set_message(t('The %signup_user_view setting has been removed.', array('%signup_user_view' => t('Users can view signups'))));
260   return $ret;
264  * Convert the misnamed "completed" column to "status" (and swap all
265  * the values: 0 == closed, 1 == open).
266  */
267 function signup_update_5200() {
268   $ret = array();
269   switch ($GLOBALS['db_type']) {
270     case 'mysql':
271     case 'mysqli':
272       $ret[] = update_sql("ALTER TABLE {signup} ADD status int NOT NULL default '1'");
273       break;
275     case 'pgsql':
276       db_add_column($ret, 'signup', 'status', 'integer', array('not null' => TRUE, 'default' => "'1'"));
277       break;
278   }
279   $ret[] = update_sql("UPDATE {signup} SET status = (1 - completed)");
280   $ret[] = update_sql("ALTER TABLE {signup} DROP completed");
281   return $ret;
285  * Add the close_signup_limit field to the {signup} table to allow
286  * signup limits for sites that upgraded from 4.6.x.  The original
287  * signup.install for 4.7.x accidentally included this column in the
288  * DB, but it's never been used in the code until now.  However, sites
289  * that upgraded from 4.6.x need this column for the module to work,
290  * so just to be safe, we also add that here.
291  */
292 function signup_update_5201() {
293   $ret = array();
294   switch ($GLOBALS['db_type']) {
295     case 'mysql':
296     case 'mysqli':
297       if (!db_column_exists('signup', 'close_signup_limit')) {
298         $ret[] = update_sql("ALTER TABLE {signup} ADD close_signup_limit int(10) unsigned NOT NULL default '0'");
299       }
300       break;
302     case 'pgsql':
303       if (!db_column_exists('signup', 'close_signup_limit')) {
304         db_add_column($ret, 'signup', 'close_signup_limit', 'integer', array('not null' => TRUE, 'default' => "'0'"));
305       }
306       break;
307   }
308   return $ret;
312  * Add "cancel own signups" permission to all roles that have "sign up
313  * for content" permission.
314  */
315 function signup_update_5202() {
316   $ret = array();
317   switch ($GLOBALS['db_type']) {
318     case 'mysql':
319     case 'mysqli':
320       $ret[] = update_sql("UPDATE {permission} SET perm = CONCAT(perm, ', cancel own signups') WHERE CONCAT(perm, ', ') LIKE '%%sign up for content, %%'");
321       break;
323     case 'pgsql':
324       $ret[] = update_sql("UPDATE {permission} SET perm = perm || ', cancel own signups' WHERE perm || ', ' LIKE '%%sign up for content, %%'");
325       break;
326   }
327   drupal_set_message(t("Added the 'cancel own signups' permission to all roles that have the 'sign up for content' permission.") .'<br />'. t('If you do not want your users to cancel their own signups, go to the <a href="@access_url">Access control</a> page and unset this permission.', array('@access_url' => url('/admin/user/access'))));
328   return $ret;
332  * Migrate signup settings per content type so that signups can be disabled
333  * completely for a content type.
334  */
335 function signup_update_5203() {
336   $old_prefix = 'signup_form_';
337   $result = db_query("SELECT name FROM {variable} WHERE name LIKE '$old_prefix%%'");
338   while ($row = db_fetch_object($result)) {
339     $old_name = $row->name;
340     $new_name = 'signup_node_default_state_'. substr($old_name, strlen($old_prefix));
341     $new_value = variable_get($old_name, 0) == 1 ? 'enabled_on' : 'disabled';
342     variable_del($old_name);
343     variable_set($new_name, $new_value);
344   }
345   drupal_set_message(t('Migrated signup settings per content type.'));
346   return array();
350  * Rename all the tokens in existing email templates and the global settings.
351  */
352 function signup_update_5204() {
353   $ret = array();
355   // Multi-part update.
356   if (!isset($_SESSION['signup_update_5204'])) {
357     // We need to start at nid 0 for the site-wide defaults, so
358     // initialize our variable to the value below that.
359     $_SESSION['signup_update_5204'] = -1;
360     $_SESSION['signup_update_5204_max'] = db_result(db_query("SELECT MAX(nid) FROM {signup}"));
361   }
363   // Array of replacements mapping old names to the new names.
364   // NOTE: To avoid trouble with db_query() trying to interpret the
365   // '%', we escape all of them as '%%' to get % literals.
366   $replacements = array(
367     '%%eventurl' => '%%node_url',
368     '%%event' => '%%node_title',
369     '%%time' => '%%node_start_time',
370     '%%username' => '%%user_name',
371     '%%useremail' => '%%user_mail',
372     '%%info' => '%%user_signup_info',
373   );
375   // Build up a nested REPLACE() fragment to have the DB do all the string
376   // conversions for us in a single query, instead of pulling the records out
377   // of the DB, doing the string manipulation in PHP, and writing back the
378   // values in a bunch of separate queries.  According to the docs, REPLACE()
379   // works the same way on both MySQL and PgSQL.
380   $reminder_replace = 'reminder_email';
381   $confirmation_replace = 'confirmation_email';
382   foreach ($replacements as $from => $to) {
383     $reminder_replace = "REPLACE($reminder_replace, '$from', '$to')";
384     $confirmation_replace = "REPLACE($confirmation_replace, '$from', '$to')";
385   }
387   // Do the next batch of the deed.
388   // Find the next N records to update, or do the final batch.
389   $next = min($_SESSION['signup_update_5204'] + 2000, $_SESSION['signup_update_5204_max']);
390   // Perform the UPDATE in our specified range of nid values.
391   db_query("UPDATE {signup} SET reminder_email = $reminder_replace, confirmation_email = $confirmation_replace WHERE nid > %d AND nid <= %d", $_SESSION['signup_update_5204'], $next);
392   // Remember where we left off.
393   $_SESSION['signup_update_5204'] = $next;
395   if ($_SESSION['signup_update_5204'] == $_SESSION['signup_update_5204_max']) {
396     // We're done, clear these out.
397     unset($_SESSION['signup_update_5204']);
398     unset($_SESSION['signup_update_5204_max']);
400     // Provide a human-readable explaination of what we did.
401     $tokens = array(
402       '%event' => '%event',
403       '%eventurl' => '%eventurl',
404       '%time' => '%time',
405       '%username' => '%username',
406       '%useremail' => '%useremail',
407       '%info' => '%info',
408       '%node_title' => '%node_title',
409       '%node_url' => '%node_url',
410       '%node_start_time' => '%node_start_time',
411       '%user_name' => '%user_name',
412       '%user_mail' => '%user_mail',
413       '%user_signup_info' => '%user_signup_info',
414       );
415     $ret[] = array('success' => TRUE, 'query' => t('Replaced %event, %eventurl, %time, %username, %useremail, and %info tokens with %node_title, %node_url, %node_start_time, %user_name, %user_mail, and %user_signup_info in the reminder and confirmation email templates.', $tokens));
416   }
417   else {
418     // Report how much is left to complete.
419     $ret['#finished'] = $_SESSION['signup_update_5204'] / $_SESSION['signup_update_5204_max'];
420   }
421   return $ret;
425  * Migrate signup user list view display type to the new variable.
426  */
427 function signup_update_6000() {
428   $ret = array();
429   variable_del('signup_user_list_view_name');
430   variable_del('signup_user_list_view_type');
431   $ret[] = array(
432     'success' => TRUE,
433     'query' => t('Removed the deprecated %old_view_name and %old_view_type variables. If you were using embedding a view on signup-enabled nodes, please visit the <a href="@signup_settings_url">Signup configuration page</a> and select a new value for the %setting_name setting (which is located under the Advanced settings).', array(
434       '%old_view_name' => 'signup_user_list_view_name',
435       '%old_view_type' => 'signup_user_list_view_type',
436       // NOTE: we can't use url() here because it would use 'update.php?q=...'
437       '@signup_settings_url' => base_path() .'?q=admin/settings/signup',
438       '%setting_name' => t('View to embed for the signup user list'),
439     )),
440   );
441   return $ret;
445  * Add unique id column to signup_log as the primary key.
447  * http://drupal.org/node/341382 for more infomation.
448  */
449 function signup_update_6001() {
450   $ret = array();
451   $field = array(
452     'type' => 'serial',
453     'size' => 'normal',
454     'unsigned' => TRUE,
455     'not null' => TRUE,
456   );
457   db_add_field($ret, 'signup_log', 'sid', $field, array('primary key' => array('sid')));
458   return $ret;  
462  * Add an 'attended' field to the {signup_log} table.
464  * http://drupal.org/node/55168 for more infomation.
465  */
466 function signup_update_6002() {
467   $ret = array();
468   $field = array(
469     'type' => 'int',
470     'size' => 'tiny',
471   );
472   db_add_field($ret, 'signup_log', 'attended', $field);
473   return $ret;