Doesn't save the image in the database Symfony 4 - file-upload

I'm writing applications in symfony and I would like to add an image to the article. I can't save the image to the database. I am trying to make an example from the documentation: https://symfony.com/doc/current/controller/upload_file.html
The image is uploaded to the directory on the server and isn't saved to the database.
$post->setThumbnail($fileName); sets the image name correctly
Entity
/**
* #Assert\Image(
* minWidth = 500,
* minHeight = 300,
* maxWidth = 1920,
* maxHeight = 1080,
* maxSize = "1M"
* )
*/
private $thumbnail;
/**
* Set thumbnail.
*
* #param string $thumbnail
*
* #return Post
*/
public function setThumbnail($thumbnail)
{
$this->thumbnail = $thumbnail;
return $this;
}
/**
* Get thumbnail.
*
* #return string
*/
public function getThumbnail()
{
return $this->thumbnail;
}
Action in Controller
/**
* Add and Edit page Post.
*
* #Route(
* {"pl": "/artykyl/{slug}"},
* name="panel_post",
* defaults={"slug"=NULL}
* )
*
* #param Request $request
* #param string|null $slug
* #param TranslatorInterface $translator
*
* #return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*/
public function post(Request $request, string $slug = null, TranslatorInterface $translator, FileUploader $fileUploader)
{
if (null === $slug) {
$post = new Post();
$newPostForm = true;
} else {
$post = $this->getDoctrine()->getRepository('App\Entity\Post')->findOneBy(['slug' => $slug]);
}
$form = $this->createForm(PostType::class, $post);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($post->getThumbnail()) {
$file = $post->getThumbnail();
$fileName = $fileUploader->upload($file);
$post->setThumbnail($fileName);
}
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
$this->addFlash('success', $translator->trans('Changes have been saved'));
return $this->redirectToRoute('panel_post', ['slug' => $post->getSlug()]);
} elseif ($form->isSubmitted() && false === $form->isValid()) {
$this->addFlash('danger', $translator->trans('Corrects form'));
}
return $this->render('backend/blog/post.html.twig', [
'currPage' => 'posts',
'form' => $form->createView(),
'post' => $post,
]);
}
File Uploader
class FileUploader
{
private $targetDirectory;
public function __construct($targetDirectory)
{
$this->targetDirectory = $targetDirectory;
}
public function upload(UploadedFile $file)
{
$fileName = md5(uniqid()).'.'.$file->guessExtension();
try {
$file->move($this->getTargetDirectory(), $fileName);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
return $fileName;
}
public function getTargetDirectory()
{
return $this->targetDirectory;
}
}
Listener ThumbnailUploadListener
class ThumbnailUploadListener
{
private $uploader;
public function __construct(FileUploader $uploader)
{
$this->uploader = $uploader;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
public function preUpdate(PreUpdateEventArgs $args)
{
$entity = $args->getEntity();
$this->uploadFile($entity);
}
private function uploadFile($entity)
{
// upload only works for Post entities
if (!$entity instanceof Post) {
return;
}
$file = $entity->getThumbnail();
// only upload new files
if ($file instanceof UploadedFile) {
$fileName = $this->uploader->upload($file);
$entity->setThumbnail($fileName);
} elseif ($file instanceof File) {
// prevents the full file path being saved on updates
// as the path is set on the postLoad listener
$entity->setThumbnail($file->getFilename());
}
}
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Post) {
return;
}
if ($fileName = $entity->getThumbnail()) {
$entity->setPost(new File($this->uploader->getTargetDirectory().'/'.$fileName));
}
}
}
services.yaml
App\EventListener\ThumbnailUploadListener:
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
- { name: doctrine.event_listener, event: postLoad }

You forgot about mapping the thumbnail field
#ORM\Column(type="string")

Related

Is there a way to optimize the mapping of users?

