Spaces:
No application file
No application file
namespace Mautic\CoreBundle\Helper; | |
use Mautic\CoreBundle\Model\AbstractCommonModel; | |
class DataExporterHelper | |
{ | |
/** | |
* Standard function to generate an array of data via any model's "getEntities" method. | |
* | |
* Overwrite in your controller if required. | |
* | |
* @param int|null $start | |
* @param AbstractCommonModel<T> $model | |
* | |
* @template T of object | |
* | |
* @return array | |
*/ | |
public function getDataForExport( | |
$start, | |
AbstractCommonModel $model, | |
array $args, | |
callable $resultsCallback = null, | |
bool $skipOrdering = false | |
) { | |
$args['limit'] = max($args['limit'], 200); | |
$args['start'] = $start; | |
$args['skipOrdering'] = $skipOrdering; | |
$results = $model->getEntities($args); | |
$items = $results['results']; | |
if (0 === count($items)) { | |
return null; | |
} | |
unset($results); | |
$toExport = []; | |
unset($args['withTotalCount']); | |
if (is_callable($resultsCallback)) { | |
foreach ($items as $item) { | |
$row = array_map(fn ($itemEncode) => html_entity_decode((string) $itemEncode, ENT_QUOTES), $resultsCallback($item)); | |
$toExport[] = $this->secureAgainstCsvInjection($row); | |
} | |
} else { | |
foreach ($items as $item) { | |
$toExport[] = $this->secureAgainstCsvInjection((array) $item); | |
} | |
} | |
$model->getRepository()->detachEntities($items); | |
return $toExport; | |
} | |
private function secureAgainstCsvInjection(array $row): array | |
{ | |
foreach ($row as $colNum => $colVal) { | |
if ($colVal && in_array(substr($colVal, 0, 1), ['+', '-', '=', '@'])) { | |
$row[$colNum] = ' '.$colVal; | |
} | |
} | |
return $row; | |
} | |
} | |