taxonomy_display.module 13.8 KB
Newer Older
Cody Craven's avatar
Cody Craven committed
1
2
3
4
5
6
7
8
<?php
// $Id$

/**
 * @file
 * Hooks for the taxonomy display module.
 */

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
 * Helper function; delete taxonomy display data.
 *
 * @param string $machine_name
 *   The machine name of the vocabulary's taxonomy display data to remove.
 * @param string|NULL|FALSE $watchdog_message
 *   Provide a watchdog message as a string. If null then a generic default
 *   message will be used. If false then no watchdog message will be recorded.
 * @param array $watchdog_variables
 *   Variables for substitution in the watchdog message.
 * @param int $watchdog_severity
 *   One of the defined watchdog constant severities: WATCHDOG_EMERGENCY,
 *   WATCHDOG_ALERT, WATCHDOG_CRITICAL, WATCHDOG_ERROR, WATCHDOG_WARNING,
 *   WATCHDOG_NOTICE, WATCHDOG_INFO, WATCHDOG_DEBUG. Defaults to
 *   WATCHDOG_NOTICE.
 *
 * @return void
26
27
 *
 * @todo test this works
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 */
function taxonomy_display_delete_taxonomy_dislpay($machine_name, $watchdog_message = NULL, $watchdog_variables = array(), $watchdog_severity = WATCHDOG_NOTICE) {
  // Delete our display record for the term being removed.
  $count = (bool) db_delete('taxonomy_display')
    ->condition('machine_name', $machine_name)
    ->execute();

  // If a record was deleted then log it in watchdog.
  if ($count && $watchdog_message !== FALSE) {
    if (empty($watchdog_message)) {
      $watchdog_message = 'Taxonomy display settings deleted for %name.';
      $watchdog_variables = array('%name' => $machine_name);
    }
    watchdog('taxonomy_display', $watchdog_message, $watchdog_variables, $watchdog_severity);
  }
}

/**
 * Helper function; retrieve taxonomy display settings from the database.
 *
 * @param string $machine_name
 *   The machine name of the vocabulary's taxonomy display data to fetch.
 *
51
52
 * @return array
 *   Return associated array.
53
54
 */
function taxonomy_display_fetch_taxonomy_display($machine_name) {
55
  $result = db_select('taxonomy_display', 'td')
56
57
58
59
    ->fields('td')
    ->condition('machine_name', $machine_name)
    ->execute()
    ->fetchAssoc();
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

  // Set defaults if a result was not found
  if (!$result) {
    return array(
      'machine_name' => $machine_name,
      'term_display_plugin' => 'TaxonomyDisplayTermDisplayHandlerCore',
      'term_display_options' => NULL,
      'associated_display_plugin' => 'TaxonomyDisplayAssociatedDisplayHandlerCore',
      'associated_display_options' => NULL,
      'no_record' => TRUE,
    );
  }

  // Prepare term display data for use.
  if (!class_exists($result['term_display_plugin'], TRUE)) {
    watchdog('taxonomy_display', 'The taxonomy term display plugin assigned to the %name vocabulary is missing, Drupal default settings were used instead.', array('%name' => $machine_name), WATCHDOG_WARNING);

    $result['term_display_plugin'] = 'TaxonomyDisplayTermDisplayHandlerCore';
    $result['term_display_options'] = NULL;
    $result['term_plugin_missing'] = TRUE;
  }
  else {
    $result['term_display_options'] = unserialize($result['term_display_options']);
  }

  // Prepare associated content display data for use.
  if (!class_exists($result['associated_display_plugin'], TRUE)) {
    watchdog('taxonomy_display', 'The taxonomy associated content plugin assigned to the %name vocabulary is missing, Drupal default settings were used instead.', array('%name' => $machine_name), WATCHDOG_WARNING);

    $result['associated_display_plugin'] = 'TaxonomyDisplayAssociatedDisplayHandlerCore';
    $result['associated_display_options'] = NULL;
    $result['associated_plugin_missing'] = TRUE;
  }
  else {
    $result['associated_display_options'] = unserialize($result['associated_display_options']);
  }

  return $result;
98
99
}

