getName() ] = true; } foreach ( $discovered as $tool ) { foreach ( $this->companions( $tool ) as $companion ) { if ( ! isset( $seen[ $companion->getName() ] ) ) { $seen[ $companion->getName() ] = true; $discovered[] = $companion; } } } return $discovered; } /** * Pool tools whose name appears in the given tool's description. * * The name must stand alone: matching on a bare substring would make * "pointics-list-channels" pull in "pointics-list-channel-building-blocks" * and vice versa, since one name is a prefix of the other. * * @param ToolInterface $tool Tool whose description is scanned. * @return ToolInterface[] */ private function companions( ToolInterface $tool ): array { $description = (string) $tool->getDescription(); if ( '' === $description ) { return []; } $companions = []; foreach ( $this->toolPool as $candidate ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Vendor property name. $name = $candidate->getName(); if ( $name === $tool->getName() ) { continue; } if ( preg_match( '/(?