API Platform : Custom setter methods don't work - api-platform.com

I'm trying to set up an ApiRessource using API Platform.
Here is my Cheese entity:
#[ORM\Entity(repositoryClass: CheeseListingRepository::class)]
#[ApiResource]
class CheeseListing
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $title = null;
#[ORM\Column(type: Types::TEXT)]
private ?string $description = null;
#[ORM\Column]
private ?int $price = null;
#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;
#[ORM\Column]
private ?bool $isPublished = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function setTextDescription(string $description): self
{
$this->description = nl2br($description);
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function getCreatedAtAgo(): string
{
return Carbon::instance($this->getCreatedAt())->diffForHumans();
}
public function setCreatedAt(\DateTimeImmutable $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
}
While my custom getter makes the field createdAtAgo appears in the JSON returned by GET operations:
{
"id": 0,
"title": "string",
"description": "string",
"createdAt": "2022-08-26T00:44:53.226Z",
"createdAtAgo": "string"
}
I'm not finding a way to be able to pass the textDescription to the POST opérations although I defined the setter setTextDescription. Here is the example value the doc keeps showing to me:
{
"title": "string",
"description": "string",
"createdAt": "2022-08-26T00:55:41.558Z"
}
Any idea to help me add the textDescription field?

I started a brand new project and I'm getting the expected result now.

Related

Laravel test Mockery

Laravel: 6.x
PHP 7.3
I'am wirte a Repositorytest. below is my code, how can I fix this error,
error
TypeError: Return value of Mockery_5_App_Repositories_PersonRepository::fetchOrNewPersonById() must be an instance of App\Models\PersonModel, instance of Mockery\CompositeExpectation returned
Repository
class ContactRepository implements ContactRepositoryInterface
{
private $contact;
private $personRepo;
public function __construct(Contact $contact)
{
$this->contact= $contact;
$this->personRepo= app()->make(PersonRepositoryInterface::class);;
}
public function updateContacts(array $datas): bool
{
foreach ($datas as $key => $value) {
$person = $this->personRepo->fetchOrNewPersonById($value['person_id']);
$person->fill($value);
if( !$person->save()){ return false; }
}
return true;
}
}
and
class PersonRepository implements PersonRepositoryInterface
{
private $personModel;
public function __construct(Person $personModel)
{
$this->personModel= $personModel;
}
public function fetchOrNewPersonById($id): PersonModel
{
return $this->personModel->firstOrNew(['id' => $id]);
}
}
..which implements a Model.
class PersonModel extends Model
{
protected $table = 'person';
}
and
class Contact extends Model
{
protected $table = 'contacts';
}
my testing code
class ContactRepositoryTest extends \Myname\Myapptests\TestCase
{
/**
* #test
*/
public function test_can_update()
{
$personMock = Mockery::mock(PersonModel::class)
->shouldReceive('fill')
->shouldReceive('save')
->andReturn(true);
$this->app->instance(PersonModel::class, $personMock);
$personRepoMock = Mockery::mock(PersonRepository::class)
->shouldReceive('fetchOrNewPersonById')->andReturn($personMock)
->getMock();
$this->app->bind(ContractRepositoryInterface::class, function () use ($contractRepoMock) {
return $contractRepoMock;
});
$modelMock = Mockery::mock(Contact::class)
$service = new class($modelMock) extends ContactRepository {};
$service->updateContacts([
['person_id' => 3, 'address' => ' XXXXXX update address'],
['person_id' => null, 'address' => ' XXXXXX create address'],
]);
$this->assertTrue(true);
}
}
Obviously I am missing something. Other examples explicitly inject the mocked object into the class they are then testing. Laravels IoC is (should be) doing this for me. Do I have to bind anything?

Spring Boot - Get Data from DB and store it in list and parse it to JSON using jackson

I'm trying to get data from multiple tables and put it in Array List of class, and then convert it to JSON Object.
But when i'm trying to parse it to json using Jackson Object Mapper all the lists are converted as below
Using ObjectMapper().writeValueAsString for deserialization from class objects to json
```{
"College": [
{
"institution": [
{
"instId": "T34",
"Country": "India",
"Code": "T33"
},
{
"instId": "T22",
"Country": "India",
"Code": "T22"
}
],
"Rating": [
{
"star": "4"
"comments": "good"
},
{
"star": "2"
"comments": "ok"
},
}
]
}```
But i want the result as below
{
"College": [
{
"institution": [
{
"instId": "T34",
"Country": "India",
"Code": "T33"
}
],
"Rating": [
{
"star": "4"
"comments": "good"
}
]
},
{
"institution": [
{
"instId": "T22",
"Country": "India",
"Code": "T22"
}
],
"Rating": [
{
"star": "2"
"comments": "ok"
}
]
}
]
}
The above is just an example.
Please help in getting the desired output.
Below are the class files used.
public class AllCollege{
List<College> college = new ArrayList<>();
public List<College> getCollege() {
return college;
}
public void setCollege(List<College> college) {
this.college = college;
}
}
public class College{
private List<Institution> institution = new ArrayList<>();
private List<Rating> rating = new ArrayList<>();
public List<Institution> getInstitution() {
return institution;
}
public void setInstitution(List<Institution> institution) {
this.institution = institution;
}
public List<Rating> getRating() {
return rating;
}
public void setRating(List<Rating> rating) {
this.rating = rating;
}
}
public class Institution {
private String instId;
private String country;
private String code;
public String getInstId() {
return instId;
}
public void setInstId(String instId) {
this.instId = instId;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
public class Rating {
private String star;
private String comments;
public String getStar() {
return star;
}
public void setStar(String star) {
this.star = star;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
Below is where the data from tables is set into ArrayList and then converted to json string.
session = sessionFactory.openSession();
String sql = "from institution";
Query<InstDto> query = session.createQuery(sql);
List<Institution> configdtoList =query.list();
College alc = new College();
alc.setInstitution(configdtoList);
.
.
.
similarly Rating table.
List<College> clist = new new ArrayList<>();
clist.add(alc);
AllCollege ac = new AllCollege();
ac.setCollege(clist);
String responseJson = new ObjectMapper().writeValueAsString(ac)
class structure as below it will help you to parse:
public class Sample {
#JsonProperty("College")
private List<College> college;
}
public class College {
private List<Institution> institution;
#JsonProperty("Rating")
private List<Rating> rating;
}
public class Rating {
private String comments;
private String star;
}
public class Institution {
#JsonProperty("Code")
private String code;
#JsonProperty("Country")
private String country;
private String instId;
}
I have created an HashMap contains the List<AllCollege> as value and then used json parser which worked as expected.

Nesting of CActiveRecord

class SomeModel extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return '{{some_table}}';
}
public function getItemByParentId($parentId)
{
$criteria=new CDbCriteria;
//some criteria
return self::model()->findAll($criteria);
}
}
This method works properly when I call it from controller
SomeModel::model()->getItemByParentId($someVariable)
But now I have 3 very similar to SomeModel models, so I want to put common methods to one class
class CommonModel extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function getItemByParentId($parentId)
{
$criteria=new CDbCriteria;
//some criteria
return self::model()->findAll($criteria);
}
}
class FirstModel extends CommonModel
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return '{{first_table}}';
}
}
class SecondModel extends CommonModel
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return '{{second_table}}';
}
}
But get error
The table "CommonModel" for active record class "CommonModel" cannot
be found in the database.
What is wrong?
Try to change:
public function getItemByParentId($parentId)
{
$criteria=new CDbCriteria;
//some criteria
return static::model()->findAll($criteria);
}

