Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation error on CollectionPage #31

Open
Crell opened this issue Jan 23, 2023 · 4 comments
Open

Validation error on CollectionPage #31

Crell opened this issue Jan 23, 2023 · 4 comments
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@Crell
Copy link

Crell commented Jan 23, 2023

I am trying to build out Mastodon support for an application, and running into a validation error I cannot explain.

Here's the code:

$server new Server([
    'ontologies' => [
        // I'm building out the ontology class based on the error messages I get.
        'mastodon' => MastodonOntology::class,
    ]
]);

// This works (after I create an extended Person and a PropertyValue)
$actor = $this->server->actor('[email protected]');

$outbox = $this->server->outbox('[email protected]');

$pages = [];

// This fails.
$page = $outbox->getPage($outbox->get()->first);

Specifically, the error comes from Util::hasProperties(), which is called with an array for $item instead of an object. (The method really needs better native types.) That makes the property_exists() call fail with a type error. After some debugging, I have determined it's being called with this array:

[
  'type' => 'CollectionPage',
  'next' => 'https://phpc.social/users/Crell/statuses/...',
  'partOf' => 'https://phpc.social/users/Crell/statuses/...',
  'items' => [],
]

Which... doesn't make sense, as CollectionPage is a built-in supported type, so I have no idea how it's still an array at that point.

I've hit a wall on debugging at this point. Any help on what's going on? There's like 10 stack layers between my code and where the error is, and I have on idea where the issue is.

(I'm quite open to submitting the Mastodon ontology as a PR once I have it working, if there would be interest.)

@landrok
Copy link
Owner

landrok commented Jan 23, 2023

Hello Crell,

As far as I can see, there are 2 points:

  • I need to have a look at your MastodonOntology::class definitions for a deeper analysis

  • If you need some flexibility for debugging, you can disable "strict" ActivityPub typing with the following Server configurations:

// Create a server instance that never fails (useful to discover new attributes or types)
$server = new Server([
    // Creates AbstractObject when a type is not locally defined
    'instance'   => [
        'types' => 'include'
    ],
]);

$handle = '[email protected]';

$outbox = $server->outbox($handle);
$pages = [];
$page = $outbox->getPage($outbox->get()->first);

// $page is an object with a toArray() method
// print_r($page->toArray());

$pages[] = $page;
while ($page->next !== null) {
    $page = $outbox->getPage($page->next);
    $pages[] = $page;
}



// Now we can work with pages
foreach ($pages as $page) {
    foreach ($page->orderedItems as $item) {
        // Do something here
    }
}

If you want to have informations about the types server parameters: https://landrok.github.io/activitypub/activitypub-server-usage.html

And 3rd point, it would be very interesting for the community to have a MastodonOntology, so if you need, we can work on a PR.

Hope this helps

@landrok landrok self-assigned this Jan 23, 2023
@landrok landrok added enhancement New feature or request question Further information is requested labels Jan 23, 2023
@Crell
Copy link
Author

Crell commented Jan 23, 2023

Here's what I've got for the Ontology so far. Note that the docs seem a bit inconsistent about whether it's preferred to make a class or just define arrays, so since I'm a fan of classes and types I'm making a class and then deriving the arrays off of them. (The Ontology class is generic so it would work for anything, making it a good candidate for a utility of its own.) This is mainly reverse-engineered from the error messages, and most of the types are me making educated guesses since the Mastodon docs don't have a type in many cases.

use ActivityPhp\Type\OntologyInterface;

class MastodonOntology implements OntologyInterface
{
    public static function getDefinition(): array
    {
        $types = [Person::class, PropertyValue::class, Note::class, Hashtag::class];

        $ret = [];
        foreach ($types as $type) {
            $rClass = new \ReflectionClass($type);
            $ret[$rClass->getShortName()] = self::getFields($rClass);
        }
        return $ret;
    }

    private static function getFields(\ReflectionClass $rClass): array
    {
        $props = $rClass->getProperties();

        return array_map(static fn (\ReflectionProperty $p) => $p->getName(), $props);
    }
}
use ActivityPhp\Type\Extended\Actor\Person as BasePerson;

class Person extends BasePerson
{
    protected string $featured;
    protected string $featuredTags;
    protected bool $manuallyApprovesFollowers;
    protected bool $discoverable;
    protected array $devices;
}
use ActivityPhp\Type\Extended\Object\Note as BaseNote;

class Note extends BaseNote
{
    protected bool $sensitive;
    protected string $atomUri;
    protected string $inReplyToAtomUri;
    // Not sure what this is.
    protected $conversation;
}
use ActivityPhp\Type;

class Hashtag extends Type
{
    protected string $href;
}
use ActivityPhp\Type;

// I think this is for a single record within the extra properties collection; it's where in the Mastodon UI you put the "your website" links, etc.

class PropertyValue extends Type
{
    protected string $value;
}

@Crell
Copy link
Author

Crell commented Jan 23, 2023

Enabling types => include does allow the process to finish and run to completion, and appears to work(!). I'd still rather have a properly defined ontology, though, so I know what the API even is. 😄

Also, is there a reason there are no @property declarations on the type classes? Since the properties are protected trying to access them directly is going to generate errors in static analyzers (like my IDE), even if they technically work.

@Crell
Copy link
Author

Crell commented Jan 28, 2023

Any further thoughts here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants