AuthorConverterTrait   B
last analyzed

Complexity

Total Complexity 45

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 45
eloc 65
c 1
b 0
f 0
dl 0
loc 166
rs 8.8

9 Methods

Rating   Name   Duplication   Size   Complexity  
B extractFromSimpleArray() 0 16 7
B convertJsonLDAuthor() 0 25 8
A convertInstitutionnel() 0 9 5
A shrinkMultiAuthors() 0 15 4
A extractAuthorFromString() 0 7 3
B extractAuthorFromIndexedArray() 0 17 8
A cleanAuthor() 0 15 4
A isAuthorsEtAl() 0 6 3
A wikifyPressAgency() 0 18 3

How to fix   Complexity   

Complex Class

Complex classes like AuthorConverterTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AuthorConverterTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * This file is part of dispositif/wikibot application (@github)
4
 * 2019-2023 © Philippe M./Irønie  <[email protected]>
5
 * For the full copyright and MIT license information, view the license file.
6
 */
7
8
declare(strict_types=1);
9
10
namespace App\Domain\Publisher\Traits;
11
12
trait AuthorConverterTrait
13
{
14
    protected function convertJsonLDAuthor(array $data, int $index): ?string
15
    {
16
        // author=Bob
17
        // Why restricted to index 1 ??
18
        if (1 === $index && $this->extractAuthorFromString($data)) {
19
            return $this->extractAuthorFromString($data);
20
        }
21
22
        if (isset($data['author']) && is_string($data['author']) && $index === 1) {
23
            return html_entity_decode($data['author']);
24
        }
25
26
        // author ['name'=>'Bob','@type'=>'Person']
27
        $simpleAuthor = $this->extractFromSimpleArray($data, $index);
28
        if ($simpleAuthor) {
29
            return $simpleAuthor;
30
        }
31
32
        // author [ 0 => ['name'=>'Bob'], 1=> ...]
33
        $extractAuthorFromArray = $this->extractAuthorFromIndexedArray($data, $index);
34
        if ($extractAuthorFromArray) {
35
            return $extractAuthorFromArray;
36
        }
37
38
        return null;
39
    }
40
41
    /**
42
     * author=Bob
43
     */
44
    protected function extractAuthorFromString(array $data): ?string
45
    {
46
        if (isset($data['author']) && is_string($data['author'])) {
47
            return html_entity_decode($data['author']);
48
        }
49
50
        return null;
51
    }
52
53
    /**
54
     * author ['name'=>'Bob','@type'=>'Person']
55
     */
56
    protected function extractFromSimpleArray(array $data, int $index): ?string
57
    {
58
        if (0 === $index
59
            && isset($data['author'])
60
            && isset($data['author']['name'])
61
            && (!isset($data['author']['@type'])
62
                || 'Person' === $data['author']['@type'])
63
        ) {
64
            if (is_string($data['author']['name'])) {
65
                return html_entity_decode($data['author']['name']);
66
            }
67
68
            return html_entity_decode((string) $data['author']['name'][0]);
69
        }
70
71
        return null;
72
    }
73
74
    /**
75
     * author [ 0 => ['name'=>'Bob'], 1=> ...]
76
     */
77
    protected function extractAuthorFromIndexedArray(array $data, int $index): ?string
78
    {
79
        if (isset($data['author']) && isset($data['author'][$index])
80
            && (!isset($data['author'][$index]['@type'])
81
                || 'Person' === $data['author'][$index]['@type'])
82
        ) {
83
            if (isset($data['author'][$index]['name']) && is_string($data['author'][$index]['name'])) {
84
                return html_entity_decode($data['author'][$index]['name']);
85
            }
86
87
            // "author" => [ "@type" => "Person", "name" => [] ]
88
            if (isset($data['author'][$index]['name'][0])) {
89
                return html_entity_decode((string) $data['author'][$index]['name'][0]);
90
            }
91
        }
92
93
        return null;
94
    }
95
96
    protected function convertInstitutionnel($data): ?string
97
    {
98
        if (isset($data['author']) && isset($data['author'][0]) && isset($data['author'][0]['@type'])
99
            && 'Person' !== $data['author'][0]['@type']
100
        ) {
101
            return html_entity_decode((string) $data['author'][0]['name']);
102
        }
103
104
        return null;
105
    }
106
107
    /**
108
     * Used by OpenGraphMapper (so also ExternMapper).
109
     * If more than 2 authors, reduce to the 2 first names.
110
     */
111
    protected function shrinkMultiAuthors(?string $authors): ?string
112
    {
113
        if (empty($authors)) {
114
            return null;
115
        }
116
        // "Bob, Martin ; Yul, Bar ; ... ; ..."
117
        if (preg_match('#([^;]+;[^;]+);[^;]+;.+#', $authors, $matches)) {
118
            return $matches[1];
119
        }
120
        // "Bob Martin, Yul Bar, ..., ...,..."
121
        if (preg_match('#([^,]+,[^,]+),[^,]+,.+#', $authors, $matches)) {
122
            return $matches[1];
123
        }
124
125
        return $authors;
126
    }
127
128
    /**
129
     * If more than 2 authors, return "oui" for the bibliographic parameter "et al.".
130
     */
131
    protected function isAuthorsEtAl(?string $authors): bool
132
    {
133
        if (empty($authors)) {
134
            return false;
135
        }
136
        return substr_count($authors, ',') >= 2 || substr_count($authors, ';') >= 1;
137
    }
138
139
    protected function cleanAuthor(?string $str = null): ?string
140
    {
141
        if ($str === null) {
142
            return null;
143
        }
144
        // "https://www.facebook.com/search/top/?q=..."
145
        if (preg_match('#^https?://.+#i', $str)) {
146
            return null;
147
        }
148
        // "Par Bob"
149
        if (preg_match('#^Par (.+)$#i', $str, $matches)) {
150
            return $matches[1];
151
        }
152
153
        return $str;
154
    }
155
156
    /**
157
     * Wikification des noms/acronymes d'agences de presse.
158
     * Note : utiliser APRES clean() et cleanAuthor() sinon bug "|"
159
     */
160
    protected function wikifyPressAgency(?string $str): ?string
161
    {
162
        if (empty($str)) {
163
            return null;
164
        }
165
        // skip potential wikilinks
166
        if (str_contains($str, '[')) {
167
            return $str;
168
        }
169
        $str = preg_replace('#\b(AFP)\b#i', '[[Agence France-Presse|AFP]]', $str);
170
        $str = str_replace('Reuters', '[[Reuters]]', $str);
171
        $str = str_replace('Associated Press', '[[Associated Press]]', $str);
172
        $str = preg_replace('#\b(PA)\b#', '[[Press Association|PA]]', $str);
173
        $str = preg_replace('#\b(AP)\b#', '[[Associated Press|AP]]', $str);
174
        $str = str_replace('Xinhua', '[[Xinhua]]', $str);
175
        $str = preg_replace('#\b(ATS)\b#', '[[Agence télégraphique suisse|ATS]]', $str);
176
177
        return preg_replace('#\b(PC|CP)\b#', '[[La Presse canadienne|PC]]', $str);
178
    }
179
}