Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions apps/qubit/modules/clipboard/actions/exportAction.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions apps/qubit/modules/settings/actions/clipboardAction.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
];
}

Expand All @@ -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':
Expand Down
8 changes: 8 additions & 0 deletions apps/qubit/modules/settings/templates/clipboardSuccess.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
<div class="accordion-body">
<?php echo render_field($form->clipboard_export_digitalobjects_enabled
->label(__('Enable digital object export'))); ?>

<?php echo render_field(
$form->clipboard_export_xml_limit
->label(__('Limit the number of information objects that can be exported as XML'))
->help(_('Affects XML clipboard exports only, not CSV exports')),
null,
['type' => 'number'],
); ?>
</div>
</div>
</div>
Expand Down
7 changes: 6 additions & 1 deletion data/fixtures/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ QubitSetting:
name: version
editable: 0
deleteable: 0
value: 197
value: 198
milestone:
name: milestone
editable: 0
Expand All @@ -29,6 +29,11 @@ QubitSetting:
editable: 1
deleteable: 0
value: 1
QubitSetting_clipboard_export_xml_limit:
name: clipboard_export_xml_limit
editable: 1
deleteable: 0
value: 1000
QubitSetting_sort_treeview:
name: sort_treeview_informationobject
editable: 1
Expand Down
45 changes: 45 additions & 0 deletions lib/task/migrate/migrations/arMigration0198.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/*
* This file is part of the Access to Memory (AtoM) software.
*
* Access to Memory (AtoM) is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Access to Memory (AtoM) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Access to Memory (AtoM). If not, see <http://www.gnu.org/licenses/>.
*/

/*
* Add new setting for the maximum number of information objects that can be
* exported as XML from the clipboard.
*
* @package AccesstoMemory
* @subpackage migration
*/
class arMigration0198
{
public const VERSION = 198;
public const MIN_MILESTONE = 2;

public function up($configuration)
{
// Add clipboard XML export limit setting.
if (null === QubitSetting::getByName('clipboard_export_xml_limit')) {
$setting = new QubitSetting();
$setting->name = 'clipboard_export_xml_limit';
$setting->editable = 1;
$setting->value = '1000';
$setting->save();
}

return true;
}
}
Loading