Skip to content

fix: resolve non-existent global function call in ExternalServicesJsonApiResponseFetcher - #216

Merged
PDowney merged 9 commits into
masterfrom
copilot/fix-non-existent-function-call
Apr 22, 2026
Merged

PDowney merged 9 commits into
masterfrom
copilot/fix-non-existent-function-call

Conversation

Copilot AI commented Apr 22, 2026

Copy link
Copy Markdown
Contributor
  • All prior modernisation complete (enum ServiceStatus, readonly constructors, typed constants, etc.)
  • Created classes/CurlInitException.phpfinal class CurlInitException extends \RuntimeException {}
  • require_once CurlInitException.php added to external-services-api.php and ExternalServicesController.php
  • Both throw new \RuntimeException replaced with throw new CurlInitException; @throws docblocks updated
  • All three files pass php -l
  • Updated CHANGELOG.md
Original prompt
Please apply the following diffs and create a pull request.
Once the PR is ready, give it a title based on the messages of the fixes being applied.

[{"message":"This call references a non-existent function 'createSecureCurlHandle'. The method 'createSecureCurlHandle' is a private instance method of 'ExternalServicesFeedParser', not a global function. This class should either receive an instance of 'ExternalServicesFeedParser' to call the method, or duplicate the secure cURL setup logic.","fixFiles":[{"filePath":"config/var/www/admin/control-panel/external-services/external-services-api.php","diff":"diff --git a/config/var/www/admin/control-panel/external-services/external-services-api.php b/config/var/www/admin/control-panel/external-services/external-services-api.php\n--- a/config/var/www/admin/control-panel/external-services/external-services-api.php\n+++ b/config/var/www/admin/control-panel/external-services/external-services-api.php\n@@ -617,13 +617,38 @@\n class ExternalServicesJsonApiResponseFetcher\n {\n     /**\n+     * Create a secure cURL handle for JSON API requests.\n+     *\n      * @param string $apiUrl API endpoint URL\n+     * @return resource|\\CurlHandle\n+     */\n+    private function createSecureCurlHandle(string $apiUrl)\n+    {\n+        $curl = curl_init($apiUrl);\n+        curl_setopt_array($curl, [\n+            CURLOPT_RETURNTRANSFER => true,\n+            CURLOPT_FOLLOWLOCATION => false,\n+            CURLOPT_MAXREDIRS => 0,\n+            CURLOPT_CONNECTTIMEOUT => 10,\n+            CURLOPT_TIMEOUT => 30,\n+            CURLOPT_SSL_VERIFYPEER => true,\n+            CURLOPT_SSL_VERIFYHOST => 2,\n+            CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,\n+            CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTPS,\n+            CURLOPT_USERAGENT => 'EngineScript External Services Monitor'\n+        ]);\n+\n+        return $curl;\n+    }\n+\n+    /**\n+     * @param string $apiUrl API endpoint URL\n      * @return array{data: array, error: ?array}\n      */\n     public function fetch(string $apiUrl): array\n     {\n         // Reuse centralized secure cURL configuration to avoid drift/duplication.\n-        $curl = createSecureCurlHandle($apiUrl);\n+        $curl = $this->createSecureCurlHandle($apiUrl);\n \n         $response = curl_exec($curl);\n         $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);\n"}]}]

…nApiResponseFetcher

Promote ExternalServicesFeedParser::createSecureCurlHandle() to public static,
update internal caller to self::, and update ExternalServicesJsonApiResponseFetcher
to call ExternalServicesFeedParser::createSecureCurlHandle() — no code duplication.

Agent-Logs-Url: https://github.com/EngineScript/EngineScript/sessions/356dcbac-660c-45c0-9f5f-75ce1d21c4b6

Co-authored-by: PDowney <11467177+PDowney@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix call to non-existent function in external-services-api fix: resolve non-existent global function call in ExternalServicesJsonApiResponseFetcher Apr 22, 2026
Copilot AI requested a review from PDowney April 22, 2026 00:11
Copilot AI and others added 4 commits April 22, 2026 00:44
…nstructors, typed constants, CurlHandle type, final classes

Agent-Logs-Url: https://github.com/EngineScript/EngineScript/sessions/abb36eca-8166-4968-a9a3-44fdc50a6a99

