dev-master
9999999-devGUI & serializer for Doctrine ORM QueryBuilder
MIT
The Requires
- php ^7.0
- doctrine/orm ^2.5
doctrine
v0.0.1
0.0.1.0GUI & serializer for Doctrine ORM QueryBuilder
MIT
The Requires
- php ^7.0
- doctrine/orm ^2.5
doctrine
Wallogit.com
2017 © Pedro Peláez
GUI & serializer for Doctrine ORM QueryBuilder
Набор инструментов по созданию экземпляра Doctrine QueryBuilder через графический интерфейс с возможностью его сериализации/десериализации., (*1)
Входят следующие инструменты:, (*2)
Symfony 2.8+, (*3)
# app/AppKernel.php
class AppKernel extends Kernel
{
public function registerBundles()
{
$bundles = [
...
new FOD\QueryConstructor\Bundle\QueryConstructorBundle(),
];
...
}
...
}
# app/config/routing.yml
...
fod_query_constructor:
resource: "@QueryConstructorBundle/Controller/DefaultController.php"
type: annotation
prefix: /fod
В папке /assets пакета содержатся готовые скомпилированные js-файлы., (*4)
/web/assets/js)cd web/assets/js ln -sfn ../../../vendor/friendsofdoctrine/query-constructor/assets query-constructor
{{ fod_query_constructor()|raw }}
функция fod_query_constructor, (*5)
Передать опцию scriptPath со ссылкой на js-файл, который будет использован вместо пути по умолчанию /web/assets/js, (*6)
{{ fod_query_constructor({'scriptPath' : '/path/to/myfile.js'})|raw }}
Передать опцию htmlId со строковым значением, которое будет использовано вместо id по умолчанию fod-query-constructor, (*7)
{{ fod_query_constructor({'htmlId' : 'custom-constructor-id'})|raw }}
Передать опцию prefix со строковым значением, которое будет использовано в качестве префикса к элементам формы, (*8)
{{ fod_query_constructor({'prefix' : 'form[query]'})|raw }}
В результате атрибут name элемента input получит значение form[query][entity] вместо entity, (*9)
Все настройки выполняются через аннотации классов и свойств., (*10)
Что сделать, (*11)
Указать аннотацию класса QC\Entity., (*12)
Результат, (*13)
ORM\Column.ORM\ManyToOne, становятся фильтрами со списками выбора (можно выбрать несколько значений)Пример, (*14)
В конструктор должна попасть сущность Room с фильтрами Id (integer), Name (string) и Building (список выбора), (*15)
<?php
// ...
use Doctrine\ORM\Mapping as ORM;
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity()
*/
class Room
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Building", inversedBy="rooms")
*/
protected $building;
}
Что сделать, (*16)
Добавить опцию title аннотации класса QC\Entity., (*17)
Результат, (*18)
Сущность будет назваться, как указано в title. Если опция не задана, используется название свойства в классе., (*19)
Пример, (*20)
Сущность Room должна иметь подпись Помещение, (*21)
<?php
// ...
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(title="Помещение")
*/
class Room
{
// ...
}
Что сделать, (*22)
Добавить аннотацию свойства QC\Property с опцией title., (*23)
Результат, (*24)
Свойство будет назваться, как указано в title. Если опция не задана, используется название класса., (*25)
Пример, (*26)
Фильтр Building должен иметь подпись Здание, (*27)
<?php
// ...
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(title="Помещение")
*/
class Room
{
// ...
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Building", inversedBy="rooms")
* @QC\Property(title="Здание")
*/
protected $building;
}
Что сделать, (*28)
Добавить опцию titleField в аннотацию свойства QC\Property с указанием названия свойства связанной сущности, откуда будут взяты значения подписей., (*29)
Результат, (*30)
Подписи элементов списка будут взяты из указанного свойства связанной сущности. Если опция titleField не задана, подписи берутся из первого поля типа string. Если в сущности такого поля нет и опция не задана явно, выбрасывается исключение., (*31)
Пример, (*32)
Вывести подписи из поля Building.address, (*33)
<?php
// ...
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(title="Помещение")
*/
class Room
{
// ...
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Building", inversedBy="rooms")
* @QC\Property(title="Здание", titleField="address")
*/
protected $building;
}
Что сделать, (*34)
Добавить опцию aggregatable_fields в аннотацию класса QC\Entity с указанием названий свойств, к которым применять аггрегирующие функции. Можно задавать как массив, так и строку (если одно поле)., (*35)
Результат, (*36)
В списке аггрегации будут присутствовать только указанные свойства. Если не задана, присутствует только первичный ключ, (*37)
Пример, (*38)
В список аггрегации должны попасть Id и Name, (*39)
<?php
// ...
use Doctrine\ORM\Mapping as ORM;
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(aggregatable_fields={"id", "name"})
*/
class Room
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Building", inversedBy="rooms")
*/
protected $building;
}
Что сделать, (*40)
Добавить опцию filterable_fields в аннотацию класса QC\Entity с указанием названий свойств, по которым можно фильтровать. Можно задавать как массив, так и строку (если одно поле)., (*41)
Результат, (*42)
В списках фильтров будут присутствовать только указанные свойства. Если опция не задана, присутствуют все свойства., (*43)
Пример, (*44)
В список фильтрации должен попасть только Name, (*45)
<?php
// ...
use Doctrine\ORM\Mapping as ORM;
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(filterable_fields="name")
*/
class Room
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Building", inversedBy="rooms")
*/
protected $building;
}
Что сделать, (*46)
Добавить опцию filterable_fields_except в аннотацию класса QC\Entity с указанием названий свойств, которые исключить из фильтрации. Можно задавать как массив, так и строку (если одно поле)., (*47)
Результат, (*48)
В списках фильтров указанные свойства будут отсутствовать. Если опция применяется совместно с filterable_fields, будут выведены только filterable_fields за исключением свойств, отмеченных в filterable_fields_except., (*49)
Пример, (*50)
В список фильтрации не должен попасть Id, (*51)
<?php
// ...
use Doctrine\ORM\Mapping as ORM;
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(filterable_fields_except="id")
*/
class Room
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Building", inversedBy="rooms")
*/
protected $building;
}
Что сделать, (*52)
Добавить опцию date_between аннотации класса QC\Entity. В опции указываются названия двух свойств сущности, содержащие даты "от" и "до"., (*53)
Результат, (*54)
К построенному запросу будет добавлено условие AND (:dateReport BETWEEN column1 AND column2), где :dateReport - дата, которая приходит из формы (удобно, если в таблице сущности применен паттерн "Версия реализации")., (*55)
Пример, (*56)
К запросу по сущности Room будет добавлено условие AND (:dateReport BETWEEN fromDate AND toDate) с параметром dateReport., (*57)
<?php
// ...
use FOD\QueryConstructor\Mapping\Annotation as QC;
/**
* @QC\Entity(date_between={"fromDate", "toDate"})
*/
class Room
{
// ...
/**
* @ORM\Column(type="datetime")
*/
protected $fromDate;
/**
* @ORM\Column(type="datetime")
*/
protected $toDate;
}
Что сделать, (*58)
Указать аннотацию класса QC\Entity в связанной сущности (которая отмечена в текущей сущности аннотацией ORM\ManyToOne., (*59)
Результат, (*60)
При задании фильтра можно будет выбрать связанную сущность и ее свойства, настраиваемые по правилам, указанным выше., (*61)
{{ fod_query_constructor()|raw }}
Параметры запроса записываются в скрытый input с именем sqlConstructor (к имени можно добавить префикс - см. настройку рендера выше), (*62)
$queryBuilder = $this->get('query_constructor.creator')->createFromJson($formParams['sqlConstructor']));
$entity->setSqlFilter(addslashes($this->get('query_constructor.serializer')->serialize($queryBuilder)));
Например, сериализованный QueryBuilder возвращается $entity->getSqlFilter():, (*63)
$queryBuilder = $this->get('query_constructor.serializer')->unserialize(stripslashes($entity->getSqlFilter()));
Создаёт экземпляр Doctrine QueryBuilder из JSON, (*64)
{
"aggregateFunction": "COUNT",
"entity": "MyClass1",
"property": "id"
"conditions": [
{
"type": "NONE",
"entity": "MyClass2",
"property": "name",
"operator": "=",
"value": "John"
}
]
}
Массив conditions[] может быть пустым.
Все поля, кроме conditions[].entity - обязательные.
Допустимые значения aggregateFunction - COUNT, SUM, MIN, MAX, AVG.
Допустимые значения conditions[].type - NONE, AND, OR.
Допустимые entity, property определяются из зарегеистрированных провайдеров (см. MetaDataProvider)., (*65)
Сериализует свойства экземпляра Doctrine QueryBuilder в виде массива. Обратно десериализует массив в QueryBuilder. Ключи массива:, (*66)
Для успешного записи результата сериализации в БД может потребоваться использовать addslashes() для экранирования 0-символов., (*67)
Бэкенд конструктора запросов, регистрация сервисов для Symfony, (*68)
Фронтенд-часть конструктора., (*69)
Альтернативы использования:, (*70)
/assets проекта (настройка файлов см. выше)npm install в корневой папке пакета query-constructorQueryConstructor из QueryConstructor.jsimport QueryConstructor from '../queryConstructor/QueryConstructor'
...
<QueryConstructor prefix="myform[field]" {...this.props.queryConstructorProps} />
...
Требуются следующие параметры:, (*71)
Конструктор формирует JSON, готовый для отдачи в Creator - в input с именем prefix[sqlConstructor], (*72)
GUI & serializer for Doctrine ORM QueryBuilder
MIT
doctrine
GUI & serializer for Doctrine ORM QueryBuilder
MIT
doctrine