Issues (56)

src/EntityManager.php (3 issues)

1
<?php
2
3
/**
4
 * Platine ORM
5
 *
6
 * Platine ORM provides a flexible and powerful ORM implementing a data-mapper pattern.
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine ORM
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13
 * of this software and associated documentation files (the "Software"), to deal
14
 * in the Software without restriction, including without limitation the rights
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
 * copies of the Software, and to permit persons to whom the Software is
17
 * furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included in all
20
 * copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
 * SOFTWARE.
29
 */
30
31
/**
32
 *  @file EntityManager.php
33
 *
34
 *  The EntityManager class
35
 *
36
 *  @package    Platine\Orm
37
 *  @author Platine Developers Team
38
 *  @copyright  Copyright (c) 2020
39
 *  @license    http://opensource.org/licenses/MIT  MIT License
40
 *  @link   https://www.platine-php.com
41
 *  @version 1.0.0
42
 *  @filesource
43
 */
44
45
declare(strict_types=1);
46
47
namespace Platine\Orm;
48
49
use Platine\Database\Connection;
50
use Platine\Orm\Mapper\EntityMapper;
51
use Platine\Orm\Query\EntityQuery;
52
use ReflectionClass;
53
use ReflectionException;
54
use RuntimeException;
55
56
/**
57
 * @class EntityManager
58
 * @package Platine\Orm
59
 * @template TEntity as Entity
60
 */
61
class EntityManager
62
{
63
    /**
64
     * The date format
65
     * @var string
66
     */
67
    protected string $dateFormat;
68
69
    /**
70
     * The cache of already resolved entities mappers
71
     * @var array<string, EntityMapper<TEntity>>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string, EntityMapper<TEntity>> at position 4 could not be parsed: Expected '>' at position 4, but found 'EntityMapper'.
Loading history...
72
     */
73
    protected array $entityMappers = [];
74
75
    /**
76
     * Create new instance
77
     * @param Connection $connection
78
     */
79
    public function __construct(protected Connection $connection)
80
    {
81
        $this->dateFormat = $connection->getDriver()->getDateFormat();
82
    }
83
84
    /**
85
     *
86
     * @return Connection
87
     */
88
    public function getConnection(): Connection
89
    {
90
        return $this->connection;
91
    }
92
93
    /**
94
     *
95
     * @return string
96
     */
97
    public function getDateFormat(): string
98
    {
99
        return $this->dateFormat;
100
    }
101
102
    /**
103
     * Get an instance of EntityQuery
104
     * @param class-string<TEntity> $entityClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TEntity> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TEntity>.
Loading history...
105
     * @return EntityQuery<TEntity>
106
     */
107
    public function query(string $entityClass): EntityQuery
108
    {
109
        return new EntityQuery($this, $this->getEntityMapper($entityClass));
110
    }
111
112
    /**
113
     * Resolve the entity mapper for the given entity class
114
     * @param class-string<TEntity> $entityClass
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TEntity> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TEntity>.
Loading history...
115
     * @return EntityMapper<TEntity>
116
     */
117
    public function getEntityMapper(string $entityClass): EntityMapper
118
    {
119
        if (isset($this->entityMappers[$entityClass])) {
120
            return $this->entityMappers[$entityClass];
121
        }
122
123
        try {
124
            $reflection = new ReflectionClass($entityClass);
125
        } catch (ReflectionException $ex) {
126
            throw new RuntimeException(
127
                sprintf('Error when build the mapper for entity [%s]', $entityClass),
128
                0,
129
                $ex
130
            );
131
        }
132
133
        if ($reflection->isSubclassOf(Entity::class) === false) {
134
            throw new RuntimeException(sprintf(
135
                '[%s] must extend [%s]',
136
                $entityClass,
137
                Entity::class
138
            ));
139
        }
140
141
        $mapper = new EntityMapper($entityClass);
142
143
        $callback = $entityClass . '::mapEntity';
144
        if (is_callable($callback)) {
145
            $callback($mapper);
146
        }
147
148
        return $this->entityMappers[$entityClass] = $mapper;
149
    }
150
}
151