Doctrine 2 custom type - symfony

I am trying to follow the example at
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/types.html
and create a custom quantity type. Everything works fine when quantity type is defined as:
class Quantity extends Type
{
const QUANTITY = 'quantity'; // modify to match your type name
public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return 'decimal(10,2)';
}
public function getName()
{
return self::QUANTITY;
}
}
However when introducting
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value->toDecimal();
}
I get the following error when saving:
FatalErrorException: Error: Call to a member function toDecimal() on a non-object in ...\Types\Quantity.php line 26

The $value you get is either string or null. You can't call toDecimal on it. Try:
public function convertToDatabaseValue($value, AbstractPlatform $platform) {
return $value === null ? null : (float) $value;
}

Related

PHPUnit 9.5 set mock (or stub or fake) to the function that calling within the class

I have a function to implement Unit test function. This function is calling a other function within the same class. I want to set pre-defined returns for this calling function (functwo()).
The project is using 'Zend_Test_PHPUnit' PHPUnit 9.5.20
I have a class like this:
class myClass {
public $x;
public $y;
public $z;
public function __constructor($x, $y, $z){
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
public function funcone()
{
$i = 1;
$a = $i + $this->functwo();
return $a;
}
public function functwo()
{
return 3;
}
}
And my Testing class is:
class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
...
}
class myClassTest extends ControllerTestCase
{
public function testCheck1()
{
$x = true;
$y = 10.5;
$z = [];
$mock = $this->getMockBuilder(myClass::class)
->setConstructorArgs([$x, $y, $z])
->getMock();
$mock->method('functwo')->willReturn(5);
$result = $mock->funcone();
$this->assertTrue($result === 6);
}
}
I still getting the null for $result and it seems testing is not calling funcone(). Any idea where I am got wrong?
There was 1 failure:
1) myClassTest::testCheck1
Failed asserting that false is true.

How to inject api-plaform's pagination filter on my custom dataprovider

I'm developing an application with symfony4, in which I'm using api-platform. I've created a custom dataprovider for a specific entity (Car for example). CarCollectionDataProvider returns all blue cars.
<?php
namespace App\DataProvider;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\PaginationExtension;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Entity\Car;
use Doctrine\Common\Persistence\ManagerRegistry;
use Generator;
final class CarCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $managerRegistry;
private $paginationExtenstion;
public function __construct(ManagerRegistry $managerRegistry, PaginationExtension $paginationExtension)
{
$this->managerRegistry = $managerRegistry;
$this->paginationExtenstion = $paginationExtension;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return Car::class === $resourceClass;
}
public function getCollection(string $resourceClass, string $operationName = null): Generator
{
$queryBuilder = $this->managerRegistry
->getManagerForClass($resourceClass)
->getRepository($resourceClass)->createQueryBuilder('car')
->where('car.color = :color')
->setParameter('color', 'blue');
$this->paginationExtenstion->applyToCollection($queryBuilder, new QueryNameGenerator(), $resourceClass, $operationName, []);
yield $this->paginationExtenstion->getResult($queryBuilder, $resourceClass, $operationName, []);
}
}
How can I inject api-platform's pagination extension on my custom dataprovider (CarCollectionDataProvider)?
this works fine for me :
<?php
namespace App\DataProvider;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\PaginationExtension;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultCollectionExtensionInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Entity\Car;
use Doctrine\Common\Persistence\ManagerRegistry;
final class CarCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $managerRegistry;
private $paginationExtension;
private $context;
public function __construct(ManagerRegistry $managerRegistry, PaginationExtension $paginationExtension)
{
$this->managerRegistry = $managerRegistry;
$this->paginationExtension = $paginationExtension;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
$this->context = $context;
return Car::class === $resourceClass;
}
public function getCollection(string $resourceClass, string $operationName = null)
{
$queryBuilder = $this->managerRegistry
->getManagerForClass($resourceClass)
->getRepository($resourceClass)->createQueryBuilder('car')
->where('car.color = :color')
->setParameter('color', 'blue');
$this->paginationExtension->applyToCollection($queryBuilder, new QueryNameGenerator(), $resourceClass, $operationName, $this->context);
if ($this->paginationExtension instanceof QueryResultCollectionExtensionInterface
&& $this->paginationExtension->supportsResult($resourceClass, $operationName, $this->context)) {
return $this->paginationExtension->getResult($queryBuilder, $resourceClass, $operationName, $this->context);
}
return $queryBuilder->getQuery()->getResult();
}
}
If all you want is allways add a criterium like ->where('car.color = :color') to the queries of all collection operations of some resouce, a custom Extension is more appropriate and will work with the default pagination (and filters):
// api/src/Doctrine/CarCollectionExtension.php
namespace App\Doctrine;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use App\Entity\Car;
use Doctrine\ORM\QueryBuilder;
final class CarCollectionExtension implements QueryCollectionExtensionInterface
{
public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null): void
{
if ($resourceClass != Car::class) return;
$rootAlias = $queryBuilder->getRootAliases()[0];
$queryBuilder->andWhere($rootAlias. '.color = :color');
$queryBuilder->setParameter('color', 'blue');
}
}
You can make this Extension specific to an operation by adding to the if statement something like:
|| $operationName == 'get_blue'
(from the docs) If you're not using the autoconfiguration, you have to register the custom extension:
# api/config/services.yaml
services:
# ...
'App\Doctrine\CarCollectionExtension':
tags:
- { name: api_platform.doctrine.orm.query_extension.collection }
If you also want to add a criterium for item operations, see the docs on Extensions

