ExportAction::run()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 9.456
c 0
b 0
f 0
cc 4
nc 8
nop 0
1
<?php
2
/**
3
 * HiPanel core package
4
 *
5
 * @link      https://hipanel.com/
6
 * @package   hipanel-core
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2014-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\actions;
12
13
use hipanel\grid\RepresentationCollectionFinder;
14
use hiqdev\higrid\DataColumn;
15
use hiqdev\yii2\export\exporters\ExporterFactoryInterface;
16
use hiqdev\yii2\export\exporters\ExporterInterface;
17
use hiqdev\yii2\export\exporters\Type;
18
use hiqdev\yii2\export\models\CsvSettings;
19
use hiqdev\yii2\export\models\TsvSettings;
20
use hiqdev\yii2\export\models\XlsxSettings;
21
use RuntimeException;
22
use Yii;
23
24
class ExportAction extends IndexAction
25
{
26
    /**
27
     * @var ExporterFactoryInterface
28
     */
29
    private $exporterFactory;
30
31
    public function __construct($id, $controller, ExporterFactoryInterface $exporterFactory, RepresentationCollectionFinder $representationCollectionFinder, array $config = [])
32
    {
33
        parent::__construct($id, $controller, $representationCollectionFinder, $config);
34
        $this->exporterFactory = $exporterFactory;
35
    }
36
37
    public function run()
38
    {
39
        $type = $this->getType();
40
        /** @var ExporterInterface $exporter */
41
        $exporter = $this->exporterFactory->build($type);
42
        $settings = $this->loadSettings($type);
43
        if ($settings !== null) {
44
            $settings->applyTo($exporter);
45
        }
46
        $representation = $this->ensureRepresentationCollection()->getByName($this->getUiModel()->representation);
47
        $gridClassName = $this->guessGridClassName();
48
        $indexAction = null;
49
        if (isset($this->controller->actions()['index'])) {
50
            $indexActionConfig = $this->controller->actions()['index'];
51
            $indexAction = Yii::createObject($indexActionConfig, ['index', $this->controller]);
52
            $indexAction->beforePerform();
53
        }
54
        $dataProvider = $indexAction ? $indexAction->getDataProvider() : $this->getDataProvider();
55
        $grid = Yii::createObject([
56
            'class' => $gridClassName,
57
            'dataProvider' => $dataProvider,
58
            'columns' => $representation->getColumns(),
59
        ]);
60
        $grid->dataColumnClass = DataColumn::class;
61
        $result = $exporter->export($grid);
62
        $filename = $exporter->filename . '.' . $type;
0 ignored issues
show
Bug introduced by
Accessing filename on the interface hiqdev\yii2\export\exporters\ExporterInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
63
64
        return Yii::$app->response->sendContentAsFile($result, $filename);
65
    }
66
67
    public function loadSettings($type)
68
    {
69
        $map = [
70
            Type::CSV => CsvSettings::class,
71
            Type::TSV => TsvSettings::class,
72
            Type::XLSX => XlsxSettings::class,
73
        ];
74
75
        $settings = Yii::createObject($map[$type]);
76
        if ($settings->load(Yii::$app->request->get(), '') && $settings->validate()) {
77
            return $settings;
78
        }
79
80
        return null;
81
    }
82
83
    protected function getType()
84
    {
85
        return Yii::$app->request->get('format');
86
    }
87
88
    /**
89
     * @return string
90
     * @throws RuntimeException
91
     */
92
    protected function guessGridClassName(): string
93
    {
94
        $controllerName = ucfirst($this->controller->id);
95
        $ns = implode('\\', array_diff(explode('\\', get_class($this->controller)), [
96
            $controllerName . 'Controller', 'controllers',
97
        ]));
98
        $girdClassName = sprintf('\%s\grid\%sGridView', $ns, $controllerName);
99
        if (class_exists($girdClassName)) {
100
            return $girdClassName;
101
        }
102
103
        throw new RuntimeException("ExportAction cannot find a {$girdClassName}");
104
    }
105
}
106