ListCommand::execute()   C
last analyzed

Complexity

Conditions 11
Paths 75

Size

Total Lines 61
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 2 Features 0
Metric Value
c 4
b 2
f 0
dl 0
loc 61
rs 6.2318
cc 11
eloc 32
nc 75
nop 2

How to fix   Long Method    Complexity   

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
namespace N98\Magento\Command\System\Url;
4
5
use Magento\Sitemap\Model\ResourceModel\Catalog\Category;
6
use Magento\Sitemap\Model\ResourceModel\Catalog\Product;
7
use Magento\Sitemap\Model\ResourceModel\Cms\Page;
8
use Magento\Store\Model\StoreManager;
9
use Magento\Store\Model\StoreManagerInterface;
10
use N98\Magento\Command\AbstractMagentoCommand;
11
use Symfony\Component\Console\Input\InputArgument;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
class ListCommand extends AbstractMagentoCommand
17
{
18
    /**
19
     * @var StoreManagerInterface
20
     */
21
    protected $storeManager;
22
23
    /**
24
     * @var Category
25
     */
26
    protected $sitemapCategoryCollection;
27
28
    /**
29
     * @var Product
30
     */
31
    protected $sitemapProductCollection;
32
33
    /**
34
     * @var \Magento\Sitemap\Model\Resource\Cms\Page
35
     */
36
    protected $sitemapPageCollection;
37
38
    protected function configure()
39
    {
40
        $this
41
            ->setName('sys:url:list')
42
            ->addOption('add-categories', null, InputOption::VALUE_NONE, 'Adds categories')
43
            ->addOption('add-products', null, InputOption::VALUE_NONE, 'Adds products')
44
            ->addOption('add-cmspages', null, InputOption::VALUE_NONE, 'Adds cms pages')
45
            ->addOption('add-all', null, InputOption::VALUE_NONE, 'Adds categories, products and cms pages')
46
            ->addArgument('stores', InputArgument::OPTIONAL, 'Stores (comma-separated list of store ids)')
47
            ->addArgument('linetemplate', InputArgument::OPTIONAL, 'Line template', '{url}')
48
            ->setDescription('Get all urls.');
49
50
        $help = <<<HELP
51
Examples:
52
53
- Create a list of product urls only:
54
55
   $ n98-magerun.phar sys:url:list --add-products 4
56
57
- Create a list of all products, categories and cms pages of store 4 
58
  and 5 separating host and path (e.g. to feed a jmeter csv sampler):
59
60
   $ n98-magerun.phar sys:url:list --add-all 4,5 '{host},{path}' > urls.csv
61
62
- The "linetemplate" can contain all parts "parse_url" return wrapped 
63
  in '{}'. '{url}' always maps the complete url and is set by default
64
HELP;
65
        $this->setHelp($help);
66
    }
67
68
    /**
69
     * Execute command
70
     *
71
     * @param StoreManager $storeManager
0 ignored issues
show
Documentation introduced by
Should the type for parameter $storeManager not be StoreManagerInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
72
     * @param Category $sitemapCategoryCollection
73
     * @param Product $sitemapProductCollection
74
     * @param Page $sitemapPageCollection
75
     */
76
    public function inject(
77
        StoreManagerInterface $storeManager,
78
        Category $sitemapCategoryCollection,
79
        Product $sitemapProductCollection,
80
        Page $sitemapPageCollection
81
    ) {
82
        $this->storeManager = $storeManager;
83
        $this->sitemapCategoryCollection = $sitemapCategoryCollection;
84
        $this->sitemapProductCollection = $sitemapProductCollection;
85
        $this->sitemapPageCollection = $sitemapPageCollection;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sitemapPageCollection of type object<Magento\Sitemap\M...ResourceModel\Cms\Page> is incompatible with the declared type object<Magento\Sitemap\Model\Resource\Cms\Page> of property $sitemapPageCollection.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86
    }
87
88
    protected function execute(InputInterface $input, OutputInterface $output)
89
    {
90
        $this->detectMagento($output, true);
91
        if (!$this->initMagento()) {
92
            return;
93
        }
94
95
        if ($input->getOption('add-all')) {
96
            $input->setOption('add-categories', true);
97
            $input->setOption('add-products', true);
98
            $input->setOption('add-cmspages', true);
99
        }
100
101
        $stores = explode(',', $input->getArgument('stores'));
102
103
        $urls = array();
104
105
        foreach ($stores as $storeId) {
106
            try {
107
                $currentStore = $this->storeManager->getStore($storeId);
108
            } catch (\Exception $e) {
109
                throw new \RuntimeException("Store with id {$storeId} doesn´t exist");
110
            }
111
112
            // base url
113
            $urls[] = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);
114
115
            $linkBaseUrl = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK);
116
117
            if ($input->getOption('add-categories')) {
118
                $urls = $this->getUrls($this->sitemapCategoryCollection, $linkBaseUrl, $storeId, $urls);
119
            }
120
121
            if ($input->getOption('add-products')) {
122
                $urls = $this->getUrls($this->sitemapProductCollection, $linkBaseUrl, $storeId, $urls);
123
            }
124
125
            if ($input->getOption('add-cmspages')) {
126
                $urls = $this->getUrls($this->sitemapPageCollection, $linkBaseUrl, $storeId, $urls);
127
            }
128
        } // foreach ($stores as $storeId)
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
129
130
        if (count($urls) === 0) {
131
            return;
132
        }
133
134
        foreach ($urls as $url) {
135
136
            // pre-process
137
            $line = $input->getArgument('linetemplate');
138
            $line = str_replace('{url}', $url, $line);
139
140
            $parts = parse_url($url);
141
            foreach ($parts as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $parts of type array<string,string>|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
142
                $line = str_replace('{' . $key . '}', $value, $line);
143
            }
144
145
            // ... and output
146
            $output->writeln($line);
147
        }
148
    }
149
150
    /**
151
     * @param string $linkBaseUrl
152
     * @param string $storeId
153
     * @param array  $urls
154
     *
155
     * @return array
156
     */
157
    protected function getUrls($entityCollection, $linkBaseUrl, $storeId, array $urls)
158
    {
159
        $collection = $entityCollection->getCollection($storeId);
160
        if (!$collection) {
161
            return $urls;
162
        }
163
        foreach ($collection as $item) {
164
            /* @var $item \Magento\Framework\Object */
165
            $urls[] = $linkBaseUrl . $item->getUrl();
166
        }
167
        return $urls;
168
    }
169
}
170