Doctrine DQL subqueries give a zero result - php

I have three related entities : Group, GroupDefault, GroupDefaultTranslation on a Mysql server.
The Group entity stores the groups of a user.
The GroupDefault entity define the default groups for any user.
The GroupDefaultTranslation entity stores the translation for the default groups.
The relationships between the entities are types:
- ManyToOne between Group and GroupDefault
- OneToManu ent GroupsDefault and GroupDefaultTranslation
My goal is to display the list of groups of a user with the corresponding translation in his language parameter.
Here is my QueryBuilder with DQL query generated :
public function findByOwnerWithLanguage($languageCode, $ownerId)
{
$qb = $this->createQueryBuilder('g')
->select('g.name')
->addSelect('gdt.content AS name')
->join('g.parent', 'gd')
->join('gd.translations', 'gdt')
->where('g.owner = :owner');
//création de l'expression AND
$orModule = $qb->expr()->andX();
$orModule->add($qb->expr()->eq('g.parent', '0'));
$orModule->add($qb->expr()->eq('gdt.locale', ':language'));
$orModule->add($qb->expr()->eq('g.owner', ':owner'));
//Ajout de l'expression à la requête
$qb->orWhere($orModule)
->setParameter('language', $languageCode, \PDO::PARAM_STR)
->setParameter('owner', $ownerId)
->orderBy('g.isMyLightbox', 'DESC')
->getQuery()
->getResult();
return $qb;
// DQL Query :
// SELECT g.name, gdt.content AS name
// FROM Horyou\Bundle\CoreBundle\Entity\Group g
// INNER JOIN g.parent gd
// INNER JOIN gd.translations gdt
// WHERE g.owner = :owner
// OR (g.parent = 0 AND gdt.locale = :language AND g.owner = :owner)
// ORDER BY g.isMyLightbox DESC
}
And here is the output of the object var_dump :
object(stdClass)[1368]
public '__CLASS__' => string 'Doctrine\ORM\QueryBuilder' (length=25)
public '_em' =>
object(stdClass)[1362]
public '__CLASS__' => string 'Doctrine\ORM\EntityManager' (length=26)
public 'config' => string 'Doctrine\ORM\Configuration' (length=26)
public 'conn' => string 'Doctrine\DBAL\Connection' (length=24)
public 'metadataFactory' => string 'Doctrine\ORM\Mapping\ClassMetadataFactory' (length=41)
public 'unitOfWork' => string 'Doctrine\ORM\UnitOfWork' (length=23)
public 'eventManager' => string 'Symfony\Bridge\Doctrine\ContainerAwareEventManager' (length=50)
public 'proxyFactory' => string 'Doctrine\ORM\Proxy\ProxyFactory' (length=31)
public 'repositoryFactory' => string 'Doctrine\ORM\Repository\DefaultRepositoryFactory' (length=48)
public 'expressionBuilder' => string 'Doctrine\ORM\Query\Expr' (length=23)
public 'closed' => boolean false
public 'filterCollection' => string 'Doctrine\ORM\Query\FilterCollection' (length=35)
public '_dqlParts' =>
array (size=9)
'distinct' => boolean false
'select' => string 'Array(2)' (length=8)
'from' => string 'Array(1)' (length=8)
'join' => string 'Array(1)' (length=8)
'set' => string 'Array(0)' (length=8)
'where' => string 'Doctrine\ORM\Query\Expr\Orx' (length=27)
'groupBy' => string 'Array(0)' (length=8)
'having' => null
'orderBy' => string 'Array(1)' (length=8)
public '_type' => int 0
public '_state' => int 1
public '_dql' => string 'SELECT g.name, gdt.content AS name FROM Horyou\Bundle\CoreBundle\Entity\Group g INNER JOIN g.parent gd INNER JOIN gd.translations gdt WHERE g.owner = :owner OR (g.parent = 0 AND gdt.locale = :language AND g.owner = :owner) ORDER BY g.isMyLightbox DESC' (length=251)
public 'parameters' =>
array (size=2)
0 => string 'Doctrine\ORM\Query\Parameter' (length=28)
1 => string 'Doctrine\ORM\Query\Parameter' (length=28)
public '_firstResult' => null
public '_maxResults' => null
public 'joinRootAliases' =>
array (size=2)
'gd' => string 'g' (length=1)
'gdt' => string 'g' (length=1)
My problem is that the result is zero.
Does anyone see what is the error in my QueryBuilder?

