| Total Complexity | 54 | 
| Total Lines | 255 | 
| Duplicated Lines | 0 % | 
| Changes | 0 | ||
Complex classes like TCaptureForkLog 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 TCaptureForkLog, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 47 | class TCaptureForkLog extends \Prado\Util\TBehavior  | 
            ||
| 48 | { | 
            ||
| 49 | public const BEHAVIOR_NAME = 'captureforklog';  | 
            ||
| 50 | |||
| 51 | /** @var bool Is the master receiver (of child logs) installed. */  | 
            ||
| 52 | private bool $_receiverInstalled = false;  | 
            ||
| 53 | |||
| 54 | /** @var ?array The parent connections to each child fork receiving logs from. */  | 
            ||
| 55 | protected ?array $_parentConnections = [];  | 
            ||
| 56 | |||
| 57 | /** @var mixed The child connection to the parent */  | 
            ||
| 58 | protected mixed $_childConnection = null;  | 
            ||
| 59 | |||
| 60 | /**  | 
            ||
| 61 | 	 * Installs {@see self::generateConnection()} on fxPrepareForFork and | 
            ||
| 62 | 	 * {@see self::configureForChildLogs()} on fxRestoreAfterFork. | 
            ||
| 63 | * @return array Event callbacks for the behavior.  | 
            ||
| 64 | */  | 
            ||
| 65 | public function events()  | 
            ||
| 66 | 	{ | 
            ||
| 67 | return [TProcessHelper::FX_PREPARE_FOR_FORK => 'generateConnection',  | 
            ||
| 68 | TProcessHelper::FX_RESTORE_AFTER_FORK => 'configureForChildLogs'];  | 
            ||
| 69 | }  | 
            ||
| 70 | |||
| 71 | /**  | 
            ||
| 72 | *  | 
            ||
| 73 | * @return ?float The priority of the behavior, default -10 and not  | 
            ||
| 74 | * the normal "null".  | 
            ||
| 75 | */  | 
            ||
| 76 | public function getPriority(): ?float  | 
            ||
| 77 | 	{ | 
            ||
| 78 | 		if (($priority = parent::getPriority()) === null) { | 
            ||
| 79 | $priority = -10;  | 
            ||
| 80 | }  | 
            ||
| 81 | return $priority;  | 
            ||
| 82 | }  | 
            ||
| 83 | |||
| 84 | /**  | 
            ||
| 85 | * This is the singleton behavior. Only one instance of itself can be a behavior  | 
            ||
| 86 | * of the owner.  | 
            ||
| 87 | * @param string $name The name of teh behavior being added to the owner.  | 
            ||
| 88 | * @param IBaseBehavior $behavior The behavior being added to the owner.  | 
            ||
| 89 | * @param TCallChain $chain The chain of event handlers.  | 
            ||
| 90 | */  | 
            ||
| 91 | public function dyAttachBehavior($name, $behavior, TCallChain $chain)  | 
            ||
| 92 | 	{ | 
            ||
| 93 | $owner = $this->getOwner();  | 
            ||
| 94 | 		if (count($owner->getBehaviors(self::class)) > 1) { | 
            ||
| 95 | $owner->detachBehavior($name);  | 
            ||
| 96 | }  | 
            ||
| 97 | return $chain->dyAttachBehavior($name, $behavior);  | 
            ||
| 98 | }  | 
            ||
| 99 | |||
| 100 | /**  | 
            ||
| 101 | * The behavior callback for fxPrepareForFork that creates a socket pair connection  | 
            ||
| 102 | * between the parent process and child process before forking.  | 
            ||
| 103 | * @param mixed $sender The TApplication doing the fork.  | 
            ||
| 104 | * @param mixed $param The parameter of fxPrepareForFork.  | 
            ||
| 105 | * @return ?array Any data to be passed back to the restore function.  | 
            ||
| 106 | * eg. `return ['key', 'data'];` will be passed in the restore function as  | 
            ||
| 107 | * `['key' => 'data', 'pid' => ###, ...]`.  | 
            ||
| 108 | */  | 
            ||
| 109 | public function generateConnection(mixed $sender, mixed $param)  | 
            ||
| 110 | 	{ | 
            ||
| 111 | $domain = TProcessHelper::isSystemWindows() ? AF_INET : AF_UNIX;  | 
            ||
| 112 | 		if (!socket_create_pair($domain, SOCK_STREAM, 0, $this->_childConnection)) { | 
            ||
| 113 | $this->_childConnection = null;  | 
            ||
| 114 | return;  | 
            ||
| 115 | }  | 
            ||
| 116 | $this->_childConnection[0] = socket_export_stream($this->_childConnection[0]);  | 
            ||
| 117 | $this->_childConnection[1] = socket_export_stream($this->_childConnection[1]);  | 
            ||
| 118 | return null;  | 
            ||
| 119 | }  | 
            ||
| 120 | |||
| 121 | /**  | 
            ||
| 122 | * The behavior call back for fxRestoreAfterFork that cleans the log and resets  | 
            ||
| 123 | * the logger to send the log to the parent process. The Parent process stores  | 
            ||
| 124 | * the child stream and pid and installs the onEndRequest handler to receive the  | 
            ||
| 125 | * logs from the children forks.  | 
            ||
| 126 | * @param mixed $sender  | 
            ||
| 127 | * @param array $data the  | 
            ||
| 128 | */  | 
            ||
| 129 | public function configureForChildLogs(mixed $sender, mixed $data)  | 
            ||
| 163 | }  | 
            ||
| 164 | }  | 
            ||
| 165 | }  | 
            ||
| 166 | |||
| 167 | /**  | 
            ||
| 168 | * Receives logs from children forked processes and merges the logs with the current  | 
            ||
| 169 | * application TLogger.  | 
            ||
| 170 | * @param ?int $pid The process ID to receive the logs from, default null for all.  | 
            ||
| 171 | * @param bool $wait Wait for results until complete, default true. When false,  | 
            ||
| 172 | * this will process the pending logs and not wait for further logs.  | 
            ||
| 173 | */  | 
            ||
| 174 | public function receiveLogsFromChildren(?int $pid = null, bool $wait = true)  | 
            ||
| 244 | }  | 
            ||
| 245 | }  | 
            ||
| 246 | |||
| 247 | /**  | 
            ||
| 248 | * First, Receives any logs from the children. If this instance is a child fork  | 
            ||
| 249 | * then send the log to the parent process. If the call is final then the connection  | 
            ||
| 250 | * to the parent is shutdown.  | 
            ||
| 251 | * @param mixed $logger The TLogger that raised the onFlushLogs event.  | 
            ||
| 252 | * @param mixed $final Is this the last and final call.  | 
            ||
| 253 | */  | 
            ||
| 254 | public function sendLogsToParent($logger, $final)  | 
            ||
| 302 | }  | 
            ||
| 303 | }  | 
            ||
| 305 | 
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths