#153714 by Magnus: Imported translation to localization server and removed CVS file.
[project/views.git] / includes / convert.inc
CommitLineData
5bb097b8
EM
1<?php
2// $Id$
3/**
4 * @file convert.inc
5 *
6 * Contains forms and routines to convert older views to newer views.
7 */
8
9/**
10 * Page callback for the tools - Views 1 convert page
11 */
12function views_ui_admin_convert() {
13 if (!db_table_exists('view_view')) {
14 return t('There are no Views 1 views stored in the database to convert.');
15 }
16 $items = array();
17 $sorts = array();
18
19 $header = array(
20 array('data' => t('View name'), 'field' => 'name', 'sort' => 'asc'),
21 array('data' => t('Description')),
22 array('data' => t('Operations')),
23 );
24 $current_views = views_get_all_views();
25
26 $result = db_query("SELECT v.* FROM {view_view} v");
27 while ($view = db_fetch_object($result)) {
28 $ops = array();
29 if (!isset($current_views[$view->name])) {
30 $ops[] = l(t('Convert'), "admin/build/views1/convert/$view->name");
31 }
32 else {
33 $ops[] = t('Converted');
34 }
35 $ops[] = l(t('Delete'), "admin/build/views1/delete/$view->name");
36
37 $item = array();
38 $item[] = check_plain($view->name);
39 $item[] = check_plain($view->description);
40 $item[] = implode(' | ', $ops);
41 $items[] = $item;
42
43 $ts = tablesort_init($header);
44 switch ($ts['sql']) {
45 case 'name':
46 default:
47 $sorts[] = $item[0];
48 break;
49 case 'title':
50 $sorts[] = $item[1];
51 break;
52 }
53 }
54
55 if (!empty($ts)) {
56 if (strtolower($ts['sort']) == 'desc') {
57 arsort($sorts);
58 }
59 else {
60 asort($sorts);
61 }
62 }
63
64 $i = array();
65 foreach ($sorts as $id => $title) {
66 $i[] = $items[$id];
67 }
68 $output = t('The table below lists Views version 1 views that are stored in the database. You can either convert them to work in Views version 2, or delete them. The views are convertible only if there is no Views 2 view with the same name.');
69 $output .= theme('table', $header, $i);
c57754c0
EM
70
71 $output .= drupal_get_form('views_ui_convert_cleanup_form');
5bb097b8
EM
72 return $output;
73}
74
75/**
c57754c0
EM
76 * Provide form to clean up Views 1 tables.
77 */
78function views_ui_convert_cleanup_form() {
79 $form['verify'] = array(
80 '#type' => 'checkbox',
81 '#title' => t('Remove all Views 1 tables'),
82 '#description' => t('Check this box and then click clean up to drop all Views 1 tables. Warning: this operation will not be reversible! Do this only if you are sure you no longer need this data.'),
83 '#required' => TRUE,
84 );
85
86 $form['submit'] = array(
87 '#type' => 'submit',
88 '#value' => t('Clean up'),
89 );
90
91 return $form;
92}
93
94function views_ui_convert_cleanup_form_submit($form, $form_state) {
95 if (empty($form_state['values']['verify'])) {
96 drupal_set_message('Please check the box to verify you want to destroy your Views 1 table data.');
97 return;
98 }
99
100 $ret = array();
101 if (db_table_exists('view_view')) {
102 db_drop_table($ret, 'view_view');
103 }
104 if (db_table_exists('view_sort')) {
105 db_drop_table($ret, 'view_sort');
106 }
107 if (db_table_exists('view_argument')) {
108 db_drop_table($ret, 'view_argument');
109 }
110 if (db_table_exists('view_tablefield')) {
111 db_drop_table($ret, 'view_tablefield');
112 }
113 if (db_table_exists('view_filter')) {
114 db_drop_table($ret, 'view_filter');
115 }
116 if (db_table_exists('view_exposed_filter')) {
117 db_drop_table($ret, 'view_exposed_filter');
118 }
119
120 drupal_set_message(t('All Views 1 tables have been removed.'));
121}
122
123/**
5bb097b8
EM
124 * Page callback for the tools - Views 1 convert page
125 */
126function views_ui_convert1($name) {
127 $old = views1_load($name);
128 if (!$old) {
129 return t('Unable to find view.');
130 }
131
132 $view = views1_import($old);
133
134 if ($view) {
135 views_ui_cache_set($view);
136 drupal_goto('admin/build/views/edit/' . $view->name);
137 }
138 else {
139 return t('Unable to convert view.');
140 }
141}
142
143/**
144 * Page to delete a Views 1 view.
145 */
146function views_ui_delete1_confirm(&$form_state, $vid) {
147 $form_state['vid'] = $vid;
148 $form = array();
149
150 $cancel = 'admin/build/views/tools/convert';
151 if (!empty($_REQUEST['cancel'])) {
152 $cancel = $_REQUEST['cancel'];
153 }
154 return confirm_form($form,
740306ef 155 t('Are you sure you want to delete the view %name?', array('%name' => $view->name)),
5bb097b8
EM
156 $cancel,
157 t('This action cannot be undone.'),
158 t('Delete'),
159 t('Cancel'));
160}
161
162/**
163 * Submit handler to delete a view.
164 */
165function views_ui_delete1_confirm_submit(&$form, &$form_state) {
166 views1_delete($form_state['vid']);
167 drupal_set_message(t('The view has been deleted'));
168 $form_state['redirect'] = 'admin/build/views/tools/convert';
169}
170
171/**
172 * Convert a Views 1 view to a Views 2 view.
173 */
174function views1_import($imported) {
65251555 175 views_include_handlers();
acf63142 176 views_module_include('views_convert.inc');
5bb097b8
EM
177
178 $view = views_new_view();
179
180 $view->name = $imported->name;
181 $view->description = $imported->description;
5bb097b8 182
ae4f31f3 183 if (!empty($imported->page) && !empty($imported->url)) {
b08a56c5 184 $page_display = $view->add_display('page');
5bb097b8
EM
185 }
186 if (!empty($imported->block)) {
b08a56c5 187 $block_display = $view->add_display('block');
5bb097b8
EM
188 }
189 $view->init_display();
190
191 $handler = &$view->display['default']->handler;
192 $handler->set_option('title', $imported->page_title);
193 $handler->set_option('header', $imported->page_header);
194 $handler->set_option('header_format', $imported->page_header_format);
195 $handler->set_option('footer', $imported->page_footer);
196 $handler->set_option('footer_format', $imported->page_footer_format);
197 $handler->set_option('empty', $imported->page_empty);
198 $handler->set_option('empty_format', $imported->page_empty_format);
199
200 $handler->set_option('use_pager', $imported->use_pager);
201 $handler->set_option('items_per_page', $imported->nodes_per_page);
202 $handler->set_option('pager_element', 0);
203 $handler->set_option('offset', 0);
204
205 $access = array('type' => 'none', 'role' => array(), 'perm' => '');
206 if ($imported->access) {
207 $access['type'] = 'role';
208 $access['role'] = drupal_map_assoc($imported->access);
209 }
210
211 $handler->set_option('access', $access);
ae4f31f3 212 if (!empty($imported->page) && !empty($imported->url)) {
b08a56c5 213 $handler = &$view->display[$page_display]->handler;
5bb097b8
EM
214 $url = str_replace('$arg', '%', $imported->url);
215 $handler->set_option('path', $url);
216 if ($imported->menu) {
217 $menu = array('type' => 'normal');
218 if ($imported->menu_tab) {
219 $menu['type'] = 'tab';
220 }
221 if ($imported->menu_tab_default) {
222 $menu['type'] = 'default tab';
223 }
ae4f31f3 224 $menu['title'] = $imported->menu_title ? $imported->menu_title : $imported->page_title;
5bb097b8
EM
225 $handler->set_option('menu', $menu);
226
227 if ($menu['type'] == 'default tab') {
228 $tab_options = array('type' => 'none');
229 switch ($imported->menu_tab_default_parent_type) {
230 case 'tab':
231 case 'normal':
232 $tab_options['type'] = $imported->menu_tab_default_parent_type;
233 break;
234 }
235 }
236 $tab_options['title'] = $imported->menu_parent_title;
237 $tab_options['weight'] = $imported->menu_parent_tab_weight;
238 $handler->set_option('tab_options', $tab_options);
239 }
5bb097b8
EM
240 }
241
ae4f31f3
EM
242 views1_convert_style($view, $handler, $imported->page_type);
243
5bb097b8 244 if (!empty($imported->block)) {
b08a56c5 245 $handler = &$view->display[$block_display]->handler;
5bb097b8 246
ae4f31f3 247 if (!empty($imported->block_title)) {
473e3346
EM
248 if (!empty($imported->page)) {
249 $handler->set_override('title');
250 }
5bb097b8
EM
251 $handler->set_option('title', $imported->block_title);
252 }
253
473e3346
EM
254 if (!empty($imported->page)) {
255 $handler->set_override('use_pager');
256 }
257 $handler->set_option('use_pager', FALSE);
258
5bb097b8 259 if ($imported->nodes_per_block != $imported->nodes_per_page) {
5bb097b8
EM
260 $handler->set_option('items_per_page', $imported->nodes_per_block);
261 $handler->set_option('offset', 0);
262 }
263
264 if (empty($imported->block_use_page_header)) {
473e3346
EM
265 if (!empty($imported->page)) {
266 $handler->set_override('header');
267 }
ae4f31f3
EM
268 if (!empty($imported->block_header)) {
269 $handler->set_option('header', $imported->block_header);
270 $handler->set_option('header_format', $imported->block_header_format);
271 }
5bb097b8
EM
272 }
273 if (empty($imported->block_use_page_footer)) {
473e3346
EM
274 if (!empty($imported->page)) {
275 $handler->set_override('footer');
276 }
ae4f31f3
EM
277 if (!empty($imported->block_footer)) {
278 $handler->set_option('footer', $imported->block_footer);
279 $handler->set_option('footer_format', $imported->block_footer_format);
280 }
5bb097b8
EM
281 }
282 if (empty($imported->block_use_page_empty)) {
473e3346
EM
283 if (!empty($imported->page)) {
284 $handler->set_override('empty');
285 }
ae4f31f3
EM
286 if (!empty($imported->block_empty)) {
287 $handler->set_option('empty', $imported->block_empty);
288 $handler->set_option('empty_format', $imported->block_empty_format);
289 }
5bb097b8
EM
290 }
291
ae4f31f3 292 $handler->set_option('use_more', $imported->block_more);
5bb097b8 293
473e3346
EM
294 if (!empty($imported->page)) {
295 $handler->set_override('style_plugin');
296 }
5bb097b8
EM
297 views1_convert_style($view, $handler, $imported->block_type);
298 }
299
300 // For each of the fields, arguments, filters, and sorts in the old view,
301 // check if a handler for this item exists in Views 2 and add it,
302 // then see if any other modules want to adapt it using hook_views_convert().
303
304 foreach ($imported->field as $field) {
ae4f31f3 305 $id = $view->add_item('default', 'field', $field['tablename'], $field['field'], array('label' => $field['label']));
5795fe91
EM
306 if ($view->display_handler->get_option('style_plugin') == 'table') {
307 $options = $view->display_handler->get_option('style_options');
5795fe91
EM
308 if (!empty($field['sortable'])) {
309 $options['info'][$id]['sortable'] = TRUE;
ae4f31f3
EM
310 if (!empty($field['defaultsort'])) {
311 $options['default'] = $id;
312 }
5795fe91
EM
313 }
314 $view->display_handler->set_option('style_options', $options);
315 }
5bb097b8 316 foreach (module_implements('views_convert') as $module) {
5795fe91 317 module_invoke($module, 'views_convert', 'default', 'field', $view, $field, $id);
5bb097b8
EM
318 }
319 }
320 foreach ($imported->sort as $field) {
ae4f31f3 321 $id = $view->add_item('default', 'sort', $field['tablename'], $field['field'], array('order' => $field['sortorder']));
5bb097b8 322 foreach (module_implements('views_convert') as $module) {
5795fe91 323 module_invoke($module, 'views_convert', 'default', 'sort', $view, $field, $id);
5bb097b8
EM
324 }
325 }
ae4f31f3
EM
326 $actions = array('ignore', 'not found', 'ignore', 'summary asc', 'summary asc', 'summary desc', 'summary asc', 'empty');
327 foreach ($imported->argument as $id => $field) {
328 if (!empty($imported->view_args_php)) {
329 $field['argoptions']['default_action'] = 'default';
330 $field['argoptions']['default_argument_type'] = 'php';
331 $field['argoptions']['default_argument_php'] = '$args = eval(\''. str_replace("'", "\\'", $imported->view_args_php) .'\');'."\n";
332 $field['argoptions']['default_argument_php'] .= 'if (isset($args['. $field['position'] .'])) {'."\n";
333 $field['argoptions']['default_argument_php'] .= ' return $args['. $field['position'] .'];'."\n";
334 $field['argoptions']['default_argument_php'] .= '}';
335 $field['argoptions']['validate_fail'] = $actions[$field['argdefault']];
336 }
337 else {
338 $field['argoptions']['default_action'] = $actions[$field['argdefault']];
339 }
340 if (!empty($field['title'])) {
341 $field['argoptions']['title'] = $field['title'];
342 }
343 if (!empty($field['wildcard'])) {
344 $field['argoptions']['wildcard'] = $field['wildcard'];
345 }
346 if (!empty($field['wildcard_substitution'])) {
347 $field['argoptions']['wildcard_substitution'] = $field['wildcard_substitution'];
348 }
5795fe91
EM
349 // Arguments didn't used to be identified by table.name so we just have to
350 // leave that out.
5bb097b8 351 foreach (module_implements('views_convert') as $module) {
5795fe91 352 module_invoke($module, 'views_convert', 'default', 'argument', $view, $field, NULL);
5bb097b8
EM
353 }
354 }
355 foreach ($imported->filter as $field) {
0ecca492
EM
356 $options = $field['value'] == '' ? array() : array('value' => $field['value']);
357 $id = $view->add_item('default', 'filter', $field['tablename'], $field['field'], $options);
5bb097b8 358 foreach (module_implements('views_convert') as $module) {
5795fe91 359 module_invoke($module, 'views_convert', 'default', 'filter', $view, $field, $id);
5bb097b8
EM
360 }
361 }
362 // Exposed filters now get added to the filter array, not as a separate array.
363 $count = 0;
364 foreach ($imported->exposed_filter as $field) {
473e3346
EM
365 list(, $id) = explode('.', $field['field'], 2);
366 $item = $view->get_item('default', 'filter', $id);
367 if (views_get_handler($item['table'], $item['field'], 'filter')) {
ae4f31f3 368 $item['exposed'] = TRUE;
5bb097b8
EM
369
370 // Use the count to emulate the old, hardcoded filter naming.
473e3346
EM
371 $item['expose']['identifier'] = 'filter' . $count;
372 $item['expose']['label'] = $field['label'];
373 $item['expose']['operator'] = $field['operator'] ? 'op' . $count : '';
374 $item['expose']['optional'] = $field['optional'];
375 $item['expose']['single'] = $field['single'];
376 $view->set_item('default', 'filter', $id, $item);
5bb097b8
EM
377 }
378 $count++;
379 foreach (module_implements('views_convert') as $module) {
473e3346 380 module_invoke($module, 'views_convert', 'default', 'exposed_filter', $view, $field, $id);
5bb097b8
EM
381 }
382 }
383
384 return $view;
385}
386
387function views1_convert_style(&$view, &$handler, $type) {
388 switch ($type) {
389 case 'list':
390 $handler->set_option('style_plugin', 'list');
391 $handler->set_option('style_options', array('type' => 'ul'));
392 $handler->set_option('row_plugin', 'fields');
393 break;
394 case 'node':
395 $handler->set_option('row_plugin', 'node');
742412e5 396 $handler->set_option('row_options', array('teaser' => FALSE, 'links' => TRUE));
5bb097b8
EM
397 break;
398 case 'teaser':
399 $handler->set_option('row_plugin', 'node');
742412e5 400 $handler->set_option('row_options', array('teaser' => TRUE, 'links' => TRUE));
5bb097b8
EM
401 break;
402 case 'table':
5795fe91
EM
403 $options = array();
404 $options['columns'] = array();
405 $options['default'] = '';
406 $options['info'] = array();
407 $options['override'] = FALSE;
408 $options['order'] = 'asc';
409
5bb097b8 410 $handler->set_option('style_plugin', 'table');
5795fe91 411 $handler->set_option('style_options', $options);
5bb097b8
EM
412 break;
413 default:
414 // Ask around if anybody else knows.
415 foreach (module_implements('views_convert') as $module) {
65251555 416 module_invoke($module, 'views_convert', $handler->display->id, 'style', $view, $type);
5bb097b8
EM
417 }
418 }
419}
420/**
421 * Load a version 1 view from the database.
422 *
423 */
424function views1_load($arg) {
425 static $cache = array();
426 $which = is_numeric($arg) ? 'vid' : 'name';
427 if (isset($cache[$which][$arg])) {
428 return $cache[$which][$arg];
429 }
430
431 $where = (is_numeric($arg) ? "v.vid = %d" : "v.name = '%s'");
432 $view = db_fetch_object(db_query("SELECT v.* FROM {view_view} v WHERE $where", $arg));
433
434 if (!$view->name) {
435 return NULL;
436 }
437
438 $view->access = ($view->access ? explode(', ', $view->access) : array());
439
440 // load the sorting criteria too.
441 $result = db_query("SELECT * FROM {view_sort} vs WHERE vid = $view->vid ORDER BY position ASC");
442
443 $view->sort = array();
444 while ($sort = db_fetch_array($result)) {
445 if (substr($sort['field'], 0, 2) == 'n.') {
446 $sort['field'] = 'node' . substr($sort['field'], 1);
447 }
448 $sort['id'] = $sort['field'];
40f7fd3f
EM
449 $bits = explode('.', $sort['field']);
450 $sort['tablename'] = $bits[0];
451 $sort['field'] = $bits[1];
452 $view->sort[$sort['position']] = $sort;
5bb097b8
EM
453 }
454
455 $result = db_query("SELECT * FROM {view_argument} WHERE vid = $view->vid ORDER BY position ASC");
456
457 $view->argument = array();
458 while ($arg = db_fetch_array($result)) {
459 $arg['id'] = $arg['type'];
40f7fd3f 460 $view->argument[$arg['position']] = $arg;
5bb097b8
EM
461 }
462
463 $result = db_query("SELECT * FROM {view_tablefield} WHERE vid = $view->vid ORDER BY position ASC");
464
465 $view->field = array();
466 while ($arg = db_fetch_array($result)) {
467 if ($arg['tablename'] == 'n') {
468 $arg['tablename'] = 'node';
469 }
470 $arg['id'] = $arg['fullname'] = "$arg[tablename].$arg[field]";
471 $arg['queryname'] = "$arg[tablename]_$arg[field]";
472 $view->field[] = $arg;
473 }
474
475 $result = db_query("SELECT * FROM {view_filter} WHERE vid = $view->vid ORDER BY position ASC");
476
477 // TODO - Is it safe to ignore this $filters variable? This function depends
478 // on lots of additional code needed to call hook_implements and construct
479 // all the views tables, so using it will add a lot of code to this file.
480 //$filters = _views_get_filters();
481 $view->filter = array();
482 while ($filter = db_fetch_array($result)) {
483 if (substr($filter['field'], 0, 2) == 'n.') {
484 $filter['field'] = 'node' . substr($filter['field'], 1);
485 }
486
487 if ($filter['operator'] == 'AND' ||
488 $filter['operator'] == 'OR' ||
40f7fd3f
EM
489 $filter['operator'] == 'NOR') {
490 // TODO - need another way to identify this type of filter
473e3346 491 // without being able to call hook_implements().
40f7fd3f 492 //|| $filters[$filter['field']]['value-type'] == 'array' ) {
5bb097b8
EM
493 if ($filter['value'] !== NULL && $filter['value'] !== '') {
494 $filter['value'] = explode(',', $filter['value']);
495 }
496 else {
497 $filter['value'] = array();
498 }
499 }
500 $filter['id'] = $filter['field'];
40f7fd3f
EM
501 $bits = explode('.', $filter['field']);
502 $filter['tablename'] = $bits[0];
503 $filter['field'] = $bits[1];
504 $view->filter[$filter['position']] = $filter;
5bb097b8
EM
505 }
506
507 $result = db_query("SELECT * FROM {view_exposed_filter} WHERE vid = $view->vid ORDER BY position ASC");
508
509 $view->exposed_filter = array();
510 while ($arg = db_fetch_array($result)) {
511 $arg['id'] = $arg['field'];
512 $view->exposed_filter[] = $arg;
513 }
514
515 $cache['vid'][$view->vid] = $view;
516 $cache['name'][$view->name] = $view;
517
518 return $view;
519}
520
521/**
522 * Delete a version 1 view from the database.
523 *
524 */
525function views1_delete($arg) {
526 static $cache = array();
527 $where = (is_numeric($arg) ? "v.vid = %d" : "v.name = '%s'");
528 $view = db_fetch_object(db_query("SELECT v.* FROM {view_view} v WHERE $where", $arg));
529
530 if (!$view->name) {
531 return NULL;
532 }
533
ae4f31f3 534
c7e5dc69
EM
535
536 $result = db_query("DELETE FROM {view_sort} WHERE vid = $view->vid");
537 $result = db_query("DELETE FROM {view_argument} WHERE vid = $view->vid");
538 $result = db_query("DELETE FROM {view_tablefield} WHERE vid = $view->vid");
539 $result = db_query("DELETE FROM {view_filter} WHERE vid = $view->vid");
540 $result = db_query("DELETE FROM {view_exposed_filter} WHERE vid = $view->vid");
541 $result = db_query("DELETE FROM {view_view} WHERE vid = $view->vid");
5bb097b8
EM
542}
543