Parent Directory
|
Revision Log
|
Revision Graph
By Daniel Berthereau: Added export of terms and vocabularies.
| 1 | <?php |
| 2 | // $Id: taxonomy_csv.module,v 2.11 2009/10/05 09:43:12 danielkm Exp $ |
| 3 | |
| 4 | /** |
| 5 | * taxonomy_csv module for Drupal |
| 6 | * |
| 7 | * Copyright (c) 2007-2008 Dennis Stevense, see LICENSE.txt for more information |
| 8 | * Copyright (c) 2009 Daniel Berthereau <daniel.drupal@berthereau.net> |
| 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify it under |
| 11 | * the terms of the GNU General Public License as published by the Free Software |
| 12 | * Foundation; either version 2 of the License, or (at your option) any later |
| 13 | * version. |
| 14 | * |
| 15 | * This program is distributed in the hope that it will be useful, but WITHOUT |
| 16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 17 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
| 18 | * details. |
| 19 | * |
| 20 | * You should have received a copy of the GNU General Public License along with |
| 21 | * this program; if not, write to the Free Software Foundation, Inc., |
| 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 23 | */ |
| 24 | |
| 25 | /** |
| 26 | * @file |
| 27 | * Quick export and import of taxonomies, structure or lists of terms to or from |
| 28 | * a csv local or distant file or a text area. |
| 29 | * |
| 30 | * Automatically exports or imports a list of terms, structure, children, |
| 31 | * related, synonyms, descriptions and/or weights from or into a vocabulary with |
| 32 | * a simple csv file. |
| 33 | * |
| 34 | * taxonomy_csv.module contains functions to manage import/export form pages. |
| 35 | * taxonomy_csv.api.inc is an api which can be use alone. It contains generic |
| 36 | * functions to import and export vocabularies or lines. |
| 37 | */ |
| 38 | |
| 39 | /** |
| 40 | * Implements hook_help(). |
| 41 | */ |
| 42 | function taxonomy_csv_help($path, $arg) { |
| 43 | global $language; |
| 44 | |
| 45 | switch ($path) { |
| 46 | case 'admin/content/taxonomy/csv_import': |
| 47 | $output = '<p>'. t('Use this form to import a taxonomy, a structure or a list of terms into a vocabulary from a simple <a href="!link" title="Wikipedia definition">CSV</a> file, a url or a copy-and-paste text.', array('!link' => url('http://en.wikipedia.org/wiki/Comma-separated_values'))) .'</p>'; |
| 48 | $output .= '<p>'. t('For performance reasons, it is recommended to disable some other taxonomy related modules before import of big taxonomies and to reactivate them after process.') .'</p>'; |
| 49 | $output .= '<p>'. t('<strong>Warning:</strong> If you want to update an existing vocabulary, make sure you have a backup before you proceed so you can roll back, if necessary.') . theme('more_help_link', url('admin/help/taxonomy_csv')) .'</p>'; |
| 50 | return $output; |
| 51 | |
| 52 | case 'admin/content/taxonomy/csv_export': |
| 53 | $output = '<p>'. t('Use this form to export a taxonomy, a structure or a list of terms to a simple <a href="!link" title="Wikipedia definition">CSV</a> file.', array('!link' => url('http://en.wikipedia.org/wiki/Comma-separated_values'))) . theme('more_help_link', url('admin/help/taxonomy_csv')) .'</p>'; |
| 54 | return $output; |
| 55 | |
| 56 | case 'admin/help#taxonomy_csv': |
| 57 | $output = file_get_contents(drupal_get_path('module', 'taxonomy_csv') . ((is_file(drupal_get_path('module', 'taxonomy_csv') ."/translations/taxonomy_csv.help.{$language->prefix}.html")) ? "/translations/taxonomy_csv.help.{$language->prefix}.html" : '/taxonomy_csv.help.html')); |
| 58 | return $output; |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | /** |
| 63 | * Implements hook_perm(). |
| 64 | */ |
| 65 | function taxonomy_csv_perm() { |
| 66 | return array( |
| 67 | 'administer taxonomy by csv', |
| 68 | 'export taxonomy by csv', |
| 69 | ); |
| 70 | } |
| 71 | |
| 72 | /** |
| 73 | * Implements hook_menu(). |
| 74 | * |
| 75 | * @note See hook_menu for a description of return values. |
| 76 | */ |
| 77 | function taxonomy_csv_menu() { |
| 78 | $items = array(); |
| 79 | |
| 80 | $items['admin/content/taxonomy/csv_import'] = array( |
| 81 | 'title' => 'CSV import', |
| 82 | 'page callback' => 'taxonomy_csv_form_import_prepare', |
| 83 | 'access arguments' => array('administer taxonomy by csv'), |
| 84 | 'weight' => 12, |
| 85 | 'type' => MENU_LOCAL_TASK, |
| 86 | ); |
| 87 | |
| 88 | $items['admin/content/taxonomy/csv_export'] = array( |
| 89 | 'title' => 'CSV export', |
| 90 | 'page callback' => 'taxonomy_csv_form_export_prepare', |
| 91 | 'access arguments' => array('export taxonomy by csv'), |
| 92 | 'weight' => 13, |
| 93 | 'type' => MENU_LOCAL_TASK, |
| 94 | ); |
| 95 | |
| 96 | return $items; |
| 97 | } |
| 98 | |
| 99 | /** |
| 100 | * Menu callback of the main import form. |
| 101 | */ |
| 102 | function taxonomy_csv_form_import_prepare() { |
| 103 | // Invoke taxonomy_csv api (defines and functions). |
| 104 | $taxonomy_csv_path = drupal_get_path('module', 'taxonomy_csv'); |
| 105 | require_once("$taxonomy_csv_path/taxonomy_csv.api.inc"); |
| 106 | |
| 107 | // Javascript and css allow to show only available options depending user's choice. |
| 108 | drupal_add_js("$taxonomy_csv_path/taxonomy_csv.js"); |
| 109 | drupal_add_css("$taxonomy_csv_path/taxonomy_csv.css"); |
| 110 | |
| 111 | return drupal_get_form('taxonomy_csv_form_import'); |
| 112 | } |
| 113 | |
| 114 | /** |
| 115 | * Generates the taxonomy CSV import form. |
| 116 | * |
| 117 | * Form contain five fieldsets: |
| 118 | * - 1. What to import ? |
| 119 | * 1. What is content of the source ? |
| 120 | * - 2. Where are items to import ? |
| 121 | * 1. Source choice |
| 122 | * 1. Source select |
| 123 | * 2. Source file or text area |
| 124 | * 2. Source options |
| 125 | * 1. Source delimiter |
| 126 | * 2. Source enclosure |
| 127 | * - 3. Which vocabulary to import into (destination) ? |
| 128 | * 1. Destination type |
| 129 | * 2. Vocabulary choice |
| 130 | * - 4. How to import ? |
| 131 | * 1. Previous or existing terms |
| 132 | * 2. Specific import options depending on source content |
| 133 | * - 5. Advanced options |
| 134 | * 1. Tweaks for big and specific vocabularies |
| 135 | * 2. How to be notified |
| 136 | * |
| 137 | * As what will become existing terms depends on what is imported, dynamic |
| 138 | * options are used: only possible parameters are shown. All options are |
| 139 | * displayed if javascript is not activated. |
| 140 | * |
| 141 | * @ingroup forms |
| 142 | * @see taxonomy_csv_form_import_validate() |
| 143 | * @see taxonomy_csv_form_import_submit() |
| 144 | */ |
| 145 | function taxonomy_csv_form_import($form_state) { |
| 146 | // Display main import form |
| 147 | $list_recommended_values = array( |
| 148 | 'import_format' => TAXONOMY_CSV_FORMAT_ALONE_TERMS, |
| 149 | 'source_choice' => 'text', |
| 150 | 'import_delimiter' => 'comma', |
| 151 | 'import_delimiter_custom' => '', |
| 152 | 'import_enclosure' => 'none', |
| 153 | 'import_enclosure_custom' => '', |
| 154 | 'vocabulary_target' => 'autocreate', |
| 155 | 'vocabulary_id' => 'choose_vocabulary', // Not used for security reason (avoid import mistake). Not to be translated. |
| 156 | 'existing_items' => TAXONOMY_CSV_EXISTING_UPDATE, |
| 157 | 'relations_create_subrelations' => FALSE, |
| 158 | 'relations_all_vocabularies' => FALSE, |
| 159 | 'disable_internal_cache' => FALSE, |
| 160 | 'disable_hierarchy_check' => FALSE, |
| 161 | 'hierarchy_level' => 2, |
| 162 | 'disable_line_checks' => FALSE, |
| 163 | 'disable_utf8_check' => FALSE, |
| 164 | 'result_stats' => 'result_stats', |
| 165 | 'result_terms' => 'result_terms', |
| 166 | 'result_level' => 'notices', |
| 167 | 'result_type' => 'by_message', |
| 168 | ); |
| 169 | |
| 170 | // Remember previous values to use in particular when reloading form. |
| 171 | // If not reloading form, then use previous saved value if exists, else recommended value. |
| 172 | // Warning: specific values 'text', 'path' and 'url are not saved here. |
| 173 | $list_previous_values = array(); |
| 174 | foreach ($list_recommended_values as $key => $value) { |
| 175 | $list_previous_values[$key] = isset($form_state['values'][$key]) ? |
| 176 | $form_state['values'][$key] : |
| 177 | variable_get("taxonomy_csv_{$key}", $value); |
| 178 | } |
| 179 | |
| 180 | $list_import_format = _taxonomy_csv_info_lists('list_import_format'); |
| 181 | |
| 182 | $list_import_delimiter = array( |
| 183 | 'comma' => t('« , » (Comma)'), |
| 184 | 'semicolon' => t('« ; » (Semicolon)'), |
| 185 | 'tabulation' => t('« » (Tabulation)'), |
| 186 | 'space' => t('« » (Space)'), |
| 187 | 'currency_sign' => t('« ¤ » (Currency sign)'), |
| 188 | 'custom_delimiter' => t('Custom delimiter'), |
| 189 | ); |
| 190 | |
| 191 | $list_import_enclosure = array( |
| 192 | 'none' => t('None'), |
| 193 | 'quotation' => t('« " » (Quotation mark)'), |
| 194 | 'custom_enclosure' => t('Custom enclosure'), |
| 195 | ); |
| 196 | |
| 197 | $list_vocabulary_target = array( |
| 198 | 'autocreate' => t('Autocreate a new vocabulary'), |
| 199 | 'duplicate' => t('Duplicate an existing vocabulary'), |
| 200 | 'existing' => t('Import in an existing vocabulary'), |
| 201 | ); |
| 202 | |
| 203 | $list_import_option = _taxonomy_csv_info_lists('list_import_option'); |
| 204 | |
| 205 | // Build form. |
| 206 | $form = array( |
| 207 | '#attributes' => array( |
| 208 | 'enctype' => 'multipart/form-data', |
| 209 | ) |
| 210 | ); |
| 211 | |
| 212 | // Used with recommended values button. |
| 213 | $form['list']['list_recommended_values'] = array( |
| 214 | '#type' => 'value', |
| 215 | '#value' => $list_recommended_values, |
| 216 | ); |
| 217 | |
| 218 | // Advertise if Pathauto module is activated. Issue http://drupal.org/node/540916. |
| 219 | if (module_exists('pathauto')) { |
| 220 | drupal_set_message(t("<strong>Warning</strong>: Pathauto module is activated.<br />This module slows down taxonomy import process and only few terms can be imported. It's advised to disabled it manually in !modules_section. Settings aren't lost when you disable it - and not uninstall it -.<br />After import process, you can reactivate Pathauto and eventually bulk generate aliases for newly imported terms.", array('!modules_section' => l(t("modules section"), 'admin/build/modules'))), 'error'); |
| 221 | } |
| 222 | |
| 223 | $form['format'] = array( |
| 224 | '#type' => 'fieldset', |
| 225 | '#title' => t('1. What do you want to import?'), |
| 226 | '#collapsible' => TRUE, |
| 227 | '#collapsed' => FALSE, |
| 228 | ); |
| 229 | |
| 230 | $form['format']['import_format'] = array( |
| 231 | '#type' => 'select', |
| 232 | '#title' => '', |
| 233 | '#options' => $list_import_format, |
| 234 | '#default_value' => $list_previous_values['import_format'], |
| 235 | '#required' => TRUE, |
| 236 | ); |
| 237 | |
| 238 | if (isset($_COOKIE['has_js'])) { |
| 239 | $form['format']['description_alone_terms'] = array( |
| 240 | '#type' => 'item', |
| 241 | '#description' => t('Only the term in the first column of each line is imported. Additional columns are ignored.'), |
| 242 | '#prefix' => '<div id="description_alone_terms">', |
| 243 | '#suffix' => '</div>', |
| 244 | ); |
| 245 | $form['format']['description_fields_links'] = array( |
| 246 | '#type' => 'item', |
| 247 | '#description' => t('Allow to import full term definitions and links.') .'<br />'. |
| 248 | t('Format: term name, term id, vocabulary id, term description, weight, number of synonyms, number of first level parents, number of first level children, number of related terms, list of synonyms, list of first level parents ids, list of first level children ids, list of related terms ids, list of vocabulary ids of related terms.') .'<br/>'. |
| 249 | t('Only term name should be defined. Other values can be empty. Ids are not internal term ids or vocabulary ids, but a unique identifiant. Ids can be a number or a name. In most case, you can use true name. In fact, term ids need to be specific only for duplicate term names in order to identify each item. So for duplicates, you can use term name with a serial number. Main term id is only needed when term is a duplicate one.') .'<br />'. |
| 250 | t("With this source content, destination is determined by source. If third column is empty, a new vocabulary will be created. If it's a name or a number, a vocabulary will be created if it doesn't exist. This process is used for related terms too. If vocabulary of a related term is not defined, vocabulary of main term is used. Warning: It's not recommended to change the vocabulary of a term with links."), |
| 251 | '#prefix' => '<div id="description_fields_links">', |
| 252 | '#suffix' => '</div>', |
| 253 | ); |
| 254 | $form['format']['description_flat'] = array( |
| 255 | '#type' => 'item', |
| 256 | '#description' => t('All items will be imported as terms.'), |
| 257 | '#prefix' => '<div id="description_flat">', |
| 258 | '#suffix' => '</div>', |
| 259 | ); |
| 260 | $form['format']['description_tree_structure'] = array( |
| 261 | '#type' => 'item', |
| 262 | '#description' => t('Allow to create a tree structure (geography, classification...).') .'<br />'. |
| 263 | t('Format: The first term is imported as a root level parent, the second as child of first term, the third as child of second term and so on. The lower child is the last term of a line. Others are hierarchical parents.'), |
| 264 | '#prefix' => '<div id="description_tree_structure">', |
| 265 | '#suffix' => '</div>', |
| 266 | ); |
| 267 | $form['format']['description_polyhierarchy'] = array( |
| 268 | '#type' => 'item', |
| 269 | '#description' => t('Allow to create a polyhierarchical structure (genealogy, complex nomenclatures...).') .'<br />'. |
| 270 | t('Format: The first term is imported as a root level parent, the second as child of first term, the third as child of second term and so on. The lower child is the last term of a line. Others are hierarchical parents.'), |
| 271 | '#prefix' => '<div id="description_polyhierarchy">', |
| 272 | '#suffix' => '</div>', |
| 273 | ); |
| 274 | $form['format']['description_parents'] = array( |
| 275 | '#type' => 'item', |
| 276 | '#description' => t('Allow to create a polyhierarchical taxonomy (genealogy...).') .'<br />'. |
| 277 | t('First item is imported as a term and next ones as parents of first term. Unlike structure import, all parents are first level parents.'), |
| 278 | '#prefix' => '<div id="description_parents">', |
| 279 | '#suffix' => '</div>', |
| 280 | ); |
| 281 | $form['format']['description_children'] = array( |
| 282 | '#type' => 'item', |
| 283 | '#description' => t('Allow to create a polyhierarchical taxonomy (genealogy...).') .'<br />'. |
| 284 | t('First item is imported as a term and next ones as children of first term. Unlike structure import, all children are first level children.'), |
| 285 | '#prefix' => '<div id="description_children">', |
| 286 | '#suffix' => '</div>', |
| 287 | ); |
| 288 | $form['format']['description_relations'] = array( |
| 289 | '#type' => 'item', |
| 290 | '#description' => t('Allow to create relations between the term in the first column and next terms of the line.'), |
| 291 | '#prefix' => '<div id="description_relations">', |
| 292 | '#suffix' => '</div>', |
| 293 | ); |
| 294 | $form['format']['description_fields'] = array( |
| 295 | '#type' => 'item', |
| 296 | '#description' => t('Import a full term definition') .'<br />'. |
| 297 | t('Format: term name, weight, description, list of synonyms.'), |
| 298 | '#prefix' => '<div id="description_fields">', |
| 299 | '#suffix' => '</div>', |
| 300 | ); |
| 301 | $form['format']['description_descriptions'] = array( |
| 302 | '#type' => 'item', |
| 303 | '#description' => t('Allow to import descriptions of terms. The term is in the first column and the matching description is in the second column.'), |
| 304 | '#prefix' => '<div id="description_descriptions">', |
| 305 | '#suffix' => '</div>', |
| 306 | ); |
| 307 | $form['format']['description_weights'] = array( |
| 308 | '#type' => 'item', |
| 309 | '#description' => t('Allow to import a weight of a term. The term is in the first column and the matching weight is in the second column.'), |
| 310 | '#prefix' => '<div id="description_weights">', |
| 311 | '#suffix' => '</div>', |
| 312 | ); |
| 313 | $form['format']['description_synonyms'] = array( |
| 314 | '#type' => 'item', |
| 315 | '#description' => t('Allow to import synonyms of terms. Each line contains a term in the first column and next items are matching synonyms.'), |
| 316 | '#prefix' => '<div id="description_synonyms">', |
| 317 | '#suffix' => '</div>', |
| 318 | ); |
| 319 | $form['format']['description_taxonomy_manager'] = array( |
| 320 | '#type' => 'item', |
| 321 | '#description' => t('Allow to import a vocabulary exported with Taxonomy manager.') .'<br />'. |
| 322 | t("Format: Each line contains: vocabulary id, term id, term name, term description and list of parents. In this format, order of all lines is important, because it's impossible to attach a parent to an item if this parent hasn't been imported in a previous line."), |
| 323 | '#prefix' => '<div id="description_taxonomy_manager">', |
| 324 | '#suffix' => '</div>', |
| 325 | ); |
| 326 | } |
| 327 | $form['format']['info'] = array( |
| 328 | '#type' => 'item', |
| 329 | '#description' => t('Notice: currently, vocabulary structure is recommended to be imported first when multiple files are imported (with fields and links, flat, tree structure, polyhierarchy, parents or children choice). See <a href="!more_help_link">advanced help</a> for informations about types.', array('!more_help_link' => url('admin/help/taxonomy_csv'))), |
| 330 | ); |
| 331 | |
| 332 | $form['import'] = array( |
| 333 | '#type' => 'fieldset', |
| 334 | '#title' => t('2. Where are items to import?'), |
| 335 | '#collapsible' => TRUE, |
| 336 | '#collapsed' => FALSE, |
| 337 | '#attributes' => array('id' => 'edit-import'), |
| 338 | ); |
| 339 | |
| 340 | $form['import']['source_choice'] = array( |
| 341 | '#type' => 'select', |
| 342 | '#title' => '', |
| 343 | '#options' => array( |
| 344 | 'text' => t('In the below text area'), |
| 345 | 'path' => t('In a local file'), |
| 346 | 'url' => t('In a distant file'), |
| 347 | ), |
| 348 | '#default_value' => $list_previous_values['source_choice'], |
| 349 | ); |
| 350 | |
| 351 | $form['import']['text'] = array( |
| 352 | '#type' => 'textarea', |
| 353 | '#title' => t('Terms to import'), |
| 354 | '#rows' => 3, |
| 355 | '#cols' => 80, |
| 356 | '#default_value' => isset($form_state['values']['text']) ? $form_state['values']['text'] : '', |
| 357 | '#description' => t('Write your csv formated terms directly in this text area.'), |
| 358 | ); |
| 359 | |
| 360 | $form['import']['path'] = array( |
| 361 | '#type' => 'file', |
| 362 | '#title' => t('CSV file'), |
| 363 | '#description' => t('Browse to the file') .'<br >'. (($max_size = parse_size(ini_get('upload_max_filesize'))) ? t('Due to server restrictions, the <strong>maximum upload file size is !max_size</strong>. Files that exceed this size will be disregarded.', array('!max_size' => format_size($max_size))) : ''), |
| 364 | ); |
| 365 | |
| 366 | $form['import']['url'] = array( |
| 367 | '#type' => 'textfield', |
| 368 | '#title' => t('CSV file'), |
| 369 | '#description' => t('Enter the url (http, ftp, file, path...)') .'<br >'. (($max_size = parse_size(ini_get('upload_max_filesize'))) ? t('Due to server restrictions, the <strong>maximum upload file size is !max_size</strong>. Files that exceed this size will be disregarded.', array('!max_size' => format_size($max_size))) : ''), |
| 370 | ); |
| 371 | |
| 372 | $form['import']['csv_format'] = array( |
| 373 | '#type' => 'fieldset', |
| 374 | '#title' => t('Advanced source settings (delimiter and enclosure)'), |
| 375 | '#description' => t('Notice: either you import terms by a file or by a text area, the csv format is the same. Default delimiter is a comma ("<strong><code> , </code></strong>"). Default enclosure is none, but quotation mark ("<strong><code> " </code></strong>") is automatically managed.'), |
| 376 | '#collapsible' => TRUE, |
| 377 | '#collapsed' => ( |
| 378 | ($list_previous_values['import_delimiter'] == $list_recommended_values['import_delimiter']) |
| 379 | && ($list_previous_values['import_enclosure'] == $list_recommended_values['import_enclosure'])), |
| 380 | '#attributes' => array('id' => 'edit-csv-format'), |
| 381 | ); |
| 382 | |
| 383 | $form['import']['csv_format']['import_delimiter'] = array( |
| 384 | '#type' => 'select', |
| 385 | '#title' => t('CSV value delimiter'), |
| 386 | '#options' => $list_import_delimiter, |
| 387 | '#default_value' => $list_previous_values['import_delimiter'], |
| 388 | '#description' => t("Choose the delimiter used in the CSV file you want to import. Tabulation can't be used with text area import."), |
| 389 | '#attributes' => array('id' => 'delimiter'), |
| 390 | ); |
| 391 | |
| 392 | $form['import']['csv_format']['import_delimiter_custom'] = array( |
| 393 | '#type' => 'textfield', |
| 394 | '#title' => '', |
| 395 | '#default_value' => $list_previous_values['import_delimiter_custom'], |
| 396 | '#size' => 2, |
| 397 | '#maxlength' => 1, |
| 398 | ); |
| 399 | |
| 400 | $form['import']['csv_format']['import_enclosure'] = array( |
| 401 | '#type' => 'select', |
| 402 | '#title' => t('CSV value enclosure'), |
| 403 | '#options' => $list_import_enclosure, |
| 404 | '#default_value' => $list_previous_values['import_enclosure'], |
| 405 | '#description' => t('Choose the enclosure used in the CSV file you want to import.'), |
| 406 | '#attributes' => array('id' => 'enclosure'), |
| 407 | ); |
| 408 | |
| 409 | $form['import']['csv_format']['import_enclosure_custom'] = array( |
| 410 | '#type' => 'textfield', |
| 411 | '#title' => '', |
| 412 | '#default_value' => $list_previous_values['import_enclosure_custom'], |
| 413 | '#size' => 2, |
| 414 | '#maxlength' => 1, |
| 415 | ); |
| 416 | |
| 417 | $form['destination'] = array( |
| 418 | '#type' => 'fieldset', |
| 419 | '#title' => t('3. Which vocabulary do you want to import into?'), |
| 420 | '#collapsible' => TRUE, |
| 421 | '#collapsed' => FALSE, |
| 422 | '#description' => t('Terms can be imported into a new vocabulary or in an existing one. You can choose to duplicate an existing vocabulary too in order to check import. You might want to !add-new-vocab.', array( |
| 423 | '!add-new-vocab' => l(t('add a new vocabulary'), 'admin/content/taxonomy/add/vocabulary', array('query' => drupal_get_destination())), |
| 424 | )) .'<br />'. |
| 425 | t('With some import formats as "Fields and links", vocabulary destination is defined by source content and this option is not used.'), |
| 426 | '#attributes' => array('id' => 'edit-destination'), |
| 427 | ); |
| 428 | |
| 429 | $list_vocabularies = taxonomy_get_vocabularies(); |
| 430 | |
| 431 | if (count($list_vocabularies) == 0) { |
| 432 | $form['destination']['#description'] .= '<br />'. t("As there isn't any vocabulary, terms will be imported in a new automatically created vocabulary."); |
| 433 | |
| 434 | $form['destination']['vocabulary_target'] = array( |
| 435 | '#type' => 'value', |
| 436 | '#value' => 'autocreate', |
| 437 | ); |
| 438 | |
| 439 | $form['destination']['vocabulary_id'] = array( |
| 440 | '#type' => 'value', |
| 441 | '#value' => 0, |
| 442 | ); |
| 443 | } |
| 444 | else { |
| 445 | $form['destination']['vocabulary_target'] = array( |
| 446 | '#type' => 'select', |
| 447 | '#options' => $list_vocabulary_target, |
| 448 | '#default_value' => $list_previous_values['vocabulary_target'], |
| 449 | '#description' => t(' |
| 450 | When you want to import a new taxonomy into an existing one, it is recommended to process in three steps in order to allow a good import. |
| 451 | <ul> |
| 452 | <li>First, check the import file with the < <em>Autocreate a new vocabulary</em> > option. Repeat this step while there are warnings and notices.</li> |
| 453 | <li>Second, check new and existing terms merge with the < <em>Duplicate an existing vocabulary</em> > option. This choice creates a duplicate of your target existing vocabulary and import your new terms into. Original nodes attachments are not duplicated.</li> |
| 454 | <li>Finally, you can import your file in the true vocabulary with the < <em>Import in an existing vocabulary</em> > option. This allows you to keep old links between existing terms and nodes.</li> |
| 455 | </ul> |
| 456 | If you only want to create a new vocabulary, the first choice is sufficient, unless when you have multiple files for one vocabulary.'), |
| 457 | ); |
| 458 | |
| 459 | $form['destination']['vocabulary_id'] = array( |
| 460 | '#type' => 'select', |
| 461 | '#title' => t('Vocabulary choice'), |
| 462 | '#options' => array( |
| 463 | 'choose_vocabulary' => t('[Choose an existing vocabulary]'), |
| 464 | ), |
| 465 | '#default_value' => 'choose_vocabulary', |
| 466 | '#description' => t('The vocabulary you want to import the file into.'), |
| 467 | ); |
| 468 | foreach ($list_vocabularies as $vid => $vocabulary) { |
| 469 | $form['destination']['vocabulary_id']['#options'][$vid] = $vocabulary->name; |
| 470 | } |
| 471 | } |
| 472 | |
| 473 | $form['import_options'] = array( |
| 474 | '#type' => 'fieldset', |
| 475 | '#title' => t('4. How to import your terms?'), |
| 476 | '#required' => TRUE, |
| 477 | '#collapsible' => TRUE, |
| 478 | '#collapsed' => FALSE, |
| 479 | ); |
| 480 | |
| 481 | $form['import_options']['existing_items'] = array( |
| 482 | '#type' => 'radios', |
| 483 | '#title' => t('What will existing or previous imported terms become when a term with same name will be imported?'), |
| 484 | '#default_value' => $list_previous_values['existing_items'], |
| 485 | '#description' => t('This option allows to set what previous imported terms will become if a new line contains the same terms. Usually, it indicates an error or a unoptimized source, unless you allow duplicates.<br /> |
| 486 | This option is used too with existing terms in the target vocabulary. Recommended value is to update and merge. If you choose to ignore previous or existing terms, the vocabulary will have duplicate terms.<br /> |
| 487 | Some choices may be currently disabled.'), |
| 488 | ); |
| 489 | if (isset($_COOKIE['has_js'])) { |
| 490 | // Store full list of generic existing_items and set only the correct one in order to keep all options possible with javascript and css. |
| 491 | $form['import_options']['existing_items']['#options'] = $list_import_option; |
| 492 | |
| 493 | // Descriptions and examples of the option existing_items option. |
| 494 | $form['import_options']['help_alone_terms'] = array( |
| 495 | '#type' => 'item', |
| 496 | '#value' => t('Additional help:') .' '. t('Alone terms'), |
| 497 | '#description' => t('This option indicates whether existing terms with the same name should be updated or ignored. If ignored, duplicates may be created.'), |
| 498 | '#prefix' => '<div id="help_alone_terms">', |
| 499 | '#suffix' => '</div>', |
| 500 | ); |
| 501 | $form['import_options']['help_fields_links'] = array( |
| 502 | '#type' => 'item', |
| 503 | '#value' => t('Additional help:') .' '. t('Full term fields and links'), |
| 504 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 505 | t('By nature, only one option can be chosen with this format.') .'<br />'. |
| 506 | t('<ul> |
| 507 | <li><em>"Update and merge"</em>: update term or create it if not exists and merge eventual item with new one.</li> |
| 508 | </ul>' |
| 509 | ), |
| 510 | '#prefix' => '<div id="help_fields_links">', |
| 511 | '#suffix' => '</div>', |
| 512 | ); |
| 513 | $form['import_options']['help_flat'] = array( |
| 514 | '#type' => 'item', |
| 515 | '#value' => t('Additional help:') .' '. t('Terms'), |
| 516 | '#description' => t('This option indicates whether existing terms with the same name should be updated or ignored. If ignored, duplicates may be created.'), |
| 517 | '#prefix' => '<div id="help_flat">', |
| 518 | '#suffix' => '</div>', |
| 519 | ); |
| 520 | $form['import_options']['help_tree_structure'] = array( |
| 521 | '#type' => 'item', |
| 522 | '#value' => t('Additional help:') .' '. t('Tree structure'), |
| 523 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.<br /> |
| 524 | This option is used with last term of the line.') .'<br />'. |
| 525 | t('<ul> |
| 526 | <li><em>"Update and replace"</em>: each parent replaces eventual older ones.</li> |
| 527 | <li><em>"Ignore and create"</em>: child is always created and eventually its parents if they don\'t exist.</li> |
| 528 | <li><em>"Ignore and create all"</em>: Child and its parents are always created, even if they already exist. Duplicates may be created.</li> |
| 529 | </ul>' |
| 530 | ), |
| 531 | '#prefix' => '<div id="help_tree_structure">', |
| 532 | '#suffix' => '</div>', |
| 533 | ); |
| 534 | $form['import_options']['help_polyhierarchy'] = array( |
| 535 | '#type' => 'item', |
| 536 | '#value' => t('Additional help:') .' '. t('Polyhierarchy'), |
| 537 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 538 | t('By nature, only one option can be chosen with this format.') .'<br />'. |
| 539 | t('<ul> |
| 540 | <li><em>"Update and merge"</em>: each child and parents are merged with old ones, except if the child has the same name than parent, in which case a new term is created, because a child cannot be a parent of itself. Warning: on next lines, direct children of this term name will be attached to the first imported term.</li> |
| 541 | </ul>' |
| 542 | ), |
| 543 | '#prefix' => '<div id="help_polyhierarchy">', |
| 544 | '#suffix' => '</div>', |
| 545 | ); |
| 546 | $form['import_options']['help_parents'] = array( |
| 547 | '#type' => 'item', |
| 548 | '#value' => t('Additional help:') .' '. t('First level parents of a list of terms'), |
| 549 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 550 | t('<ul> |
| 551 | <li><em>"Update and merge"</em>: each child and parents are merged with old ones. No duplicate are created.</li> |
| 552 | <li><em>"Update and replace"</em>: each parent replaces eventual older ones.</li> |
| 553 | <li><em>"Ignore and create"</em>: child is always created and eventually its parents if they don\'t exist.</li> |
| 554 | <li><em>"Ignore and create all"</em>: Child and its parents are always created, even if they already exist. Duplicates may be created.</li> |
| 555 | </ul>' |
| 556 | ), |
| 557 | '#prefix' => '<div id="help_parents">', |
| 558 | '#suffix' => '</div>', |
| 559 | ); |
| 560 | $form['import_options']['help_children'] = array( |
| 561 | '#type' => 'item', |
| 562 | '#value' => t('Additional help:') .' '. t('First level children of a list of terms'), |
| 563 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 564 | t('<ul> |
| 565 | <li><em>"Update and merge"</em>: each child and parents are merged with old ones.</li> |
| 566 | <li><em>"Update and replace"</em>: each parent replaces eventual older ones.</li> |
| 567 | <li><em>"Ignore and create"</em>: child is always created and eventually its parents if they don\'t exist.</li> |
| 568 | <li><em>"Ignore and create all"</em>: Child and its parents are always created, even if they already exist. Duplicates may be created.</li> |
| 569 | </ul>' |
| 570 | ), |
| 571 | '#prefix' => '<div id="help_children">', |
| 572 | '#suffix' => '</div>', |
| 573 | ); |
| 574 | $form['import_options']['help_relations'] = array( |
| 575 | '#type' => 'item', |
| 576 | '#value' => t('Additional help:') .' '. t('Related terms'), |
| 577 | '#description' => t('This option indicates whether existing terms with the same name should be updated or ignored. |
| 578 | <p>For example, if existing related terms of term < <code>Drupal</code> > are < <code>Free</code> > and < <code>Open source</code> > and an imported line in the csv file is < <code>"Drupal","Knowledge management","Free"</code> >, then:') .'<br >'. |
| 579 | t('<ul> |
| 580 | <li><em>"Update and merge"</em> choice makes related terms of < <code>Drupal</code> > are now < <code>Free</code> >, < <code>Open source</code> > and < <code>Knowledge management</code> >;</li> |
| 581 | <li><em>"Update and replace"</em> choice makes related terms of < <code>Drupal</code> > are now < <code>Knowledge management</code> > and < <code>Free</code> >;</li> |
| 582 | <li><em>"Ignore and create"</em> choice makes two < <code>Drupal</code> > terms, one with existing related and other items and another one with the imported related terms < <code>Knowledge management</code> > and < <code>Free</code> >, which one has not been duplicated;</li> |
| 583 | <li><em>"Ignore and create all"</em> choice makes two < <code>Drupal</code> > as previously, but create too related term < <code>Free</code> > even if it exist.</li> |
| 584 | </ul></p>' |
| 585 | ), |
| 586 | '#prefix' => '<div id="help_relations">', |
| 587 | '#suffix' => '</div>', |
| 588 | ); |
| 589 | $form['import_options']['help_fields'] = array( |
| 590 | '#type' => 'item', |
| 591 | '#value' => t('Additional help:') .' '. t('Full term definition'), |
| 592 | '#description' => t('This option indicates whether existing terms with the same name should be updated or ignored. If ignored, duplicates may be created.') .'<br />'. |
| 593 | t('<ul> |
| 594 | <li><em>"Update and merge"</em>: update term or create it if not exists and merge eventual description with new one.</li> |
| 595 | <li><em>"Update and replace"</em>: update term or create it if not exists and replace eventual description with new one.</li> |
| 596 | <li><em>"Ignore and create"</em>: term is always created.</li> |
| 597 | </ul>' |
| 598 | ), |
| 599 | '#prefix' => '<div id="help_fields">', |
| 600 | '#suffix' => '</div>', |
| 601 | ); |
| 602 | $form['import_options']['help_descriptions'] = array( |
| 603 | '#type' => 'item', |
| 604 | '#value' => t('Additional help:') .' '. t('Descriptions'), |
| 605 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 606 | t('<ul> |
| 607 | <li><em>"Update and merge"</em>: update term or create it if not exists and merge eventual description with new one.</li> |
| 608 | <li><em>"Update and replace"</em>: update term or create it if not exists and replace eventual description with new one.</li> |
| 609 | <li><em>"Ignore and create"</em>: term is always created.</li> |
| 610 | </ul>' |
| 611 | ), |
| 612 | '#prefix' => '<div id="help_descriptions">', |
| 613 | '#suffix' => '</div>', |
| 614 | ); |
| 615 | $form['import_options']['help_weights'] = array( |
| 616 | '#type' => 'item', |
| 617 | '#value' => t('Additional help:') .' '. t('Weights'), |
| 618 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.'), |
| 619 | '#prefix' => '<div id="help_weights">', |
| 620 | '#suffix' => '</div>', |
| 621 | ); |
| 622 | $form['import_options']['help_synonyms'] = array( |
| 623 | '#type' => 'item', |
| 624 | '#value' => t('Additional help:') .' '. t('Synonyms'), |
| 625 | '#description' => t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 626 | t('<ul> |
| 627 | <li><em>"Update and merge"</em>: update term or create it if not exists and merge eventual synonyms with new ones. Always remove duplicate synonyms.</li> |
| 628 | <li><em>"Update and replace"</em>: update term or create it if not exists and replace eventual synonyms with new ones.</li> |
| 629 | <li><em>"Ignore and create"</em>: term is always created.</li> |
| 630 | </ul>' |
| 631 | ), |
| 632 | '#prefix' => '<div id="help_synonyms">', |
| 633 | '#suffix' => '</div>', |
| 634 | ); |
| 635 | $form['import_options']['help_taxonomy_manager'] = array( |
| 636 | '#type' => 'item', |
| 637 | '#value' => t('Additional help:') .' '. t('Taxonomy manager'), |
| 638 | '#description' => t("When a vocabulary is imported in an existing one, only third option (ignore existing terms) can be used.") .'<br />'. |
| 639 | t('This option indicates whether and how existing terms with the same name should be updated or ignored.') .'<br />'. |
| 640 | t('<ul> |
| 641 | <li><em>"Update and merge"</em>: update term or create it if not exists and merge eventual parents with new ones.</li> |
| 642 | <li><em>"Update and replace"</em>: update term or create it if not exists and replace eventual parents with new ones.</li> |
| 643 | <li><em>"Ignore and create"</em>: term is always created.</li> |
| 644 | </ul>' |
| 645 | ), |
| 646 | '#prefix' => '<div id="help_taxonomy_manager">', |
| 647 | '#suffix' => '</div>', |
| 648 | ); |
| 649 | } |
| 650 | else { |
| 651 | // Use this form only if no javascript (or, in a next evolution, in a second step wizard). |
| 652 | $form['import_options']['#description'] = '<br />'. t("As you see this notice, javascript is not activated on your browser. Only options matching your source content and vocabulary destination needs to be set. Others won't be used. If you want specific examples and options, activate javascript or see <a href=\"!more_help_link\"> advanced help</a>.", array('!more_help_link' => url('admin/help/taxonomy_csv'))); |
| 653 | |
| 654 | $form['import_options']['existing_items']['#options'] = array_intersect_key($list_import_option, array_flip(array( |
| 655 | TAXONOMY_CSV_EXISTING_UPDATE, |
| 656 | TAXONOMY_CSV_EXISTING_UPDATE_MERGE, |
| 657 | TAXONOMY_CSV_EXISTING_UPDATE_REPLACE, |
| 658 | TAXONOMY_CSV_EXISTING_IGNORE, |
| 659 | TAXONOMY_CSV_EXISTING_IGNORE_CREATE, |
| 660 | TAXONOMY_CSV_EXISTING_IGNORE_ALL, |
| 661 | ))); |
| 662 | } |
| 663 | |
| 664 | // Specific options to import relations. |
| 665 | $form['import_options']['relations'] = array( |
| 666 | '#type' => 'fieldset', |
| 667 | '#title' => t('Specific settings of:') .' '. t('Related terms'), |
| 668 | '#collapsible' => TRUE, |
| 669 | '#collapsed' => FALSE, |
| 670 | '#description' => t('Set these options only if you import:') .' '. t('Related terms') .'.', |
| 671 | '#attributes' => array('id' => 'edit-relations'), |
| 672 | ); |
| 673 | $form['import_options']['relations']['relations_create_subrelations'] = array( |
| 674 | '#type' => 'checkbox', |
| 675 | '#title' => t('Import subrelations'), |
| 676 | '#default_value' => $list_previous_values['relations_create_subrelations'], |
| 677 | '#description' => t('This checkbox allows to import subrelations of related terms and not only relations of first column term with others. |
| 678 | <p>For example, with the line < <code>"Paris","London","Bern","Roma"</code> >, default import is to make a link between < <code>Paris</code> > and each of three terms. There is no link between < <code>London</code> > and < <code>Bern</code> > neither < <code>Roma</code> >. Checking this option creates not only relations with first term, but all subrelations too: < <code>London</code> > and < <code>Bern</code> >, < <code>London</code> > and < <code>Roma</code> > and finally < <code>Bern</code> > and < <code>Roma</code> >.</p>'), |
| 679 | ); |
| 680 | // Internal use only. |
| 681 | $form['import_options']['relations']['relations_all_vocabularies'] = array( |
| 682 | '#type' => 'value', |
| 683 | '#title' => t('Make relations with existing terms of all vocabularies'), |
| 684 | '#default_value' => $list_previous_values['relations_all_vocabularies'], |
| 685 | '#description' => t("This checkbox allows to create relations with existing terms in other vocabularies if they don't exist in selected vocabulary."), |
| 686 | '#disabled' => TRUE, |
| 687 | ); |
| 688 | |
| 689 | $form['advanced_options'] = array( |
| 690 | '#type' => 'fieldset', |
| 691 | '#title' => t('5. Advanced options'), |
| 692 | '#collapsible' => TRUE, |
| 693 | '#collapsed' => FALSE, |
| 694 | '#attributes' => array('id' => 'advanced_options'), |
| 695 | ); |
| 696 | |
| 697 | $form['advanced_options']['tweaks'] = array( |
| 698 | '#type' => 'fieldset', |
| 699 | '#title' => t('Tweaks for big or specific vocabularies'), |
| 700 | '#collapsible' => TRUE, |
| 701 | '#collapsed' => ( |
| 702 | ($list_previous_values['disable_internal_cache'] == $list_recommended_values['disable_internal_cache']) |
| 703 | && ($list_previous_values['disable_hierarchy_check'] == $list_recommended_values['disable_hierarchy_check']) |
| 704 | && ($list_previous_values['disable_line_checks'] == $list_recommended_values['disable_line_checks']) |
| 705 | && ($list_previous_values['disable_utf8_check'] == $list_recommended_values['disable_utf8_check']) |
| 706 | ), |
| 707 | ); |
| 708 | |
| 709 | $form['advanced_options']['tweaks']['disable_internal_cache'] = array( |
| 710 | '#type' => 'checkbox', |
| 711 | '#title' => t('Disable internal cache'), |
| 712 | '#default_value' => $list_previous_values['disable_internal_cache'], |
| 713 | '#description' => t("To disable internal cache allows to import vocabularies of any size. Internal cache is used to speed up process, to reduce access to sql base an to be informed about process. When disabled, no information about results can be displayed except eventual first error or warning.<br /> |
| 714 | It's recommended to disable cache if the imported vocabulary is too big (from 1000 or 10000 lines depending on the server), because it avoids memory congestion on server."), |
| 715 | ); |
| 716 | |
| 717 | $form['advanced_options']['tweaks']['disable_hierarchy_check'] = array( |
| 718 | '#type' => 'checkbox', |
| 719 | '#title' => t('Manually set vocabulary hierarchy'), |
| 720 | '#default_value' => $list_previous_values['disable_hierarchy_check'], |
| 721 | ); |
| 722 | $form['advanced_options']['tweaks']['hierarchy_level'] = array( |
| 723 | '#type' => 'radios', |
| 724 | '#title' => '', |
| 725 | '#options' => _taxonomy_csv_info_lists('hierarchy_text'), |
| 726 | '#default_value' => $list_previous_values['hierarchy_level'], |
| 727 | '#prefix' => '<div id="hierarchy_level">', |
| 728 | '#suffix' => '</div>', |
| 729 | ); |
| 730 | $form['advanced_options']['tweaks']['vocabulary_hierarchy_info'] = array( |
| 731 | '#type' => 'item', |
| 732 | '#value' => '', |
| 733 | '#description' => t('Because to calculate vocabulary hierarchy is memory intensive, this option allows to set hierarchy manually without verify it.'), |
| 734 | ); |
| 735 | |
| 736 | $form['advanced_options']['tweaks']['disable_line_checks'] = array( |
| 737 | '#type' => 'checkbox', |
| 738 | '#title' => t('Disable line checks'), |
| 739 | '#default_value' => $list_previous_values['disable_line_checks'], |
| 740 | '#description' => t('If you are sure that vocabulary to import is well formated (utf8, order of items...), you can disable checks.'), |
| 741 | ); |
| 742 | |
| 743 | $form['advanced_options']['tweaks']['disable_utf8_check'] = array( |
| 744 | '#type' => 'checkbox', |
| 745 | '#title' => t('Disable file conversion to UTF-8'), |
| 746 | '#description' => t('This checkbox allows to disable convert to UTF-8, what can resolve problems with some rare server configurations. Be sure your file is UTF-8 encoded when disabling this option. This option is not used with a textarea import.'), |
| 747 | ); |
| 748 | if (function_exists('mb_detect_encoding')) { |
| 749 | $form['advanced_options']['tweaks']['disable_utf8_check']['#default_value'] = $list_previous_values['disable_utf8_check']; |
| 750 | } |
| 751 | else { |
| 752 | $form['advanced_options']['tweaks']['disable_utf8_check']['#default_value'] = TRUE; |
| 753 | $form['advanced_options']['tweaks']['disable_utf8_check']['#disabled'] = TRUE; |
| 754 | $form['advanced_options']['tweaks']['disable_utf8_check']['#description'] .= '<br />'. t('This checkbox is currently disabled, because iconv, GNU recode or mbstring for PHP are not installed on your server.'); |
| 755 | } |
| 756 | |
| 757 | $form['advanced_options']['result_display'] = array( |
| 758 | '#type' => 'fieldset', |
| 759 | '#title' => t('Results informations to display'), |
| 760 | '#collapsible' => TRUE, |
| 761 | '#collapsed' => ( |
| 762 | ($list_previous_values['result_stats'] === $list_recommended_values['result_stats']) |
| 763 | && ($list_previous_values['result_terms'] === $list_recommended_values['result_terms']) |
| 764 | && ($list_previous_values['result_level'] == $list_recommended_values['result_level']) |
| 765 | && ($list_previous_values['result_type'] == $list_recommended_values['result_type']) |
| 766 | ), |
| 767 | ); |
| 768 | |
| 769 | $form['advanced_options']['result_display']['result_display_cache'] = array( |
| 770 | '#type' => 'item', |
| 771 | '#description' => t('Except first warning, no information can be displayed when internal cache is disabled.'), |
| 772 | '#prefix' => '<div id="result_display_cache">', |
| 773 | '#suffix' => '</div>', |
| 774 | ); |
| 775 | |
| 776 | $form['advanced_options']['result_display']['result_choices'] = array( |
| 777 | '#type' => 'checkboxes', |
| 778 | '#options' => array( |
| 779 | 'result_stats' => t('Basic stats on imported terms'), |
| 780 | 'result_terms' => t('List of imported terms'), |
| 781 | ), |
| 782 | '#default_value' => array( |
| 783 | $list_previous_values['result_stats'], |
| 784 | $list_previous_values['result_terms'], |
| 785 | ), |
| 786 | '#prefix' => '<div id="result_display_options">', |
| 787 | ); |
| 788 | |
| 789 | $form['advanced_options']['result_display']['result_level'] = array( |
| 790 | '#type' => 'radios', |
| 791 | '#title' => t('Log level'), |
| 792 | '#options' => array( |
| 793 | 'none' => t('Only first warning'), |
| 794 | 'warnings' => t('Warnings'), |
| 795 | 'notices' => t('Warnings and notices'), |
| 796 | 'infos' => t('Warnings, notices and informations'), |
| 797 | // 'full' => t('Errors, warnings, notices and informations for each term'), |
| 798 | ), |
| 799 | '#default_value' => $list_previous_values['result_level'], |
| 800 | ); |
| 801 | |
| 802 | $form['advanced_options']['result_display']['result_type'] = array( |
| 803 | '#type' => 'radios', |
| 804 | '#title' => t('Group warnings'), |
| 805 | '#options' => array( |
| 806 | 'by_message' => t('By message (compact view)'), |
| 807 | 'by_line' => t('By line (list view)'), |
| 808 | // 'by_collapse' => t('Group warnings and notices by line (collapsible view)'), |
| 809 | ), |
| 810 | '#default_value' => $list_previous_values['result_type'], |
| 811 | '#prefix' => '<div id="result_type">', |
| 812 | '#suffix' => '</div>', |
| 813 | ); |
| 814 | |
| 815 | $form['advanced_options']['result_display']['result_info'] = array( |
| 816 | '#type' => 'item', |
| 817 | '#description' => t('Warning: display warnings, notices and informations, especially by line, can help you to detect issues when submitted list of terms is not clean, but it may be memory intensive.'), |
| 818 | '#suffix' => '</div>', |
| 819 | ); |
| 820 | |
| 821 | $form['import_submit'] = array( |
| 822 | '#type' => 'submit', |
| 823 | '#value' => t('Import'), |
| 824 | ); |
| 825 | |
| 826 | $form['recommended_values_submit'] = array( |
| 827 | '#type' => 'submit', |
| 828 | '#value' => t('Default values'), |
| 829 | '#validate' => array('_taxonomy_csv_form_recommended_values'), |
| 830 | ); |
| 831 | |
| 832 | return $form; |
| 833 | } |
| 834 | |
| 835 | /** |
| 836 | * Handles CSV import form validation. |
| 837 | * |
| 838 | * @see taxonomy_csv_form_import() |
| 839 | */ |
| 840 | function taxonomy_csv_form_import_validate($form, &$form_state) { |
| 841 | $options = &$form_state['values']; |
| 842 | |
| 843 | // First, simplify values to be compatible with Api. |
| 844 | |
| 845 | // Load source local file. Check is made by Api. |
| 846 | // 'url' and 'text' are loaded and checked by Api. |
| 847 | if ($options['source_choice'] == 'path') { |
| 848 | $options['file'] = file_save_upload('path'); |
| 849 | } |
| 850 | // Clean textarea in order to decrease memory usage. |
| 851 | if ($options['source_choice'] != 'text') { |
| 852 | $options['text'] = ''; |
| 853 | } |
| 854 | |
| 855 | // Define true delimiter. |
| 856 | $delimiter = array( |
| 857 | 'comma' => ',', |
| 858 | 'semicolon' => ';', |
| 859 | 'tabulation' => "\t", |
| 860 | 'space' => ' ', |
| 861 | 'currency_sign' => '¤', |
| 862 | 'custom_delimiter' => $options['import_delimiter_custom'], |
| 863 | ); |
| 864 | $options['delimiter'] = $delimiter[$options['import_delimiter']]; |
| 865 | |
| 866 | // Define true enclosure. |
| 867 | $enclosure = array( |
| 868 | 'none' => '', |
| 869 | 'quotation' => '"', |
| 870 | 'custom_enclosure' => $options['import_enclosure_custom'], |
| 871 | ); |
| 872 | $options['enclosure'] = $enclosure[$options['import_enclosure']]; |
| 873 | |
| 874 | // Define result preferences. |
| 875 | foreach ($options['result_choices'] as $key => $value) { |
| 876 | $options[$key] = $value; |
| 877 | } |
| 878 | |
| 879 | // Second, make API checks and eventually update options by reference. |
| 880 | $messages = _taxonomy_csv_vocabulary_import_check_options($options); |
| 881 | |
| 882 | // Non API checks. |
| 883 | if (($options['import_delimiter'] == 'custom_delimiter') |
| 884 | && (empty($options['import_delimiter_custom']))) { |
| 885 | $messages['import_delimiter_custom'] = t('You choose to use a custom delimiter, but your delimiter is empty.'); |
| 886 | } |
| 887 | |
| 888 | if (($options['import_enclosure'] == 'custom_enclosure') |
| 889 | && (empty($options['import_enclosure_custom']))) { |
| 890 | $messages['import_enclosure_custom'] = t('You choose to use a custom enclosure, but your enclosure is empty.'); |
| 891 | } |
| 892 | |
| 893 | if (($options['import_delimiter'] == 'custom_delimiter') |
| 894 | && (drupal_strlen($options['import_delimiter_custom']) > 1)) { |
| 895 | $messages['import_delimiter_custom'] = t('Delimiter should have only one character.'); |
| 896 | } |
| 897 | if (($options['import_enclosure'] == 'custom_enclosure') |
| 898 | && (drupal_strlen($options['import_enclosure_custom']) > 1)) { |
| 899 | $messages['import_enclosure_custom'] = t('Enclosure should have only zero or one character.'); |
| 900 | } |
| 901 | |
| 902 | // Validate form. |
| 903 | foreach ($messages as $item => $message) { |
| 904 | if (in_array($item, $options)) { |
| 905 | form_set_error($item, $message); |
| 906 | } |
| 907 | else { |
| 908 | drupal_set_message($message, 'error'); |
| 909 | } |
| 910 | } |
| 911 | } |
| 912 | |
| 913 | /** |
| 914 | * Handles CSV import form submission and launch batch set. |
| 915 | * |
| 916 | * @see taxonomy_csv_form_import() |
| 917 | */ |
| 918 | function taxonomy_csv_form_import_submit($form, &$form_state) { |
| 919 | // Remember last preferences and prepare only options to be sent to Api. |
| 920 | foreach (array( |
| 921 | 'import_format', |
| 922 | 'source_choice', |
| 923 | 'import_delimiter', |
| 924 | 'import_delimiter_custom', |
| 925 | 'import_enclosure', |
| 926 | 'import_enclosure_custom', |
| 927 | 'vocabulary_target', |
| 928 | 'vocabulary_id', |
| 929 | 'existing_items', |
| 930 | 'relations_create_subrelations', |
| 931 | 'relations_all_vocabularies', |
| 932 | 'disable_internal_cache', |
| 933 | 'disable_hierarchy_check', |
| 934 | 'hierarchy_level', |
| 935 | 'disable_line_checks', |
| 936 | 'disable_utf8_check', |
| 937 | 'result_stats', |
| 938 | 'result_terms', |
| 939 | 'result_level', |
| 940 | 'result_type', |
| 941 | ) as $option) { |
| 942 | variable_set("taxonomy_csv_$option", $form_state['values'][$option]); |
| 943 | $options[$option] = $form_state['values'][$option]; |
| 944 | } |
| 945 | // Finish to prepare $options. Unset useless options for api. |
| 946 | $options['internal_cache'] = !$options['disable_internal_cache']; |
| 947 | $options['hierarchy_check'] = !$options['disable_hierarchy_check']; |
| 948 | $options['line_checks'] = !$options['disable_line_checks']; |
| 949 | $options['utf8_check'] = !$options['disable_utf8_check']; |
| 950 | unset($options['disable_internal_cache']); |
| 951 | unset($options['disable_hierarchy_check']); |
| 952 | unset($options['disable_line_checks']); |
| 953 | unset($options['disable_utf8_check']); |
| 954 | $options['delimiter'] = $form_state['values']['delimiter']; |
| 955 | $options['enclosure'] = $form_state['values']['enclosure']; |
| 956 | unset($options['import_delimiter']); |
| 957 | unset($options['import_delimiter_custom']); |
| 958 | unset($options['import_enclosure']); |
| 959 | unset($options['import_enclosure_custom']); |
| 960 | $options['file'] = $form_state['values']['file']; |
| 961 | if ($options['source_choice'] == 'text') { |
| 962 | $options['text'] = &$form_state['values']['text']; |
| 963 | unset($form_state['values']['text']); |
| 964 | } |
| 965 | $options['path'] = $form_state['values']['path']; |
| 966 | $options['url'] = $form_state['values']['url']; |
| 967 | |
| 968 | // Prepares process batch (will be automatically processed when returns). |
| 969 | taxonomy_csv_vocabulary_import($options); |
| 970 | |
| 971 | // End of form process. Reinitialize choices. |
| 972 | unset($form_state['values']); |
| 973 | unset($form_state['storage']); |
| 974 | $form_state['rebuild'] = TRUE; |
| 975 | } |
| 976 | |
| 977 | /** |
| 978 | * Menu callback of the main export form. |
| 979 | */ |
| 980 | function taxonomy_csv_form_export_prepare() { |
| 981 | // Invoke taxonomy_csv api (defines and functions). |
| 982 | $taxonomy_csv_path = drupal_get_path('module', 'taxonomy_csv'); |
| 983 | require_once("$taxonomy_csv_path/taxonomy_csv.api.inc"); |
| 984 | |
| 985 | // Javascript and css allow to show only available options depending user's choice. |
| 986 | drupal_add_js("$taxonomy_csv_path/taxonomy_csv.js"); |
| 987 | drupal_add_css("$taxonomy_csv_path/taxonomy_csv.css"); |
| 988 | |
| 989 | return drupal_get_form('taxonomy_csv_form_export'); |
| 990 | } |
| 991 | |
| 992 | /** |
| 993 | * Generates the taxonomy CSV export form. |
| 994 | * |
| 995 | * Form contain three fieldsets: |
| 996 | * - 1. How to export (format of csv file) ? |
| 997 | * - 2. Which vocabulary to export ? |
| 998 | * - 3. How to export ? |
| 999 | * 1. Csv delimiter |
| 1000 | * 2. Csv enclosure |
| 1001 | * 3. Csv end of line |
| 1002 | * |
| 1003 | * @ingroup forms |
| 1004 | * @see taxonomy_csv_form_export_validate() |
| 1005 | * @see taxonomy_csv_form_export_submit() |
| 1006 | */ |
| 1007 | function taxonomy_csv_form_export($form_state) { |
| 1008 | // Display main export form |
| 1009 | $list_recommended_values = array( |
| 1010 | 'export_format' => TAXONOMY_CSV_FORMAT_ALONE_TERMS, |
| 1011 | 'export_delimiter' => 'comma', |
| 1012 | 'export_delimiter_custom' => '', |
| 1013 | 'export_enclosure' => 'none', |
| 1014 | 'export_enclosure_custom' => '', |
| 1015 | 'export_line_ending' => 'Unix', |
| 1016 | 'export_order' => 'name', |
| 1017 | 'fields_links_terms_ids' => 'name_if_needed', |
| 1018 | 'fields_links_vocabularies_ids' => 'none', |
| 1019 | ); |
| 1020 | |
| 1021 | // Remember previous values to use in particular when reloading form. |
| 1022 | // If not reloading form, then use previous saved value if exists, else recommended value. |
| 1023 | $list_previous_values = array(); |
| 1024 | foreach ($list_recommended_values as $key => $value) { |
| 1025 | $list_previous_values[$key] = isset($form_state['values'][$key]) ? |
| 1026 | $form_state['values'][$key] : |
| 1027 | variable_get("taxonomy_csv_{$key}", $value); |
| 1028 | } |
| 1029 | |
| 1030 | $list_export_format = _taxonomy_csv_info_lists('list_export_format'); |
| 1031 | |
| 1032 | $list_export_delimiter = array( |
| 1033 | 'comma' => t('« , » (Comma)'), |
| 1034 | 'semicolon' => t('« ; » (Semicolon)'), |
| 1035 | 'tabulation' => t('« » (Tabulation)'), |
| 1036 | 'space' => t('« » (Space)'), |
| 1037 | 'currency_sign' => t('« ¤ » (Currency sign)'), |
| 1038 | 'custom_delimiter' => t('Custom delimiter'), |
| 1039 | ); |
| 1040 | |
| 1041 | $list_export_enclosure = array( |
| 1042 | 'none' => t('None'), |
| 1043 | 'quotation' => t('« " » (Quotation mark)'), |
| 1044 | 'custom_enclosure' => t('Custom enclosure'), |
| 1045 | ); |
| 1046 | |
| 1047 | $list_export_line_ending = array( |
| 1048 | 'Unix' => t('Linux / Unix'), |
| 1049 | 'Mac' => t('Mac'), |
| 1050 | 'Microsoft DOS' => t('Microsoft DOS'), |
| 1051 | ); |
| 1052 | |
| 1053 | $list_export_order = array( |
| 1054 | 'name' => t('Alphabetic order'), |
| 1055 | 'tid' => t('Internal order'), |
| 1056 | 'weight' => t('Weight'), |
| 1057 | ); |
| 1058 | |
| 1059 | // Build form. |
| 1060 | $form = array( |
| 1061 | '#attributes' => array( |
| 1062 | 'enctype' => 'multipart/form-data', |
| 1063 | ) |
| 1064 | ); |
| 1065 | |
| 1066 | $list_vocabularies = taxonomy_get_vocabularies(); |
| 1067 | |
| 1068 | if (count($list_vocabularies) == 0) { |
| 1069 | $form['info'] = array( |
| 1070 | '#type' => 'item', |
| 1071 | '#value' => t("As there isn't any vocabulary, nothing can be exported..."), |
| 1072 | ); |
| 1073 | |
| 1074 | return $form; |
| 1075 | } |
| 1076 | // Else there are vocabularies. |
| 1077 | |
| 1078 | // Used with recommended values button. |
| 1079 | $form['list']['list_recommended_values'] = array( |
| 1080 | '#type' => 'value', |
| 1081 | '#value' => $list_recommended_values, |
| 1082 | ); |
| 1083 | |
| 1084 | $form['format'] = array( |
| 1085 | '#type' => 'fieldset', |
| 1086 | '#title' => t('1. What do you want to export?'), |
| 1087 | '#collapsible' => TRUE, |
| 1088 | '#collapsed' => FALSE, |
| 1089 | ); |
| 1090 | |
| 1091 | $form['format']['export_format'] = array( |
| 1092 | '#type' => 'select', |
| 1093 | '#title' => '', |
| 1094 | '#options' => $list_export_format, |
| 1095 | '#default_value' => $list_previous_values['export_format'], |
| 1096 | '#required' => TRUE, |
| 1097 | ); |
| 1098 | |
| 1099 | $form['format']['info'] = array( |
| 1100 | '#type' => 'item', |
| 1101 | '#description' => t('See <a href="!more_help_link">advanced help</a> for informations about formats.', array('!more_help_link' => url('admin/help/taxonomy_csv'))) .'<br />'. |
| 1102 | t('Only "fields and links" format manages duplicate term names. In all case, you will be notified if a duplicate is found.'), |
| 1103 | ); |
| 1104 | |
| 1105 |