Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
45.58% covered (danger)
45.58%
103 / 226
28.57% covered (danger)
28.57%
2 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
RecordDataFormatterFactory
45.58% covered (danger)
45.58%
103 / 226
28.57% covered (danger)
28.57%
2 / 7
40.24
0.00% covered (danger)
0.00%
0 / 1
 __invoke
94.44% covered (success)
94.44%
17 / 18
0.00% covered (danger)
0.00%
0 / 1
2.00
 getAuthorFunction
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 getLanguageLineSettings
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
4.01
 getDefaultCollectionInfoSpecs
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 1
2
 getDefaultCollectionRecordSpecs
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
2
 getDefaultCoreSpecs
100.00% covered (success)
100.00%
74 / 74
100.00% covered (success)
100.00%
1 / 1
1
 getDefaultDescriptionSpecs
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
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
31namespace VuFind\View\Helper\Root;
32
33use Laminas\ServiceManager\Exception\ServiceNotCreatedException;
34use Laminas\ServiceManager\Exception\ServiceNotFoundException;
35use Laminas\ServiceManager\Factory\FactoryInterface;
36use Psr\Container\ContainerExceptionInterface as ContainerException;
37use Psr\Container\ContainerInterface;
38
39use 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 */
51class 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}