1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8class Tiki_Profile_Writer_Queue
9{
10	private $entries = [];
11
12	function add(array $data)
13	{
14		if ($info = $this->findInfo($data)) {
15			$hash = "{$info['type']}:{$info['object']}";
16
17			if ($info['remove']) {
18				unset($this->entries[$hash]);
19			} else {
20				$this->entries[$hash] = $info;
21			}
22		}
23	}
24
25	function filterIncluded(Tiki_Profile_Writer $writer)
26	{
27		array_walk(
28			$this->entries,
29			function (& $entry) use ($writer) {
30				$timestamp = $writer->getInclusionTimestamp($entry['type'], $entry['object']);
31				$entry['stored'] = $timestamp;
32				$entry['status'] = $timestamp ? 'MODIFIED' : 'NEW';
33			}
34		);
35
36		$this->entries = array_filter(
37			$this->entries,
38			function ($entry) use ($writer) {
39				return $entry['timestamp'] > $entry['stored'];
40			}
41		);
42	}
43
44	function filterInstalled(Tiki_Profile_Writer_ProfileFinder $finder)
45	{
46		$this->entries = array_filter(
47			$this->entries,
48			function ($entry) use ($finder) {
49				$finder->lookup($entry['type'], $entry['object']);
50
51				return ! $finder->checkProfileAndFlush();
52			}
53		);
54	}
55
56	private function findInfo(array $data)
57	{
58		if ($data['type'] == 'wiki page') {
59			return [
60				'type' => 'wiki_page',
61				'object' => $data['object'],
62				'timestamp' => $data['timestamp'],
63				'remove' => $data['action'] == 'Removed',
64			];
65		} elseif ($data['type'] == 'category') {
66			return [
67				'type' => 'category',
68				'object' => $data['object'],
69				'timestamp' => $data['timestamp'],
70				'remove' => $data['action'] == 'Removed',
71			];
72		} elseif ($data['action'] == 'feature') {
73			return [
74				'type' => 'preference',
75				'object' => $data['object'],
76				'timestamp' => $data['timestamp'],
77				'remove' => false,
78			];
79		} elseif ($data['type'] == 'tracker') {
80			$extra = parse_str($data['detail'], $parts);
81			if (isset($parts['fieldId'])) {
82				return [
83					'type' => 'tracker_field',
84					'object' => $parts['fieldId'],
85					'timestamp' => $data['timestamp'],
86					'remove' => $parts['operation'] == 'remove_field',
87				];
88			} else {
89				return [
90					'type' => 'tracker',
91					'object' => $data['object'],
92					'timestamp' => $data['timestamp'],
93					'remove' => $data['action'] == 'Removed',
94				];
95			}
96		}
97	}
98
99	function __toString()
100	{
101		$entries = $this->entries;
102		usort(
103			$entries,
104			function ($a, $b) {
105				return $a['timestamp'] - $b['timestamp'];
106			}
107		);
108
109		array_walk(
110			$entries,
111			function (& $entry) {
112				$entry['timestamp'] = date('Y-m-d H:i:s (D)', $entry['timestamp']);
113			},
114			$entries
115		);
116
117		$columns = ['timestamp', 'type', 'object', 'status'];
118		$widths = array_fill_keys($columns, 0);
119
120		array_unshift(
121			$entries,
122			[
123				'type' => 'Type',
124				'object' => 'Object',
125				'timestamp' => 'Last Modification',
126				'status' => 'Status',
127			]
128		);
129
130		foreach ($entries as $entry) {
131			foreach ($columns as $column) {
132				$widths[$column] = max($widths[$column], mb_strlen($entry[$column]));
133			}
134		}
135
136		$out = '';
137		foreach ($entries as $entry) {
138			foreach ($columns as $column) {
139				$out .= str_pad($entry[$column], $widths[$column] + 3);
140			}
141			$out .= PHP_EOL;
142		}
143
144		return $out;
145	}
146}
147