diff --git a/apps/qubit/modules/clipboard/actions/exportAction.class.php b/apps/qubit/modules/clipboard/actions/exportAction.class.php index 9edef64836..219b5839e7 100644 --- a/apps/qubit/modules/clipboard/actions/exportAction.class.php +++ b/apps/qubit/modules/clipboard/actions/exportAction.class.php @@ -28,6 +28,7 @@ class ClipboardExportAction extends DefaultEditAction 'includeAllLevels', 'includeDigitalObjects', 'includeDrafts', + 'includeNonVisibleElements', ]; private $choices = []; @@ -80,6 +81,19 @@ public function execute($request) $this->digitalObjectsAvailable = true; } + // Determine if there are non-visible elements that should be hidden + $this->nonVisibleElementsIncluded = false; + $defTemplate = sfConfig::get(('app_default_template_'.strtolower($this->objectType))); + + foreach (sfConfig::getAll() as $setting => $value) { + if ( + (false !== strpos($setting, ('app_element_visibility_'.$defTemplate))) + && (0 == sfConfig::get($setting)) + ) { + $this->nonVisibleElementsIncluded = true; + } + } + // Show export options panel if: // information object type // or, if actor type and digital objects are on the clipboard @@ -110,6 +124,13 @@ public function execute($request) && $this->context->user->isAuthenticated() && 'on' == $request->getParameter('includeDrafts'); + // Get field includeNonVisibleElements if: + // options enabled + // and, user is authenticated + $this->nonVisibleElementsIncluded = $this->showOptions + && $this->context->user->isAuthenticated() + && 'on' == $request->getParameter('includeNonVisibleElements'); + parent::execute($request); $this->response->addJavaScript('exportOptions', 'last'); @@ -160,6 +181,7 @@ public function execute($request) 'public' => !$this->draftsIncluded, 'objectType' => $this->objectType, 'levels' => $levelsOfDescription, + 'nonVisibleElementsIncluded' => $this->nonVisibleElementsIncluded, ]; $msg = ('xml' == $this->formatType) ? 'XML export' : 'CSV export'; @@ -428,6 +450,28 @@ protected function addField($name) $this->form->setDefault('includeDrafts', true); } + break; + // Enable field includeNonVisibleElements if: + // information object type + // and, user is authenticated + case 'includeNonVisibleElements': + if ( + 'informationObject' == $this->objectType + && $this->context->user->isAuthenticated() + ) { + $this->form->setWidget( + 'includeNonVisibleElements', + new sfWidgetFormInputCheckbox( + ['label' => __('Include non-visible elements')] + ) + ); + + $this->helpMessages[] = __( + 'Choosing "Include non-visible elements" will include those not marked as Visible Elements.' + ); + $this->form->setDefault('includeNonVisibleElements', false); + } + break; default: diff --git a/js/exportOptions.js b/js/exportOptions.js index 856ad6a178..7f65de2eeb 100644 --- a/js/exportOptions.js +++ b/js/exportOptions.js @@ -167,7 +167,7 @@ onObjectTypeChange: function () { - + var url = window.location.href.split('?')[0] + '?type='; var type = this.$type.val().trim(); switch (type) diff --git a/lib/flatfile/QubitFlatfileExport.class.php b/lib/flatfile/QubitFlatfileExport.class.php index 441a7d8c06..b69b01c7bd 100644 --- a/lib/flatfile/QubitFlatfileExport.class.php +++ b/lib/flatfile/QubitFlatfileExport.class.php @@ -40,6 +40,8 @@ class QubitFlatfileExport protected $rowsPerFile = 1000; // how many rows until creating new export file protected $separatorChar = '|'; // character to use when imploding arrays to a single value + protected $params; + protected $nonVisibleElementsIncluded; /* * Constructor @@ -243,6 +245,10 @@ public function exportResource(&$resource) $this->loadResourceSpecificConfiguration(get_class($resource)); } + if (!$this->params['nonVisibleElementsIncluded']) { + $this->getHiddenVisibleElementCsvHeaders(); + } + $this->resource = $resource; // If writing to a directory, generate filename periodically to keep each @@ -269,6 +275,13 @@ public function exportResource(&$resource) } } + $this->prepareRowFromResource(); + + if (!empty($this->nonVisibleElementsIncluded)) { + // Remove elements from $this->columnNames that are in $this->nonVisibleElementsIncluded + $this->columnNames = array_diff($this->columnNames, $this->nonVisibleElementsIncluded); + } + // If file doesn't yet exist, write headers if (!file_exists($filePath)) { $this->appendRowToCsvFile($filePath, $this->columnNames); @@ -279,9 +292,8 @@ public function exportResource(&$resource) Qubit::clearClassCaches(); } - $this->prepareRowFromResource(); - // Write row to file and initialize row + $this->row = array_slice($this->row, 0, count($this->columnNames)); $this->appendRowToCsvFile($filePath, $this->row); $this->row = array_fill(0, count($this->columnNames), null); ++$this->rowsExported; @@ -296,8 +308,9 @@ public function prepareRowFromResource() foreach ($this->columnNames as $index => $column) { $value = $this->row[$index]; - // If row value hasn't been set to anything, attempt to get resource property - if (null === $value) { + // If row value hasn't been set to anything and element is not hidden, + // attempt to get resource property + if (null === $value && !in_array($column, $this->nonVisibleElementsIncluded)) { if (in_array($column, $this->standardColumns)) { $value = $this->resource->{$column}; } elseif (($sourceColumn = array_search($column, $this->columnMap)) !== false) { @@ -305,15 +318,72 @@ public function prepareRowFromResource() } elseif (isset($this->propertyMap[$column])) { $value = $this->resource->getPropertyByName($this->propertyMap[$column])->__toString(); } - } - // Add column value (imploding if necessary) - $this->row[$index] = $this->content($value); + // Add column value (imploding if necessary) + $this->row[$index] = $this->content($value); + } else { + // Unset hidden elements columns + unset($this->row[$index]); + } } $this->modifyRowBeforeExport(); } + /** + * Get parameters to determine hidden elements. + * + * @param array parameters for CSV export + * @param mixed $params + */ + public function passParams($params) + { + $this->params = $params; + } + + /** + * Get list of hidden elements. + */ + public function getHiddenVisibleElementCsvHeaders() + { + $nonVisibleElementsIncluded = []; + $nonVisibleElements = []; + + if (!$this->params['nonVisibleElementsIncluded']) { + $template = sfConfig::get('app_default_template_'.strtolower($this->params['objectType'])); + + // Get list of elements hidden from settings + foreach (sfConfig::getAll() as $setting => $value) { + if ( + (false !== strpos($setting, ('app_element_visibility_'.$template))) + && (!strpos($setting, ('__source'))) + && (0 == sfConfig::get($setting)) + ) { + array_push($nonVisibleElements, $setting); + } + } + + if (!empty($nonVisibleElements)) { + $mapPath = sfConfig::get('sf_lib_dir').DIRECTORY_SEPARATOR.'job/visibleElementsHeaderMap.yml'; + $headers = sfYaml::load($mapPath); + + // Get xml/csv headers to remove + foreach ($nonVisibleElements as $e) { + $prefix = 'app_element_visibility_'; + $element = str_replace($prefix, '', $e); + + if (array_key_exists($element, $headers)) { + foreach ($headers[$element]['csv'] as $ele) { + array_push($nonVisibleElementsIncluded, $ele); + } + } + } + } + } + + $this->nonVisibleElementsIncluded = $nonVisibleElementsIncluded; + } + /* * Custom configuration logic * diff --git a/lib/job/arInformationObjectCsvExportJob.class.php b/lib/job/arInformationObjectCsvExportJob.class.php index a6b8858dbb..a3f91d5c61 100644 --- a/lib/job/arInformationObjectCsvExportJob.class.php +++ b/lib/job/arInformationObjectCsvExportJob.class.php @@ -72,6 +72,9 @@ protected function exportResource($resource, $path) */ protected function exportDataAndDigitalObject($resource, $path) { + // Pass parameters to QubitFlatfileExport to determine hidden visible elements + $this->csvWriter->passParams($this->params); + // Append resource metadata to CSV file $this->csvWriter->exportResource($resource); diff --git a/lib/job/arInformationObjectXmlExportJob.class.php b/lib/job/arInformationObjectXmlExportJob.class.php index 4599ef9e33..33704033ad 100644 --- a/lib/job/arInformationObjectXmlExportJob.class.php +++ b/lib/job/arInformationObjectXmlExportJob.class.php @@ -90,6 +90,27 @@ protected function exportResource($resource, $path) } } + $nonVisibleElementsIncluded = $this->getHiddenVisibleElementXmlHeaders(); + + // Remove hidden visible elements from xml + if (!empty($nonVisibleElementsIncluded) && !$this->params['nonVisibleElementsIncluded']) { + foreach ($nonVisibleElementsIncluded as $element) { + // Determine if opening tag has additional elements that needs to + // be removed for closing tag + // ex. + $parts = explode(' ', $element, 2); + + // Set regular expression to match xml headers + if ('' != $parts[1]) { + $pattern = '/<'.$element.'.*?<\/'.$parts[0].'>/s'; + } else { + $pattern = '/<'.$element.'.*?<\/'.$element.'>/s'; + } + + $xml = preg_replace($pattern, '', $xml); + } + } + $filename = exportBulkBaseTask::generateSortableFilename( $resource, 'xml', @@ -109,4 +130,47 @@ protected function exportResource($resource, $path) ++$this->itemsExported; $this->logExportProgress(); } + + /** + * Get list of hidden elements. + * + * @return array hidden elements + */ + protected function getHiddenVisibleElementXmlHeaders() + { + $nonVisibleElementsIncluded = []; + $nonVisibleElements = []; + + $template = sfConfig::get('app_default_template_'.strtolower($this->params['objectType'])); + + // Get list of elements hidden from settings + foreach (sfConfig::getAll() as $setting => $value) { + if ( + (false !== strpos($setting, ('app_element_visibility_'.$template))) + && (!strpos($setting, ('__source'))) + && (0 == sfConfig::get($setting)) + ) { + array_push($nonVisibleElements, $setting); + } + } + + if (!empty($nonVisibleElements)) { + $mapPath = sfConfig::get('sf_lib_dir').DIRECTORY_SEPARATOR.'job/visibleElementsHeaderMap.yml'; + $headers = sfYaml::load($mapPath); + + // Get xml/csv headers to remove + foreach ($nonVisibleElements as $e) { + $prefix = 'app_element_visibility_'; + $element = str_replace($prefix, '', $e); + + if (array_key_exists($element, $headers)) { + foreach ($headers[$element]['xml'] as $ele) { + array_push($nonVisibleElementsIncluded, $ele); + } + } + } + } + + return $nonVisibleElementsIncluded; + } } diff --git a/lib/job/visibleElementsHeaderMap.yml b/lib/job/visibleElementsHeaderMap.yml new file mode 100644 index 0000000000..d210eba141 --- /dev/null +++ b/lib/job/visibleElementsHeaderMap.yml @@ -0,0 +1,546 @@ +# Headers mapping used for hiding Visible Elements form exports +--- +isad_access_points_area: + label: "Access points" + csv: + - eventActors + - subjectAccessPoints + - placeAccessPoints + - nameAccessPoints + - genreAccessPoints + xml: + - controlaccess +isad_allied_materials_area: + label: "Allied materials area" + csv: + - locationOfOriginals + - locationOfCopies + - relatedUnitsOfDescription + - publicationNote + xml: + - originalsloc + - altformavail + - relatedmaterial + - bibliography +isad_appraisal_destruction: + label: "Appraisal" + csv: + - appraisal + xml: + - appraisal +isad_archival_history: + label: "Archival history" + csv: + - archivalHistory + xml: + - custodhist +isad_control_archivists_notes: + label: "Archivist's notes" + csv: + - archivistNote + xml: + - processinfo +isad_conditions_of_access_use_area: + label: "Conditions of access and use area" + csv: + - accessConditions + - reproductionConditions + - languageNote + - physicalCharacteristics + - findingAids + xml: + - accessrestrict + - userestrict + - phystech + - otherfindaid +isad_content_and_structure_area: + label: "Content and structure area" + csv: + - scopeAndContent + - appraisal + - accruals + - arrangement + xml: + - scopecontent + - appraisal + - accurals + - arrangement +isad_context_area: + label: "Context area" + csv: + - repository + - archivalHistory + - acquisition + xml: + - repository + - publisher + - custodhist + - acqinfo +isad_control_dates: + label: "Dates of creation" + csv: + - revisionHistory + xml: + - date +isad_description_control_area: + label: "Description control area" + csv: + - descriptionIdentifier + - institutionIdentifier + - rules + - sources + - archivistNote + - revisionHistory + - descriptionStatus + - levelOfDetail + - languageOfDescription + xml: + - processinfo + - eadid + - odd type="institutionIdentifier" + - descrules + - note type="sourcesDescription" + - odd type="statusDescription" + - odd type="levelOfDetail" + - langusage +isad_control_description_identifier: + label: "Description identifier" + csv: + - descriptionIdentifier + xml: + - odd type="descriptionIdentifier" +isad_identity_area: + label: "Identity area" + csv: + - identifier + - title + - levelOfDescription + - extentAndMedium + - eventDates + - eventTypes + xml: + - eadid + - titlestmt + - physdesc + - unitdate +isad_immediate_source: + label: "Immediate source of acquisition or transfer" + csv: + - acquisition + xml: + - acqinfo +isad_control_institution_identifier: + label: "Institution identifier" + csv: + - institutionIdentifier + xml: + - odd type="institutionIdentifier" +isad_control_languages: + label: "Language(s)" + csv: + - languageOfDescription + xml: + - language +isad_control_level_of_detail: + label: "Level of detail" + csv: + - levelOfDetail + xml: + - odd type="levelOfDetail" +isad_notes: + label: "Notes" + csv: + - generalNote + xml: + - note type="generalNote" +isad_notes_area: + label: "Notes area" + csv: + - generalNote + - alternativeIdentifierLabels + - alternativeIdentifiers + xml: + - note type="generalNote" + - unitid type="alternative" +isad_physical_condition: + label: "Physical characteristics and technical requirements" + csv: + - physicalCharacteristics + xml: + - phystech +isad_control_rules_conventions: + label: "Rules or conventions" + csv: + - rules + xml: + - descrules +isad_control_scripts: + label: "Script(s)" + csv: + - script + xml: + - scriptcode +isad_control_sources: + label: "Sources" + csv: + - sources + xml: + - note type="sourcesDescription" +isad_control_status: + label: "Status" + csv: + - publicationStatus + xml: + - odd type="publicationStatus" +rad_access_points_area: + label: "Access points" + csv: + - subjectAccessPoints + - placeAccessPoints + - nameAccessPoints + - genreAccessPoints + xml: + - name role="subject" + - genreform + - subject + - geogname +rad_archival_description_area: + label: "Archival description area" + csv: + - archivalHistory + - scopeAndContent + xml: + - custodhist + - scopecontent +rad_material_specific_details_area: + label: "Class of material specific details area" + csv: + - radStatementOfScaleCartographic + - radStatementOfProjection + - radStatementOfCoordinates + - radStatementOfScaleArchitectural + - radIssuingJurisdiction + xml: + - materialspec +rad_conservation_notes: + label: "Conservation note(s)" + csv: + - radNoteConservation + xml: + - odd type="conservation" +rad_description_control_area: + label: "Control area" + csv: + - descriptionIdentifier + - institutionIdentifier + - rules + - revisionHistory + - sources + - languageOfDescription + - descriptionStatus + - levelOfDetail + - scriptOfDescription + xml: + - odd type="descriptionIdentifier" + - odd type="institutionIdentifier" + - descrules + - date + - note type="sourcesDescription" + - odd type="statusDescription" + - odd type="levelOfDetail" +rad_archival_history: + label: "Custodial history" + csv: + - archivalHistory + xml: + - custodhist +rad_control_dates: + label: "Dates of creation" + csv: + - revisionHistory + xml: + - date +rad_dates_of_creation_area: + label: "Dates of creation area" + csv: + - eventDates + - eventTypes + - eventActors + - eventPlaces + xml: + - unitdate + - name role="eventTypes" +rad_control_description_identifier: + label: "Description identifier" + csv: + - descriptionIdentifier + xml: + - odd type="descriptionIdentifier" +rad_edition_area: + label: "Edition area" + csv: + - radEdition + - radEditionStatementOfResponsibility + xml: + - edition +rad_general_notes: + label: "General note(s)" + csv: + - generalNote + xml: + - note type="generalNote" +rad_immediate_source: + label: "Immediate source of acquisition" + csv: + - acquisition + xml: + - acqinfo +rad_control_institution_identifier: + label: "Institution identifier" + csv: + - institutionIdentifier + xml: + - odd type="institutionIdentifier" +rad_control_language: + label: "Language" + csv: + - languageOfDescription + xml: + - langusage +rad_control_level_of_detail: + label: "Level of detail" + csv: + - levelOfDetail + xml: + - odd type="levelOfDetail" +rad_notes_area: + label: "Notes area" + csv: + - physicalCharacteristics + - acquisition + - arrangement + - languageNote + - language + - script + - locationOfOriginals + - locationOfCopies + - accessConditions + - reproductionConditions + - findingAids + - relatedUnitsOfDescription + - accruals + - generalNote + - radNoteAccompanyingMaterial + - radNoteAlphaNumericDesignation + - radNoteConservation + - radNoteEdition + - radNotePhysicalDescription + - radNotePublishersSeries + - radNoteRights + - radNoteSignaturesInscriptions + - radNoteCast + - radNoteCredits + xml: + - phystech + - acqinfo + - arrangement + - langmaterial + - originalsloc + - altformavail + - accessrestrict + - userestrict + - otherfindaid + - relatedmaterial + - accruals + - note type="generalNote" + - odd type="material" + - odd type="alphanumericDesignation" + - odd type="conservation" + - odd type="edition" + - odd type="physDesc" + - odd type="bibSeries" + - odd type="rights" +rad_physical_condition: + label: "Physical condition" + csv: + - physicalCharacteristics + xml: + - phystech +rad_physical_description_area: + label: "Physical description area" + csv: + - extentAndMedium + xml: + - physdesc +rad_publishers_series_area: + label: "Publisher's series area" + csv: + - radTitleProperOfPublishersSeries + - radParallelTitlesOfPublishersSeries + - radOtherTitleInformationOfPublishersSeries + - radStatementOfResponsibilityRelatingToPublishersSeries + - radNumberingWithinPublishersSeries + - radPublishersSeriesNote + xml: + - bibseries +rad_rights_notes: + label: "Rights note(s)" + csv: + - radNoteRights + xml: + - odd type="rights" +rad_control_rules_conventions: + label: "Rules or conventions" + csv: + - rules + xml: + - descrules +rad_control_script: + label: "Script" + csv: + - script + xml: +rad_control_sources: + label: "Sources" + csv: + - sources + xml: + - note type="sourcesDescription" +rad_standard_number_area: + label: "Standard number area" + csv: + - radStandardNumber + xml: + - unitid type="standard" +rad_control_status: + label: "Status" + csv: + - publicationStatus + xml: + - odd type="publicationStatus" +rad_title_responsibility_area: + label: "Title and statement of responsibility area" + csv: + - title + - levelOfDescription + - repository + - identifier + - radGeneralMaterialDesignation + - alternateTitle + - radOtherTitleInformation + - radTitleVariationsInTitle + - radTitleSourceOfTitleProper + - radTitleParallelTitles + - radTitleContinues + - radTitleStatementOfResponsibilityNote + - radTitleAttributionsAndConjectures + - alternativeIdentifiers + - alternativeIdentifierLabels + xml: + - titlestmt + - repository + - unitid + - unittitle type="parallel" + - unittitle type="otherInfo" + - odd type="titleVariation" + - odd type="titleSource" + - odd type="titleParallel" + - odd type="titleContinuation" + - odd type="titleStatRep" + - odd type="titleAttributions" + - unitid type="alternative" +dacs_identity_area: + label: "Identity area" + csv: + - identifier + - title + - levelOfDescription + - extentAndMedium + - repository + - eventDates + - eventTypes + xml: + - eadid + - titlestmt + - physdesc + - repository + - unitdate +dacs_content_area: + label: "Content and structure area" + csv: + - scopeAndContent + - arrangement + xml: + - scopecontent + - arrangement +dacs_conditions_of_access_area: + label: "Conditions of access and use area" + csv: + - accessConditions + - reproductionConditions + - languageNote + - physicalCharacteristics + - findingAids + xml: + - accessrestrict + - userestrict + - phystech + - otherfindaid +dacs_acquisition_area: + label: "Acquisition and appraisal area" + csv: + - acquisition + - appraisal + - accruals + - archivalHistory + xml: + - acqinfo + - appraisal + - accurals + - custodhist +dacs_materials_area: + label: "Related materials area" + csv: + - locationOfOriginals + - locationOfCopies + - relatedUnitsOfDescription + - publicationNote + xml: + - originalsloc + - altformavail + - relatedmaterial + - bibliography +dacs_notes_area: + label: "Notes area" + csv: + - generalNote + - alternativeIdentifierLabels + - alternativeIdentifiers + xml: + - note type="generalNote" + - unitid type="alternative" +dacs_control_area: + label: "Description control area" + csv: + - rules + - sources + - archivistNote + xml: + - descrules + - note type="sourcesDescription" + - processinfo +dacs_access_points_area: + label: "Access points" + csv: + - subjectAccessPoints + - placeAccessPoints + - nameAccessPoints + - genreAccessPoints + - eventActors + xml: + - controlaccess +dacs_physical_access: + label: "Physical access" + csv: + - accessionNumber + xml: diff --git a/plugins/arDominionB5Plugin/modules/clipboard/templates/exportSuccess.php b/plugins/arDominionB5Plugin/modules/clipboard/templates/exportSuccess.php index 712a378305..7d26158396 100644 --- a/plugins/arDominionB5Plugin/modules/clipboard/templates/exportSuccess.php +++ b/plugins/arDominionB5Plugin/modules/clipboard/templates/exportSuccess.php @@ -61,6 +61,9 @@ includeDigitalObjects)) { ?> includeDigitalObjects); ?> + includeNonVisibleElements)) { ?> + includeNonVisibleElements); ?> +