Completed
Push — 7.x-3.x ( d8666b...d48267 )
by Devin
03:54
created

modules/commons/commons_bw/commons_bw.module::commons_bw_system_info_alter()   D

Complexity

Conditions 9
Paths 16

Size

Total Lines 37
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 14
nc 16
nop 3
dl 0
loc 37
rs 4.909
c 0
b 0
f 0
1
<?php
2
/**
3
 * @file
4
 * Code for the Commons Browsing Widget feature.
5
 */
6
7
include_once 'commons_bw.features.inc';
8
9
/**
10
 * Implements hook_hook_info().
11
 */
12
function commons_bw_hook_info() {
13
  $hooks = array(
14
    'commons_bw_group_widget',
15
    'commons_bw_create_all_widget',
16
  );
17
18
  return array_fill_keys($hooks, array('group' => 'commons'));
19
}
20
21
/**
22
 * Implements hook_system_info_alter().
23
 */
24
function commons_bw_system_info_alter(&$info, $file, $type) {
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
25
  // Commons BW dynamically adds the title_field field to content types that
26
  // request it.
27
  // We must add a corresponding line for each field instance to commons_bw.info
28
  // so that Features is aware of the instance and can successfully revert the
29
  // field_instance component back to its default state.
30
  if ($file->name == 'commons_bw') {
31
    foreach (node_type_get_types() as $node_type_object) {
32
      $node_type = $node_type_object->type;
33
34
      if (commons_bw_node_auto_title_instance($node_type)) {
35
        $info['features']['field_instance'][] = "node-$node_type-title_field";
36
      }
37
    }
38
  }
39
40
  // Dynamically adding a field to a content type results in features
41
  // automatically detecting Commons BW as a dependency.
42
  // We manually exclude the dependency in order to prevent the content type
43
  // modules from appearing overridden and to allow them to be used
44
  // independently of Commons BW.
45
  $node_types = &drupal_static(__FUNCTION__);
46
47
  if (!isset($node_types)) {
48
    foreach (module_implements('node_info') as $module) {
49
      $node_types[$module] = call_user_func($module . '_node_info');
50
    }
51
  }
52
53
  if (isset($node_types[$file->name])) {
54
    foreach ($node_types[$file->name] as $node_type => $node_info) {
55
      if (commons_bw_node_auto_title_instance($node_type)) {
56
        $info['features_exclude']['dependencies']['commons_bw'] = 'commons_bw';
57
      }
58
    }
59
  }
60
}
61
62
/**
63
 * Implements hook_modules_enabled().
64
 */
65
function commons_bw_modules_enabled($modules) {
66
  // Ensure that dynamically added title_field fields are in the default state
67
  // when modules that provide content types are enabled.
68
  foreach ($modules as $module) {
69
    if (module_hook($module, 'node_info')) {
70
      features_revert(array('commons_bw' => array('field_instance')));
71
    }
72
  }
73
}
74
75
/**
76
 * Implements hook_forms().
77
 *
78
 * The bundle is added to the partial node form ID, to prevent duplicate IDs on
79
 * the same page, but all of the partial forms are built with the same function.
80
 */
81
function commons_bw_forms($form_id, $args) {
0 ignored issues
show
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
82
  $forms = array();
83
84
  if (strpos($form_id, 'commons_bw_partial_node_form__') === 0) {
85
    $forms[$form_id] = array(
86
      'callback' => 'commons_bw_partial_node_form',
87
    );
88
  }
89
90
  return $forms;
91
}
92
93
/**
94
 * Implements hook_form_FORM_ID_alter().
95
 */
96
function commons_bw_form_views_exposed_form_alter(&$form, &$form_state, $form_id) {
0 ignored issues
show
Unused Code introduced by
The parameter $form_state is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $form_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
97
  // Implements tweaks to exposed filters and sorts per the Commons designs.
98
  if (strpos($form['#id'],'views-exposed-form-commons-bw') === 0) {
99
    // Remove the sort order (eg, descending vs ascending).
100
    $form['sort_order']['#access'] = FALSE;
101
    $form['sort_by']['#title'] = t('Sorted by');
102
  }
103
}
104
105
/**
106
 * Implements hook_form_FORM_ID_alter().
107
 *
108
 * Add a setting to group content fields, to determine whether they will be
109
 * displayed on the mini node form of the browsing widget.
110
 */
111
function commons_bw_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
0 ignored issues
show
Unused Code introduced by
The parameter $form_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
112
  if (!og_is_group_content_type($form['instance']['entity_type']['#value'], $form['instance']['bundle']['#value'])) {
113
    return;
114
  }
