og.install 17.2 KB
Newer Older
1
<?php
2 3

/**
4
 * TODO: upgrade all update_14+ updates to d6
5
 */
6

7 8

/**
9
 * Definition of hook_schema();
10
 */
11 12 13 14
function og_schema() {
  $schema = array();

  $schema['og'] = array(
15
    'description'     => 'Stores information about each group.',
16 17
    'fields'          => array(
      'nid'             => array(
18
        'description'     => "The group's {node}.nid.",
19 20 21 22
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
23
      'og_selective'       => array(
24
        'description'     => 'Determines how subscription requests are handled (open, moderated, invite only, closed).',
25 26 27 28 29
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
        'default'         => 0,
      ),
30
      'og_description'     => array(
31
        'description'     => 'Group description. Shows up by default on group directory.',
32 33 34 35
        'type'            => 'varchar',
        'length'          => 255,
        'not null'        => FALSE,
      ),
36
      'og_theme'           => array(
37
        'description'     => 'The group specific theme (if any). See {system}.name.',
38 39 40 41
        'type'            => 'varchar',
        'length'          => 255,
        'not null'        => FALSE,
      ),
42
      'og_register'        => array(
43
        'description'     => 'Should users be able to join this group from registration form.',
44 45 46 47 48
        'type'            => 'int',
        'size'            => 'tiny',
        'not null'        => TRUE,
        'default'         => 0,
      ),
49
      'og_directory'       => array(
50
        'description'     => 'Should this group appear in the groups directory.',
51 52 53 54 55
        'type'            => 'int',
        'size'            => 'tiny',
        'not null'        => TRUE,
        'default'         => 0,
      ),
56
      'og_language'        => array(
57
        'description'     => 'Group specific language. See {languages}.language.',
58 59 60 61 62
        'type'            => 'varchar',
        'length'          => 12,
        'not null'        => TRUE,
        'default'         => '',
      ),
63
      'og_private'         => array(
64
        'description'     => 'Is group home page private or public.',
65 66 67 68 69 70 71 72
        'type'            => 'int',
        'size'            => 'tiny',
        'not null'        => TRUE,
        'default'         => 0,
      ),
    ),
    'primary key'       => array('nid'),
  );
73

74
  $schema['og_uid'] = array(
75
    'description'     => 'Group memberships',
76 77
    'fields'          => array(
      'nid'             => array(
78
        'description'     => "Group's {node}.nid.",
79 80 81 82 83
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
      'og_role'         => array(
84
        'description'     => 'Not currently used.',
85 86 87 88 89 90
        'type'            => 'int',
        'size'            => 'tiny',
        'not null'        => TRUE,
        'default'         => 0,
      ),
      'is_active'       => array(
91
        'description'     => 'Is this membership active or pending?',
92 93 94 95 96 97
        'type'            => 'int',
        'size'            => 'tiny',
        'not null'        => TRUE,
        'default'         => 0,
      ),
      'is_admin'        => array(
98
        'description'     => 'Is this user a group administrator?',
99 100 101 102 103 104
        'type'            => 'int',
        'size'            => 'tiny',
        'not null'        => TRUE,
        'default'         => 0,
      ),
      'uid'             => array(
105
        'description'     => 'The user for this membership. See {users}.uid.',
106 107 108 109 110
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
      'created'         => array(
111
        'description'     => 'Time when this membership was created.',
112 113 114 115 116 117
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => FALSE,
        'default'         => 0,
      ),
      'changed'         => array(
118
        'description'     => 'Time when this membership was last changed.',
119 120 121 122 123 124 125
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => FALSE,
        'default'         => 0,
      ),
    ),
    'primary key'       => array('nid', 'uid'),
126 127 128
    'indexes' => array(
      'uid' => array('uid'),
    ),
129 130
  );
  $schema['og_ancestry'] = array(
131
    'description'     => 'Stores associations between nodes and groups.',
132 133
    'fields'          => array(
      'nid'             => array(
134
        'description'     => "The post's {node}.nid.",
135 136 137 138 139
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
      'group_nid'       => array(
140
        'description'     => "The group's {node}.nid.",
141 142 143 144 145
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
    ),
146
    'primary key'       => array('nid', 'group_nid'),
147 148 149
    'indexes'           => array(
      'group_nid'         => array('group_nid'),
    ),
150
  );
151

152
  return $schema;
153
}
154

155 156
function og_install() {
  drupal_install_schema('og');
157

158
  // enable standard og blocks. for custom profiles, block may not be included yet.
159
  if (function_exists('_block_rehash')) {
160
    _block_rehash();
161
  }
162

163 164

  // Need og_readme() function.
165
  include_once dirname(__FILE__) . '/og.module';
166
  drupal_set_message(t('Organic groups module enabled. Please see the included !readme_file for further installation instructions.', array('!readme_file' => og_readme())));
167 168
}

169
// First 5.x update.
170 171
// use the new na_arbitrator way of writing to node_access table
function og_update_14() {
172 173 174
  switch ($GLOBALS['db_type']) {
    case 'mysql':
    case 'mysqli':
175 176 177 178 179 180 181 182 183 184
      $ret[] = update_sql("CREATE TABLE {og_ancestry} (
        nid int(11) NOT NULL,
        group_nid int(11) NOT NULL,
        is_public int(1) NULL,
        KEY  (nid),
        KEY  (group_nid)
      ) /*!40100 DEFAULT CHARACTER SET utf8 */;");
    break;
    case 'pgsql':
      db_query("CREATE TABLE {og_ancestry} (
185 186 187 188 189 190
        nid int NOT NULL,
        group_nid int NOT NULL,
        is_public smallint NOT NULL
      );");
      db_query("CREATE INDEX {og_ancestry}_nid_idx ON {og_ancestry} (nid);");
      db_query("CREATE INDEX {og_ancestry}_group_nid_idx ON {og_ancestry} (group_nid);");
191
    break;
192
  }
193
  og_migrate_type_basic_14();
194

195 196
  // populate og_ancestry.
  $result = db_query_temporary(
197 198 199
    "SELECT na.nid, na.gid, IF(MIN(na.realm) = 'og_all', 1, 0) AS is_public
     FROM {node_access} na INNER JOIN {node} n ON na.nid=n.nid
     WHERE realm IN ('og_all', 'og_subscriber') AND n.type NOT IN ('%s') GROUP BY na.nid, na.gid ORDER BY nid ASC",
200 201 202
       implode(', ', variable_get('og_node_types', array('og'))), 'og_migrate');
  $sql = "INSERT INTO {og_ancestry} (nid, group_nid, is_public) SELECT nid, gid, is_public FROM {og_migrate}";
  db_query($sql);
203

204 205 206 207
  // rebuild takes care of writing new access records
  // too bad this part can't be performed over multiple updates
  node_access_rebuild();
  return array();
208 209 210 211 212
}

// Create a user managed node type which replaces the deprecated og_basic module
// helper function for og_update_14
function og_migrate_type_basic_14() {
213
  if (og_is_group_type('og')) {
214 215
    $info = array('type' => 'og', 'name' => 'group', 'module' => 'node', 'has_title' => 1, 'title_label' => 'Group name', 'has_body' => 1, 'body_label' => 'Welcome message', 'description' => 'A group provides a home page for like minded users. There they post articles about their shared interest.', 'help' => '', 'min_word_count' => 0, 'custom' => 1, 'modified' => 1, 'locked' => 0, 'orig_type' => 'og');
    node_type_save((object)$info);
216
    module_disable(array('og_basic'));
217
    node_types_rebuild();
218 219 220
  }
}

221
// Safely add primary key to og_ancestry table. Called from og.istall and og_access.install.
222
function og_ancestry_dedupe(&$ret) {
223 224 225 226
  $schema['og_ancestry_new'] = array(
    'description'     => '',
    'fields'          => array(
      'nid'             => array(
227
        'description'     => "The post's {node}.nid.",
228 229 230 231 232
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
      'group_nid'       => array(
233
        'description'     => "The group's {node}.nid.",
234 235 236 237 238 239 240 241 242 243 244 245 246
        'type'            => 'int',
        'size'            => 'normal',
        'not null'        => TRUE,
      ),
    ),
  );
  db_create_table($ret, 'og_ancestry_new', $schema['og_ancestry_new']);
  $ret[] = update_sql("INSERT INTO {og_ancestry_new} SELECT DISTINCT * FROM {og_ancestry}");
  db_drop_table($ret, 'og_ancestry');
  db_rename_table($ret, 'og_ancestry_new', 'og_ancestry');
  db_add_primary_key($ret, 'og_ancestry', array('nid', 'group_nid'));
}

247 248 249
function og_update_15() {
  variable_del('og_max_posts');
  variable_del('og_home_page_presentation');
250
  return array();
251 252
}

253 254
function og_update_16() {
  // we are no longer denying access to nodes without groups. see http://drupal.org/node/107289
255 256 257
  if (variable_get('og_enabled', 0)) {
    node_access_rebuild();
  }
258 259 260
  return array();
}

261 262 263 264 265 266 267 268
function og_update_17() {
  // we are once again putting group nodes into the node access system. see http://drupal.org/node/128306
  if (variable_get('og_enabled', 0)) {
    node_access_rebuild();
  }
  return array();
}

269 270 271 272 273 274 275 276
function og_update_18() {
  // woops. got it a bit wrong last time
  if (variable_get('og_enabled', 0)) {
    node_access_rebuild();
  }
  return array();
}

Zen's avatar
Zen committed
277
// Formerly contained og_uid_global code which is no longer required.
278
function og_update_19() {
Zen's avatar
Zen committed
279
  return array();
280 281
}

282 283 284 285 286 287 288
function og_update_20() {
  switch ($GLOBALS['db_type']) {
  case 'mysql':
  case 'mysqli':
    $ret[] = update_sql("ALTER TABLE {og} ADD private int(1) NOT NULL default 0");
    break;
  case 'pgsql':
289
    $ret[] = update_sql("ALTER TABLE {og} ADD private smallint NOT NULL default 0");
290 291 292 293
    break;
  }
  return $ret;
}
294 295 296

/**
 * Changes '@body' to '@node_teaser' in existing e-mail templates.
297
 */
298 299 300 301 302 303 304 305 306 307 308 309 310
function og_update_5600() {
  $ret = array();
  $variables = array('og_new_node_body', 'og_new_node_subject');
  foreach ($variables as $variable) {
    $value = variable_get($variable, '');
    if (!empty($value)) {
      variable_set($variable, str_replace('@body', '@node_teaser', $value));
      $ret[] = array('success' => TRUE, 'query' => "Replaced @body with @node_teaser in $variable");
    }
  }
  return $ret;
}

311 312
/**
 * Enable og_access module if needed
313
 */
314 315 316
function og_update_5700() {
  $ret = array();
  if (variable_get('og_enabled', FALSE) && !module_exists('og_access')) {
317
    drupal_install_modules('og_access');
318 319
  }
  // variable_del('og_enabled'); is harmless to leave around, and will help if someone reruns the update.
320

321 322 323
  return $ret;
}

324 325
/**
 * Update variables to new content type system. Also rebuild node_access for new grants system.
326
 *
327 328
 * @return void
 **/
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
function og_update_5701() {
  $ret = array();
  $types = node_get_types();
  foreach ($types as $type) {
    if (in_array($type->type, variable_get('og_node_types', array('og')))) {
      variable_set('og_content_type_usage_'. $type->type, 'group');
    }
    elseif (in_array($type->type, variable_get('og_omitted', array('og')))) {
      variable_set('og_content_type_usage_'. $type->type, 'omitted');
    }
    elseif (in_array($type->type, variable_get('og_omitted_email_node_types', array('og')))) {
     variable_set('og_content_type_usage_'. $type->type, 'group_post_standard_nomail');
    }
    else {
      variable_set('og_content_type_usage_'. $type->type, 'group_post_standard_mail');
344
    }
345
  }
346

347 348 349 350
 node_access_rebuild();
 return $ret;
}

Zen's avatar
Zen committed
351
/**
352
 * Notifications upgrade: Set flag to indicate that this is an upgraded
Zen's avatar
Zen committed
353
 * installation.
354
 */
Zen's avatar
Zen committed
355 356 357
function og_update_5703() {
  // Remove mail / no mail options from OG group types and move preferences to
  // og_notifications.
358
  include_once dirname(__FILE__) . '/og.module';
Zen's avatar
Zen committed
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379
  $types = og_get_types('group_post');
  $mail_types = array();
  foreach ($types as $type) {
    $variable = 'og_content_type_usage_'. $type;
    $usage = variable_get($variable, '');
    switch ($usage) {
      case 'group_post_standard_mail':
        $mail_types[$type] = $type;
      case 'group_post_standard_nomail':
        variable_set($variable, 'group_post_standard');
        break;
      case 'group_post_wiki_mail':
        $mail_types[$type] = $type;
      case 'group_post_wiki_nomail':
        variable_set($variable, 'group_post_wiki');
        break;
    }
  }
  // Set variable for og_notifications. If it is never enabled, this variable
  // is also deleted in og_uninstall.
  variable_set('og_notifications_content_types', $mail_types);
380

Zen's avatar
Zen committed
381 382
  // Vestigial variable.
  variable_del('og_omitted_email_node_types');
383

Zen's avatar
Zen committed
384 385 386 387
  // Set update flag for og_notifications.
  variable_set('og_notifications_update_required', 1);

  return array();
388 389
}

Zen's avatar
Zen committed
390 391 392 393 394 395 396 397
function og_update_6000() {
  $ret = array();
  // Fix how we append the custom request text from a group join request.
  $name = 'og_request_user_body';
  if ($txt = variable_get($name, FALSE)) {
    $txt .= "\n\nPersonal message from @username:\n------------------\n\n@request";
    variable_set($name, $txt);
  }
398
  return $ret;
Zen's avatar
Zen committed
399 400 401 402 403 404 405
}

// Update to support views modularization while retaining backward compatibility.
function og_update_6001() {
  $ret = array();
  drupal_install_modules(array('og_views'));
  //enable the og_views block instead of the plain og one
406
  $ret[] = update_sql("UPDATE {blocks} SET module = 'og_views', delta = '1' WHERE module = 'og' AND delta = '5'");
Zen's avatar
Zen committed
407 408 409 410 411 412
  return $ret;
}

// Change field names in {og} table. Enables use of drupal_write_record()
function og_update_6002() {
  $ret = array();
413

Zen's avatar
Zen committed
414 415 416 417 418 419 420 421 422 423 424 425
  $schema = drupal_get_schema_unprocessed('og', 'og');
  $fields = $schema['fields'];
  db_change_field($ret, 'og', 'selective', 'og_selective', $fields['og_selective']);
  db_change_field($ret, 'og', 'register', 'og_register', $fields['og_register']);
  db_change_field($ret, 'og', 'theme', 'og_theme', $fields['og_theme']);
  db_change_field($ret, 'og', 'directory', 'og_directory', $fields['og_directory']);
  db_change_field($ret, 'og', 'description', 'og_description', $fields['og_description']);
  db_change_field($ret, 'og', 'language', 'og_language', $fields['og_language']);
  db_change_field($ret, 'og', 'private', 'og_private', $fields['og_private']);
  return $ret;
}

426
// Migrate the is_public column from og_ancestry to a new og_nid table. Denormalizing.
427
function og_update_6203() {
428 429 430 431 432 433
  $ret = array();
  if (module_exists('og_access')) {
    // Do nothing. An og_access update handles this.
  }
  else {
    db_drop_field($ret, 'og_ancestry', 'is_public');
434
    og_ancestry_dedupe($ret);
435
  }
436

437 438 439
  return $ret;
}

440 441 442 443 444 445 446 447 448
/**
 * Add index 'group_nid' to og_ancestry table.
 */
function og_update_6204() {
  $ret = array();
  db_add_index($ret, 'og_ancestry', 'group_nid', array('group_nid'));
  return $ret;
}

449 450 451 452 453 454 455 456 457
/**
 * Add an index on og_uid.uid.
 */
function og_update_6205() {
  $ret = array();
  db_add_index($ret, 'og_uid', 'uid', array('uid'));
  return $ret;
}

Zen's avatar
Zen committed
458 459
// end updates //

460
function og_uninstall() {
461
  drupal_uninstall_schema('og');
462

463 464
  // In case og_notifications has never been enabled, the vestigial
  // og_uid_global table will still be around.
465 466 467 468
  if (variable_get('og_notifications_update_required', FALSE)) {
    db_query('DROP TABLE {og_uid_global}');
  }

469
  // Delete variables
470
  $variables = array(
471
    'og_help', 'og_block_cnt_2', 'og_block_cnt_3',
472
    'og_audience_checkboxes', 'og_omitted', 'og_content_type_usage',
Zen's avatar
Zen committed
473
    'og_audience_required',
474 475 476 477 478 479 480
    'og_visibility_directory', 'og_visibility_registration',
    'og_home_page_view', 'og_email_max', 'og_node_types',
    'og_admin_email_body', 'og_email_notification_pattern',
    'og_approve_user_body', 'og_approve_user_subject',
    'og_deny_user_body', 'og_deny_user_subject',
    'og_invite_user_body', 'og_invite_user_subject',
    'og_new_admin_body', 'og_new_admin_subject',
481
    'og_remove_admin_body', 'og_remove_admin_subject',
482
    'og_new_node_body', 'og_new_node_subject',
483
    'og_request_user_body', 'og_request_user_subject',
484
    'og_notifications_update_required', 'og_notifications_content_types'
485
  );
486 487 488

  foreach (node_get_types() as $type_name => $type) {
    $variables[] = 'og_max_groups_' . $type_name;
489
    $variables[] = 'og_content_type_usage_' . $type_name;
490 491
  }

492 493 494
  foreach ($variables as $variable) {
    variable_del($variable);
  }
495
}
496 497 498

function og_requirements($phase) {
  // Need og_readme() function.
499
  include_once dirname(__FILE__) . '/og.module';
500

501 502 503 504 505 506 507
  $requirements = array();
  // Ensure translations don't break at install time
  $t = get_t();
  if ($phase == 'runtime') {
    $og_types = og_get_types('group');
    $all_types = array_keys(node_get_types('types'));
    if (!count(array_intersect($og_types, $all_types))) {
Zen's avatar
Zen committed
508 509 510 511
      $requirements['og_group_types']  = array(
        'title' => $t('Organic groups group type'),
        'value' => $t('You have no node types which are acting as groups. See the notes section of the !readme_file and the content types fieldset at top of <a href="!settings">OG settings</a>.', array('!readme_file' => og_readme(), '!settings' => url('admin/og/og'))),
        'severity' => REQUIREMENT_ERROR,
512 513
      );
    }
Zen's avatar
Zen committed
514

515 516 517 518 519 520 521 522
    if (!module_exists('og_access')) {
      $requirements['og_access'] = array(
        'title' => $t('Organic groups access control'),
        'value' => $t('Organic groups access control module is disabled. See the <a href="@modules">modules page</a>.', array('@modules' => url('admin/build/modules'))),
        'severity' => REQUIREMENT_INFO
      );
    }
  }
523

524 525
  return $requirements;
}