Tustin / psn-php

A PHP wrapper for the PSN API
https://tustin.dev/psn-php/
MIT License
354 stars 73 forks source link

$trophy->progressTargetValue (), $trophy->earnedDatetime () doesn't work anymore (and exit script) #222

Closed Reuns closed 1 year ago

Reuns commented 1 year ago

Hello there !

I didn't touch anything and once again : there is a new error.

<b>Fatal error</b>:  Uncaught Error: Call to a member function get() on null in [...]/vendor/tustin/haste/src/Http/HttpClient.php:34
Stack trace:
#0 [...]/vendor/tustin/psn-php/src/Model/Trophy/Trophy.php(194): Tustin\Haste\Http\HttpClient-&gt;get()
#1 [...]/vendor/tustin/psn-php/src/Model.php(42): Tustin\PlayStation\Model\Trophy\Trophy-&gt;fetch()
#2 [...]/vendor/tustin/psn-php/src/Model.php(69): Tustin\PlayStation\Model-&gt;performFetch()
#3 [...]/vendor/tustin/psn-php/src/Model/Trophy/Trophy.php(112): Tustin\PlayStation\Model-&gt;pluck()
  thrown in <b>[...]/vendor/tustin/haste/src/Http/HttpClient.php</b> on line <b>34</b><br />

Is it just me or Sony made new changes again ?

Reuns commented 1 year ago

Ok so the "progressTargetValue" doesn't work anymore... I hadn't test the "rewardName" and "rewardImageUrl" but get rid off them as well (just in case ....)

Reuns commented 1 year ago

There's also an other issue (which is quite more important than the previous one. Since I migrate to 3.0.1 (or dev-master) : If the timestamp from $trophy->earnedDatetime () is missing than the script stop. I've tried a lot of thing, but everytime I have this fatal error

<b>Fatal error</b>:  Uncaught Error: Call to a member function get() on null in [...]/vendor/tustin/haste/src/Http/HttpClient.php:34
Stack trace:
#0 [...]/vendor/tustin/psn-php/src/Model/Trophy/Trophy.php(194): Tustin\Haste\Http\HttpClient-&gt;get()
#1 [...]/vendor/tustin/psn-php/src/Model.php(42): Tustin\PlayStation\Model\Trophy\Trophy-&gt;fetch()
#2 [...]/vendor/tustin/psn-php/src/Model.php(69): Tustin\PlayStation\Model-&gt;performFetch()
#3 [...]/vendor/tustin/psn-php/src/Model/Trophy/Trophy.php(153): Tustin\PlayStation\Model-&gt;pluck()
#4 [...]/tasks/importPsn/importPsn.php(1399): Tustin\PlayStation\Model\Trophy\Trophy-&gt;earnedDateTime()
#5 [...]/index.php(118): require('/...')
#6 {main}
  thrown in <b>[...]/vendor/tustin/haste/src/Http/HttpClient.php</b> on line <b>34</b><br />

Previously the missing timestamp wasn't a problem though. Right now I don't know how to avoid this fatal error. No matter what I do in my script, each time I call $trophy->earnedDateTime () I'm in a dead end :(

Any help would be great. Any idea @Ragowit @Tustin ?

Ragowit commented 1 year ago

I guess you could check $trophy->earned() to see if it's true (or 1) before calling earnedDateTime.

Reuns commented 1 year ago

I already do. But still ... Don't you have this issue ? Am I the only one ?

Ragowit commented 1 year ago

And you're sure you are checking on a user's trophy, and not a game's trophy?

Reuns commented 1 year ago

Yes. :) I can get the timestamp for all trophies except for those where the timestamp is (oddly) missing.

Ragowit commented 1 year ago

I don't know then, I don't have that issue. Here's a snippet of code that I'm using.

if ($trophy->earned() || ($trophy->progress() != '' && intval($trophy->progress()) > 0)) {
    if ($trophy->earnedDateTime() === '') {
        $dtAsTextForInsert = null;
    } else {
        // Format time to the way I want it
        $dateTimeObject = DateTime::createFromFormat("Y-m-d\TH:i:s\Z", $trophy->earnedDateTime());
        $dtAsTextForInsert = $dateTimeObject->format("Y-m-d H:i:s");
    }

    // SQL stuff
}
Reuns commented 1 year ago

Thanks for your snippet :) It doesn't work though.

as soon as I tried to access $trophy->earnedDateTime () on a earned trophy without timestamp ... I've got this error.

i'm checking datas and it works well on that

     [cache:Tustin\PlayStation\Model:private] => Array
       (
            [trophyId] => 1
            [trophyHidden] => 
            [earned] => 1
            [earnedDateTime] => 2009-11-12T23:53:31Z
            [trophyType] => gold
            [trophyRare] => 1
            [trophyEarnedRate] => 7.6
        )

But not on that

    [cache:Tustin\PlayStation\Model:private] => Array
        (
            [trophyId] => 3
            [trophyHidden] => 
            [earned] => 1
            [trophyType] => bronze
            [trophyRare] => 3
            [trophyEarnedRate] => 66.4
        )

As it works for all of you, could it be my php version ? 8.1.11 It has always work fine and I didn't change anything on my scripts or phpversion but updated the psn-php via composer.

Ragowit commented 1 year ago

I'm running PHP 8.1.11 myself so that isn't an issue. Dunno what it can be. Revert to the 3.0.0 version and manually edit Client.php with .com instead of .net, does that resolve your issue?

Reuns commented 1 year ago

Wow It works very well on 3.0.0 ! There might has been more changes on 3.0.1 than .net / .com change. It might be important to find out what is it, as I'll may need to make future updates ... (@Tustin ?)

Thanks for your help (once again) @Ragowit !

Tustin commented 1 year ago

@Reuns Thanks for the notice. I'll have a look at this and see what might be causing it. I did make a minor change to the Haste library I used for the HTTP requests but I'm not sure why it would've broken some of the requests.

Tustin commented 1 year ago

Okay so I've discovered the issue. The reason the fatal error Uncaught Error: Call to a member function get() on null is occurring is because I'm not passing an HTTP client to the Trophy model (whether I intentionally did this or not I'm not sure). However, the underlying issue is because the property you are trying to access (earnedDateTime) is missing from the object data that was passed to the Trophy model so the model tries to fetch the trophy data from the API (this can happen because Sony gives different trophy information depending on what endpoint you request).

When I give the Trophy model a valid HTTP client, it turns out the API is failing when I try to access an individual trophy's endpoint. Here's MWII for example: https://m.np.playstation.com/api/trophy/v1/npCommunicationIds/NPWR24223_00/trophyGroups/default/trophies/0?npServiceName=trophy2

I'm not sure if Sony changed this endpoint, or if maybe this is why I never supplied a HTTP client to the Trophy model; I can't remember. I'll do some investigating to see if there is a valid endpoint for getting an individual trophy's data.

Tustin commented 1 year ago

Fixed with ccca89f255d31551036d524591a86d631ba86ba3. If you could please test this with dev-master and let me know if it's working, that would be great 😄 . If it's fine, I'll push a quick release to Packagist. @Reuns. Do note that if you try to read a property for a trophy whose object data hasn't been cached already, it will force a HTTP request for every trophy requested (possibly causing API rate limits)

Reuns commented 1 year ago

There's no more error. Thank you @Tustin !

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.