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

✨ Allow the user to modify the query and exported fields. #114

Open
wants to merge 4 commits into
base: 1.2
Choose a base branch
from
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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,32 @@ class User extends Resource

More installation instructions can be found at: [https://docs.laravel-excel.com/nova/1.1/getting-started/installation.html](https://docs.laravel-excel.com/nova/1.1/getting-started/installation.html)

## Modify your export

Currently the export is based on the index fields but this might not be what you want to do.
You can modify with ease the query and the exported fields this way:

```php
/**
* Get the actions available for the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function actions(Request $request)
{
return [
(new DownloadExcel)
->alterateQuery(function ($query) {
$query->select('id', 'first_name');
})
->exportFields(['first_name', 'id']),
];
}
```

Feel free to join tables if necessary but you should always select the fields you want to export to avoid confusions.

## 🎓 Learning Laravel Excel

You can find the full documentation of Laravel Nova Excel [on the website](https://docs.laravel-excel.com/nova).
Expand Down
88 changes: 68 additions & 20 deletions src/Actions/ExportToExcel.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ class ExportToExcel extends Action implements FromQuery, WithCustomChunkSize, Wi
*/
protected $resource;

/**
* @var callable|null
*/
protected $callbackQuery;

/**
* @var array|null
*/
protected $exportAttributes;

/**
* @var Builder
*/
Expand Down Expand Up @@ -90,6 +100,10 @@ public function handleRequest(ActionRequest $request)
$this->handleOnly($this->request);
$this->handleHeadings($query, $this->request);

if (is_callable($this->callbackQuery)) {
($this->callbackQuery)($query);
}

return $this->handle($request, $this->withQuery($query));
}

Expand Down Expand Up @@ -119,6 +133,31 @@ public function handle(ActionRequest $request, Action $exportable): array
: Action::message(__('Resource was successfully exported.'));
}

/**
* @param callable $callable
*
* @return $this
*/
public function tapQuery(callable $callable)
{
$this->callbackQuery = $callable;

return $this;
}

/**
* Sets the attributes to be selected.
*
* @param array|mixed $exportAttributes
* @return $this
*/
public function exportAttributes($exportAttributes)
{
$this->exportAttributes = is_array($exportAttributes) ? $exportAttributes : func_get_args();

return $this;
}

/**
* @param callable $callback
*
Expand Down Expand Up @@ -237,33 +276,42 @@ protected function getDefaultExtension(): string
protected function replaceFieldValuesWhenOnResource(Model $model, array $only = []): array
{
$resource = $this->resolveResource($model);
$fields = $this->resourceFields($resource);
$fields = $this->exportAttributes ?? $this->resourceFields($resource);

$row = [];
foreach ($fields as $field) {
if (!$this->isExportableField($field)) {
continue;
}

if (\in_array($field->attribute, $only, true)) {
$row[$field->attribute] = $field->value;
} elseif (\in_array($field->name, $only, true)) {
// When no field could be found by their attribute name, it's most likely a computed field.
$row[$field->name] = $field->value;
// If custom user fields
if (is_array($fields)) {
foreach ($fields as $field) {
$row[$field] = $model->{$field};
}
} else {
// If index fields
foreach ($fields as $field) {
if (!$this->isExportableField($field)) {
continue;
}

if (\in_array($field->attribute, $only, true)) {
$row[$field->attribute] = $field->value;
} elseif (\in_array($field->name, $only, true)) {
// When no field could be found by their attribute name, it's most likely a computed field.
$row[$field->name] = $field->value;
}
}
}

// Add fields that were requested by ->only(), but are not registered as fields in the Nova resource.
foreach (array_diff($only, array_keys($row)) as $attribute) {
if ($model->{$attribute}) {
$row[$attribute] = $model->{$attribute};
} else {
$row[$attribute] = '';
// Add fields that were requested by ->only(), but are not registered as fields in the Nova resource.
foreach (array_diff($only, array_keys($row)) as $attribute) {
if ($model->{$attribute}) {
$row[$attribute] = $model->{$attribute};
} else {
$row[$attribute] = '';
}
}
}

// Fix sorting
$row = array_merge(array_flip($only), $row);
// Fix sorting
$row = array_merge(array_flip($only), $row);
}

return $row;
}
Expand Down