| Total Complexity | 53 |
| Total Lines | 393 |
| Duplicated Lines | 0 % |
| Changes | 4 | ||
| Bugs | 0 | Features | 0 |
Complex classes like ExtensionsOutWorkTimeConf 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.
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 ExtensionsOutWorkTimeConf, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 41 | class ExtensionsOutWorkTimeConf extends AsteriskConfigClass |
||
| 42 | { |
||
| 43 | // The module hook applying priority |
||
| 44 | public int $priority = 510; |
||
| 45 | public const OUT_WORK_TIME_CONTEXT = 'check-out-work-time'; |
||
| 46 | private string $conf = ''; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * Generates core modules config files |
||
| 50 | */ |
||
| 51 | protected function generateConfigProtected(): void |
||
| 52 | { |
||
| 53 | $config = ''; |
||
| 54 | /** @var OutWorkTimes $rule */ |
||
| 55 | $rules = OutWorkTimes::find(); |
||
| 56 | foreach ($rules as $rule){ |
||
| 57 | if(empty($rule->calType)){ |
||
| 58 | continue; |
||
| 59 | } |
||
| 60 | $config.= "[calendar-$rule->id]".PHP_EOL. |
||
| 61 | 'type='.$rule->calType.PHP_EOL. |
||
| 62 | 'url='.$rule->calUrl.PHP_EOL. |
||
| 63 | 'user='.$rule->calUser.PHP_EOL. |
||
| 64 | 'secret='.$rule->calSecret.PHP_EOL. |
||
| 65 | 'refresh=1'.PHP_EOL. |
||
| 66 | 'timeframe=60'.PHP_EOL. |
||
| 67 | 'channel = Local/s@calendar-event'.PHP_EOL. |
||
| 68 | 'app = Playback'.PHP_EOL. |
||
| 69 | 'appdata = beep'. PHP_EOL.PHP_EOL; |
||
| 70 | } |
||
| 71 | Util::fileWriteContent($this->config->path('asterisk.astetcdir') . '/calendar.conf', $config); |
||
| 72 | $arr_out = []; |
||
| 73 | $pid = Processes::getPidOfProcess('asterisk'); |
||
| 74 | if(!empty($pid)){ |
||
| 75 | $asteriskPath = Util::which('asterisk'); |
||
| 76 | Processes::mwExec("{$asteriskPath} -rx 'module reload res_calendar'", $arr_out); |
||
| 77 | } |
||
| 78 | |||
| 79 | } |
||
| 80 | |||
| 81 | /** |
||
| 82 | * Generates the extension contexts for out of work time configurations. |
||
| 83 | * |
||
| 84 | * @return string The generated configuration. |
||
| 85 | */ |
||
| 86 | public function extensionGenContexts(): string |
||
| 87 | { |
||
| 88 | $this->generateConfigProtected(); |
||
| 89 | $this->generateOutWorkTimes(); |
||
| 90 | return $this->conf; |
||
| 91 | } |
||
| 92 | |||
| 93 | |||
| 94 | /** |
||
| 95 | * |
||
| 96 | * @return string Set global vars. |
||
| 97 | */ |
||
| 98 | public function extensionGlobals(): string |
||
| 99 | { |
||
| 100 | $configs = ''; |
||
| 101 | $dbData = Sip::find("type = 'friend' AND ( disabled <> '1')"); |
||
| 102 | foreach ($dbData as $sipPeer) { |
||
| 103 | $context_id = SIPConf::getContextId($sipPeer->host, $sipPeer->port); |
||
| 104 | $configs .= "CONTEXT_ID_$sipPeer->uniqid=$context_id".PHP_EOL; |
||
| 105 | } |
||
| 106 | return $configs; |
||
| 107 | } |
||
| 108 | |||
| 109 | /** |
||
| 110 | * Generates the customized incoming context for a specific route before dialing system. |
||
| 111 | * |
||
| 112 | * @param string $rout_number The route number. |
||
| 113 | * |
||
| 114 | * @return string The generated configuration. |
||
| 115 | */ |
||
| 116 | public function generateIncomingRoutBeforeDialSystem(string $rout_number): string |
||
| 117 | { |
||
| 118 | // Check the schedule for incoming external calls. |
||
| 119 | return 'same => n,NoOp(contextID: ${contextID})' . PHP_EOL . "\t" . |
||
| 120 | 'same => n,ExecIf($["${CONTEXT}" == "public-direct-dial"]?Set(contextID=none-incoming))' . PHP_EOL . "\t" . |
||
| 121 | 'same => n,ExecIf($["${contextID}x" == "x"]?Set(contextID=${CONTEXT_ID_${providerID}}))' . PHP_EOL . "\t" . |
||
| 122 | 'same => n,ExecIf($["${contextID}x" == "x"]?Set(contextID=${CONTEXT}))' . PHP_EOL . "\t" . |
||
| 123 | 'same => n,GosubIf($["${IGNORE_TIME}" != "1"]?' . self::OUT_WORK_TIME_CONTEXT . ',${EXTEN},1)' . PHP_EOL . "\t"; |
||
| 124 | } |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Generates the out of work time configurations. |
||
| 128 | * |
||
| 129 | * @return void |
||
| 130 | */ |
||
| 131 | private function generateOutWorkTimes(): void |
||
| 132 | { |
||
| 133 | $this->conf = PHP_EOL."[playback-exit]".PHP_EOL. |
||
| 134 | 'exten => ' . ExtensionsConf::ALL_EXTENSION . ',1,Gosub(dial_outworktimes,${EXTEN},1)' . PHP_EOL."\t". |
||
| 135 | 'same => n,Playback(${filename})' . PHP_EOL. "\t". |
||
| 136 | 'same => n,Hangup()'.PHP_EOL. |
||
| 137 | 'exten => _[hit],1,Hangup()'.PHP_EOL.PHP_EOL; |
||
| 138 | $this->conf .= '[calendar-event]'.PHP_EOL. |
||
| 139 | 'exten => s,1,NoOp( calendar: ${CALENDAR_EVENT(calendar)}, summary: ${CALENDAR_EVENT(summary)} )'.PHP_EOL."\t". |
||
| 140 | 'same => n,NoOp( description: ${CALENDAR_EVENT(description)} )'.PHP_EOL."\t". |
||
| 141 | 'same => n,NoOp( start: ${CALENDAR_EVENT(start)}, end: ${CALENDAR_EVENT(end)})'.PHP_EOL."\t". |
||
| 142 | 'same => n,NoOp( busystate: ${CALENDAR_EVENT(busystate)} )'.PHP_EOL."\t". |
||
| 143 | 'same => n,answer()'.PHP_EOL."\t". |
||
| 144 | 'same => n,Wait(2)' . PHP_EOL . |
||
| 145 | 'same => n,hangup' . PHP_EOL . PHP_EOL; |
||
| 146 | |||
| 147 | $routesData = $this->getRoutesData(); |
||
| 148 | $additionalContexts = ''; |
||
| 149 | $conf_out_set_var = ''; |
||
| 150 | $data = OutWorkTimes::find(['order'=>'priority, date_from'])->toArray(); |
||
| 151 | $this->conf .= "[" . self::OUT_WORK_TIME_CONTEXT . "]".PHP_EOL; |
||
| 152 | $this->conf .= 'exten => ' . ExtensionsConf::ALL_EXTENSION . ',1,Set(currentYear=${STRFTIME(,,%Y)})' . "\n\t"; |
||
| 153 | foreach ($data as $ruleData) { |
||
| 154 | $contextId = 'check-out-work-time-'.$ruleData['id']; |
||
| 155 | $this->conf .= 'same => n,Gosub('.$contextId.',${EXTEN},1)'.PHP_EOL."\t"; |
||
| 156 | $additionalContexts.= '['.$contextId.']'.PHP_EOL; |
||
| 157 | $additionalContexts.= 'exten => _[0-9*#+a-zA-Z]!,1,NoOp()'.PHP_EOL."\t"; |
||
| 158 | // Restrictions for the route are not allowed for this rule. |
||
| 159 | if ($ruleData['allowRestriction'] === '1') { |
||
| 160 | $additionalContexts.= 'same => n,ExecIf($["${DIALPLAN_EXISTS('.$contextId.'-${contextID},${EXTEN},1)}" == "0"]?return)'.PHP_EOL."\t"; |
||
| 161 | } |
||
| 162 | if(empty($ruleData['calType'])){ |
||
| 163 | $this->generateOutWorkRule($ruleData, $conf_out_set_var, $additionalContexts); |
||
| 164 | }else{ |
||
| 165 | $appdata = $this->initRuleAppData($ruleData, $conf_out_set_var); |
||
| 166 | $additionalContexts.= 'same => n,GotoIf(${CALENDAR_BUSY(calendar-'.$ruleData['id'].')}?'.$appdata.')'.PHP_EOL."\t"; |
||
| 167 | } |
||
| 168 | $additionalContexts.= 'same => n,return'.PHP_EOL; |
||
| 169 | $additionalContexts.= 'exten => _[hit],1,Hangup()'.PHP_EOL; |
||
| 170 | $contextData = $routesData[$ruleData['id']]??[]; |
||
| 171 | foreach ($contextData as $subContext => $arrayDid){ |
||
| 172 | $additionalContexts.= "[$contextId-$subContext]".PHP_EOL; |
||
| 173 | foreach (array_unique($arrayDid) as $did){ |
||
| 174 | $additionalContexts .= "exten => $did,1,NoOp(-)" . PHP_EOL; |
||
| 175 | } |
||
| 176 | } |
||
| 177 | $additionalContexts.= PHP_EOL; |
||
| 178 | |||
| 179 | } |
||
| 180 | $this->conf .= "same => n,return".PHP_EOL; |
||
| 181 | $this->conf .= 'exten => _[hit],1,Hangup()' . PHP_EOL.PHP_EOL; |
||
| 182 | $this->conf .= $additionalContexts.PHP_EOL; |
||
| 183 | $this->conf .= PHP_EOL.$conf_out_set_var.PHP_EOL; |
||
| 184 | } |
||
| 185 | |||
| 186 | /** |
||
| 187 | * Retrieves the data for the routes. |
||
| 188 | * |
||
| 189 | * @return array |
||
| 190 | */ |
||
| 191 | private function getRoutesData(): array |
||
| 228 | } |
||
| 229 | |||
| 230 | /** |
||
| 231 | * Generate the out-of-work rule based on the provided data. |
||
| 232 | * |
||
| 233 | * @param array $srcOutData The data for the out-of-work rule. |
||
| 234 | * @param string &$conf_out_set_var The output string for the SET variables. |
||
| 235 | * @param string &$conf The output string for the configuration. |
||
| 236 | * |
||
| 237 | * @return void |
||
| 238 | */ |
||
| 239 | private function generateOutWorkRule(array $srcOutData, string &$conf_out_set_var, string &$conf): void |
||
| 240 | { |
||
| 241 | $intervals = $this->splitIntoMonthlyIntervals($srcOutData['date_from'], $srcOutData['date_to']); |
||
| 242 | if(empty($intervals)){ |
||
| 243 | $timesArray = $this->getTimesInterval($srcOutData); |
||
| 244 | $weekdays = $this->getWeekDayInterval($srcOutData); |
||
| 245 | [$mDays, $months] = $this->initDaysMonthsInterval($srcOutData); |
||
| 246 | $appdata = $this->initRuleAppData($srcOutData, $conf_out_set_var); |
||
| 247 | foreach ($timesArray as $times) { |
||
| 248 | $conf .= "same => n,GotoIfTime($times,$weekdays,$mDays,$months?{$appdata})\n\t"; |
||
| 249 | } |
||
| 250 | }else{ |
||
| 251 | foreach ($intervals as $interval){ |
||
| 252 | [$srcOutData['date_from'],$srcOutData['date_to']] = $interval; |
||
| 253 | |||
| 254 | $timesArray = $this->getTimesInterval($srcOutData); |
||
| 255 | $weekdays = $this->getWeekDayInterval($srcOutData); |
||
| 256 | |||
| 257 | [$mDays, $months] = $this->initDaysMonthsInterval($srcOutData); |
||
| 258 | $appdata = $this->initRuleAppData($srcOutData, $conf_out_set_var); |
||
| 259 | |||
| 260 | $year = 1 * date('Y', $srcOutData['date_from']); |
||
| 261 | foreach ($timesArray as $times) { |
||
| 262 | $timeAppData = "GotoIfTime($times,$weekdays,$mDays,$months?{$appdata})"; |
||
| 263 | $conf .= 'same => n,ExecIf($["${currentYear}" == "'.$year.'"]?'.$timeAppData.')'."\n\t"; |
||
| 264 | } |
||
| 265 | } |
||
| 266 | } |
||
| 267 | } |
||
| 268 | |||
| 269 | /** |
||
| 270 | * Get intervals from timestamp |
||
| 271 | * @param $date_from |
||
| 272 | * @param $date_to |
||
| 273 | * @return array |
||
| 274 | */ |
||
| 275 | private function splitIntoMonthlyIntervals($date_from, $date_to):array |
||
| 276 | { |
||
| 277 | if(empty($date_from) || empty($date_to)){ |
||
| 278 | return []; |
||
| 279 | } |
||
| 280 | $intervals = []; |
||
| 281 | $start = new DateTime(); |
||
| 282 | $start->setTimestamp($date_from); |
||
| 283 | $end = new DateTime(); |
||
| 284 | $end->setTimestamp($date_to); |
||
| 285 | while ($start < $end) { |
||
| 286 | $interval_start = clone $start; |
||
| 287 | $interval_end = clone $start; |
||
| 288 | $interval_end->modify('last day of this month 23:59:59'); |
||
| 289 | if ($interval_end > $end) { |
||
| 290 | $interval_end = $end; |
||
| 291 | } |
||
| 292 | $intervals[] = [ |
||
| 293 | $interval_start->getTimestamp(), |
||
| 294 | $interval_end->getTimestamp() |
||
| 295 | ]; |
||
| 296 | $start->modify('first day of next month 00:00:00'); |
||
| 297 | } |
||
| 298 | |||
| 299 | return $intervals; |
||
| 300 | } |
||
| 301 | |||
| 302 | /** |
||
| 303 | * Get the time intervals based on the provided out-of-work data. |
||
| 304 | * |
||
| 305 | * @param array $out_data The out-of-work data. |
||
| 306 | * |
||
| 307 | * @return array The time intervals. |
||
| 308 | */ |
||
| 309 | private function getTimesInterval(array $out_data): array |
||
| 310 | { |
||
| 311 | $time_from = $out_data['time_from']; |
||
| 312 | $time_to = $out_data['time_to']; |
||
| 313 | if (empty($time_from) && empty($time_to)) { |
||
| 314 | $intervals = ['*']; |
||
| 315 | } else { |
||
| 316 | $time_from = $this->normaliseTime($time_from); |
||
| 317 | $time_to = $this->normaliseTime($time_to, '23:59'); |
||
| 318 | if (strtotime($time_from) > strtotime($time_to)) { |
||
| 319 | $intervals = [ |
||
| 320 | "{$time_from}-23:59", |
||
| 321 | "00:00-{$time_to}" |
||
| 322 | ]; |
||
| 323 | } else { |
||
| 324 | $intervals = [ |
||
| 325 | "{$time_from}-{$time_to}" |
||
| 326 | ]; |
||
| 327 | } |
||
| 328 | } |
||
| 329 | return $intervals; |
||
| 330 | } |
||
| 331 | |||
| 332 | /** |
||
| 333 | * Normalize the time to an acceptable format. |
||
| 334 | * |
||
| 335 | * @param string $srcTime The source time to be normalized. |
||
| 336 | * @param string $defVal The default value to be used if the source time is empty. |
||
| 337 | * @return string The normalized time. |
||
| 338 | */ |
||
| 339 | private function normaliseTime($srcTime, $defVal = '00:00'): string |
||
| 340 | { |
||
| 341 | $time = (empty($srcTime)) ? $defVal : $srcTime; |
||
| 342 | return (strlen($time) === 4) ? "0{$time}" : $time; |
||
| 343 | } |
||
| 344 | |||
| 345 | /** |
||
| 346 | * Initialize the rule application data based on the rule type. |
||
| 347 | * |
||
| 348 | * @param array $ruleData The rule data. |
||
| 349 | * @param string $conf_out_set_var The reference to the configuration variable for output. |
||
| 350 | * |
||
| 351 | * @return string An array containing the data. |
||
| 352 | */ |
||
| 353 | private function initRuleAppData($ruleData, string &$conf_out_set_var): string |
||
| 372 | } |
||
| 373 | |||
| 374 | /** |
||
| 375 | * Returns a string representing the weekday interval. |
||
| 376 | * |
||
| 377 | * @param array $out_data An array containing the weekday_from and weekday_to values. |
||
| 378 | * |
||
| 379 | * @return string The weekday interval string. |
||
| 380 | */ |
||
| 381 | private function getWeekDayInterval(array $out_data): string |
||
| 398 | } |
||
| 399 | |||
| 400 | /** |
||
| 401 | * Initializes the days and months interval based on the provided data. |
||
| 402 | * |
||
| 403 | * @param array $out_data An array containing the date_from and date_to values. |
||
| 404 | * |
||
| 405 | * @return array An array containing the days and months interval. |
||
| 406 | */ |
||
| 407 | private function initDaysMonthsInterval(array $out_data): array |
||
| 408 | { |
||
| 409 | // Extract date_from and date_to values |
||
| 410 | $date_from = $out_data['date_from']; |
||
| 411 | $date_to = $out_data['date_to']; |
||
| 412 | if (empty($date_from)) { |
||
| 413 | // If date_from is empty, set mDays and months to '*' |
||
| 414 | $mDays = '*'; |
||
| 415 | $months = '*'; |
||
| 416 | } else { |
||
| 417 | // Convert date_from to lowercase day and month abbreviations |
||
| 418 | $mDays = strtolower(date("j", (int)$date_from)); |
||
| 419 | $months = strtolower(date("M", (int)$date_from)); |
||
| 420 | if (!empty($date_to)) { |
||
| 421 | $mDays .= "-" . strtolower(date("j", (int)$date_to)); |
||
| 422 | $months .= "-" . strtolower(date("M", (int)$date_to)); |
||
| 423 | } |
||
| 424 | } |
||
| 425 | return array($mDays, $months); |
||
| 426 | } |
||
| 427 | |||
| 428 | public function generateModulesConf(): string |
||
| 434 | } |
||
| 435 | } |