Cody Craven's avatar
Cody Craven committed
100
101
102
103
/**
 * Implements hook_form_FORM_ID_alter().
 */
function taxonomy_display_form_field_ui_display_overview_form_alter(&$form, &$form_state) {
104
105
  form_load_include($form_state, 'inc', 'taxonomy_display', 'taxonomy_display.admin');
  taxonomy_display_admin_form($form, $form_state);
Cody Craven's avatar
Cody Craven committed
106
107
}

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * Helper function; retrieve the plugin fieldset from configuration form.
 *
 * This is set up just so we don't break implementing modules in the future if
 * we change the form placement for some reason.
 *
 * @param array $form
 *   Form array.
 * @param string $fetch
 *   String either 'term' or 'associated'.
 *
 * @return array|FALSE
 *   Returns the form fieldset if valid, otherwise boolean false.
 */
function taxonomy_display_form_fieldset(&$form, $fetch = 'term') {
  if (isset($form['additional_settings']['taxonomy_display'][$fetch . '_display_form'])) {
    return $form['additional_settings']['taxonomy_display'][$fetch . '_display_form'];
  }

  return FALSE;
}

Cody Craven's avatar
Cody Craven committed
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
/**
 * Implements of hook_menu_alter().
 */
function taxonomy_display_menu_alter(&$items) {
  $items['taxonomy/term/%taxonomy_term']['page callback'] = 'taxonomy_display_taxonomy_term_page';
  $items['taxonomy/term/%taxonomy_term']['title callback'] = 'taxonomy_display_taxonomy_term_title';
  $items['taxonomy/term/%taxonomy_term']['file'] = 'taxonomy_display.module';
  $items['taxonomy/term/%taxonomy_term']['module'] = 'taxonomy_display';
}

/**
 * Implements hook_permission().
 */
function taxonomy_display_permission() {
  $permissions = array(
    'administer taxonomy display' => array(
      'title' => t('Administer taxonomy display'),
      'description' => t('Change the display settings for taxonomy term pages in each vocabulary.'),
    ),
  );
  return $permissions;
}

/**
 * Retrieve an array of Taxonomy Display plugins.
 * 
 * @param null|string $type
 *   Only retrieve plugins of a specific type, expected values 'term' and 
 *   'associated'. By default, NULL, this will return an array with both.
 * 
 * @return array|void
 *   If an expected value is provided for $type, or no value is provided, an
 *   array will be returned. If an unexpected value is provided nothing will be
 *   returned.
 */
function taxonomy_display_plugins($type = NULL) {
  // TODO: Add caching, likely not a big issue as this is only called in admin
  // areas, but still.

  $plugins = module_invoke_all('taxonomy_display_plugins');

  // Expose our retrieved plugins to altering.
  drupal_alter('taxonomy_display_plugins', $plugins);

  if (is_null($type)) {
    return $plugins;
  }

  if (array_key_exists($type, $plugins)) {
    return $plugins[$type];
  }
}

/**
 * Implements hook_taxonomy_display_plugins().
 *
 * Taxonomy Display invokes this hook when looking for plugins for displaying
 * taxonomy term and taxonomy term's associated content.
 */
