Completed
Pull Request — develop (#182)
by Tom
04:37
created

ListCommand::getUrls()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 12
rs 9.4285
cc 3
eloc 7
nc 3
nop 4
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 $sitmapProductCollection
0 ignored issues
show
Documentation introduced by
There is no parameter named $sitmapProductCollection. Did you maybe mean $sitemapProductCollection?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
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
        if ($input->getOption('add-all')) {
91
            $input->setOption('add-categories', true);
92
            $input->setOption('add-products', true);
93
            $input->setOption('add-cmspages', true);
94
        }
95
96
        $this->detectMagento($output, true);
97
        if ($this->initMagento()) {
98
            $stores = explode(',', $input->getArgument('stores'));
99
100
            $urls = array();
101
102
            foreach ($stores as $storeId) {
103
                try {
104
                    $currentStore = $this->storeManager->getStore($storeId);
105
                } catch (\Exception $e) {
106
                    throw new \RuntimeException("Store with id {$storeId} doesn´t exist");
107
                }
108
109
                // base url
110
                $urls[] = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);
111
112
                $linkBaseUrl = $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK);
113
114
                if ($input->getOption('add-categories')) {
115
                    $urls = $this->getUrls($this->sitemapCategoryCollection, $linkBaseUrl, $storeId, $urls);
116
                }
117
118
                if ($input->getOption('add-products')) {
119
                    $urls = $this->getUrls($this->sitemapProductCollection, $linkBaseUrl, $storeId, $urls);
120
                }
121
122
                if ($input->getOption('add-cmspages')) {
123
                    $urls = $this->getUrls($this->sitemapPageCollection, $linkBaseUrl, $storeId, $urls);
124
                }
125
            } // 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...
126
127
            if (count($urls) === 0) {
128
                return;
129
            }
130
131
            foreach ($urls as $url) {
132
133
                // pre-process
134
                $line = $input->getArgument('linetemplate');
135
                $line = str_replace('{url}', $url, $line);
136
137
                $parts = parse_url($url);
138
                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...
139
                    $line = str_replace('{' . $key . '}', $value, $line);
140
                }
141
142
                // ... and output
143
                $output->writeln($line);
144
            }
145
        }
146
    }
147
148
    /**
149
     * @param string $resourceModel
0 ignored issues
show
Bug introduced by
There is no parameter named $resourceModel. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
150
     * @param string $linkBaseUrl
151
     * @param string $storeId
152
     * @param array  $urls
153
     *
154
     * @return array
155
     */
156
    protected function getUrls($entityCollection, $linkBaseUrl, $storeId, array $urls)
157
    {
158
        $collection = $entityCollection->getCollection($storeId);
159
        if (!$collection) {
160
            return $urls;
161
        }
162
        foreach ($collection as $item) {
163
            /* @var $item \Magento\Framework\Object */
164
            $urls[] = $linkBaseUrl . $item->getUrl();
165
        }
166
        return $urls;
167
    }
168
}
169