Projet

Général

Profil

Paste
Télécharger (10,9 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / views / includes / ajax.inc @ 5d12d676

1
<?php
2

    
3
/**
4
 * @file
5
 * Handles the server side AJAX interactions of Views.
6
 */
7

    
8
/**
9
 * @defgroup ajax Views AJAX library
10
 * @{
11
 * Handles the server side AJAX interactions of Views.
12
 */
13

    
14
/**
15
 * Menu callback to load a view via AJAX.
16
 */
17
function views_ajax() {
18
  if (isset($_REQUEST['view_name']) && isset($_REQUEST['view_display_id'])) {
19
    $name = $_REQUEST['view_name'];
20
    $display_id = $_REQUEST['view_display_id'];
21
    $args = isset($_REQUEST['view_args']) && $_REQUEST['view_args'] !== '' ? explode('/', $_REQUEST['view_args']) : array();
22
    $path = isset($_REQUEST['view_path']) ? rawurldecode($_REQUEST['view_path']) : NULL;
23
    $dom_id = isset($_REQUEST['view_dom_id']) ? preg_replace('/[^a-zA-Z0-9_-]+/', '-', $_REQUEST['view_dom_id']) : NULL;
24
    $pager_element = isset($_REQUEST['pager_element']) ? intval($_REQUEST['pager_element']) : NULL;
25

    
26
    $commands = array();
27

    
28
    // Remove all of this stuff from $_GET so it doesn't end up in pagers and
29
    // tablesort URLs.
30
    foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', 'ajax_html_ids', 'ajax_page_state') as $key) {
31
      if (isset($_GET[$key])) {
32
        unset($_GET[$key]);
33
      }
34
      if (isset($_REQUEST[$key])) {
35
        unset($_REQUEST[$key]);
36
      }
37
      if (isset($_POST[$key])) {
38
        unset($_POST[$key]);
39
      }
40
    }
41

    
42
    // Load the view.
43
    $view = views_get_view($name);
44
    if ($view && $view->access($display_id) && $view->set_display($display_id) && $view->display_handler->use_ajax()) {
45
      // Fix 'q' for paging.
46
      if (!empty($path)) {
47
        $_GET['q'] = $path;
48
      }
49

    
50
      // If page parameter is in the $_POST exclude it from $_GET, otherwise
51
      // support views_ajax requests using $_GET.
52
      $exclude = isset($_POST['page']) ? array('page') : array();
53
      // Add all $_POST data to $_GET as many things, such as tablesorts,
54
      // exposed filters and paging assume $_GET.
55
      $_GET = $_POST + drupal_get_query_parameters($_GET, $exclude);
56

    
57
      // Overwrite the destination.
58
      // @see drupal_get_destination()
59
      $origin_destination = $path;
60
      $query = drupal_http_build_query(drupal_get_query_parameters());
61
      if ($query != '') {
62
        $origin_destination .= '?' . $query;
63
      }
64
      $destination = &drupal_static('drupal_get_destination');
65
      $destination = array('destination' => $origin_destination);
66

    
67
      // Override the display's pager_element with the one actually used.
68
      if (isset($pager_element)) {
69
        $commands[] = views_ajax_command_scroll_top('.view-dom-id-' . $dom_id);
70
        $view->display[$display_id]->handler->set_option('pager_element', $pager_element);
71
      }
72
      // Reuse the same DOM id so it matches that in Drupal.settings.
73
      $view->dom_id = $dom_id;
74

    
75
      $commands[] = ajax_command_replace('.view-dom-id-' . $dom_id, $view->preview($display_id, $args));
76
    }
77
    drupal_alter('views_ajax_data', $commands, $view);
78
    return array('#type' => 'ajax', '#commands' => $commands);
79
  }
80
}
81

    
82
/**
83
 * Creates a Drupal AJAX 'viewsSetForm' command.
84
 *
85
 * @param string $output
86
 *   The form to display in the modal.
87
 * @param string $title
88
 *   The title.
89
 * @param string $url
90
 *   An optional URL.
91
 *
92
 * @return array
93
 *   An array suitable for use with the ajax_render() function.
94
 */
95
function views_ajax_command_set_form($output, $title, $url = NULL) {
96
  $command = array(
97
    'command' => 'viewsSetForm',
98
    'output' => $output,
99
    'title' => $title,
100
  );
101
  if (isset($url)) {
102
    $command['url'] = $url;
103
  }
104
  return $command;
105
}
106

    
107
/**
108
 * Creates a Drupal AJAX 'viewsDismissForm' command.
109
 *
110
 * @return array
111
 *   An array suitable for use with the ajax_render() function.
112
 */
