Completed
Push — develop ( 5e03e2...c8a8fd )
by Adrien
28:49
created

IOFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet;
4
5
use PhpOffice\PhpSpreadsheet\Shared\File;
6
7
/**
8
 * Copyright (c) 2006 - 2016 PhpSpreadsheet
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
 *
24
 * @category   PhpSpreadsheet
25
 * @copyright  Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
26
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
27
 */
28
class IOFactory
29
{
30
    /**
31
     * Search locations
32
     *
33
     * @var    array
34
     * @static
35
     */
36
    private static $searchLocations = [
37
        ['type' => 'IWriter', 'path' => 'PhpSpreadsheet/Writer/{0}.php', 'class' => '\\PhpOffice\\PhpSpreadsheet\\Writer\\{0}'],
38
        ['type' => 'IReader', 'path' => 'PhpSpreadsheet/Reader/{0}.php', 'class' => '\\PhpOffice\\PhpSpreadsheet\\Reader\\{0}'],
39
    ];
40
41
    /**
42
     * Autoresolve classes
43
     *
44
     * @var    array
45
     * @static
46
     */
47
    private static $autoResolveClasses = [
48
        'Xlsx',
49
        'Xls',
50
        'Excel2003XML',
51
        'Ods',
52
        'SYLK',
53
        'Gnumeric',
54
        'HTML',
55
        'CSV',
56
    ];
57
58
    /**
59
     *    Private constructor for IOFactory
60
     */
61
    private function __construct()
62
    {
63
    }
64
65
    /**
66
     * Get search locations
67
     *
68
     * @static
69
     * @return    array
70
     */
71
    public static function getSearchLocations()
72
    {
73
        return self::$searchLocations;
74
    }
75
76
    /**
77
     * Set search locations
78
     *
79
     * @static
80
     * @param    array $value
81
     * @throws    Reader\Exception
82
     */
83
    public static function setSearchLocations($value)
84
    {
85
        if (is_array($value)) {
86
            self::$searchLocations = $value;
87
        } else {
88
            throw new Reader\Exception('Invalid parameter passed.');
89
        }
90
    }
91
92
    /**
93
     * Add search location
94
     *
95
     * @static
96
     * @param    string $type        Example: IWriter
97
     * @param    string $location    Example: PhpSpreadsheet/Writer/{0}.php
98
     * @param    string $classname     Example: Writer\{0}
99
     */
100
    public static function addSearchLocation($type = '', $location = '', $classname = '')
101
    {
102
        self::$searchLocations[] = ['type' => $type, 'path' => $location, 'class' => $classname];
103
    }
104
105
    /**
106
     * Create Writer\IWriter
107
     *
108
     * @static
109
     * @param    Spreadsheet $spreadsheet
110
     * @param    string  $writerType    Example: Xlsx
111
     * @throws    Writer\Exception
112
     * @return    Writer\IWriter
113
     */
114 57 View Code Duplication
    public static function createWriter(Spreadsheet $spreadsheet, $writerType = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
    {
116
        // Search type
117 57
        $searchType = 'IWriter';
118
119
        // Include class
120 57
        foreach (self::$searchLocations as $searchLocation) {
121 57
            if ($searchLocation['type'] == $searchType) {
122 57
                $className = str_replace('{0}', $writerType, $searchLocation['class']);
123
124 57
                $instance = new $className($spreadsheet);
125 57
                if ($instance !== null) {
126 57
                    return $instance;
127
                }
128
            }
129
        }
130
131
        // Nothing found...
132
        throw new Writer\Exception("No $searchType found for type $writerType");
133
    }
134
135
    /**
136
     * Create Reader\IReader
137
     *
138
     * @static
139
     * @param    string $readerType    Example: Xlsx
140
     * @throws    Reader\Exception
141
     * @return    Reader\IReader
142
     */
143 24 View Code Duplication
    public static function createReader($readerType = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
    {
145
        // Search type
146 24
        $searchType = 'IReader';
147
148
        // Include class
149 24
        foreach (self::$searchLocations as $searchLocation) {
150 24
            if ($searchLocation['type'] == $searchType) {
151 24
                $className = str_replace('{0}', $readerType, $searchLocation['class']);
152
153 24
                $instance = new $className();
154 24
                if ($instance !== null) {
155 24
                    return $instance;
156
                }
157
            }
158
        }
159
160
        // Nothing found...
161
        throw new Reader\Exception("No $searchType found for type $readerType");
162
    }
163
164
    /**
165
     * Loads Spreadsheet from file using automatic Reader\IReader resolution
166
     *
167
     * @static
168
     * @param     string         $pFilename        The name of the spreadsheet file
169
     * @throws    Reader\Exception
170
     * @return    Spreadsheet
171
     */
172 9
    public static function load($pFilename)
173
    {
174 9
        $reader = self::createReaderForFile($pFilename);
175
176 9
        return $reader->load($pFilename);
177
    }
178
179
    /**
180
     * Identify file type using automatic Reader\IReader resolution
181
     *
182
     * @static
183
     * @param     string         $pFilename        The name of the spreadsheet file to identify
184
     * @throws    Reader\Exception
185
     * @return    string
186
     */
187 9
    public static function identify($pFilename)
188
    {
189 9
        $reader = self::createReaderForFile($pFilename);
190 7
        $className = get_class($reader);
191 7
        $classType = explode('\\', $className);
192 7
        unset($reader);
193
194 7
        return array_pop($classType);
195
    }
196
197
    /**
198
     * Create Reader\IReader for file using automatic Reader\IReader resolution
199
     *
200
     * @static
201
     * @param     string         $pFilename        The name of the spreadsheet file
202
     * @throws    Reader\Exception
203
     * @return    Reader\IReader
204
     */
205 18
    public static function createReaderForFile($pFilename)
206
    {
207 18
        File::assertFile($pFilename);
208
209
        // First, lucky guess by inspecting file extension
210 16
        $pathinfo = pathinfo($pFilename);
211
212 16
        $extensionType = null;
213 16
        if (isset($pathinfo['extension'])) {
214 16
            switch (strtolower($pathinfo['extension'])) {
215 16
                case 'xlsx':            //    Excel (OfficeOpenXML) Spreadsheet
216 11
                case 'xlsm':            //    Excel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)
217 11
                case 'xltx':            //    Excel (OfficeOpenXML) Template
218 11
                case 'xltm':            //    Excel (OfficeOpenXML) Macro Template (macros will be discarded)
219 5
                    $extensionType = 'Xlsx';
220 5
                    break;
221 11
                case 'xls':                //    Excel (BIFF) Spreadsheet
222 8
                case 'xlt':                //    Excel (BIFF) Template
223 3
                    $extensionType = 'Xls';
224 3
                    break;
225 8
                case 'ods':                //    Open/Libre Offic Calc
226 6
                case 'ots':                //    Open/Libre Offic Calc Template
227 2
                    $extensionType = 'Ods';
228 2
                    break;
229 6
                case 'slk':
230 2
                    $extensionType = 'SYLK';
231 2
                    break;
232 4
                case 'xml':                //    Excel 2003 SpreadSheetML
233 2
                    $extensionType = 'Excel2003XML';
234 2
                    break;
235 2
                case 'gnumeric':
236 2
                    $extensionType = 'Gnumeric';
237 2
                    break;
238
                case 'htm':
239
                case 'html':
240
                    $extensionType = 'HTML';
241
                    break;
242
                case 'csv':
243
                    // Do nothing
244
                    // We must not try to use CSV reader since it loads
245
                    // all files including Excel files etc.
246
                    break;
247
                default:
248
                    break;
249
            }
250
251 16
            if ($extensionType !== null) {
252 16
                $reader = self::createReader($extensionType);
253
                // Let's see if we are lucky
254 16
                if (isset($reader) && $reader->canRead($pFilename)) {
255 16
                    return $reader;
256
                }
257
            }
258
        }
259
260
        // If we reach here then "lucky guess" didn't give any result
261
        // Try walking through all the options in self::$autoResolveClasses
262
        foreach (self::$autoResolveClasses as $autoResolveClass) {
263
            //    Ignore our original guess, we know that won't work
264
            if ($autoResolveClass !== $extensionType) {
265
                $reader = self::createReader($autoResolveClass);
266
                if ($reader->canRead($pFilename)) {
267
                    return $reader;
268
                }
269
            }
270
        }
271
272
        throw new Reader\Exception('Unable to identify a reader for this file');
273
    }
274
}
275