diff --git a/apps/qubit/modules/clipboard/actions/exportAction.class.php b/apps/qubit/modules/clipboard/actions/exportAction.class.php index fcd8cc7124..46de67aad3 100644 --- a/apps/qubit/modules/clipboard/actions/exportAction.class.php +++ b/apps/qubit/modules/clipboard/actions/exportAction.class.php @@ -268,6 +268,28 @@ protected function runExportJob($options) } } + if ( + 'arInformationObjectXmlExportJob' == $jobName + && !$options['current-level-only'] ?? false + ) { + $countRecords = $this->countInformationObjectsToExport($options); + + $xmlExportLimit = sfConfig::get('app_clipboard_export_xml_limit', 1000); + + if ($countRecords > $xmlExportLimit) { + $message = $this->context->i18n->__( + 'This XML export would include %1% records, which exceeds the maximum of %2%. ' + .'Please refine the scope of your export by reducing the number of selected ' + .'items or de-selecting the "Include descendants" option.', + ['%1%' => $countRecords, '%2%' => $xmlExportLimit], + ); + + $this->response->setStatusCode(400); + + return $this->renderText(json_encode(['error' => $message])); + } + } + $job = QubitJob::runJob($jobName, $options); // Generate, store and return a token to associate unauthenticated users @@ -527,6 +549,51 @@ protected function processField($field) } } + /** + * Count the number of information objects that would be included by an export. Accounts for + * descendants, and public-only exports. + * + * @param array $options export options including slugs + * + * @return int the number of records to be exported + */ + private function countInformationObjectsToExport($options) + { + $slugs = $options['params']['slugs'] ?? []; + + if (empty($slugs)) { + return 0; + } + + if ($options['current-level-only'] ?? false) { + return count($slugs); + } + + $placeholders = implode(',', array_fill(0, count($slugs), '?')); + $params = array_values($slugs); + + // Count all information objects that fall within the nested set range + // of the clipboard items (i.e. the items themselves plus descendants). + // When 'public' is set, exclude draft records to match the actual + // export behaviour. + $sql = "SELECT COUNT(DISTINCT d.id) AS total + FROM slug s + INNER JOIN information_object io ON s.object_id = io.id + INNER JOIN information_object d + ON d.lft >= io.lft AND d.rgt <= io.rgt + WHERE s.slug IN ({$placeholders})"; + + if ($options['public'] ?? false) { + $sql .= ' AND d.id IN (SELECT st.object_id FROM status st WHERE st.type_id = ? AND st.status_id = ?)'; + $params[] = QubitTerm::STATUS_TYPE_PUBLICATION_ID; + $params[] = QubitTerm::PUBLICATION_STATUS_PUBLISHED_ID; + } + + $result = QubitPdo::fetchOne($sql, $params); + + return (int) $result->total; + } + private function getJobNameString() { switch ($this->objectType) { diff --git a/apps/qubit/modules/settings/actions/clipboardAction.class.php b/apps/qubit/modules/settings/actions/clipboardAction.class.php index 71bc4f5876..476da6b644 100644 --- a/apps/qubit/modules/settings/actions/clipboardAction.class.php +++ b/apps/qubit/modules/settings/actions/clipboardAction.class.php @@ -28,6 +28,7 @@ class SettingsClipboardAction extends SettingsEditAction 'clipboard_send_message_html', 'clipboard_send_http_method', 'clipboard_export_digitalobjects_enabled', + 'clipboard_export_xml_limit', ]; public static $I18N = [ 'clipboard_send_button_text', @@ -47,6 +48,7 @@ public function earlyExecute() 'clipboard_send_message_html' => $this->i18n->__('Sending...'), 'clipboard_send_http_method' => 'POST', 'clipboard_export_digitalobjects_enabled' => '0', + 'clipboard_export_xml_limit' => '1000', ]; } @@ -63,6 +65,12 @@ protected function addField($name) break; + case 'clipboard_export_xml_limit': + $this->form->setValidator($name, new sfValidatorInteger(['min' => 1])); + $this->form->setWidget($name, new sfWidgetFormInput()); + + break; + case 'clipboard_send_enabled': case 'clipboard_send_http_method': case 'clipboard_export_digitalobjects_enabled': diff --git a/apps/qubit/modules/settings/templates/clipboardSuccess.php b/apps/qubit/modules/settings/templates/clipboardSuccess.php index 4de1300d7a..fad8608d77 100644 --- a/apps/qubit/modules/settings/templates/clipboardSuccess.php +++ b/apps/qubit/modules/settings/templates/clipboardSuccess.php @@ -78,6 +78,14 @@