113
function views_ajax_command_dismiss_form() {
114
  $command = array(
115
    'command' => 'viewsDismissForm',
116
  );
117
  return $command;
118
}
119

    
120
/**
121
 * Creates a Drupal AJAX 'viewsHilite' command.
122
 *
123
 * @param string $selector
124
 *   The selector to highlight.
125
 *
126
 * @return
127
 *   An array suitable for use with the ajax_render() function.
128
 */
129
function views_ajax_command_hilite($selector) {
130
  return array(
131
    'command' => 'viewsHilite',
132
    'selector' => $selector,
133
  );
134
}
135

    
136
/**
137
 * Creates a Drupal AJAX 'addTab' command.
138
 *
139
 * @param string $id
140
 *   The DOM ID.
141
 * @param string $title
142
 *   The title.
143
 * @param string $body
144
 *   The body.
145
 *
146
 * @return array
147
 *   An array suitable for use with the ajax_render() function.
148
 */
149
function views_ajax_command_add_tab($id, $title, $body) {
150
  $command = array(
151
    'command' => 'viewsAddTab',
152
    'id' => $id,
153
    'title' => $title,
154
    'body' => $body,
155
  );
156
  return $command;
157
}
158

    
159
/**
160
 * Scroll to top of the current view.
161
 *
162
 * @return array
163
 *   An array suitable for use with the ajax_render() function.
164
 */
165
function views_ajax_command_scroll_top($selector) {
166
  $command = array(
167
    'command' => 'viewsScrollTop',
168
    'selector' => $selector,
169
  );
170
  return $command;
171
}
172

    
173
/**
174
 * Shows Save and Cancel buttons.
175
 *
176
 * @param bool $changed
177
 *   Whether of not the view has changed.
178
 *
179
 * @return array
180
 *   An array suitable for use with the ajax_render() function.
181
 */
182
function views_ajax_command_show_buttons($changed) {
183
  $command = array(
184
    'command' => 'viewsShowButtons',
185
    'changed' => (bool) $changed,
186
  );
187
  return $command;
188
}
189

    
190
/**
191
 * Trigger the Views live preview.
192
 *
193
 * @return array
194
 *   An array suitable for use with the ajax_render() function.
195
 */
196
function views_ajax_command_trigger_preview() {
197
  $command = array(
198
    'command' => 'viewsTriggerPreview',
199
  );
200
  return $command;
201
}
202

    
203
/**
204
 * Replace the page title.
205
 *
206
 * @return array
207
 *   An array suitable for use with the ajax_render() function.
208
 */
209
function views_ajax_command_replace_title($title) {
210
  $command = array(
211
    'command' => 'viewsReplaceTitle',
212
    'title' => $title,
213
    'siteName' => variable_get('site_name', 'Drupal'),
214
  );
215
  return $command;
216
}
217

    
218
/**
219
 * Return an AJAX error.
220
 *
221
 * @param string $message
222
 *   The message to display.
223
 *
224
 * @return array
225
 *   An array suitable for use with the ajax_render() function.
226
 */
227
function views_ajax_error($message) {
228
  $commands = array();
229
  $commands[] = views_ajax_command_set_form($message, t('Error'));
230
  return $commands;
231
}
232

    
233
/**
234
 * Wrapper around drupal_build_form to handle some AJAX stuff automatically.
235
 *
236
 * This makes some assumptions about the client.
237
 */
