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