ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
mergeduplicates.php
Go to the documentation of this file.
1#!/usr/bin/env php
2<?php
3
4namespace 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
9 __DIR__ . '/../vendor/autoload.php', // In case vobject is cloned directly
10 __DIR__ . '/../../../autoload.php', // In case vobject is a composer dependency.
11];
12
13foreach ($paths as $path) {
14 if (file_exists($path)) {
15 include $path;
16 break;
17 }
18}
19
20if (!class_exists('Sabre\\VObject\\Version')) {
21 fwrite(STDERR, "Composer autoloader could not be loaded.\n");
22 die(1);
23}
24
25echo "sabre/vobject ", Version::VERSION, " duplicate contact merge tool\n";
26
27if ($argc < 3) {
28
29 echo "\n";
30 echo "Usage: ", $argv[0], " input.vcf output.vcf [debug.log]\n";
31 die(1);
32
33}
34
35$input = fopen($argv[1], 'r');
36$output = fopen($argv[2], 'w');
37$debug = isset($argv[3]) ? fopen($argv[3], 'w') : null;
38
40
41// The following properties are ignored. If they appear in some vcards
42// but not in others, we don't consider them for the sake of finding
43// differences.
45 "PRODID",
46 "VERSION",
47 "REV",
48 "UID",
49 "X-ABLABEL",
50];
51
52
54
56 "Total vcards" => 0,
57 "No FN property" => 0,
58 "Ignored duplicates" => 0,
59 "Merged values" => 0,
60 "Error" => 0,
61 "Unique cards" => 0,
62 "Total written" => 0,
63];
64
65function writeStats() {
66
67 global $stats;
68 foreach ($stats as $name => $value) {
69 echo str_pad($name, 23, " ", STR_PAD_RIGHT), str_pad($value, 6, " ", STR_PAD_LEFT), "\n";
70 }
71 // Moving cursor back a few lines.
72 echo "\033[" . count($stats) . "A";
73
74}
75
76function write($vcard) {
77
78 global $stats, $output;
79
80 $stats["Total written"]++;
81 fwrite($output, $vcard->serialize() . "\n");
82
83}
84
85while ($vcard = $splitter->getNext()) {
86
87 $stats["Total vcards"]++;
88 writeStats();
89
90 $fn = isset($vcard->FN) ? (string)$vcard->FN : null;
91
92 if (empty($fn)) {
93
94 // Immediately write this vcard, we don't compare it.
95 $stats["No FN property"]++;
96 $stats['Unique cards']++;
97 write($vcard);
98 $vcard->destroy();
99 continue;
100
101 }
102
103 if (!isset($collectedNames[$fn])) {
104
105 $collectedNames[$fn] = $vcard;
106 $stats['Unique cards']++;
107 continue;
108
109 } else {
110
111 // Starting comparison for all properties. We only check if properties
112 // in the current vcard exactly appear in the earlier vcard as well.
113 foreach ($vcard->children() as $newProp) {
114
115 if (in_array($newProp->name, $ignoredProperties)) {
116 // We don't care about properties such as UID and REV.
117 continue;
118 }
119 $ok = false;
120 foreach ($collectedNames[$fn]->select($newProp->name) as $compareProp) {
121
122 if ($compareProp->serialize() === $newProp->serialize()) {
123 $ok = true;
124 break;
125 }
126 }
127
128 if (!$ok) {
129
130 if ($newProp->name === 'EMAIL' || $newProp->name === 'TEL') {
131
132 // We're going to make another attempt to find this
133 // property, this time just by value. If we find it, we
134 // consider it a success.
135 foreach ($collectedNames[$fn]->select($newProp->name) as $compareProp) {
136
137 if ($compareProp->getValue() === $newProp->getValue()) {
138 $ok = true;
139 break;
140 }
141 }
142
143 if (!$ok) {
144
145 // Merging the new value in the old vcard.
146 $collectedNames[$fn]->add(clone $newProp);
147 $ok = true;
148 $stats['Merged values']++;
149
150 }
151
152 }
153
154 }
155
156 if (!$ok) {
157
158 // echo $newProp->serialize() . " does not appear in earlier vcard!\n";
159 $stats['Error']++;
160 if ($debug) fwrite($debug, "Missing '" . $newProp->name . "' property in duplicate. Earlier vcard:\n" . $collectedNames[$fn]->serialize() . "\n\nLater:\n" . $vcard->serialize() . "\n\n");
161
162 $vcard->destroy();
163 continue 2;
164 }
165
166 }
167
168 }
169
170 $vcard->destroy();
171 $stats['Ignored duplicates']++;
172
173}
174
175foreach ($collectedNames as $vcard) {
176
177 // Overwriting any old PRODID
178 $vcard->PRODID = '-//Sabre//Sabre VObject ' . Version::VERSION . '//EN';
179 write($vcard);
180 writeStats();
181
182}
183
184echo str_repeat("\n", count($stats)), "\nDone.\n";
$path
Definition: aliased.php:25
An exception for terminatinating execution or to throw for unit testing.
The VCard component.
Definition: VCard.php:18
const VERSION
Full version number.
Definition: Version.php:17
select
Definition: langcheck.php:166
foreach( $paths as $path) if(!class_exists( 'Sabre\\VObject\\Version'))
foreach($paths as $path) if($argc< 3) $input
global $argv
Definition: svg-scanner.php:41