238
function views_ajax_form_wrapper($form_id, &$form_state) {
239
  ctools_include('dependent');
240

    
241
  // This won't override settings already in.
242
  $form_state += array(
243
    'rerender' => FALSE,
244
    'no_redirect' => !empty($form_state['ajax']),
245
    'no_cache' => TRUE,
246
    'build_info' => array(
247
      'args' => array(),
248
    ),
249
  );
250

    
251
  $form = drupal_build_form($form_id, $form_state);
252
  $output = drupal_render($form);
253

    
254
  // These forms have the title built in, so set the title here.
255
  if (empty($form_state['ajax']) && !empty($form_state['title'])) {
256
    drupal_set_title($form_state['title']);
257
    drupal_add_css(drupal_get_path('module', 'views_ui') . '/css/views-admin.css');
258
  }
259

    
260
  if (!empty($form_state['ajax']) && (empty($form_state['executed']) || !empty($form_state['rerender']))) {
261
    // If the form didn't execute and we're using ajax, build up a AJAX command
262
    // list to execute.
263
    $commands = array();
264

    
265
    $display = '';
266
    if ($messages = theme('status_messages')) {
267
      $display = '<div class="views-messages">' . $messages . '</div>';
268
    }
269
    $display .= $output;
270

    
271
    $title = empty($form_state['title']) ? '' : $form_state['title'];
272
    if (!empty($form_state['help_topic'])) {
273
      $module = !empty($form_state['help_module']) ? $form_state['help_module'] : 'views';
274
      if (module_exists('advanced_help')) {
275
        $title = theme('advanced_help_topic', array('module' => $module, 'topic' => $form_state['help_topic'])) . $title;
276
      }
277
    }
278

    
279
    $url = empty($form_state['url']) ? url($_GET['q'], array('absolute' => TRUE)) : $form_state['url'];
280

    
281
    $commands[] = views_ajax_command_set_form($display, $title, $url);
282

    
283
    if (!empty($form_state['#section'])) {
284
      $commands[] = views_ajax_command_hilite('.' . drupal_clean_css_identifier($form_state['#section']));
285
    }
286

    
287
    return $commands;
288
  }
289

    
290
  // These forms have the title built in, so set the title here.
291
  if (empty($form_state['ajax']) && !empty($form_state['title'])) {
292
    drupal_set_title($form_state['title']);
293
  }
294

    
295
  return $output;
296
}
297

    
298

    
299
/**
300
 * Page callback for views user autocomplete.
301
 */
302
function views_ajax_autocomplete_user($string = '') {
303
  // The user enters a comma-separated list of user name. We only autocomplete
304
  // the last name.
305
  $array = drupal_explode_tags($string);
306

    
307
  // Fetch last name.
308
  $last_string = trim(array_pop($array));
309
  $matches = array();
310
  if ($last_string != '') {
311
    $prefix = count($array) ? implode(', ', $array) . ', ' : '';
312

    
313
    if (strpos('anonymous', strtolower($last_string)) !== FALSE) {
314
      $matches[$prefix . 'Anonymous'] = 'Anonymous';
315
    }
316

    
317
    $result = db_select('users', 'u')
318
      ->fields('u', array('uid', 'name'))
319
      ->condition('u.name', db_like($last_string) . '%', 'LIKE')
320
      ->range(0, 10)
321
      ->execute()
322
      ->fetchAllKeyed();
323

    
324
    foreach ($result as $account) {
325
      $n = $account;
326
      // Commas and quotes in terms are special cases, so encode 'em.
327
      if (strpos($account, ',') !== FALSE || strpos($account, '"') !== FALSE) {
328
        $n = '"' . str_replace('"', '""', $account) . '"';
329
      }
330
      $matches[$prefix . $n] = check_plain($account);
331
    }
332
  }
333

    
334
  drupal_json_output($matches);
335
}
336

    
337
/**
338
 * Page callback for views taxonomy autocomplete.
339
 *
340
 * @param int $vid
341
 *   The vocabulary id of the tags which should be returned.
342
 * @param string $tags_typed
343
 *   The typed string of the user.
344
 *
345
 * @see taxonomy_autocomplete()
346
 */
347
function views_ajax_autocomplete_taxonomy($vid, $tags_typed = '') {
348
  // The user enters a comma-separated list of tags. We only autocomplete the
349
  // last tag.
350
  $tags_typed = drupal_explode_tags($tags_typed);
351
  $tag_last = drupal_strtolower(array_pop($tags_typed));
352

    
353
  $matches = array();
354
  if ($tag_last != '') {
355

    
356
    $query = db_select('taxonomy_term_data', 't');
357
    $query->addTag('translatable');
358
    $query->addTag('taxonomy_term_access');
359

    
360
    // Do not select already entered terms.
361
    if (!empty($tags_typed)) {
362
      $query->condition('t.name', $tags_typed, 'NOT IN');
363
    }
364
    // Select rows that match by term name.
365
    $tags_return = $query
366
      ->fields('t', array('tid', 'name'))
367
      ->condition('t.vid', $vid)
368
      ->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')
369
      ->range(0, 10)
370
      ->execute()
371
      ->fetchAllKeyed();
372

    
373
    $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
374

    
375
    $term_matches = array();
376
    foreach ($tags_return as $tid => $name) {
377
      $n = $name;
378
      // Term names containing commas or quotes must be wrapped in quotes.
379
      if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
380
        $n = '"' . str_replace('"', '""', $name) . '"';
381
      }
382
      // Add term name to list of matches.
383
      $term_matches[$prefix . $n] = check_plain($name);
384
    }
385
  }
386

    
387
  drupal_json_output($term_matches);
388
}
389

    
390
/**
391
 * @}
392
 */