I have entity from form framework.
public function editAction($id)
{
$request = $this->getRequest();
$r = $this->getProfileRepository();
$profile = $id ? $r->find($id) :
new \Alden\BonBundle\Entity\Profile();
/* #var $profile \Alden\BonBundle\Entity\Profile */
$form = $this->createForm(
new \Alden\BonBundle\Form\Type\ProfileType(),
$profile);
if ($request->getMethod() == 'POST')
{
$form->bindRequest($request);
if ($form->isValid())
{
...
I need to convert $profile into array. In class Profile all properties are defined as private so I can't iterate like foreach($profile as $key => $value) {...}
You can use Reflection to retrieve class properties. Then, use a PropertyPath to retrieve properties values.
Here is an example:
$reflectedClass = new \ReflectionClass($yourClass);
$objectProperties = $reflectedClass->getProperties();
$datas = array();
foreach ($objectProperties as $objectProperty) {
$property = $objectProperty->getName();
$path = new PropertyPath($property);
$datas[] = $path->getValue($object);
}
But, if your form / entity is simple, you can just create a dedicated method in entity to return the right array.
Related
I'm new with symfony and I'm trying to view data from one of my tables with random order and a limit of 4. I tried doing it in the repository but RAND() is not working so I'm trying in the controller.
The error is the following one:
"Warning: array_rand() expects parameter 1 to be array, object given"
And I don't understand why, when in the $response I set the data into an array.
This is my actual code:
/**
* #Route("/ws/random/superviviente", name="ws_random_survi")
*/
public function randomSurvi(Request $request): Response
{
$data = $request->request->all();
$entityManager = $this->getDoctrine()->getManager();
$randomPerks = $entityManager->getRepository(Perks::class)
->getRandomPerks();
$response = new JsonResponse();
$response -> setStatusCode(200);
$response -> setData(array('random perk' => $randomPerks));
$resultRandom = array_rand($response);
return $resultRandom;
}
You are trying to use array_rand on a doctrine array collection.
You could either convert it as array and back to a doctrine array :
use Doctrine\Common\Collections\ArrayCollection;
public function randomSurvi(Request $request): Response
{
$data = $request->request->all();
$entityManager = $this->getDoctrine()->getManager();
$randomPerks = $entityManager->getRepository(Perks::class)
->getRandomPerks();
$resultRandom = new ArrayCollection(array_rand($randomPerks->toArray()));
return new JsonResponse($resultRandom);
}
Otherwise it would work with shuffle :
$randomPerks = $entityManager->getRepository(Perks::class)->getRandomPerks();
$randomPerks = shuffle($randomPerks);
Or get random perks directly through your method in your repository.
See example from #Krzysztof Trzos:
public function getRandomProducts($amount = 7)
{
return $this->getRandomProductsNativeQuery($amount)->getResult();
}
/**
* #param int $amount
* #return ORM\NativeQuery
*/
public function getRandomProductsNativeQuery($amount = 7)
{
# set entity name
$table = $this->getClassMetadata()
->getTableName();
# create rsm object
$rsm = new ORM\Query\ResultSetMapping();
$rsm->addEntityResult($this->getEntityName(), 'p');
$rsm->addFieldResult('p', 'id', 'id');
# make query
return $this->getEntityManager()->createNativeQuery("
SELECT p.id FROM {$table} p ORDER BY RAND() LIMIT 0, {$amount}
", $rsm);
}
You could write your own query to achieve this, so create a new method inside the repository like so:
public function getRandomPerks(int $limit): array
{
$queryBuilder = $this->createQueryBuilder('p');
return $queryBuilder
->setMaxResults($limit)
->orderBy('RAND()')
->getQuery()
->getResult();
}
Then in your controller all you would to do is call the method and pass a limit:
$randomPerks = $entityManager->getRepository(Perks::class)
->getRandomPerks(4);
i'm using a event listener on the submit of a form where, i need to catch a xml file, open it and extract his contents, put it on an entity and add that to a collection from other entity.
right now this is works:
$builder->addEventListener(FormEvents::SUBMIT, function(FormEvent $event){
$entity = $event->getData();
if($entity){
$parent = $event->getForm()->getParent()->getData();
$gpx = $entity['gpx'];
if($gpx){
$xmlGpx = simplexml_load_file($gpx);
foreach ($xmlGpx->wpt as $pt) {
$point = new MonitoringPoint();
$point->setPoint(new \CrEOF\Spatial\PHP\Types\Geometry\Point((string) $pt['lat'], (string) $pt['lon']));
$point->setAltitude((float) $pt->ele);
$point->setDate(($pt->time->count() ? new \DateTime((string)$pt->time) : null ));
$point->setAccuracy((float) $pt->hdop);
$parent->addMonitoringPoint($point);
}
$fileName = $gpx->getClientOriginalName();
$directory = __DIR__.'/../../../../web/uploads/';
$date = new \DateTime();
$newFileName = md5($gpx->getClientOriginalName().$date->getTimestamp());
$gpx->move($directory, $fileName);
$fs = new Filesystem();
$fs->rename($directory.$fileName, $directory.$newFileName.'.gpx');
$parent->setGpx($newFileName.'.gpx');
}
}
});
$parent is an instance of Monitoring, if i open $parent i will see that the $point vars has been added on the collection monitoringPoints of the variable, and the gpx too.
but then i go so see the entity right before been persisted, inside newAction
$entity = new Monitoring($params);
$form = $this->createForm(new MonitoringType(), $entity, array(
'action' => $this->generateUrl('my_route'),
'method' => 'POST',
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
dump($entity);die;
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
}
and the collection is empty! but the gpx attribute contains the right value.
does the collection gets reseted?
i had to pass the points in to an array within the session, still think that was not the best option, but worked
$array = [];
foreach ($xmlGpx->wpt as $pt) {
$point = new MonitoringPoint();
$point->setPoint(new \CrEOF\Spatial\PHP\Types\Geometry\Point((string) $pt['lat'], (string) $pt['lon']));
$point->setAltitude((float) $pt->ele);
$point->setDate(($pt->time->count() ? new \DateTime((string)$pt->time) : null ));
$point->setAccuracy((float) $pt->hdop);
$point->setMonitoring($parent);
array_push($array, $point);
}
$session = new Session();
$session->getFlashBag()->add('array', $array);
in the newAction:
$em = $this->getDoctrine()->getManager();
$session = new Session();
$array = $session->getFlashBag()->get('array');
foreach($array[0] as $point) {
$point->setMonitoring($entity);
$entity->addMonitoringPoint($point);
}
$em->persist($entity);
$em->flush();
dont know why the array got reseted when it comes to the controller, cause i had setted the points in the entity during the submit
I'm building an API using FOSRestBundle in Symfony2 and I'm trying to remove the entity associations from an entity with no luck, to minimize the JSON data sent in the API response.
public function helperRemoveAssociations($entities) {
$em = $this->getEntityManager();
$data = array();
/** #var WBEntity $entity */
foreach ($entities as $entity) {
$entityAssociations = $entity->getAssociationNames($em); // ex: array('category', 'comments')
foreach ($entityAssociations as $associationName) {
$associationGetter = 'get' . ucfirst($associationName);
$associationSetter = 'set' . ucfirst($associationName);
/** #var WBEntity $associationObject */
$associationObject = $entity->$associationGetter();
$associationId = $associationObject->getEntityId($em); // ex: 51
$entity->$associationSetter($associationId); // I am not allowed to write an integer
}
$data[] = $entity;
}
return $data;
}
How can I accomplish this, replacing the associated entities with their respective ids.
I have learnt Symfony2 since several months.
I have created a service. When I use it in a simple controller, I have no problem. When I use it in my controller that manages my entity, I have a problem.
My service is:
<?php
namespace Cours\BlogBundle\Services;
class Service1
{
public function creerSlug($texte)
{
$texte = transliterator_transliterate("Latin-ASCII; [:Punctuation:] Remove; Lower();", $texte);
$texte = preg_replace('/[-\s]+/', '-', $texte);
$texte = trim($texte, '-');
return $texte;
}
}
My simple controller is:
<?php
namespace Cours\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Cours\BlogBundle\Services\Service1;
class TestController extends Controller
{
public function indexAction()
{
$texte = "Le test du slug";
$service1 = $this->container->get('service1');
$texte = $service1->creerSlug($texte);
return $this->render('CoursBlogBundle:Test:index.html.twig', array('texte' => $texte));
}
}
The action of my controller that manages my entity is:
public function ajouterAction(Request $request)
{
$rubrique = new Rubrique();
$form = $this->createForm(new RubriqueType(), $rubrique);
if ($request->isMethod('POST'))
{
$form->handleRequest($request);
if ($form->isValid())
{
$manager = $this->getDoctrine()->getManager();
$rubrique = $form->getData();
$texte = $rubrique->getTexte();
$service1 = $this->container->get('service1');
$slug = $serviceSlug->creerSlug($texte);
$slug = $rubrique->setSlug($slug);
$manager->persist($rubrique);
$manager->flush();
return $this->redirect($this->generateUrl('cours_blog_accueil'));
}
}
return $this->render('CoursBlogBundle:Rubrique:ajouter.html.twig', array('form' => $form->createView()));
}
My view tells me that my slug can’t be empty.
I think there is a mistake in my action but I can’t find it.
Does anyone help me?
KISSES AND THANK YOU VERY MUCH
change
$service1 = $this->container->get('service1');
$slug = $serviceSlug->creerSlug($texte);
to
$serviceSlug = $this->container->get('service1');
$slug = $serviceSlug->creerSlug($texte);
I suggest to comment/remove $rubrique = $form->getData(); $texte = $rubrique->getTexte(); from ajouterAction and set the text manually (just for testing purpose):
if ($form->isValid())
{
$manager = $this->getDoctrine()->getManager();
// $rubrique = $form->getData();
// $texte = $rubrique->getTexte();
$rubrique->setTexte('Some text');
$service1 = $this->get('service1');
$slug = $service1->creerSlug($rubrique->getTexte());
...
if it works, you can set some validations to the texte field in your form type which prevents entering an invalid value.
Also I suggest to use some libraries (Cocur/Slugify can be a good option) instead of handling the process by yourself.
I'm using symfony2 and createForm to get the http post data. After witch I do:
$Data = (array) $form->getData();
And I get:
array (size=1)
'�Far\MT\AccountBundle\Entity\Movement�toAccount' => int 3
I don't think this is the normal behavior for these cases, any sugestions?
the toAccount should be the complete index name.
Wasn't able to reproduce the conditions in a test case for the cli:
<?php
namespace A;
class MyClass
{
public $id;
public $name;
public $age;
}
$object = new MyClass();
$object->name = "Andre";
$object->id = 1;
$object->age = 30;
var_dump($object);
$Ar = (array) $object;
var_dump($Ar)
This above worked ok.
I used this solution:
//comment
$Data = $form->getData();
$obj = new \ReflectionObject($Data);
$props = $obj->getProperties();
$propname = array();
foreach ($props as $prop) {
$tmp = "get".ucfirst($prop->name);
if (($res = $Data->$tmp() )!== null) {
$propname[$prop->name] = $res;
}
}
$tmpSearch = $propname;
I'll clean it up after.
You can use the Symfony normalizer class, as your propose will fail when you have fields in your form name with underscore like 'facility_id' but your setter is called facilityId
<?php
$data = $form->getData();
$normalizers = new \Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer();
$norm = $normalizers->normalize($data);
print_r($norm);
you'll get output like
Array ( [fullname] => fullnameVal [email] => emaile#lkjl.com [phoneNumber] => 5554444 [facilityId] => 123132 )