Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review of docs 1 #617

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions docs/assets/LaravelDoctrineOrm.skipper
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0"?>
<skipper version="3.3.7.1828" mvc="Without MVC" orm="Doctrine2" name="laravel-doctrine-orm" uuid="05bd1ab1-6fa2-494a-ba43-d95b253dcc78">
<module name="\App\Doctrine\ORM\Entity" local-name="App\Doctrine\ORM\Entity" namespace="\" export-format="Doctrine2PhpAttributes" export-path="Entity" uuid="ffabe3f5-6845-47b9-bf58-d50040e32df3">
<entity name="\Theory" local-name="Theory" namespace="\" uuid="0b5e27f7-8bbb-4272-9ae7-33029445c61a">
<field name="id" type="integer" required="true" unique="true" primary="true" auto-increment="true" uuid="a512cdab-c3ab-4f16-8b34-3feb50bccc32"/>
<field name="title" type="string" required="true" uuid="d30d20a6-742b-4ac3-a317-d37414c4762a"/>
<field name="scientist_id" type="integer" required="true" uuid="0bdfca1a-c956-4891-9e72-43ec1c8abdb7"/>
<orm-attributes>
<attribute name="repository-class">App\Doctrine\ORM\Repository\TheoryRepository</attribute>
</orm-attributes>
</entity>
<association from="\Theory" to="\Scientist" caption="Scientist Theories" owner-alias="theories" inverse-alias="scientist" many-owner="true" many-inverse="false" parent-required="true" uuid="2ae5c987-bccb-401d-9ce7-cbcf840081b7">
<association-field from="scientist_id" to="id" uuid="38740ad6-d179-4bc2-b15b-b3d5089aa1c0"/>
</association>
<entity name="\Scientist" local-name="Scientist" namespace="\" uuid="0d22923a-73b4-4575-b83b-7f5f72f46fc5">
<field name="id" type="integer" required="true" unique="true" primary="true" auto-increment="true" uuid="57e7fc69-6afe-4376-965c-13155aef0a97"/>
<field name="firstName" type="string" uuid="ae683788-22ce-4d37-b209-ae35b5deceb1"/>
<field name="lastName" type="string" required="true" uuid="41672585-785a-467f-80f3-47c10ff96786"/>
<orm-attributes>
<attribute name="repository-class">App\Doctrine\ORM\Repository\ScientistRepository</attribute>
</orm-attributes>
</entity>
</module>
<visual-data>
<association uuid="2ae5c987-bccb-401d-9ce7-cbcf840081b7" caption1-position-x="0" caption1-position-y="0" center-position-x="0" center-position-y="0" color="#969696"/>
<entity uuid="0b5e27f7-8bbb-4272-9ae7-33029445c61a" bg-color="#FFFFFF" hdr-color="#D2D2D2" position-x="119" position-y="128" size-x="0" size-x2="104" size-y="0" size-y2="59"/>
<entity uuid="0d22923a-73b4-4575-b83b-7f5f72f46fc5" bg-color="#FFFFFF" hdr-color="#D2D2D2" position-x="19" position-y="22" size-x="0" size-x2="93" size-y="0" size-y2="59"/>
<module uuid="ffabe3f5-6845-47b9-bf58-d50040e32df3" bg-color="#FEFCE8" position-x="61" position-y="72" size-x="11" size-x2="251" size-y="22" size-y2="228"/>
<project uuid="05bd1ab1-6fa2-494a-ba43-d95b253dcc78" size-x="0" size-x2="362" size-y="0" size-y2="350"/>
</visual-data>
</skipper>
Binary file added docs/assets/scientist-theory.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 3 additions & 6 deletions docs/auth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,9 @@ wish to use with authentication.

class User implements \Illuminate\Contracts\Auth\Authenticatable
{

/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
#[ORM\Id]
#[ORM\Column(type: "integer")]
#[ORM\GeneratedValue(strategy: "AUTO")]
protected $id;

public function getAuthIdentifierName()
Expand Down
145 changes: 48 additions & 97 deletions docs/entities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,73 @@
Entities
========

Out of the box, this package uses the default Laravel connection from
the ``.env`` file ``DB_CONNECTION``, which means that you are ready to start
fetching and persisting.
The default Doctrine ORM connection comes from
the ``.env`` file: ``DB_CONNECTION``. Further configuration of a new install
is not necessary to get started.

Unlike Eloquent, Doctrine ORM is **not** an active record pattern, but a
`data-mapper <https://tsh.io/blog/active-record-vs-data-mapper-patterns-in-php/>`_
pattern. Every active record model extends a base class that implements all
the persistent, database, logic.

Entities are objects with identity. Their identity has a conceptual meaning
inside your domain. In an application, each theory has a unique id. You can
uniquely identify each theory by that id.

Doctrine entities don't extend any class, they are just plain PHP classes
with properties (and, historically, getters and setters).
Historically, the properties are protected or private, so they only can be accessed
through getters and setters. However, with property hooks in PHP 8.4, entities
composed of gloal properties only will become the norm.


.. code-block:: php

$scientist = new Scientist(
'Albert',
'Einstein'
);
$scientist = new Scientist();
$scientist->firstName = 'Albert';
$scientist->lastName = 'Einstein';

$theory = new Theory();
$theory->title = 'Theory of Relativity';
$theory->scientist = $scientist;

$scientist->addTheory(
new Theory('Theory of relativity')
);
$scientist->theories->add($theory);

EntityManager::persist($scientist);
EntityManager::persist($theory);
EntityManager::flush();

Unlike Eloquent, Doctrine is **not** an Active Record pattern, but a
Data Mapper pattern. Every Active Record model extends a base class
(with all the database logic), which has a lot of overhead and dramatically
slows down your application with thousands or millions of records.
Doctrine entities don't extend any class, they are just regular PHP classes
with properties and getters and setters.
Generally the properties are protected or private, so they only can be accessed
through getters and setters.

However, with property hooks in 8.4, entities composed of gloal properties only
may become the norm.
In Doctrine ORM, the domain and business logic is completely separated from
the persistence logic. This means we have to tell Doctrine how it should map
the columns from the database to our Entity class.
In this example we are using attributes. Another possibility is XML.

The domain/business logic is completely separated from the persistence logic.
This means we have to tell Doctrine how it should map the columns from the
database to our Entity class. In this example we are using annotations.
Other possiblities are YAML, XML or PHP arrays.
.. note::

There used to be more ways to define your metadata in Doctrine ORM, but
time has shown the only options of Attributes and XML are necessary.

Entities are objects with identity. Their identity has a conceptual meaning
inside your domain. In an application each article has a unique id. You can
uniquely identify each article by that id.

Relations are stored in ``ArrayCollection``. It's advised to always set this
default value in the constructor. ``$this->theories = new ArrayCollection()``.
Relations are of type ``Doctrine\Common\Collections\Collection``. When writing
an entity, you should assign an empty collection property to a new
``Doctrine\Common\Collections\ArrayCollection``.
You can easily add on new relations with ``->add()``, remove them with
``->removeElement()`` or check if the relation is already defined with
``->contains()``

The ``Scientist`` entity used in the example above looks like this when using
The ``Scientist`` entity, used in the example above, looks like this when using
annotations for the meta data.

.. image:: assets/scientist-theory.png

.. code-block:: php

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

#[ORM\Entity]
#[ORM\Entity(repositoryClass: "App\Doctrine\ORM\Repository\ScientistRepository")]
class Scientist
{
#[ORM\Id]
Expand All @@ -66,62 +77,28 @@ annotations for the meta data.
private int $id;

#[ORM\Column(type: "string", nullable: false)]
private string $firstname;
private string $firstName;

#[ORM\Column(type: "string", nullable: false)]
private string $lastname;
private string $lastName;

#[ORM\OneToMany(targetEntity: \Theory::class, mappedBy: "scientist")]
#[ORM\OneToMany(targetEntity: Theory::class, mappedBy: "scientist")]
private Collection $theories;

/**
* @param $firstname
* @param $lastname
*/
public function __construct()
{
$this->theories = new ArrayCollection();
}

public function getId(): int
{
return $this->id;
}

public function getFirstname(): string
{
return $this->firstname;
}

public function getLastname(): string
{
return $this->lastname;
}

public function addTheory(Theory $theory): self
{
if (! $this->theories->contains($theory)) {
$theory->setScientist($this);
$this->theories->add($theory);
}

return $this;
}

public function getTheories(): Collection
{
return $this->theories;
}
}


The related `Theory` entity would look like this:
The related `Theory` entity looks like this:

.. code-block:: php

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Entity(repositoryClass: "App\Doctrine\ORM\Repository\TheoryRepository")]
class Theory
{
#[ORM\Id]
Expand All @@ -132,35 +109,9 @@ The related `Theory` entity would look like this:
#[ORM\Column(type: "string", nullable: false)]
private string $title;

#[ORM\ManyToOne(targetEntity: \Scientist::class, inversedBy: "theories")]
#[ORM\ManyToOne(targetEntity: Scientist::class, inversedBy: "theories")]
#[ORM\JoinColumn(name: "scientist_id", referencedColumnName: "id", nullable: false)]
private Scientist $scientist;

public function __construct()
{
}

public function getId(): int
{
return $this->id;
}

public function getTitle(): string
{
return $this->title;
}

public function setScientist(Scientist $scientist): self
{
$this->scientist = $scientist;

return $this;
}

public function getScientist(): Scientist
{
return $this->scientist;
}
}


Expand Down
9 changes: 5 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ Doctrine ORM ^3.0, and Doctrine DBAL ^4.0.
Introduction
============

Doctrine 2 is an object-relational mapper (ORM) for PHP that provides
transparent persistence for PHP objects. It uses the Data Mapper pattern at
the heart, aiming for a complete separation of your domain/business logic
Doctrine ORM is an object-relational mapper for PHP that provides
transparent persistence for PHP objects.
Doctrine uses the `data-mapper pattern <https://tsh.io/blog/active-record-vs-data-mapper-patterns-in-php/>`_,
aiming for a complete separation of your domain and business logic
from the persistence in a relational database management system.

The benefit of Doctrine for the programmer is the ability to focus on the
object-oriented business logic and worry about persistence only as a
secondary problem. This doesn’t mean persistence is downplayed by Doctrine 2.
secondary problem. This doesn’t mean persistence is downplayed by Doctrine ORM.
However, it is our belief that there are considerable benefits for
object-oriented programming if persistence and entities are seperate.

Expand Down
38 changes: 22 additions & 16 deletions docs/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,38 +39,44 @@ Environment variables used inside the config
Application Folder Structure
============================

Doctrine entities do not belong in the ``Model`` directory.
Because Eloquent is a part of the Laravel Framework, you will need a
directory structure just for Doctrine that is flexible enough to accomodate
two ORMs.
Doctrine entities do not belong in the ``Model`` directory. Doctrine supplies
not just an ORM but also an `ODM <https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/2.9/index.html>`_.
So, when using Doctrine ORM, it is important to always address it as ORM.

This is the recommended directory structure for a Doctrine ORM Installation:

.. code-block:: bash

~/app/ORM/Doctrine
~/app/ORM/Doctrine/Entity
~/app/ORM/Doctrine/Repository
~/app/ORM/Doctrine/Subscriber
~/app/ORM/Doctrine/Listener
~/app/Doctrine/ORM

If you are using both Eloquent and Doctrine together in an application, it is
suggested you modify your directory structure to accomodate both in a logical
way.
Underneath this directory you may choose to have one directory per entity
manager or, for an app with just one entity manager, the following directories
are suggested:

.. code-block:: bash

~/app/ORM/Eloquent
~/app/ORM/Eloquent/Models
~/app/Doctrine/ORM/Entity
~/app/Doctrine/ORM/Repository
~/app/Doctrine/ORM/Subscriber
~/app/Doctrine/ORM/Listener

If you are new to Doctrine ORM, it is recommended you review the
`Repository Pattern <https://blog.mnavarro.dev/the-repository-pattern-done-right>`_.


Entity Metadata
===============

Change the ``config/doctrine.php`` file paths

.. code-block:: php

'paths' => [
base_path('app/ORM/Doctrine/Entity'),
base_path('app/Doctrine/ORM/Entity'),
],


Manual registration
Manual Registration
===================

After updating composer, add the ServiceProvider to the providers
Expand Down
Loading