Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
45.58% |
103 / 226 |
|
28.57% |
2 / 7 |
CRAP | |
0.00% |
0 / 1 |
RecordDataFormatterFactory | |
45.58% |
103 / 226 |
|
28.57% |
2 / 7 |
40.24 | |
0.00% |
0 / 1 |
__invoke | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
2.00 | |||
getAuthorFunction | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
3 | |||
getLanguageLineSettings | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
4.01 | |||
getDefaultCollectionInfoSpecs | |
0.00% |
0 / 60 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultCollectionRecordSpecs | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultCoreSpecs | |
100.00% |
74 / 74 |
|
100.00% |
1 / 1 |
1 | |||
getDefaultDescriptionSpecs | |
0.00% |
0 / 39 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * Factory for record driver data formatting view helper |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2016. |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2, |
12 | * as published by the Free Software Foundation. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | * |
23 | * @category VuFind |
24 | * @package View_Helpers |
25 | * @author Demian Katz <demian.katz@villanova.edu> |
26 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
27 | * @link https://vufind.org/wiki/development:architecture:record_data_formatter |
28 | * Wiki |
29 | */ |
30 | |
31 | namespace VuFind\View\Helper\Root; |
32 | |
33 | use Laminas\ServiceManager\Exception\ServiceNotCreatedException; |
34 | use Laminas\ServiceManager\Exception\ServiceNotFoundException; |
35 | use Laminas\ServiceManager\Factory\FactoryInterface; |
36 | use Psr\Container\ContainerExceptionInterface as ContainerException; |
37 | use Psr\Container\ContainerInterface; |
38 | |
39 | use function count; |
40 | |
41 | /** |
42 | * Factory for record driver data formatting view helper |
43 | * |
44 | * @category VuFind |
45 | * @package View_Helpers |
46 | * @author Demian Katz <demian.katz@villanova.edu> |
47 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
48 | * @link https://vufind.org/wiki/development:architecture:record_data_formatter |
49 | * Wiki |
50 | */ |
51 | class RecordDataFormatterFactory implements FactoryInterface |
52 | { |
53 | /** |
54 | * Schema.org view helper |
55 | * |
56 | * @var SchemaOrg |
57 | */ |
58 | protected $schemaOrgHelper = null; |
59 | |
60 | /** |
61 | * The order in which groups of authors are displayed. |
62 | * |
63 | * The dictionary keys here correspond to the dictionary keys in the $labels |
64 | * array in getAuthorFunction() |
65 | * |
66 | * @var array<string, int> |
67 | */ |
68 | protected $authorOrder = ['primary' => 1, 'corporate' => 2, 'secondary' => 3]; |
69 | |
70 | /** |
71 | * Create an object |
72 | * |
73 | * @param ContainerInterface $container Service manager |
74 | * @param string $requestedName Service being created |
75 | * @param null|array $options Extra options (optional) |
76 | * |
77 | * @return object |
78 | * |
79 | * @throws ServiceNotFoundException if unable to resolve the service. |
80 | * @throws ServiceNotCreatedException if an exception is raised when |
81 | * creating a service. |
82 | * @throws ContainerException&\Throwable if any other error occurs |
83 | * |
84 | * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
85 | */ |
86 | public function __invoke( |
87 | ContainerInterface $container, |
88 | $requestedName, |
89 | array $options = null |
90 | ) { |
91 | if (!empty($options)) { |
92 | throw new \Exception('Unexpected options sent to factory.'); |
93 | } |
94 | $this->schemaOrgHelper = $container->get('ViewHelperManager')->get('schemaOrg'); |
95 | $config = $container |
96 | ->get(\VuFind\Config\PluginManager::class) |
97 | ->get('RecordDataFormatter'); |
98 | $helper = new $requestedName($config); |
99 | $helper->setDefaults( |
100 | 'collection-info', |
101 | [$this, 'getDefaultCollectionInfoSpecs'] |
102 | ); |
103 | $helper->setDefaults( |
104 | 'collection-record', |
105 | [$this, 'getDefaultCollectionRecordSpecs'] |
106 | ); |
107 | $helper->setDefaults('core', [$this, 'getDefaultCoreSpecs']); |
108 | $helper->setDefaults('description', [$this, 'getDefaultDescriptionSpecs']); |
109 | return $helper; |
110 | } |
111 | |
112 | /** |
113 | * Get the callback function for processing authors. |
114 | * |
115 | * @return callable |
116 | */ |
117 | protected function getAuthorFunction() |
118 | { |
119 | return function ($data, $options) { |
120 | // Lookup array of singular/plural labels (note that Other is always |
121 | // plural right now due to lack of translation strings). |
122 | $labels = [ |
123 | 'primary' => ['Main Author', 'Main Authors'], |
124 | 'corporate' => ['Corporate Author', 'Corporate Authors'], |
125 | 'secondary' => ['Other Authors', 'Other Authors'], |
126 | ]; |
127 | // Lookup array of schema labels. |
128 | $schemaLabels = [ |
129 | 'primary' => 'author', |
130 | 'corporate' => 'creator', |
131 | 'secondary' => 'contributor', |
132 | ]; |
133 | |
134 | // Sort the data: |
135 | $final = []; |
136 | foreach ($data as $type => $values) { |
137 | $final[] = [ |
138 | 'label' => $labels[$type][count($values) == 1 ? 0 : 1], |
139 | 'values' => [$type => $values], |
140 | 'options' => [ |
141 | 'pos' => $options['pos'] + $this->authorOrder[$type], |
142 | 'renderType' => 'RecordDriverTemplate', |
143 | 'template' => 'data-authors.phtml', |
144 | 'context' => [ |
145 | 'type' => $type, |
146 | 'schemaLabel' => $schemaLabels[$type], |
147 | 'requiredDataFields' => [ |
148 | ['name' => 'role', 'prefix' => 'CreatorRoles::'], |
149 | ], |
150 | ], |
151 | ], |
152 | ]; |
153 | } |
154 | return $final; |
155 | }; |
156 | } |
157 | |
158 | /** |
159 | * Get the settings for formatting language lines. |
160 | * |
161 | * @return array |
162 | */ |
163 | protected function getLanguageLineSettings(): array |
164 | { |
165 | if ($this->schemaOrgHelper) { |
166 | $langSpan = $this->schemaOrgHelper |
167 | ->getTag('span', ['property' => 'availableLanguage', 'typeof' => 'Language']); |
168 | $nameSpan = $this->schemaOrgHelper->getTag('span', ['property' => 'name']); |
169 | $itemPrefix = $langSpan . $nameSpan; |
170 | $itemSuffix = ($nameSpan ? '</span>' : '') . ($langSpan ? '</span>' : ''); |
171 | } else { |
172 | $itemPrefix = $itemSuffix = ''; |
173 | } |
174 | return compact('itemPrefix', 'itemSuffix') + [ |
175 | 'translate' => true, |
176 | 'translationTextDomain' => 'ISO639-3::', |
177 | ]; |
178 | } |
179 | |
180 | /** |
181 | * Get default specifications for displaying data in collection-info metadata. |
182 | * |
183 | * @return array |
184 | */ |
185 | public function getDefaultCollectionInfoSpecs() |
186 | { |
187 | $spec = new RecordDataFormatter\SpecBuilder(); |
188 | $spec->setMultiLine( |
189 | 'Authors', |
190 | 'getDeduplicatedAuthors', |
191 | $this->getAuthorFunction() |
192 | ); |
193 | $spec->setLine('Summary', 'getSummary'); |
194 | $spec->setLine( |
195 | 'Format', |
196 | 'getFormats', |
197 | 'RecordHelper', |
198 | ['helperMethod' => 'getFormatList'] |
199 | ); |
200 | $spec->setLine( |
201 | 'Language', |
202 | 'getLanguages', |
203 | null, |
204 | $this->getLanguageLineSettings() |
205 | ); |
206 | $spec->setTemplateLine( |
207 | 'Published', |
208 | 'getPublicationDetails', |
209 | 'data-publicationDetails.phtml' |
210 | ); |
211 | $spec->setLine( |
212 | 'Edition', |
213 | 'getEdition', |
214 | null, |
215 | [ |
216 | 'itemPrefix' => '<span property="bookEdition">', |
217 | 'itemSuffix' => '</span>', |
218 | ] |
219 | ); |
220 | $spec->setTemplateLine('Series', 'getSeries', 'data-series.phtml'); |
221 | $spec->setTemplateLine( |
222 | 'Subjects', |
223 | 'getAllSubjectHeadings', |
224 | 'data-allSubjectHeadings.phtml' |
225 | ); |
226 | $spec->setTemplateLine('Online Access', true, 'data-onlineAccess.phtml'); |
227 | $spec->setTemplateLine( |
228 | 'Related Items', |
229 | 'getAllRecordLinks', |
230 | 'data-allRecordLinks.phtml' |
231 | ); |
232 | $spec->setLine('Notes', 'getGeneralNotes'); |
233 | $spec->setLine('Production Credits', 'getProductionCredits'); |
234 | $spec->setLine( |
235 | 'ISBN', |
236 | 'getISBNs', |
237 | null, |
238 | ['itemPrefix' => '<span property="isbn">', 'itemSuffix' => '</span>'] |
239 | ); |
240 | $spec->setLine( |
241 | 'ISSN', |
242 | 'getISSNs', |
243 | null, |
244 | ['itemPrefix' => '<span property="issn">', 'itemSuffix' => '</span>'] |
245 | ); |
246 | return $spec->getArray(); |
247 | } |
248 | |
249 | /** |
250 | * Get default specifications for displaying data in collection-record metadata. |
251 | * |
252 | * @return array |
253 | */ |
254 | public function getDefaultCollectionRecordSpecs() |
255 | { |
256 | $spec = new RecordDataFormatter\SpecBuilder(); |
257 | $spec->setLine('Summary', 'getSummary'); |
258 | $spec->setMultiLine( |
259 | 'Authors', |
260 | 'getDeduplicatedAuthors', |
261 | $this->getAuthorFunction() |
262 | ); |
263 | $spec->setLine( |
264 | 'Language', |
265 | 'getLanguages', |
266 | null, |
267 | $this->getLanguageLineSettings() |
268 | ); |
269 | $spec->setLine( |
270 | 'Format', |
271 | 'getFormats', |
272 | 'RecordHelper', |
273 | ['helperMethod' => 'getFormatList'] |
274 | ); |
275 | $spec->setLine('Access', 'getAccessRestrictions'); |
276 | $spec->setLine('Related Items', 'getRelationshipNotes'); |
277 | return $spec->getArray(); |
278 | } |
279 | |
280 | /** |
281 | * Get default specifications for displaying data in core metadata. |
282 | * |
283 | * @return array |
284 | */ |
285 | public function getDefaultCoreSpecs() |
286 | { |
287 | $spec = new RecordDataFormatter\SpecBuilder(); |
288 | $spec->setTemplateLine( |
289 | 'Published in', |
290 | 'getContainerTitle', |
291 | 'data-containerTitle.phtml' |
292 | ); |
293 | $spec->setLine( |
294 | 'New Title', |
295 | 'getNewerTitles', |
296 | null, |
297 | ['recordLink' => 'title'] |
298 | ); |
299 | $spec->setLine( |
300 | 'Previous Title', |
301 | 'getPreviousTitles', |
302 | null, |
303 | ['recordLink' => 'title'] |
304 | ); |
305 | $spec->setMultiLine( |
306 | 'Authors', |
307 | 'getDeduplicatedAuthors', |
308 | $this->getAuthorFunction() |
309 | ); |
310 | $spec->setLine( |
311 | 'Format', |
312 | 'getFormats', |
313 | 'RecordHelper', |
314 | ['helperMethod' => 'getFormatList'] |
315 | ); |
316 | $spec->setLine( |
317 | 'Language', |
318 | 'getLanguages', |
319 | null, |
320 | $this->getLanguageLineSettings() |
321 | ); |
322 | $spec->setTemplateLine( |
323 | 'Published', |
324 | 'getPublicationDetails', |
325 | 'data-publicationDetails.phtml' |
326 | ); |
327 | $spec->setLine( |
328 | 'Edition', |
329 | 'getEdition', |
330 | null, |
331 | [ |
332 | 'itemPrefix' => '<span property="bookEdition">', |
333 | 'itemSuffix' => '</span>', |
334 | ] |
335 | ); |
336 | $spec->setTemplateLine('Series', 'getSeries', 'data-series.phtml'); |
337 | $spec->setTemplateLine( |
338 | 'Subjects', |
339 | 'getAllSubjectHeadings', |
340 | 'data-allSubjectHeadings.phtml' |
341 | ); |
342 | $spec->setTemplateLine( |
343 | 'Citations', |
344 | 'getCitations', |
345 | 'data-citations.phtml', |
346 | ); |
347 | $spec->setTemplateLine( |
348 | 'child_records', |
349 | 'getChildRecordCount', |
350 | 'data-childRecords.phtml', |
351 | ['allowZero' => false] |
352 | ); |
353 | $spec->setTemplateLine('Online Access', true, 'data-onlineAccess.phtml'); |
354 | $spec->setTemplateLine( |
355 | 'Related Items', |
356 | 'getAllRecordLinks', |
357 | 'data-allRecordLinks.phtml' |
358 | ); |
359 | $spec->setTemplateLine('Tags', true, 'data-tags.phtml'); |
360 | return $spec->getArray(); |
361 | } |
362 | |
363 | /** |
364 | * Get default specifications for displaying data in the description tab. |
365 | * |
366 | * @return array |
367 | */ |
368 | public function getDefaultDescriptionSpecs() |
369 | { |
370 | $spec = new RecordDataFormatter\SpecBuilder(); |
371 | $spec->setTemplateLine('Summary', true, 'data-summary.phtml'); |
372 | $spec->setLine('Published', 'getDateSpan'); |
373 | $spec->setLine('Item Description', 'getGeneralNotes'); |
374 | $spec->setLine('Physical Description', 'getPhysicalDescriptions'); |
375 | $spec->setLine('Publication Frequency', 'getPublicationFrequency'); |
376 | $spec->setLine('Playing Time', 'getPlayingTimes'); |
377 | $spec->setLine('Format', 'getSystemDetails'); |
378 | $spec->setLine('Audience', 'getTargetAudienceNotes'); |
379 | $spec->setLine('Awards', 'getAwards'); |
380 | $spec->setLine('Production Credits', 'getProductionCredits'); |
381 | $spec->setLine('Bibliography', 'getBibliographyNotes'); |
382 | $spec->setLine( |
383 | 'ISBN', |
384 | 'getISBNs', |
385 | null, |
386 | ['itemPrefix' => '<span property="isbn">', 'itemSuffix' => '</span>'] |
387 | ); |
388 | $spec->setLine( |
389 | 'ISSN', |
390 | 'getISSNs', |
391 | null, |
392 | ['itemPrefix' => '<span property="issn">', 'itemSuffix' => '</span>'] |
393 | ); |
394 | $spec->setLine( |
395 | 'DOI', |
396 | 'getCleanDOI', |
397 | null, |
398 | [ |
399 | 'itemPrefix' => '<span property="identifier">', |
400 | 'itemSuffix' => '</span>', |
401 | ] |
402 | ); |
403 | $spec->setLine('Related Items', 'getRelationshipNotes'); |
404 | $spec->setLine('Access', 'getAccessRestrictions'); |
405 | $spec->setLine('Finding Aid', 'getFindingAids'); |
406 | $spec->setLine('Publication_Place', 'getHierarchicalPlaceNames'); |
407 | $spec->setTemplateLine('Author Notes', true, 'data-authorNotes.phtml'); |
408 | return $spec->getArray(); |
409 | } |
410 | } |