AbstractResponderViewListener.php (3339B)
1 <?php 2 3 namespace PartKeepr\ExportBundle\EventListener; 4 5 use Exporter\Writer\WriterInterface; 6 use Symfony\Component\HttpFoundation\Request; 7 use Symfony\Component\HttpFoundation\Response; 8 use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent; 9 use Symfony\Component\PropertyAccess\PropertyAccess; 10 11 abstract class AbstractResponderViewListener 12 { 13 const FORMAT = 'null'; 14 15 /** 16 * Converts the response to an exported format. 17 * 18 * @param GetResponseForControllerResultEvent $event 19 * 20 * @return Response|mixed 21 */ 22 public function onKernelView(GetResponseForControllerResultEvent $event) 23 { 24 $controllerResult = $event->getControllerResult(); 25 26 if ($controllerResult instanceof Response) { 27 return; 28 } 29 30 $request = $event->getRequest(); 31 32 $format = $request->attributes->get('_api_format'); 33 if (static::FORMAT !== $format) { 34 return; 35 } 36 37 switch ($request->getMethod()) { 38 case Request::METHOD_POST: 39 $status = 201; 40 break; 41 42 case Request::METHOD_DELETE: 43 $status = 204; 44 break; 45 46 default: 47 $status = 200; 48 break; 49 } 50 51 $columns = []; 52 53 if ($event->getRequest()->query->has('columns')) { 54 $columns = json_decode($event->getRequest()->query->get('columns')); 55 } 56 57 $data = $this->flatten($controllerResult, $columns); 58 59 $file = tempnam(sys_get_temp_dir(), 'partkeepr_export'); 60 unlink($file); 61 $writer = $this->getWriter($file); 62 $writer->open(); 63 foreach ($data as $item) { 64 $writer->write($item); 65 } 66 67 $writer->close(); 68 69 $exportData = file_get_contents($file); 70 71 $event->setResponse(new Response($exportData, $status)); 72 } 73 74 /** 75 * Returns the writer. 76 * 77 * @param $file 78 * 79 * @return WriterInterface 80 */ 81 abstract protected function getWriter($file); 82 83 /** 84 * Flattens the given data. Uses the property accessor to retrieve nested data. 85 * 86 * @param $data array The data, typically an array of entities 87 * @param $mappings array The mappings as array, e.g. [ "name", "description", "storageLocation.name" ] 88 * 89 * @return array 90 */ 91 protected function flatten($data, $mappings) 92 { 93 $accessor = PropertyAccess::createPropertyAccessor(); 94 $finalData = []; 95 foreach ($data as $key => $row) { 96 foreach ($mappings as $mapping) { 97 try { 98 $finalData[$key][$mapping] = $accessor->getValue($row, $mapping); 99 100 if (is_object($finalData[$key][$mapping])) { 101 if ($finalData[$key][$mapping] instanceof \DateTime) { 102 $finalData[$key][$mapping] = $finalData[$key][$mapping]->format(\DateTime::W3C); 103 } 104 } 105 106 if ($finalData[$key][$mapping] === null) { 107 $finalData[$key][$mapping] = "null"; 108 } 109 } catch (\Exception $e) { 110 $finalData[$key][$mapping] = "null"; 111 } 112 } 113 } 114 115 return $finalData; 116 } 117 }