cms/drupal/modules/field/field.install
changeset 541 e756a8c72c3d
equal deleted inserted replaced
540:07239de796bb 541:e756a8c72c3d
       
     1 <?php
       
     2 
       
     3 /**
       
     4  * @file
       
     5  * Install, update and uninstall functions for the field module.
       
     6  */
       
     7 
       
     8 /**
       
     9  * Implements hook_schema().
       
    10  */
       
    11 function field_schema() {
       
    12   // Static (meta) tables.
       
    13   $schema['field_config'] = array(
       
    14     'fields' => array(
       
    15       'id' => array(
       
    16         'type' => 'serial',
       
    17         'not null' => TRUE,
       
    18         'description' => 'The primary identifier for a field',
       
    19       ),
       
    20       'field_name' => array(
       
    21         'type' => 'varchar',
       
    22         'length' => 32,
       
    23         'not null' => TRUE,
       
    24         'description' => 'The name of this field. Non-deleted field names are unique, but multiple deleted fields can have the same name.',
       
    25       ),
       
    26       'type' => array(
       
    27         'type' => 'varchar',
       
    28         'length' => 128,
       
    29         'not null' => TRUE,
       
    30         'description' => 'The type of this field.',
       
    31       ),
       
    32      'module' => array(
       
    33         'type' => 'varchar',
       
    34         'length' => 128,
       
    35         'not null' => TRUE,
       
    36         'default' => '',
       
    37         'description' => 'The module that implements the field type.',
       
    38       ),
       
    39       'active' => array(
       
    40         'type' => 'int',
       
    41         'size' => 'tiny',
       
    42         'not null' => TRUE,
       
    43         'default' => 0,
       
    44         'description' => 'Boolean indicating whether the module that implements the field type is enabled.',
       
    45       ),
       
    46       'storage_type' => array(
       
    47         'type' => 'varchar',
       
    48         'length' => 128,
       
    49         'not null' => TRUE,
       
    50         'description' => 'The storage backend for the field.',
       
    51       ),
       
    52       'storage_module' => array(
       
    53         'type' => 'varchar',
       
    54         'length' => 128,
       
    55         'not null' => TRUE,
       
    56         'default' => '',
       
    57         'description' => 'The module that implements the storage backend.',
       
    58       ),
       
    59       'storage_active' => array(
       
    60         'type' => 'int',
       
    61         'size' => 'tiny',
       
    62         'not null' => TRUE,
       
    63         'default' => 0,
       
    64         'description' => 'Boolean indicating whether the module that implements the storage backend is enabled.',
       
    65       ),
       
    66       'locked' => array(
       
    67         'type' => 'int',
       
    68         'size' => 'tiny',
       
    69         'not null' => TRUE,
       
    70         'default' => 0,
       
    71         'description' => '@TODO',
       
    72       ),
       
    73       'data' => array(
       
    74         'type' => 'blob',
       
    75         'size' => 'big',
       
    76         'not null' => TRUE,
       
    77         'serialize' => TRUE,
       
    78         'description' => 'Serialized data containing the field properties that do not warrant a dedicated column.',
       
    79       ),
       
    80       'cardinality' => array(
       
    81         'type' => 'int',
       
    82         'size' => 'tiny',
       
    83         'not null' => TRUE,
       
    84         'default' => 0,
       
    85       ),
       
    86       'translatable' => array(
       
    87         'type' => 'int',
       
    88         'size' => 'tiny',
       
    89         'not null' => TRUE,
       
    90         'default' => 0,
       
    91       ),
       
    92       'deleted' => array(
       
    93         'type' => 'int',
       
    94         'size' => 'tiny',
       
    95         'not null' => TRUE,
       
    96         'default' => 0,
       
    97       ),
       
    98     ),
       
    99     'primary key' => array('id'),
       
   100     'indexes' => array(
       
   101       'field_name' => array('field_name'),
       
   102       // Used by field_sync_field_status().
       
   103       'active' => array('active'),
       
   104       'storage_active' => array('storage_active'),
       
   105       'deleted' => array('deleted'),
       
   106       // Used by field_modules_disabled().
       
   107       'module' => array('module'),
       
   108       'storage_module' => array('storage_module'),
       
   109       'type' => array('type'),
       
   110       'storage_type' => array('storage_type'),
       
   111     ),
       
   112   );
       
   113   $schema['field_config_instance'] = array(
       
   114     'fields' => array(
       
   115       'id' => array(
       
   116         'type' => 'serial',
       
   117         'not null' => TRUE,
       
   118         'description' => 'The primary identifier for a field instance',
       
   119       ),
       
   120       'field_id' => array(
       
   121         'type' => 'int',
       
   122         'not null' => TRUE,
       
   123         'description' => 'The identifier of the field attached by this instance',
       
   124       ),
       
   125       'field_name' => array(
       
   126         'type' => 'varchar',
       
   127         'length' => 32,
       
   128         'not null' => TRUE,
       
   129         'default' => ''
       
   130       ),
       
   131       'entity_type' => array(
       
   132         'type' => 'varchar',
       
   133         'length' => 32,
       
   134         'not null' => TRUE,
       
   135         'default' => ''
       
   136       ),
       
   137       'bundle' => array(
       
   138         'type' => 'varchar',
       
   139         'length' => 128,
       
   140         'not null' => TRUE,
       
   141         'default' => ''
       
   142       ),
       
   143       'data' => array(
       
   144         'type' => 'blob',
       
   145         'size' => 'big',
       
   146         'not null' => TRUE,
       
   147         'serialize' => TRUE,
       
   148       ),
       
   149       'deleted' => array(
       
   150         'type' => 'int',
       
   151         'size' => 'tiny',
       
   152         'not null' => TRUE,
       
   153         'default' => 0,
       
   154       ),
       
   155     ),
       
   156     'primary key' => array('id'),
       
   157     'indexes' => array(
       
   158       // Used by field_delete_instance().
       
   159       'field_name_bundle' => array('field_name', 'entity_type', 'bundle'),
       
   160       // Used by field_read_instances().
       
   161       'deleted' => array('deleted'),
       
   162     ),
       
   163   );
       
   164   $schema['cache_field'] = drupal_get_schema_unprocessed('system', 'cache');
       
   165   $schema['cache_field']['description'] = 'Cache table for the Field module to store already built field information.';
       
   166 
       
   167   return $schema;
       
   168 }
       
   169 
       
   170 /**
       
   171  * Utility function: create a field by writing directly to the database.
       
   172  *
       
   173  * This function can be used for databases whose schema is at field module
       
   174  * version 7000 or higher.
       
   175  *
       
   176  * @ingroup update_api
       
   177  */
       
   178 function _update_7000_field_create_field(&$field) {
       
   179   // Merge in default values.`
       
   180   $field += array(
       
   181     'entity_types' => array(),
       
   182     'cardinality' => 1,
       
   183     'translatable' => FALSE,
       
   184     'locked' => FALSE,
       
   185     'settings' => array(),
       
   186     'indexes' => array(),
       
   187     'deleted' => 0,
       
   188     'active' => 1,
       
   189   );
       
   190 
       
   191   // Set storage.
       
   192   $field['storage'] = array(
       
   193     'type' => 'field_sql_storage',
       
   194     'settings' => array(),
       
   195     'module' => 'field_sql_storage',
       
   196     'active' => 1,
       
   197   );
       
   198 
       
   199   // Fetch the field schema to initialize columns and indexes. The field module
       
   200   // is not guaranteed to be loaded at this point.
       
   201   module_load_install($field['module']);
       
   202   $schema = (array) module_invoke($field['module'], 'field_schema', $field);
       
   203   $schema += array('columns' => array(), 'indexes' => array());
       
   204   // 'columns' are hardcoded in the field type.
       
   205   $field['columns'] = $schema['columns'];
       
   206   // 'indexes' can be both hardcoded in the field type, and specified in the
       
   207   // incoming $field definition.
       
   208   $field['indexes'] += $schema['indexes'];
       
   209 
       
   210   // The serialized 'data' column contains everything from $field that does not
       
   211   // have its own column and is not automatically populated when the field is
       
   212   // read.
       
   213   $data = $field;
       
   214   unset($data['columns'], $data['field_name'], $data['type'], $data['active'], $data['module'], $data['storage_type'], $data['storage_active'], $data['storage_module'], $data['locked'], $data['cardinality'], $data['deleted']);
       
   215   // Additionally, do not save the 'bundles' property populated by
       
   216   // field_info_field().
       
   217   unset($data['bundles']);
       
   218 
       
   219   // Write the field to the database.
       
   220   $record = array(
       
   221     'field_name' => $field['field_name'],
       
   222     'type' => $field['type'],
       
   223     'module' => $field['module'],
       
   224     'active' => (int) $field['active'],
       
   225     'storage_type' => $field['storage']['type'],
       
   226     'storage_module' => $field['storage']['module'],
       
   227     'storage_active' => (int) $field['storage']['active'],
       
   228     'locked' => (int) $field['locked'],
       
   229     'data' => serialize($data),
       
   230     'cardinality' => $field['cardinality'],
       
   231     'translatable' => (int) $field['translatable'],
       
   232     'deleted' => (int) $field['deleted'],
       
   233   );
       
   234   // We don't use drupal_write_record() here because it depends on the schema.
       
   235   $field['id'] = db_insert('field_config')
       
   236     ->fields($record)
       
   237     ->execute();
       
   238 
       
   239   // Create storage for the field.
       
   240   field_sql_storage_field_storage_create_field($field);
       
   241 }
       
   242 
       
   243 /**
       
   244  * Utility function: delete a field stored in SQL storage directly from the database.
       
   245  *
       
   246  * To protect user data, this function can only be used to delete fields once
       
   247  * all information it stored is gone. Delete all data from the
       
   248  * field_data_$field_name table before calling by either manually issuing
       
   249  * delete queries against it or using _update_7000_field_delete_instance().
       
   250  *
       
   251  * This function can be used for databases whose schema is at field module
       
   252  * version 7000 or higher.
       
   253  *
       
   254  * @param $field_name
       
   255  *   The field name to delete.
       
   256  *
       
   257  * @ingroup update_api
       
   258  */
       
   259 function _update_7000_field_delete_field($field_name) {
       
   260   $table_name = 'field_data_' . $field_name;
       
   261   if (db_select($table_name)->range(0, 1)->countQuery()->execute()->fetchField()) {
       
   262     $t = get_t();
       
   263     throw new Exception($t('This function can only be used to delete fields without data'));
       
   264   }
       
   265   // Delete all instances.
       
   266   db_delete('field_config_instance')
       
   267     ->condition('field_name', $field_name)
       
   268     ->execute();
       
   269 
       
   270   // Nuke field data and revision tables.
       
   271   db_drop_table($table_name);
       
   272   db_drop_table('field_revision_' . $field_name);
       
   273 
       
   274   // Delete the field.
       
   275   db_delete('field_config')
       
   276     ->condition('field_name', $field_name)
       
   277     ->execute();
       
   278 }
       
   279 
       
   280 
       
   281 /**
       
   282  * Utility function: delete an instance and all its data of a field stored in SQL Storage.
       
   283  *
       
   284  * BEWARE: this function deletes user data from the field storage tables.
       
   285  *
       
   286  * This function is valid for a database schema version 7000.
       
   287  *
       
   288  * @ingroup update_api
       
   289  */
       
   290 function _update_7000_field_delete_instance($field_name, $entity_type, $bundle) {
       
   291   // Delete field instance configuration data.
       
   292   db_delete('field_config_instance')
       
   293     ->condition('field_name', $field_name)
       
   294     ->condition('entity_type', $entity_type)
       
   295     ->condition('bundle', $bundle)
       
   296     ->execute();
       
   297 
       
   298   // Nuke data.
       
   299   db_delete('field_data_' . $field_name)
       
   300     ->condition('entity_type', $entity_type)
       
   301     ->condition('bundle', $bundle)
       
   302     ->execute();
       
   303   db_delete('field_revision_' . $field_name)
       
   304     ->condition('entity_type', $entity_type)
       
   305     ->condition('bundle', $bundle)
       
   306     ->execute();
       
   307 }
       
   308 
       
   309 /**
       
   310  * Utility function: fetch all the field definitions from the database.
       
   311  *
       
   312  * Warning: unlike the field_read_fields() API function, this function returns
       
   313  * all fields by default, including deleted and inactive fields, unless
       
   314  * specified otherwise in the $conditions parameter.
       
   315  *
       
   316  * @param $conditions
       
   317  *   An array of conditions to limit the select query to.
       
   318  * @param $key
       
   319  *   The name of the field property the return array is indexed by. Using
       
   320  *   anything else than 'id' might cause incomplete results if the $conditions
       
   321  *   do not filter out deleted fields.
       
   322  *
       
   323  * @return
       
   324  *   An array of fields matching $conditions, keyed by the property specified
       
   325  *   by the $key parameter.
       
   326  *
       
   327  * @ingroup update_api
       
   328  */
       
   329 function _update_7000_field_read_fields(array $conditions = array(), $key = 'id') {
       
   330   $fields = array();
       
   331   $query = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC))
       
   332     ->fields('fc');
       
   333   foreach ($conditions as $column => $value) {
       
   334     $query->condition($column, $value);
       
   335   }
       
   336   foreach ($query->execute() as $record) {
       
   337     $field = unserialize($record['data']);
       
   338     $field['id'] = $record['id'];
       
   339     $field['field_name'] = $record['field_name'];
       
   340     $field['type'] = $record['type'];
       
   341     $field['module'] = $record['module'];
       
   342     $field['active'] = $record['active'];
       
   343     $field['storage']['type'] = $record['storage_type'];
       
   344     $field['storage']['module'] = $record['storage_module'];
       
   345     $field['storage']['active'] = $record['storage_active'];
       
   346     $field['locked'] = $record['locked'];
       
   347     $field['cardinality'] = $record['cardinality'];
       
   348     $field['translatable'] = $record['translatable'];
       
   349     $field['deleted'] = $record['deleted'];
       
   350 
       
   351     $fields[$field[$key]] = $field;
       
   352   }
       
   353   return $fields;
       
   354 }
       
   355 
       
   356 /**
       
   357  * Utility function: write a field instance directly to the database.
       
   358  *
       
   359  * This function can be used for databases whose schema is at field module
       
   360  * version 7000 or higher.
       
   361  *
       
   362  * @ingroup update_api
       
   363  */
       
   364 function _update_7000_field_create_instance($field, &$instance) {
       
   365   // Merge in defaults.
       
   366   $instance += array(
       
   367     'field_id' => $field['id'],
       
   368     'field_name' => $field['field_name'],
       
   369     'deleted' => 0,
       
   370   );
       
   371 
       
   372   // The serialized 'data' column contains everything from $instance that does
       
   373   // not have its own column and is not automatically populated when the
       
   374   // instance is read.
       
   375   $data = $instance;
       
   376   unset($data['id'], $data['field_id'], $data['field_name'], $data['entity_type'], $data['bundle'], $data['deleted']);
       
   377 
       
   378   $record = array(
       
   379     'field_id' => $instance['field_id'],
       
   380     'field_name' => $instance['field_name'],
       
   381     'entity_type' => $instance['entity_type'],
       
   382     'bundle' => $instance['bundle'],
       
   383     'data' => serialize($data),
       
   384     'deleted' => (int) $instance['deleted'],
       
   385   );
       
   386   $instance['id'] = db_insert('field_config_instance')
       
   387     ->fields($record)
       
   388     ->execute();
       
   389 }
       
   390 
       
   391 /**
       
   392  * @addtogroup updates-6.x-to-7.x
       
   393  * @{
       
   394  */
       
   395 
       
   396 /**
       
   397  * Field update version placeholder.
       
   398  */
       
   399 function field_update_7000() {
       
   400   // Some update helper functions (such as _update_7000_field_create_field())
       
   401   // modify the database directly. They can be used safely only if the database
       
   402   // schema matches the field module schema established for Drupal 7.0 (i.e.
       
   403   // version 7000). This function exists solely to set the schema version to
       
   404   // 7000, so that update functions calling those helpers can do so safely
       
   405   // by declaring a dependency on field_update_7000().
       
   406 }
       
   407 
       
   408 /**
       
   409  * Fix fields definitions created during the d6 to d7 upgrade path.
       
   410  */
       
   411 function field_update_7001() {
       
   412   $fields = _update_7000_field_read_fields();
       
   413   foreach ($fields as $field) {
       
   414     // _update_7000_field_create_field() was broken in d7 RC2, and the fields
       
   415     // created during a d6 to d7 upgrade do not correcly store the 'index'
       
   416     // entry. See http://drupal.org/node/996160.
       
   417 
       
   418     module_load_install($field['module']);
       
   419     $schema = (array) module_invoke($field['module'], 'field_schema', $field);
       
   420     $schema += array('indexes' => array());
       
   421     // 'indexes' can be both hardcoded in the field type, and specified in the
       
   422     // incoming $field definition.
       
   423     $field['indexes'] += $schema['indexes'];
       
   424 
       
   425     // Place the updated entries in the existing serialized 'data' column.
       
   426     $data = db_query("SELECT data FROM {field_config} WHERE id = :id", array(':id' => $field['id']))->fetchField();
       
   427     $data = unserialize($data);
       
   428     $data['columns'] = $field['columns'];
       
   429     $data['indexes'] = $field['indexes'];
       
   430 
       
   431     // Save the new data.
       
   432     $query = db_update('field_config')
       
   433       ->condition('id', $field['id'])
       
   434       ->fields(array('data' => serialize($data)))
       
   435       ->execute();
       
   436   }
       
   437 }
       
   438 
       
   439 /**
       
   440  * @} End of "addtogroup updates-6.x-to-7.x".
       
   441  */
       
   442 
       
   443 /**
       
   444  * @addtogroup updates-7.x-extra
       
   445  * @{
       
   446  */
       
   447 
       
   448 /**
       
   449  * Split the all-inclusive field_bundle_settings variable per bundle.
       
   450  */
       
   451 function field_update_7002() {
       
   452   $settings = variable_get('field_bundle_settings', array());
       
   453   if ($settings) {
       
   454     foreach ($settings as $entity_type => $entity_type_settings) {
       
   455       foreach ($entity_type_settings as $bundle => $bundle_settings) {
       
   456         variable_set('field_bundle_settings_' . $entity_type . '__' . $bundle, $bundle_settings);
       
   457       }
       
   458     }
       
   459     variable_del('field_bundle_settings');
       
   460   }
       
   461 }
       
   462 
       
   463 /**
       
   464  * Add the FieldInfo class to the class registry.
       
   465  */
       
   466 function field_update_7003() {
       
   467   // Empty update to force a rebuild of the registry.
       
   468 }
       
   469 
       
   470 /**
       
   471  * Grant the new "administer fields" permission to trusted users.
       
   472  */
       
   473 function field_update_7004() {
       
   474   // Assign the permission to anyone that already has a trusted core permission
       
   475   // that would have previously let them administer fields on an entity type.
       
   476   $rids = array();
       
   477   $permissions = array(
       
   478     'administer site configuration',
       
   479     'administer content types',
       
   480     'administer users',
       
   481   );
       
   482   foreach ($permissions as $permission) {
       
   483     $rids = array_merge($rids, array_keys(user_roles(FALSE, $permission)));
       
   484   }
       
   485   $rids = array_unique($rids);
       
   486   foreach ($rids as $rid) {
       
   487     _update_7000_user_role_grant_permissions($rid, array('administer fields'), 'field');
       
   488   }
       
   489 }
       
   490 
       
   491 /**
       
   492  * @} End of "addtogroup updates-7.x-extra".
       
   493  */