Actually it's not a result - it's just a dump of a query builder object. I think you have to do something like this:
...
$qb->orWhere($orModule)
->setParameter('language', $languageCode, \PDO::PARAM_STR)
->setParameter('owner', $ownerId)
->orderBy('g.isMyLightbox', 'DESC');
$result = $qb->getQuery()->getResult();
return $result;

Related

MYSQL PHP Array grouping

Having trouble wrapping my head around this conceptually. Still new to this. Basically I have this return from my database :
array (size=456)
0 =>
object(stdClass)[358]
public 'id' => string '2432' (length=4)
public 'symbol' => string '.AMLP' (length=14)
public 'last' => string '0.01' (length=4)
public 'volume' => string '3690' (length=4)
public 'the_date' => string '2019-09-13' (length=10)
public 'the_screener' => string '1' (length=1)
public 'notes' => string 'notes here' (length=149)
1 =>
object(stdClass)[726]
public 'id' => string '2417' (length=4)
public 'symbol' => string '.ARCC' (length=14)
public 'last' => string '2.25' (length=4)
public 'volume' => string '1633' (length=4)
public 'the_date' => string '2019-09-13' (length=10)
public 'the_screener' => string '1' (length=1)
public 'notes' => string 'notes' (length=60)
2 =>
object(stdClass)[726]
public 'id' => string '2447' (length=4)
public 'symbol' => string '.ARCC' (length=14)
public 'last' => string '2.25' (length=4)
public 'volume' => string '1633' (length=4)
public 'the_date' => string '2019-09-12' (length=10)
public 'the_screener' => string '1' (length=1)
public 'notes' => string 'notes here 3' (length=60)
3 =>
What I'm trying to do with PHP is create an object/array that I can work with that displays these items like
AMLP 1 found on dates 2019-09-13
ARCC 2 found on dates 2019-09-13, 2019-09-12
In the end I would display these in a table, but conceptually this is what I'm trying to do.
I've tried creating an array in my foreach I use to display this information in a table, but I was thinking about it and it's probably better to just use the same query data and break it down separately.
So I'd like to create an array like :
Array
(
[1] => Array
(
[id] => 1
[symbol] => ARCC
[dates] => Array
(
[3] => Array
(
2019-09-13
2019-09-12
)
)
)
)
Consider your array is $arrDates. If you want to access properties like object properties
$arrFinal = [];
foreach ($arrDates as $intKey => $obj){
$strSymbol = getSubSymbol($obj->symbol);
if(!isset($arrFinal[$strSymbol])) {
$arrFinal[$strSymbol] = [ 'id' => $obj->id, 'symbol' => $obj->symbol];
}
$arrFinal[$strSymbol]['dates'][] = $obj->the_date;
}
// Now loop throuh arrFinal and do print the statements you want.
foreach($arrFinal as $strSubSymbol => $arrData){
echo $strSubSymbol . ' '. count($arrData['dates']) . ' found on dates ' . implode(',', $arrData['dates']). PHP_EOL;
}
Function to get the desired subpart of symbol
function getSubSymbol($symbol_original){
$symbol = preg_split('/(?=\d)/', $symbol_original, 2); //get everything up until first number or the date in the string in this case.
$symbol_here = substr($symbol[0], 1);
return $symbol_here;
}

Join many to one

