Failed Conditions
Push — perf-tests ( 50942d...2fc93e )
by Adrien
14:53
created

SheetIterator::current()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
3
namespace Box\Spout\Reader\ODS;
4
5
use Box\Spout\Common\Exception\IOException;
6
use Box\Spout\Reader\Exception\XMLProcessingException;
7
use Box\Spout\Reader\IteratorInterface;
8
use Box\Spout\Reader\Wrapper\XMLReader;
9
10
/**
11
 * Class SheetIterator
12
 * Iterate over ODS sheet.
13
 *
14
 * @package Box\Spout\Reader\ODS
15
 */
16
class SheetIterator implements IteratorInterface
17
{
18
    const CONTENT_XML_FILE_PATH = 'content.xml';
19
20
    /** Definition of XML nodes name and attribute used to parse sheet data */
21
    const XML_NODE_TABLE = 'table:table';
22
    const XML_ATTRIBUTE_TABLE_NAME = 'table:name';
23
24
    /** @var string $filePath Path of the file to be read */
25
    protected $filePath;
26
27
    /** @var bool Whether date/time values should be returned as PHP objects or be formatted as strings */
28
    protected $shouldFormatDates;
29
30
    /** @var XMLReader The XMLReader object that will help read sheet's XML data */
31
    protected $xmlReader;
32
33
    /** @var \Box\Spout\Common\Escaper\ODS Used to unescape XML data */
34
    protected $escaper;
35
36
    /** @var bool Whether there are still at least a sheet to be read */
37
    protected $hasFoundSheet;
38
39
    /** @var int The index of the sheet being read (zero-based) */
40
    protected $currentSheetIndex;
41
42
    /**
43
     * @param string $filePath Path of the file to be read
44
     * @param bool $shouldFormatDates Whether date/time values should be returned as PHP objects or be formatted as strings
45
     * @throws \Box\Spout\Reader\Exception\NoSheetsFoundException If there are no sheets in the file
46
     */
47
    public function __construct($filePath, $shouldFormatDates)
48
    {
49
        $this->filePath = $filePath;
50
        $this->shouldFormatDates = $shouldFormatDates;
51
        $this->xmlReader = new XMLReader();
52
53
        /** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
54
        $this->escaper = \Box\Spout\Common\Escaper\ODS::getInstance();
55
    }
56
57
    /**
58
     * Rewind the Iterator to the first element
59
     * @link http://php.net/manual/en/iterator.rewind.php
60
     *
61
     * @return void
62
     * @throws \Box\Spout\Common\Exception\IOException If unable to open the XML file containing sheets' data
63
     */
64
    public function rewind()
65
    {
66
        $this->xmlReader->close();
67
68
        if ($this->xmlReader->openFileInZip($this->filePath, self::CONTENT_XML_FILE_PATH) === false) {
69
            $contentXmlFilePath = $this->filePath . '#' . self::CONTENT_XML_FILE_PATH;
70
            throw new IOException("Could not open \"{$contentXmlFilePath}\".");
71
        }
72
73
        try {
74
            $this->hasFoundSheet = $this->xmlReader->readUntilNodeFound(self::XML_NODE_TABLE);
75
        } catch (XMLProcessingException $exception) {
76
           throw new IOException("The content.xml file is invalid and cannot be read. [{$exception->getMessage()}]");
77
       }
78
79
        $this->currentSheetIndex = 0;
80
    }
81
82
    /**
83
     * Checks if current position is valid
84
     * @link http://php.net/manual/en/iterator.valid.php
85
     *
86
     * @return boolean
87
     */
88
    public function valid()
89
    {
90
        return $this->hasFoundSheet;
91
    }
92
93
    /**
94
     * Move forward to next element
95
     * @link http://php.net/manual/en/iterator.next.php
96
     *
97
     * @return void
98
     */
99
    public function next()
100
    {
101
        $this->hasFoundSheet = $this->xmlReader->readUntilNodeFound(self::XML_NODE_TABLE);
102
103
        if ($this->hasFoundSheet) {
104
            $this->currentSheetIndex++;
105
        }
106
    }
107
108
    /**
109
     * Return the current element
110
     * @link http://php.net/manual/en/iterator.current.php
111
     *
112
     * @return \Box\Spout\Reader\ODS\Sheet
113
     */
114
    public function current()
115
    {
116
        $escapedSheetName = $this->xmlReader->getAttribute(self::XML_ATTRIBUTE_TABLE_NAME);
117
        $sheetName = $this->escaper->unescape($escapedSheetName);
118
119
        return new Sheet($this->xmlReader, $this->shouldFormatDates, $sheetName, $this->currentSheetIndex);
120
    }
121
122
    /**
123
     * Return the key of the current element
124
     * @link http://php.net/manual/en/iterator.key.php
125
     *
126
     * @return int
127
     */
128
    public function key()
129
    {
130
        return $this->currentSheetIndex + 1;
131
    }
132
133
    /**
134
     * Cleans up what was created to iterate over the object.
135
     *
136
     * @return void
137
     */
138
    public function end()
139
    {
140
        $this->xmlReader->close();
141
    }
142
}
143