Completed
Pull Request — master (#57)
by jean-marie
26:09
created

InitFileIterator::isReadableWorksheet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
namespace Pim\Bundle\ExcelConnectorBundle\Iterator;
4
5
use Box\Spout\Reader\XLSX\Sheet;
6
use Box\Spout\Reader\XLSX\SheetIterator;
7
use Pim\Component\Connector\Reader\File\FileIterator;
8
use Symfony\Component\OptionsResolver\OptionsResolver;
9
10
/**
11
 * XSLX initialization file iterator
12
 *
13
 * @author    JM Leroux <[email protected]>
14
 * @author    Antoine Guigan <[email protected]>
15
 * @copyright 2013 Akeneo SAS (http://www.akeneo.com)
16
 * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
17
 */
18
class InitFileIterator extends FileIterator
19
{
20
    /** @var SheetIterator */
21
    protected $worksheetIterator;
22
23
    /** @var array */
24
    protected $options;
25
26
    /** @var bool */
27
    protected $nextWorksheet = false;
28
29
    /**
30
     * {@inheritdoc}
31
     */
32
    public function __construct($type, $filePath, array $options = [])
33
    {
34
        parent::__construct($type, $filePath, $options);
35
        $resolver = new OptionsResolver();
36
        $this->configureOptions($resolver);
37
        $this->options = $resolver->resolve($options);
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function current()
44
    {
45
        $data = $this->rows->current();
46
        if (!$this->valid() || null === $data || empty($data)) {
47
            $this->rewind();
48
49
            return null;
50
        }
51
52
        $data = $this->trimRight($data);
53
54
        return $data;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function key()
61
    {
62
        $worksheetName = $this->worksheetIterator->current()->getName();
63
64
        return sprintf('%s/%s', $worksheetName, $this->rows->key());
65
    }
66
67
    /**
68
     * @inheritdoc
69
     */
70
    public function valid()
71
    {
72
        return $this->worksheetIterator->valid() && $this->rows && $this->rows->valid();
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function next()
79
    {
80
        $this->rows->next();
81
        if (!$this->rows->valid()) {
82
            $this->worksheetIterator->next();
83
            $this->nextWorksheet = true;
84
            if ($this->worksheetIterator->valid()) {
85
                $this->initializeValuesIterator();
86
            }
87
        }
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function rewind()
94
    {
95
        $this->worksheetIterator = new \CallbackFilterIterator(
0 ignored issues
show
Documentation Bug introduced by
It seems like new \CallbackFilterItera...ntSheet->getName()); }) of type object<CallbackFilterIterator> is incompatible with the declared type object<Box\Spout\Reader\XLSX\SheetIterator> of property $worksheetIterator.

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...
96
            $this->reader->getSheetIterator(),
97
            function (Sheet $currentSheet) {
98
                return $this->isReadableWorksheet($currentSheet->getName());
99
            }
100
        );
101
        $this->worksheetIterator->rewind();
102
        if ($this->worksheetIterator->valid()) {
103
            $this->initializeValuesIterator();
104
        }
105
    }
106
107
    protected function trimRight($data)
108
    {
109
        $lastElement = end($data);
110
        while (false !== $lastElement && empty($lastElement)) {
111
            array_pop($data);
112
            $lastElement = end($data);
113
        }
114
115
        return $data;
116
    }
117
118
    /**
119
     * Initializes the current worksheet
120
     */
121
    protected function initializeValuesIterator()
122
    {
123
        $this->createValuesIterator();
124
125
        if (!$this->rows->valid() || !$this->isReadableWorksheet($this->reader->getSheetIterator()->current()->getName())) {
126
            $this->worksheetIterator->next();
127
            if ($this->worksheetIterator->valid()) {
128
                $this->initializeValuesIterator();
129
            }
130
        }
131
    }
132
133
    /**
134
     * Returns true if the worksheet should be read
135
     *
136
     * @param string $title
137
     *
138
     * @return boolean
139
     */
140
    protected function isReadableWorksheet($title)
141
    {
142
        return $this->isIncludedWorksheet($title) && !$this->isExcludedWorksheet($title);
143
    }
144
145
    /**
146
     * Returns true if the worksheet should be indluded
147
     *
148
     * @param string $title The title of the worksheet
149
     *
150
     * @return boolean
151
     */
152
    protected function isIncludedWorksheet($title)
153
    {
154
        if (!isset($this->options['include_worksheets'])) {
155
            return true;
156
        }
157
158
        foreach ($this->options['include_worksheets'] as $regexp) {
159
            if (preg_match($regexp, $title)) {
160
                return true;
161
            }
162
        }
163
164
        return false;
165
    }
166
167
    /**
168
     * Returns true if the worksheet should be excluded
169
     *
170
     * @param string $title The title of the worksheet
171
     *
172
     * @return boolean
173
     */
174
    protected function isExcludedWorksheet($title)
175
    {
176
        if (!isset($this->options['exclude_worksheets'])) {
177
            return false;
178
        }
179
180
        foreach ($this->options['exclude_worksheets'] as $regexp) {
181
            if (preg_match($regexp, $title)) {
182
                return true;
183
            }
184
        }
185
186
        return false;
187
    }
188
189
    /**
190
     * Create the values iterator according to the 'header_key' option
191
     * Set the headers
192
     * Leave reader cursor on the headers, like in the PIM
193
     */
194
    protected function createValuesIterator()
195
    {
196
        $sheet = $this->worksheetIterator->current();
197
        $this->rows = $sheet->getRowIterator();
198
        $this->rows->rewind();
199
        while ($this->rows->valid() && ($this->options['header_key'] !== trim($this->rows->current()[0]))) {
200
            $this->rows->next();
201
        }
202
        $this->headers = $this->trimRight($this->rows->current());
203
        if ($this->nextWorksheet) {
204
            $this->rows->next();
205
        }
206
        $this->nextWorksheet = false;
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    protected function configureOptions(OptionsResolver $resolver)
213
    {
214
        $resolver->setDefaults([
215
            'skip_empty' => false,
216
        ]);
217
218
        $resolver->setRequired([
219
            'header_key',
220
        ]);
221
222
        $resolver->setDefined([
223
            'include_worksheets',
224
            'exclude_worksheets',
225
        ]);
226
    }
227
}
228