-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathCallNumberCategory.php
406 lines (348 loc) · 10.4 KB
/
CallNumberCategory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
<?php
/**
* webtrees: online genealogy
* Copyright (C) 2022 webtrees development team
* <http://webtrees.net>
*
* RepositoryHierarchy (webtrees custom module):
* Copyright (C) 2022 Markus Hemprich
* <http://www.familienforschung-hemprich.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace Jefferson49\Webtrees\Module\RepositoryHierarchy;
use Fisharebest\Webtrees\Date;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Source;
use Fisharebest\Webtrees\Tree;
use Illuminate\Support\Collection;
use RuntimeException;
use function md5;
/**
* Call number category class
*/
class CallNumberCategory
{
//Strings corresponding to variable names, e.g. for views
public const VAR_TREE = 'tree';
public const VAR_XREF = 'xref';
public const VAR_REPOSITORY_XREF = 'repository_xref';
public const VAR_CATEGORY_NAME = 'category_name';
public const VAR_CATEGORY_FULL_NAME = 'category_full_name';
//Default category name for sources without call number
public const EMPTY_CATEGORY_NAME = 'Sources without call number';
//Default category name for sources without category in the call number
public const DEFAULT_CATEGORY_NAME = 'Default category';
//Tree, to which this call number category belongs
private Tree $tree;
//The delimiter used for this call number category
private string $delimiter;
//An arrray with regular expressions describing the delimiters used for this call number category
private array $delimiter_reg_exps = [];
//Whether it is the root category
private bool $is_root = false;
//The name of this call number category
private string $name ='';
//The full name of this call number category including the full trunk of the call number
private string $full_name ='';
//An id (typically a hash value), which identifies this call number category
private string $id = '';
//Hierarchy level, on which this call number category is located in the hierarchy of sub categories
private int $hierarchy_level = 1;
//List of sources related to this category
private array $sources = [];
//List of truncated call numbers for sources
//[source xref => truncated call number]
private array $truncated_call_numbers = [];
//List of related sub categories. Provides a recursive structure for a hierarchy of sub categories
private array $sub_categories = [];
//Overall date range of the category
private ?Date $overall_date_range = null;
/**
* Constructor
*/
public function __construct(
Tree $tree,
array $delimiter_reg_exps,
bool $is_root = false,
string $name = '',
string $full_name = '',
int $hierarchy_level = 1,
array $sources = [],
array $sub_categories = []
) {
$this->tree = $tree;
$this->delimiter_reg_exps = $delimiter_reg_exps;
$this->is_root = $is_root;
$this->name = $name;
$this->full_name = $full_name;
$this->id = md5($full_name);
$this->hierarchy_level = $hierarchy_level;
$this->sources = $sources;
$this->sub_categories = $sub_categories;
}
/**
* Get tree
*
* @return Tree
*/
public function getTree(): Tree
{
return $this->tree;
}
/**
* Get delimiter
*
* @return string
*/
public function getDelimiter(): string
{
return $this->delimiter;
}
/**
* Get getDelimiterRegExps
*
* @return array
*/
public function getDelimiterRegExps(): array
{
return $this->delimiter_reg_exps;
}
/**
* Whether it is the root category
*
* @return bool
*/
public function isRoot(): bool
{
return $this->is_root;
}
/**
* Get name
*
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* Get name to show in front end
*
* @param bool $get_full_name
*
* @return string
*/
public function getFrontEndName(bool $get_full_name = false): string
{
if ($get_full_name) {
$name = $this->full_name;
} else {
$name = $this->name;
}
if (strpos($name, CallNumberCategory::EMPTY_CATEGORY_NAME) !== false) {
return I18N::translate('Sources without call number');
} elseif (strpos($name, CallNumberCategory::DEFAULT_CATEGORY_NAME) !== false) {
return I18N::translate('Default call number category');
} else {
return $name;
}
}
/**
* Get full_name
*
* @return string
*/
public function getFullName(): string
{
return $this->full_name;
}
/**
* Get id
*
* @return string
*/
public function getId(): string
{
return $this->id;
}
/**
* Get hierarchy level
*
* @return int
*/
public function getHierarchyLevel(): int
{
return $this->hierarchy_level;
}
/**
* Get sources
*
* @return array
*/
public function getSources(): array
{
return $this->sources;
}
/**
* Get sub categories
*
* @return array
*/
public function getSubCategories(): array
{
return $this->sub_categories;
}
/**
* Get overall date range
*
* @return Date
*/
public function getOverallDateRange(): ?Date
{
return $this->overall_date_range;
}
/**
* Add source
*
* @param Source $source
*
* @return void
*/
public function addSource(Source $source)
{
array_push($this->sources, $source);
}
/**
* Add sub category
*
* @param CallNumberCategory $sub_category
*
* @return void
*/
public function addSubCategory(CallNumberCategory $sub_category)
{
array_push($this->sub_categories, $sub_category);
}
/**
* Calculate date range
*
* @param array $date_ranges_of_sources A table, which contains the date ranges for all known sources
*
* @return Date
*/
public function calculateDateRange(array $date_ranges_of_sources): ?Date
{
$date_ranges = [];
//Collect all date ranges for sub categories
$sub_categories = $this->getSubCategories();
foreach ($sub_categories as $sub_category) {
$date_range = $sub_category->calculateDateRange($date_ranges_of_sources);
if ($date_range !== null) {
array_push($date_ranges, $date_range);
}
}
//Collect all date ranges for sources
$sources = $this->sources;
foreach ($sources as $source) {
if (array_key_exists($source->xref(), $date_ranges_of_sources)) {
$date_range = $date_ranges_of_sources[$source->xref()];
array_push($date_ranges, $date_range);
}
}
$this->overall_date_range = Functions::getOverallDateRange($date_ranges);
return $this->overall_date_range;
}
/**
* Add truncated call number for a source to the truncated call numbers list
*
* @param Source $source
* @param string $truncated_call_number
*
* @return void
*/
public function addTruncatedCallNumber(Source $source, string $truncated_call_number)
{
$this->truncated_call_numbers[$source->xref()] = $truncated_call_number;
}
/**
* Get truncated call number for a source
*
* @param Source $source
*
* @return string
*/
public function getTruncatedCallNumber(Source $source): string
{
if (array_key_exists($source->xref(), $this->truncated_call_numbers)) {
return $this->truncated_call_numbers[$source->xref()];
} else {
return '';
}
}
/**
* Display date range
*
* @param string $delimiter [ISO 8601 allows: '/' odr '--']
*
* @return string
*/
public function displayISODateRange(string $delimiter = '/'): string
{
if (($this->overall_date_range !== null) && $this->overall_date_range->isOK()) {
return Functions::displayISOformatForDateRange($this->overall_date_range, $delimiter);
}
return '';
}
/**
* Save a file with C16Y data for call number category titles
*
* @param string $path
* @param string $repository_xref
* @param CallNumberCategory $root_category
*
* @return void
*/
public static function saveC16YFile(string $path, string $tree_name, string $repository_xref, CallNumberCategory $root_category): void
{
$po_file = $path . $tree_name . '_' . $repository_xref . '.php';
//Delete file if already existing
if (file_exists($po_file)) {
unlink($po_file);
}
if (!$fp = fopen($po_file, "c")) {
throw new RuntimeException('Cannot open file: ' . $po_file);
}
if (fwrite($fp, "<?php\n") === false) {
throw new RuntimeException('Cannot write to file: ' . $po_file);
}
self::writeCallNumberCategoryTitleToStream($fp, $root_category);
fclose($fp);
}
/**
* Write call number category title to stream
*
* @param $stream
* @param CallNumberCategory $category
*
* @return Collection
*/
public static function writeCallNumberCategoryTitleToStream($stream, CallNumberCategory $category): void
{
$sub_categories = $category->getSubCategories();
foreach ($sub_categories as $sub_category) {
fwrite($stream, "gettext('" . $sub_category->getFrontEndName(true) . "');\n");
self::writeCallNumberCategoryTitleToStream($stream, $sub_category);
}
}
}