Пример #1
0
 /**
  * Installs the plugin.
  */
 public function hookInstall()
 {
     // Default stylesheet.
     $this->_options['xml_import_xsl_directory'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libraries';
     $this->_options['xml_import_stylesheet'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . (XmlImportPlugin::isFullCsvImport() ? 'generic_mixed.xsl' : 'generic_item.xsl');
     // Checks the ability to use XSLT.
     try {
         $xslt = new XSLTProcessor();
     } catch (Exception $e) {
         throw new Zend_Exception(__('This plugin requires XSLT support.'));
     }
     $this->_installOptions();
 }
Пример #2
0
 /**
  * Initialize the form.
  */
 public function init()
 {
     parent::init();
     $this->_columnDelimiter = CsvImport_RowIterator::getDefaultColumnDelimiter();
     $this->_enclosure = XmlImportPlugin::isFullCsvImport() ? CsvImport_RowIterator::getDefaultEnclosure() : '"';
     $this->_elementDelimiter = CsvImport_ColumnMap_Element::getDefaultElementDelimiter();
     $this->_tagDelimiter = CsvImport_ColumnMap_Tag::getDefaultTagDelimiter();
     $this->_fileDelimiter = CsvImport_ColumnMap_File::getDefaultFileDelimiter();
     $this->setName('xmlimport');
     $this->setAttrib('id', 'xmlimport');
     $this->setMethod('post');
     // Radio button for selecting record type.
     $this->addElement('radio', 'file_import', array('label' => __('How many files do you want to import?'), 'multiOptions' => array('file' => __('One xml file'), 'folder' => __('All xml files in a folder'), 'recursive' => __('All xml files in a folder (recursive)')), 'description' => __('The xsl sheet will create one csv file from this or these xml files and send it to CsvImport.'), 'required' => true, 'value' => 'file'));
     // One xml file upload.
     $this->_addFileElement();
     // Multiple files.
     $this->addElement('text', 'xml_folder', array('description' => __('The server should be able to access to this uri.')));
     // Helper to manage multiple files.
     $this->addElement('text', 'format_filename', array('description' => __('The format of the filenames to search (format: "suffix.extension", for example "refnum.xml"; default: ".xml").') . ' ' . __('This is useful especially when folders contains multiple xml files.'), 'value' => get_option('xml_import_format_filename')));
     // Radio button for selecting record type.
     if (XmlImportPlugin::isFullCsvImport()) {
         $values = array('Manage' => __('Manage records (import, update, remove)'), 'Report' => __('Omeka CSV Report'), 'Item' => __('Items'), 'File' => __('Files metadata (update)'), 'Mix' => __('Mixed records'), 'Update' => __('Update records'));
         $description = '';
     } else {
         $values = array('Manage' => __('Manage records (import, update, remove) (only if CsvImport full is enabled)'), 'Report' => __('Omeka CSV Report'), 'Item' => __('Items'), 'File' => __('Files metadata (only if CsvImport full is enabled)'), 'Mix' => __('Mixed records (only if CsvImport full is enabled)'), 'Update' => __('Update records (only if CsvImport full is enabled)'));
         $description = __('Metadata of files cannot be imported and nothing can be updated, because you are using standard Csv Import.');
     }
     $this->addElement('radio', 'format', array('label' => __('Choose the type of record you want to import (according to the xsl sheet below):'), 'description' => $description, 'multiOptions' => $values, 'value' => get_option('xml_import_format'), 'required' => TRUE));
     $this->_addColumnDelimiterElement();
     if (XmlImportPlugin::isFullCsvImport()) {
         $this->_addEnclosureElement();
     } else {
         $enclosureElement = new Zend_Form_Element_Hidden('enclosure');
         $enclosureElement->setValue($this->_enclosure);
         $this->addElement($enclosureElement);
     }
     $this->_addElementDelimiterElement();
     $this->_addTagDelimiterElement();
     $this->_addFileDelimiterElement();
     $identifierField = get_option('csv_import_identifier_field');
     if (!empty($identifierField) && $identifierField != 'internal id') {
         $currentIdentifierField = $this->_getElementFromIdentifierField($identifierField);
         if ($currentIdentifierField) {
             $identifierField = $currentIdentifierField->id;
         }
     }
     $values = get_table_options('Element', null, array('record_types' => array('All'), 'sort' => 'alphaBySet'));
     $values = array('' => __('No default identifier field'), 'internal id' => __('Internal id')) + $values;
     $this->addElement('select', 'identifier_field', array('label' => __('Identifier field (required)'), 'description' => __('The default identifier should be available for all record types that are currently imported in the file.'), 'multiOptions' => $values, 'value' => $identifierField));
     if (XmlImportPlugin::isFullCsvImport()) {
         $this->addElement('select', 'action', array('label' => __('Action'), 'multiOptions' => label_table_options(array(CsvImport_ColumnMap_Action::ACTION_UPDATE_ELSE_CREATE => __('Update the record if it exists, else create one'), CsvImport_ColumnMap_Action::ACTION_CREATE => __('Create a new record'), CsvImport_ColumnMap_Action::ACTION_UPDATE => __('Update values of specific fields'), CsvImport_ColumnMap_Action::ACTION_ADD => __('Add values to specific fields'), CsvImport_ColumnMap_Action::ACTION_REPLACE => __('Replace values of all fields'), CsvImport_ColumnMap_Action::ACTION_DELETE => __('Delete the record'), CsvImport_ColumnMap_Action::ACTION_SKIP => __('Skip process of the record')), __('No default action'))));
     } else {
         $actionElement = new Zend_Form_Element_Hidden('action');
         $actionElement->setValue(false);
         $this->addElement($actionElement);
     }
     $values = get_table_options('ItemType', __('No default item type'));
     $this->addElement('select', 'item_type_id', array('label' => __('Item type'), 'multiOptions' => $values));
     $values = get_table_options('Collection', __('No default collection'));
     $this->addElement('select', 'collection_id', array('label' => __('Collection'), 'multiOptions' => $values));
     $this->addElement('checkbox', 'records_are_public', array('label' => __('Make records public'), 'description' => __('Check to make records (items or collections) public by default.')));
     $this->addElement('checkbox', 'records_are_featured', array('label' => __('Feature records'), 'description' => __('Check to make records (items or collections) featured by default.')));
     $this->addElement('checkbox', 'elements_are_html', array('label' => __('Elements are html'), 'description' => __('Set default format of all imported elements as html, else raw text.'), 'value' => get_option('csv_import_html_elements')));
     if (XmlImportPlugin::isFullCsvImport()) {
         $this->addElement('checkbox', 'create_collections', array('label' => __('Create collections'), 'description' => __("If the collection of an item doesn't exist, it will be created.") . '<br />' . __('Use "Update" to set metadata of a collection.'), 'value' => get_option('csv_import_create_collections')));
         $this->addElement('select', 'contains_extra_data', array('label' => __('Contains extra data'), 'description' => __('Other columns can be used as values for non standard data.'), 'multiOptions' => array('no' => __('No, so unrecognized column names will be noticed'), 'manual' => __('Perhaps, so the mapping should be done manually'), 'ignore' => __('Ignore unrecognized column names'), 'yes' => __("Yes, so column names won't be checked")), 'value' => get_option('csv_import_extra_data')));
     } else {
         $createCollectionsElement = new Zend_Form_Element_Hidden('create_collections');
         $createCollectionsElement->setValue(false);
         $this->addElement($createCollectionsElement);
         $extraDataElement = new Zend_Form_Element_Hidden('contains_extra_data');
         $extraDataElement->setValue('no');
         $this->addElement($extraDataElement);
     }
     // XSLT Stylesheet.
     $values = $this->_listDirectory(get_option('xml_import_xsl_directory'), 'xsl');
     // Don't return an error if the folder is unavailable, but simply set an
     // empty list.
     if ($values === false) {
         $values = array();
     }
     $this->addElement('select', 'stylesheet', array('label' => __('Xsl sheet'), 'description' => __('The generic xsl sheet is "xml_import_generic_item.xsl". It transforms a flat xml file with multiple records into a csv file with multiple rows to import via "Item" format.'), 'multiOptions' => $values, 'required' => true, 'value' => get_option('xml_import_stylesheet')));
     $this->addElement('text', 'stylesheet_parameters', array('label' => __('Add specific parameters to use with this xsl sheet'), 'description' => __('Format: "< parameter_1_name = parameter 1 value >< parameter_2_name = parameter 2 value >"...') . ' ' . __('For generic imports, one important parameter is the name of the node that represents a record.') . ' ' . __('It automatically uses the first level node, but it may be a sub level one.') . ' ' . __('In that case, set it like that: "< node = record_name >".'), 'value' => get_option('xml_import_stylesheet_parameters')));
     $this->addDisplayGroup(array('file_import', 'xml_file', 'xml_folder', 'format_filename', 'format'), 'file_type');
     $this->addDisplayGroup(array('column_delimiter_name', 'column_delimiter', 'enclosure_name', 'enclosure', 'element_delimiter_name', 'element_delimiter', 'tag_delimiter_name', 'tag_delimiter', 'file_delimiter_name', 'file_delimiter'), 'csv_format', array('legend' => __('CSV format'), 'description' => __('Set delimiters and enclosure used in the file.')));
     $this->addDisplayGroup(array('identifier_field', 'action', 'item_type_id', 'collection_id', 'records_are_public', 'records_are_featured', 'elements_are_html'), 'default_values', array('legend' => __('Default values'), 'description' => __("Set the default values to use when the column doesn't exist.")));
     $this->addDisplayGroup(array('create_collections', 'contains_extra_data'), 'import_features', array('legend' => __('Features to use'), 'description' => __('Set features used to process the file.')));
     $this->addDisplayGroup(array('stylesheet', 'stylesheet_parameters'), 'xsl_params', array('legend' => __('XSL transformation'), 'description' => __('Set xslt sheet and optional parameters used to process the file.')));
     // Submit button.
     $submit = $this->createElement('submit', 'submit', array('label' => __('Upload'), 'class' => 'submit submit-medium'));
     $submit->setDecorators(array('ViewHelper', array('HtmlTag', array('tag' => 'div', 'class' => 'xmlimportupload'))));
     $this->addElement($submit);
     $this->applyOmekaStyles();
     $this->setAutoApplyOmekaStyles(false);
 }
Пример #3
0
 /**
  * Helper to generate csv file.
  */
 private function _generateCsv($args)
 {
     // Get variables from args array passed into detached process.
     $fileImport = $args['file_import'];
     $xmlFolder = $args['xml_folder'];
     $formatFilename = $args['format_filename'];
     if ($fileImport == 'file') {
         $fileList = $args['file_list'];
     } else {
         $fileList = $this->_listRecursiveDirectory($xmlFolder, $formatFilename, $fileImport == 'recursive');
     }
     $csvFilename = $args['csv_filename'];
     $format = $args['format'];
     $action = $args['action'];
     $identifierField = $args['identifier_field'];
     $itemTypeId = $args['item_type_id'];
     $collectionId = $args['collection_id'];
     $recordsArePublic = $args['public'];
     $recordsAreFeatured = $args['featured'];
     $elementsAreHtml = $args['html_elements'];
     $createCollections = $args['create_collections'];
     $containsExtraData = $args['extra_data'];
     $tagName = $args['tag_name'];
     $columnDelimiter = $args['column_delimiter'];
     $enclosure = $args['enclosure'];
     $elementDelimiter = $args['element_delimiter'];
     $tagDelimiter = $args['tag_delimiter'];
     $fileDelimiter = $args['file_delimiter'];
     $stylesheet = $args['stylesheet'];
     $stylesheetParameters = $args['stylesheet_parameters'];
     // Delimiters for Csv Report are fixed.
     if ($format == 'Report') {
         $columnDelimiter = ',';
         $enclosure = '"';
         $elementDelimiter = CsvImport_ColumnMap_ExportedElement::DEFAULT_ELEMENT_DELIMITER;
         $tagDelimiter = ',';
         $fileDelimiter = ',';
     }
     $endOfLine = "\n";
     // No paramater for this option: fields are always automapped.
     $automapColumns = 1;
     $csvFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'omeka_xml_import_' . date('Ymd-His') . '_' . $this->_sanitizeString($csvFilename) . '.csv';
     $csvFilename = 'Via Xml Import: ' . $csvFilename;
     // Prepare parameters for the stylesheet.
     $parameters = array('delimiter' => $columnDelimiter, 'enclosure' => $enclosure, 'delimiter_element' => $elementDelimiter, 'delimiter_tag' => $tagDelimiter, 'delimiter_file' => $fileDelimiter, 'end_of_line' => $endOfLine, 'node' => $tagName);
     if ($format == 'Manage') {
         $parameters['identifier_field'] = $identifierField;
     }
     // Add custom parameters. Allowed types are already checked.
     $parametersAdded = trim($stylesheetParameters) == '' ? array() : array_values(array_map('trim', explode('><', trim($stylesheetParameters, ' <>'))));
     foreach ($parametersAdded as $value) {
         if (strpos($value, '=') !== FALSE) {
             list($paramName, $paramValue) = explode('=', $value);
             if ($paramName != '') {
                 $parameters[trim($paramName)] = trim($paramValue);
             }
         }
     }
     try {
         // Flag used to keep or remove headers in the first row.
         $flag_first = TRUE;
         // Convert each xml file to csv with the selected stylesheet and
         // parameters. A result can be empty for a file when there are no
         // metadata to import or if the xml file is not a good one.
         foreach ($fileList as $filepath => $filename) {
             // Let headers only for the first file.
             if ($flag_first) {
                 $flag_first = FALSE;
             } else {
                 $parameters['headers'] = 'false';
             }
             $result = $this->_apply_xslt_and_save($filepath, $stylesheet, '', $parameters);
             if ($result === NULL) {
                 $this->_helper->flashMessenger(__('Error when transforming xml file "%s" with the xsl sheet "%s".', $filepath, $stylesheet), 'error');
                 $this->_helper->redirector->goto('index');
             }
             $output = $result;
             // @todo Use Zend/Omeka api.
             $result = $this->_append_file($csvFilePath, $output);
             if ($result === FALSE) {
                 $this->_helper->flashMessenger(__('Error saving data, because the filepath "%s" is not writable.', $filepath), 'error');
                 $this->_helper->redirector->goto('index');
             }
         }
         // Check final resulted file.
         if (filesize($csvFilePath) == 0) {
             $this->_helper->flashMessenger(__('The conversion of the xml file "%s" to csv via the xslt style sheet "%s" gives an empty file. Check your options and your files.', basename($filepath), basename($stylesheet)), 'error');
             $this->_helper->redirector->goto('index');
         }
         // Get the view.
         $view = $this->view;
         // Set up CsvImport validation and column mapping if needed.
         $file = XmlImportPlugin::isFullCsvImport() ? new CsvImport_File($csvFilePath, $columnDelimiter, $enclosure) : new CsvImport_File($csvFilePath, $columnDelimiter);
         if (!$file->parse()) {
             $msg = __('Your CSV file is incorrectly formatted.') . ' ' . $file->getErrorString();
             $this->_helper->flashMessenger($msg, 'error');
             $this->_helper->redirector->goto('index');
         }
         // Go directly to the correct view of CsvImport plugin.
         $csvImportSession = new Zend_Session_Namespace('CsvImport');
         // @see CsvImport_IndexController::indexAction().
         $csvImportSession->setExpirationHops(2);
         $csvImportSession->originalFilename = $csvFilename;
         $csvImportSession->filePath = $csvFilePath;
         // Option used with full Csv Import only.
         $csvImportSession->format = $format;
         $csvImportSession->action = $action;
         $csvImportSession->identifierField = $identifierField;
         $csvImportSession->itemTypeId = $itemTypeId;
         $csvImportSession->collectionId = $collectionId;
         if (XmlImportPlugin::isFullCsvImport()) {
             $csvImportSession->recordsArePublic = $recordsArePublic;
             $csvImportSession->recordsAreFeatured = $recordsAreFeatured;
         } else {
             $csvImportSession->itemsArePublic = $recordsArePublic;
             $csvImportSession->itemsAreFeatured = $recordsAreFeatured;
         }
         // Options used with full Csv Import only.
         $csvImportSession->elementsAreHtml = $elementsAreHtml;
         $csvImportSession->createCollections = $createCollections;
         $csvImportSession->automapColumns = $automapColumns;
         $csvImportSession->containsExtraData = $containsExtraData;
         // Options used with Csv Import standard only.
         $csvImportSession->automapColumnNamesToElements = $automapColumns;
         $csvImportSession->columnDelimiter = $columnDelimiter;
         $csvImportSession->enclosure = $enclosure;
         $csvImportSession->columnNames = $file->getColumnNames();
         $csvImportSession->columnExamples = $file->getColumnExamples();
         // A bug appears in CsvImport when examples contain UTF-8 characters
         // like 'ГЧ„чŁ'.
         foreach ($csvImportSession->columnExamples as &$value) {
             $value = iconv('ISO-8859-15', 'UTF-8', @iconv('UTF-8', 'ISO-8859-15' . '//IGNORE', $value));
         }
         $csvImportSession->elementDelimiter = $elementDelimiter;
         $csvImportSession->tagDelimiter = $tagDelimiter;
         $csvImportSession->fileDelimiter = $fileDelimiter;
         $csvImportSession->ownerId = $this->getInvokeArg('bootstrap')->currentuser->id;
         // All is valid, so we save settings.
         set_option('xml_import_format', $args['format']);
         set_option('xml_import_stylesheet', $args['stylesheet']);
         set_option('xml_import_stylesheet_parameters', $args['stylesheet_parameters']);
         set_option('xml_import_format_filename', $args['format_filename']);
         if (XmlImportPlugin::isFullCsvImport()) {
             set_option(CsvImport_ColumnMap_IdentifierField::IDENTIFIER_FIELD_OPTION_NAME, $args['identifier_field']);
         }
         set_option(CsvImport_RowIterator::COLUMN_DELIMITER_OPTION_NAME, $args['column_delimiter']);
         if (XmlImportPlugin::isFullCsvImport()) {
             set_option(CsvImport_RowIterator::ENCLOSURE_OPTION_NAME, $args['enclosure']);
         }
         set_option(CsvImport_ColumnMap_Element::ELEMENT_DELIMITER_OPTION_NAME, $args['element_delimiter']);
         set_option(CsvImport_ColumnMap_Tag::TAG_DELIMITER_OPTION_NAME, $args['tag_delimiter']);
         set_option(CsvImport_ColumnMap_File::FILE_DELIMITER_OPTION_NAME, $args['file_delimiter']);
         set_option('csv_import_html_elements', $args['html_elements']);
         set_option('csv_import_create_collections', $args['create_collections']);
         set_option('csv_import_extra_data', $args['extra_data']);
         if ($csvImportSession->containsExtraData == 'manual' && $this->session->format != 'Report') {
             $this->_helper->redirector->goto('map-columns', 'index', 'csv-import');
         }
         switch ($format) {
             case 'Manage':
                 $this->_helper->redirector->goto('check-manage-csv', 'index', 'csv-import');
             case 'Report':
                 $this->_helper->redirector->goto('check-omeka-csv', 'index', 'csv-import');
             case 'Mix':
                 $this->_helper->redirector->goto('check-mix-csv', 'index', 'csv-import');
             case 'Update':
                 $this->_helper->redirector->goto('check-update-csv', 'index', 'csv-import');
             default:
                 $this->_helper->redirector->goto('map-columns', 'index', 'csv-import');
         }
     } catch (Exception $e) {
         $msg = __('Error in your xml file, in your xsl sheet or in your options.') . ' ' . __('The xsl sheet should produce a valid csv file with a header and at least one row of metadata.') . ' ' . $e->getMessage();
         $this->_helper->flashMessenger($msg, 'error');
         $this->view->error = $msg;
         $this->_helper->redirector->goto('index');
     }
 }