Symfony passing request to function to an other controller

I try to give '$_REQUEST['vider']' to an other controller like this :
return $this->forward('TestBundle:Rapport:bo', array('vider' => 'vider'));
//, array ($_REQUEST['vider'] => 'vider) doesn't work too
But in my function Rapport:bo, $_REQUEST['vider'] is null, i give it in the array, where i failed ?
edit :
my Rapport:bo function :
public function boAction(Request $request) {
var_dump($_REQUEST['vider']); // is null
if ( isset($_REQUEST['vider']) ) ) {
var_dump('test');
}
}
Try with:
public function boAction($vider) {
your logic...

PHPUnit: Call to undefined method

I want to run simple player inserting test.
My code is something like that:
class Player{
public $id;
public $name;
}
class PlayerDAO{
//db stuff
.....
privatefunction input($player){
$player->id = mysql_real_escape_string($player->id);
$player->name = mysql_real_escape_string($player->name);
return $player;
}
public function insert($player){
$player = $this->input($player);
mysql_query("INSERT INTO player (name) VALUES ('.$player->name.')");
}
public function countPlayers(){
$r = mysql_query("SELECT * FROM player");
return mysql_num_rows($r);
}
}
//Test class
class PlayerTest extends PHPUnit_Framework_TestCase {
public function testInsert(){
$player = new Player();
$player->name = 'Test name';
$count1 = PlayerDAO::countPlayers();
PlayerDAO::insert($player);
$count2 = PlayerDAO::countPlayers();
$this->assertEquals(($count2-$count1), 1);
}
}
If i run test, i get error message: Fatal error: Call to undefined method PlayerTest::input() in ...PlayerTest.php. If i remove method input() from insert() method, the error message is gone.

Pass a set function as an argument

How can I pass a 'set' function as the Function Object argument of another function?
eg:
public class IdModel
{
private var _id:String;
public function IdModel(source:Source)
{
//Create Binding
BindingUtils.bindSetter(id,source,"id");
}
public function get id():String
{
return _id;
}
public function set id(value:String):void
{
_id = value;
}
}
}
In the example above the 'id' argument is being evaluated and returning a String, so it won't compile with the error: "String is not assignable to argument of type Function".
Thanks
In this particular case you don't need to; you can use BindingUtils.bindProperty instead:
BindingUtils.bindProperty(this, "id", source, "id");
But if you really want to use bindSetter and a function you can probably do:
BindingUtils.bindSetter(function (arg:*): void { id = arg; }, source, "id");

Resources