Passed
Push — develop ( cddb1d...e5b86c )
by Andrew
05:45
created

FileController::actionImportCsv()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 55
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 55
rs 9.344
c 0
b 0
f 0
cc 3
nc 4
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Retour plugin for Craft CMS 3.x
4
 *
5
 * Retour allows you to intelligently redirect legacy URLs, so that you don't
6
 * lose SEO value when rebuilding & restructuring a website
7
 *
8
 * @link      https://nystudio107.com/
9
 * @copyright Copyright (c) 2018 nystudio107
10
 */
11
12
namespace nystudio107\retour\controllers;
13
14
use nystudio107\retour\Retour;
15
use nystudio107\retour\assetbundles\retour\RetourImportAsset;
16
use nystudio107\retour\helpers\MultiSite as MultiSiteHelper;
17
use nystudio107\retour\helpers\Permission as PermissionHelper;
18
19
use Craft;
20
use craft\helpers\ArrayHelper;
21
use craft\helpers\UrlHelper;
22
use craft\web\Controller;
23
24
use yii\base\InvalidConfigException;
25
use yii\web\Response;
26
use yii\web\UploadedFile;
27
28
use League\Csv\Reader;
29
30
/**
31
 * @author    nystudio107
32
 * @package   Retour
33
 * @since     3.0.0
34
 */
35
class FileController extends Controller
36
{
37
    // Constants
38
    // =========================================================================
39
40
    const DOCUMENTATION_URL = 'https://github.com/nystudio107/craft-retour/';
41
42
    // Protected Properties
43
    // =========================================================================
44
45
    protected $allowAnonymous = [];
46
47
    // Public Methods
48
    // =========================================================================
49
50
    /**
51
     * @throws \yii\web\BadRequestHttpException
52
     * @throws \yii\web\ForbiddenHttpException
53
     * @throws \craft\errors\MissingComponentException
54
     */
55
    public function actionImportCsvColumns()
56
    {
57
        PermissionHelper::controllerPermissionCheck('retour:redirects');
58
        $this->requirePostRequest();
59
        $filename = Craft::$app->getRequest()->getRequiredBodyParam('filename');
60
        $columns = Craft::$app->getRequest()->getRequiredBodyParam('columns');
61
        $csv = Reader::createFromPath($filename);
62
        $headers = array_flip($csv->fetchOne(0));
63
        $csv->setOffset(1);
64
        $columns = ArrayHelper::filterEmptyStringsFromArray($columns);
0 ignored issues
show
Bug introduced by
It seems like $columns can also be of type string; however, parameter $arr of craft\helpers\ArrayHelpe...EmptyStringsFromArray() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

64
        $columns = ArrayHelper::filterEmptyStringsFromArray(/** @scrutinizer ignore-type */ $columns);
Loading history...
65
        $csv->each(function ($row) use ($headers, $columns) {
66
            $redirectConfig = [
67
                'id' => 0,
68
            ];
69
            if (isset($columns[0], $headers[$columns[0]])) {
70
                $redirectConfig['redirectSrcUrl'] = $row[$headers[$columns[0]]] ?? null;
71
            }
72
            if (isset($columns[1], $headers[$columns[1]])) {
73
                $redirectConfig['redirectDestUrl'] = $row[$headers[$columns[1]]] ?? null;
74
            }
75
            if (isset($columns[2], $headers[$columns[2]])) {
76
                $redirectConfig['redirectMatchType'] = $row[$headers[$columns[2]]] ?? null;
77
            }
78
            if (isset($columns[3], $headers[$columns[3]])) {
79
                $redirectConfig['redirectHttpCode'] = $row[$headers[$columns[3]]] ?? null;
80
            }
81
            Retour::$plugin->redirects->saveRedirect($redirectConfig);
82
        });
83
84
        @unlink($filename);
0 ignored issues
show
Bug introduced by
It seems like $filename can also be of type array and array; however, parameter $filename of unlink() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

84
        @unlink(/** @scrutinizer ignore-type */ $filename);
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

84
        /** @scrutinizer ignore-unhandled */ @unlink($filename);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
85
        Retour::$plugin->clearAllCaches();
86
        Craft::$app->getSession()->setNotice(Craft::t('retour', 'Redirects imported from CSV file.'));
87
88
        $this->redirect('retour/redirects');
89
    }
90
91
    /**
92
     * @param string|null $siteHandle
93
     *
94
     * @return Response
95
     * @throws \yii\web\ForbiddenHttpException
96
     * @throws \yii\web\NotFoundHttpException
97
     */
98
    public function actionImportCsv(string $siteHandle = null): Response
99
    {
100
        $variables = [];
101
        PermissionHelper::controllerPermissionCheck('retour:redirects');
102
        // Get the site to edit
103
        $siteId = MultiSiteHelper::getSiteIdFromHandle($siteHandle);
104
        $pluginName = Retour::$settings->pluginName;
105
        $templateTitle = Craft::t('retour', 'Import CSV File');
106
        $view = Craft::$app->getView();
107
        // Asset bundle
108
        try {
109
            $view->registerAssetBundle(RetourImportAsset::class);
110
        } catch (InvalidConfigException $e) {
111
            Craft::error($e->getMessage(), __METHOD__);
112
        }
113
        $variables['baseAssetsUrl'] = Craft::$app->assetManager->getPublishedUrl(
114
            '@nystudio107/retour/assetbundles/retour/dist',
115
            true
116
        );
117
        // Enabled sites
118
        MultiSiteHelper::setMultiSiteVariables($siteHandle, $siteId, $variables);
119
        $variables['controllerHandle'] = 'file';
120
121
        // Basic variables
122
        $variables['fullPageForm'] = true;
123
        $variables['docsUrl'] = self::DOCUMENTATION_URL;
124
        $variables['pluginName'] = $pluginName;
125
        $variables['title'] = $templateTitle;
126
        $variables['crumbs'] = [
127
            [
128
                'label' => $pluginName,
129
                'url' => UrlHelper::cpUrl('retour'),
130
            ],
131
            [
132
                'label' => 'Redirects',
133
                'url' => UrlHelper::cpUrl('retour/redirects'),
134
            ],
135
        ];
136
        $variables['docTitle'] = "{$pluginName} - Redirects - {$templateTitle}";
137
        $variables['selectedSubnavItem'] = 'redirects';
138
139
        // The CSV file
140
        $file = UploadedFile::getInstanceByName('file');
141
        if ($file !== null) {
142
            $filename = Craft::$app->getPath()->getTempPath() . DIRECTORY_SEPARATOR . uniqid($file->name, true);
143
            $file->saveAs($filename, false);
144
            $csv = Reader::createFromPath($file->tempName);
145
            $headers = $csv->fetchOne(0);
146
            Craft::info(print_r($headers, true), __METHOD__);
147
            $variables['headers'] = $headers;
148
            $variables['filename'] = $filename;
149
        }
150
151
        // Render the template
152
        return $this->renderTemplate('retour/import/index', $variables);
153
    }
154
}
155