Can I access discriminator field from php in doctrine2?
Extending what beberlei said, you could declare some constants in the Attribute class, and an abstract getType()
function. Then, overload it in every derived attribute class.
Something like:
abstract class Attribute {
const TYPE_BOOL = 0;
const TYPE_INT = 1;
...
abstract public function getType();
}
class BooleanAttribute extends Attribute {
public function getType() {
return parent::TYPE_BOOL;
}
}
How to get the discriminator type from repository
According to the docs, you can use INSTANCE OF to do it.
As you want to use the discriminator values, using the class metadata and constructing a CASE expression, you can select the value for each instance:
$meta = $em->getMetadataFactory()->getMetadataFor(Flux::class);
$discriminatorMap = $meta->discriminatorMap;
$caseQl = '(case';
foreach ($discriminatorMap as $fieldValue => $class) {
$caseQl .= " when p INSTANCE OF " . $class . " then '" . $fieldValue . "'";
}
$caseQl .= ' else 0 end) as HIDDEN atype';
$qb->addSelect($caseQl);
$qb->having("atype LIKE :type");
$qb->setParameter('type', '%FluxNew%');
Note that the field atype is defined as HIDDEN, so that it is not returned in the result.
Also for this solution having needs to be used, not where(since the atype is a calculated value).
Alternatively, you could use Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS to include the foreign key column values in the result:
$paginator->getQuery()
->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, true)
->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);
References:
- how to get discriminator map values
- Calculated column
- Force 'fetch joined' relations to include IDENTITY of their ManyToOne relations using HYDRATE_ARRAY?
Map a discriminator column to a field with Doctrine 2
Sadly, there is no documented way to map the discr column to an entity. That's because the discr column is really part of the database and not the entity.
However, it's quite common to just put the discr value directly in your class definition. It's not going to change and you will always get the same class for the same value anyways.
class Person
{
protected $discr = 'person';
class Employee extends Person
{
protected $discr = 'employee';
Doctrine 2 - How to use discriminator column in where clause
I think that you should use INSTANCE OF
Doctrine Inheritance: Discriminator from Entity attribute and not table column?
Given the fact that shopType
is a rather static property (in the sense that it will always be the same for all instances of a class) you can simply define the shopType
as default for the property, and use the existing column as discriminator column:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="shopType", type="string")
* @ORM\DiscriminatorMap({"local" = "LocalShop", "foreign" = "ForeignShop"})
*/
class Shop
{
protected const TYPE_LOCAL = 'local';
protected const TYPE_FOREIGN = 'foreign';
// ...
}
/**
* @Entity
*/
class LocalShop extends Shop
{
protected $shopType = Shop::TYPE_LOCAL;
// ...
}
/**
* @Entity
*/
class ForeignShop extends Shop
{
protected $shopType = Shop::TYPE_FOREIGN;
// ...
}
Doctrine's hydrators will take a new instance of your class, which gets instantiated with all default values applied, and then write all the fetched information from the database to the mapped properties.
Since your property has the expected value in the defaults, and is not mapped, its correct default value will not be changed by the hydration process and have the expected value, even when fetched from the database.
In that process, the constructor is not called (Entities are either cloned or produced by Reflection's newInstanceWithoutConstructor), which is why the original code did not work.
Doctrine2 / querying discriminator value
It's not so much that you're doing something wrong, but there is a method to work around the issue. You can make it possible to return the card type with the following.
In class Card add:
public function getCardType()
{
return $this->discr;
}
in class MemberCard add:
protected $discr = 'member';
in class ClientCard add:
protected $discr = 'client';
Related Topics
How to Convert Object into String in PHP
Php: Catch Exception and Continue Execution, Is It Possible
Use a Variable Within Heredoc in PHP
Using Array_Intersect on a Multi-Dimensional Array
Forcing Access to _Php_Incomplete_Class Object Properties
SQL & PHP - Which Is Faster MySQL_Num_Rows() or 'Select Count()'
Setting Post Variable Without Using Form
PHP Strtotime +1 Month Adding an Extra Month
Inserting Now() into Database with Codeigniter's Active Record
Php: How to Generate a Hmacsha256 Signature of a String
How to Connect PHP with Microsoft Access Database
How Validate Unique Email Out of the User That Is Updating It in Laravel
$Path Environment Variable for Apache2 on MAC
Laravel 5.3 Withcount() Nested Relation
Where to Put the PHP Artisan Migrate Command
How to Convert Array to a String Using Methods Other Than JSON