PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / sabre / vobject / bin / mergeduplicates.php
ameliabooking / vendor / sabre / vobject / bin Last commit date
bench.php 6 months ago bench_freebusygenerator.php 6 months ago bench_manipulatevcard.php 6 months ago fetch_windows_zones.php 1 year ago generate_vcards 1 year ago generateicalendardata.php 6 months ago mergeduplicates.php 6 months ago rrulebench.php 6 months ago vobject 1 year ago
mergeduplicates.php
161 lines
1 #!/usr/bin/env php
2 <?php
3
4 namespace AmeliaVendor\Sabre\VObject;
5
6 // This sucks.. we have to try to find the composer autoloader. But chances
7 // are, we can't find it this way. So we'll do our bestest
8 $paths = [
9 __DIR__.'/../vendor/autoload.php', // In case vobject is cloned directly
10 __DIR__.'/../../../autoload.php', // In case vobject is a composer dependency.
11 ];
12
13 foreach ($paths as $path) {
14 if (file_exists($path)) {
15 include $path;
16 break;
17 }
18 }
19
20 if (!class_exists('AmeliaVendor\\Sabre\\VObject\\Version')) {
21 fwrite(STDERR, "Composer autoloader could not be loaded.\n");
22 exit(1);
23 }
24
25 echo 'sabre/vobject ', Version::VERSION, " duplicate contact merge tool\n";
26
27 if ($argc < 3) {
28 echo "\n";
29 echo 'Usage: ', $argv[0], " input.vcf output.vcf [debug.log]\n";
30 exit(1);
31 }
32
33 $input = fopen($argv[1], 'r');
34 $output = fopen($argv[2], 'w');
35 $debug = isset($argv[3]) ? fopen($argv[3], 'w') : null;
36
37 $splitter = new Splitter\VCard($input);
38
39 // The following properties are ignored. If they appear in some vcards
40 // but not in others, we don't consider them for the sake of finding
41 // differences.
42 $ignoredProperties = [
43 'PRODID',
44 'VERSION',
45 'REV',
46 'UID',
47 'X-ABLABEL',
48 ];
49
50 $collectedNames = [];
51
52 $stats = [
53 'Total vcards' => 0,
54 'No FN property' => 0,
55 'Ignored duplicates' => 0,
56 'Merged values' => 0,
57 'Error' => 0,
58 'Unique cards' => 0,
59 'Total written' => 0,
60 ];
61
62 function writeStats()
63 {
64 global $stats;
65 foreach ($stats as $name => $value) {
66 echo str_pad($name, 23, ' ', STR_PAD_RIGHT), str_pad($value, 6, ' ', STR_PAD_LEFT), "\n";
67 }
68 // Moving cursor back a few lines.
69 echo "\033[".count($stats).'A';
70 }
71
72 function write($vcard)
73 {
74 global $stats, $output;
75
76 ++$stats['Total written'];
77 fwrite($output, $vcard->serialize()."\n");
78 }
79
80 while ($vcard = $splitter->getNext()) {
81 ++$stats['Total vcards'];
82 writeStats();
83
84 $fn = isset($vcard->FN) ? (string) $vcard->FN : null;
85
86 if (empty($fn)) {
87 // Immediately write this vcard, we don't compare it.
88 ++$stats['No FN property'];
89 ++$stats['Unique cards'];
90 write($vcard);
91 $vcard->destroy();
92 continue;
93 }
94
95 if (!isset($collectedNames[$fn])) {
96 $collectedNames[$fn] = $vcard;
97 ++$stats['Unique cards'];
98 continue;
99 } else {
100 // Starting comparison for all properties. We only check if properties
101 // in the current vcard exactly appear in the earlier vcard as well.
102 foreach ($vcard->children() as $newProp) {
103 if (in_array($newProp->name, $ignoredProperties)) {
104 // We don't care about properties such as UID and REV.
105 continue;
106 }
107 $ok = false;
108 foreach ($collectedNames[$fn]->select($newProp->name) as $compareProp) {
109 if ($compareProp->serialize() === $newProp->serialize()) {
110 $ok = true;
111 break;
112 }
113 }
114
115 if (!$ok) {
116 if ('EMAIL' === $newProp->name || 'TEL' === $newProp->name) {
117 // We're going to make another attempt to find this
118 // property, this time just by value. If we find it, we
119 // consider it a success.
120 foreach ($collectedNames[$fn]->select($newProp->name) as $compareProp) {
121 if ($compareProp->getValue() === $newProp->getValue()) {
122 $ok = true;
123 break;
124 }
125 }
126
127 if (!$ok) {
128 // Merging the new value in the old vcard.
129 $collectedNames[$fn]->add(clone $newProp);
130 $ok = true;
131 ++$stats['Merged values'];
132 }
133 }
134 }
135
136 if (!$ok) {
137 // echo $newProp->serialize() . " does not appear in earlier vcard!\n";
138 ++$stats['Error'];
139 if ($debug) {
140 fwrite($debug, "Missing '".$newProp->name."' property in duplicate. Earlier vcard:\n".$collectedNames[$fn]->serialize()."\n\nLater:\n".$vcard->serialize()."\n\n");
141 }
142
143 $vcard->destroy();
144 continue 2;
145 }
146 }
147 }
148
149 $vcard->destroy();
150 ++$stats['Ignored duplicates'];
151 }
152
153 foreach ($collectedNames as $vcard) {
154 // Overwriting any old PRODID
155 $vcard->PRODID = '-//Sabre//Sabre VObject '.Version::VERSION.'//EN';
156 write($vcard);
157 writeStats();
158 }
159
160 echo str_repeat("\n", count($stats)), "\nDone.\n";
161