I've created a method to call this getUserIdsByAllBranches() and the return would be an array. If array is not empty, I'll be doing another process. But I have a problem here in mapping or getting all the users with all branches.
Here's the code:
/**
* Get all User Ids of Branch Permission User
* By All Branches
* #param Array
* #return Array
*/
public function getUserIdsByAllBranches($override = [])
{
if (count($override) !== 0) {
foreach($override as $property => $value) {
${$property} = $value;
}
} else {
$branchLength = App::make(BranchRepository::class)->get()->count();
}
$userIdsWithAllBranches = [];
$userIds = $this->getUserIds();
foreach($userIds as $userId) {
$identical = true;
$userBranchIds = array_values($this->get()
->where('user_id', $userId)
->pluck(['branch_id'])
->unique()
->toArray());
if(count($userBranchIds) === $branchLength) {
$initialPermissions = [];
foreach($userBranchIds as $index => $userBranchId) {
if(!$identical) {
continue;
}
$branchUserPermissions = $this->get()
->where('user_id', $userId)
->where('branch_id', $userBranchId)
->sortBy('permission_id')
->pluck(['permission_id']);
if($index === 0) {
$initialPermissions = $branchUserPermissions;
} else {
if($initialPermissions != $branchUserPermissions) {
$identical = false;
}
}
}
} else {
$identical = false;
}
if($identical) {
array_push($userIdsWithAllBranches, $userId);
}
}
return $userIdsWithAllBranches;
}
/**
* Get all User Ids of Branch Permission User
*
* #return Array
*/
public function getUserIds()
{
return array_values($this->get()
->sortBy('user_id')
->pluck(['user_id'])
->unique()
->toArray());
}
This method getUserIds(), will be returning all the user ids for branch permission user table.
Branch Permission User Table:
branch_id
permission_id
user_id

TYPO3 9 get resources and categories from pages, queryBuilder join problems

