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