22
33namespace Differ ;
44
5- class FilesDiffCommand implements CommandInterface
5+ class FilesDiffCommand implements FilesDiffCommandInterface
66{
77 private FileReaderInterface $ fileReader ;
8+
9+ /**
10+ * @var array<int,string> $filesPaths
11+ */
812 private array $ filesPaths ;
13+
14+ /**
15+ * @var array<mixed,mixed> $filesDataItems
16+ */
917 private array $ filesDataItems ;
18+
19+ /**
20+ * @var array<mixed,mixed> $content1Descriptor
21+ */
1022 private array $ content1Descriptor ;
23+
24+ /**
25+ * @var array<mixed,mixed> $content2Descriptor
26+ */
1127 private array $ content2Descriptor ;
28+
29+ /**
30+ * @var array<mixed,mixed> $differenceDescriptor
31+ */
1232 private array $ differenceDescriptor ;
33+
1334 private const array STATUS_KEYS = [
1435 "not changed " , "changed " , "added " , "deleted " , "empty " , "new value "
1536 ];
@@ -21,7 +42,10 @@ public function __construct(FileReaderInterface $reader)
2142 $ this ->fileReader = $ reader ;
2243 }
2344
24- private function normalizeData ($ data )
45+ /**
46+ * @param mixed $data
47+ */
48+ private function normalizeData (mixed $ data ): mixed
2549 {
2650 $ normalizedValue = $ data ;
2751 if (is_bool ($ data )) {
@@ -42,42 +66,69 @@ private function normalizeData($data)
4266 return $ normalizedValue ;
4367 }
4468
69+ /**
70+ * @param array<string> $fileContentKeys
71+ * @param array<string,mixed> $initContentDescriptor
72+ * @return array<mixed,mixed>
73+ */
4574 private function getContent (
4675 $ fileContentKeys ,
4776 $ initContentDescriptor
4877 ): array {
49- return array_reduce (
78+ $ result = array_reduce (
5079 $ fileContentKeys ,
5180 function ($ contentDescriptor , $ fileKey ) {
52- $ fileItem = $ contentDescriptor ['fileContent ' ];
81+ $ fileItem = is_array ($ contentDescriptor ) ? $ contentDescriptor ['fileContent ' ] : "" ;
82+
83+ $ fileContent = is_array ($ fileItem ) ? $ fileItem [$ fileKey ] : $ fileItem ;//"";
84+
85+ $ levelNum = is_array ($ contentDescriptor ) ? $ contentDescriptor ["level " ] : 0 ;
86+ $ level = is_numeric ($ levelNum ) ?
87+ ($ levelNum + 1 ) : throw new DifferException ("internal error: level is not numeric \n" );
5388
54- $ fileContent = $ fileItem [$ fileKey ];
89+ $ historyValue = is_array ($ contentDescriptor ) ? $ contentDescriptor ["history " ] : "" ;
90+ $ historyString = is_string ($ historyValue ) ? $ historyValue : "" ;
91+ $ history = ($ historyString === "" ) ? $ fileKey : $ historyString . ". " . $ fileKey ;
5592
56- $ level = $ contentDescriptor ["level " ] + 1 ;
57- $ history = ($ contentDescriptor ["history " ] === "" ) ?
58- $ fileKey : $ contentDescriptor ["history " ] . ". " . $ fileKey ;
5993 $ fileContentKeys = array_keys (
6094 is_array ($ fileContent ) ? $ fileContent : []
6195 );
6296 asort ($ fileContentKeys );
97+
6398 $ initContentDescriptor = [
6499 "level " => $ level ,
65100 "history " => $ history ,
66101 "fileKey " => $ fileKey ,
67- "fileContent " => $ fileContent
102+ "fileContent " => $ fileContent ,
103+ "output " => []
68104 ];
69105
70- $ contentDescriptor ['output ' ][] = $ this ->getContent (
71- $ fileContentKeys ,
72- $ initContentDescriptor
73- );
106+ if (is_array ($ contentDescriptor ) && isset ($ contentDescriptor ['output ' ])) {
107+ if (is_array ($ contentDescriptor ['output ' ])) {
108+ $ contentDescriptor ['output ' ][] = $ this ->getContent (
109+ $ fileContentKeys ,
110+ $ initContentDescriptor
111+ );
112+ }
113+ }
74114
75115 return $ contentDescriptor ;
76116 },
77117 $ initContentDescriptor
78118 );
119+ if (is_array ($ result )) {
120+ return $ result ;
121+ } else {
122+ return [];
123+ }
79124 }
80125
126+ /**
127+ * @param null|string|array<string|mixed>|mixed $file1Content
128+ * @param null|string|array<string|mixed>|mixed $file2Content
129+ * @param string $currentStatus
130+ * @param boolean $nextItemIsNotArray
131+ */
81132 private function getNextItemStatus (
82133 $ file1Content ,
83134 $ file2Content ,
@@ -103,6 +154,15 @@ private function getNextItemStatus(
103154 return $ status ;
104155 }
105156
157+ /**
158+ * @param string $status
159+ * @param int $level
160+ * @param string $fileKey
161+ * @param string $history
162+ * @param null|mixed $file1Content
163+ * @param null|mixed $file2Content
164+ * @return array<string|mixed>
165+ */
106166 private function getInitDifferenceDescriptor (
107167 $ status ,
108168 $ level ,
@@ -135,25 +195,44 @@ private function getInitDifferenceDescriptor(
135195 return $ initDifferenceDescriptor ;
136196 }
137197
138- public function getStatusKeys ()
198+ /**
199+ * @return array<int,string>
200+ */
201+ public function getStatusKeys (): array
139202 {
140203 return self ::STATUS_KEYS ;
141204 }
142205
206+ /**
207+ * @param array<int,string> $fileContentKeys
208+ * @param array<mixed> $initDifferenceDescriptor
209+ * @return mixed
210+ */
143211 private function getDifference (
144212 $ fileContentKeys ,
145213 $ initDifferenceDescriptor
146- ): array {
214+ ): mixed {
147215 return array_reduce (
148216 $ fileContentKeys ,
149217 function ($ differenceDescriptor , $ fileKey ) {
150- $ file1Item = $ differenceDescriptor ["file1Content " ];
151- $ file2Item = $ differenceDescriptor ["file2Content " ];
218+ $ file1Item = is_array ($ differenceDescriptor ) ? $ differenceDescriptor ["file1Content " ] : [];
219+ $ file2Item = is_array ($ differenceDescriptor ) ? $ differenceDescriptor ["file2Content " ] : [];
220+
221+ $ file1Content = null ;
222+ if (is_array ($ file1Item )) {
223+ $ file1Content = in_array ($ fileKey , $ file1Item ) ? $ file1Item [$ fileKey ] : null ;
224+ }
225+ $ file2Content = null ;
226+ if (is_array ($ file2Item )) {
227+ $ file2Content = in_array ($ fileKey , $ file2Item ) ? $ file2Item [$ fileKey ] : null ;
228+ }
152229
153- $ file1Content = $ file1Item [$ fileKey ] ?? null ;
154- $ file2Content = $ file2Item [$ fileKey ] ?? null ;
155230 $ nextItemIsNotArray = !(is_array ($ file1Item ) && is_array ($ file2Item ));
156- $ currentStatus = $ differenceDescriptor ['status ' ];
231+ $ currentStatus = "not changed " ;
232+ if (is_array ($ differenceDescriptor )) {
233+ $ tmpStatus = $ differenceDescriptor ['status ' ];
234+ $ currentStatus = is_string ($ tmpStatus ) ? $ tmpStatus : "not changed " ;
235+ }
157236
158237 $ status = $ this ->getNextItemStatus (
159238 $ file1Content ,
@@ -162,9 +241,16 @@ function ($differenceDescriptor, $fileKey) {
162241 $ nextItemIsNotArray
163242 );
164243
165- $ level = $ differenceDescriptor ["level " ] + 1 ;
166- $ history = ($ differenceDescriptor ["history " ] === "" ) ?
167- $ fileKey : $ differenceDescriptor ["history " ] . ". " . $ fileKey ;
244+ $ prevLevel = is_array ($ differenceDescriptor ) ? $ differenceDescriptor ["level " ] : 0 ;
245+ $ level = is_integer ($ prevLevel ) ? $ prevLevel + 1 : 0 ;
246+ $ history = "" ;
247+ if (is_array ($ differenceDescriptor )) {
248+ $ nextHistory = $ differenceDescriptor ["history " ];
249+ $ strHistory = is_string ($ nextHistory ) ? $ nextHistory : "" ;
250+ $ history = ($ differenceDescriptor ["history " ] === "" ) ?
251+ $ fileKey : $ strHistory . ". " . $ fileKey ;
252+ }
253+
168254 $ contentKeys = array_keys (array_merge (
169255 is_array ($ file1Content ) ? $ file1Content : [],
170256 is_array ($ file2Content ) ? $ file2Content : []
@@ -180,80 +266,100 @@ function ($differenceDescriptor, $fileKey) {
180266 $ file2Content
181267 );
182268
183- $ differenceDescriptor ["output " ][] = $ this ->getDifference (
184- $ contentKeys ,
185- $ initDifferenceDescriptor
186- );
269+ if (is_array ($ differenceDescriptor )) {
270+ if (is_array ($ differenceDescriptor ["output " ])) {
271+ $ differenceDescriptor ["output " ][] = $ this ->getDifference (
272+ $ contentKeys ,
273+ $ initDifferenceDescriptor
274+ );
275+ }
276+ }
277+
187278 return $ differenceDescriptor ;
188279 },
189280 $ initDifferenceDescriptor
190281 );
191282 }
192283
193- public function execute (CommandInterface $ command = null ): CommandInterface
284+ public function execute (CommandLineParserInterface $ command ): FilesDiffCommandInterface
194285 {
195- if (!is_null ($ command )) {
286+ $ fileNames = $ command ->getFileNames ();
287+ if (is_array ($ fileNames )) {
196288 $ this ->filesPaths = [
197- $ command -> getFileNames () ['FILE1 ' ],
198- $ command -> getFileNames () ['FILE2 ' ]
289+ is_string ( $ fileNames [ ' FILE1 ' ]) ? $ fileNames ['FILE1 ' ] : "" ,
290+ is_string ( $ fileNames [ ' FILE2 ' ]) ? $ fileNames ['FILE2 ' ] : ""
199291 ];
292+ };
200293
201- foreach ($ this ->filesPaths as $ filePath ) {
202- $ this ->filesDataItems [] = $ this ->fileReader ->readFile ($ filePath );
203- }
294+ foreach ($ this ->filesPaths as $ filePath ) {
295+ $ this ->filesDataItems [] = $ this ->fileReader ->readFile ($ filePath );
296+ }
204297
298+ $ filesDataItems = $ this ->filesDataItems [0 ];
299+ $ file1Content = [];
300+ if (is_array ($ filesDataItems )) {
205301 $ file1Content = array_map (
206302 fn ($ item ) => $ this ->normalizeData ($ item ),
207- $ this -> filesDataItems [ 0 ],
303+ $ filesDataItems
208304 );
305+ }
209306
307+ $ filesDataItems = $ this ->filesDataItems [1 ];
308+ $ file2Content = [];
309+ if (is_array ($ filesDataItems )) {
210310 $ file2Content = array_map (
211311 fn ($ item ) => $ this ->normalizeData ($ item ),
212- $ this ->filesDataItems [1 ]
213- );
214-
215- $ fileKeys = array_keys ($ file1Content );
216- asort ($ fileKeys );
217- $ initContent1Descriptor = [
218- "level " => 0 ,
219- "fileKey " => "initKey " ,
220- "history " => "" ,
221- "fileContent " => $ file1Content
222- ];
223-
224- $ this ->content1Descriptor = $ this ->getContent (
225- $ fileKeys ,
226- $ initContent1Descriptor
312+ $ filesDataItems
227313 );
314+ }
228315
229- $ fileKeys = array_keys ($ file2Content );
230- asort ($ fileKeys );
231- $ initContent2Descriptor = [
232- "level " => 0 ,
233- "fileKey " => "initKey " ,
234- "history " => "" ,
235- "fileContent " => $ file2Content
236- ];
316+ $ fileKeys = array_keys ($ file1Content );
317+ asort ($ fileKeys );
318+ $ initContent1Descriptor = [
319+ "level " => 0 ,
320+ "fileKey " => "initKey " ,
321+ "history " => "" ,
322+ "fileContent " => $ file1Content ,
323+ "output " => []
324+ ];
325+
326+ $ this ->content1Descriptor = $ this ->getContent (
327+ $ fileKeys ,
328+ $ initContent1Descriptor
329+ );
237330
238- $ this ->content2Descriptor = $ this ->getContent (
239- $ fileKeys ,
240- $ initContent2Descriptor
241- );
331+ $ fileKeys = array_keys ($ file2Content );
332+ asort ($ fileKeys );
333+ $ initContent2Descriptor = [
334+ "level " => 0 ,
335+ "fileKey " => "initKey " ,
336+ "history " => "" ,
337+ "fileContent " => $ file2Content ,
338+ "output " => []
339+ ];
340+
341+ $ this ->content2Descriptor = $ this ->getContent (
342+ $ fileKeys ,
343+ $ initContent2Descriptor
344+ );
242345
243- $ mergedFileKeys = array_keys (array_merge ($ file1Content , $ file2Content ));
244- asort ($ mergedFileKeys );
245- $ initDifferenceDescriptor = [
246- "level " => 0 ,
247- "status " => "init " ,
248- "fileKey " => "initKey " ,
249- "history " => "" ,
250- "file1Content " => $ file1Content ,
251- "file2Content " => $ file2Content ,
252- ];
253- $ this ->differenceDescriptor = $ this ->getDifference (
254- $ mergedFileKeys ,
255- $ initDifferenceDescriptor
256- );
346+ $ mergedFileKeys = array_keys (array_merge ($ file1Content , $ file2Content ));
347+ asort ($ mergedFileKeys );
348+ $ initDifferenceDescriptor = [
349+ "level " => 0 ,
350+ "status " => "init " ,
351+ "fileKey " => "initKey " ,
352+ "history " => "" ,
353+ "file1Content " => $ file1Content ,
354+ "file2Content " => $ file2Content ,
355+ "output " => []
356+ ];
357+ $ differenceResult = $ this ->getDifference (
358+ $ mergedFileKeys ,
359+ $ initDifferenceDescriptor
360+ );
361+ if (is_array ($ differenceResult )) {
362+ $ this ->differenceDescriptor = $ differenceResult ;
257363 }
258364
259365 return $ this ;
@@ -271,16 +377,25 @@ public function getFile2Name(): string
271377 return end ($ filename2Path );
272378 }
273379
380+ /**
381+ * @return array<mixed,mixed>
382+ */
274383 public function getContent1Descriptor (): array
275384 {
276385 return $ this ->content1Descriptor ;
277386 }
278387
388+ /**
389+ * @return array<mixed,mixed>
390+ */
279391 public function getContent2Descriptor (): array
280392 {
281393 return $ this ->content2Descriptor ;
282394 }
283395
396+ /**
397+ * @return array<mixed,mixed>
398+ */
284399 public function getDifferenceDescriptor (): array
285400 {
286401 return $ this ->differenceDescriptor ;
0 commit comments