Passed
Branch dev (b7aeac)
by Dispositif
03:10
created

GoogleBooksTrait::simplifyGoogleUrl()   C

Complexity

Conditions 12
Paths 75

Size

Total Lines 67
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 12
eloc 26
nc 75
nop 1
dl 0
loc 67
rs 6.9666
c 1
b 0
f 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of dispositif/wikibot application (@github)
4
 * 2019/2020 © 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 DomainException;
13
use Exception;
14
15
trait GoogleBooksTrait
16
{
17
    public static function isTrackingUrl(string $url): bool
18
    {
19
        $data = static::parseGoogleBookQuery($url);
20
        foreach ($data as $param => $value) {
21
            if (in_array($param, static::TRACKING_PARAMETERS)) {
0 ignored issues
show
Bug introduced by
The constant App\Domain\Publisher\Goo...it::TRACKING_PARAMETERS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
22
                return true;
23
            }
24
        }
25
26
        return false;
27
    }
28
29
    /**
30
     * Parse URL argument from ?query and #fragment.
31
     *
32
     * @param string $url
33
     *
34
     * @return array
35
     */
36
    public static function parseGoogleBookQuery(string $url): array
37
    {
38
        // Note : Also datas in URL after the '#' !!! (URL fragment)
39
        $queryData = parse_url($url, PHP_URL_QUERY); // after ?
40
        $fragmentData = parse_url($url, PHP_URL_FRAGMENT); // after #
41
        // queryData precedence over fragmentData
42
        parse_str(implode('&', [$fragmentData, $queryData]), $val);
43
44
        return static::arrayKeysToLower($val);
45
    }
46
47
    /**
48
     * Clean the google book URL from optional&tracking data.
49
     *
50
     * @param string $url
51
     *
52
     * @return string URL
53
     * @throws Exception
54
     */
55
    public static function simplifyGoogleUrl(string $url): string
56
    {
57
        if (!static::isGoogleBookURL($url)) {
58
            // not DomainException for live testing with OuvrageOptimize
59
            throw new Exception('not a Google Book URL');
60
        }
61
62
        $gooDat = static::parseGoogleBookQuery($url);
63
        if (empty($gooDat['id'])) {
64
            throw new DomainException("no GoogleBook 'id' in URL");
65
        }
66
        if (!preg_match('#[0-9A-Za-z_\-]{12}#', $gooDat['id'])) {
67
            throw new DomainException("GoogleBook 'id' malformed");
68
        }
69
70
        $dat = [];
71
        // keep only a few parameters (+'q' ?)
72
        // q : keywords search / dq : quoted phrase search
73
        // q can be empty !!!!
74
        $keeps = ['id', 'pg', 'printsec', 'q', 'dq'];
75
        foreach ($keeps as $keep) {
76
            if (isset($gooDat[$keep])) {
77
                $dat[$keep] = $gooDat[$keep];
78
            }
79
        }
80
81
        // 1 exemple : https://fr.wikipedia.org/w/index.php?title=Foudre_de_Catatumbo&diff=next&oldid=168721836&diffmode=source
82
        // 1. mettre URL &dq= pour final
83
        //
84
        // 2. si q!=dq (changement ultérieur formulaire recherche) alors q= prévaut pour résultat final
85
        // 2. mettre URL &q pour final
86
        //
87
        // 3. Recherche global sur http://books.google.fr => pg= dq= (#q= avec q==dq)
88
        // 3. dans ce cas (q==dq), url final avec seulement dq= donne résultat OK
89
        //
90
        // 4 . if you use a url without &redir_esc=y#v=onepage for a book with "Preview" available,
91
        // usually &dq shows the highlighted text in full page view whereas &q shows the snippet view (so you have to
92
        // click on the snippet to see the full page).
93
        // &dq allows highlighting in books where there is "Preview" available and &pg=PTx is in the URL
94
        //
95
        // #v=onepage ou #v=snippet
96
        if (isset($dat['q']) && isset($dat['dq'])) {
97
            // si q==dq alors dq prévaut pour affichage (sinon affichage différent avec url seulement q=)
98
            if ($dat['q'] === $dat['dq']) {
99
                unset($dat['q']);
100
            } // si q!=dq (exemple : nouveaux mots clés dans formulaire recherche) alors q= prévaut pour résultat final
101
            else {
102
                unset($dat['dq']);
103
            }
104
        }
105
        if (empty($dat['q'])) {
106
            unset($dat['q']);
107
        }
108
        if (empty($dat['dq'])) {
109
            unset($dat['dq']);
110
        }
111
112
        $googleURL = static::DEFAULT_GOOGLEBOOKS_URL;
0 ignored issues
show
Bug introduced by
The constant App\Domain\Publisher\Goo...DEFAULT_GOOGLEBOOKS_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
113
114
        // domain .com .fr
115
        $gooDomain = static::parseGoogleDomain($url);
116
        if ($gooDomain) {
117
            $googleURL = str_replace('.com', $gooDomain, $googleURL);
118
        }
119
120
        // todo http_build_query process an urlencode, but a not encoded q= value ("fu+bar") is beautiful
121
        return $googleURL.'?'.http_build_query($dat);
122
    }
123
124
    /**
125
     * Check google URL pattern.
126
     *
127
     * @param string $text
128
     *
129
     * @return bool
130
     */
131
    public static function isGoogleBookURL(string $text): bool
132
    {
133
        if (preg_match('#^'.static::GOOGLEBOOKS_START_URL_PATTERN.'[^>\]} \n]+$#i', $text) > 0) {
0 ignored issues
show
Bug introduced by
The constant App\Domain\Publisher\Goo...BOOKS_START_URL_PATTERN was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
134
            return true;
135
        }
136
137
        return false;
138
    }
139
140
    /**
141
     * return '.fr' or '.com'.
142
     *
143
     * @param string $url
144
     *
145
     * @return string|null
146
     */
147
    private static function parseGoogleDomain(string $url): ?string
148
    {
149
        $host = parse_url($url, PHP_URL_HOST);
150
        if (!empty($host) && preg_match('#\.[a-z]{2,3}$#', $host, $matches) > 0) {
151
            // Maroc : google.co.ma (sous-domaine!!)
152
            return str_replace(['.ma', '.uk', '.au'], ['.co.ma', '.co.uk', '.com.au'], $matches[0]); // .fr
153
        }
154
155
        return null;
156
    }
157
}
158