I am trying to use API Platform serialization with calculated field as in here https://api-platform.com/docs/core/serialization/#calculated-field
Here is the code
/**
* #Groups({
* "read:actionJeu"
* })
*/
public function getTimePassed(){
return 4;
}
The normalization context is normalizationContext={"groups"={"read:actionJeu"}, "enable_max_depth"=true}
The problem is that when I do return 4, it shows this error
But when I change the return to something else (for example return new \DateTime('now') ), I get it working.
I wonder why this is happening, I tried with string too, but it doesn't work.
I supose that your entity property $timePassed is type of DateTime. Return type of method getTimePassed() also must be the DateTime type. You can change type of property $timePassed to int instead of DateTime or make your custom TimePassedSerializer service.
/** this **/
private int $timePasede;
/** insted of this **/
private DateTime $timePasede
It might be caused by the API Platform core package version.
Try installing version 2.6.8 or 2.6.6.
I was dealing with the same thing on the 2.6.7.
The example defines the return type of the function with : int at the end, so that it's clear that this function will return an integer.
I guess that api-platform will expect an object per default until a different return type has been defined.
So this should work from my understanding. Note that I haven't tested it because I don't have the possibility for it right now.
/**
* #Groups({
* "read:actionJeu"
* })
*/
public function getTimePassed(): int {
return 4;
}
Related
I have the following code:
$request->headers->get('Accept-Language', 'en');
I provide a default value but Psalm thinks it's potentially null since ->get() declares that return a nullable string:
// vendor/symfony/http-foundation/HeaderBag.php
/**
* Returns a header value by name.
*
* #return string|null The first header value or default value
*/
public function get(string $key, string $default = null) { /* */ }
How can I fix this so psalm knows it's not null?
Since you cannot control the annotation in the upstream library, you'll have to provide the missing information to Psalm in your own code.
A couple of ways to go about it:
Cast to string, so Psalm has no doubt what type get() is getting you:
$a = (string) $request->headers->get('Accept-Language', 'en');
Yup, the cast is redundant, but it's clear and concise. I usually do this just for economy.
You could explicitly declare that the variable that result of this get() call is a string:
/** #var string $acceptLanguage **/
$acceptLanguage = $request->headers->get('Accept-Language', 'en');
Finally, you can simply suppress the PossiblyNullArgument wherever you need it:
/** #psalm-suppress PossiblyNullArgument */
iWantAString($request->headers->get('Accept-Language', 'en'));
See all these working here.
You can also combine some of the above with your own wrapper method to deal with getting values from the request, making sure you always return string. If you do that, you should probably throw an exception if the parameter is not found.
In addition to #yivi's answer that shows you how you can override type inference or suppress the error, you can also explain the type to Psalm by providing correct docblock using conditional types either directly in the source code (if you have control over that) or in a stub file.
/**
* Returns a header value by name.
*
* #psalm-return ($default is null ? (string|null) : string)
*/
public function get(string $key, string $default = null) { /* */ }
https://psalm.dev/r/41b8471847
I am using symfony 2, I have one field in database "old_status". I want to change it to "status" field (change in both database + entity. I changed it because It is making the developer confuse)
/**
* #var integer
*
* #ORM\Column(name="status", type="smallint", nullable=false, options={"unsigned"=true})
*
* #Expose
*/
private $status;
So in the response it will change to "status". But I don't want to change the contract. I want to show both of "old_status" and "status" fields but with same value. So the current partner will continue use "old_status" until they move to new field. The new partner will use "status".
I don't want add more field in database, I want to handler it by use entity.
Can I do it with entity?
You can simply leave the old getter and make them both new and old methods use the new field name status.
something like:
public function getStatus() {
return $this->status;
}
/**
* #deprecated Renamed to getStatus
*/
public function getOldStatus() {
return $this->status;
}
You can do a similar thing with other methods, like setters, if needed.
Since $status is a private field, it's just a matter of public interface.
I'm trying to create a timestamp database field type for my Symfony project.
I have created the following database type:
class TimestampType extends Type {
const TIMESTAMP_TYPE_NAME = 'timestamp';
/**
* Gets the SQL declaration snippet for a field of this type.
*
* #param array $fieldDeclaration The field declaration.
* #param \Doctrine\DBAL\Platforms\AbstractPlatform $platform The currently used database platform.
*
* #return string
*/
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return "TIMESTAMP";
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
return $value;
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
return $value;
}
/**
* Gets the name of this type.
*
* #return string
*
* #todo Needed?
*/
public function getName()
{
return self::TIMESTAMP_TYPE_NAME;
}
}
In my entity, I have declared the following property:
/**
* #var \DateTime
* #ORM\Column(name="created", type="timestamp", options={"default":"CURRENT_TIMESTAMP"})
*/
protected $created = null;
It all looks good, but when running a database update, I get an error:
An exception occurred while executing 'ALTER TABLE question CHANGE created created TIMESTAMP DEFAULT 'CURRENT_TIMESTAMP' NOT NULL COMMENT '(DC2Type:timestamp)'':
SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'created'
For some reason, my default value is being encapsulated in single quotes. This doesn't happen for datetime fields, but then I get an error the default value is invalid.
Is there any way I can make Symfony accept a timetamp field with CURRENT_TIMESTAMP as default value?
I've tried the following in my custom type, by commenting out the appending query Symfony adds:
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return "TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '(DC2Type:" . self::TIMESTAMP_TYPE_NAME . ")' #--";
}
That works, but now Symfony always thinks it needs to update my tables and runs the query for every table that it thinks it needs to update.
My goal is to have a timestamp in the database if I run native insert queries. I know it can be done using HasLifecycleCallbacks and I have them configured, but I want to avoid ORM at some points and use native queries.
Any help would be appreciated. :)
A funny little trick I've seen is this (you wouldn't need the database type you created, just update the mapping):
/**
* #ORM\Column(type="datetime", nullable=false)
* #ORM\Version
* #var \DateTime
*/
protected $created = null;
What happens behind the scenes is that Doctrine will end up casting the datetime to a timestamp since it was combined with #version, and should add the default timestamp schema change.
With that said, this isn't quite the intended use for this feature (http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-version), and I'd be curious what happens on subsequent update queries you make.
I know you're looking for the default to be set in MySQL so you can run queries outside of Doctrine, but the clearest way to add a default timestamp for me has always been to add it in the object's constructor:
public function __construct()
{
$this->created = new \DateTime();
}
I have a entity with several fields. Now I have added to my database a new column "date" that is a datetime object.
But when I add a new register to the database this field always have value null, never caught the value that I put in the form.
The entity have the correct values, but if I saw all the values, the entity manager has a variable called "SelectColumnListSQL", and in this SQL action, doesn't appear the field "date".
The logs doesn't write any error, only store in my database the rest of the fields ok but this not.
If hay use dev enviromnent, in this case all works right :S
Any idea??
--- Entity Info ---
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime", nullable=false)
*/
protected $date;
/**
* Set date
*
* #param \DateTime $date
* #return Quotes
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
Thanks!
Please, concrete which ORM are you using (Doctrine, Propel...)
Have you already run the following commands?
php app/console doctrine:generate:entities
php app/console doctrine:schema:update
You must include the info in your Entity dir in your Bundle
I am pretty sure that you forget one setter method or the method is misspelled.
See the example below for more details.
Assume that you have this entity
class Entity{
// ...
private field;
// the getter and setter methods
public function getField(){
// ...
}
public function setField(){ // I guess this function is missing or misspelled
// ...
// If the function is missing or misspelled,
// doctrine will not take into account the changes you did for that field
}
}
best,
Check that you have totaly updated your database by this command:
php app/console doctrine:schema:update --dump-sql
I want to save a datetime in the database which was created with the doctrine schema tool.
In my form I set a date and time and i want to save it as a datetime in the database.
So i tried this:
$e->setStartDateTime(new Zend_Date('2011-09-01T22:00:00',Zend_date::DATETIME));
But i get the error:
PHP Fatal error: Call to undefined method Zend_Date::format() in /var/www/shared/Doctrine/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Types/DateTimeType.php on line 44
Does anyone have experience with this and able to help me with this problem?
You can override the native datatypes to use Zend_Date instead of PHP's native DateTime which is the default for Doctrine data types 'datetime', 'time', and 'date'.
First in your application Bootstrap file, add the following BEFORE you instantiate your Doctrine EntityManager. This code should come before any other Doctrine code:
Doctrine\DBAL\Types\Type::overrideType('datetime', 'yournamespace\types\DateTimeType');
Doctrine\DBAL\Types\Type::overrideType('date', 'yournamespace\types\DateType');
Doctrine\DBAL\Types\Type::overrideType('time', 'yournamespace\types\Time');
Now you simply need to implement the 3 classes. It's easiest to just extend the corresponding Doctrine classes to achieve this. The code is actually the same for all 3 classes, the only difference is the class you extend from and the name of your class. Here is the DateTimeType class as an example:
namespace yournamespace\type;
use Doctrine\DBAL\Types\DateTimeType as DoctrineDateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* Override 'datetime' type in Doctrine to use Zend_Date
*/
class DateTimeType extends DoctrineDateTimeType
{
/**
* Convert from db to Zend_Date
*
* #param string $value
* #param AbstractPlatform $platform
* #return \Zend_Date|null
*/
public function convertToPhpValue($value, AbstractPlatform $platform)
{
if (is_null($value)) {
return null;
}
\Zend_Date::setOptions(array('format_type' => 'php', ));
$phpValue = new \Zend_Date($value, $platform->getDateTimeFormatString());
\Zend_Date::setOptions(array('format_type' => 'iso', ));
return $phpValue;
}
/**
* Convert from Zend_Date to db
*
* #param string $value
* #param AbstractPlatform $platform
* #return string|null
*/
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
if (is_null($value)) {
return null;
}
\Zend_Date::setOptions(array('format_type' => 'php', ));
$dbValue = $value->toString($platform->getDateTimeFormatString());
\Zend_Date::setOptions(array('format_type' => 'iso', ));
return $dbValue;
}
}
Now you can still use #Column(type="datetime") annotations in Doctrine. When saving to the database, you can save entity properties of type "datetime" to Zend_Date instances. Also when grabbing entities out of the database, properties of type "datetime" will now be Zend_Dates.
Doctrine2 expects PHP DateTime objects for DQL date and datetime types.
If you are not forced to use a Zend_Date, to this:
->setStartDateTime(new DateTime('2011-09-01T22:00:00'))
Else, convert it to a DateTime:
new DateTime('#' . $zendDate->getTimestamp())
See DateTime docs.
You can implement a Custom Mapping Type or use this ZendDateType implementation.
You may find this guide helpful.