115
116
  // See if we're building for the first time, or getting pre-saved values.
117
  $field_name = $form['#field']['field_name'];
118
119
  if(!empty($form_state['field'][$field_name][LANGUAGE_NONE]['instance']['display_in_partial_form'])) {
120
    $display_default = $form_state['field'][$field_name][LANGUAGE_NONE]['instance']['display_in_partial_form'];
121
  }
122
  else if (isset($form_state['build_info']['args'][0]['display_in_partial_form'])) {
123
    $display_default = $form_state['build_info']['args'][0]['display_in_partial_form'];
124
  }
125
  else {
126
    $display_default = FALSE;
127
  }
128
129
  $form['instance']['display_in_partial_form'] = array(
130
    '#type' => 'checkbox',
131
    '#title' => t('Display in the browsing widget mini-form'),
132
    '#default_value' => $display_default,
133
  );
134
}
135
136
/**
137
 * Partial node form for the browsing widget.
138
 */
139
function commons_bw_partial_node_form($form, &$form_state, $bundle, $group_id = NULL) {
140
  global $user;
141
  global $language;
142
143
  if (!$group_id) {
144
    // Reset the og_field_widget_form cache because otherwise it ignores
145
    // multiple tries to render the same group audience widget (We have the
146
    // same group audience widget on the All and Posts tabs, when displaying
147
    // this form without group context).
148
    drupal_static_reset('og_field_widget_form');
149
  }
150
151
  if ($group_id) {
152
    $form_state['group_id'] = $group_id;
153
  }
154
155
  $instances = field_info_instances('node', $bundle);
156
157
  // Remove all fields except those marked as "display_in_partial_form".
158
  foreach($instances as $field_name => $instance) {
159
    if (empty($instance['display_in_partial_form'])) {
160
      unset($instances[$field_name]);
161
    }
162
  }
163
164
  // Make sure there's a field left to display.
165
  if (empty($instances)) {
166
    return $form;
167
  }
168
169
  // Create a dummy node for field_attach_form().
170
  $node = new stdClass();
171
  $node->type = $bundle;
172
  node_object_prepare($node);
173
174
  if (module_exists('locale')) {
175
    if (locale_multilingual_node_type($node->type)) {
176
      $node->language = $language->language;
177
    }
178
    else {
179
      $default = language_default();
180
      $node->language = $default->language;
181
    }
182
  }
183
  else {
184
    $node->language = LANGUAGE_NONE;
185
  }
186
187
  field_attach_form('node', $node, $form, $form_state, entity_language('node', $node));
188
189
  foreach(element_children($form) as $field_name) {
190
    if (empty($instances[$field_name])) {
191
      $form[$field_name]['#access'] = FALSE;
192
    }
193
  }
194
195
  if (!empty($form['#metatags'])) {
196
    unset($form['#metatags']);
197
  }
198
199
  // When not in a group context, enable the group audience widget.
200
  $form[OG_AUDIENCE_FIELD]['#weight'] = 100;
201
  $form[OG_AUDIENCE_FIELD]['#access'] = !$group_id;
202
203
  // Add a default form title.
204
  $form['title'] = array(
205
    '#markup' => t('Create content'),
206
    '#weight' => -100,
207
  );
208
209
  // Display the user's picture.
210
  $wrapper = entity_metadata_wrapper('user', $user);
211
  $path = empty($user->picture) ? variable_get('user_picture_default') : $wrapper->value()->picture->uri;
212
  $form['user_picture'] = array(
213
    '#theme' => 'image_style',
214
    '#style_name' => '50x50_avatar',
215
    '#path' => $path,
216
    '#prefix' => '<div class="user-picture">',
217
    '#suffix' => '</div>',
218
    '#weight' => -20,
219
  );
220
221
  $form['actions'] = array(
222
    '#type' => 'actions',
223
    '#weight' => 200,
224
  );
225
  $form['actions']['submit'] = array(
226
    '#type' => 'submit',
227
    '#value' => t('Save'),
228
  );
229
230
  // Attach the browsing widget JS and give it a higher weight than
231
  // quicktabs.js.
232
  $form['#attached']['js'][] = array(
233
    'data' => drupal_get_path('module', 'commons_bw') . '/js/partial_node_form.js',
234
    'type' => 'file',
235
    'weight' => 100,
236
  );
237
238
  // Add in some descriptive classes for css down the line.
239
  $form['#attributes']['class'][] = 'node';
240
  $form['#attributes']['class'][] = 'commons-bw-partial-node-form';
241
  $form['#attributes']['class'][] = 'commons-bw-partial-node-form-' . $bundle;
242
243
  // Add a link to the full node form.
244
  $form['full_form'] = array(
245
    '#theme' => 'link',
246
    '#text' => t('Go to full form'),
247
    '#path' => 'node/add/' . str_replace('_', '-', $bundle),
248
    '#options' => array(
249
      'attributes' => array('class' => array('full-form')),
250
      'html' => FALSE,
251
    ),
252
    '#weight' => 100,
253
  );
254
255
  if ($group_id) {
256
    $form['full_form']['#options']['query'] = array(OG_AUDIENCE_FIELD => $group_id);
257
  }
258
259
  // Add the commons_bw after build first, in case other pre-renders needs need
260
  // to address fields by there CSS ID.
261
  array_unshift($form['#pre_render'], 'commons_bw_partial_node_form_after_build');
262
  $form['#validate'][] = 'commons_bw_partial_node_form_validate';
263
264
  return $form;
265
}
266
267
/**
268
 * After-build call-back. See commons_bw_partial_node_form().
269
 */
