Tustin / psn-php

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

Offset in user trophytitles? #212

Closed Ragowit closed 2 years ago

Ragowit commented 2 years ago

I'm currently in the need of using an offset when grabbing a users trophytitles. The TrophyTitlesIterator seems to have this implemented but I can't figure out how to use it.

https://github.com/Tustin/psn-php/blob/54444ce0cd8833355801ab95f97e4b4dbab2a027/src/Iterator/TrophyTitlesIterator.php#L26-L36

Have been trying different things, but they all start with the first one on the list and not my offset.

$user = $client->users()->find($accountId);
$offset = 10;
$trophyTitles = $user->trophyTitles();
$trophyTitles->getIterator()->access($offset);
foreach ($trophyTitles as $trophyTitle) {
    // Doesn't work
}
foreach ($trophyTitles->getIterator() as $trophyTitle) {
    // Doesn't work
}
$iterator = $trophyTitles->getIterator();
$iterator->access($offset);
foreach ($iterator as $trophyTitle) {
    // Doesn't work
}
gabetavares commented 2 years ago

Use getCache() or just iterate normal over it:

foreach ($trophyTitles as $trophyTitle) {
    var_dump($trophyTitle->getCache());
}

Remember when using Iterator you must also use its methods, take a look at AbstractApiIterator.php for the built-in methods:

while($trophyTitles->valid()) {
    var_dump($trophyTitles->current()->getCache());
    $trophyTitles->next();
}

But well step-by-step;

$trophyTitles = $user->trophyTitles(); // Get the instance
$trophyTitles = $trophyTitles->getIterator(); // Get the iterator with the cached results

$trophyTitles->access(10); // Append new enties to cache at the end of current cached results
$trophyTitles = $trophyTitles->access(10); // Return null

It means your offset results starts at cache[100].

In the middle of access() you notice the update() with:

$this->cache = array_merge($this->cache, $items);

To get the offset from the current call, you must override the access(0) to access($offset) somehow. (Using the access method as you're trying to).


The cursor from offset does not seem to be a literal integer.

The current docs say:

/**
 * Access a specific cursor in the API.
 *
 * @param mixed $cursor
 * @return void
 */
public abstract function access($cursor): void;

Note the @param mixed $cursor means that cursor does not necessarily mean an integer as offset, and 0 does not mean the position 0.

Also note you cannot Iterate over access since the return is :void. (I've seen you tried to update through the access, just pointing it to make sure)

For example:

I'm not entirely sure about this, barely remember of using this one, when I did was on users->getIterator() and offsets does not seem to work properly as intended, at some point data start getting duplicated and confused.

I did a lot of edits because I was debugging while writing it.

Ragowit commented 2 years ago

Woa, thanks for this answer!

The reason I asked was because my script timed out for one particular user. And only that user. So I thought I could "continue" where I timed out by using an offset. However, it might just have been a temporarily problem because I have since succeeded in scanning the full library of the user and thus no longer in need to find an alternate way with using offset.

But thanks for the answer, if I need to delve deeper into this again sometime!