Test Setup Failed
Push — master ( c5c2a9...00574e )
by Dispositif
02:16
created

GoogleBookMapper::langFilterByIsbn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 34
rs 10
1
<?php
2
/**
3
 * This file is part of dispositif/wikibot application
4
 * 2019 : Philippe M. <[email protected]>
5
 * For the full copyright and MIT license information, please view the LICENSE file.
6
 */
7
8
declare(strict_types=1);
9
10
namespace App\Domain\Publisher;
11
12
use App\Domain\Enums\Language;
13
use Scriptotek\GoogleBooks\Volume;
14
15
/**
16
 * Google Books API data mapping.
17
 * Doc : https://developers.google.com/books/docs/v1/reference/volumes
18
 * Class GoogleBookMapper.
19
 */
20
class GoogleBookMapper extends AbstractBookMapper implements MapperInterface
21
{
22
    // raw URL or wiki-template ?
23
    const MODE_RAW_URL = true;
24
25
    const GOOGLE_URL_REPLACE = 'https://books.google.com/books?id=%s&printsec=frontcover';
26
27
    // sous-titre non ajoutés :
28
    const SUBTITLE_FILTER = ['roman', 'récit', 'poèmes', 'biographie'];
29
    /**
30
     * @var bool|null
31
     */
32
    private $mapLanguageData = false;
33
34
    /**
35
     * @param           $volume Volume
36
     *
37
     * @return array
38
     */
39
    public function process($volume): array
40
    {
41
        return [
42
            // language : data not accurate !
43
            'langue' => $this->langFilterByIsbn($volume),
44
            'auteur1' => $volume->authors[0],
45
            'auteur2' => $volume->authors[1] ?? null,
46
            'auteur3' => $volume->authors[2] ?? null,
47
            'titre' => $volume->title,
48
            'sous-titre' => $this->filterSubtitle($volume),
49
            'année' => $this->convertDate2Year($volume->publishedDate),
50
            'pages totales' => (string)$volume->pageCount ?? null,
51
            'isbn' => $this->convertIsbn($volume),
52
            'présentation en ligne' => $this->presentationEnLigne($volume),
53
            'lire en ligne' => $this->lireEnLigne($volume),
54
        ];
55
    }
56
57
    /**
58
     * Use the inconstant 'language' ?
59
     *
60
     * @param bool $useLanguage
61
     */
62
    public function mapLanguageData(bool $useLanguage)
63
    {
64
        $this->mapLanguageData = $useLanguage;
65
    }
66
67
    /**
68
     * @param $volume
69
     *
70
     * @return string|null
71
     */
72
    private function filterSubtitle($volume): ?string
73
    {
74
        // "biographie" ?
75
        if (empty($volume->subtitle) || in_array(mb_strtolower($volume->subtitle), self::SUBTITLE_FILTER)) {
76
            return null;
77
        }
78
79
        if (strlen($volume->subtitle) > 50) {
80
            return null;
81
        }
82
83
        return $volume->subtitle;
84
    }
85
86
    /**
87
     * @param $data
88
     *
89
     * @return string|null
90
     */
91
    private function convertDate2Year($data)
92
    {
93
        if (!isset($data)) {
94
            return null;
95
        }
96
        if (preg_match('/[^0-9]?([12][0-9]{3})[^0-9]?/', $data, $matches) > 0) {
97
            return (string)$matches[1];
98
        }
99
100
        return null;
101
    }
102
103
    /**
104
     * @param Volume $volume
105
     *
106
     * @return string|null
107
     */
108
    private function convertIsbn(Volume $volume): ?string
109
    {
110
        if (!isset($volume->industryIdentifiers)) {
111
            return null;
112
        }
113
        // so isbn-13 replace isbn-10
114
        // todo refac algo (if 2x isbn13?)
115
        $isbn = null;
116
        $ids = (array)$volume->industryIdentifiers;
117
        foreach ($ids as $id) {
118
            if (!isset($isbn) && in_array($id->type, ['ISBN_10', 'ISBN_13'])) {
119
                $isbn = $id->identifier;
120
            }
121
            if ('ISBN_13' === $id->type) {
122
                $isbn = $id->identifier;
123
            }
124
        }
125
126
        return $isbn;
127
    }
128
129
    /**
130
     * @param Volume $volume
131
     *
132
     * @return string|null
133
     */
134
    private function presentationEnLigne(Volume $volume): ?string
135
    {
136
        if (empty($volume->id) || !in_array($volume->accessInfo->viewability, ['PARTIAL'])) {
137
            return null;
138
        }
139
140
        return $this->returnGoogleRef($volume);
141
    }
142
143
    /**
144
     * @param Volume $volume
145
     *
146
     * @return string|null
147
     */
148
    private function lireEnLigne(Volume $volume): ?string
149
    {
150
        if (empty($volume->id) || !in_array($volume->accessInfo->viewability, ['ALL_PAGES'])) {
151
            return null;
152
        }
153
154
        return $this->returnGoogleRef($volume);
155
    }
156
157
    /**
158
     * @param Volume $volume
159
     *
160
     * @return string
161
     */
162
    private function returnGoogleRef(Volume $volume): string
163
    {
164
        if (self::MODE_RAW_URL) {
165
            return sprintf(self::GOOGLE_URL_REPLACE, $volume->id);
166
        }
167
168
        return sprintf('{{Google Livres|%s}}', $volume->id);
169
    }
170
171
    /**
172
     * /!\ Google Books language data not consistant !
173
     * set $mapLanguageData to true to use that data in mapping.
174
     *
175
     * @param Volume $volume
176
     *
177
     * @return string|null
178
     */
179
    private function langFilterByIsbn(Volume $volume): ?string
180
    {
181
        if (!$this->mapLanguageData) {
1 ignored issue
show
Bug Best Practice introduced by
The expression $this->mapLanguageData of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
182
            return null;
183
        }
184
//        $isbn = $this->convertIsbn($volume);
185
//        if ($isbn) {
186
//            try {
187
//                $isbnMachine = new IsbnFacade($isbn);
188
//                $isbnMachine->validate();
189
//                $isbnLang = $isbnMachine->getCountryShortName();
190
//            } catch (\Throwable $e) {
191
//                unset($e);
192
//            }
193
//        }
194
//        if (isset($isbnLang)) {
195
//            echo "(ISBN lang: ".$isbnLang.")\n";
196
//        } else {
197
//            echo "(no ISBN lang)\n";
198
//        }
199
200
        $gooLang = $volume->language;
201
        // filtering lang because seems inconsistant
202
//        if (isset($isbnLang) && !empty($gooLang) && $gooLang !== $isbnLang) {
203
//            echo sprintf(
204
//                "*** Filtering Google langue=%s because ISBN langue=%s ",
205
//                $gooLang,
206
//                $isbnLang
207
//            );
208
//
209
//            return null;
210
//        }
211
212
        return Language::all2wiki($gooLang);
1 ignored issue
show
Bug introduced by
It seems like $gooLang can also be of type null; however, parameter $lang of App\Domain\Enums\Language::all2wiki() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

212
        return Language::all2wiki(/** @scrutinizer ignore-type */ $gooLang);
Loading history...
213
    }
214
}
215