Базовый компонент для интеграции Sencha Ext JS Ext.direct в приложение PHP.
Эта библиотека предоставляет серверную реализацию Sencha Ext.direct — коммуникационного компонента в стиле RPC, который является частью Sencha Ext JS и Sencha Touch .
ext direct — это протокол удаленного вызова процедур (RPC), не зависящий от платформы и языка. ext direct обеспечивает беспрепятственную связь между клиентской частью приложения Ext JS и любой серверной платформой, соответствующей спецификации. ext direct не сохраняет состояние и является легким, поддерживая такие функции, как обнаружение API, пакетную обработку вызовов и события между сервером и клиентом.
В настоящее время эта библиотека используется только как основа teqneers/ext-direct-bundle, пакета Symfony, который интегрирует * Ext.direct* в приложение на базе Symfony. Мы не пытались использовать библиотеку как отдельный компонент или в каком-либо другом контексте, кроме среды Symfony, поэтому ниже описано только то, как она должна работать теоретически без пакета. Мы будем признательны за любую помощь и вклад, чтобы сделать библиотеку более полезной за пределами пакета.
Вы можете установить эту библиотеку с помощью композитора
composer require teqneers/ext-direct
или добавьте пакет напрямую в файл композитора.json.
Стратегия именования определяет, как имена классов и пространств имен PHP преобразуются в имена действий Ext.direct , совместимые с Javascript. Стратегия именования по умолчанию преобразует разделитель namspapce в
.
. Таким образом, MyNamespaceService
преобразуется в My.namespace.Service
. Обратите внимание, что преобразование должно быть обратимым ( My.namespace.Service
=> MyNamespaceService
).
$ namingStrategy = new TQ ExtDirect Service DefaultNamingStrategy ();
Реестр служб использует фабрику метаданных из библиотеки jms/metadata
и связанный драйвер аннотаций (который, в свою очередь, использует средство чтения аннотаций doctrine/annotations
) для чтения метаинформации о возможных аннотированных классах служб.
$ serviceRegistry = new TQ ExtDirect Service DefaultServiceRegistry (
new Metadata MetadataFactory (
new TQ ExtDirect Metadata Driver AnnotationDriver (
new Doctrine Common Annotations AnnotationReader ()
)
),
$ namingStrategy
);
Реестр служб можно заполнить вручную, вызвав addServices()
или addService()
, или импортировав службы с помощью TQExtDirectServiceServiceLoader
. Реализация по умолчанию TQExtDirectServicePathServiceLoader
может читать классы из набора заданных путей.
Диспетчер событий не является обязательным, но он необходим для использования таких функций, как преобразование и проверка аргументов, преобразование результатов прослушивателя профилирования.
$ eventDispatcher = new Symfony Component EventDispatcher EventDispatcher ();
Маршрутизатор используется для преобразования входящих запросов Ext.direct в вызовы методов PHP для правильного класса обслуживания. ContainerServiceFactory
поддерживает извлечение сервисов из контейнера внедрения зависимостей Symfony или создание экземпляров простых сервисов, которые вообще не принимают аргументов конструктора. Статические вызовы служб обходят фабрику служб.
$ router = new TQ ExtDirect Router Router (
new TQ ExtDirect Router ServiceResolver (
$ serviceRegistry ,
new TQ ExtDirect Service ContainerServiceFactory (
/* a SymfonyComponentDependencyInjectionContainerInterface */
)
),
$ eventDispatcher
);
Объект конечной точки — это фасад перед всеми серверными компонентами Ext.direct . С помощью метода createServiceDescription()
можно получить соответствующее стандарту описание API, в то время как handleRequest()
принимает SymfonyComponentHttpFoundationRequest
и возвращает SymfonyComponentHttpFoundationResponse
, который содержит ответ Ext.direct для вызовов службы. полученный.
$ 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 '
)
);
Менеджер конечных точек — это просто набор конечных точек, которые позволяют извлекать данные по идентификатору конечной точки. Это позволяет легко использовать несколько независимых API.
$ 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 ();
Процессом маршрутизации можно управлять и дополнять его с помощью прослушивателей событий в диспетчере событий, передаваемом в маршрутизатор. Библиотека предоставляет четыре подписчика событий, которые позволяют
Поставляемые преобразователи аргументов и результатов используют библиотеку jms/serializer
для предоставления расширенных возможностей (де-)сериализации, тогда как валидатор аргументов по умолчанию использует библиотеку 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 */
)
);
Службы, которые будут предоставляться через API Ext.direct , должны быть украшены соответствующей метаинформацией. В настоящее время это возможно только с использованием аннотаций (например, известных из Doctrine, Symfony или других современных библиотек PHP).
Каждый класс обслуживания, который будет представлен как действие Ext.direct, должен быть помечен TQExtDirectAnnotationAction
. Аннотация Action
дополнительно принимает параметр идентификатора службы для служб, которые не являются статическими и не могут быть созданы с помощью конструктора без параметров.
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
}
Кроме того, каждый метод, который будет представлен в действии Ext.direct, должен быть помечен TQExtDirectAnnotationMethod
. Аннотация Method
опционально принимает значение true
, чтобы обозначить метод как обработчик формы (принимающий обычные сообщения формы), или false
, чтобы обозначить метод как обычный метод Ext.direct (это значение по умолчанию).
/**
* @DirectAction("app.direct.service3")
*/
class Service3
{
/**
* @DirectMethod()
*/
public function methodA ()
{
// regular method
}
/**
* @DirectMethod(true)
*/
public function methodB ()
{
// form handler method
}
}
Расширенные функции, такие как именованные параметры и строго именованные параметры, описанные в спецификации Ext.direct, в настоящее время не доступны через систему аннотаций.
Параметры, которые входят в метод, вызываемый через запрос Ext.direct, также могут быть аннотированы для применения проверки параметров. Для этого необходимо, чтобы TQExtDirectRouterEventListenerArgumentValidationListener
был зарегистрирован в соответствующем диспетчере событий.
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 )
{
}
}
Если сигнатура вызываемого метода предоставляет параметр(ы) с подсказкой типа для SymfonyComponentHttpFoundationRequest
и/или TQExtDirectRouterRequest
, входящий HTTP-запрос Symfony и/или необработанный Ext.direct request автоматически вводятся в вызов метода. Это особенно важно для методов обработки форм, поскольку другого способа доступа к параметрам входящего HTTP-запроса (сообщения формы) не существует.
Как только TQExtDirectRouterEventListenerArgumentConversionListener
включен, можно использовать строго типизированные параметры объекта в методах службы. Эти аргументы будут автоматически десериализованы из входящего запроса JSON и вставлены в вызов метода.
То же самое справедливо и для возврата объектов из вызова метода службы. Если TQExtDirectRouterEventListenerResultConversionListener
включен, возвращаемые значения автоматически сериализуются в JSON, даже если они являются нетривиальными объектами.
Как аргумент, так и преобразование возвращаемого значения основаны на превосходной библиотеке jms/serializer
Йоханнеса Шмитта. Дополнительную информацию смотрите в документации.
Спецификацию ext direct можно найти на веб-сайте документации Sencha.
Лицензия MIT (MIT)
Авторские права (c) 2015 TEQneers GmbH & Co. KG
Настоящим бесплатно любому лицу, получившему копию этого программного обеспечения и связанных с ним файлов документации («Программное обеспечение»), предоставляется разрешение на работу с Программным обеспечением без ограничений, включая, помимо прочего, права на использование, копирование, изменение, объединение. публиковать, распространять, сублицензировать и/или продавать копии Программного обеспечения, а также разрешать лицам, которым предоставлено Программное обеспечение, делать это при соблюдении следующих условий:
Вышеупомянутое уведомление об авторских правах и данное уведомление о разрешении должны быть включены во все копии или существенные части Программного обеспечения.
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЯМИ ТОВАРНОЙ ЦЕННОСТИ, ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ АВТОРЫ ИЛИ ОБЛАДАТЕЛИ АВТОРСКИХ ПРАВ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УБЫТКИ ИЛИ ДРУГУЮ ОТВЕТСТВЕННОСТЬ, БУДЬ В ДЕЙСТВИЯХ ПО КОНТРАКТУ, ПРАВОНАРУШЕНИЮ ИЛИ ДРУГИМ ОБРАЗОМ, ВОЗНИКАЮЩИЕ ОТ, ИЗ ИЛИ В СВЯЗИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ИЛИ ДРУГИМИ СДЕЛКАМИ, ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ.