Doctrine QueryBuilder COUNT and Voters



我有一些实体,例如Device带有投票器的实体,允许当前用户访问或不访问某些Device

搜索Device时,为了过滤,我使用了一个运行良好的array_filter函数。

但是,我想对我的Device实体进行一些统计,例如Device的数量Brand.

我的查询正常:

$query = $this->createQueryBuilder('d')
->select('COUNT(d.id), b.name')
->join('d.model', 'm')
->join('m.Brand', 'b')
->groupBy('b.name')
;
return $query->getQuery()->getResult();

我有一个包含我的数据的数组。

但选民不适用。

如果我将用户切换到可能无法访问所有Device的用户,我仍然会看到相同的数字。

那么,我如何过滤选民的COUNT请求?

Device实体 :

<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use GedmoMappingAnnotation as Gedmo;

/**
* @ORMEntity(repositoryClass="AppRepositoryDeviceRepository")
*/
class Device
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=15)
*/
private $reference;
/**
* @ORMColumn(type="string", length=20)
*/
private $imei;
/**
* @ORMColumn(type="date", nullable=true)
*/
private $buyDate;
/**
* @ORMColumn(type="float", nullable=true)
*/
private $buyPrice;
/**
* @ORMManyToOne(targetEntity="AppEntityDeviceGrade")
*/
private $grade;
/**
* @ORMManyToOne(targetEntity="AppEntityCustomerGroup")
* @ORMJoinColumn(nullable=false)
*/
private $customerGroup;
/**
* @ORMManyToOne(targetEntity="AppEntityCustomerEntity")
*/
private $customerEntity;
/**
* @ORMManyToOne(targetEntity="AppEntityCustomerSite")
*/
private $customerSite;
/**
* @ORMManyToOne(targetEntity="AppEntityModel")
* @ORMJoinColumn(nullable=false)
*/
private $model;
/**
* @ORMColumn(type="date", nullable=true)
*/
private $sellDate;
/**
* @ORMColumn(type="float", nullable=true)
*/
private $sellPrice;

/**
* @ORMColumn(type="datetime", nullable=true)
* @GedmoTimestampable(on="create")
*/
private $dateAdd;
/**
* @ORMColumn(type="datetime", nullable=true)
* @GedmoTimestampable(on="update")
*/
private $dateUpd;
/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @GedmoBlameable(on="create")
*/
private $createdBy;
/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @GedmoBlameable(on="update")
*/
private $modifiedBy;
/**
* @ORMOneToMany(targetEntity="AppEntityDeviceStatusHistory", mappedBy="device")
*/
private $deviceStatusHistories;