270
function commons_bw_partial_node_form_after_build($form) {
271
  $bundle = $form['#bundle'];
272
273
  // Set the form action to the form's tab.
274
  $tabs = commons_bw_get_tab_definitions();
275
276
  // Search for the tab displaying the current bundle.
277
  foreach ($tabs as $tab_id => $settings) {
278
    if ($settings['bundle'] == $bundle) {
279
      break;
280
    }
281
  }
282
283
  $form['#action'] = url(current_path(), array('query' => array('qt-commons_bw' => $tab_id)));
0 ignored issues
show
Bug introduced by
The variable $tab_id seems to be defined by a foreach iteration on line 277. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
284
285
  return $form;
286
}
287
288
/**
289
 * Validation handler; Attach the node validation to the partial node form.
290
 */
291
function commons_bw_partial_node_form_validate($form, $form_state) {
292
  $node = $form['#entity'];
293
294
  field_attach_validate('node', $node);
295
  node_validate($node, $form, $form_state);
296
297
  if ((!module_exists('commons_trusted_contacts') || (module_exists('commons_trusted_contacts') && !module_exists('og_access'))) && empty($form_state['group_id']) && empty($form_state['values'][OG_AUDIENCE_FIELD][LANGUAGE_NONE][0])) {
298
    form_set_error(OG_AUDIENCE_FIELD, t('Please enter one or more groups where this content will be posted.'));
299
    return FALSE;
300
  }
301
}
302
303
/**
304
 * Submit handler; Create a node from the partial node form.
305
 */
306
function commons_bw_partial_node_form_submit($form, $form_state) {
307
  $node = $form['#entity'];
308
309
  node_submit($node);
310
311
  // Mark the node as created with the partial form
312
  $node->partial_node_form = TRUE;
313
  field_attach_submit('node', $node, $form, $form_state);
314
315
  $wrapper = entity_metadata_wrapper('node', $node);
316
317
  // If the node has a body and doesn't has a title, create a title from the
318
  // body.
319
  if ((empty($wrapper->title_field) || !$wrapper->title_field->value()) && empty($node->title)) {
320
    if (!empty($wrapper->body) && $wrapper->body->value()) {
321
      $title = htmlspecialchars_decode($wrapper->body->value->value());
322
323
      // Strip tags and whitespaces.
324
      $title = preg_replace('/[\t\n\r\0\x0B]/', '', strip_tags($title));
325
326
      // Shorten the title.
327
      $node->title = truncate_utf8($title, 30, TRUE, TRUE);
328
    }
329
  }
330
331
  // Set the group audience.
332
  if (!empty($form_state['group_id'])) {
333
    $wrapper->{OG_AUDIENCE_FIELD}->set(array($form_state['group_id']));
334
  }
335
336
  $node->form_state = $form_state;
337
338
  $wrapper->save();
339
340
  // Notify about the node creation.
341
  $arguments = array('@type' => node_type_get_name($node), '%title' => $node->title);
342
343
  drupal_set_message(t('@type %title has been created.', $arguments));
344
}
345
346
/**
347
 * Get a list of modules that add content to a particular type of widget.
348
 *
349
 * The only currently supported widget type is 'group', but this
350
 * could be extended to support other entities.
351
 *
352
 * @param $widget_type
353
 *   An optional type of widget to restrict results to, defaults to 'group'.
354
 *
355
 * @return array
356
 *   An array of return values of the hook implementations.
357
 */
