Unable to recreate SQL query with Doctrine - php

I am having issues trying to recreate the following query:
select *
from acme_opties_relaties as r
inner join acme_options as o on o.id = r.id_a
inner join acme_option_subgroup as osg on osg.option_id = o.id
where osg.subgroup_id in (309, 303, 306, 300)
and o.id <> 47086
and r.soort = 2
and o.project_id = 140018
What i get is the following query:
SELECT t0_.id_a AS id_a_17, t0_.id_b AS id_b_18,
t0_.soort AS soort_0, t1_.id AS id_1, t1_.external_id AS external_id_2, t1_.external_ref AS external_ref_3, t1_.`name`
AS name_4, t1_.name_sales AS name_sales_5, t1_.price AS price_6, t1_.warranty AS warranty_7, t1_.material AS material_8, t1_.no_option
AS no_option_9, t1_.print AS print_10, t1_.text_warranty AS text_warranty_11, t1_.text_technical AS text_technical_12, t1_.text_sales AS text_sales_13, t1_.`group`
AS group_14, t1_.created AS created_15, t1_.updated AS updated_16, t1_.project_id AS project_id_19
FROM acme_opties_relaties t0_
INNER JOIN acme_options t1_ ON
(t1_.id <> 47086 AND t0_.soort = 2 AND EXISTS
(SELECT 1 FROM acme_option_subgroup t2_ INNER JOIN acme_subgroep t3_ ON t2_.subgroup_id = t3_.id WHERE t2_.option_id = t1_.id AND t3_.id IN (309, 303, 306, 300))
AND t1_.project_id = 140018)
any pointers / directions would be appreciated.
<?php
declare(strict_types = 1);
namespace Acme\Domain\Entity\Option;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Acme\Domain\Entity\Element\SubElement;
use Acme\Domain\Value\Option\Relation\Type;
/**
* Class RelationRepository
* Relations are interpreted as following.
* id_a is depending on id_b
* id_a is selected by id_b
* id_a is excluded by id_b
*
* #package Acme\Domain\Entity\Option
*/
class RelationRepository extends EntityRepository
{
/**
* #var array
*/
private $directions = ['left', 'right'];
/**
* getLeft returns the left side of the relations.
*
* #param Option $option
* #param SubElement $subElement
* #param Type $type
* #return array
*/
private function getLeft(Option $option, SubElement $subElement, Type $type, bool $inversed = false): Query
{
return $this->getQuery($option, $subElement, $type, 'left', $inversed);
}
/**
* getRight returns the right side of the relations.
*
* #param Option $option
* #param SubElement $subElement
* #param Type $type
* #return array
*/
private function getRight(Option $option, SubElement $subElement, Type $type, bool $inversed = false): Query
{
return $this->getQuery($option, $subElement, $type, 'right', $inversed);
}
/**
* getQuery returns the full Query needed to get a Collection of Relations.
*
* #param Option $option
* #param SubElement $subElement
* #param Type $type
* #param string $direction
* #return Query
*/
private function getQuery(Option $option, SubElement $subElement, Type $type, string $direction, bool $inversed): Query
{
$direction = strtolower($direction);
$this->validateDirection($direction);
$qb = $this->_em->createQueryBuilder()
->select(['r', 'option'])
->from('Acme\Domain\Entity\Option\Relation', 'r')
->join('Acme\Domain\Entity\Option\Option', 'option')
;
$subGroups = iterator_to_array($subElement->getElement()->getSubGroups());
return $this->addDirectionWhere($qb, $direction, $inversed)
->andWhere('r.type=:type')
->andWhere(':subGroup MEMBER OF option.subGroups')
->andWhere('option.project=:project')
->setParameter(':type', $type->getValue())
->setParameter(':opt', $option->getId())
->setParameter(':project', $option->getProject())
->setParameter(':subGroup', $subGroups)
->getQuery();
}
/**
* validateDirection checks if the direction given is valid.
*
* #param string $direction
*/
private function validateDirection(string $direction)
{
if (!in_array($direction, $this->directions, true)) {
throw new \InvalidArgumentException(sprintf('Unexpected direction given [%s]. Expected on of: [%s]',
$direction,
implode(', ', $direction)
));
}
}
/**
* addDirectionWhere returns a prepared QueryBuilder with a WHERE on the side needed.
*
* #param $direction
* #return \Doctrine\ORM\QueryBuilder
*/
private function addDirectionWhere(QueryBuilder $qb, $direction, $inversed = false): QueryBuilder
{
switch ($direction) {
case 'right':
$where = $inversed ? 'r.relation<>:opt' : 'r.relation=:opt';
break;
default:
$where = $inversed ? 'r.option<>:opt' : 'r.option=:opt';
break;
}
$qb->where($where);
return $qb;
}
/**
* getRequiredOptions returns a Collection of Relations which are required by the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return array
*/
public function getRequiredOptions(Option $option, SubElement $subElement): array
{
return $this->getRight($option, $subElement, Type::get(Type::DEPEND))->getResult();
}
/**
* getDependingOptions returns a Collection of Relations which depend on the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return mixed
*/
public function getDependingOptions(Option $option, SubElement $subElement): array
{
return $this->getLeft($option, $subElement, Type::get(Type::DEPEND))->getResult();
}
/**
* getRequiringOptionsExceptCurrent returns a Collection of Relations which require a Option, except the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return array
*/
public function getRequiringOptionsExceptCurrent(Option $option, SubElement $subElement): array
{
return $this->getLeft($option, $subElement, Type::get(Type::DEPEND), true)->getResult();
}
/**
* getExceludedOptions returns a Collection of Relations which are excluded by the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return array
*/
public function getExceludedOptions(Option $option, SubElement $subElement): array
{
return $this->getLeft($option, $subElement, Type::get(Type::EXCLUDE))->getResult();
}
/**
* getExcludedByOptions returns a Collection of Relations which exclude the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return array
*/
public function getExcludedByOptions(Option $option, SubElement $subElement): array
{
return $this->getRight($option, $subElement, Type::get(Type::EXCLUDE))->getResult();
}
/**
* getSelectedOptions returns a Collection of Relations which are selected by the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return array
*/
public function getSelectedOptions(Option $option, SubElement $subElement): array
{
return $this->getLeft($option, $subElement, Type::get(Type::SELECT))->getResult();
}
/**
* getSelectedByOptions returns a Collection of Relations which select the given Option.
*
* #param Option $option
* #param SubElement $subElement
* #return array
*/
public function getSelectedByOptions(Option $option, SubElement $subElement): array
{
return $this->getRight($option, $subElement, Type::get(Type::SELECT))->getResult();
}
}
/**
* #ORM\Entity(repositoryClass="Acme\Domain\Entity\Option\RelationRepository")
* #ORM\Table(name="acme_opties_relaties")
*/
class Relation
{
/**
* #ORM\ManyToOne(targetEntity="Acme\Domain\Entity\Option\Option", inversedBy="relations")
* #ORM\JoinColumn(name="id_a", referencedColumnName="id")
* #ORM\Id()
*/
private $option;
/**
* #ORM\OneToOne(targetEntity="Acme\Domain\Entity\Option\Option", fetch="EAGER")
* #ORM\JoinColumn(name="id_b", referencedColumnName="id")
* #ORM\Id()
*/
private $relation;
/**
* Class Option
* #package Acme\Domain\Entity\Option
* #ORM\Entity(repositoryClass="OptionRepository")
* #ORM\Table(name="acme_options")
*/
class Option
{
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Acme\Domain\Entity\Option\Relation", mappedBy="option")
*/
private $relations;
The issue is that the join between the relation and option is not on r.option.id_a = option.id but is on r.option.id_a <> X, it should join on the ids and in the where apply the <> X

Oh well, we still have most of SQL available. So changed it to:
private function getQuery(Option $option, SubElement $subElement, Type $type, string $direction, bool $inversed): Query
{
$direction = strtolower($direction);
$this->validateDirection($direction);
$query = 'select r, option, relation
from Acme\Domain\Entity\Option\Relation r
join r.option option
join r.relation relation
join option.subGroups osg
where osg in (:subGroup)
and option.project = :project
and r.type = :type
';
$query = $this->addDirectionWhere($query, $direction, $inversed);
$subGroups = iterator_to_array($subElement->getElement()->getSubGroups());
$q = $this->_em->createQuery($query);
$q->setParameter(':type', $type->getValue())
->setParameter(':option', $option->getId())
->setParameter(':project', $option->getProject())
->setParameter(':subGroup', $subGroups);
return $q;
}
I am still very open to know what the equivalent would be usin QueryBuilder. Because that has my preference.

Related

Laravel Nova pass value of one filter to another filter

I am trying to filter Laravel Nova resource (Reviews) data using 2 'select-filters'.
I have a filter A = Manufacturers and filter B = Models.
A Manufacturer has many Models. I have manufacturer and model column in products table.
'Model' filter by default show all the values in the select dropdown. I want to reduce the select options in the 'Model' filter when 'Manufacturer' is selected.
so, for example: When Manufacturer = "Apple" then 'Model' filter should show only Apple 'Models'.
In my Review Resource, I have below code:
/**
* Get the filters available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function filters(Request $request)
{
return [
new Manufacturer(),
new Model(),
];
}
Manufacturer Filter code
class Manufacturer extends Filter
{
/**
* The filter's component.
*
* #var string
*/
public $component = 'select-filter';
/**
* Apply the filter to the given query.
*
* #param \Illuminate\Http\Request $request
* #param \Illuminate\Database\Eloquent\Builder $query
* #param mixed $value
*
* #return \Illuminate\Database\Eloquent\Builder
*/
public function apply(Request $request, $query, $value)
{
return $query->whereHas('product', function ($query) use ($value) {
$query->where('manufacturer', $value);
});
}
/**
* Get the filter's available options.
*
* #param \Illuminate\Http\Request $request
*
* #return array
*/
public function options(Request $request)
{
return Product::select('manufacturer')
->withoutGlobalScopes()
->withoutTrashed()
->groupBy('manufacturer')
->orderBy('manufacturer')
->pluck('manufacturer')
->mapWithKeys(function ($manufacturer) {
return [$manufacturer => strtolower($manufacturer)];
})
->toArray();
}
}
Model Filter code
class Model extends Filter
{
/**
* The filter's component.
*
* #var string
*/
public $component = 'select-filter';
/**
* Apply the filter to the given query.
*
* #param \Illuminate\Http\Request $request
* #param \Illuminate\Database\Eloquent\Builder $query
* #param mixed $value
*
* #return \Illuminate\Database\Eloquent\Builder
*/
public function apply(Request $request, $query, $value)
{
return $query->whereHas('product', function ($query) use ($value) {
$query->where('model', $value);
});
}
/**
* Get the filter's available options.
*
* #param \Illuminate\Http\Request $request
*
* #return array
*/
public function options(Request $request)
{
//
//
//I want to add a condition below ->where('manufacturer', $manufacturer)
//
//
return Product::select('model')
->withoutGlobalScopes()
->withoutTrashed()
->groupBy('model')
->orderBy('model')
->pluck('model')
->mapWithKeys(function ($model) {
return [$model => strtolower($model)];
})
->toArray();
}
}
I tried to decode $request to get the filter values but returns null.
I found the library that helps achieve exactly what I wanted.
The library can be found here: https://github.com/awesome-nova/dependent-filter
Once the above library is installed, the two filters can be set as shown below:
Filter A
<?php
namespace App\Nova\Filters;
use Illuminate\Http\Request;
use App\Models\Product;
use AwesomeNova\Filters\DependentFilter;
class Manufacturer extends DependentFilter
{
/**
* Name of filter.
*
* #var string
*/
public $name = 'Manufacturer';
/**
* Attribute name of filter. Also it is key of filter.
*
* #var string
*/
public $attribute = 'manufacturer';
/**
* The filter's component.
*
* #var string
*/
public $component = 'awesome-nova-dependent-filter';
/**
* Apply the filter to the given query.
*
* #param \Illuminate\Http\Request $request
* #param \Illuminate\Database\Eloquent\Builder $query
* #param mixed $value
* #return \Illuminate\Database\Eloquent\Builder
*/
public function apply(Request $request, $query, $value)
{
return $query->whereHas('product', function ($query) use ($value) {
$query->where('manufacturer', $value);
});
}
/**
* Get the filter's available options.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function options(Request $request, array $filters = [])
{
return Product::select('manufacturer')
->pluck('manufacturer')
->mapWithKeys(function ($manufacturer) {
return [$manufacturer => $manufacturer];
})->toArray();
}
Filter B
<?php
namespace App\Nova\Filters;
use App\Models\Product;
use Illuminate\Http\Request;
use AwesomeNova\Filters\DependentFilter;
class Model extends DependentFilter
{
/**
* Name of filter.
*
* #var string
*/
public $name = 'Model';
/**
* Attribute name of filter. Also it is key of filter.
*
* #var string
*/
public $attribute = 'model';
/**
* The filter's component.
*
* #var string
*/
public $component = 'awesome-nova-dependent-filter';
/**
* The filter's dependentOf.
*
* #var array
*/
public $dependentOf = ['manufacturer'];
public $hideWhenEmpty = true;
/**
* Apply the filter to the given query.
*
* #param \Illuminate\Http\Request $request
* #param \Illuminate\Database\Eloquent\Builder $query
* #param mixed $value
* #return \Illuminate\Database\Eloquent\Builder
*/
public function apply(Request $request, $query, $value)
{
return $query->whereHas('product', function ($query) use ($value) {
$query->where('model', $value);
});
}
/**
* Get the filter's available options.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function options(Request $request, array $filters = [])
{
return Product::select('model')
->where('manufacturer', $filters['manufacturer'])
->pluck('model')
->mapWithKeys(function ($model) {
return [$model => $model];
})->toArray();
}
}
Resource File
public function filters(Request $request)
{
return [
Manufacturer::make(),
Model::make(),
];
}

JMS Groups Serialization and PagerFantaBundle

I'm working on a RESTFull API with Symfony and FOSRESTBundle. I use the JMS Serializer with groups to show differents fields depending on the context.
For listing my resources, I want implement PagerFantaBundle. All work fine except that PagerFanta does not consider the serialization groups.
Below my code :
Pagination function :
protected function paginate(QueryBuilder $qb, $limit = 20, $offset = 0) {
if($limit == 0 || $offset < 0) {
throw new \LogicException("$limit & $offset must be greater than 0");
}
$pager = new Pagerfanta(new DoctrineORMAdapter($qb));
$currentPage = ceil($offset + 1 / $limit);
$pager->setCurrentPage($currentPage);
$pager->setMaxPerPage((int) $limit);
return $pager;
}
List apartment function :
public function listApartments(Location $location, $order = 'asc', $limit = 20, $offset = 0) {
$qb = $this->createQueryBuilder('a')
->select('a')
->orderBy('a.title', $order);
return $this->paginate($qb, $limit, $offset);
}
Controller :
/**
* #Rest\Get(
* path = "/apartments",
* name = "apartments_get_all"
* )
* #Rest\QueryParam(
* name="order",
* requirements="asc|desc",
* nullable=true,
* description="Sort order (asc or desc)"
* )
* #Rest\QueryParam(
* name="limit",
* requirements="\d+",
* default="20",
* description="Max number of apartments per page"
* )
* #Rest\QueryParam(
* name="offset",
* requirements="\d+",
* default="0",
* description="Pagination offset"
* )
* #Rest\View(statusCode=200, serializerGroups={"listApartment"})
*/
public function getApartmentsAction(ParamFetcherInterface $paramFetcher)
{
$pager = $this->getDoctrine()->getRepository("HGBCoreBundle:Apartment")->listApartments(
new Location(),
$paramFetcher->get('order'),
$paramFetcher->get('limit'),
$paramFetcher->get('offset')
);
return new Apartments($pager);
}
Apartments representation :
class Apartments
{
/**
* #Type("array<HGB\CoreBundle\Entity\Apartment>")
*/
public $data;
public $meta;
public function __construct(Pagerfanta $data)
{
$this->data = $data->getCurrentPageResults();
$this->addMeta('limit', $data->getMaxPerPage());
$this->addMeta('current_items', count($data->getCurrentPageResults()));
$this->addMeta('total_items', $data->getNbResults());
$this->addMeta('offset', $data->getCurrentPageOffsetStart());
}
public function addMeta($name, $value)
{
if (isset($this->meta[$name])) {
throw new \LogicException(sprintf('This meta already exists. You are trying to override this meta, use the setMeta method instead for the %s meta.', $name));
}
$this->setMeta($name, $value);
}
public function setMeta($name, $value)
{
$this->meta[$name] = $value;
}
}
Apartment Entity :
/**
* Apartment
*
* #ORM\Table(name="apartment")
* #ORM\Entity(repositoryClass="HGB\CoreBundle\Repository\ApartmentRepository")
* #JMS\ExclusionPolicy("all")
*/
class Apartment
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups({"listApartment"})
* #JMS\Expose()
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=200)
* #JMS\Groups({"listApartment"})
* #JMS\Expose()
* #Assert\NotBlank()
*/
private $title;
...
So, how can I use group serialization with PagerFanta, or what pagination system could I use with groups serialization ?
Thanks
I've found the solution. Just need to configure the serialization groups for the Apartments representation like this :
<?php
namespace HGB\CoreBundle\Representation;
use JMS\Serializer\Annotation as Serializer;
use Pagerfanta\Pagerfanta;
/**
* Class Apartments
* #package HGB\CoreBundle\Representation
* #Serializer\ExclusionPolicy("all")
*/
class Apartments
{
/**
* #Serializer\Type("array<HGB\CoreBundle\Entity\Apartment>")
* #Serializer\Groups("listApartment")
* #Serializer\Expose()
*/
public $data;
/**
* #Serializer\Groups("listApartment")
* #Serializer\Expose()
*/
public $meta;
public function __construct(Pagerfanta $data)
{
$this->data = $data;
$this->addMeta('limit', $data->getMaxPerPage());
$this->addMeta('current_items', count($data->getCurrentPageResults()));
$this->addMeta('total_items', $data->getNbResults());
$this->addMeta('offset', $data->getCurrentPageOffsetStart());
}
public function addMeta($name, $value)
{
if (isset($this->meta[$name])) {
throw new \LogicException(sprintf('This meta already exists. You are trying to override this meta, use the setMeta method instead for the %s meta.', $name));
}
$this->setMeta($name, $value);
}
public function setMeta($name, $value)
{
$this->meta[$name] = $value;
}
}

PhpStorm Laravel 5 Form/Html not found issue

So I've seen this question a million times around the internet already, but my problem is slightly different.
I've created a new Laravel project and tried to use Html and Form classes. They did not exist so I did everything to include them to my project. And voila! It works... Kinda...
The classes Html and Form seem to be working. If I create a form and refresh in my browser, there's no error and the form is showing. But... PhpStorm does not recognize the classes, it keeps whining about undefined class Html and Form. With this there's the problem that the auto-complete for those classes do not work at all.
I've also included the _ide_helper.php class by 'barryvdh' (found on https://github.com/barryvdh/laravel-ide-helper) But that did not help with this problem.
I'm out of ideas, can anyone help me on this one? Would be greatly appreciated.
Cheers!
This works for me, do you have your composer.json file set up properly?
Make sure the scripts section is set up properly and then run composer dump-autoload.
composer.json
"scripts": {
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan ide-helper:generate",
"php artisan optimize"
] ...
},
Here is what my _ide_helper.php file looks like.
_ide_helper.php
class Form extends \Illuminate\Html\FormFacade{
/**
* Open up a new HTML form.
*
* #param array $options
* #return string
* #static
*/
public static function open($options = array()){
return \Illuminate\Html\FormBuilder::open($options);
}
/**
* Create a new model based form builder.
*
* #param mixed $model
* #param array $options
* #return string
* #static
*/
public static function model($model, $options = array()){
return \Illuminate\Html\FormBuilder::model($model, $options);
}
/**
* Set the model instance on the form builder.
*
* #param mixed $model
* #return void
* #static
*/
public static function setModel($model){
\Illuminate\Html\FormBuilder::setModel($model);
}
/**
* Close the current form.
*
* #return string
* #static
*/
public static function close(){
return \Illuminate\Html\FormBuilder::close();
}
/**
* Generate a hidden field with the current CSRF token.
*
* #return string
* #static
*/
public static function token(){
return \Illuminate\Html\FormBuilder::token();
}
/**
* Create a form label element.
*
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function label($name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::label($name, $value, $options);
}
/**
* Create a form input field.
*
* #param string $type
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function input($type, $name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::input($type, $name, $value, $options);
}
/**
* Create a text input field.
*
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function text($name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::text($name, $value, $options);
}
/**
* Create a password input field.
*
* #param string $name
* #param array $options
* #return string
* #static
*/
public static function password($name, $options = array()){
return \Illuminate\Html\FormBuilder::password($name, $options);
}
/**
* Create a hidden input field.
*
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function hidden($name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::hidden($name, $value, $options);
}
/**
* Create an e-mail input field.
*
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function email($name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::email($name, $value, $options);
}
/**
* Create a url input field.
*
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function url($name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::url($name, $value, $options);
}
/**
* Create a file input field.
*
* #param string $name
* #param array $options
* #return string
* #static
*/
public static function file($name, $options = array()){
return \Illuminate\Html\FormBuilder::file($name, $options);
}
/**
* Create a textarea input field.
*
* #param string $name
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function textarea($name, $value = null, $options = array()){
return \Illuminate\Html\FormBuilder::textarea($name, $value, $options);
}
/**
* Create a select box field.
*
* #param string $name
* #param array $list
* #param string $selected
* #param array $options
* #return string
* #static
*/
public static function select($name, $list = array(), $selected = null, $options = array()){
return \Illuminate\Html\FormBuilder::select($name, $list, $selected, $options);
}
/**
* Create a select range field.
*
* #param string $name
* #param string $begin
* #param string $end
* #param string $selected
* #param array $options
* #return string
* #static
*/
public static function selectRange($name, $begin, $end, $selected = null, $options = array()){
return \Illuminate\Html\FormBuilder::selectRange($name, $begin, $end, $selected, $options);
}
/**
* Create a select year field.
*
* #param string $name
* #param string $begin
* #param string $end
* #param string $selected
* #param array $options
* #return string
* #static
*/
public static function selectYear(){
return \Illuminate\Html\FormBuilder::selectYear();
}
/**
* Create a select month field.
*
* #param string $name
* #param string $selected
* #param array $options
* #param string $format
* #return string
* #static
*/
public static function selectMonth($name, $selected = null, $options = array(), $format = '%B'){
return \Illuminate\Html\FormBuilder::selectMonth($name, $selected, $options, $format);
}
/**
* Get the select option for the given value.
*
* #param string $display
* #param string $value
* #param string $selected
* #return string
* #static
*/
public static function getSelectOption($display, $value, $selected){
return \Illuminate\Html\FormBuilder::getSelectOption($display, $value, $selected);
}
/**
* Create a checkbox input field.
*
* #param string $name
* #param mixed $value
* #param bool $checked
* #param array $options
* #return string
* #static
*/
public static function checkbox($name, $value = 1, $checked = null, $options = array()){
return \Illuminate\Html\FormBuilder::checkbox($name, $value, $checked, $options);
}
/**
* Create a radio button input field.
*
* #param string $name
* #param mixed $value
* #param bool $checked
* #param array $options
* #return string
* #static
*/
public static function radio($name, $value = null, $checked = null, $options = array()){
return \Illuminate\Html\FormBuilder::radio($name, $value, $checked, $options);
}
/**
* Create a HTML reset input element.
*
* #param string $value
* #param array $attributes
* #return string
* #static
*/
public static function reset($value, $attributes = array()){
return \Illuminate\Html\FormBuilder::reset($value, $attributes);
}
/**
* Create a HTML image input element.
*
* #param string $url
* #param string $name
* #param array $attributes
* #return string
* #static
*/
public static function image($url, $name = null, $attributes = array()){
return \Illuminate\Html\FormBuilder::image($url, $name, $attributes);
}
/**
* Create a submit button element.
*
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function submit($value = null, $options = array()){
return \Illuminate\Html\FormBuilder::submit($value, $options);
}
/**
* Create a button element.
*
* #param string $value
* #param array $options
* #return string
* #static
*/
public static function button($value = null, $options = array()){
return \Illuminate\Html\FormBuilder::button($value, $options);
}
/**
* Get the ID attribute for a field name.
*
* #param string $name
* #param array $attributes
* #return string
* #static
*/
public static function getIdAttribute($name, $attributes){
return \Illuminate\Html\FormBuilder::getIdAttribute($name, $attributes);
}
/**
* Get the value that should be assigned to the field.
*
* #param string $name
* #param string $value
* #return string
* #static
*/
public static function getValueAttribute($name, $value = null){
return \Illuminate\Html\FormBuilder::getValueAttribute($name, $value);
}
/**
* Get a value from the session's old input.
*
* #param string $name
* #return string
* #static
*/
public static function old($name){
return \Illuminate\Html\FormBuilder::old($name);
}
/**
* Determine if the old input is empty.
*
* #return bool
* #static
*/
public static function oldInputIsEmpty(){
return \Illuminate\Html\FormBuilder::oldInputIsEmpty();
}
/**
* Get the session store implementation.
*
* #return \Illuminate\Session\Store $session
* #static
*/
public static function getSessionStore(){
return \Illuminate\Html\FormBuilder::getSessionStore();
}
/**
* Set the session store implementation.
*
* #param \Illuminate\Session\Store $session
* #return $this
* #static
*/
public static function setSessionStore($session){
return \Illuminate\Html\FormBuilder::setSessionStore($session);
}
/**
* Register a custom macro.
*
* #param string $name
* #param callable $macro
* #return void
* #static
*/
public static function macro($name, $macro){
\Illuminate\Html\FormBuilder::macro($name, $macro);
}
/**
* Checks if macro is registered.
*
* #param string $name
* #return bool
* #static
*/
public static function hasMacro($name){
return \Illuminate\Html\FormBuilder::hasMacro($name);
}
}
class Html extends \Illuminate\Html\HtmlFacade{
/**
* Convert an HTML string to entities.
*
* #param string $value
* #return string
* #static
*/
public static function entities($value){
return \Illuminate\Html\HtmlBuilder::entities($value);
}
/**
* Convert entities to HTML characters.
*
* #param string $value
* #return string
* #static
*/
public static function decode($value){
return \Illuminate\Html\HtmlBuilder::decode($value);
}
/**
* Generate a link to a JavaScript file.
*
* #param string $url
* #param array $attributes
* #param bool $secure
* #return string
* #static
*/
public static function script($url, $attributes = array(), $secure = null){
return \Illuminate\Html\HtmlBuilder::script($url, $attributes, $secure);
}
/**
* Generate a link to a CSS file.
*
* #param string $url
* #param array $attributes
* #param bool $secure
* #return string
* #static
*/
public static function style($url, $attributes = array(), $secure = null){
return \Illuminate\Html\HtmlBuilder::style($url, $attributes, $secure);
}
/**
* Generate an HTML image element.
*
* #param string $url
* #param string $alt
* #param array $attributes
* #param bool $secure
* #return string
* #static
*/
public static function image($url, $alt = null, $attributes = array(), $secure = null){
return \Illuminate\Html\HtmlBuilder::image($url, $alt, $attributes, $secure);
}
/**
* Generate a HTML link.
*
* #param string $url
* #param string $title
* #param array $attributes
* #param bool $secure
* #return string
* #static
*/
public static function link($url, $title = null, $attributes = array(), $secure = null){
return \Illuminate\Html\HtmlBuilder::link($url, $title, $attributes, $secure);
}
/**
* Generate a HTTPS HTML link.
*
* #param string $url
* #param string $title
* #param array $attributes
* #return string
* #static
*/
public static function secureLink($url, $title = null, $attributes = array()){
return \Illuminate\Html\HtmlBuilder::secureLink($url, $title, $attributes);
}
/**
* Generate a HTML link to an asset.
*
* #param string $url
* #param string $title
* #param array $attributes
* #param bool $secure
* #return string
* #static
*/
public static function linkAsset($url, $title = null, $attributes = array(), $secure = null){
return \Illuminate\Html\HtmlBuilder::linkAsset($url, $title, $attributes, $secure);
}
/**
* Generate a HTTPS HTML link to an asset.
*
* #param string $url
* #param string $title
* #param array $attributes
* #return string
* #static
*/
public static function linkSecureAsset($url, $title = null, $attributes = array()){
return \Illuminate\Html\HtmlBuilder::linkSecureAsset($url, $title, $attributes);
}
/**
* Generate a HTML link to a named route.
*
* #param string $name
* #param string $title
* #param array $parameters
* #param array $attributes
* #return string
* #static
*/
public static function linkRoute($name, $title = null, $parameters = array(), $attributes = array()){
return \Illuminate\Html\HtmlBuilder::linkRoute($name, $title, $parameters, $attributes);
}
/**
* Generate a HTML link to a controller action.
*
* #param string $action
* #param string $title
* #param array $parameters
* #param array $attributes
* #return string
* #static
*/
public static function linkAction($action, $title = null, $parameters = array(), $attributes = array()){
return \Illuminate\Html\HtmlBuilder::linkAction($action, $title, $parameters, $attributes);
}
/**
* Generate a HTML link to an email address.
*
* #param string $email
* #param string $title
* #param array $attributes
* #return string
* #static
*/
public static function mailto($email, $title = null, $attributes = array()){
return \Illuminate\Html\HtmlBuilder::mailto($email, $title, $attributes);
}
/**
* Obfuscate an e-mail address to prevent spam-bots from sniffing it.
*
* #param string $email
* #return string
* #static
*/
public static function email($email){
return \Illuminate\Html\HtmlBuilder::email($email);
}
/**
* Generate an ordered list of items.
*
* #param array $list
* #param array $attributes
* #return string
* #static
*/
public static function ol($list, $attributes = array()){
return \Illuminate\Html\HtmlBuilder::ol($list, $attributes);
}
/**
* Generate an un-ordered list of items.
*
* #param array $list
* #param array $attributes
* #return string
* #static
*/
public static function ul($list, $attributes = array()){
return \Illuminate\Html\HtmlBuilder::ul($list, $attributes);
}
/**
* Build an HTML attribute string from an array.
*
* #param array $attributes
* #return string
* #static
*/
public static function attributes($attributes){
return \Illuminate\Html\HtmlBuilder::attributes($attributes);
}
/**
* Obfuscate a string to prevent spam-bots from sniffing it.
*
* #param string $value
* #return string
* #static
*/
public static function obfuscate($value){
return \Illuminate\Html\HtmlBuilder::obfuscate($value);
}
/**
* Register a custom macro.
*
* #param string $name
* #param callable $macro
* #return void
* #static
*/
public static function macro($name, $macro){
\Illuminate\Html\HtmlBuilder::macro($name, $macro);
}
/**
* Checks if macro is registered.
*
* #param string $name
* #return bool
* #static
*/
public static function hasMacro($name){
return \Illuminate\Html\HtmlBuilder::hasMacro($name);
}
}
EDIT
Do you have you config/app.php and composer.json files set up properly?
app.php
'providers' => [
...
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
Illuminate\Html\HtmlServiceProvider::class,
...
];
'aliases' => [
...
'Form' => Illuminate\Html\FormFacade::class,
'Html' => Illuminate\Html\HtmlFacade::class,
...
];
composer.json
"require": {
...
"illuminate/html": "~5.0",
...
},
"require-dev": {
...
"barryvdh/laravel-ide-helper": "~2.0",
...
},