public function __construct()
{
$this->deviceStatusHistories = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getReference(): ?string
{
return $this->reference;
}
public function setReference(string $reference): self
{
$this->reference = $reference;
return $this;
}
public function getImei(): ?string
{
return $this->imei;
}
public function setImei(string $imei): self
{
$this->imei = $imei;
return $this;
}
public function getBuyDate(): ?DateTimeInterface
{
return $this->buyDate;
}
public function setBuyDate(?DateTimeInterface $buyDate): self
{
$this->buyDate = $buyDate;
return $this;
}
public function getBuyPrice(): ?float
{
return $this->buyPrice;
}
public function setBuyPrice(?float $buyPrice): self
{
$this->buyPrice = $buyPrice;
return $this;
}
public function getGrade(): ?DeviceGrade
{
return $this->grade;
}
public function setGrade(?DeviceGrade $grade): self
{
$this->grade = $grade;
return $this;
}
public function getCustomerGroup(): ?CustomerGroup
{
return $this->customerGroup;
}
public function setCustomerGroup(?CustomerGroup $customerGroup): self
{
$this->customerGroup = $customerGroup;
return $this;
}
public function getCustomerEntity(): ?CustomerEntity
{
return $this->customerEntity;
}
public function setCustomerEntity(?CustomerEntity $customerEntity): self
{
$this->customerEntity = $customerEntity;
return $this;
}
public function getCustomerSite(): ?CustomerSite
{
return $this->customerSite;
}
public function setCustomerSite(?CustomerSite $customerSite): self
{
$this->customerSite = $customerSite;
return $this;
}
public function getModel(): ?Model
{
return $this->model;
}
public function setModel(?Model $model): self
{
$this->model = $model;
return $this;
}
public function getSellDate(): ?DateTimeInterface
{
return $this->sellDate;
}
public function setSellDate(?DateTimeInterface $sellDate): self
{
$this->sellDate = $sellDate;
return $this;
}
public function getSellPrice(): ?float
{
return $this->sellPrice;
}
public function setSellPrice(?float $sellPrice): self
{
$this->sellPrice = $sellPrice;
return $this;
}
public function getDateAdd(): ?DateTimeInterface
{
return $this->dateAdd;
}
public function setDateAdd(DateTimeInterface $dateAdd): self
{
$this->dateAdd = $dateAdd;
return $this;
}
public function getDateUpd(): ?DateTimeInterface
{
return $this->dateUpd;
}
public function setDateUpd(DateTimeInterface $dateUpd): self
{
$this->dateUpd = $dateUpd;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function getModifiedBy(): ?User
{
return $this->modifiedBy;
}
public function setModifiedBy(?User $modifiedBy): self
{
$this->modifiedBy = $modifiedBy;
return $this;
}
/**
* @return Collection|DeviceStatusHistory[]
*/
public function getDeviceStatusHistories(): Collection
{
return $this->deviceStatusHistories;
}
public function addDeviceStatusHistory(DeviceStatusHistory $deviceStatusHistory): self
{
if (!$this->deviceStatusHistories->contains($deviceStatusHistory)) {
$this->deviceStatusHistories[] = $deviceStatusHistory;
$deviceStatusHistory->setDevice($this);
}
return $this;
}
public function removeDeviceStatusHistory(DeviceStatusHistory $deviceStatusHistory): self
{
if ($this->deviceStatusHistories->contains($deviceStatusHistory)) {
$this->deviceStatusHistories->removeElement($deviceStatusHistory);
// set the owning side to null (unless already changed)
if ($deviceStatusHistory->getDevice() === $this) {
$deviceStatusHistory->setDevice(null);
}
}
return $this;
}
public function __toString(): string
{
return $this->reference.' / '.$this->imei.' / '.$this->getModel()->getName().' - '.
$this->getModel()->getBrand()->getName().' - '.$this->getModel()->getColor()->getName().
' - '.$this->getModel()->getStorage()->getCapacity();
}

}

Model实体 :

<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use GedmoMappingAnnotation as Gedmo;
use VichUploaderBundleMappingAnnotation as Vich;
use SymfonyComponentHttpFoundationFileFile;


/**
* @ORMEntity(repositoryClass="AppRepositoryModelRepository")
* @VichUploadable
*/
class Model
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
*/
private $name;
/**
* @ORMColumn(type="boolean")
*/
private $isActive;
/**
* @ORMColumn(type="date", nullable=true)
*/
private $dateStartSell;
/**
* @ORMColumn(type="date", nullable=true)
*/
private $dateEndSell;
/**
* @ORMColumn(type="date", nullable=true)
*/
private $dateEndSupport;
/**
* @ORMManyToOne(targetEntity="AppEntityBrand", inversedBy="models")
* @ORMJoinColumn(nullable=false)
*/
private $Brand;
/**
* @ORMManyToOne(targetEntity="AppEntityColor")
* @ORMJoinColumn(nullable=false)
*/
private $color;
/**
* @ORMManyToOne(targetEntity="AppEntityStorage")
*/
private $storage;
/**
* @ORMColumn(type="datetime", nullable=true)
* @GedmoTimestampable(on="create")
*/
private $dateAdd;
/**
* @ORMColumn(type="datetime", nullable=true)
* @GedmoTimestampable(on="update")
*/
private $dateUpd;
/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @GedmoBlameable(on="create")
*/
private $createdBy;
/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @GedmoBlameable(on="update")
*/
private $modifiedBy;
/**
* @ORMManyToMany(targetEntity="AppEntityCustomerGroup", inversedBy="models")
*/
private $customerGroup;
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @VichUploadableField(mapping="model_image", fileNameProperty="imageName", size="imageSize")
*
* @var File
*/
private $imageFile;
/**
* @ORMColumn(type="string", length=255, nullable=true)
*
* @var string
*/
private $imageName;
/**
* @ORMColumn(type="integer", nullable=true)
*
* @var integer
*/
private $imageSize;

public function __construct(?File $imageFile = null)
{
$this->customerGroup = new ArrayCollection();
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->dateUpd = new DateTimeImmutable();
}
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
public function getDateStartSell(): ?DateTimeInterface
{
return $this->dateStartSell;
}
public function setDateStartSell(?DateTimeInterface $dateStartSell): self
{
$this->dateStartSell = $dateStartSell;
return $this;
}
public function getDateEndSell(): ?DateTimeInterface
{
return $this->dateEndSell;
}
public function setDateEndSell(?DateTimeInterface $dateEndSell): self
{
$this->dateEndSell = $dateEndSell;
return $this;
}
public function getDateEndSupport(): ?DateTimeInterface
{
return $this->dateEndSupport;
}
public function setDateEndSupport(?DateTimeInterface $dateEndSupport): self
{
$this->dateEndSupport = $dateEndSupport;
return $this;
}
public function getBrand(): ?Brand
{
return $this->Brand;
}
public function setBrand(?Brand $Brand): self
{
$this->Brand = $Brand;
return $this;
}
public function getColor(): ?Color
{
return $this->color;
}
public function setColor(?Color $color): self
{
$this->color = $color;
return $this;
}
public function getStorage(): ?Storage
{
return $this->storage;
}
public function setStorage(?Storage $storage): self
{
$this->storage = $storage;
return $this;
}
public function getDateAdd(): ?DateTimeInterface
{
return $this->dateAdd;
}
public function setDateAdd(DateTimeInterface $dateAdd): self
{
$this->dateAdd = $dateAdd;
return $this;
}
public function getDateUpd(): ?DateTimeInterface
{
return $this->dateUpd;
}
public function setDateUpd(DateTimeInterface $dateUpd): self
{
$this->dateUpd = $dateUpd;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function getModifiedBy(): ?User
{
return $this->modifiedBy;
}
public function setModifiedBy(?User $modifiedBy): self
{
$this->modifiedBy = $modifiedBy;
return $this;
}
public function __toString(): string
{
return $this->getBrand()->getName().' '.$this->getName().' '.$this->getColor()->getName().' '.$this->getStorage()->getCapacity();
}
/**
* @return Collection|CustomerGroup[]
*/
public function getCustomerGroup(): Collection
{
return $this->customerGroup;
}
public function addCustomerGroup(CustomerGroup $customerGroup): self
{
if (!$this->customerGroup->contains($customerGroup)) {
$this->customerGroup[] = $customerGroup;
}
return $this;
}
public function removeCustomerGroup(CustomerGroup $customerGroup): self
{
if ($this->customerGroup->contains($customerGroup)) {
$this->customerGroup->removeElement($customerGroup);
}
return $this;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|SymfonyComponentHttpFoundationFileUploadedFile $imageFile
*/
public function setImageFile(?File $imageFile = null): void
{
$this->imageFile = $imageFile;
if (null !== $imageFile) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->dateUpd = new DateTimeImmutable();
}
}
public function getImageFile(): ?File
{
return $this->imageFile;
}
public function setImageName(?string $imageName): void
{
$this->imageName = $imageName;
}
public function getImageName(): ?string
{
return $this->imageName;
}
public function setImageSize(?int $imageSize): void
{
$this->imageSize = $imageSize;
}
public function getImageSize(): ?int
{
return $this->imageSize;
}
}

Brand实体:

<?php
namespace AppEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use GedmoMappingAnnotation as Gedmo;

/**
* @ORMEntity(repositoryClass="AppRepositoryBrandRepository")
* @ORMHasLifecycleCallbacks()
*/
class Brand
{
/**
* @ORMId()
* @ORMGeneratedValue()
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMColumn(type="string", length=255)
*/
private $name;
/**
* @ORMColumn(type="datetime")
* @GedmoTimestampable(on="create")
*/
private $dateAdd;
/**
* @ORMColumn(type="datetime")
* @GedmoTimestampable(on="create")
*/
private $dateUpd;
/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @ORMJoinColumn(nullable=false)
* @GedmoBlameable(on="create")
*/
private $createdBy;
/**
* @ORMManyToOne(targetEntity="AppEntityUser")
* @ORMJoinColumn(nullable=false)
* @GedmoBlameable(on="update")
*/
private $modifiedBy;
/**
* @ORMColumn(type="boolean")
*/
private $isDeleted;
/**
* @ORMColumn(type="boolean")
*/
private $isActive;
/**
* @ORMOneToMany(targetEntity="AppEntityModel", mappedBy="Brand")
*/
private $models;
public function __construct()
{
$this->models = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getDateAdd(): ?DateTimeInterface
{
return $this->dateAdd;
}
public function setDateAdd(DateTimeInterface $dateAdd): self
{
$this->dateAdd = $dateAdd;
return $this;
}
public function getDateUpd(): ?DateTimeInterface
{
return $this->dateUpd;
}
public function setDateUpd(DateTimeInterface $dateUpd): self
{
$this->dateUpd = $dateUpd;
return $this;
}
public function getCreatedBy(): ?User
{
return $this->createdBy;
}
public function setCreatedBy(?User $createdBy): self
{
$this->createdBy = $createdBy;
return $this;
}
public function getModifiedBy(): ?User
{
return $this->modifiedBy;
}
public function setModifiedBy(?User $modifiedBy): self
{
$this->modifiedBy = $modifiedBy;
return $this;
}
public function getIsDeleted(): ?bool
{
return $this->isDeleted;
}
public function setIsDeleted(bool $isDeleted): self
{
$this->isDeleted = $isDeleted;
return $this;
}
public function getIsActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): self
{
$this->isActive = $isActive;
return $this;
}
/**
* @return Collection|Model[]
*/
public function getModels(): Collection
{
return $this->models;
}
public function addModel(Model $model): self
{
if (!$this->models->contains($model)) {
$this->models[] = $model;
$model->setBrand($this);
}
return $this;
}
public function removeModel(Model $model): self
{
if ($this->models->contains($model)) {
$this->models->removeElement($model);
// set the owning side to null (unless already changed)
if ($model->getBrand() === $this) {
$model->setBrand(null);
}
}
return $this;
}
}

感谢您的帮助!

最好

朱利安

投票者不会更新您的查询。它用于检查用户是否有权访问代码的某些部分。

如果你想根据你的选民拥有你的设备,你需要根据你需要编写正确的查询!

感谢您的留言

@Alexandre : 我要这样搜索。

我为实现我的目标做了什么: - 在模型和品牌实体中添加与inversedby的双向关系。 这样,我可以做到:

$brands = $this->getDoctrine()->getRepository(Brand::class)->findAll();
$arrayBrands = array();
$arrayDevicesCount = array();
foreach($brands as  $brand)
{
$devicesCount = 0;
$models = $brand->getModels();
foreach ($models as $model)
{
$devices = $model->getDevices()->getValues();
$devices = array_filter($devices, function (Device $device){
return $this->isGranted('view', $device);
});
$devicesCount+= count($devices);
}
if($devicesCount > 0)
{
array_push($arrayBrands, $brand->getName());
array_push($arrayDevicesCount, $devicesCount);
}
}

这运作良好!

最新更新