Complex classes like Salariu 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 Salariu, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 31 | class Salariu |
||
| 32 | { |
||
| 33 | |||
| 34 | use \danielgp\bank_holidays\Romanian, |
||
| 35 | \danielgp\common_lib\CommonCode, |
||
| 36 | \danielgp\salariu\Bonuses, |
||
| 37 | \danielgp\salariu\ForeignCurrency, |
||
| 38 | \danielgp\salariu\Taxation; |
||
| 39 | |||
| 40 | private $appFlags; |
||
| 41 | private $tApp = null; |
||
| 42 | |||
| 43 | public function __construct() |
||
| 44 | { |
||
| 45 | $configPath = 'Salariu' . DIRECTORY_SEPARATOR . 'config'; |
||
| 46 | $interfaceElements = $this->readTypeFromJsonFileUniversal($configPath, 'interfaceElements'); |
||
| 47 | $this->appFlags = [ |
||
| 48 | 'FI' => $interfaceElements['Form Input'], |
||
| 49 | 'TCAS' => $interfaceElements['Table Cell Applied Style'], |
||
| 50 | 'TCSD' => $interfaceElements['Table Cell Style Definitions'], |
||
| 51 | ]; |
||
| 52 | $this->initializeSprGlbAndSession(); |
||
| 53 | $this->handleLocalizationSalariu($interfaceElements['Application']); |
||
| 54 | echo $this->setHeaderHtml(); |
||
| 55 | $this->processFormInputDefaults($interfaceElements['Default Values']); |
||
| 56 | echo $this->setFormInput(); |
||
| 57 | $this->setExchangeRateValues($interfaceElements['Application'], $interfaceElements['Relevant Currencies']); |
||
| 58 | echo $this->setFormOutput($configPath); |
||
| 59 | echo $this->setFooterHtml($interfaceElements['Application']); |
||
| 60 | } |
||
| 61 | |||
| 62 | private function buildArrayOfFieldsStyled() |
||
| 63 | { |
||
| 64 | $sReturn = []; |
||
| 65 | foreach ($this->appFlags['TCAS'] as $key => $value) { |
||
| 66 | $sReturn[$this->tApp->gettext($key)] = $value; |
||
| 67 | } |
||
| 68 | return $sReturn; |
||
| 69 | } |
||
| 70 | |||
| 71 | private function buildStyleForCellFormat($styleId) |
||
| 72 | { |
||
| 73 | $sReturn = []; |
||
| 74 | foreach ($this->appFlags['TCSD'][$styleId] as $key => $value) { |
||
| 75 | $sReturn[] = $key . ':' . $value; |
||
| 76 | } |
||
| 77 | return implode(';', $sReturn) . ';'; |
||
| 78 | } |
||
| 79 | |||
| 80 | private function getOvertimes($aryStngs) |
||
| 81 | { |
||
| 82 | $pcToBoolean = [0 => true, 1 => false]; |
||
| 83 | $pcBoolean = $pcToBoolean[$this->tCmnSuperGlobals->get('pc')]; |
||
| 84 | $ymVal = $this->tCmnSuperGlobals->get('ym'); |
||
| 85 | $snVal = $this->tCmnSuperGlobals->get('sn'); |
||
| 86 | $mnth = $this->setMonthlyAverageWorkingHours($ymVal, $aryStngs, $pcBoolean); |
||
| 87 | return [ |
||
| 88 | 'os175' => ceil($this->tCmnSuperGlobals->get('os175') * 1.75 * $snVal / $mnth), |
||
| 89 | 'os200' => ceil($this->tCmnSuperGlobals->get('os200') * 2 * $snVal / $mnth), |
||
| 90 | ]; |
||
| 91 | } |
||
| 92 | |||
| 93 | private function getValues($lngBase, $aStngs) |
||
| 94 | { |
||
| 95 | $inDate = $this->tCmnSuperGlobals->get('ym'); |
||
| 96 | $inDT = new \DateTime(date('Y/m/d', $inDate)); |
||
| 97 | $wkDay = $this->setWorkingDaysInMonth($inDT, $this->tCmnSuperGlobals->get('pc')); |
||
| 98 | $nMealDays = ($wkDay - $this->tCmnSuperGlobals->get('zfb')); |
||
| 99 | $shLbl = [ |
||
| 100 | 'HFP' => 'Health Fund Percentage', |
||
| 101 | 'HFUL' => 'Health Fund Upper Limit', |
||
| 102 | 'HTP' => 'Health Tax Percentage', |
||
| 103 | 'IT' => 'Income Tax', |
||
| 104 | 'MTV' => 'Meal Ticket Value', |
||
| 105 | ]; |
||
| 106 | $unemploymentBase = $lngBase; |
||
| 107 | if ($this->tCmnSuperGlobals->get('ym') < mktime(0, 0, 0, 1, 1, 2008)) { |
||
| 108 | $unemploymentBase = $this->tCmnSuperGlobals->get('sn'); |
||
| 109 | } |
||
| 110 | $aReturn = [ |
||
| 111 | 'ba' => $this->setFoodTicketsValue($inDate, $aStngs[$shLbl['MTV']]) * $nMealDays, |
||
| 112 | 'cas' => $this->setHealthFundTax($inDate, $lngBase, $aStngs[$shLbl['HFP']], $aStngs[$shLbl['HFUL']]), |
||
| 113 | 'sanatate' => $this->setHealthTax($inDate, $lngBase, $aStngs[$shLbl['HTP']]), |
||
| 114 | 'somaj' => $this->setUnemploymentTax($inDate, $unemploymentBase), |
||
| 115 | ]; |
||
| 116 | $pdVal = [ |
||
| 117 | $inDate, |
||
| 118 | ($lngBase + $aReturn['ba']), |
||
| 119 | $this->tCmnSuperGlobals->get('pi'), |
||
| 120 | $aStngs['Personal Deduction'], |
||
| 121 | ]; |
||
| 122 | $aReturn['pd'] = $this->setPersonalDeduction($pdVal[0], $pdVal[1], $pdVal[2], $pdVal[3]); |
||
| 123 | $restArrayToDeduct = [ |
||
| 124 | $aReturn['cas'], |
||
| 125 | $aReturn['sanatate'], |
||
| 126 | $aReturn['somaj'], |
||
| 127 | $aReturn['pd'], |
||
| 128 | ]; |
||
| 129 | $rest = $lngBase - array_sum($restArrayToDeduct); |
||
| 130 | if ($inDate >= mktime(0, 0, 0, 7, 1, 2010)) { |
||
| 131 | $rest += round($aReturn['ba'], -4); |
||
| 132 | if ($inDate >= mktime(0, 0, 0, 10, 1, 2010)) { |
||
| 133 | $aReturn['gbns'] = $this->tCmnSuperGlobals->get('gbns') * pow(10, 4); |
||
| 134 | $rest += round($aReturn['gbns'], -4); |
||
| 135 | } |
||
| 136 | } |
||
| 137 | $rest += $this->tCmnSuperGlobals->get('afet') * pow(10, 4); |
||
| 138 | $aReturn['impozit'] = $this->setIncomeTax($inDate, $rest, $aStngs[$shLbl['IT']]); |
||
| 139 | $aReturn['zile'] = $wkDay; |
||
| 140 | return $aReturn; |
||
| 141 | } |
||
| 142 | |||
| 143 | private function handleLocalizationSalariu($appSettings) |
||
| 144 | { |
||
| 145 | $this->handleLocalizationSalariuInputsIntoSession($appSettings); |
||
| 146 | $this->handleLocalizationSalariuSafe($appSettings); |
||
| 147 | $localizationFile = 'Salariu/locale/' . $this->tCmnSession->get('lang') . '/LC_MESSAGES/salariu.mo'; |
||
| 148 | $translations = new \Gettext\Translations; |
||
| 149 | $translations->addFromMoFile($localizationFile); |
||
| 150 | $this->tApp = new \Gettext\Translator(); |
||
| 151 | $this->tApp->loadTranslations($translations); |
||
| 152 | } |
||
| 153 | |||
| 154 | private function handleLocalizationSalariuInputsIntoSession($appSettings) |
||
| 155 | { |
||
| 156 | if (is_null($this->tCmnSuperGlobals->get('lang')) && is_null($this->tCmnSession->get('lang'))) { |
||
| 157 | $this->tCmnSession->set('lang', $appSettings['Default Language']); |
||
| 158 | } elseif (!is_null($this->tCmnSuperGlobals->get('lang'))) { |
||
| 159 | $this->tCmnSession->set('lang', filter_var($this->tCmnSuperGlobals->get('lang'), FILTER_SANITIZE_STRING)); |
||
| 160 | } |
||
| 161 | } |
||
| 162 | |||
| 163 | /** |
||
| 164 | * to avoid potential language injections from other applications that do not applies here |
||
| 165 | */ |
||
| 166 | private function handleLocalizationSalariuSafe($appSettings) |
||
| 167 | { |
||
| 168 | if (!array_key_exists($this->tCmnSession->get('lang'), $appSettings['Available Languages'])) { |
||
| 169 | $this->tCmnSession->set('lang', $appSettings['Default Language']); |
||
| 170 | } |
||
| 171 | } |
||
| 172 | |||
| 173 | private function processFormInputDefaults($inDefaultValues) |
||
| 174 | { |
||
| 175 | if (is_null($this->tCmnSuperGlobals->get('ym'))) { |
||
| 176 | $this->tCmnSuperGlobals->request->set('ym', mktime(0, 0, 0, date('m'), 1, date('Y'))); |
||
| 177 | } |
||
| 178 | foreach ($inDefaultValues as $key => $value) { |
||
| 179 | if (is_null($this->tCmnSuperGlobals->get($key))) { |
||
| 180 | $this->tCmnSuperGlobals->request->set($key, $value); |
||
| 181 | } |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | private function setFooterHtml($appSettings) |
||
| 196 | |||
| 197 | private function setFormInput() |
||
| 198 | { |
||
| 199 | $sReturn = $this->setFormInputElements(); |
||
| 200 | $btn = $this->setStringIntoShortTag('input', [ |
||
| 201 | 'type' => 'submit', |
||
| 202 | 'id' => 'submit', |
||
| 203 | 'value' => $this->setLabel('bc') |
||
| 204 | ]); |
||
| 205 | $sReturn[] = $this->setFormRow($this->setLabel('fd'), $btn, 1); |
||
| 216 | |||
| 217 | private function setFormInputElements() |
||
| 235 | |||
| 236 | private function setFormInputSelectPC() |
||
| 244 | |||
| 245 | private function setFormInputSelectPI() |
||
| 253 | |||
| 254 | private function setFormInputSelectYM() |
||
| 267 | |||
| 268 | private function setFormInputText($inName, $inSize, $inAfterLabel) |
||
| 279 | |||
| 280 | private function setFormOutput($configPath) |
||
| 340 | |||
| 341 | private function setFormRow($text, $value, $type = 'amount') |
||
| 370 | |||
| 371 | private function setFormatRow($text, $value) |
||
| 386 | |||
| 387 | private function setHeaderHtml() |
||
| 400 | |||
| 401 | private function setLabel($labelId) |
||
| 418 | |||
| 419 | private function setLabelSuffix($text) |
||
| 427 | } |
||
| 428 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: