Completed
Push — master ( de7e19...857622 )
by Ron
02:42
created

DiffStorageStoreRowData::getDiffFormatted()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 1
Metric Value
c 1
b 1
f 1
dl 0
loc 11
rs 9.4285
cc 3
eloc 8
nc 3
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
		if(array_key_exists('keys', $options)) {
128
			$row = array_intersect_key($row, array_combine($options['keys'], $options['keys']));
129
		}
130
		if(array_key_exists('ignore', $options)) {
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