This solution was working til TYPO3 8.7. But breaks in TYPO3 9.
I've some submenu showing images from page-resources and using categories.descriptions for css.
I use custom viewhelpers for that. But now the JOIN-sql is broken... Don't know why, because it worked in 8.7 and previous.
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
class SysCategoryViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* #var integer $uid (CE)
*/
public function initializeArguments() {
$this->registerArgument('uid', 'integer', 'enthaelt die UID des CE', TRUE);
}
/**
* #var integer $uid
*/
public function render($uid = null) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$queryBuilder->getRestrictions()
->removeAll();
$query = $queryBuilder
->select('*')
->from('sys_category')
->join('sys_category','sys_category_record_mm','MM', $queryBuilder->expr()->andX($queryBuilder->expr()->eq('MM.uid_foreign', $uid),$queryBuilder->expr()->eq('MM.uid_local', 'uid')))
->setMaxResults(1);
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
$this->templateVariableContainer->add('sysCategoryDetailArray', $res);
}
}
ERRORMESSAGE
(1/2) Doctrine\DBAL\Exception\SyntaxErrorException
An exception occurred while executing
SELECT * FROM sys_category INNER JOIN sys_category_record_mm MM ON
(`MM`.`uid_foreign` = ) AND (MM.uid_local = uid)
LIMIT 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND (MM.uid_local = uid) LIMIT 1' at line 1
and for fal:
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Database\ConnectionPool;
class FalResourceViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* #author INGENIUMDESIGN
*/
public function initializeArguments() {
$this->registerArgument('uid', 'integer', 'enthaelt die UID des CE', TRUE);
}
/**
* #var mixed $uid
*/
public function render($uid = null) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file');
if($uid) {
$query = $queryBuilder
->select('*')
->from('sys_file')
->join('sys_file', 'sys_file_reference', 'MM',
$queryBuilder->expr()->andX(
$queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('MM.uid_foreign', $uid),
$queryBuilder->expr()->eq('MM.tablenames', '"pages"')
),
$queryBuilder->expr()->eq('MM.uid_local', 'sys_file.uid')
)
)
->setMaxResults(1);
//die($query->getSQL());
$result = $query->execute();
$res = [];
while ($row = $result->fetch()) {
$res[] = $row;
}
$this->templateVariableContainer->add('sysFileArray', $res);
}
}
}
Can anybody check those queryBuilder-statements?
Thanx in advance
EnzephaloN
Here's the solution:
FalResourceViewhelper
Just use the TYPO3-core-method $fileRepository->findByRelation(); This returns the page-related resources.
Use like this:
<e:falResource data="{page.data}" table="pages" field="media" as="sysFileArray">
<f:if condition="{sysFileArray.0.uid}!=0">
<f:image src="{sysFileArray.0.uid}" treatIdAsReference="1" class="img-responsive"/>
</f:if>
</e:falResouce>
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
/**
* FalViewHelper
*/
class FalResourceViewHelper extends AbstractViewHelper{
use CompileWithRenderStatic;
/**
* #var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments.
*
* #throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('data', 'array', 'Data of current record', true);
$this->registerArgument('table', 'string', 'table', false, 'tt_content');
$this->registerArgument('field', 'string', 'field', false, 'image');
$this->registerArgument('as', 'string', 'Name of variable to create', false, 'items');
}
/**
* #param array $arguments
* #param \Closure $renderChildrenClosure
* #param RenderingContextInterface $renderingContext
* #return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
$variableProvider = $renderingContext->getVariableProvider();
if (is_array($arguments['data']) && $arguments['data']['uid'] && $arguments['data'][$arguments['field']]) {
$fileRepository = GeneralUtility::makeInstance(FileRepository::class);
$items = $fileRepository->findByRelation(
$arguments['table'],
$arguments['field'],
$arguments['data']['uid']
);
$localizedId = null;
if (isset($arguments['data']['_LOCALIZED_UID'])) {
$localizedId = $arguments['data']['_LOCALIZED_UID'];
} elseif (isset($arguments['data']['_PAGES_OVERLAY_UID'])) {
$localizedId = $arguments['data']['_PAGES_OVERLAY_UID'];
}
$isTableLocalizable = (
!empty($GLOBALS['TCA'][$arguments['table']]['ctrl']['languageField'])
&& !empty($GLOBALS['TCA'][$arguments['table']]['ctrl']['transOrigPointerField'])
);
if ($isTableLocalizable && $localizedId !== null) {
$items = $fileRepository->findByRelation($arguments['table'], $arguments['field'], $localizedId);
}
} else {
$items = null;
}
$variableProvider->add($arguments['as'], $items);
$content = $renderChildrenClosure();
$variableProvider->remove($arguments['as']);
return $content;
}
}
It's easy.
--
SysCategoryViewHelper works like this:
<e:sysCategory data="{page.data}" as="sysCategoryDetailArray">
<f:if condition="{sysCategoryDetailArray.0}">
<i class="fa fa-4x {sysCategoryDetailArray.0.description}"></i>
</f:if>
</e:sysCategory>
And here is the code:
<?php
namespace EnzephaloN\ThemePsoa\ViewHelper;
use TYPO3\CMS\Core\Resource\FileRepository;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
use TYPO3\CMS\Core\Database\ConnectionPool;
class SysCategoryViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper {
use CompileWithRenderStatic;
/**
* #var bool
*/
protected $escapeOutput = false;
/**
* Initialize arguments.
*
* #throws \TYPO3Fluid\Fluid\Core\ViewHelper\Exception
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('data', 'array', 'Data of current record', true);
$this->registerArgument('as', 'string', 'Name of variable to create', false, 'items');
}
/**
* #param array $arguments
* #param \Closure $renderChildrenClosure
* #param RenderingContextInterface $renderingContext
* #return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) {
$variableProvider = $renderingContext->getVariableProvider();
if (is_array($arguments['data']) && $arguments['data']['uid']) {
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_category');
$queryBuilder->getRestrictions()
->removeAll();
$query = $queryBuilder
->select('*')
->from('sys_category')
->join('sys_category', 'sys_category_record_mm', 'MM', $queryBuilder->expr()->andX(
$queryBuilder->expr()->eq('MM.uid_foreign', $arguments['data']['uid']),
$queryBuilder->expr()->eq('MM.uid_local','sys_category.uid')));
$result = $query->execute();
$items = [];
while ($row = $result->fetch()) {
$items[] = $row;
}
} else {
$items = null;
}
$variableProvider->add($arguments['as'], $items);
$content = $renderChildrenClosure();
$variableProvider->remove($arguments['as']);
return $content;
}
}

Syntax Error - line 0, col 122: Error: Expected end of string, got 'ON'

I'm trying to use ON in my Query Builder but it returns [Syntax Error] line 0, col 122: Error: Expected end of string, got 'ON'.
Code:
public function filterChamados(Request $request)
{
$em = $this->getDoctrine()->getManager()->getRepository(Chamados::class)
->createQueryBuilder('c')->select('c.id, d.name_fantasy, c.status, c.titulo, c.description')
->join(Clients::class, 'd',Join::ON,'c.id_client = d.id');
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
};
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
};
if ($request->get('open_date')) {
$em->andWhere('c.open_date >=:open_date')
->setParameter('open_date', $request->get('open_date'));
}
if ($request->get('close_date')) {
$em->andWhere('c.close_date <=:close_date')
->setParameter('close_date', $request->get('close_date'));
}
$em->getQuery()->getArrayResult();
return new JsonResponse($em);
}
If I return its DQL, I get:
SELECT c.id, d.name_fantasy, c.status, c.titulo, c.description FROM App\Entity\Chamados c INNER JOIN App\Entity\Clients d ON c.id_client = d.id WHERE (d.name_fantasy=:client OR d.razao_social=:client)
If I run the SQL directly into PGAdmin, it works.
If I change ON to WITH, it does not return errors, but the result comes empty. Plus, I can't run its SQL directly into PGAdmin.
What am I doing wrong?
EDIT:
This is my raw SQL (considering I'm using all fields):
SELECT
c.id, d.name_fantasy, c. status, c.titulo, c.description
FROM
chamados c
JOIN
clients d
ON
c.id_client_id = d.id
WHERE
c.status = 2 --:status
AND
(d.name_fantasy = 'FARMÁCIA ALGUMA COISA' OR d.razao_social = 'FARMÁCIA ALGUMA COISA') -- :client
AND
c.open_date >= '2019-03-03 10:00' --:open_date
AND
c.close_date <= '2019-09-03 18:00' --:close_date
Entity Chamados:
/**
* #ORM\Entity(repositoryClass="App\Repository\ChamadosRepository")
*/
class Chamados
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $titulo;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Clients", inversedBy="chamados")
* #ORM\JoinColumn(nullable=false)
*/
private $id_client;
/**
* #ORM\Column(type="integer", options={"default" = 0})
*/
private $status;
/**
* #ORM\Column(type="text", nullable=true)
*/
private $description;
/**
* #ORM\ManyToMany(targetEntity="App\Entity\User", inversedBy="chamados")
*/
private $user;
/**
* #ORM\Column(type="datetime")
*/
private $open_date;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $update_date;
/**
* #ORM\Column(type="datetime", nullable=true)
*/
private $close_date;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Tramite", mappedBy="chamado")
*/
private $tramites;
public function __construct()
{
$this->user = new ArrayCollection();
$this->tramites = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getIdClient(): ?Clients
{
return $this->id_client;
}
public function setIdClient(?Clients $id_client): self
{
$this->id_client = $id_client;
return $this;
}
public function getStatus(): ?int
{
return $this->status;
}
public function setStatus(int $status): self
{
$this->status = $status;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(?string $description): self
{
$this->description = $description;
return $this;
}
/**
* #return Collection|User[]
*/
public function getUser(): Collection
{
return $this->user;
}
public function addUser(User $user): self
{
if (!$this->user->contains($user)) {
$this->user[] = $user;
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->user->contains($user)) {
$this->user->removeElement($user);
}
return $this;
}
public function getOpenDate(): ?DateTimeInterface
{
return $this->open_date;
}
public function setOpenDate(DateTimeInterface $open_date): self
{
$this->open_date = $open_date;
return $this;
}
public function getUpdateDate(): ?DateTimeInterface
{
return $this->update_date;
}
public function setUpdateDate(?DateTimeInterface $update_date): self
{
$this->update_date = $update_date;
return $this;
}
public function getCloseDate(): ?DateTimeInterface
{
return $this->close_date;
}
public function setCloseDate(?DateTimeInterface $close_date): self
{
$this->close_date = $close_date;
return $this;
}
/**
* #return mixed
*/
public function getTitulo()
{
return $this->titulo;
}
/**
* #param mixed $titulo
* #return Chamados
*/
public function setTitulo($titulo)
{
$this->titulo = $titulo;
return $this;
}
/**
* #return Collection|Tramite[]
*/
public function getTramites(): Collection
{
return $this->tramites;
}
public function addTramite(Tramite $tramite): self
{
if (!$this->tramites->contains($tramite)) {
$this->tramites[] = $tramite;
$tramite->setChamado($this);
}
return $this;
}
public function removeTramite(Tramite $tramite): self
{
if ($this->tramites->contains($tramite)) {
$this->tramites->removeElement($tramite);
// set the owning side to null (unless already changed)
if ($tramite->getChamado() === $this) {
$tramite->setChamado(null);
}
}
return $this;
}
}
Entity Clients:
/**
* #ORM\Entity(repositoryClass="App\Repository\ClientsRepository")
*/
class Clients
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name_fantasy;
/**
* #ORM\Column(type="string", length=255)
*/
private $razao_social;
/**
* #ORM\Column(type="string", length=128, nullable=true)
*/
private $contact_email;
/**
* #ORM\Column(type="string", length=16, nullable=true)
*/
private $contact_telephone;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Chamados", mappedBy="id_client")
*/
private $chamados;
/**
* #ORM\Column(type="boolean", options={"default"="true"})
*/
private $active;
public function __construct()
{
$this->chamados = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getNameFantasy(): ?string
{
return $this->name_fantasy;
}
public function setNameFantasy(string $name_fantasy): self
{
$this->name_fantasy = mb_convert_case($name_fantasy, MB_CASE_UPPER, 'UTF-8');
return $this;
}
public function getRazaoSocial(): ?string
{
return $this->razao_social;
}
public function setRazaoSocial(string $razao_social): self
{
$this->razao_social = mb_convert_case($razao_social, MB_CASE_UPPER, 'UTF-8');
return $this;
}
public function getContactEmail(): ?string
{
return $this->contact_email;
}
public function setContactEmail(?string $contact_email): self
{
$this->contact_email = $contact_email;
return $this;
}
public function getContactTelephone(): ?string
{
return $this->contact_telephone;
}
public function setContactTelephone(?string $contact_telephone): self
{
$this->contact_telephone = $contact_telephone;
return $this;
}
/**
* #return Collection|Chamados[]
*/
public function getChamados(): Collection
{
return $this->chamados;
}
public function addChamado(Chamados $chamado): self
{
if (!$this->chamados->contains($chamado)) {
$this->chamados[] = $chamado;
$chamado->setIdClient($this);
}
return $this;
}
public function removeChamado(Chamados $chamado): self
{
if ($this->chamados->contains($chamado)) {
$this->chamados->removeElement($chamado);
// set the owning side to null (unless already changed)
if ($chamado->getIdClient() === $this) {
$chamado->setIdClient(null);
}
}
return $this;
}
/**
* #return mixed
*/
public function getActive()
{
return $this->active;
}
/**
* #param mixed $active
* #return Clients
*/
public function setActive($active)
{
$this->active = $active;
return $this;
}
}
Edit 2:
The error is gone and the query is being built properly, but the result is empty.
Controller:
public function filterChamados(Request $request)
{
$em = $this->getDoctrine()->getManager()->getRepository(Chamados::class)
->createQueryBuilder('c')->select('c.id, d.name_fantasy, c.status, c.titulo, c.description')
->join('c.id_client', 'd');
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
}
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
}
if ($request->get('open_date')) {
$em->andWhere('c.open_date >=:open_date')
->setParameter('open_date', $request->get('open_date'));
}
if ($request->get('close_date')) {
$em->andWhere('c.close_date <=:close_date')
->setParameter('close_date', $request->get('close_date'));
}
$em->getQuery()->getArrayResult();
return new JsonResponse($em);
}
Generated query:
[2019-08-21 17:22:31] doctrine.DEBUG: SELECT c0_.id AS id_0, c1_.name_fantasy AS name_fantasy_1, c0_.status AS status_2, c0_.titulo AS titulo_3, c0_.description AS description_4 FROM chamados c0_ INNER JOIN clients c1_ ON c0_.id_client_id = c1_.id WHERE (c1_.name_fantasy = ? OR c1_.razao_social = ?) ["PADARIA","PADARIA"] []
PgAdmin3: If I put both values inside the query and replace " by ', it works, otherwise it returns column "PADARIA" does not exist.
Inside AJAX request: it returns an empty JSON.
For some reason you have a semicolon where it should not be, try the following function, not saying it will work though:
function filterChamados(Request $request)
{
$em = $this->getDoctrine()->getManager()->getRepository(Chamados::class)
->createQueryBuilder('c')->select('c.id, d.name_fantasy, c.status, c.titulo, c.description')
->join('c.Clients', 'd', Join::ON, 'c.id_client = d.id');
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
}
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
}
if ($request->get('open_date')) {
$em->andWhere('c.open_date >=:open_date')
->setParameter('open_date', $request->get('open_date'));
}
if ($request->get('close_date')) {
$em->andWhere('c.close_date <=:close_date')
->setParameter('close_date', $request->get('close_date'));
}
$em->getQuery()->getArrayResult();
return new JsonResponse($em);
}
Notice how I have removed the semicolon from the following pieces of code:
if ($request->request->get('status')) {
$em->where('c.status = :status')
->setParameter('status', $request->request->get('status'));
};
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('(d.name_fantasy=:client OR d.razao_social=:client)')
->setParameter('client', strtoupper(trim($request->get('client'))));
};
Also notice how I have change the JOIN:
->join('c.Clients', 'd', Join::ON, 'c.id_client = d.id');
UPDATE:
Change this:
if(strtoupper(trim($request->get('client')))) {
$client = strtoupper(trim($request->get('client')));
$em->andWhere('d.name_fantasy=:client')
->orWhere('d.razao_social=:client')
->setParameter('client', $client);
}
Or:
if (strtoupper(trim($request->get('client')))) {
$em->andWhere('d.name_fantasy=:client OR d.razao_social=:client')
->setParameter('client', strtoupper(trim($request->get('client'))));
};
More info here.