Co-authored-by: PDowney <11467177+PDowney@users.noreply.github.com>
Updated the changelog to reflect recent changes, including the addition of a dedicated Curl exception class and various refactorings for PHP 8.2–8.4 modernization.
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@sonarqubecloud

Copy link
Copy Markdown

@PDowney
PDowney marked this pull request as ready for review April 22, 2026 03:20
Copilot AI review requested due to automatic review settings April 22, 2026 03:20
@PDowney
PDowney merged commit 7debf86 into master Apr 22, 2026
10 of 11 checks passed
@github-actions
github-actions Bot deleted the copilot/fix-non-existent-function-call branch April 22, 2026 03:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an invalid call to a non-existent global createSecureCurlHandle() by centralizing secure cURL handle creation and reusing it from the JSON API response fetcher, while also modernizing and de-duplicating parts of the external services parsing stack.

Changes:

  • Introduced CurlInitException and switched cURL init failures from generic runtime exceptions to a dedicated exception type.
  • Centralized secure cURL creation via a shared trait and updated ExternalServicesJsonApiResponseFetcher to call the correct instance method.
  • Refactored external-services parsing to reduce duplication (shared nested-path resolver, ServiceStatus enum), and cleaned up repetitive version parsing in ServiceController.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
config/var/www/admin/control-panel/external-services/external-services-api.php Fixes the non-existent function call by reusing a shared cURL factory; adds shared JSON path resolver and ServiceStatus enum refactors.
config/var/www/admin/control-panel/controllers/ServiceController.php Consolidates repeated version parsing logic into a helper method.
config/var/www/admin/control-panel/controllers/ExternalServicesController.php Adds CurlInitException loading and factors cURL setup into a reusable helper for external requests.
config/var/www/admin/control-panel/classes/CurlInitException.php Adds a dedicated exception type for curl_init() failures.
CHANGELOG.md Documents the refactor/modernisation changes.

Comment on lines +221 to +230
* HTML-escaped. Returns 'Unknown' when output is null or the pattern
* does not match.
*
* @param string|null $output Raw command output
* @param string $pattern PCRE pattern with one capture group for the version
* @return string Sanitized version string or 'Unknown'
*/
private function parseVersionOutput(?string $output, string $pattern): string
{
if ($output !== null && preg_match($pattern, $output, $matches)) {

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parseVersionOutput() assumes $output is null or a string, but the SystemCommand::*Version() methods return string|false. If they return false, preg_match() will throw a TypeError (bool given), which is not caught by this controller. Guard with is_string($output) before calling preg_match(), or widen the parameter type to string|false and treat false as Unknown.

Suggested change
* HTML-escaped. Returns 'Unknown' when output is null or the pattern
* does not match.
*
* @param string|null $output Raw command output
* @param string $pattern PCRE pattern with one capture group for the version
* @return string Sanitized version string or 'Unknown'
*/
private function parseVersionOutput(?string $output, string $pattern): string
{
if ($output !== null && preg_match($pattern, $output, $matches)) {
* HTML-escaped. Returns 'Unknown' when output is null, false, or the
* pattern does not match.
*
* @param string|false|null $output Raw command output
* @param string $pattern PCRE pattern with one capture group for the version
* @return string Sanitized version string or 'Unknown'
*/
private function parseVersionOutput(string|false|null $output, string $pattern): string
{
if (is_string($output) && preg_match($pattern, $output, $matches)) {

Copilot uses AI. Check for mistakes.
Comment on lines 625 to 636
/**
* @param string $apiUrl API endpoint URL
* @return array{data: array, error: ?array}
*/
public function fetch(string $apiUrl): array
{
// Reuse centralized secure cURL configuration to avoid drift/duplication.
$curl = createSecureCurlHandle($apiUrl);
$curl = $this->createSecureCurlHandle($apiUrl);

$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ExternalServicesJsonApiResponseFetcher::fetch() now calls createSecureCurlHandle() from SecureCurlHandleTrait, which can throw CurlInitException. That breaks fetch()'s stated contract of always returning an array{data, error} and can bubble exceptions to any future callers. Consider catching CurlInitException inside fetch() and returning FetchError, or update the method’s PHPDoc/contract to document the thrown exception and ensure all callers handle it.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants