We're using Swagger for our API specification and Swagger Code Generator to automatically generate the related models.
We're using the provided PHP models which works great but doesn't take benefit of PHP 7.1.
I tried to find PHP 7.1 models but I could not find any nor on the official repository or others people repositories.
Do you know some places where models that take benefit of PHP7 stand?
If not, our team is willing to do them. Some of you would be interested?
Current models, made for PHP5:
/**
* Figure.
*/
class Figure implements ArrayAccess {
/**
* #return int
*/
public function getId() {
return $this->container['id'];
}
/**
* #param int $id
*
* #return $this
*/
private function setId($id) {
$this->container['id'] = $id;
return $this;
}
}
Models taking benefit of PHP 7 would look like:
/**
* Figure.
*/
class Figure implements ArrayAccess {
public function getId(): int {
return $this->container['id'];
}
private function setId(int $id): self {
$this->container['id'] = $id;
return $this;
}
}
Related
In our application, we use repositories for models that are fetched from the database. So, we have an abstract repository that knows about the database, has a loadById method to load a database record and an abstract getEntity method that creates an object for that specific repository. Example code:
abstract class EntityRepository {
/**
* #param int $id
* #return AbstractEntity
*/
public function loadById($id) {
$record = $this->db->loadById($id);
$entity = $this->getEntity();
return $this->inflate($record, $entity);
}
/**
* #return AbstractEntity
*/
protected abstract function getEntity();
}
class PeopleRepository extends EntityRepository {
protected function getEntity() {
return new PeopleEntity();
}
}
abstract class AbstractEntity {
private $id;
/**
* #return int
*/
public function getId() {
return $this->id;
}
/**
* #param int $id;
*/
public function setId($id) {
$this->id = $id;
}
}
class PeopleEntity extends AbstractEntity {
private $name;
/**
* #return string
*/
public function getName() {
return $this->name;
}
/**
* #param string $name;
*/
public function setName($name) {
$this->name= $name;
}
}
When using an instance of PeopleRepository and fetching a model through loadById, PhpStorm is not able to resolve the returned model to a concrete type, but provides only code completion for the functions of AbstractEntity. Is there any simple way to make it work?
In https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata, I've only found ways to make it work for concrete classes and their functions. So, enumerating all repository classes and all their ways of creating an entity might work. But I'd love to see an abstract way of defining like "All instances of EntityRepository will return an entity of that type defined in getEntity() when loading an entity"
I doubt there's a blanket way of doing this. Even using PHPStorm meta you have to be explicit for each case. Perhaps the way of doing this is by doing something like adding a repository facade e.g.
class RepositoryFacade {
public static function __callStatic($method, $args) {
if ($args[0] == People::class) {
array_shift($args);
return new PeopleRepository()->{$method}(...$args);
}
}
}
Then you might be able to typehint this using:
override(RepositoryFacade::loadById(0), type(0));
Of course the facade is not really the best pattern to be using in general so I can see how this might not be ideal.
I have a game where the player can finish some tasks.
I have separated the behaviour part of the task to its ORM part.
Eventually a copy of the task is being saved somewhere on the player's document (doesn't matter where for this specific question).
The problem is, I am not sure where to put the extra information that I send to the client that is not necessary for the behaviour itself, but it is needed to show the player information regarding the task itself.
This is my task interface:
interface ITask
{
/**
* #param Player $player
*/
public function init(Player $player);
/**
* #param PlayerAction $action
*/
public function progress(PlayerAction $action);
public function reset();
/**
* #return bool
*/
public function isComplete();
}
This is my abstract task:
abstract class BaseTask implements ITask
{
/**
* #var int
*/
public $id;
/**
* #var int
*/
protected $currentValue;
/**
* #var int
*/
protected $targetValue;
public function __construct($targetValue)
{
$this->currentValue = 0;
$this->targetValue = $targetValue;
}
/**
* #param int
*/
public abstract function setCurrentValue($current);
/**
* #return int
*/
public abstract function getCurrentValue();
/**
* #return int
*/
public abstract function getID();
/**
* #param int
*/
public abstract function setID($id);
/**
* #return int
*/
public abstract function getTargetValue();
/**
* #param int
*/
public abstract function setTargetValue($target);
/**
* #return boolean
*/
public function isComplete()
{
if ($this->getCurrentValue() >= $this->getTargetValue())
{
return true;
}
return false;
}
}
Now I need to decide how where to put the extra data, e.g description, title, theme etc...
I thought about two options: I can just put it on the base task
itself, but then what happens if I don't need it? I just leave it
blank? feel like the wrong place for me.
I could create a wrapper
class that will hold the task, but then I will need to always
call the wrapper to get to the task, and it feels kind of
wrong.
Looking for alternative suggestions.
You should inherit the CustomTask from TaskBase.
If you you have limitation in inheritance, encapsulate additional fields into a class called TaskAdditionalInfoBase and associate to the TaskBase.
Then various classes can inherit TaskAdditionalInfoBase to present a custom additional info to the the task.
I'm completely new to Zend framework (though I've already used Symfony2 and I've heard they're similar), and I've started a project in which I have to upgrade a site (that is already fully functional) that was created with Zend 1.11.
The aim of my upgrade is to allow data (that was originally stored in a database, and that will now be stored in nosql, and a database, and could be in the future stored elsewhere) to be more buildable and less strongly coupled with Zend's model. (Model as in the M of MVC).
In order to achieve this, I was asked to use a web service that would interact with the data, and Zend's model.
That way, when the data's structure would be modified, the Zend website wouldn't directly be impacted, (and would still work!) and we'd just have to re-arrange the web service.
Is there any elegant way to make Zend's model interact with a web service rather than a database?
I hope my question is understandable...
Have a nice day,
M.G.
You can use Data mapper pattern. As a reference, you can see how the module ZfcUser has adopted this pattern
You can create an interface of mapper for each entity and create an implementation according to the the data storage.
For example,
Product Entity
class Product
{
/**
* #var int
*/
protected $id;
/**
* #var string
*/
protected $name;
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
*
* #param int $id
* #return UserInterface
*/
public function setId($id)
{
$this->id = (int) $id;
return $this;
}
/**
* Get name.
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set name.
*
* #param string $name
* #return UserInterface
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
}
Product Mapper
<?php
<?php
namespace Product\Mapper;
interface ProductMapperInterface
{
/**
* #var int $id
* #returns \Product\Entity\Product
*/
public function findById($id);
/**
* #var array $criteria
* #returns \Product\Entity\Product[]
*/
public function find(array $criteria, .....);
/**
* #var \Product\Entity\Product $product
*/
public function insert($product);
/**
* #var \Product\Entity\Product $product
*/
public function update($product);
}
To populate the entity, you can use hydrators. As a reference, you can view how ZfcUser uses hydrators.
I'm looking for a way to extend my Symfony2 (i currently use 2.3) Entity class with a method to effectively filter its relations on demand. So, imaging i have such 2 classes with OneToMany relation:
/**
* ME\MyBundle\Entity\Kindergarten
*/
class Kindergarten
{
/**
* #var integer $id
*/
private $id;
/**
* #var ME\MyBundle\Entity\Kinder
*/
private $kinders;
public function __construct()
{
$this->kinders = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get kinders
*
* #return Doctrine\Common\Collections\Collection
*/
public function getKinders()
{
return $this->kinders;
}
}
/**
* ME\MyBundle\Entity\Kinder
*/
class Kinder
{
/**
* #var integer $id
*/
private $id;
/**
* #var string $name
*/
private $name;
/**
* #var integer $age
*/
private $age;
}
My goal is to have a method on Kindergarten class to get on demand all kinders with age, for instance, between 10 and 12:
$myKindergarten->getKindersByAgeInInterval(10,12);
Of course, i can do something like:
class Kindergarten
{
...
public function getKindersByAgeInInterval($start, $end)
{
return $this->getKinders()->filter(
function($kinder) use ($start, $end)
{
$kinderAge = $kinder->getAge();
if($kinderAge < $start || $kinderAge > $end)
{
return false;
}
return true;
}
);
}
...
}
The solution above will work, but it's very inefficient, since I need to iterate across ALL kinders which can be a really big list and have no way to cache such filters. I have in mind usage of Criteria class or some proxy patterns, but not sure about a way to do it nice in Symfony2 especially since they probably will need access to EntityManager.
Any ideas?
I would suggest extracting this responsibility into an EntityRepository:
<?php
class KinderRepository extends \Doctrine\ORM\EntityRepository
{
public function findByKindergartenAndAge(Kindergarten $entity, $minAge = 10, $maxAge = 20)
{
return $this->createQueryBuilder()
->... // your query logic here
}
}
All the lookups should really happen in classes where you have access to the entity manager.
This is actually the way suggested by the Doctrine architecture. You can never have access to any services from your entities, and if you ever think you need it, well, then something is wrong with your architecture.
Of course, it may occur to you that the repository method could become pretty ugly if you later decide on adding more criteria (imagine you'll be searching by kindergarten, age, weight and height too, see http://www.whitewashing.de/2013/03/04/doctrine_repositories.html). Then you should consider implementing more logic, but again, that should not be that necessary.
I am working on a project that utilizes Zend Framework 1.12 integrated with doctrine 2. I am having trouble with a Bidirectional One-to-Many relation in said project.
The two entities concerning my problem are Team and Player; a team can have many players.
The Team Entity:
namespace Entities;
use Doctrine\Common\Collections\Collection,
Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity(repositoryClass="Repositories\TeamRepository")
* #Table(name="team")
*/
class Team extends Entity{
/**
* #Column(type="string", length=255)
*/
protected $name;
/**
* #OneToMany(targetEntity="Player", mappedBy="team")
*/
protected $players;
public function __construct() {
$this->players = new ArrayCollection();
}
public function getName(){
return $this->name;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getPlayers() {
return $this->players;
}
And the Player Entity:
namespace Entities;
/**
* #Entity(repositoryClass="Repositories\PlayerRepository")
* #Table(name="player")
*/
class Player extends Entity{
public function __construct() {
}
/**
* #Column(type="string", length=255)
*/
protected $name;
/**
* #ManyToOne(targetEntity="Team", inversedBy="players")
* #JoinColumn(name="team_id", referencedColumnName="id")
*/
protected $team;
public function getName(){
return $this->name;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getTeam() {
return $this->team;
}
public function setTeam($team) {
$this->team = $team;
return $this;
}
}
Now in my player controller for example I can retrieve a player and get the team name
$oPlayer = $this->_em->find('Entities\Player', $player_id);
$teamname = $oPlayer->getTeam()->getName();
This works as expected and I successfully obtain the name of the players team.
However the other way around does not work. I can not retrieve all the players given a team
$oTeam = $this->_em->find('Entities\Team', $team_id);
$oPlayers = $oTeam->getPlayers();
When I var_dump this the result looks like
object(Doctrine\ORM\PersistentCollection)#238 (9) {
["snapshot":"Doctrine\ORM\PersistentCollection":private]=>
array(0) {
}
["owner":"Doctrine\ORM\PersistentCollection":private]=>
object(Entities\Team)#195 (7) {
...
}
Note that a persistenCollection seems to be build, however the array is empty.
I have read the doctrine manual extensively and googled my behind off and am now at a loss.
Also the fact that there is no error message, I am having a hard time solving this problem.
Any pointers would be more than welcome.
The problem has been resolved. I have been trying to puzzle the solution together for posterity but have come to the conclusion that I no longer have the files where I now suspect the original error was located. I managed to get a working copy derived from another project. By brute force 'diff'-ing and replacing code I traced the error of the empty array of the persistent collection, to my bootstrap and resources/doctrine.php config file, which unfortunately I do not have any longer and therefore can not confirm this. With string(4) "team" still being returned (as discussed in the comments) embarrassingly I finally found out that it was just due to a die() I put in the doctrine library file and forgot about.