summaryrefslogtreecommitdiff
path: root/modules/filter/filter.install
blob: 3fab5b44f1990dc5e9f6f6069d969a1ef99096b3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
<?php
// $Id$

/**
 * @file
 * Install, update and uninstall functions for the filter module.
 */

/**
 * Implement hook_schema().
 */
function filter_schema() {
  $schema['filter'] = array(
    'description' => 'Table that maps filters (HTML corrector) to text formats (Filtered HTML).',
    'fields' => array(
      'format' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Foreign key: The {filter_format}.format to which this filter is assigned.',
      ),
      'module' => array(
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'default' => '',
        'description' => 'The origin module of the filter.',
      ),
      'name' => array(
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Name of the filter being referenced.',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'Weight of filter within format.',
      ),
      'status' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'Filter enabled status. (1 = enabled, 0 = disabled)',
      ),
      'settings' => array(
        'type' => 'text',
        'not null' => FALSE,
        'size' => 'big',
        'serialize' => TRUE,
        'description' => 'A serialized array of name value pairs that store the filter settings for the specific format.',
      ),
    ),
    'primary key' => array('format', 'name'),
    'unique keys' => array(
      'fmn' => array('format', 'module', 'name'),
    ),
    'indexes' => array(
      'list' => array('format', 'weight', 'module', 'name'),
    ),
  );
  $schema['filter_format'] = array(
    'description' => 'Stores text formats: custom groupings of filters, such as Filtered HTML.',
    'fields' => array(
      'format' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'description' => 'Primary Key: Unique ID for format.',
      ),
      'name' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Name of the text format (Filtered HTML).',
        'translatable' => TRUE,
      ),
      'cache' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'Flag to indicate whether format is cacheable. (1 = cacheable, 0 = not cacheable)',
      ),
      'weight' => array(
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
        'description' => 'Weight of text format to use when listing.',
      )
    ),
    'primary key' => array('format'),
    'unique keys' => array(
      'name' => array('name'),
    ),
  );

  $schema['cache_filter'] = drupal_get_schema_unprocessed('system', 'cache');
  $schema['cache_filter']['description'] = 'Cache table for the Filter module to store already filtered pieces of text, identified by text format and md5 hash of the text.';

  return $schema;
}

/**
 * @defgroup updates-6.x-to-7.x Filter updates from 6.x to 7.x
 * @{
 */

/**
 * Add a weight column to the filter formats table.
 */
