Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve asset and log CSV exports #783

Merged
merged 21 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
146719f
Initial farmOS Export module.
mstenta Jan 25, 2024
07882e1
Move KML export actions to new farm_export_kml module.
mstenta Jan 25, 2024
60d2357
Provide CSV export actions for asset and log entities via new farm_ex…
mstenta Jan 21, 2024
4e22c5f
Move CSV export action logic to a confirmation form.
mstenta Jan 22, 2024
3cc0c51
Issue #3328886: Make it clear that CSV exports are limited
mstenta Jan 22, 2024
21d022b
Add farm_export_csv to optional modules.
mstenta Jan 18, 2024
5fcb89a
Initial farmOS CSV module.
mstenta Jan 16, 2024
410da5d
Provide a ContentEntityNormalizer with an option to explicity include…
mstenta Jan 22, 2024
5980274
Add logic for restricting columns to supported base and bundle field …
mstenta Jan 24, 2024
9995efd
Provide an EntityReferenceFieldItemNormalizer with options to return …
mstenta Jan 25, 2024
6ccf2cd
Provide a TextLongFieldItemNormalizer with an option to return proces…
mstenta Jan 25, 2024
0a3a508
Provide a TimestampItemNormalizer with an option to return RFC3339 fo…
mstenta Jan 26, 2024
ee34ca6
Configure CSV export normalizers to flatten values.
mstenta Jan 25, 2024
22024a8
Install the farm_export_csv module on sites that have farm_ui_views i…
mstenta Jan 18, 2024
8b8ac5b
Remove CSV REST export displays from log, asset, plan Views.
mstenta Jan 16, 2024
4d05465
Update export docs to describe the difference between asset, log, qua…
mstenta Jan 26, 2024
0bb5fac
Simplify and include count in CSV export question
paul121 Feb 1, 2024
604ce5f
Change export warning message
paul121 Feb 1, 2024
28b2d3b
Use strict type checking for context variables that should be TRUE
paul121 Feb 1, 2024
65c0159
Implement BaseFormIdInterface
paul121 Feb 1, 2024
c0cc0a9
Add CHANGELOG.md line for #783.
mstenta Jan 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- [Recommend running composer update twice #653](https://github.com/farmOS/farmOS/pull/786)
- [Edit form UI improvements #770](https://github.com/farmOS/farmOS/pull/770)
- [Improve asset and log CSV exports #783](https://github.com/farmOS/farmOS/pull/783)

## [3.0.1] 2024-01-18

Expand Down
22 changes: 18 additions & 4 deletions docs/guide/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@

## CSV

All [Asset](/guide/assets), [Log](/guide/logs), and
[Quantity](/guide/quantities) lists in farmOS include an "Export CSV" link at
the bottom that will generate and download a CSV file. Any sorts or filters
that are applied to the list will be represented in the CSV output.
All [Asset](/guide/assets) and [Log](/guide/logs) lists in farmOS provide an
"Export CSV" action that will generate a CSV of selected records. These include
most of the record's information, including columns that are not visible in the
list pages themselves.

[Quantity](/guide/quantities) lists provide an "Export CSV" link at the bottom of the page
that serve a similar purpose. These exports include all of the columns that are
visible on the Quantity list page, including information about the Quantity
itself, as well as some information about the Log records that the Quantity
is attached to.

Any sorts or filters that are applied to the list will be represented in the
CSV output.

**Warning: CSV exports do not include all data.**

The [farmOS API](/development/api) is the best way to get access to all raw data
in a farmOS instance.

## KML

Expand Down
3 changes: 2 additions & 1 deletion farm.profile
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ function farm_modules() {
'farm_lab_test' => t('Lab test logs'),
'farm_birth' => t('Birth logs'),
'farm_medical' => t('Medical logs'),
'farm_export_csv' => t('CSV exporter'),
'farm_import_csv' => t('CSV importer'),
'farm_kml' => t('KML export features'),
'farm_export_kml' => t('KML exporter'),
'farm_import_kml' => t('KML asset importer'),
'farm_map_mapbox' => t('Mapbox map layers: Satellite, Outdoors'),
'farm_api_default_consumer' => t('Default API Consumer'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ dependencies:
- image.style.thumbnail
module:
- asset
- csv_serialization
- farm_group
- farm_location
- image
- options
- rest
- serialization
- state_machine
- user
id: farm_group_members
Expand Down Expand Up @@ -1052,17 +1049,6 @@ display:
plugin_id: result
empty: false
content: 'Displaying @start - @end of @total'
display_link:
id: display_link
table: views
field: display_link
relationship: none
group_type: group
admin_label: ''
plugin_id: display_link
label: 'Export CSV'
empty: false
display_id: csv
display_extenders: { }
cache_metadata:
max-age: 0
Expand All @@ -1073,61 +1059,6 @@ display:
- url.query_args
- user.permissions
tags: { }
csv:
id: csv
display_title: 'CSV export (rest)'
display_plugin: rest_export
position: 2
display_options:
pager:
type: none
options:
offset: 0
style:
type: serializer
options:
uses_fields: false
formats:
csv: csv
row:
type: data_field
options:
field_options:
asset_bulk_form:
alias: ''
raw_output: false
image_target_id:
alias: ''
raw_output: false
id:
alias: ''
raw_output: false
name:
alias: ''
raw_output: false
type:
alias: ''
raw_output: false
flag_value:
alias: ''
raw_output: false
status:
alias: ''
raw_output: false
display_description: ''
display_extenders: { }
path: assets.csv
auth:
- cookie
cache_metadata:
max-age: 0
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- request_format
- url
- user.permissions
tags: { }
page:
id: page
display_title: 'Group members (page)'
Expand Down
5 changes: 5 additions & 0 deletions modules/core/csv/farm_csv.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: farmOS CSV
description: Provides CSV features for farmOS.
type: module
package: farmOS
core_version_requirement: ^10
19 changes: 19 additions & 0 deletions modules/core/csv/farm_csv.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
services:
farm_csv.normalizer.content_entity_normalizer:
class: Drupal\farm_csv\Normalizer\ContentEntityNormalizer
tags:
- { name: normalizer, priority: 10 }
arguments: ['@entity_type.manager', '@entity_type.repository', '@entity_field.manager']
farm_csv.normalizer.text_long_field_item:
class: Drupal\farm_csv\Normalizer\TextLongFieldItemNormalizer
tags:
- { name: normalizer, priority: 10 }
farm_csv.normalizer.entity_reference_field_item:
class: Drupal\farm_csv\Normalizer\EntityReferenceFieldItemNormalizer
tags:
- { name: normalizer, priority: 10 }
arguments: ['@entity.repository']
farm_csv.normalizer.timestamp_item:
class: Drupal\farm_csv\Normalizer\TimestampItemNormalizer
tags:
- { name: normalizer, priority: 10 }
43 changes: 43 additions & 0 deletions modules/core/csv/src/Normalizer/ContentEntityNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Drupal\farm_csv\Normalizer;

use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\serialization\Normalizer\ContentEntityNormalizer as CoreContentEntityNormalizer;

/**
* Normalizes farmOS content entities for CSV exports.
*/
class ContentEntityNormalizer extends CoreContentEntityNormalizer {

/**
* The supported format.
*/
const FORMAT = 'csv';

/**
* {@inheritdoc}
*/
public function normalize($entity, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {
$data = parent::normalize($entity, $format, $context);

// If columns were explicitly included, remove others.
if (!empty($context['include_columns'])) {
foreach (array_keys($data) as $key) {
if (!in_array($key, $context['include_columns'])) {
unset($data[$key]);
}
}
}

return $data;
}

/**
* {@inheritdoc}
*/
public function supportsNormalization($data, string $format = NULL, array $context = []): bool {
return $data instanceof ContentEntityInterface && $format == static::FORMAT;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Drupal\farm_csv\Normalizer;

use Drupal\Core\Config\Entity\ConfigEntityInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItemInterface;
use Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer as CoreEntityReferenceFieldItemNormalizer;

/**
* Normalizes entity reference fields for farmOS CSV exports.
*/
class EntityReferenceFieldItemNormalizer extends CoreEntityReferenceFieldItemNormalizer {

/**
* The supported format.
*/
const FORMAT = 'csv';

/**
* {@inheritdoc}
*/
public function normalize($field_item, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {

// Attempt to load the referenced entity.
/** @var \Drupal\Core\Entity\EntityInterface $entity */
if ($entity = $field_item->get('entity')->getValue()) {

// Return content entity labels, if desired.
if ($entity instanceof ContentEntityInterface && isset($context['content_entity_labels']) && $context['content_entity_labels'] === TRUE) {
return $entity->label();
}

// Return config entity IDs, if desired.
if ($entity instanceof ConfigEntityInterface && isset($context['config_entity_ids']) && $context['config_entity_ids'] === TRUE) {
return $entity->id();
}
}

// Otherwise, delegate to the parent method.
return parent::normalize($field_item, $format, $context);
}

/**
* {@inheritdoc}
*/
public function supportsNormalization($data, string $format = NULL, array $context = []): bool {
return $data instanceof EntityReferenceItemInterface && $format == static::FORMAT;
}

}
40 changes: 40 additions & 0 deletions modules/core/csv/src/Normalizer/TextLongFieldItemNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Drupal\farm_csv\Normalizer;

use Drupal\serialization\Normalizer\FieldItemNormalizer;
use Drupal\text\Plugin\Field\FieldType\TextLongItem;

/**
* Normalizes long text fields for farmOS CSV exports.
*/
class TextLongFieldItemNormalizer extends FieldItemNormalizer {

/**
* The supported format.
*/
const FORMAT = 'csv';

/**
* {@inheritdoc}
*/
public function normalize($field_item, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {
/** @var \Drupal\text\Plugin\Field\FieldType\TextLongItem $field_item */

// Return processed text, if desired.
if (isset($context['processed_text']) && $context['processed_text'] === TRUE) {
return $field_item->get('processed')->getValue();
}

// Delegate to the parent method.
return parent::normalize($field_item, $format, $context);
}

/**
* {@inheritdoc}
*/
public function supportsNormalization($data, string $format = NULL, array $context = []): bool {
return $data instanceof TextLongItem && $format == static::FORMAT;
}

}
31 changes: 31 additions & 0 deletions modules/core/csv/src/Normalizer/TimestampItemNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Drupal\farm_csv\Normalizer;

use Drupal\serialization\Normalizer\TimestampItemNormalizer as CoreTimestampItemNormalizer;

/**
* Normalizes timestamp fields for farmOS CSV exports.
*/
class TimestampItemNormalizer extends CoreTimestampItemNormalizer {

/**
* The supported format.
*/
const FORMAT = 'csv';

/**
* {@inheritdoc}
*/
public function normalize($object, $format = NULL, array $context = []): array|string|int|float|bool|\ArrayObject|NULL {
$data = parent::normalize($object, $format, $context);

// Return the RFC3339 formatted date, if desired.
if (isset($context['rfc3339_dates']) && $context['rfc3339_dates'] === TRUE) {
return $data['value'];
}

return $data;
}

}
5 changes: 5 additions & 0 deletions modules/core/export/farm_export.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: farmOS Export
description: Features for exporting records.
type: module
package: farmOS
core_version_requirement: ^10
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
langcode: en
status: true
dependencies:
module:
- asset
- farm_export_csv
id: asset_csv_action
label: 'Export CSV'
type: asset
plugin: entity:csv_action:asset
configuration: { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
langcode: en
status: true
dependencies:
module:
- farm_export_csv
- log
id: log_csv_action
label: 'Export CSV'
type: log
plugin: entity:csv_action:log
configuration: { }
8 changes: 8 additions & 0 deletions modules/core/export/modules/csv/farm_export_csv.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: farmOS Export CSV
description: Provides a CSV export action for farmOS.
type: module
package: farmOS
core_version_requirement: ^10
dependencies:
- farm:farm_export
- farm:farm_csv