Un composant de base pour intégrer Sencha Ext JS Ext.direct dans une application PHP
Cette bibliothèque fournit une implémentation côté serveur pour Sencha Ext.direct, un composant de communication de style RPC qui fait partie de Ext JS et Sencha Touch de Sencha.
ext direct est un protocole d'appel de procédure à distance (RPC) indépendant de la plate-forme et du langage. ext direct permet une communication transparente entre le côté client d'une application Ext JS et toute plate-forme serveur conforme à la spécification. ext direct est sans état et léger, prenant en charge des fonctionnalités telles que la découverte d'API, le traitement par lots d'appels et les événements serveur-client.
Actuellement, cette bibliothèque n'est utilisée que comme base de teqneers/ext-direct-bundle, un bundle Symfony qui intègre * Ext.direct* dans une application basée sur Symfony. Nous n'avons pas essayé d'utiliser la bibliothèque en tant que composant autonome ou dans tout autre contexte qu'un environnement Symfony, donc ce qui suit indique uniquement comment elle devrait fonctionner théoriquement sans le bundle. Nous apprécierions toute aide et contribution pour rendre la bibliothèque plus utile en dehors du bundle.
Vous pouvez installer cette bibliothèque en utilisant composer
composer require teqneers/ext-direct
ou ajoutez le package directement à votre fichier composer.json.
La stratégie de dénomination détermine la manière dont les noms de classe et les espaces de noms PHP sont traduits en noms d'action Ext.direct compatibles Javascript. La stratégie de dénomination par défaut traduit le séparateur namspapce en un . . Ainsi, MyNamespaceService est traduit en My.namespace.Service . Attention, la transformation doit être réversible ( My.namespace.Service => MyNamespaceService ).
$ namingStrategy = new TQ ExtDirect Service DefaultNamingStrategy (); Le registre de services utilise une fabrique de métadonnées de la bibliothèque jms/metadata et un pilote d'annotation associé (qui à son tour utilise un lecteur d'annotations doctrine/annotations ) pour lire les métainformations sur les classes de service annotées possibles.
$ serviceRegistry = new TQ ExtDirect Service DefaultServiceRegistry (
new Metadata MetadataFactory (
new TQ ExtDirect Metadata Driver AnnotationDriver (
new Doctrine Common Annotations AnnotationReader ()
)
),
$ namingStrategy
); Le registre des services peut être rempli manuellement en appelant addServices() ou addService() ou en important des services à l'aide d'un TQExtDirectServiceServiceLoader . L'implémentation par défaut TQExtDirectServicePathServiceLoader peut lire des classes à partir d'un ensemble de chemins donnés.
Le répartiteur d'événements est facultatif mais est requis pour utiliser des fonctionnalités telles que la conversion et la validation des arguments, la conversion des résultats de l'écouteur de profilage.
$ eventDispatcher = new Symfony Component EventDispatcher EventDispatcher (); Le routeur est utilisé pour traduire les requêtes Ext.direct entrantes en appels de méthode PHP vers la classe de service appropriée. ContainerServiceFactory prend en charge la récupération de services à partir d'un conteneur d'injection de dépendance Symfony ou l'instanciation de services simples qui ne prennent aucun argument de constructeur. Les appels de service statiques contournent l’usine de service.
$ router = new TQ ExtDirect Router Router (
new TQ ExtDirect Router ServiceResolver (
$ serviceRegistry ,
new TQ ExtDirect Service ContainerServiceFactory (
/* a SymfonyComponentDependencyInjectionContainerInterface */
)
),
$ eventDispatcher
); L'objet point de terminaison est une façade devant tous les composants côté serveur Ext.direct . Avec sa méthode createServiceDescription() , on peut obtenir une description d'API conforme aux normes tandis que handleRequest() prend un SymfonyComponentHttpFoundationRequest et renvoie un SymfonyComponentHttpFoundationResponse qui contient la réponse Ext.direct pour les appels de service. reçu.
$ endpoint = TQ ExtDirect Service Endpoint (
' default ' , // endpoint id
new TQ ExtDirect Description ServiceDescriptionFactory (
$ serviceRegistry ,
' My.api ' ,
$ router ,
new TQ ExtDirect Router RequestFactory (),
' My.api.REMOTING_API '
)
);Le gestionnaire de points de terminaison n'est qu'une simple collection de points de terminaison qui permettent la récupération à l'aide de l'identifiant du point de terminaison. Cela permet une exposition facile de plusieurs API indépendantes.
$ manager = new TQ ExtDirect Service EndpointManager ();
$ manager -> addEndpoint ( $ endpoint );
$ defaultEndpoint = $ manager -> getEndpoint ( ' default ' );
$ apiResponse = $ defaultEndpoint -> createServiceDescription ( ' /path/to/router ' );
$ apiResponse -> send ();
$ request = Symfony Component HttpFoundation Request:: createFromGlobals ();
$ response = $ defaultEndpoint -> handleRequest ( $ request );
$ response -> send ();Le processus de routage peut être manipulé et augmenté en utilisant des écouteurs d'événements sur le répartiteur d'événements transmis au routeur. La bibliothèque propose quatre abonnés aux événements qui permettent
Les convertisseurs d'arguments et de résultats fournis utilisent la bibliothèque jms/serializer pour fournir des capacités de (dés)sérialisation étendues, tandis que le validateur d'arguments par défaut utilise la bibliothèque symfony/validator .
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ArgumentConversionListener (
new TQ ExtDirect Router ArgumentConverter ( /* a JMSSerializerSerializer */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ArgumentValidationListener (
new TQ ExtDirect Router ArgumentValidator ( /* a SymfonyComponentValidatorValidatorValidatorInterface */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener ResultConversionListener (
new TQ ExtDirect Router ResultConverter ( /* a JMSSerializerSerializer */ )
)
);
$ eventDispatcher -> addSubscriber (
new TQ ExtDirect Router EventListener StopwatchListener (
/* a SymfonyComponentStopwatchStopwatch */
)
);Les services à exposer via l'API Ext.direct doivent être décorés avec des méta-informations appropriées. Actuellement, cela n'est possible qu'en utilisant des annotations (comme celles connues de Doctrine, Symfony ou d'autres bibliothèques PHP modernes).
Chaque classe de service qui sera exposée en tant qu'action Ext.direct doit être annotée avec TQExtDirectAnnotationAction . L'annotation Action prend éventuellement un paramètre d'identifiant de service pour les services qui ne sont ni statiques ni pouvant être instanciés avec un constructeur sans paramètre.
use TQ ExtDirect Annotation as Direct ;
/**
* @DirectAction()
*/
class Service1
{
// service will be instantiated using the parameter-less constructor if called method is not static
}
/**
* @DirectAction("app.direct.service2")
*/
class Service2
{
// service will be retrieved from the dependency injection container using id "app.direct.service2" if called method is not static
} De plus, chaque méthode qui sera exposée lors d'une action Ext.direct doit être annotée avec TQExtDirectAnnotationMethod . L'annotation Method prend éventuellement soit true pour désigner la méthode comme étant un gestionnaire de formulaire (en prenant des publications de formulaire normales), soit false pour désigner la méthode comme étant une méthode Ext.direct normale (c'est la valeur par défaut).
/**
* @DirectAction("app.direct.service3")
*/
class Service3
{
/**
* @DirectMethod()
*/
public function methodA ()
{
// regular method
}
/**
* @DirectMethod(true)
*/
public function methodB ()
{
// form handler method
}
}Les fonctionnalités étendues telles que les paramètres nommés et les paramètres nommés stricts décrits dans la spécification Ext.direct ne sont actuellement pas exposées via le système d'annotation.
Les paramètres qui entrent dans une méthode appelée via une requête Ext.direct peuvent également être annotés pour appliquer la validation des paramètres. Cela nécessite que TQExtDirectRouterEventListenerArgumentValidationListener soit enregistré auprès du répartiteur d'événements approprié.
use Symfony Component Validator Constraints as Assert ;
/**
* @DirectAction("app.direct.service4")
*/
class Service4
{
/**
* @DirectMethod()
* @DirectParameter("a", { @AssertNotNull(), @AssertType("int") })
*
* @param int $a
*/
public function methodA ( $ a )
{
}
} Si la signature de la méthode appelée expose des paramètres avec un indice de type pour SymfonyComponentHttpFoundationRequest et/ou TQExtDirectRouterRequest , la requête HTTP Symfony entrante et/ou le Ext.direct brut Les requêtes sont injectées automatiquement dans l’appel de méthode. Ceci est particulièrement important pour les méthodes de gestion des formulaires car il n’existe aucun autre moyen d’accéder aux paramètres de la requête HTTP entrante (publication du formulaire).
Dès que TQExtDirectRouterEventListenerArgumentConversionListener est activé, on peut utiliser des paramètres d'objet strictement typés sur les méthodes de service. Ces arguments seront automatiquement désérialisés de la requête JSON entrante et seront injectés dans l'appel de méthode.
Il en va de même pour le renvoi d'objets à partir d'un appel de méthode de service. Si TQExtDirectRouterEventListenerResultConversionListener est activé, les valeurs de retour sont automatiquement sérialisées en JSON même s'il s'agit d'objets non triviaux.
L'argument ainsi que la conversion de la valeur de retour sont basés sur l'excellente bibliothèque jms/serializer de Johannes Schmitt. Consultez la documentation pour plus d'informations.
La spécification ext direct peut être trouvée sur le site Web de documentation de Sencha.
La licence MIT (MIT)
Copyright (c) 2015 TEQneers GmbH & Co. KG
L'autorisation est accordée par la présente, gratuitement, à toute personne obtenant une copie de ce logiciel et des fichiers de documentation associés (le « Logiciel »), d'utiliser le Logiciel sans restriction, y compris, sans limitation, les droits d'utilisation, de copie, de modification, de fusion. , publier, distribuer, accorder des sous-licences et/ou vendre des copies du Logiciel, et permettre aux personnes à qui le Logiciel est fourni de le faire, sous réserve des conditions suivantes :
L'avis de droit d'auteur ci-dessus et cet avis d'autorisation doivent être inclus dans toutes les copies ou parties substantielles du logiciel.
LE LOGICIEL EST FOURNI « TEL QUEL », SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS MAIS SANS LIMITATION LES GARANTIES DE QUALITÉ MARCHANDE, D'ADAPTATION À UN USAGE PARTICULIER ET DE NON-VIOLATION. EN AUCUN CAS LES AUTEURS OU LES TITULAIRES DES DROITS D'AUTEUR NE SERONT RESPONSABLES DE TOUTE RÉCLAMATION, DOMMAGES OU AUTRE RESPONSABILITÉ, QUE CE SOIT DANS UNE ACTION CONTRACTUELLE, DÉLIT OU AUTRE, DÉCOULANT DE, DE OU EN RELATION AVEC LE LOGICIEL OU L'UTILISATION OU D'AUTRES TRANSACTIONS DANS LE LOGICIEL.