function taxonomy_display_taxonomy_display_plugins() {
  // To add custom plugins in your own hook implementation return an array with
  // the format below:
192
  $plugins = array(
Cody Craven's avatar
Cody Craven committed
193
194
195
    // In the two arrays 'associated' and 'term', provide the implementing class
    // name of your handler as the keys and the text to be displayed to the user
    // for display as the value.
196
197
198
    // 
    // Note: All of the class's files are in our module's .info files array so
    //   that auto loading works.
Cody Craven's avatar
Cody Craven committed
199
    'associated' => array(
200
201
      'TaxonomyDisplayAssociatedDisplayHandlerCore' => t('Core'),
      'TaxonomyDisplayAssociatedDisplayHandlerHidden' => t('Hidden'),
Cody Craven's avatar
Cody Craven committed
202
203
204
205
206
207
    ),
    'term' => array(
      'TaxonomyDisplayTermDisplayHandlerCore' => t('Core'),
      'TaxonomyDisplayTermDisplayHandlerHidden' => t('Hidden'),
    ),
  );
208
209
210
211
212
213
214

  // Conditional plugins
  if (module_exists('views')) {
    $plugins['associated']['TaxonomyDisplayAssociatedDisplayHandlerViews'] = t('Views');
  }

  return $plugins;
Cody Craven's avatar
Cody Craven committed
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
/**
 * Helper function; save a taxonomy display record in the database.
 *
 * @param string $machine_name
 *   The machine name of the vocabulary's taxonomy display data to save.
 * @param array $save_data
 *
 * @param string|NULL|FALSE $watchdog_message
 *   Provide a watchdog message as a string. If null then a generic default
 *   message will be used. If false then no watchdog message will be recorded.
 * @param array $watchdog_variables
 *   Variables for substitution in the watchdog message.
 * @param int $watchdog_severity
 *   One of the defined watchdog constant severities: WATCHDOG_EMERGENCY,
 *   WATCHDOG_ALERT, WATCHDOG_CRITICAL, WATCHDOG_ERROR, WATCHDOG_WARNING,
 *   WATCHDOG_NOTICE, WATCHDOG_INFO, WATCHDOG_DEBUG. Defaults to
 *   WATCHDOG_NOTICE.
 *
 * @return void
 */
function taxonomy_display_save_taxonomy_display($machine_name, $save_data = array(), $watchdog_message = NULL, $watchdog_variables = array(), $watchdog_severity = WATCHDOG_NOTICE) {
  // Prepare the fields to be used for the insert or update query.
  $query_fields = array();
  foreach($save_data as $k => $v) {
    switch ($k) {
      case 'machine_name':
      case 'term_display_plugin':
      case 'associated_display_plugin':
        $query_fields[$k] = $v;
        break;
      case 'term_display_options':
      case 'associated_display_options':
        $query_fields[$k] = serialize($v);
        break;
      default:
        break;
    }
  }
  // Allow other modules to alter our fields before they are inserted/updated.
  drupal_alter('taxonomy_display_save_fields', $query_fields, $save_data);

  // Retrieve the machine name, tells us whether to insert or update.
  $update = taxonomy_display_fetch_taxonomy_display($machine_name);

  // Perform our save
  try {
    // If update
264
    if (!isset($update['no_record'])) {
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
      // Do not proceed if there are no fields to update.
      if (empty($query_fields)) {
        return;
      }

      // Query
      $count = (bool) db_update('taxonomy_display')
        ->fields($query_fields)
        ->condition('machine_name', $machine_name)
        ->execute();

      if ($count && $watchdog_message !== FALSE) {
        if (empty($watchdog_message)) {
          $watchdog_message = 'Taxonomy display vocabulary data updated for %machine_name.';
          $watchdog_variables = array('%machine_name' => $machine_name);
        }
        watchdog('taxonomy_display', $watchdog_message, $watchdog_variables, $watchdog_severity);
      }
    }
    // Else insert
    else {
      // If the record is being inserted we do not want to force the user to
      // supply machine_name twice for no reason, if they know it is an insert.
      if (!isset($query_fields['machine_name'])) {
        $query_fields['machine_name'] = $machine_name;
      }

      // Query
      $value = db_insert('taxonomy_display')
        ->fields($query_fields)
        ->execute();

      if ($watchdog_message !== FALSE) {
        if (empty($watchdog_message)) {
          $watchdog_message = 'Taxonomy display vocabulary data created for %machine_name.';
          $watchdog_variables = array('%machine_name' => $machine_name);
        }
        watchdog('taxonomy_display', $watchdog_message, $watchdog_variables, $watchdog_severity);
      }
    }
  }
  catch(Exception $e) {
    drupal_set_message(t('Taxonomy display data save failed. Message = %message, query= %query',
      array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error');
  }
}

Cody Craven's avatar
Cody Craven committed
312
313
314
315
316
317
318
319
320
321
/**
 * Page callback; displays all nodes associated with a term.
 *
 * @param $term
 *   A term object.
 *
 * @return
 *   The page content.
 */
function taxonomy_display_taxonomy_term_page($term) {
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
  // Build breadcrumb like core does, we could make this alterable in the future
  // especially if something like custom breadcrumbs tells us how they would
  // like to alter this.
  // @see taxonomy_term_page()
  $current = (object) array(
    'tid' => $term->tid,
  );
  $breadcrumb = array();
  while ($parents = taxonomy_get_parents($current->tid)) {
    $current = array_shift($parents);
    $breadcrumb[] = l($current->name, 'taxonomy/term/' . $current->tid);
  }
  $breadcrumb[] = l(t('Home'), NULL);
  $breadcrumb = array_reverse($breadcrumb);
  drupal_set_breadcrumb($breadcrumb);
  drupal_add_feed('taxonomy/term/' . $term->tid . '/feed', 'RSS - ' . $term->name);

  // Build our content
  $build = array();

  $display_settings = taxonomy_display_fetch_taxonomy_display($term->vocabulary_machine_name);

  // Term display
  $term_display = new $display_settings['term_display_plugin'];
  $build['term_heading'] = $term_display->displayTerm($term, $display_settings['term_display_options']);

348
  // Associated content display
349
350
  $associated_display = new $display_settings['associated_display_plugin'];
  $build = array_merge($build, $associated_display->displayAssociated($term, $display_settings['associated_display_options']));
Cody Craven's avatar
Cody Craven committed
351
352
353
354
355
356
357

  return $build;
}

/**
 * Title callback; display title for term pages.
 *
358
359
360
361
 * As of now we do not do anything with this. If we come up with something that
 * would be helpful or requested we can add it. This is simply to make all of
 * the hook_menu_alter functions we changed point to the same module.
 *
Cody Craven's avatar
Cody Craven committed
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
 * @param $term
 *   A term object.
 *
 * @return
 *   The term name to be used as the page title.
 */
function taxonomy_display_taxonomy_term_title($term) {
  return taxonomy_term_title($term);
}

/**
 * Implements taxonomy_vocabulary_delete().
 *
 * @todo test this works
 */
function taxonomy_display_taxonomy_vocabulary_delete($vocabulary) {
378
379
380
381
  // Delete our display record for the vocabulary being removed.
  taxonomy_display_delete_taxonomy_dislpay($vocabulary->machine_name,
      'Taxonomy display settings deleted for %name in response to the vocabulary being deleted.',
      array('%name' => $vocabulary->machine_name));
Cody Craven's avatar
Cody Craven committed
382
383
384
385
386
387
388
389
390
391
}

/**
 * Implements taxonomy_vocabulary_update().
 *
 * @todo test this works
 */
function taxonomy_display_taxonomy_vocabulary_update($vocabulary) {
  // If the machine name is changed update our display table so that the display
  // settings still apply.
392
393
394
395
396
397
  if ($vocabulary->old_machine_name != $vocabulary->machine_name &&
      taxonomy_display_fetch_taxonomy_display($vocabulary->old_machine_name)) {
    taxonomy_display_save_taxonomy_dislpay($vocabulary->old_machine_name,
        array('machine_name' => $vocabulary->machine_name),
        'Taxonomy display vocabulary changed machine name from %old to %new in response to the vocabulary machine name being altered.',
        array('%old' => $vocabulary->old_machine_name, '%new' => $vocabulary->machine_name));
Cody Craven's avatar
Cody Craven committed
398
399
  }
}