DI container can't find a class

I have an existing application with line below
\Yii::$container->invoke([$this, 'injections']);
and this line couses the error
ReflectionException Class Redis does not exist
I have a file Redis.php where defined class Redis in the /common/components directory.
But yii looks for it at the /common/components/myAPI/
А class that contains a line
\Yii::$container->invoke([$this, 'injections']);
ia located by the path /common/components/myAPI/
The whole class where I try to call the Redis
abstract class AEntity{
const API_BE_SOCCER_COUNTER = 'API_BE_SOCCER_COUNTER';
/**
* #var Fetcher $_fetcher
* #var boolean $_isFromCache
* #var APIConfig $_config
* #var string $_redisKey
* #var array $_params
*/
private $_fetcher,
$_isFromCache = null,
$_params = [],
$_redisKey = null,
$_mainApi;
/**
* #var APIRedisManager $_redis
*/
private $_redis,
$_config;
/**
* #var Array $_dbTable
* #var Array $_dbMap
*/
protected $_dbMap,
$_dbTable;
/**
*
* #return array
*/
protected function setParams(Array $params = []){
$this->_params = $params;
}
protected abstract function keyRelationShip();
protected abstract function getAttributes();
protected abstract function jsonArrayMap();
protected function setRedisKey($redisData){
$this->_redisKey = $redisData;
}
protected function mapArrays(){
$jsonArrayMap = $this->jsonArrayMap();
foreach ($jsonArrayMap as $arrayMap){
$mapPath = $arrayMap['path'] ? explode('.', $arrayMap['path']) : null;
$key = $arrayMap['key'];
$arr = $arrayMap['array'];
$assoc = $arrayMap['assoc'];
$tmpData = $this->_mainApi;
if($mapPath){
foreach($mapPath as $mapper) {
if(!isset($tmpData[$mapper])){
$this->{$key} = null;
return false;
}
$tmpData = $tmpData[$mapper];
}
}
$this->{$key} = $arr ? $this->jsonArrayMapper($tmpData, $assoc, $mapPath) : $tmpData;
}
}
public function injections(APIConfig $config, Fetcher $fetcher, APIRedisManager $redisManager){
$this->_config = $config;
$this->_fetcher = $fetcher;
$this->_redis = $redisManager;
}
protected function initialize(Array $params = []){
$constant = static::keyRelationShip();
$redisKey = $this->paramToRedis($params);
$this->setParams($params);
$this->setRedisKey($redisKey);
\Yii::$container->invoke([$this, 'injections']);
$this->_config->get($constant, $this->_params);
$this->_redis->setConfig($this->_config);
$this->_fetcher->setConfig($this->_config);
$this->_mainApi = $this->getAPIRequest();
$this->mapArrays();
}
/**
* #return array
*/
public function getMainApi(){
return $this->_mainApi;
}
/**
* #return APIRedisManager
*/
public function getRedis(){
return $this->_redis;
}
/**
* #return array
* #throws \Exception
*/
public function loadYiiData(){
$arrModel = [];
if (!$this->_dbTable) new Exception('No Table Specified.');
if (!$this->_dbMap) new Exception('No DB Map Specified.');
foreach ($this->_dbMap as $keyApi => $keyDB){
if(!isset($this->$keyDB)) throw new \Exception("KeyDB: $keyDB, is not Set");
$arrModel[$this->_dbTable][$keyApi] = $this->$keyDB;
}
return $arrModel;
}
/**
* GET API request logic
*
* #return array
*/
public function getAPIRequest(){
$redisKey = $this->formulateRedisKeyLogic();
$storedRequest = $this->_redis->getConfig() ? $this->_redis->get($redisKey) : null;
if(!$storedRequest){
$this->_isFromCache = false;
$apiRequestResult = $this->_fetcher->get()->asArray();
$this->_redis->incrCounter();
if($apiRequestResult && !$storedRequest){
$serializedApiRequest = serialize($apiRequestResult);
$this->_redis->store($serializedApiRequest, $redisKey);
}
}else{
$this->_isFromCache = true;
$apiRequestResult = unserialize($storedRequest);
}
return $apiRequestResult;
}
/** #return boolean */
public function isFromCache(){
return $this->_isFromCache;
}
private function formulateRedisKeyLogic(){
$config = $this->_redis->getConfig();
if(isset($config['key']) && strpos($this->_redisKey,'$.')!==false){
$configKey = $config['key'];
$redisKey = $configKey . $this->_redisKey;
$redisKey = str_replace('$.', '', $redisKey);
}
else{
$redisKey = $this->_redisKey;
}
return $redisKey;
}
protected function paramToRedis($param){
$className = (new \ReflectionClass($this))->getShortName();
$buildRedisKey = '$._'.str_replace('=', '_', http_build_query($param, null, ','));
$paramKey = $buildRedisKey.'_'.$className;
return $paramKey;
}
/**
* GET API request logic
*
* #return array
*/
protected function jsonArrayMapper(Array $entityItems, $assoc = false, $mapPath= true){
$aEntityArray = [];
$attributes = $this->getAttributes();
$Klass = static::class;
if($mapPath){
foreach ($entityItems as $entityItem){
$aEntity = new $Klass(false);
foreach ($attributes as $attribute){
$aEntity->{$attribute} = $entityItem[$attribute];
}
$assoc ? $aEntityArray[$entityItem[$assoc]] = $aEntity : $aEntityArray[] = $aEntity;
}
}else{
$aEntity = new $Klass(false);
foreach ($attributes as $attribute){
$aEntity->{$attribute} = $entityItems[$attribute];
}
$aEntityArray = $aEntity;
}
return $aEntityArray;
}
public function __set($key, $value){
$this->{$key} = $value;
}
public function __get($name) {
return $this->{$key};
}
}
This is a super class for class those have such constructor
public function __construct($fullInitizalization=true, $params = []) {
if($fullInitizalization){
$redisParams = $this->paramToRedis($params);
parent::initialize($params);
}
}
When DI container trying to instaniate APIRedisConnection class, it passes parameter with type Redis:
/** #param Redis $redis */
function __construct(Redis $redis){
$this->_redis = $redis;
}
Class Redis can't be found in the project, but I can see it in IDE and this class was written on PHP 7
Although the whole project written on PHP 5.6

