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

Using phpdoc as language expression #478

Open
sylfabre opened this issue Apr 8, 2019 · 8 comments
Open

Using phpdoc as language expression #478

sylfabre opened this issue Apr 8, 2019 · 8 comments

Comments

@sylfabre
Copy link
Contributor

sylfabre commented Apr 8, 2019

At AssoConnect, we use the PHPDoc content (class, method and property) as description for GraphQL as we do not want to duplicate code/content.

We have developed a custom language expression @phpdoc(SomeClass::$someProperty).

Would you like a PR for this?

@Vincz
Copy link
Collaborator

Vincz commented Apr 24, 2019

Hi @sylfabre,
I don't really understand what you mean. Could you add more examples ?

@sylfabre
Copy link
Contributor Author

Hi @Vincz
We use it for description mostly.

For instance with https://github.com/overblog/GraphQLBundle/blob/master/docs/definitions/type-system/object.md as an example:

  • you probably need to describe the method character_friends with The friends of the character.
  • you don't want to duplicate this description
    => we use description: @phpdoc('SomeClass::character_friends()') instead of description: "The friends of the character."

@murtukov
Copy link
Member

@Vincz I think he means something like this:

Query:
    type: object
    config:
        fields:
            author:
                type: "Author"
                description: '@=phpdoc("App\\Entity\\Author")'
                args:
                    id:
                        description: '@=phpdoc("App\\Entity\\Author::$id")'
                        type: "Int"
                     name:
                        description: '@=phpdoc("App\\Entity\\Author::getName()")'
                        type: "String"
                resolve: "@=resolver('Author', [args, info])"

@sylfabre If so I find it ok.

@sylfabre
Copy link
Contributor Author

@murtukov you're right

@mcg-web
Copy link
Member

mcg-web commented Jul 19, 2019

@sylfabre what behind phpdoc expression function? Is the parsing done on runtime or on Symfony container compile time?

@sylfabre
Copy link
Contributor Author

sylfabre commented Jul 19, 2019

@mcg-web this is the code

<?php

namespace App\GraphQL\ExpressionLanguage;

use Overblog\GraphQLBundle\ExpressionLanguage\ExpressionFunction;

class PhpDoc extends ExpressionFunction
{
    public function __construct()
    {
        parent::__construct(
            'phpdoc',
            function ($string) {
                // Removing backslashes and double-quotes
                // App\\Entity\\AccountingBankReconciliation::\$id => App\Entity\AccountingBankReconciliation::$id
                $string = substr(stripcslashes($string), 1, -1);

                // Property comment
                if (preg_match('/^[a-zA-Z0-9\\\\]+::\$[a-zA-Z0-9]+$/', $string)) {
                    list($class, $name) = explode('::$', $string);
                    $reflection = new \ReflectionProperty($class, $name);
                } elseif (preg_match('/^[a-zA-Z0-9\\\\]+::[A-Z0-9_]+$/', $string)) {
                    // Constant comment
                    list($class, $name) = explode('::', $string);
                    $reflection = new \ReflectionClassConstant($class, $name);
                } elseif (preg_match('/^[a-zA-Z0-9\\\\]+::[a-zA-Z0-9]+\(\)$/', $string)) {
                    // Method comment
                    list($class, $name) = explode('::', $string);
                    $reflection = new \ReflectionMethod($class, substr($name, 0, -2));
                } else {
                    // Class comment
                    $reflection = new \ReflectionClass($string);
                }

                $phpdoc = $reflection->getDocComment();

                // First line
                $line = explode("\n", $phpdoc)[1];
                // Removing spaces prefix
                $line = trim($line);
                // Removing '* '
                $line = mb_substr($line, 2);

                return '\'' . $line . '\'';
            }
        );
    }
}

The parsing is done on Symfony container compile time

@murtukov
Copy link
Member

murtukov commented Jul 19, 2019

@sylfabre So eventually it dublicates the code, it just happens behind the scenes.
For example, if I have a description on my User::method(), then I do graphql:compile then i change the description on User::method(). I will have 2 different discriptions, because I didn't call graphql:compile after changing the description on my method. It can lead to a confusion, if users forget to call graphql:compile, there won't be a single source of truth anymore.

Basically it doesn't prevent the dublication of code, it just automates it.

@sylfabre
Copy link
Contributor Author

@murtukov you don't have to write it two times in your code: that's why it is no longer duplicated.

And yes eventually it's duplicated in the cache like the YAML config files are rewritten in PHP in the cache too.

Your point about confusion is valid: the cache should be invalidated when a description is changed (like what happens when you update a YAML config file)

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

No branches or pull requests

4 participants