Complex classes like StyleManager 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 StyleManager, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 11 | class StyleManager |
||
| 12 | { |
||
| 13 | /** Nodes used to find relevant information in the styles XML file */ |
||
| 14 | const XML_NODE_NUM_FMTS = 'numFmts'; |
||
| 15 | const XML_NODE_NUM_FMT = 'numFmt'; |
||
| 16 | const XML_NODE_CELL_XFS = 'cellXfs'; |
||
| 17 | const XML_NODE_XF = 'xf'; |
||
| 18 | |||
| 19 | /** Attributes used to find relevant information in the styles XML file */ |
||
| 20 | const XML_ATTRIBUTE_NUM_FMT_ID = 'numFmtId'; |
||
| 21 | const XML_ATTRIBUTE_FORMAT_CODE = 'formatCode'; |
||
| 22 | const XML_ATTRIBUTE_APPLY_NUMBER_FORMAT = 'applyNumberFormat'; |
||
| 23 | |||
| 24 | /** By convention, default style ID is 0 */ |
||
| 25 | const DEFAULT_STYLE_ID = 0; |
||
| 26 | |||
| 27 | const NUMBER_FORMAT_GENERAL = 'General'; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @see https://msdn.microsoft.com/en-us/library/ff529597(v=office.12).aspx |
||
| 31 | * @var array Mapping between built-in numFmtId and the associated format - for dates only |
||
| 32 | */ |
||
| 33 | protected static $builtinNumFmtIdToNumFormatMapping = [ |
||
| 34 | 14 => 'm/d/yyyy', // @NOTE: ECMA spec is 'mm-dd-yy' |
||
| 35 | 15 => 'd-mmm-yy', |
||
| 36 | 16 => 'd-mmm', |
||
| 37 | 17 => 'mmm-yy', |
||
| 38 | 18 => 'h:mm AM/PM', |
||
| 39 | 19 => 'h:mm:ss AM/PM', |
||
| 40 | 20 => 'h:mm', |
||
| 41 | 21 => 'h:mm:ss', |
||
| 42 | 22 => 'm/d/yyyy h:mm', // @NOTE: ECMA spec is 'm/d/yy h:mm', |
||
| 43 | 45 => 'mm:ss', |
||
| 44 | 46 => '[h]:mm:ss', |
||
| 45 | 47 => 'mm:ss.0', // @NOTE: ECMA spec is 'mmss.0', |
||
| 46 | ]; |
||
| 47 | |||
| 48 | /** @var string Path of the XLSX file being read */ |
||
| 49 | protected $filePath; |
||
| 50 | |||
| 51 | /** @var bool Whether the XLSX file contains a styles XML file */ |
||
| 52 | protected $hasStylesXMLFile; |
||
| 53 | |||
| 54 | /** @var string|null Path of the styles XML file */ |
||
| 55 | protected $stylesXMLFilePath; |
||
| 56 | |||
| 57 | /** @var InternalEntityFactory Factory to create entities */ |
||
| 58 | protected $entityFactory; |
||
| 59 | |||
| 60 | /** @var array Array containing the IDs of built-in number formats indicating a date */ |
||
| 61 | protected $builtinNumFmtIdIndicatingDates; |
||
| 62 | |||
| 63 | /** @var array Array containing a mapping NUM_FMT_ID => FORMAT_CODE */ |
||
| 64 | protected $customNumberFormats; |
||
| 65 | |||
| 66 | /** @var array Array containing a mapping STYLE_ID => [STYLE_ATTRIBUTES] */ |
||
| 67 | protected $stylesAttributes; |
||
| 68 | |||
| 69 | /** @var array Cache containing a mapping NUM_FMT_ID => IS_DATE_FORMAT. Used to avoid lots of recalculations */ |
||
| 70 | protected $numFmtIdToIsDateFormatCache = []; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @param string $filePath Path of the XLSX file being read |
||
| 74 | * @param WorkbookRelationshipsManager $workbookRelationshipsManager Helps retrieving workbook relationships |
||
| 75 | * @param InternalEntityFactory $entityFactory Factory to create entities |
||
| 76 | */ |
||
| 77 | 74 | public function __construct($filePath, $workbookRelationshipsManager, $entityFactory) |
|
| 87 | |||
| 88 | /** |
||
| 89 | * Returns whether the style with the given ID should consider |
||
| 90 | * numeric values as timestamps and format the cell as a date. |
||
| 91 | * |
||
| 92 | * @param int $styleId Zero-based style ID |
||
| 93 | * @return bool Whether the cell with the given cell should display a date instead of a numeric value |
||
| 94 | */ |
||
| 95 | 46 | public function shouldFormatNumericValueAsDate($styleId) |
|
| 114 | |||
| 115 | /** |
||
| 116 | * Reads the styles.xml file and extract the relevant information from the file. |
||
| 117 | * |
||
| 118 | * @return void |
||
| 119 | */ |
||
| 120 | 13 | protected function extractRelevantInfo() |
|
| 139 | |||
| 140 | /** |
||
| 141 | * Extracts number formats from the "numFmt" nodes. |
||
| 142 | * For simplicity, the styles attributes are kept in memory. This is possible thanks |
||
| 143 | * to the reuse of formats. So 1 million cells should not use 1 million formats. |
||
| 144 | * |
||
| 145 | * @param \Box\Spout\Reader\Wrapper\XMLReader $xmlReader XML Reader positioned on the "numFmts" node |
||
| 146 | * @return void |
||
| 147 | */ |
||
| 148 | 9 | protected function extractNumberFormats($xmlReader) |
|
| 161 | |||
| 162 | /** |
||
| 163 | * Extracts style attributes from the "xf" nodes, inside the "cellXfs" section. |
||
| 164 | * For simplicity, the styles attributes are kept in memory. This is possible thanks |
||
| 165 | * to the reuse of styles. So 1 million cells should not use 1 million styles. |
||
| 166 | * |
||
| 167 | * @param \Box\Spout\Reader\Wrapper\XMLReader $xmlReader XML Reader positioned on the "cellXfs" node |
||
| 168 | * @return void |
||
| 169 | */ |
||
| 170 | 13 | protected function extractStyleAttributes($xmlReader) |
|
| 190 | |||
| 191 | /** |
||
| 192 | * @return array The custom number formats |
||
| 193 | */ |
||
| 194 | 6 | protected function getCustomNumberFormats() |
|
| 202 | |||
| 203 | /** |
||
| 204 | * @return array The styles attributes |
||
| 205 | */ |
||
| 206 | 13 | protected function getStylesAttributes() |
|
| 214 | |||
| 215 | /** |
||
| 216 | * @param array $styleAttributes Array containing the style attributes (2 keys: "applyNumberFormat" and "numFmtId") |
||
| 217 | * @return bool Whether the style with the given attributes indicates that the number is a date |
||
| 218 | */ |
||
| 219 | 38 | protected function doesStyleIndicateDate($styleAttributes) |
|
| 235 | |||
| 236 | /** |
||
| 237 | * Returns whether the number format ID indicates that the number is a date. |
||
| 238 | * The result is cached to avoid recomputing the same thing over and over, as |
||
| 239 | * "numFmtId" attributes can be shared between multiple styles. |
||
| 240 | * |
||
| 241 | * @param int $numFmtId |
||
| 242 | * @return bool Whether the number format ID indicates that the number is a date |
||
| 243 | */ |
||
| 244 | 36 | protected function doesNumFmtIdIndicateDate($numFmtId) |
|
| 257 | |||
| 258 | /** |
||
| 259 | * @param int $numFmtId |
||
| 260 | * @return string|null The custom number format or NULL if none defined for the given numFmtId |
||
| 261 | */ |
||
| 262 | 36 | protected function getFormatCodeForNumFmtId($numFmtId) |
|
| 269 | |||
| 270 | /** |
||
| 271 | * @param int $numFmtId |
||
| 272 | * @return bool Whether the number format ID indicates that the number is a date |
||
| 273 | */ |
||
| 274 | 36 | protected function isNumFmtIdBuiltInDateFormat($numFmtId) |
|
| 278 | |||
| 279 | /** |
||
| 280 | * @param string|null $formatCode |
||
| 281 | * @return bool Whether the given format code indicates that the number is a date |
||
| 282 | */ |
||
| 283 | 34 | protected function isFormatCodeCustomDateFormat($formatCode) |
|
| 292 | |||
| 293 | /** |
||
| 294 | * @param string $formatCode |
||
| 295 | * @return bool Whether the given format code matches a date format pattern |
||
| 296 | */ |
||
| 297 | 28 | protected function isFormatCodeMatchingDateFormatPattern($formatCode) |
|
| 321 | |||
| 322 | /** |
||
| 323 | * Returns the format as defined in "styles.xml" of the given style. |
||
| 324 | * NOTE: It is assumed that the style DOES have a number format associated to it. |
||
| 325 | * |
||
| 326 | * @param int $styleId Zero-based style ID |
||
| 327 | * @return string The number format code associated with the given style |
||
| 328 | */ |
||
| 329 | 2 | public function getNumberFormatCode($styleId) |
|
| 344 | } |
||
| 345 |