Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like OLE often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use OLE, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
39 | class OLE |
||
40 | { |
||
41 | const OLE_PPS_TYPE_ROOT = 5; |
||
42 | const OLE_PPS_TYPE_DIR = 1; |
||
43 | const OLE_PPS_TYPE_FILE = 2; |
||
44 | const OLE_DATA_SIZE_SMALL = 0x1000; |
||
45 | const OLE_LONG_INT_SIZE = 4; |
||
46 | const OLE_PPS_SIZE = 0x80; |
||
47 | |||
48 | /** |
||
49 | * The file handle for reading an OLE container |
||
50 | * @var resource |
||
51 | */ |
||
52 | public $_file_handle; |
||
53 | |||
54 | /** |
||
55 | * Array of PPS's found on the OLE container |
||
56 | * @var array |
||
57 | */ |
||
58 | public $_list = []; |
||
59 | |||
60 | /** |
||
61 | * Root directory of OLE container |
||
62 | * @var OLE_PPS_Root |
||
63 | */ |
||
64 | public $root; |
||
65 | |||
66 | /** |
||
67 | * Big Block Allocation Table |
||
68 | * @var array (blockId => nextBlockId) |
||
69 | */ |
||
70 | public $bbat; |
||
71 | |||
72 | /** |
||
73 | * Short Block Allocation Table |
||
74 | * @var array (blockId => nextBlockId) |
||
75 | */ |
||
76 | public $sbat; |
||
77 | |||
78 | /** |
||
79 | * Size of big blocks. This is usually 512. |
||
80 | * @var int number of octets per block. |
||
81 | */ |
||
82 | public $bigBlockSize; |
||
83 | |||
84 | /** |
||
85 | * Size of small blocks. This is usually 64. |
||
86 | * @var int number of octets per block |
||
87 | */ |
||
88 | public $smallBlockSize; |
||
89 | |||
90 | /** |
||
91 | * Reads an OLE container from the contents of the file given. |
||
92 | * |
||
93 | * @acces public |
||
94 | * @param string $file |
||
95 | * @throws \PhpSpreadsheet\Reader\Exception |
||
96 | * @return mixed true on success, PEAR_Error on failure |
||
97 | */ |
||
98 | public function read($file) |
||
182 | |||
183 | /** |
||
184 | * @param int block id |
||
185 | * @param int byte offset from beginning of file |
||
186 | */ |
||
187 | public function _getBlockOffset($blockId) |
||
191 | |||
192 | /** |
||
193 | * Returns a stream for use with fread() etc. External callers should |
||
194 | * use \PhpSpreadsheet\Shared\OLE\PPS\File::getStream(). |
||
195 | * @param int|PPS block id or PPS |
||
196 | * @return resource read-only stream |
||
197 | */ |
||
198 | public function getStream($blockIdOrPps) |
||
222 | |||
223 | /** |
||
224 | * Reads a signed char. |
||
225 | * @param resource file handle |
||
226 | * @return int |
||
227 | */ |
||
228 | private static function _readInt1($fh) |
||
234 | |||
235 | /** |
||
236 | * Reads an unsigned short (2 octets). |
||
237 | * @param resource file handle |
||
238 | * @return int |
||
239 | */ |
||
240 | private static function _readInt2($fh) |
||
246 | |||
247 | /** |
||
248 | * Reads an unsigned long (4 octets). |
||
249 | * @param resource file handle |
||
250 | * @return int |
||
251 | */ |
||
252 | private static function _readInt4($fh) |
||
258 | |||
259 | /** |
||
260 | * Gets information about all PPS's on the OLE container from the PPS WK's |
||
261 | * creates an OLE_PPS object for each one. |
||
262 | * |
||
263 | * @param int the block id of the first block |
||
264 | * @return mixed true on success, PEAR_Error on failure |
||
265 | */ |
||
266 | public function _readPpsWks($blockId) |
||
331 | |||
332 | /** |
||
333 | * It checks whether the PPS tree is complete (all PPS's read) |
||
334 | * starting with the given PPS (not necessarily root) |
||
335 | * |
||
336 | * @param int $index The index of the PPS from which we are checking |
||
337 | * @return bool Whether the PPS tree for the given PPS is complete |
||
338 | */ |
||
339 | public function _ppsTreeComplete($index) |
||
350 | |||
351 | /** |
||
352 | * Checks whether a PPS is a File PPS or not. |
||
353 | * If there is no PPS for the index given, it will return false. |
||
354 | * |
||
355 | * @param int $index The index for the PPS |
||
356 | * @return bool true if it's a File PPS, false otherwise |
||
357 | */ |
||
358 | View Code Duplication | public function isFile($index) |
|
366 | |||
367 | /** |
||
368 | * Checks whether a PPS is a Root PPS or not. |
||
369 | * If there is no PPS for the index given, it will return false. |
||
370 | * |
||
371 | * @param int $index The index for the PPS. |
||
372 | * @return bool true if it's a Root PPS, false otherwise |
||
373 | */ |
||
374 | View Code Duplication | public function isRoot($index) |
|
382 | |||
383 | /** |
||
384 | * Gives the total number of PPS's found in the OLE container. |
||
385 | * |
||
386 | * @return int The total number of PPS's found in the OLE container |
||
387 | */ |
||
388 | public function ppsTotal() |
||
392 | |||
393 | /** |
||
394 | * Gets data from a PPS |
||
395 | * If there is no PPS for the index given, it will return an empty string. |
||
396 | * |
||
397 | * @param int $index The index for the PPS |
||
398 | * @param int $position The position from which to start reading |
||
399 | * (relative to the PPS) |
||
400 | * @param int $length The amount of bytes to read (at most) |
||
401 | * @return string The binary string containing the data requested |
||
402 | * @see OLE_PPS_File::getStream() |
||
403 | */ |
||
404 | public function getData($index, $position, $length) |
||
416 | |||
417 | /** |
||
418 | * Gets the data length from a PPS |
||
419 | * If there is no PPS for the index given, it will return 0. |
||
420 | * |
||
421 | * @param int $index The index for the PPS |
||
422 | * @return int The amount of bytes in data the PPS has |
||
423 | */ |
||
424 | public function getDataLength($index) |
||
432 | |||
433 | /** |
||
434 | * Utility function to transform ASCII text to Unicode |
||
435 | * |
||
436 | * @static |
||
437 | * @param string $ascii The ASCII string to transform |
||
438 | * @return string The string in Unicode |
||
439 | */ |
||
440 | public static function ascToUcs($ascii) |
||
450 | |||
451 | /** |
||
452 | * Utility function |
||
453 | * Returns a string for the OLE container with the date given |
||
454 | * |
||
455 | * @static |
||
456 | * @param int $date A timestamp |
||
457 | * @return string The string for the OLE container |
||
458 | */ |
||
459 | public static function localDateToOLE($date = null) |
||
495 | |||
496 | /** |
||
497 | * Returns a timestamp from an OLE container's date |
||
498 | * |
||
499 | * @static |
||
500 | * @param int $string A binary string with the encoded date |
||
501 | * @return string The timestamp corresponding to the string |
||
502 | */ |
||
503 | public static function OLE2LocalDate($string) |
||
526 | } |
||
527 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.