Symfony2 and Entity Field : Expected argument of type "Doctrine\ORM\QueryBuilder", "NULL" given

I have problems with my classes Symfony2.
I have 3 classes "Niveau, Classe and Serie" that here. A class is related to a level and against a Series by Series Level and are in contact with several class. Here is the source code
/**
* KS\SchoolBundle\Entity\Niveau
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="KS\SchoolBundle\Entity\NiveauRepository")
*/
class Niveau
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $niveau
*
* #ORM\Column(name="niveau", type="string", length=255)
*/
private $niveau;
/**
* #var string $code
*
* #ORM\Column(name="code", type="string", length=255)
*/
private $code;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set niveau
*
* #param string $niveau
* #return Niveau
*/
public function setNiveau($niveau)
{
$this->niveau = $niveau;
return $this;
}
/**
* Get niveau
*
* #return string
*/
public function getNiveau()
{
return $this->niveau;
}
/**
* Set code
*
* #param string $code
* #return Niveau
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
}
/**
* KS\SchoolBundle\Entity\Serie
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="KS\SchoolBundle\Entity\SerieRepository")
*/
class Serie
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $serie
*
* #ORM\Column(name="serie", type="string", length=255)
*/
private $serie;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $serie
* #return Serie
*/
public function setSerie($serie)
{
$this->serie = $serie;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getSerie()
{
return $this->seriee;
}
}
/**
* KS\SchoolBundle\Entity\Classe
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="KS\SchoolBundle\Entity\ClasseRepository")
*/
class Classe
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #var type integer
*
* #ORM\ManyToOne(targetEntity="KS\SchoolBundle\Entity\Niveau")
* #ORM\JoinColumn(nullable=false)
*/
private $niveau;
/**
*
* #var type integer
*
* #ORM\ManyToOne(targetEntity="KS\SchoolBundle\Entity\Serie")
* #ORM\JoinColumn
*/
private $serie;
/**
*
* #var type string
*
* #ORM\ManyToOne(targetEntity="KS\SchoolBundle\Entity\Section", inversedBy="classes")
* #ORM\JoinColumn(nullable=false)
*/
private $section;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set niveau
*
* #param KS\School\Entity\Niveau $niveau
* #return Classe
*/
public function setNiveau(\KS\School\Entity\Niveau $niveau)
{
$this->niveau = $niveau;
return $this;
}
/**
* Get niveau
*
* #return KS\School\Entity\Niveau
*/
public function getNiveau()
{
return $this->niveau;
}
/**
* Set serie
*
* #param KS\School\Entity\Serie $serie
* #return Classe
*/
public function setSerie(\KS\School\Entity\Serie $serie)
{
$this->serie = $serie;
return $this;
}
/**
* Get serie
*
* #return KS\School\Entity\Serie
*/
public function getSerie()
{
return $this->serie;
}
/**
* Set section
*
* #param KS\School\Entity\Section $section
* #return Classe
*/
public function setSection(\KS\School\Entity\Section $section)
{
$this->section = $section;
return $this;
}
/**
* Get section
*
* #return KS\School\Entity\Section
*/
public function getSection()
{
return $this->section;
}
public function __toString() {
return $this->getNiveau() . ' ' . $this->getSerie();
}
}
My problem is that entity in a field I want to display a dropdown that has value as a concatenation of the code level and series of Series I which procedé as follows
->add('class', 'entity', array(
'class' => 'KSSchoolBundle:Classe',
'property' => 'value',
'query_builder' => function (\KS\SchoolBundle\Entity\ClasseRepository $er) {
$results = $er->findAllClassesByCodeAndSerie();
$data = array();
foreach ($results as $result) {
$data[] = array(
'id' => $result['id'],
'value' => $result['code'] . ' ' . is_null($result['serie']) ? '' : $result['serie'],
);
}
return $data;
},
)
)
but nothing since there. query_builder return $data that is as you see an array. id must be the value of the option tag value and value should be what the user must see, but I do not see how to do this. The browser give this error Expected argument of type "Doctrine\ORM\QueryBuilder", "array" given
I wonder if that would be a way to do it right the Class class at the __toString () whereby it returns something like getNiveau (). getCode (). ''. getSerie (). getSerie ()
Please one hand it's been two days that I am on this form.
You return an array instead of a QueryBuilder instance in your options array for the entity field type named 'class'.
The wrong part is this one:
'query_builder' => function (\KS\SchoolBundle\Entity\ClasseRepository $er) {
// this is wrong as it does not return a Query but your Class entities themself ...
// findByCodeAndSerie would normally receive 2 arguments: $code & $serie
// but anyway ... this does not belong here !
$results = $er->findAllClassesByCodeAndSerie();
// ... weird stuff
$data = array();
// ... more weird stuff
return $data; /// you return an array instead of QueryBuilder
a correct implementation would be something like this:
use KS\SchoolBundle\Entity\ClasseRepository;
// ...
// 'property' => 'value', // remove this !!
'query_builder' => function(ClasseRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.code', 'ASC');
},
now just add the __toString() method to your Class entity. This will be the rendered label for the entity:
public function __toString()
{
return $this->niveau . $this->code . ' ' . $this->serie . $this->serie;
}
Read the enitity field type reference for more information and examples.

->find($id) in entity returns an empty proxy object symfony2

I'm doing a search on an entity, but this returns me a proxy object. Thus I am trying to do the search.
$em = $this->getDoctrine()->getEntityManager();
$tipou = $em->getRepository('SertecomvendoautosBundle:TipoUsuario')->find(5);
In the database, table tipo_usuario I have only two records with ID 4 and 5, but to make the search with ID 4, doctrine returns the object for me and not the proxy object that returns me with ID 5.
$em = $this->getDoctrine()->getEntityManager();
$tipou = $em->getRepository('SertecomvendoautosBundle:TipoUsuario')->find(4);
This brings the object in the normal way.
Really do not understand this behavior that doctrine, I would like to know what happens with this.
This is code of entity tipo_usuario.
class TipoUsuario {
/**
* #var string $tipouNombre
*/
private $tipouNombre;
/**
* #var string $tipouToken
*/
private $tipouToken;
/**
* #var datetime $tipouCreatedAt
*/
private $tipouCreatedAt;
/**
* #var datetime $tipouUpdatedAt
*/
private $tipouUpdatedAt;
/**
* #var integer $tipouId
*/
private $tipouId;
/**
* Set tipouNombre
*
* #param string $tipouNombre
*/
public function setTipouNombre($tipouNombre)
{
$this->tipouNombre = $tipouNombre;
}
/**
* Get tipouNombre
*
* #return string
*/
public function getTipouNombre()
{
return $this->tipouNombre;
}
/**
* Set tipouToken
*
* #param string $tipouToken
*/
public function setTipouToken($tipouToken)
{
$this->tipouToken = $tipouToken;
}
/**
* Get tipouToken
*
* #return string
*/
public function getTipouToken()
{
return $this->tipouToken;
}
/**
* Set tipouCreatedAt
*
* #param datetime $tipouCreatedAt
*/
public function setTipouCreatedAt($tipouCreatedAt)
{
$this->tipouCreatedAt = $tipouCreatedAt;
}
/**
* Get tipouCreatedAt
*
* #return datetime
*/
public function getTipouCreatedAt()
{
return $this->tipouCreatedAt;
}
/**
* Set tipouUpdatedAt
*
* #param datetime $tipouUpdatedAt
*/
public function setTipouUpdatedAt($tipouUpdatedAt)
{
$this->tipouUpdatedAt = $tipouUpdatedAt;
}
/**
* Get tipouUpdatedAt
*
* #return datetime
*/
public function getTipouUpdatedAt()
{
return $this->tipouUpdatedAt;
}
/**
* Get tipouId
*
* #return integer
*/
public function getTipouId()
{
return $this->tipouId;
}

Categories