Doctrine get accessor for entities - symfony

Is there anyway to access the data of my entity without to use a specific accessor to my column value. Is there any generic accessor? See example:
$em = $this->getDoctrine()->getManager();
$data = $em->getRepository('EgBundle:Table')->findAll()
foreach($data as $row) {
var_dump($row->get('col1')); // I would like to do this
var_dump($row->getCol1()); // instead of this
$col = 'getCol1'; var_dump($row->$col()); // this is my temporary solution
}

You might be able to make use of the symfony2 PropertyAccessor component.
Docs here: http://symfony.com/doc/current/components/property_access/introduction.html
Example:
$accessor = PropertyAccess::createPropertyAccessor();
$accessor->getValue($row, 'col1');

You can get an array if you use DQL
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery('SELECT table FROM EgBundle\Entity\Table table');
$data = $query->getQuery()->getArrayResult();
foreach ($data as $row) {
var_dump($data['col1']);
}

No, not without adding support for that with userland code. You can add something like:
public function get($property) {
return $this->$property;
}

Related

ParamConverter: inject curent user in Repository

In a view, I want to display linked values, but all of the linked values can't be displayed because they depends to the user access.
To do that I just need to do a leftJoin with a ->where('user', $user). The question is... how can I inject the current user in the Repository from the ParamConverter ?
Assuming you are using Doctrine, this should work;
In your controller;
$objRepo = $this->getDoctrine()->getManager()->getRepository('AppBundle:Objects');
$files = $this->objRepo->getAllForUserId($this->getUser()->getId());
And in your repo file;
public function getAllForUserId($user_id, $limit=100)
{
if (null === $user_id) {
throw new ORMInvalidArgumentException('User id not set');
}
$queryBuilder = $this->createQueryBuilder('obj');
$queryBuilder->select(array('obj', 'usr'))
->innerJoin('obj.users', 'usr')
->where('usr.id = :user_id')
->setParameter(':user_id', $user_id)
->orderBy('file.created', Criteria::DESC);
$query = $queryBuilder->getQuery();
return $query->getResult();
}

Persist multiple entities in symfony2

I cannot persist multiple entities inside the controller. I can only save the last one.
My code:
$product = new Product();
$names = ['yellow', 'blue', 'red']; // save these to the table
foreach ($name as $name) {
$product->setName($name);
$em->persist($product);
// $em->flush(); // doesn't work either
}
$em->flush();
I am using Symfony 2.7
You have to create a new Product inside your loop.
Right now it's only taking 1 product, and it's constantly updating that one.
$names = ['yellow', 'blue', 'red']; // save these to the table
foreach ($names as $name) {
$product = new Product();
$product->setName($name);
$em->persist($product);
}
$em->flush();
I created this solution which looks nice:
array_walk($arrayOfEntities, function ($entity) {
$entityManager->persist($entity);
});
Use clone operator (php 5+)
$product = new Product();
$names = ['yellow', 'blue', 'red'];
foreach ($names as $name) {
$tmpProductObj = clone $product;
$em->persist($tmpProductObj);
}
$em->flush();
More information about cloning an object can be found here
You are only creating one Object Product.
Obviously, only one object will be persisted to the database then.
Also at the top your variable is called $Product(capital P) while in the loop it is called $product.
Try this instead:
$NameList = array("yellow","blue","red"); // save these to the table
foreach($NameList as $name){
$product = new Product();
$product->setName($name);
$em->persist($Product);
//$em->flush(); // doesnot work either
}
$em->flush();
If I want add multiple objects after set its value I use clone in loop:
$application = new Application();
$application->setSomething($someting);
for ($i = 1; $i <= $request->get('number_of_applications'); $i++){
$applicationObj = clone $application;
$em->persist($applicationObj);
}
$em->flush();

Symfony call get by Name from variable

I would like to call a getter with the stored fieldname from the database.
For example, there are some fieldnames store like ['id','email','name'].
$array=Array('id','email','name');
Normally, I will call ->getId() or ->getEmail()....
In this case, I have no chance to handle things like this. Is there any possibility to get the variable as part of the get Command like...
foreach ($array as $item){
$value[]=$repository->get$item();
}
Can I use the magic Method in someway? this is a bit confusing....
Symfony offers a special PropertyAccessor you could use:
use Symfony\Component\PropertyAccess\PropertyAccess;
$accessor = PropertyAccess::createPropertyAccessor();
class Person
{
private $firstName = 'Wouter';
public function getFirstName()
{
return $this->firstName;
}
}
$person = new Person();
var_dump($accessor->getValue($person, 'first_name')); // 'Wouter'
http://symfony.com/doc/current/components/property_access/introduction.html#using-getters
You can do it like this :
// For example, to get getId()
$reflectionMethod = new ReflectionMethod('AppBundle\Entity\YourEntity','get'.$soft[0]);
$i[] = $reflectionMethod->invoke($yourObject);
With $yourObject being the object of which you want to get the id from.
EDIT : Don't forget the use to add :
use ReflectionMethod;
Hope this helps.
<?php
// You can get Getter method like this
use Doctrine\Common\Inflector\Inflector;
$array = ['id', 'email', 'name'];
$value = [];
foreach ($array as $item){
$method = Inflector::classify('get_'.$item);
// Call it
if (method_exists($repository, $method))
$value[] = $repository->$method();
}