How add a specific variable in custom AuthStorage in Zend Framework 2

I'm working on ZF2 and I have developped my own storage for authentication but I wonder how to add a new persistent variable (session-like).
Look My Auth Storage :
<?php
namespace Application\Model;
use Zend\Authentication\Storage;
use Zend\Authentication\Storage\StorageInterface;
use Zend\ServiceManager\ServiceManagerAwareInterface;
use Zend\ServiceManager\ServiceManager;
use Application\Model\User;
class MyAuthStorage implements Storage\StorageInterface, ServiceManagerAwareInterface
{
protected $storage;
protected $userTable;
protected $resolvedIdentity;
protected $serviceManager;
public function isEmpty() {
[...]
}
public function read() {
[...]
}
public function write($contents) {
[...]
}
public function clear() {
[...]
}
public function getStorage() {
[...]
}
public function setStorage(Storage\StorageInterface $storage) {
[...]
}
public function getUserTable() {
[...]
}
public function getServiceManager() {
[...]
}
public function setServiceManager(ServiceManager $serviceManager) {
[...]
}
}
I would like to add a variable called foo in my storage (my session ?)
I try this, but it doesn't work :
protected $foo;
public function setFoo($value) {
$this->foo= $value;
}
public function getFoo() {
return $this->foo;
}
Any ideas ?
Ok, I found something and it works for me :
I've added these things in my auth storage class
use Zend\Session\Container;
Then,
protected $container;
public function setContainer(Container $container) {
$this->container = $container;
return $this->container;
}
public function getContainer() {
if (!isset($this->container)) {
$this->setContainer(new Container('myauthstorage'));
}
return $this->container;
}
And now I can do in my controller stuff like that :
$container = $this->getServiceLocator()->get('AuthService')->getStorage()->getContainer();
$container->foo = true;
if ($container->foo) {
// Congrats !
}
A good example how to write last login time.
namespace Application\Model;
use Zend\Authentication\Storage;
class AuthStorage extends Storage\Session
{
public function setRememberMe($rememberMe = 0, $time = 1209600)
{
if ($rememberMe == 1) {
$this->session->getManager()->rememberMe($time);
}
}
public function forgetMe()
{
$this->session->getManager()->forgetMe();
}
public function lastLogin()
{
$this->session->{$this->getMember()}->last_login = time();
}
}
Check this tutorial :
http://samsonasik.wordpress.com/2012/10/23/zend-framework-2-create-login-authentication-using-authenticationservice-with-rememberme/
Sounds like your personnal AuthStorage should extends Storage\Session like this :
namespace SanAuth\Model;
use Zend\Authentication\Storage;
class MyAuthStorage extends Storage\Session
{
public function setRememberMe($rememberMe = 0, $time = 1209600)
{
if ($rememberMe == 1) {
$this->session->getManager()->rememberMe($time);
}
}
public function forgetMe()
{
$this->session->getManager()->forgetMe();
}
}

Select one entry from #OneToMany Association from within Model

I have Doctrine 2 model defined as:
class Movie {
/** #Id #Column(type="integer") #GeneratedValue #var int */
private $id;
/**
* #ManyToOne(targetEntity="Language")
* #JoinColumn(nullable=false)
*/
private $default_title_language;
/**
* #OneToMany(targetEntity="MovieTitle", mappedBy="movie")
* #var MovieTitle[]
*/
protected $titles = null;
public function __construct() {
$this->titles = new ArrayCollection();
}
public function get_titles() { return $this->titles; }
public function get_title(Language $language = NULL) {
if (is_null($language)) {
$language = $this->default_title_language;
}
// ??????????
}
public function add_title(MovieTitle $title) { $this->titles[] = $title; }
public function get_default_title_language() {
return $this->default_title_language;
}
public function set_default_title_language(Language $language) {
$this->default_title_language = $language;
}
}
so... there are Movie, MovieTitle and Language models. One Movie may have many titles (Language dependent). I want to provide Movie model with a method - which will return me only one parameterized title. How can I do this? (marked with ??????????)
Doctrine 2.1 has indexed collections. It should do the job
http://www.doctrine-project.org/docs/orm/2.0/en/tutorials/working-with-indexed-associations.html

Resources