358
function commons_bw_get_tab_definitions($widget_type = 'group') {
359
  $hook_name = 'commons_bw_' . $widget_type . '_widget';
360
361
  $tabs = module_invoke_all($hook_name);
362
363
  drupal_alter($hook_name, $tabs);
364
365
  return $tabs;
366
}
367
368
/**
369
 * Helper function to determine whether Commons_BW should define a title field
370
 * instance on behalf of a content type.
371
 *
372
 * @param $node_type
373
 *   The type of the node to check auto title settings for.
374
 *
375
 * @return boolean
376
 *   The value of the auto title setting if available, TRUE otherwise.
377
 */
378
function commons_bw_node_auto_title_instance($node_type) {
379
  $commons_groups_entity_types = commons_groups_get_group_content_entity_types();
380
381
  return isset($commons_groups_entity_types['node'][$node_type]['auto_title_instance']) ? $commons_groups_entity_types['node'][$node_type]['auto_title_instance'] : TRUE;
382
}
383
384
/**
385
 * Provides a styled content creation dropdown widget for the 'all' tab of the
386
 * group homepage browsing widget.
387
 *
388
 * @param $group
389
 *   The group node associated with the group homepage.
390
 *
391
 * @return string
392
 *   The content creation dropdown widget HTML.
393
 */
394
function commons_bw_create_all_widget($group) {
395
  $links = array();
396
397
  // Collect definitions from implementing modules.
398
  $items = module_invoke_all('commons_bw_create_all_widget', $group);
399
  uasort($items, 'element_sort');
400
401
  foreach ($items as $module => $item) {
402
    $links[] = $item['link'] . ' ' . $item['text'];
403
404
    // Populate the default content creation link.
405
    if (isset($item['default']) && $item['default']) {
406
      $default = $item;
407
    }
408
  }
409
410
  $output = '';
411
412
  if (!empty($default)) {
413
    $output .= $default['link'] . '<a class="commons-bw-create-choose"><span></span></a>';
414
  }
415
416
  $output .= '<div class="commons-bw-create-choose-bg"></div><div class="commons-bw-create-choose-holder">' . theme('item_list', array('items' => $links, 'type' => 'ul', 'attributes' => array('class' => 'commons-bw-create-all-widget-types'))) . '</div>';
417
418
  return $output;
419
}
420
421
/**
422
 * Generate a renderable group widget.
423
 *
424
 * @param $group
425
 *   An optional group node to be used as a tab and views argument.
426
 *
427
 * @return array
428
 *   An array in the format expected by drupal_render().
429
 */
430
function commons_bw_generate_group_widget($group = NULL) {
431
  // Prepare an array of default quicktabs settings.
432
  $settings = array(
433
    'style' => 'Commons Pills',
434
    'ajax' => FALSE,
435
    'html' => TRUE,
436
  );
437
438
  // Load the browsing widget tab definitions.
439
  $tabs = commons_bw_get_tab_definitions('group');
440
441
  foreach ($tabs as $machine_name => $tab_settings) {
442
    // Populate the group argument.
443
    $tabs[$machine_name]['args'] = $group ? $group->nid : 0;
444
445
    // Add the result count to the title for 'view' tabs.
446
    if ($tab_settings['type'] == 'view') {
447
      // Get the view specified by the tab settings.
448
      $view = views_get_view($tab_settings['vid']);
449
450
      // If the tab specified a view display use it, otherwise the view will be
451
      // rendered using the default display.
452
      if (isset($tab_settings['display'])) {
453
        $view->set_display($tab_settings['display']);
454
      }
455
456
      // If the tab references a group, set it as a tab argument.
457
      if ($group) {
458
        $view->set_arguments(array($group->nid));
459
      }
460
461
      $view->display_handler->options['filters']['flagged']['value'] = 'All';
462
      $view->get_total_rows = TRUE;
463
      $view->execute();
464
465
      // Append the result count to the tab title.
466
      $tabs[$machine_name]['title'] = $tabs[$machine_name]['title'] . ' <span class="commons-bw-result-count">'. $view->total_rows . '</span>';
467
    }
468
469
    // Use the current tab as the quicktabs default if the tab settings specify.
470
    if (!empty($tabs[$machine_name]['default'])) {
471
      $settings['default_tab'] = $machine_name;
472
    }
473
  }
474
475
  return quicktabs_build_quicktabs('commons_bw', $settings, $tabs);
476
}
477
478
/**
479
 * Implements hook_quicktabs_tabstyles().
480
 */
481
function commons_bw_quicktabs_tabstyles() {
482
  $path = drupal_get_path('module', 'commons_bw');
483
484
  return array(
485
    $path . '/plugins/quicktabs_styles/commons_pills/commons_pills.css' => t('Commons Pills'),
486
    $path . '/plugins/quicktabs_styles/commons_tabs/commons_tabs.css' => t('Commons Tabs'),
487
  );
488
}
489