In Codeigniter I am tryign to join two tables with a one-to-many relation. I want to get one result from my table housetype and all of its values/members from other table housetype_member:
$this->db->select('*');
$this->db->join('housetype_member', 'housetype_member.housetype_id = housetype.PkId', 'left');
$result = $this->db->get_where('housetype', array('PkId' => $id));
return $result->result();
So far I get such result:
array (size=2)
0 =>
object(stdClass)[28]
public 'PkID' => string '4' (length=1)
public 'Name' => string 'Classic' (length=7)
public 'image' => string '1449063250.jpg' (length=14)
1 =>
object(stdClass)[30]
public 'PkID' => string '4' (length=1)
public 'Name' => string 'Classic' (length=7)
public 'image' => string '1449063288.gif' (length=14)
First two object values (PkID, Name) are from the first table and the last one (image) is from the second left table. Everything is good but I get an array with two elements, when I only need one housetype object.
Is there a way to write above code so that my returned object would look like this:
object(stdClass)[28]
public 'PkID' => string '4' (length=1)
public 'Name' => string 'Classic' (length=7)
public 'image' =>
array (size=2)
0 => string '1449063250.jpg' (length=14)
1 => string '1449063288.gif' (length=14)
I need one result from the first table and to it I want to join all of its members from the second table.
Can it be done with Codeigniters active record, can it be done at all?
Add group_by() clause to your query.
$this->db->group_by('housetype.PkId');

How to map a join to a join in Doctrine ORM native sql result set

How to map a join to a join in Doctrine ORM native sql result set
I want a result set with entities that have a join to a join. When dumping the result set I see that the join isn't correct.
The join in the second entity in the result set is joined to the first entity. And the join in the second entity is null.
But if I leave out the mapping of a field of the deepest join, the joins will be correct (except of the missing field).
relation
MyEntity ----> FooEntity ----> BarEntity
sql result
id some_field foo_id bar_id my_field
1 testa 123 456 test1
1 testb 8823 998 test2
mapping
$rsm->addEntityResult('MyEntity', 'a');
// first join
$rsm->addJoinedEntityResult('FooEntity', 'foo', 'a', 'foo');
// join to the first join
$rsm->addJoinedEntityResult('BarEntity', 'bar', 'foo', 'foo');
$rsm->addFieldResult('a', 'id', 'id')
->addFieldResult('a', 'some_field', 'someField')
->addFieldResult('foo', 'foo_id', 'id')
->addFieldResult('bar', 'bar_id', 'id');
print_r
// if I disable this addFieldResult, the joins are correct, but myField === null
//$rsm->addFieldResult('bar', 'my_field', 'myField')
object(stdClass)[352]
public '__CLASS__' => string 'FooEntity' (length=42)
public 'id' => int 123
public 'bar' =>
object(stdClass)[446]
public '__CLASS__' => string 'BarEntity' (length=49)
public 'id' => string '456' (length=2)
public 'myField' => null
object(stdClass)[352]
public '__CLASS__' => string 'FooEntity' (length=42)
public 'id' => int 8823
public 'bar' =>
object(stdClass)[446]
public '__CLASS__' => string 'BarEntity' (length=49)
public 'id' => string '998' (length=2)
public 'myField' => null
// if I enable this addFieldResult, the joins are incorrect
$rsm->addFieldResult('bar', 'my_field', 'myField');
object(stdClass)[352]
public '__CLASS__' => string 'FooEntity' (length=42)
public 'id' => int 123
public 'bar' =>
object(stdClass)[446] |
public '__CLASS__' => string 'BarEntity' (length=49) | THE WRONG BarEntity
public 'id' => string '998' (length=2) |
public 'myField' => null |
object(stdClass)[352]
public '__CLASS__' => string 'FooEntity' (length=42)
public 'id' => int 8823
public 'bar' => null | IT SHOULD BE HERE
Thanks for any help
Richard

Building a form dynamically with Codeigniter and Active Record queries

