Passed
Push — master ( 800a7c...2f3156 )
by dima
03:06
created

AbstractOptDataMapper::addMappingField()   D

Complexity

Conditions 9
Paths 16

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 5
Bugs 0 Features 0
Metric Value
c 5
b 0
f 0
dl 0
loc 26
ccs 0
cts 19
cp 0
rs 4.9091
cc 9
eloc 14
nc 16
nop 2
crap 90
1
<?php
2
/*
3
 * To change this license header, choose License Headers in Project Properties.
4
 * To change this template file, choose Tools | Templates
5
 * and open the template in the editor.
6
 */
7
8
namespace SimpleORM;
9
10
/**
11
 * Description of AbstractOptDataMapper
12
 *
13
 * @author d.lanec
14
 */
15
abstract class AbstractOptDataMapper extends AbstractDataMapper{
16
	
17
	protected $soft_delete_key;
18
	
19
	protected $key;
20
	
21
	protected $table;
22
	
23
	protected $mapping_fields;
24
	
25
	protected $mapping_fields_aliases;
26
	
27
	protected $relations = [];
28
29
	protected $DI;
30
			
31
	function __construct(\League\Container\Container $DI, QueryBuilderInterface $adapter, $db_name = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
32
		
33
		$this->DI = $DI;
34
		
35
		$this->setMappingFields();
36
		
37
		parent::__construct($adapter, $db_name);
38
	}
39
40
	/**
41
	 * Установка поля для маппинга
42
	 */
43
	protected function addMappingField($alias,$field = null){
44
		
45
		if(is_string($field)){
46
			$field = ['field'	=>	$field];
47
		}
48
		elseif(empty($field)){
49
			$field = ['field'	=>	$alias];
50
		}
51
		elseif(is_array($field) && !isset($field['field'])){
52
			$field['field']	= $alias;
53
		}
54
	
55
		$this->mapping_fields[$alias] = $field;
56
57
		if(isset($field['primary']) && $field['primary']===true){
58
			$this->key = $field['field'];
59
		}
60
		
61
		if(isset($field['softdelete']) && $field['softdelete']===true){
62
			$this->soft_delete_key = $field['field'];
63
		}
64
		
65
		$this->mapping_fields_aliases[$field['field']] = $alias;
66
		
67
		return $this;
68
	}
69
	
70
	/**
71
	 * Уставнока таблицы
72
	 */
73
	protected function setEntityTable() {
74
		return $this->table;
75
	}
76
77
	/**
78
	 * Установка ключа
79
	 */
80
	protected function getPrimaryKey() {
81
		return $this->key;
82
	}
83
84
	/**
85
	 * Устанвка поля для мягкого удаляения
86
	 */
87
	protected function setSoftDeleteKey() {
88
		return $this->soft_delete_key;
89
	}
90
91
	/**
92
	 * Подготавливаем конечный вариант Сущности
93
	 * 
94
	 * @param \Core\Infrastructure\EntityInterface $Entity
95
	 * @param array $row
96
	 * @return \Core\Infrastructure\EntityInterface
97
	 * @throws BadMethodCallException
98
	 */
99
	protected function buildEntity(EntityInterface $Entity, array $row){
100
		
101
        foreach ($this->mapping_fields as $alias => $cfg ) {
102
			
103
			$value = false;
104
			
105
			$field = $cfg['field'];
106
			
107
			$method_set = 'set' . ucfirst($alias);
108
			
109
			if(!method_exists($Entity, $method_set )){
110
				throw new BadMethodCallException("Метод {$method_set}  не определен");
111
			}			
112
			
113
			//событие на формирование поля
114
			if( isset($cfg['build']) && is_object($cfg['build']) ){
115
				$value = call_user_func($cfg['build'], $row);
116
			}
117
			//на связь
118
			elseif(isset($cfg['relation'])){
119
				
120
				$mapper = $this->DI->get($cfg['relation']);
121
				
122
				if($this->use_joins===true){
123
					$value = $mapper->createEntity($row);
124
				}
125
				else{
126
					$fkey = isset($cfg['on']) ? $cfg['on'] :$mapper->key;
127
					$value = $mapper->findBySpecification((new Specification)->setWhere($fkey, $row[$field]));
128
				}				
129
				
130
			}
131 View Code Duplication
			elseif(is_string($field) && isset($row[strtolower($field)])){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
				$value = $row[strtolower($field)];
133
			}
134
			
135
			if($value!==false)
136
				$Entity->{$method_set}($value);
137
			
138
        }
139
		
140
        return $Entity;		
141
	}	
142
143
	
144
	/**
145
	 * из объекта формирует массив
146
	 * @param \Core\Infrastructure\EntityInterface $Entity
147
	 * @return \Core\Infrastructure\EntityInterface
148
	 * @throws BadMethodCallException
149
	 */
150
	protected function unbuildEntity(EntityInterface $Entity){
151
		
152
		$row = [];
153
154
        foreach ($this->mapping_fields as $alias => $cfg ) {
155
			
156
			$field = $cfg['field'];
157
			
158
			$method_get = 'get' . ucfirst($alias);
159
			
160
			if(!method_exists($Entity, $method_get )){
161
				throw new BadMethodCallException("Метод {$method_get}  не определен");
162
			}		
163
			
164
			//--------------------------------------------------------------------
165
			if( isset($cfg['unbuild']) && is_object($cfg['unbuild']) ){
166
				$value = call_user_func($cfg['unbuild'], $Entity->{$method_get}() );
167
			}
168
			elseif(isset($cfg['relation'])){
169
				
170
				if(isset($cfg['on']))
171
					$fkey = $this->DI->get($cfg['relation'])->getFieldAlias($cfg['on']);
172
				else
173
					$fkey = 'id';
174
				
175
				$value = $Entity->{$method_get}()->{'get'.$fkey}();
176
				
177
			}			
178
			else{
179
				$value = $Entity->{$method_get}();
180
			}			
181
						
182
			$row[$field] = $value;
183
184
        }
185
186
        return $row;		
187
	}	
188
	
189
	
190
	public function getFieldAlias($field){
191
		
192
		return $this->mapping_fields_aliases[$field];
193
		
194
	}
195
196
		/**
197
	 * Построение join-ов
198
	 */
199
	protected function setRelations(ISpecificationCriteria $Specification){
200
201
		$joins = [];
202
203
		foreach ($this->mapping_fields as $field => $cfg){
204
			if(isset($cfg['relation'])){
205
				
206
				$this->relations[$field] = $mapper = $this->DI->get($cfg['relation']);
207
208
				$table = $mapper->getEntityTable();
209
210
				$relation_key = isset($cfg['on'])? $cfg['on'] : $mapper->key;
211
				
212
				$joins[$table] = [
213
						'alias'	=> $field,
214
						//'type'	=> 'INNER',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
215
						'on'	=> "`{$this->table}`.{$cfg['field']} = `{$field}`.{$relation_key}"
216
				];
217
218
			}
219
		}	
220
221
		if($this->use_joins===true){
222
			$Specification->setJoins($joins);
223
		}			
224
	}	
225
	
226
	/**
227
	 * На успешное сохранение
228
	 * @param \SimpleORM\EntityInterface $Entity
229
	 */
230 View Code Duplication
	protected function onSaveSuccess(EntityInterface $Entity){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
231
		
232
		
233
		foreach ($this->relations as $alias => $mapper) {
234
			$Entity = $Entity->{'get'.$alias}();
235
			if(!$mapper->save($Entity)){
236
				throw new \Autoprice\Exceptions\EntityNotSaveException('Unable to save Entity!');
237
			}
238
		}
239
		
240
		return true;
241
	}
242
	
243
	/**
244
	 * На успешное удаление
245
	 * @param \SimpleORM\EntityInterface $Entity
246
	 */
247 View Code Duplication
	protected function onDeleteSuccess(EntityInterface $Entity) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
248
		foreach ($this->relations as $alias => $mapper) {
249
			$Entity = $Entity->{'get'.$alias}();
250
			if(!$mapper->delete($Entity)){
251
				throw new \Autoprice\Exceptions\EntityNotDeleteException('Unable to delete Entity!');
252
			}
253
		}
254
		
255
		return true;
256
	}
257
}
258