Symfony2 Doctrine Raw SQL Stored Procedure Loop through multiple result sets

I have managed to execute raw SQL (ie no ResultSetMapping) and can call and execute an MSSQL Stored Procedure.
The code I have is as follows:
$em = $this->get('doctrine')->getManager();
$stmt = $em
->getConnection()
->prepare('EXEC someSP :id,null,:uid');
$stmt->bindValue('id', '629674');
$stmt->bindValue('uid', '217');
$stmt->execute();
$results = $stmt->fetchAll();
No that works fine; however the issue i have is if the SP returns more than one result set the above only returns the first result set. Is there any way to loop through and get each result set?
I had to deal with the similar issue and this is what I came up with. This function is from the class that extends Doctrine\ORM\EntityRepository so I have access to the _em property in general case you can use $this->get('doctrine')->getManager(); to get entity manager.
protected function execMultiSetQuery($query, $params, $connection = 'default') {
// Init
$conn = $this->_em
->getConnection($connection)
->getWrappedConnection();
// Processing
if ($conn instanceof \Doctrine\DBAL\Driver\PDOConnection) {
$stmt = $conn->prepare($query);
$stmt->execute($params);
// Loop through the row sets
$results = array();
do {
try {
$results[] = $stmt->fetch(\PDO::FETCH_ASSOC);
}
catch (\Exception $e) {}
} while($stmt->nextRowset());
$stmt->closeCursor(); // Clean up
return $results;
}
else {
return false;
}
}
OK I was able to do this but i had to create my own wrapper around the connection:
Its a work around at best but the code basically creates a new PDO connection using the DBAL params in conf.yml. it them prepares and executes the statement and returns all the result sets.
code is free to use here:
https://github.com/scott-davidjones/Symfony2DBALSPWrapper
You can try and itterate over each set 1 by one. But really fetchAll should do the same as below, cant hurt to try though...
$em = $this->get('doctrine')->getManager();
$stmt = $em
->getConnection()
->prepare('EXEC someSP :id,null,:uid');
$stmt->bindValue('id', '629674');
$stmt->bindValue('uid', '217');
$stmt->execute();
do{
$results[] = $stmt->fetchAll()
} while($stmt->nextRowset());

A different service for my Flex app using Zend_Amf

I have an iterator service that works fine already and returns a correctly structured values to my flex application through my Zend Amf server
$contacts = array();
mysql_connect( 'localhost', 'root', 'test' );
mysql_select_db( 'test' );
$res = mysql_query( 'SELECT * FROM contact' );
while( $contact = mysql_fetch_assoc($res) ) {
$contacts []= $contact;
}
return $contacts;
However I would like to adjust this so that I can leverage my MVC structure and achieve the same results.
I have placed an excerpt that can be brought to working condition
$contacts = array();
$table = new Model_DbTable_Contact();
$result = $table->fetchAll();
//Return an array to be consumed by my flex application
foreach ($result as $row)
{
/*do something*/
}
return $contacts;
You'll want to look into ValueObjects. Zend_Amf supports those, and it's a good idea to use that. That way you can have objects that are native to both PHP and Flex.
$server->setClassMap('ContactVO', 'Contact');
Your Flex would then have a class:
[Bindable]
[RemoteClass(alias="Contact")]
public class ContactVO
{
}
Would tell your server that you're going to map your Contact class to ContactVO in Flex.
then you could do:
$data = array();
foreach ($result as $row)
{
$data[] = new Contact($row);
//assuming the Contact constructor parses the array data
}
return $data;
and your Contact objects would get to Flex as ContactVO objects
So here I have a function in the logical model for a database table:
public function fetchAll() {
$resultSet = $this->getDbTable()->fetchAll();
$entries = array();
foreach( $resultSet as $row ) {
$entry = new Model_ClosingData();
$entry->setId($row->id)
->setContractMonth($row->monthId)
->setCommodity($row->commodityId)
->setDate($row->date)
->setPrice($row->price)
->setVolume($row->volume)
->setOutstandingInterest($row->outstandingInterest);
$entries[] = $entry;
}
return $entries;
}

Resources