Model
function get_prices()
{
$table_by_product = 'printer_businesscards'; //replace with URI Segment
//Get all the columns in the table set by the page URI of $table_by_product variable
$get_all_col_names = $this->db->list_fields($table_by_product);
//Loop through the column names. All names starting with 'O_' are optional fields for the
//current product. Get all Distinct values and create a radio button list in form.
foreach ($get_all_col_names as $key => $value) {
//get all o_types for the product by column name
if ($all_O_types = preg_match('/O_/', $value))
{
$O_types = array($value);
foreach ($O_types as $O) {
//echo $O;
$this->db->select($O);
$this->db->distinct();
$qO = $this->db->get($table_by_product);
$qO_Array = $qO->result_object();
}
}
//Get all x_types for the product by column name. All 'X_' types are specific product options.
//Create a dropdown menu with all DISTINCT product options.
if ($all_X_types = preg_match('/X_/', $value))
{
$X_types = array($value);
foreach ($X_types as $X) {
//echo $X;
$this->db->select($X);
$this->db->distinct();
$qX = $this->db->get($table_by_product);
$qX_Array = $qX->result_object();
}
}
}
return array($qX_Array,$qO_Array);
}
}
So each product has different options but all products options are prefixed by "X_" or "O_". I need to get the DISTINCT values of each COLUMN of "X_" and "O_" and in any VIEW I need to build a form with these values. Here is a look at the array:
array (size=3)
0 =>
object(stdClass)[19]
public 'X_SIZE' => string '1.75x3' (length=6)
1 =>
object(stdClass)[20]
public 'X_SIZE' => string '1.75x3.5(slim)' (length=14)
2 =>
object(stdClass)[21]
public 'X_SIZE' => string '2x3' (length=3)
array (size=3)
0 =>
object(stdClass)[17]
public 'X_PAPER' => string '14ptGlossCoatedCoverwithUV(C2S)' (length=31)
1 =>
object(stdClass)[18]
public 'X_PAPER' => string '14ptPremiumUncoatedCover' (length=24)
2 =>
object(stdClass)[24]
public 'X_PAPER' => string '16ptDullCoverwithMatteFinish' (length=28)
array (size=2)
0 =>
object(stdClass)[23]
public 'X_COLOR' => string '1000' (length=4)
1 =>
object(stdClass)[22]
public 'X_COLOR' => string '1002' (length=4)
array (size=4)
0 =>
object(stdClass)[20]
public 'X_QTY' => string '100' (length=3)
1 =>
object(stdClass)[21]
public 'X_QTY' => string '250' (length=3)
2 =>
object(stdClass)[17]
public 'X_QTY' => string '500' (length=3)
3 =>
object(stdClass)[19]
public 'X_QTY' => string '1000' (length=4)
array (size=3)
0 =>
object(stdClass)[25]
public 'O_RC' => string 'YES' (length=3)
1 =>
object(stdClass)[26]
public 'O_RC' => string 'NO' (length=2)
2 =>
object(stdClass)[27]
public 'O_RC' => string 'NA' (length=2)
My current MODEL is only returning X_QTY and O_RC to my view.
What am I doing incorrectly?
You are only returning the last result object of each; ie, you are setting
$qO_Array = $qO->result_object();
to a variable, and it should be:
$qO_Array[] = $qO->result_object();
to get all of them
BTW - do you have a specific reason for calling result_object() instead of the usual result() or result_array()? It's not necessarily wrong, but I wonder if you are doing it intentionally?

php array count

I have a var dump of my sql query which return the following
I wanna to count in the array below that how many rows of myID = 5 are there. How would I do that. I am using php. Thanks in advance
array
0 =>
object(stdClass)[17]
public 'myID' => string '5' (length=1)
public 'data' => string '123' (length=3)
1 =>
object(stdClass)[18]
public 'myID' => string '5' (length=1)
public 'data' => string '123' (length=3)
2 =>
object(stdClass)[19]
public 'relativeTypeID' => string '2' (length=1)
public 'data' => string '256' (length=3)
3 =>
object(stdClass)[20]
public 'myID' => string '4' (length=1)
public 'data' => string '786' (length=3)
object(stdClass)[21]
public 'myID' => string '4' (length=1)
public 'data' => string '786' (length=3)
Do you always have the same value of data for the same myID? In other words, is data functionally dependant on myID?
If so, you can get the database to do this for you:
SELECT myID, data, COUNT(*) AS cnt
FROM (your query here)
GROUP BY myID, data
This would give you results like the following:
myID data cnt
'5' '123' 3
'2' '256' 1
'4' '786' 2
Or, you can use a foreach statement, like:
$count = 0;
foreach($arr as $item)
{
// Given that your item is an stdClass Object you access its property with "->"
// if an array $item["myID"] instead
if ( $item->myID == '4' )
{
$count ++;
}
}

Categories