Better DI for database.
[rock.divinelegy.git] / DataAccess / DataMapper / DataMapper.php
1 <?php
2
3 namespace DataAccess\DataMapper;
4
5 use Domain\Entities\IDivineEntity;
6 use DataAccess\IDatabaseFactory;
7 use DataAccess\DataMapper\IDataMapper;
8 use DataAccess\Queries\IQueryBuilder;
9 use DataAccess\DataMapper\Helpers\AbstractPopulationHelper;
10 use ReflectionClass;
11
12 class DataMapper implements IDataMapper
13 {
14 private $_db;
15 private $_maps;
16
17 public function __construct($maps, IDatabaseFactory $databaseFactory)
18 {
19 $this->_db = $databaseFactory->createInstance();
20 $this->_maps = include $maps;
21 }
22
23 public function map($entityName, IQueryBuilder $queryBuilder)
24 {
25 $queryString = $queryBuilder->buildQuery();
26
27 $statement = $this->_db->prepare(sprintf($queryString,
28 $this->_maps[$entityName]['table']
29 ));
30
31 $statement->execute();
32 $rows = $statement->fetchAll();
33
34 $entities = array();
35
36 foreach($rows as $row)
37 {
38 $className = $this->_maps[$entityName]['class']; //the entity to instantiate and return
39 $constructors = AbstractPopulationHelper::getConstrutorArray($this->_maps, $entityName, $row, $this->_db);
40
41 if(count($constructors) == 0)
42 {
43 $class = new $className;
44 } else {
45 $r = new ReflectionClass($className);
46 $class = $r->newInstanceArgs($constructors);
47 }
48
49 $class->setId($row['id']);
50 $entities[$row['id']] = $class;
51 }
52
53 return $entities;
54 }
55
56 public function save(IDivineEntity $entity)
57 {
58 $queries = AbstractPopulationHelper::generateUpdateSaveQuery($this->_maps, $entity, $entity->getId(), $this->_db);
59
60 // if($queries['TYPE'] == AbstractPopulationHelper::QUERY_TYPE_CREATE)
61 // {
62 unset($queries['TYPE']);
63 $idMap = [];
64 foreach($queries as $index => $query)
65 {
66 $runQuery = true;
67 if (preg_match_all('/'.preg_quote('%').'(.*?)'.preg_quote('%').'/s', $query, $matches)) {
68 foreach($matches[1] as $index_ref)
69 {
70 if($index_ref != 'MAIN_QUERY_ID')
71 {
72 $index_id = str_replace('INDEX_REF_', '', $index_ref);
73 $query = str_replace('%INDEX_REF_' . $index_id . '%', $idMap['INDEX_REF_' . $index_id], $query);
74 } else {
75 $runQuery = false;
76 }
77 }
78 }
79
80 if($runQuery)
81 {
82 $statement = $this->_db->prepare($query);
83 $statement->execute();
84 $refIndex = $index+1;
85 $idMap['INDEX_REF_' . $refIndex] = $this->_db->lastInsertId();
86 unset($queries[$index]);
87 } else {
88 //update query so that other references are resolved.
89 $queries[$index] = $query;
90 }
91 }
92
93 //at this point we have queries left that depend on the main query id
94 foreach($queries as $query)
95 {
96 $query = str_replace('%MAIN_QUERY_ID%', end($idMap), $query);
97 $statement = $this->_db->prepare($query);
98 $statement->execute();
99 }
100 //}
101
102 echo '<pre>';
103 print_r($queries);
104 echo '</pre>';
105 }
106
107 //TODO: Implement
108 public function remove(IDivineEntity $entity) {
109 ;
110 }
111 }