saloonphp / saloon

🤠 Build beautiful API integrations and SDKs with Saloon
https://docs.saloon.dev
MIT License
2.03k stars 105 forks source link

Inteliphense cannot recognize the merge() method on request #395

Closed Whizboy-Arnold closed 1 month ago

Whizboy-Arnold commented 5 months ago

Undefined method 'merge'.intelephense(1013)

I keep getting this bugging underline by inteliphense on vs-code, it complains not to find the method and even cannot autocomplete, however the code works fine. I got to only know the merge() method itself since i was already using it from previous version as mergeData() however this new v3 merge() seems to have something lacking i cant point out.

image

The other method is setJsonFlags within the request itself

image

Could you clarify if this is a saloon problem or inteliphense, although all my other code and even previous version is working fine, only version 3 brings up these issues.

juse-less commented 5 months ago

Hi!

It'd be easier if you shared the request class. But assuming you're using the right body trait, this is an issue with Intelephense. The JsonBodyRepository::setJsonFlags() method is defined right on the class without any dynamic resolving or so.

The JsonBodyRepository::merge() method is inherited from ArrayBodyRepository, which has no dynamic resolving to it either.

The HasJsonBody trait that you'd use for JSON bodies also declares JsonBodyRepository as the return type for the body() method.

Whizboy-Arnold commented 4 months ago

Hello @juse-less Thank you for the timely response, Sorry for the delay its only that i found a quick fix for it, by annotating the type for intelliphense. However still for a better solution it may be good to just have it out of the box. to replicate the problem here is my request class:

`<?php namespace App\Http\Integrations\MyServer;

use App\Http\Integrations\MyServer\MyServerConnector; use Illuminate\Support\Facades\Log;

class MyServerService
{ private $debug=false; private MyServerConnector $my_service;

public function __construct( 
){
    $this->my_service = new MyServerConnector;
}

public function getService($request_ref, array $pegs ){
    $request = new MyRequest("ENGINE_1");

    // the probelmatic part is below for now adding the anotation helps with inteliphense. 
    /** @var Saloon\Contracts\Body\MergeableBody $reqb **/
    $reqb=$request->body();
    $reqb->merge([
        "request_ref" => $request_ref,
        "pegs" => $pegs,
    ]);

    Log::debug(" with ".$request->body());
    $response = $this->my_service->send($request);        
    Log::debug(" response status: ".$response->status());
    Log::debug(" response object: ".$response->body());
    if($this->debug)Log::debug(" response object: ".print_r($response->object(),true));
    return $response->object();  
}

} ` then this is my request....

`<?php

namespace App\Http\Integrations\MyServer\Requests;

use Saloon\Contracts\Body\HasBody; use Saloon\Enums\Method; use Saloon\Http\Request; use Saloon\Traits\Body\HasJsonBody;

class MyFocusRequest extends Request implements HasBody { use HasJsonBody;

// protected ?string $connector = CoreApiConnector::class;//// this is not used in v3 

public function __construct(public string $engine_code) {
    /** @var Saloon\Contracts\Body\JsonBodyRepository $reqb **/
    $reqb=$this->body();
    $reqb->setJsonFlags(JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);

}

/**
 * The HTTP method of the request
 */
protected Method $method = Method::POST;

/**
 * The endpoint for the request
 */
public function resolveEndpoint(): string
{
    return "/myendpoint"; 
}

} `

and here is the screenshot of when i annotate, the underlining goes away: image

juse-less commented 4 months ago

I'd need to double-check the difference between v2 and v3. But if I recall correctly, we had interfaces for each body type, which then type-hinted with the appropriate body type.

HasBody is type-hinted with a generic body (as it should). The traits for the respective body type implementation, however, overrides that generic type with the more narrow type.

As to why Intelephense doesn't work with that, I'm not sure. It could be something like Intelephense not working correctly with traits and/or in combination with interfaces. But if I remember correctly on the difference between v2 and v3, it does sound like Intelephense takes the type from the interface rather than the trait.

I can't see that it'd be an error in Saloon itself, as my PhpStorm, Phpactor, and PHPStan works correctly for me. Nor did I see any type errors in the code when I looked.

If you haven't already, though, I'd recommend re-indexing the project(s). Sometimes indexes get corrupted, regardless of editor/IDE/language server.