Passed
Branch dev (1a31b5)
by Dispositif
03:03
created

RefWebTransformer::isTransformAutorized()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 16
c 1
b 0
f 0
nc 10
nop 1
dl 0
loc 27
rs 8.8333
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\Application;
11
12
use App\Domain\Models\Wiki\AbstractWikiTemplate;
13
use App\Domain\Models\Wiki\ArticleTemplate;
14
use App\Domain\Models\Wiki\LienWebTemplate;
15
use App\Domain\Models\Wiki\OuvrageTemplate;
16
use App\Domain\Publisher\WebMapper;
17
use App\Domain\Utils\WikiTextUtil;
18
use App\Domain\WikiTemplateFactory;
19
use App\Infrastructure\Logger;
20
use Psr\Log\LoggerInterface;
21
use Symfony\Component\Yaml\Yaml;
22
use Throwable;
23
24
/**
25
 * Class RefWebTransformer
26
 *
27
 * @package App\Application
28
 */
29
class RefWebTransformer implements TransformerInterface
30
{
31
32
    public $skipUnauthorised = true;
33
    /**
34
     * @var Logger
35
     */
36
    protected $log;
37
    private $config;
38
    /**
39
     * @var string|string[]
40
     */
41
    private $domain;
42
    /**
43
     * @var string
44
     */
45
    private $url;
46
    /**
47
     * @var WebMapper
48
     */
49
    private $mapper;
50
    /**
51
     * @var array
52
     */
53
    private $data = [];
54
    /**
55
     * @var array
56
     */
57
    public $summaryLog = [];
58
59
    /**
60
     * RefWebTransformer constructor.
61
     *
62
     * @param LoggerInterface $log
63
     */
64
    public function __construct(LoggerInterface $log)
65
    {
66
        $this->log = $log;
1 ignored issue
show
Documentation Bug introduced by
$log is of type Psr\Log\LoggerInterface, but the property $log was declared to be of type App\Infrastructure\Logger. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
67
68
        $this->config = Yaml::parseFile(__DIR__.'/resources/config_presse.yaml');
69
        $this->data['newspaper'] = json_decode(file_get_contents(__DIR__.'/resources/data_newspapers.json'), true);
70
        $this->data['scientific domain'] = json_decode(
71
            file_get_contents(__DIR__.'/resources/data_scientific_domain.json'),
72
            true
73
        );
74
        $this->data['scientific wiki'] = json_decode(
75
            file_get_contents(__DIR__.'/resources/data_scientific_wiki.json'),
76
            true
77
        );
78
79
        $this->mapper = new WebMapper(new Logger());
80
    }
81
82
    public function process(string $string)
83
    {
84
        if (!$this->isTransformAutorized($string)) {
85
            return $string;
86
        }
87
88
        $publish = new PublisherAction($this->url);
89
        try {
90
            sleep(3);
91
            $html = $publish->getHTMLSource();
92
            $htmlData = $publish->extractWebData($html);
93
            $this->log->debug('htmlData', $htmlData);
94
        } catch (Throwable $e) {
95
            // ne pas générer de lien brisé !!
96
            $this->log->notice('erreur sur extractWebData');
97
98
            return $string;
99
        }
100
101
        $mapData = $this->mapper->process($htmlData);
102
103
        // check dataValide
104
        if (empty($mapData) || empty($mapData['url']) || empty($mapData['titre'])) {
105
            $this->log->info('Mapping incomplet');
106
107
            return $string;
108
        }
109
110
        $this->tagAndLog($mapData);
111
        $this->addSummaryLog($mapData);
112
113
        $template = $this->chooseTemplateByData($mapData);
114
115
        $mapData = $this->replaceSitenameByConfig($mapData, $template);
116
117
        $template->hydrate($mapData, true);
118
119
        $serialized = $template->serialize(true);
120
        $this->log->info($serialized."\n");
121
122
        return $serialized;
123
    }
124
125
    protected function isTransformAutorized(string $string): bool
126
    {
127
        if (!preg_match('#^http?s://[^ ]+$#i', $string)) {
128
            return false;
129
        }
130
        $this->url = $string;
131
        $parseURL = parse_url($this->url);
132
        $this->domain = str_replace('www.', '', $parseURL['host']);
133
134
        if (!isset($this->config[$this->domain])) {
135
            $this->log->info("Domain ".$this->domain." non configuré\n");
136
            if ($this->skipUnauthorised) {
137
                return false;
138
            }
139
            echo "> Domaine ".Color::LIGHT_RED.$this->domain.Color::NORMAL." non configuré\n";
140
        }
141
142
        $this->config[$this->domain] = $this->config[$this->domain] ?? [];
143
        $this->config[$this->domain] = is_array($this->config[$this->domain]) ? $this->config[$this->domain] : [];
144
145
        if ($this->config[$this->domain] === 'desactived' || isset($this->config[$this->domain]['desactived'])) {
146
            $this->log->info("Domain ".$this->domain." desactivé\n");
147
148
            return false;
149
        }
150
151
        return true;
152
    }
153
154
    private function tagAndLog(array $mapData)
155
    {
156
        $this->log->debug('mapData', $mapData);
157
158
        if (isset($mapData['DATA-ARTICLE']) && $mapData['DATA-ARTICLE']) {
159
            $this->log->notice("Article OK");
160
        }
161
        if (isset($this->data['newspaper'][$this->domain])) {
162
            $this->log->notice('PRESSE');
163
        }
164
        if ($this->isScientificDomain()) {
165
            $this->log->notice('SCIENCE');
166
        }
167
    }
168
169
    private function isScientificDomain(): bool
170
    {
171
        if (isset($this->data['scientific domain'][$this->domain])) {
172
            return true;
173
        }
174
        if (strpos('.revues.org', $this->domain) > 0) {
175
            return true;
176
        }
177
178
        return false;
179
    }
180
181
    private function addSummaryLog(array $mapData)
182
    {
183
        $this->summaryLog[] = $mapData['site'] ?? $mapData['périodique'] ?? '?';
184
    }
185
186
    /**
187
     * todo refac lisible
188
     */
189
    private function chooseTemplateByData(array $mapData): AbstractWikiTemplate
190
    {
191
        // Logique : choix template
192
        $this->config[$this->domain]['template'] = $this->config[$this->domain]['template'] ?? [];
193
        $mapData['DATA-ARTICLE'] = $mapData['DATA-ARTICLE'] ?? false;
194
195
        if ($this->config[$this->domain]['template'] === 'article'
196
            || ($this->config[$this->domain]['template'] === 'auto' && $mapData['DATA-ARTICLE'])
197
            || ($mapData['DATA-ARTICLE'] && !empty($this->data['newspaper'][$this->domain]))
198
            || $this->isScientificDomain()
199
        ) {
200
            $templateName = 'article';
201
        }
202
        if (!isset($templateName) || $this->config[$this->domain]['template'] === 'lien web') {
203
            $templateName = 'lien web';
204
        }
205
        $template = WikiTemplateFactory::create($templateName);
206
        $template->userSeparator = " |";
207
208
        return $template;
209
    }
210
211
    /**
212
     * Logique : remplacement titre périodique ou nom du site
213
     *
214
     * @param array $mapData
215
     * @param       $template
216
     *
217
     * @return array
218
     */
219
    private function replaceSitenameByConfig(array $mapData, $template): array
220
    {
221
        // from wikidata URL of newspapers
222
        if (!empty($this->data['newspaper'][$this->domain])) {
223
            $frwiki = $this->data['newspaper'][$this->domain]['frwiki'];
224
            $label = $this->data['newspaper'][$this->domain]['fr'];
225
            if (isset($mapData['site']) || $template instanceof LienWebTemplate) {
226
                $mapData['site'] = WikiTextUtil::wikilink($label, $frwiki);
227
            }
228
            if (isset($mapData['périodique']) || $template instanceof ArticleTemplate) {
229
                $mapData['périodique'] = WikiTextUtil::wikilink($label, $frwiki);
230
            }
231
        }
232
233
        // from wikidata of scientific journals
234
        if (isset($mapData['périodique']) && isset($this->data['scientific wiki'][$mapData['périodique']])) {
235
            $mapData['périodique'] = WikiTextUtil::wikilink(
236
                $mapData['périodique'],
237
                $this->data['scientific wiki'][$mapData['périodique']]
238
            );
239
        }
240
241
        // from YAML config
242
        if (!empty($this->config[$this->domain]['site']) && $template instanceof LienWebTemplate) {
243
            $mapData['site'] = $this->config[$this->domain]['site'];
244
        }
245
        if (!empty($this->config[$this->domain]['périodique'])
246
            && (!empty($mapData['périodique'])
247
                || $template instanceof OuvrageTemplate)
248
        ) {
249
            $mapData['périodique'] = $this->config[$this->domain]['périodique'];
250
        }
251
252
        return $mapData;
253
    }
254
255
}
256