Completed
Push — master ( 857622...96d875 )
by Ron
02:21
created

DiffStorageStoreRowData::applyOptions()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 12
Code Lines 8

Duplication

Lines 6
Ratio 50 %

Importance

Changes 2
Bugs 2 Features 1
Metric Value
c 2
b 2
f 1
dl 6
loc 12
rs 8.8571
cc 6
eloc 8
nc 5
nop 2
1
<?php
2
namespace DataDiff;
3
4
use Exception;
5
6
class DiffStorageStoreRowData implements DiffStorageStoreRowDataInterface {
7
	/** @var array */
8
	private $row;
9
	/** @var array */
10
	private $keys;
11
	/** @var array */
12
	private $valueKeys;
13
	/** @var array */
14
	private $converter;
15
	/** @var array */
16
	private $foreignRow;
17
18
	/**
19
	 * @param array $row
20
	 * @param array $foreignRow
21
	 * @param array $keys
22
	 * @param array $valueKeys
23
	 * @param array $converter
24
	 */
25
	public function __construct(array $row = [], array $foreignRow = [], array $keys, array $valueKeys, array $converter) {
26
		$this->row = $row;
27
		$this->foreignRow = $foreignRow;
28
		$this->keys = $keys;
29
		$this->valueKeys = $valueKeys;
30
		$this->converter = $converter;
31
	}
32
33
	/**
34
	 * @param array $options
35
	 * @return array
36
	 */
37
	public function getData(array $options = []) {
38
		return $this->applyOptions($this->row, $options);
39
	}
40
41
	/**
42
	 * @param array $options
43
	 * @return array
44
	 */
45
	public function getForeignData(array $options = []) {
46
		return $this->applyOptions($this->foreignRow, $options);
47
	}
48
49
	/**
50
	 * @param array $options
51
	 * @return array
52
	 */
53
	public function getKeyData(array $options = []) {
54
		$row = $this->getData();
55
		$row = array_intersect_key($row, array_combine($this->keys, $this->keys));
56
		return $row;
57
	}
58
59
	/**
60
	 * @param array $options
61
	 * @return array
62
	 */
63
	public function getValueData(array $options = []) {
64
		$row = $this->getData();
65
		$row = array_intersect_key($row, array_combine($this->valueKeys, $this->valueKeys));
66
		return $row;
67
	}
68
69
	/**
70
	 * @param array $fields
71
	 * @return array
72
	 */
73
	public function getDiff(array $fields = null) {
74
		$diff = [];
75
		$localRow = $this->getData(['keys' => $fields]);
76
		$foreignRow = $this->getForeignData(['keys' => $fields]);
77
		$keys = array_keys(array_merge($this->row, $this->foreignRow));
78
		$formattedLocalRow = $this->formatRow($localRow);
79
		$formattedForeignRow = $this->formatRow($foreignRow);
80
		foreach($keys as $key) {
81
			$conv = function (array $row) use ($key) {
82
				$value = null;
83
				if(array_key_exists($key, $row)) {
84
					$value = $row[$key];
85
					if(array_key_exists($key, $this->converter)) {
86
						$value = call_user_func($this->converter[$key], $value);
87
					}
88
				}
89
				return $value;
90
			};
91
			$localValue = call_user_func($conv, $formattedLocalRow);
92
			$foreignValue = call_user_func($conv, $formattedForeignRow);
93
			if(json_encode($localValue) !== json_encode($foreignValue)) {
94
				$diff[$key] = ['local' => $localValue, 'foreign' => $foreignValue];
95
			}
96
		}
97
		return $diff;
98
	}
99
100
	/**
101
	 * @param array $fields
102
	 * @param mixed $format
103
	 * @return array
104
	 * @throws Exception
105
	 */
106
	public function getDiffFormatted(array $fields = null, $format = null) {
107
		$diff = $this->getDiff($fields);
108
		if($format === null) {
109
			$result = [];
110
			foreach($diff as $fieldName => $values) {
111
				$result[] = sprintf("%s: %s -> %s", $fieldName, $values['foreign'], $values['local']);
112
			}
113
			return join(', ', $result);
114
		}
115
		throw new Exception("Unknown format: {$format}");
116
	}
117
118
	/**
119
	 * @param array $row
120
	 * @param array $options
121
	 * @return array
122
	 */
123
	private function applyOptions(array $row, array $options) {
124
		if(count($options) < 1) {
125
			return $row;
126
		}
127 View Code Duplication
		if(array_key_exists('keys', $options) && is_array($options['keys'])) {
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...
128
			$row = array_intersect_key($row, array_combine($options['keys'], $options['keys']));
129
		}
130 View Code Duplication
		if(array_key_exists('ignore', $options) && is_array($options['ignore'])) {
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...
131
			$row = array_diff_key($row, array_combine($options['ignore'], $options['ignore']));
132
		}
133
		return $row;
134
	}
135
136
	/**
137
	 * @param array $row
138
	 * @return array
139
	 */
140
	private function formatRow($row) {
141
		$schema = $this->converter;
142
		$schema = array_map(function () { return null; }, $schema);
143
		$row = array_merge($schema, $row);
144
		return $row;
145
	}
146
}
147