SQL "VIEW" in codeigniter

I want to create an SQL view within the codeigniter model. What is the best way of doing this?
I use mutliple models depending on wich table i need to work
application/core/MY_model.php
<?php
/**
* CRUD Model
* A base model providing CRUD, pagination and validation.
*/
class MY_Model extends CI_Model
{
public $table;
public $primary_key;
public $default_limit = 15;
public $page_links;
public $query;
public $form_values = array();
protected $default_validation_rules = 'validation_rules';
protected $validation_rules;
public $validation_errors;
public $total_rows;
public $date_created_field;
public $date_modified_field;
public $native_methods = array(
'select', 'select_max', 'select_min', 'select_avg', 'select_sum', 'join',
'where', 'or_where', 'where_in', 'or_where_in', 'where_not_in', 'or_where_not_in',
'like', 'or_like', 'not_like', 'or_not_like', 'group_by', 'distinct', 'having',
'or_having', 'order_by', 'limit'
);
function __construct()
{
parent::__construct();
}
public function __call($name, $arguments)
{
call_user_func_array(array($this->db, $name), $arguments);
return $this;
}
/**
* Sets CI query object and automatically creates active record query
* based on methods in child model.
* $this->model_name->get()
*/
public function get($with = array(), $include_defaults = true)
{
if ($include_defaults) {
$this->set_defaults();
}
foreach ($with as $method) {
$this->$method();
}
$this->query = $this->db->get($this->table);
return $this;
}
/**
* Query builder which listens to methods in child model.
* #param type $exclude
*/
private function set_defaults($exclude = array())
{
$native_methods = $this->native_methods;
foreach ($exclude as $unset_method) {
unset($native_methods[array_search($unset_method, $native_methods)]);
}
foreach ($native_methods as $native_method) {
$native_method = 'default_' . $native_method;
if (method_exists($this, $native_method)) {
$this->$native_method();
}
}
}
/**
* Call when paginating results.
* $this->model_name->paginate()
*/
public function paginate($with = array())
{
$uri_segment = '';
$offset = 0;
$per_page = $this->default_limit;
$this->load->helper('url');
$this->load->library('pagination');
$this->set_defaults();
foreach ($with as $method) {
$this->$method();
}
$this->total_rows = $this->db->count_all_results($this->table);
$uri_segments = $this->uri->segment_array();
foreach ($uri_segments as $key => $segment) {
if ($segment == 'page') {
$uri_segment = $key + 1;
if (isset($uri_segments[$uri_segment])) {
$offset = $uri_segments[$uri_segment];
}
unset($uri_segments[$key], $uri_segments[$key + 1]);
$base_url = site_url(implode('/', $uri_segments) . '/page/');
}
}
if (!$uri_segment) {
$base_url = site_url($this->uri->uri_string() . '/page/');
}
$config = array(
'base_url' => $base_url,
'uri_segment' => $uri_segment,
'total_rows' => $this->total_rows,
'per_page' => $per_page
);
if ($this->config->item('pagination_style')) {
$config = array_merge($config, $this->config->item('pagination_style'));
}
$this->pagination->initialize($config);
$this->page_links = $this->pagination->create_links();
/**
* Done with pagination, now on to the paged results
*/
$this->set_defaults();
foreach ($with as $method) {
$this->$method();
}
$this->db->limit($per_page, $offset);
$this->query = $this->db->get($this->table);
return $this;
}
function paginate_api($limit, $offset)
{
$this->set_defaults();
if (empty($limit)) {
$limit = $this->default_limit;
}
if (empty($offset)) {
$offset = 0;
}
$this->db->limit($limit, $offset);
return $this->db->get($this->table)->result();
}
/**
* Retrieves a single record based on primary key value.
*/
public function get_by_id($id, $with = array())
{
foreach ($with as $method) {
$this->$method();
}
return $this->where($this->primary_key, $id)->get()->row();
}
public function save($id = NULL, $db_array = NULL)
{
if (!$db_array) {
$db_array = $this->db_array();
}
if (!$id) {
if ($this->date_created_field) {
$db_array[$this->date_created_field] = time();
}
$this->db->insert($this->table, $db_array);
// $this->session->set_flashdata('alert_success', 'Record successfully created.');
return $this->db->insert_id();
} else {
if ($this->date_modified_field) {
$db_array[$this->date_modified_field] = time();
}
$this->db->where($this->primary_key, $id);
$this->db->update($this->table, $db_array);
// $this->session->set_flashdata('alert_success', 'Record successfully updated.');
return $id;
}
}
/**
* Returns an array based on $_POST input matching the ruleset used to
* validate the form submission.
*/
public function db_array()
{
$db_array = array();
$validation_rules = $this->{$this->validation_rules}();
foreach ($this->input->post() as $key => $value) {
if (array_key_exists($key, $validation_rules)) {
$db_array[$key] = $value;
}
}
return $db_array;
}
/**
* Deletes a record based on primary key value.
* $this->model_name->delete(5);
*/
public function delete($id, $others = array())
{
if (!empty($others)) {
foreach ($others as $k => $v) {
$this->db->where($k, $v);
}
} else {
$this->db->where($this->primary_key, $id);
}
return $this->db->delete($this->table);
// $this->session->set_flashdata('alert_success', 'Record successfully deleted.');
}
/**
* Returns the CI query result object.
* $this->model_name->get()->result();
*/
public function result()
{
return $this->query->result();
}
/**
* Returns the CI query row object.
* $this->model_name->get()->row();
*/
public function row()
{
return $this->query->row();
}
/**
* Returns CI query result array.
* $this->model_name->get()->result_array();
*/
public function result_array()
{
return $this->query->result_array();
}
/**
* Returns CI query row array.
* $this->model_name->get()->row_array();
*/
public function row_array()
{
return $this->query->row_array();
}
/**
* Returns CI query num_rows().
* $this->model_name->get()->num_rows();
*/
public function num_rows()
{
return $this->query->num_rows();
}
/**
* Used to retrieve record by ID and populate $this->form_values.
* #param int $id
*/
public function prep_form($id = NULL)
{
if (!$_POST and ($id)) {
$this->db->where($this->primary_key, $id);
$row = $this->db->get($this->table)->row();
foreach ($row as $key => $value) {
$this->form_values[$key] = $value;
}
}
}
/**
* Performs validation on submitted form. By default, looks for method in
* child model called validation_rules, but can be forced to run validation
* on any method in child model which returns array of validation rules.
* #param string $validation_rules
* #return boolean
*/
public function run_validation($validation_rules = NULL)
{
if (!$validation_rules) {
$validation_rules = $this->default_validation_rules;
}
foreach (array_keys($_POST) as $key) {
$this->form_values[$key] = $this->input->post($key);
}
if (method_exists($this, $validation_rules)) {
$this->validation_rules = $validation_rules;
$this->load->library('form_validation');
$this->form_validation->set_rules($this->$validation_rules());
$run = $this->form_validation->run();
$this->validation_errors = validation_errors();
return $run;
}
}
/**
* Returns the assigned form value to a form input element.
* #param type $key
* #return type
*/
public function form_value($key)
{
return (isset($this->form_values[$key])) ? $this->form_values[$key] : '';
}
}
then when i need a model for a specific database i use class inside models
models/content.php
class content_types extends MY_Model
{
function __construct()
{
parent::__construct();
$this->curentuserdata = $this->session->userdata('lg_result');
$this->userprofile = $this->session->userdata('user_profile');
}
public $table = 'content_types';
public $primary_key = 'id';
public $default_limit = 50;
public function default_order_by()
{
$this->db->order_by('id asc');
}
}
then where i need to call the model
$this->modelname->save($id,array());
$this->modelname->where()->get()->row();
so create one for the 'view table' and the others for insert tables