I am working in Symfony2. I have a field in table that uses LONGBLOB. So now I want to display field data.When I display this LONGBLOB field data it show's me text like this
Resource id #404 but actually in field I have stored the dummy text.
This is my defaultcontrolle file code
DefaultController.php
function video_showAction($id)
{
$em = $this->getDoctrine()->getManager();
$video = $em->getRepository('MyBundle:Video')->find($id);
return $this->render('MyBundle:Default:VideoShow.html.twig', array('qShow' => $video ));
}
VideoShow.html.twig
Description: {{ qShow.description }}
// it will display "Resource id #404"
How can I display the actual data not he Refrence.
As you mentioned in your own answer, you should rewrite your getter function.
I propose something like that:
private $descriptionAsText = null;
public function getDescription()
{
if (is_null($this->descriptionAsText))
{
$this->descriptionAsText = stream_get_contents($this->description);
}
return $this->descriptionAsText;
}
If your stream can change in the same instance of the entity, you can eventually use:
public function getDescription()
{
rewind($this->description);
return stream_get_contents($this->description);
}
I dislike your current method, as if you need to use {{ qShow.description }} twice or more, you will get troubles because of your stream offset.
You need to rewind your resource each time you're doing a stream_get_contents, because it places the offset at the end of your stream (or at the specified length).
You can reproduce this behavior using the following code:
<?php
file_put_contents("/tmp/test.txt", "Hello, world!");
$handle = fopen("/tmp/test.txt", "r");
$contents = stream_get_contents($handle);
echo "Contents A = {$contents}\n"; // Contents A = Hello, world!
$contents = stream_get_contents($handle);
echo "Contents B = {$contents}\n"; // Contents B =
fclose($handle);
This behaviour is there since PHP 5.3 (I guess), so if you try this code on Codepad (who uses 5.2.5), you will not reproduce.
I have found the Solution.
I just need to use stream_get_contents. So I have put this into Getter method of my Entity.
Like this
MyEntity.php
// Getter Function need to be change like this
public function getDescription()
{
if ($this->description != '')
return stream_get_contents($this->description);
return $this->description;
}
Now When I display the content it shows me the Actual Data that the Recourse Id contains.
For using LONGBLOB firs you need do the following works. this works are describe in detail at the following link please check that you do all of them and then try again to show your qShow.description on your twig file. I think "Resource id #404" error say you that you have problem reading your resource with 404 ID Number.
http://symfony2.ylly.fr/add-new-data-type-in-doctrine-2-in-symfony-2-jordscream/
Related
I'm trying to create Doctrine SQLFilter. I need to filter for "deleted" field. But i want to make filter works with both (true and false) values too.
Something like this:
<?php
namespace Rem\CostsBundle\Doctrine;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\Filter\SQLFilter;
class ItemDeletedFilter extends SQLFilter
{
public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
{
if ($targetEntity->getReflectionClass()->name != 'Rem\CostsBundle\Entity\Item') {
return '';
}
$fdata = $this->getParameter('deleted');
$filter = '1<>1';
foreach ($fdata as $param) {
$filter .= sprintf('OR %s.deleted = %s', $targetTableAlias, $param);
}
return $filter;
}
}
But when I'm trying to set array of posible filter values in controller
$filters
->enable('costs_item_deleted')
->setParameter('deleted', [true, false]);
I get an error 500
Warning: PDO::quote() expects parameter 1 to be string, array given
This is clear situation. But, after all HOW to send array of params to my SQL filter?
UPD after Dmitry answer: This is not actualy what I wanted. Let say: what if I wanted to filter by few values of field? For records of 2015 and 2016 years for example... So i need to set some sort of array-of-years in ->setParameter. But it want only strings! And sends an error when i'm trying to set something else.
How do you solve this?
Or even more complicated example. What if I need to filter by relational field. In this case I need to set entity as param of filter. Or even ArrayCollection of entities!
For now I'm decide it like this: I json_encode array before set it to setParameter in controller. And then I json_decode it in Filter class. BUT! There in Filter class I need to make one more step. I need to remove single and doublequotes from json string. Because they was added by setParameter to escape string (thats why we love it )) ).
Code hacks like this we call "crutches" here in Russia. So I'd like to avoid of them and write more elegant code )
Make it IN instead of comparing.
foreach ($fdata as $param) {
$filter .= sprintf('OR %s.deleted IN (%s)', $targetTableAlias, param);
}
I have an old SS2.4 site which I have updated to SS3.1.13. The only part of the old site I can't get working is a search form that filters DataObjects. The old code is:
public function doCollectionSearch($data, $form)
{
$filters = array();
...
//setup some filters based on user selections
...
$where = implode(" AND ", $filters);
if(!isset($_REQUEST['start'])) $_REQUEST['start'] = 0;
$limit = $_REQUEST['start'].",50";
return $this->customise(array(
'Collections' => DataObject::get("Collection", $where, "Genus, Species ASC", null, $limit)
))->renderWith(array('Collection_results','Page'));
}
I have updated the last part to:
return $this->customise(array(
'Collections' => Collection::get()->where($where)->sort("Genus, Species ASC")->limit($limit)
))->renderWith(array('Collection_results','Page'));
But I get a "the method 'fortemplate' does not exist on 'CollectionPage_Controller'".
I know the $where is not right yet, but if I strip that out I still get an error..
I know I am missing something obvious...can anyone suggest a fix?
You'll get that error if your template accesses a method or database field that returns an object that can't be reduced to a string. This often happens when you have a related object (say a parent page) and you do something like the following:
<p>My parent is: $Parent</p>
Instead of
<p>My parent is: $Parent.Title</p>
The same thing existed in 2.4 so this doesn't totally explain your problem, but I'd look for something like the above scenario in your templates.
I am trying to remove galleryhasmedia from gallery.
However gallery entity doesn't have removegalleryhasmedia or something.
so I did a clumsy way, but it doesnt work.
$em = $this->getDoctrine()->getManager();
$firstGhmArray = $gallery->getGalleryHasMedias();
echo count($gallery->getGalleryHasMedias()) // before count
$afterGhmArray = array();
foreach ($firstGhmArray as $ghm){
if ($ghm->getId() == $id){ // id is the target id to delete
//delete
}
else {
array_push($afterGhmArray , $ghm);
}
$gallery->setGalleryHasMedias($afterGhmArray);
}
echo count($gallery->getGalleryHasMedias()) // after count
$em->persist($gallery);
$em->flush();
I think if galleryHasMedias are normal array collection.
I can delete the element with this procedure.
I need to do something more for galleryhasmedia??
You can override the Gallery entity and add this function to it :
public function clearGalleryHasMedias()
{
$this->galleryHasMedias->clear();
}
galleryHasMedias field is an ArrayCollection which can be cleared using the clear method. Its weird tho that setting an empty array doesn't clear work but i guess my solution is worth the shot.
Let's say I have a main form (foo entity form) where I have an embedded form (bar entity embedded form).
Let's also say that foo - 1/many - bar (of course).
Now, I want to display all possible bar entities in the system, even if they aren't associated with foo. So before bind form with foo entity, I usually do some query, extract data and, if bar isn't already associated with foo, associate it (basically i create some "virtual" association that haven't to be persisted under certain circumstance. I can't use symfony2 native method as I need to handle some attributes and Symfony2 don't let me do that)
All works like a charm. Now I added to bar form a non-mapped field that should help me to know whenever to save or not the association.
Into controller I check for the presence of this field and if not, I artificially unset the index of the collection from request object. When I dump the request all is good (embedded elements without flag aren't there anymore).
BUT
When I bind request object to entity, all embedded form elements are still there. This is driving me totally cray.
Code example
(I will not paste entity code as the issue is not there. I will not paste form code also)
public function createAction()
{
$foo = new Foo();
$foo_form = $this->createForm(new FooType(), $foo);
if ($request->getMethod() == 'POST') {
$parameter_array = $request->request->all();
$bar_array = $parameter_array['foo']['bar'];
//If I dump here, of course, all bar are setted
foreach ($bar_array as $index => $bar) {
if (!isset($bar['associate'])) { //this is the flag
unset($parameter_array['foo']['bar'][$index]);
}
}
$request->request->replace($parameter_array);
//If i dump $request->request->all(); all non-flagged bar are gone
$foo_form->bind($request);
$foo->getBars(); //If I dump this all bar(s) are still there (even the not-flagged ones)
}
}
I've found a workaround. As I can't controller - or at least it seems I cannot - directly parameter bag when entities are involved, I've simply act upon object after form and object are binded.
My code is now this
public function createAction()
{
$foo = new Foo();
$foo_form = $this->createForm(new FooType(), $foo);
if ($request->getMethod() == 'POST') {
$foo_form->bind($request);
if ($foo_form->isValid()) {
$parameter_array = $request->request->all();
if (isset($parameter_array['foo']['bar'])) {
$bars = $foo->getBars();
$bar_array = $parameter_array['foo']['bar'];
foreach ($bar_array as $index => $bar) { //Of course here
if (!isset($bar['associate'])) { // I can use array_filter
$bars->remove($index); // or something similar. Is just more readable that way for this answer
}
}
$foo->setBars($bars);
}
}
}
}
Is there a better solution?
I have been looking for hours for a way of setting a condition on the list of items that an APYDataGridBundle grid should return but could not find an answer.
Is there a way to set a DQL Query and pass it to the grid to display the exact query results I want to fetch?
This is the code:
public function filteredlistAction(){
// Create simple grid based on the entity
$source = new Entity('ACMEBundle:MyEntity');
// Get a grid instance
$grid = $this->get('grid');
// Attach the source to the grid
$grid->setSource($source);
...
...
**$grid->getColumns()->getColumnById('myentity_filter_column')->setData('the exact value I tried to match');**
// Manage the grid redirection, exports and the response of the controller
return $grid->getGridResponse('ACMEBundle:MyEntity:index_filteredlist.html.twig');
}
You can add a callback (closure or callable) to run before QueryBuilder execution - its done like this :
$source->manipulateQuery(
function ($query)
{
$query->resetDQLPart('orderBy');
}
);
$grid->setSource($source);
$query is an instance of QueryBuilder so you can change whatever you need to
Example taken from docs here
A more "complicated" query.
$estaActivo = 'ACTIVO';
$tableAlias = $source->getTableAlias();
$source->manipulateQuery(
function ($query) use ($tableAlias, $estaActivo)
{
$query->andWhere($tableAlias . '.estado = :estaActivo')
->andWhere($tableAlias . '.tipoUsuario IN (:rol)')
->setParameter('estaActivo', $estaActivo)
->setParameter('rol', array('VENDEDOR','SUPERVISOR'), \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
}
);
Cheers!