function filter_update_7000() {
  db_add_field('filter_formats', 'weight', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
}

/**
 * Break out "escape HTML filter" option to its own filter.
 */
function filter_update_7001() {
  $result = db_query("SELECT format FROM {filter_formats}")->fetchCol();
  $insert = db_insert('filters')->fields(array('format', 'module', 'delta', 'weight'));

  foreach ($result as $format_id) {
    // Deprecated constants FILTER_HTML_STRIP = 1 and FILTER_HTML_ESCAPE = 2.
    if (variable_get('filter_html_' . $format_id, 1) == 2) {
      $insert->values(array(
        'format' => $format_id,
        'filter' => 'filter',
        'delta' => 4,
        'weight' => 0,
      ));
    }
    variable_del('filter_html_' . $format_id);
  }

  $insert->execute();
}

/**
 * Rename {filters} table to {filter} and {filter_formats} table to {filter_format}.
 */
function filter_update_7002() {
  db_rename_table('filters', 'filter');
  db_rename_table('filter_formats', 'filter_format');
}

/**
 * Remove hardcoded numeric deltas from all filters in core.
 */
function filter_update_7003() {
  // Get an array of the renamed filter deltas, organized by module.
  $renamed_deltas = array(
    'filter' => array(
      '0' => 'filter_html',
      '1' => 'filter_autop',
      '2' => 'filter_url',
      '3' => 'filter_htmlcorrector',
      '4' => 'filter_html_escape',
    ),
    'php' => array(
      '0' => 'php_code',
    ),
  );

  // Rename field 'delta' to 'name'.
  db_drop_unique_key('filter', 'fmd');
  db_drop_index('filter', 'list');
  db_change_field('filter', 'delta', 'name',
    array(
      'type' => 'varchar',
      'length' => 32,
      'not null' => TRUE,
      'default' => '',
      'description' => 'Name of the filter being referenced.',
    ),
    array(
      'unique keys' => array(
        'fmn' => array('format', 'module', 'name'),
      ),
      'indexes' => array(
        'list' => array('format', 'weight', 'module', 'name'),
      ),
    )
  );

  // Loop through each filter and make changes to the core filter table.
  foreach ($renamed_deltas as $module => $deltas) {
    foreach ($deltas as $old_delta => $new_delta) {
    	db_update('filter')
    	  ->fields(array('name', $new_delta))
    	  ->condition('module', $module)
    	  ->condition('name', $old_delta)
    	  ->execute();
    }
  }
}

/**
 * Move filter settings storage into {filter} table.
 *
 * - Remove {filter}.fid.
 * - Add (format, name) as primary key for {filter}.
 * - Add {filter}.status.
 * - Add {filter}.settings.
 */
function filter_update_7004() {
  db_drop_field('filter', 'fid');
  db_add_primary_key('filter', array('format', 'name'));
  db_add_field('filter', 'status',
    array(
      'type' => 'int',
      'not null' => TRUE,
      'default' => 0,
      'description' => 'Filter enabled status. (1 = enabled, 0 = disabled)',
    )
  );
  db_add_field('filter', 'settings',
    array(
      'type' => 'text',
      'not null' => FALSE,
      'size' => 'big',
      'serialize' => TRUE,
      'description' => 'A serialized array of name value pairs that store the filter settings for the specific format.',
    )
  );

  // Enable all existing filters ({filter} contained only enabled previously).
  db_update('filter')
    ->fields('status', '1')
    ->execute();

  // Move filter settings from system variables into {filter}.settings.
  $filters = db_query("SELECT * FROM {filter} WHERE module = :name", array(':name' => 'filter'));
  foreach ($filters as $filter) {
    $settings = array();
    if ($filter->name == 'filter_html') {
      if ($setting = variable_get("allowed_html_{$filter->format}", NULL)) {
        $settings['allowed_html'] = $setting;
        variable_del("allowed_html_{$filter->format}");
      }
      if ($setting = variable_get("filter_html_help_{$filter->format}", NULL)) {
        $settings['filter_html_help'] = $setting;
        variable_del("filter_html_help_{$filter->format}");
      }
      if ($setting = variable_get("filter_html_nofollow_{$filter->format}", NULL)) {
        $settings['filter_html_nofollow'] = $setting;
        variable_del("filter_html_nofollow_{$filter->format}");
      }
    }
    elseif ($filter->name == 'filter_url') {
      if ($setting = variable_get("filter_url_length_{$filter->format}", NULL)) {
        $settings['filter_url_length'] = $setting;
        variable_del("filter_url_length_{$filter->format}");
      }
    }
    if (!empty($settings)) {
    	db_upddate('filter')
    	  ->fields(array('settings' => serialize($settings)))
    	  ->condition('format', $filter->format)
    	  ->condition('name', $filter->name)
    	  ->execute();
    }
  }
}

/**
 * Integrate text formats with the user permissions system.
 *
 * This function converts text format role assignments to use the new text
 * format permissions introduced in Drupal 7, creates a fallback (plain text)
 * format that is available to all users, and explicitly sets the text format
 * in cases that used to rely on a single site-wide default.
 */
function filter_update_7005() {

  // Move role data from the filter system to the user permission system.
  $all_roles = array_keys(user_roles());
  $default_format = variable_get('filter_default_format', 1);
  $result = db_query("SELECT * FROM {filter_format}");
  foreach ($result as $format) {
    // We need to assign the default format to all roles (regardless of what
    // was stored in the database) to preserve the behavior of the site at the
    // moment of the upgrade.
    $format_roles = ($format->format == $default_format ? $all_roles : explode(',', $format->roles));
    foreach ($format_roles as $format_role) {
      if (in_array($format_role, $all_roles)) {
        user_role_grant_permissions($format_role, array(filter_permission_name($format)));
      }
    }
  }

  // Drop the roles field from the {filter_format} table.
  db_drop_field('filter_format', 'roles');

  // Add a fallback text format which outputs plain text and appears last on
  // the list for all users. Generate a unique name for it, starting with
  // "Plain text".
  $start_name = 'Plain text';
  $format_name = $start_name;
  while ($format = db_query('SELECT format FROM {filter_format} WHERE name = :name', array(':name' => $format_name))->fetchField()) {
    $id = empty($id) ? 1 : $id + 1;
    $format_name = $start_name . ' ' . $id;
  }
  $fallback_format = new stdClass();
  $fallback_format->name = $format_name;
  $fallback_format->cache = 1;
  $fallback_format->weight = 1;
  // This format should output plain text, so we escape all HTML and apply the
  // line break filter only.
  $fallback_format->filters = array(
    'filter_html_escape' => array('status' => 1),
    'filter_autop' => array('status' => 1),
  );
  filter_format_save($fallback_format);
  variable_set('filter_fallback_format', $fallback_format->format);
  drupal_set_message('A new <em>Plain text</em> format has been created which will be available to all users. You can configure this text format on the <a href="' . url('admin/config/content/formats/' . $fallback_format->format) . '">text format configuration page</a>.');

  // Move the former site-wide default text format to the top of the list, so
  // that it continues to be the default text format for all users.
  db_update('filter_format')
    ->fields(array('weight' => -1))
    ->condition('format', $default_format)
    ->execute();

  // It was previously possible for a value of "0" to be stored in database
  // tables to indicate that a particular piece of text should be filtered
  // using the default text format. Therefore, we have to convert all such
  // instances (in Drupal core) to explicitly use the appropriate format.
  // Note that the update of the node body field is handled separately, in
  // node_update_7006().
  foreach (array('block_custom', 'comment') as $table) {
    if (db_table_exists($table)) {
      db_update($table)
        ->fields(array('format' => $default_format))
        ->condition('format', 0)
        ->execute();
    }
  }

  // We do not delete the 'filter_default_format' variable, since other modules
  // may need it in their update functions.
  // @todo This variable can be deleted in Drupal 8.
}

/**
 * @} End of "defgroup updates-6.x-to-7.x"
 * The next series of updates should start at 8000.
 */