Some time ago, I wrote about the art of transpiling PHP code:
Transpiling PHP code enables to use the latest PHP features for development, yet release the plugin with its code converted to an older PHP version for production, as to target a bigger user base.
I spent the past few weeks further tuning this process for the Gato GraphQL plugin.
I'm happy to announce that, from now on, it's required PHP version has been upgraded, to PHP 8.0:
Since the plugin can now count on PHP 8.0, I've been able to complete adding a type to all properties for all PHP classes across the code base, now also including union types.
Awesome!
Here is the summary of all the new PHP 8.0 features available when developing the plugin.
When developing Gato GraphQL, the following PHP 8.0 features are now available:
Let's see an example of each, how they are used in the plugin for development, and what they get transpiled down to when generating graphql-api.zip
.
Code example :
interface CustomPostTypeAPIInterface
{
public function createCustomPost ( array $data ): string | int | null | Error ;
}
Copy
Transpiled to:
interface CustomPostTypeAPIInterface
{
public function createCustomPost ( array $data )
}
Copy
Code example :
interface CMSServiceInterface
{
public function getOption ( string $option , mixed $default = false ): mixed ;
}
Copy
Transpiled to:
interface CMSServiceInterface
{
public function getOption ( string $option , $default = false );
}
Copy
Code example :
foreach ( $directiveResolvers as $directiveResolver ) {
$directiveResolverName = $directiveResolver -> getDirectiveName ();
$this -> directiveNameClasses [ $directiveResolverName ][] = $directiveResolver :: class ;
}
Copy
Transpiled to:
foreach ( $directiveResolvers as $directiveResolver ) {
$directiveResolverName = $directiveResolver -> getDirectiveName ();
$this -> directiveNameClasses [ $directiveResolverName ][] = get_class ( $directiveResolver );
}
Copy
Code example :
public function getSchemaFieldType ( TypeResolverInterface $typeResolver , string $fieldName ): ? string
{
$ret = match ( $fieldName ) {
'accessControlLists' => TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID ),
'cacheControlLists' => TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID ),
'fieldDeprecationLists' => TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID ),
'schemaConfigurations' => TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID ),
default => parent :: getSchemaFieldType ( $typeResolver , $fieldName ),
};
return $ret ;
}
Copy
Transpiled to:
public function getSchemaFieldType ( TypeResolverInterface $typeResolver , string $fieldName ): ? string
{
switch ( $fieldName ) {
case 'accessControlLists' :
$ret = TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID );
break ;
case 'cacheControlLists' :
$ret = TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID );
break ;
case 'fieldDeprecationLists' :
$ret = TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID );
break ;
case 'schemaConfigurations' :
$ret = TypeCastingHelpers :: makeArray ( SchemaDefinition :: TYPE_ID );
break ;
default :
$ret = parent :: getSchemaFieldType ( $typeResolver , $fieldName );
break ;
}
return $ret ;
}
Copy
Code example :
try {
// ...
} catch ( InvalidArgumentException ) {
return sprintf (
'<p>%s</p>' ,
\ __ ( 'Oops, the documentation for this module is not available' , 'graphql-api' )
);
}
Copy
Transpiled to:
try {
// ...
} catch ( InvalidArgumentException $exception ) {
return sprintf (
'<p>%s</p>' ,
\ __ ( 'Oops, the documentation for this module is not available' , 'graphql-api' )
);
}
Copy
Code example :
public function getSchemaDirectiveDeprecationDescription ( TypeResolverInterface $typeResolver ): ? string
{
return $this -> getSchemaDefinitionResolver ( $typeResolver )?-> getSchemaDirectiveDeprecationDescription ( $typeResolver );
}
Copy
Transpiled to:
public function getSchemaDirectiveDeprecationDescription ( TypeResolverInterface $typeResolver ): ? string
{
return $this -> getSchemaDefinitionResolver ( $typeResolver ) ? $this -> getSchemaDefinitionResolver ( $typeResolver )-> getSchemaDirectiveDeprecationDescription ( $typeResolver ) : null ;
}
Copy
Code example :
abstract class AbstractEndpointResolver
{
function __construct ( protected EndpointHelpers $endpointHelpers )
{
}
}
Copy
Transpiled to:
abstract class AbstractEndpointResolver
{
/**
* @var \GraphQLAPI\GraphQLAPI\Services\Helpers\ EndpointHelpers
*/
protected $endpointHelpers ;
function __construct ( EndpointHelpers $endpointHelpers )
{
$this -> endpointHelpers = $endpointHelpers ;
}
}
Copy
Code example :
public function resolveFieldTypeResolverClass ( TypeResolverInterface $typeResolver , string $fieldName ): ? string
{
switch ( $fieldName ) {
case 'accessControlLists' :
return CustomPostTypeResolver :: class ;
}
return parent :: resolveFieldTypeResolverClass (
$typeResolver ,
$fieldName ,
);
}
Copy
Transpiled to:
public function resolveFieldTypeResolverClass ( TypeResolverInterface $typeResolver , string $fieldName ): ? string
{
switch ( $fieldName ) {
case 'accessControlLists' :
return CustomPostTypeResolver :: class ;
}
return parent :: resolveFieldTypeResolverClass ( $typeResolver , $fieldName );
}
Copy