Passed
Push — master ( bacc5f...5eccc7 )
by Dispositif
02:22
created

OuvrageOptimize::getSummaryLog()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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;
11
12
use App\Domain\Enums\Language;
13
use App\Domain\Models\Wiki\GoogleLivresTemplate;
14
use App\Domain\Models\Wiki\OuvrageTemplate;
15
use App\Domain\Publisher\GoogleBooksUtil;
16
use App\Domain\Utils\TextUtil;
17
use App\Domain\Utils\WikiTextUtil;
18
use App\Infrastructure\FileManager;
19
use DomainException;
20
use Exception;
21
use Psr\Log\LoggerInterface;
22
use Psr\Log\NullLogger;
23
use Throwable;
24
25
use function mb_strlen;
26
27
/**
28
 * Legacy.
29
 * TODO move methods to OuvrageClean setters
30
 * TODO AbstractProcess
31
 * TODO observer/event (log, MajorEdition)
32
 * Class OuvrageProcess.
33
 */
34
class OuvrageOptimize
35
{
36
    const CONVERT_GOOGLEBOOK_TEMPLATE = false; // change OuvrageOptimizeTest !!
37
38
    const WIKI_LANGUAGE = 'fr';
39
40
    protected $original;
41
42
    private $wikiPageTitle;
43
44
    private $summaryLog = [];
45
46
    public $notCosmetic = false;
47
48
    public $major = false;
49
50
    private $ouvrage;
51
52
    // todo inject TextUtil + ArticleVersion ou WikiRef
53
    /**
54
     * @var LoggerInterface|NullLogger
55
     */
56
    private $log;
57
58 47
    public function __construct(OuvrageTemplate $ouvrage, $wikiPageTitle = null, ?LoggerInterface $log = null)
59
    {
60 47
        $this->original = $ouvrage;
61 47
        $this->ouvrage = clone $ouvrage;
62 47
        $this->wikiPageTitle = ($wikiPageTitle) ?? null;
63 47
        $this->log = $log ?? new NullLogger();
64 47
    }
65
66
    /**
67
     * @return $this
68
     * @throws Exception
69
     */
70 47
    public function doTasks(): self
71
    {
72 47
        $this->cleanAndPredictErrorParameters();
73
74 47
        $this->processAuthors();
75
76 47
        $this->processLang();
77 47
        $this->processLang('langue originale');
78
79 47
        $this->processTitle();
80 47
        $this->convertLienAuteurTitre();
81 47
        $this->processEditeur();
82 47
        $this->processDates();
83 47
        $this->externalTemplates();
84 47
        $this->predictFormatByPattern();
85
86 47
        $this->processIsbn();
87 47
        $this->processBnf();
88
89 47
        $this->processLocation(); // 'lieu'
90
91 47
        $this->GoogleBookURL('lire en ligne');
92 47
        $this->GoogleBookURL('présentation en ligne');
93
94 47
        return $this;
95
    }
96
97
    /**
98
     * Todo: injection dep.
99
     * Todo : "[s. l.]" sans lieu "s.l.n.d." sans lieu ni date.
100
     *
101
     * @throws Exception
102
     */
103 47
    private function processLocation()
104
    {
105 47
        $location = $this->getParam('lieu');
106 47
        if (empty($location)) {
107 42
            return;
108
        }
109
110
        // typo and unwikify
111 5
        $memo = $location;
112 5
        $location = WikiTextUtil::unWikify($location);
113 5
        $location = TextUtil::mb_ucfirst($location);
114 5
        if ($memo !== $location) {
115 1
            $this->setParam('lieu', $location);
116 1
            $this->log('±lieu');
117 1
            $this->notCosmetic = true;
118
        }
119
120
        // translation : "London"->"Londres" seulement si langue=fr
121 5
        if ($this->hasParamValue('langue')
122 5
            && $this->getParam('langue') === self::WIKI_LANGUAGE
123
        ) {
124 1
            $manager = new FileManager();
125 1
            $row = $manager->findCSVline(__DIR__.'/resources/traduction_ville.csv', $location);
126 1
            if (!empty($row) && !empty($row[1])) {
127 1
                $this->setParam('lieu', $row[1]);
128 1
                $this->log('lieu francisé');
129 1
                $this->notCosmetic = true;
130
            }
131
        }
132 5
    }
133
134 47
    private function processBnf()
135
    {
136 47
        $bnf = $this->getParam('bnf');
137 47
        if (!$bnf) {
138 46
            return;
139
        }
140 1
        $bnf = str_ireplace('FRBNF', '', $bnf);
141 1
        $this->setParam('bnf', $bnf);
142 1
    }
143
144
    /**
145
     * @throws Exception
146
     */
147 47
    private function processAuthors()
148
    {
149 47
        $this->distinguishAuthors();
150
        //$this->fusionFirstNameAndName(); // desactived : no consensus
151 47
    }
152
153 47
    private function convertLienAuteurTitre(): void
154
    {
155 47
        $auteurParams = ['auteur1', 'auteur2', 'auteur2', 'titre'];
156 47
        foreach ($auteurParams as $auteurParam) {
157 47
            if ($this->hasParamValue($auteurParam)
158 47
                && $this->hasParamValue('lien '.$auteurParam)
159
            ) {
160 1
                $this->setParam(
161 1
                    $auteurParam,
162 1
                    WikiTextUtil::wikilink(
163 1
                        $this->getParam($auteurParam),
164 1
                        $this->getParam('lien '.$auteurParam)
165
                    )
166
                );
167 1
                $this->unsetParam('lien '.$auteurParam);
168
            }
169
        }
170 47
    }
171
172
    /**
173
     * Detect and correct multiple authors in same parameter.
174
     * Like "auteurs=J. M. Waller, M. Bigger, R. J. Hillocks".
175
     *
176
     * @throws Exception
177
     */
178 47
    private function distinguishAuthors()
179
    {
180
        // merge params of author 1
181 47
        $auteur1 = $this->getParam('auteur') ?? '';
182 47
        $auteur1 .= $this->getParam('auteurs') ?? '';
183 47
        $auteur1 .= $this->getParam('prénom1') ?? '';
184 47
        $auteur1 .= ' '.$this->getParam('nom1') ?? '';
185 47
        $auteur1 = trim($auteur1);
186
        // of authors 2
187 47
        $auteur2 = $this->getParam('auteur2') ?? '';
188 47
        $auteur2 .= $this->getParam('prénom2') ?? '';
189 47
        $auteur2 .= ' '.$this->getParam('nom2') ?? '';
190 47
        $auteur2 = trim($auteur2);
191
192
        // skip if wikilink in author
193 47
        if (empty($auteur1) || WikiTextUtil::isWikify($auteur1)) {
194 42
            return;
195
        }
196
197 5
        $machine = new PredictAuthors();
198 5
        $res = $machine->predictAuthorNames($auteur1);
199
200 5
        if (1 === count($res)) {
201
            // auteurs->auteur?
202 3
            return;
203
        }
204
        // Many authors... and empty "auteur2"
205 2
        if (count($res) >= 2 && empty($auteur2)) {
206
            // delete author-params
207 1
            array_map(
208
                function ($param) {
209 1
                    $this->unsetParam($param);
210 1
                },
211 1
                ['auteur', 'auteurs', 'prénom1', 'nom1']
212
            );
213
            // iterate and edit new values
214 1
            $count = count($res);
215 1
            for ($i = 0; $i < $count; ++$i) {
216 1
                $this->setParam(sprintf('auteur%s', $i + 1), $res[$i]);
217
            }
218 1
            $this->log('distinction auteurs');
219 1
            $this->major = true;
220 1
            $this->notCosmetic = true;
221
        }
222 2
    }
223
224
    /**
225
     * todo: move/implement.
226
     *
227
     * @param string|null $param
228
     *
229
     * @throws Exception
230
     */
231 47
    private function processLang(?string $param = 'langue')
232
    {
233 47
        $lang = $this->getParam($param) ?? null;
234
235 47
        if ($lang) {
236 6
            $lang2 = Language::all2wiki($lang);
237
238
            // strip "langue originale=fr"
239 6
            if ('langue originale' === $param && self::WIKI_LANGUAGE === $lang2
240 6
                && (!$this->getParam('langue') || $this->getParam('langue') === $lang2)
241
            ) {
242 1
                $this->unsetParam('langue originale');
243 1
                $this->log('-langue originale');
244
            }
245
246 6
            if ($lang2 && $lang !== $lang2) {
247 4
                $this->setParam($param, $lang2);
248 4
                if (self::WIKI_LANGUAGE !== $lang2) {
249 3
                    $this->log('±'.$param);
250
                }
251
            }
252
        }
253 47
    }
254
255
    /**
256
     * Validate or correct ISBN.
257
     *
258
     * @throws Exception
259
     */
260 47
    private function processIsbn()
261
    {
262 47
        $isbn = $this->getParam('isbn') ?? '';
263 47
        if (empty($isbn)) {
264 37
            return;
265
        }
266
267
        // ISBN-13 à partir de 2007
268 10
        $year = $this->findBookYear();
269 10
        if ($year !== null && $year < 2007 && 10 === strlen($this->stripIsbn($isbn))) {
270
            // juste mise en forme ISBN-10 pour 'isbn'
271
            try {
272 2
                $isbnMachine = new IsbnFacade($isbn);
273 2
                $isbnMachine->validate();
274 2
                $isbn10pretty = $isbnMachine->format('ISBN-10');
275 2
                if ($isbn10pretty !== $isbn) {
276 2
                    $this->setParam('isbn', $isbn10pretty);
277 2
                    $this->log('ISBN10');
278
                    //                    $this->notCosmetic = true;
279
                }
280
            } catch (Throwable $e) {
281
                // ISBN not validated
282
                $this->setParam(
283
                    'isbn invalide',
284
                    sprintf('%s %s', $isbn, $e->getMessage() ?? '')
285
                );
286
                $this->log(sprintf('ISBN invalide: %s', $e->getMessage()));
287
                $this->notCosmetic = true;
288
            }
289
290 2
            return;
291
        }
292
293
        try {
294 8
            $isbnMachine = new IsbnFacade($isbn);
295 8
            $isbnMachine->validate();
296 7
            $isbn13 = $isbnMachine->format('ISBN-13');
297 1
        } catch (Throwable $e) {
298
            // ISBN not validated
299
            // TODO : bot ISBN invalide (queue, message PD...)
300 1
            $this->setParam(
301 1
                'isbn invalide',
302 1
                sprintf('%s %s', $isbn, $e->getMessage() ?? '')
303
            );
304 1
            $this->log(sprintf('ISBN invalide: %s', $e->getMessage()));
305 1
            $this->notCosmetic = true;
306
307
            // TODO log file ISBNinvalide
308 1
            return;
309
        }
310
311
        // Si $isbn13 et 'isbn2' correspond à ISBN-13 => suppression
312 7
        if (isset($isbn13)
313 7
            && $this->hasParamValue('isbn2')
314 7
            && $this->stripIsbn($this->getParam('isbn2')) === $this->stripIsbn($isbn13)
315
        ) {
316 1
            $this->unsetParam('isbn2');
317
        }
318
319
        // ISBN-10 ?
320 7
        $stripIsbn = $this->stripIsbn($isbn);
321 7
        if (10 === mb_strlen($stripIsbn)) {
322
            // ajout des tirets
323 4
            $isbn10pretty = $isbn;
324
325
            try {
326 4
                $isbn10pretty = $isbnMachine->format('ISBN-10');
327
            } catch (Throwable $e) {
328
                unset($e);
329
            }
330
331
            // archivage ISBN-10 dans 'isbn2'
332 4
            if (!$this->getParam('isbn2')) {
333 4
                $this->setParam('isbn2', $isbn10pretty);
334
            }
335
            // sinon dans 'isbn3'
336 4
            if ($this->hasParamValue('isbn2')
337 4
                && $this->stripIsbn($this->getParam('isbn2')) !== $stripIsbn
338 4
                && empty($this->getParam('isbn3'))
339
            ) {
340
                $this->setParam('isbn3', $isbn10pretty);
341
            }
342
            // delete 'isbn10' (en attendant modification modèle)
343 4
            if ($this->hasParamValue('isbn10') && $this->stripIsbn($this->getParam('isbn10')) === $stripIsbn) {
344
                $this->unsetParam('isbn10');
345
            }
346
        }
347
348
        // ISBN correction
349 7
        if ($isbn13 !== $isbn) {
350 7
            $this->setParam('isbn', $isbn13);
351 7
            $this->log('ISBN');
352
            //            $this->notCosmetic = true;
353
        }
354 7
    }
355
356
    /**
357
     * Find year of book publication.
358
     *
359
     * @return int|null
360
     * @throws Exception
361
     */
362 10
    private function findBookYear(): ?int
363
    {
364 10
        $annee = $this->getParam('année');
365 10
        if (!empty($annee) && is_numeric($annee)) {
366 1
            return intval($annee);
367
        }
368 9
        $date = $this->getParam('date');
369 9
        if ($date && preg_match('#[^0-9]?([12][0-9][0-9][0-9])[^0-9]?#', $date, $matches) > 0) {
370 1
            return intval($matches[1]);
371
        }
372
373 8
        return null;
374
    }
375
376 9
    private function stripIsbn(string $isbn): string
377
    {
378 9
        return trim(preg_replace('#[^0-9Xx]#', '', $isbn));
379
    }
380
381 47
    private function processTitle()
382
    {
383 47
        $currentTask = 'titres';
0 ignored issues
show
Unused Code introduced by
The assignment to $currentTask is dead and can be removed.
Loading history...
384
385 47
        $oldtitre = $this->getParam('titre');
386 47
        $this->langInTitle();
387 47
        $this->deWikifyExternalLink('titre');
388 47
        $this->upperCaseFirstLetter('titre');
389 47
        $this->typoDeuxPoints('titre');
390
391 47
        $this->extractSubTitle();
392
393
        // 20-11-2019 : Retiré majuscule à sous-titre
394
395 47
        if ($this->getParam('titre') !== $oldtitre) {
396 5
            $this->log('±titre');
397
        }
398
399 47
        $this->valideNumeroChapitre();
400 47
        $this->deWikifyExternalLink('titre chapitre');
401 47
        $this->upperCaseFirstLetter('titre chapitre');
402 47
    }
403
404 13
    private function detectColon($param): bool
405
    {
406
        // > 0 don't count a starting colon ":bla"
407 13
        if ($this->hasParamValue($param) && mb_strrpos($this->getParam('titre'), ':') > 0) {
408 3
            return true;
409
        }
410
411 10
        return false;
412
    }
413
414 47
    private function extractSubTitle(): void
415
    {
416
        // FIXED bug [[fu:bar]]
417 47
        if (!$this->getParam('titre') || WikiTextUtil::isWikify($this->getParam('titre'))) {
418 34
            return;
419
        }
420
421 13
        if (!$this->detectColon('titre')) {
422 10
            return;
423
        }
424
        // Que faire si déjà un sous-titre ?
425 3
        if ($this->hasParamValue('sous-titre')) {
426
            return;
427
        }
428
429
        // titre>5 and sous-titre>5 and sous-titre<40
430 3
        if (preg_match('#^(?<titre>[^:]{5,}):(?<st>.{5,40})$#', $this->getParam('titre'), $matches) > 0) {
431 3
            $this->setParam('titre', trim($matches['titre']));
432 3
            $this->setParam('sous-titre', trim($matches['st']));
433 3
            $this->log('>sous-titre');
434
        }
435 3
    }
436
437
    /**
438
     * Normalize a Google Book links.
439
     * Clean the useless URL parameters or transform into wiki-template.
440
     *
441
     * @param $param
442
     *
443
     * @throws Exception
444
     */
445 47
    private function googleBookUrl(string $param): void
446
    {
447 47
        $url = $this->getParam($param);
448 47
        if (empty($url)
449 47
            || !GoogleBooksUtil::isGoogleBookURL($url)
450
        ) {
451 47
            return;
452
        }
453
454 1
        if (self::CONVERT_GOOGLEBOOK_TEMPLATE) {
455
            $template = GoogleLivresTemplate::createFromURL($url);
456
            if ($template) {
457
                $this->setParam($param, $template->serialize());
458
                $this->log('{Google}');
459
                $this->notCosmetic = true;
460
461
                return;
462
            }
463
        }
464
465
        try {
466 1
            $goo = GoogleBooksUtil::simplifyGoogleUrl($url);
467
        } catch (DomainException $e) {
468
            // ID manquant ou malformé
469
            $errorValue = sprintf(
470
                '%s <!-- ERREUR %s -->',
471
                $url,
472
                $e->getMessage()
473
            );
474
            $this->setParam($param, $errorValue);
475
            $this->log('erreur URL');
476
            $this->notCosmetic = true;
477
            $this->major = true;
478
        }
479
480 1
        if (!empty($goo) && $goo !== $url) {
481 1
            $this->setParam($param, $goo);
482
            // cleaned tracking parameters in Google URL ?
483 1
            if (GoogleBooksUtil::isTrackingUrl($url)) {
484 1
                $this->log('tracking');
485 1
                $this->notCosmetic = true;
486
            }
487
        }
488 1
    }
489
490
    /**
491
     * - {{lang|...}} dans titre => langue=... puis titre nettoyé
492
     *  langue=L’utilisation de ce paramètre permet aussi aux synthétiseurs vocaux de reconnaître la langue du titre de
493
     * l’ouvrage.
494
     * Il est possible d'afficher plusieurs langues, en saisissant le nom séparé par des espaces ou des virgules. La première langue doit être celle du titre.
495
     *
496
     * @throws Exception
497
     */
498 47
    private function langInTitle(): void
499
    {
500 47
        if (preg_match(
501 47
                '#^{{ ?(?:lang|langue) ?\| ?([a-z-]{2,5}) ?\| ?(?:texte=)?([^{}=]+)(?:\|dir=rtl)?}}$#i',
502 47
                $this->getParam('titre'),
503
                $matches
504 47
            ) > 0
505
        ) {
506
            $lang = trim($matches[1]);
507
            $newtitre = str_replace($matches[0], trim($matches[2]), $this->getParam('titre'));
508
509
            // problème : titre anglais de livre français
510
            // => conversion {{lang}} du titre seulement si langue= défini
511
            // opti : restreindre à ISBN zone 2 fr ?
512
            if ($lang === $this->getParam('langue')) {
513
                $this->setParam('titre', $newtitre);
514
                $this->log('°titre');
515
            }
516
517
            // desactivé à cause de l'exception décrite ci-dessus
518
            // si langue=VIDE : ajout langue= à partir de langue titre
519
            //            if (self::WIKI_LANGUAGE !== $lang && empty($this->getParam('langue'))) {
520
            //                $this->setParam('langue', $lang);
521
            //                $this->log('+langue='.$lang);
522
            //            }
523
        }
524 47
    }
525
526 47
    private function processDates()
527
    {
528
        // dewikification
529 47
        $params = ['date', 'année', 'mois', 'jour'];
530 47
        foreach ($params as $param) {
531 47
            if ($this->hasParamValue($param) && WikiTextUtil::isWikify(' '.$this->getParam($param))) {
532 1
                $this->setParam($param, WikiTextUtil::unWikify($this->getParam($param)));
533
            }
534
        }
535
536
        try {
537 47
            $this->moveDate2Year();
538
        } catch (Exception $e) {
539
            $this->log->warning('Exception '.$e->getMessage());
540
        }
541 47
    }
542
543
    /**
544
     * todo: move to AbstractWikiTemplate ?
545
     * Correction des parametres rejetés à l'hydratation données.
546
     *
547
     * @throws Exception
548
     */
549 47
    private function cleanAndPredictErrorParameters()
550
    {
551 47
        if (empty($this->ouvrage->parametersErrorFromHydrate)) {
552 45
            return;
553
        }
554 2
        $allParamsAndAlias = $this->ouvrage->getParamsAndAlias();
555
556 2
        foreach ($this->ouvrage->parametersErrorFromHydrate as $name => $value) {
557 2
            if (!is_string($name)) {
558
                // example : 1 => "ouvrage collectif" from |ouvrage collectif|
559 1
                continue;
560
            }
561
562
            // delete error parameter if no value
563 2
            if (empty($value)) {
564
                unset($this->ouvrage->parametersErrorFromHydrate[$name]);
565
566
                continue;
567
            }
568
569 2
            $maxDistance = 1;
570 2
            if (mb_strlen($name) >= 4) {
571 2
                $maxDistance = 2;
572
            }
573 2
            if (mb_strlen($name) >= 8) {
574
                $maxDistance = 3;
575
            }
576
577 2
            $predName = TextUtil::predictCorrectParam($name, $allParamsAndAlias, $maxDistance);
578 2
            if ($predName && mb_strlen($name) >= 5) {
579 2
                if (empty($this->getParam($predName))) {
580 2
                    $predName = $this->ouvrage->getAliasParam($predName);
581 2
                    $this->setParam($predName, $value);
582 2
                    $this->log(sprintf('%s⇒%s ?', $name, $predName));
583 2
                    $this->notCosmetic = true;
584 2
                    unset($this->ouvrage->parametersErrorFromHydrate[$name]);
585
                }
586
            }
587
        }
588 2
    }
589
590
    /**
591
     * TODO : return "" instead of null ?
592
     *
593
     * @param $name
594
     *
595
     * @return string|null
596
     * @throws Exception
597
     */
598 47
    private function getParam(string $name): ?string
599
    {
600 47
        return $this->ouvrage->getParam($name);
601
    }
602
603 47
    private function hasParamValue(string $name): bool
604
    {
605 47
        return $this->ouvrage->hasParamValue($name);
1 ignored issue
show
Deprecated Code introduced by
The function App\Domain\Models\Wiki\A...mplate::hasParamValue() has been deprecated: 17-04-2020 : Scrutinizer doesn't identify as same as !empty(getParam()) For a parameter, check is the value exists (not empty). ( Ignorable by Annotation )

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

605
        return /** @scrutinizer ignore-deprecated */ $this->ouvrage->hasParamValue($name);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
606
    }
607
608 35
    private function setParam($name, $value)
609
    {
610
        // todo : overwrite setParam() ?
611 35
        if (!empty($value) || $this->ouvrage->getParam($name)) {
612 35
            $this->ouvrage->setParam($name, $value);
613
        }
614 35
    }
615
616 26
    private function log(string $string): void
617
    {
618 26
        if (!empty($string)) {
619 26
            $this->summaryLog[] = trim($string);
620
        }
621 26
    }
622
623
    /**
624
     * Bool ?
625
     * déwikification du titre : consensus Bistro 27 août 2011
626
     * idem  'titre chapitre'.
627
     *
628
     * @param string $param
629
     *
630
     * @throws Exception
631
     */
632 47
    private function deWikifyExternalLink(string $param): void
633
    {
634 47
        if (empty($this->getParam($param))) {
635 47
            return;
636
        }
637 15
        if (preg_match('#^\[(http[^ \]]+) ([^]]+)]#i', $this->getParam($param), $matches) > 0) {
638 1
            $this->setParam($param, str_replace($matches[0], $matches[2], $this->getParam($param)));
639 1
            $this->log('±'.$param);
640
641 1
            if (in_array($param, ['titre', 'titre chapitre'])) {
642 1
                if (empty($this->getParam('lire en ligne'))) {
643 1
                    $this->setParam('lire en ligne', $matches[1]);
644 1
                    $this->log('+lire en ligne');
645
646 1
                    return;
647
                }
648
                $this->log('autre lien externe: '.$matches[1]);
649
            }
650
        }
651 14
    }
652
653 47
    private function upperCaseFirstLetter($param)
654
    {
655 47
        if (!$this->hasParamValue($param)) {
656 47
            return;
657
        }
658 15
        $newValue = TextUtil::mb_ucfirst(trim($this->getParam($param)));
659 15
        $this->setParam($param, $newValue);
660 15
    }
661
662
    /**
663
     * Typo internationale 'titre : sous-titre'.
664
     * Fix fantasy typo of subtitle with '. ' or ' - '.
665
     * International Standard Bibliographic Description :
666
     * https://fr.wikipedia.org/wiki/Wikip%C3%A9dia:Le_Bistro/13_janvier_2016#Modif_du_mod%C3%A8le:Ouvrage.
667
     *
668
     * @param $param
669
     *
670
     * @throws Exception
671
     */
672 47
    private function typoDeuxPoints($param)
673
    {
674 47
        $origin = $this->getParam($param) ?? '';
675 47
        if (empty($origin)) {
676 32
            return;
677
        }
678
        // FIXED bug [[fu:bar]]
679 15
        if (WikiTextUtil::isWikify($origin)) {
680 2
            return;
681
        }
682
683 13
        $origin = TextUtil::replaceNonBreakingSpaces($origin);
684
685 13
        $strTitle = $origin;
686
687
        // CORRECTING TYPO FANTASY OF SUBTITLE
688
689
        // Replace first '.' by ':' if no ': ' and no numbers around (as PHP 7.3)
690
        // exlude pattern "blabla... blabla"
691
        // TODO: statistics
692
693
        // Replace ' - ' or ' / ' (spaced!) by ' : ' if no ':' and no numbers after (as PHP 7.3 or 1939-1945)
694 13
        if (!mb_strpos(':', $strTitle) && preg_match('#.{6,} ?[-/] ?[^0-9)]{6,}#', $strTitle) > 0) {
695 4
            $strTitle = preg_replace('#(.{6,}) [-/] ([^0-9)]{6,})#', '$1 : $2', $strTitle);
696
        }
697
698
        // international typo style " : " (first occurrence)
699 13
        $strTitle = preg_replace('#[ ]*:[ ]*#', ' : ', $strTitle);
700
701 13
        if ($strTitle !== $origin) {
702 3
            $this->setParam($param, $strTitle);
703 3
            $this->log(sprintf(':%s', $param));
704
        }
705 13
    }
706
707 47
    private function valideNumeroChapitre()
708
    {
709 47
        $value = $this->getParam('numéro chapitre');
710 47
        if (empty($value)) {
711 47
            return;
712
        }
713
        // "12" ou "VI", {{II}}, II:3
714
        if (preg_match('#^[0-9IVXL\-.:{}]+$#i', $value) > 0) {
715
            return;
716
        }
717
        // déplace vers "titre chapitre" ?
718
        if (!$this->getParam('titre chapitre')) {
719
            $this->unsetParam('numéro chapitre');
720
            $this->setParam('titre chapitre', $value);
721
        }
722
        $this->log('≠numéro chapitre');
723
    }
724
725 9
    private function unsetParam($name)
726
    {
727 9
        $this->ouvrage->unsetParam($name);
728 9
    }
729
730
    /**
731
     * TODO move+refac
732
     * TODO CommentaireBiblioTemplate  ExtraitTemplate
733
     * Probleme {{commentaire biblio}} <> {{commentaire biblio SRL}}
734
     * Generate supplementary templates from obsoletes params.
735
     *
736
     * @throws Exception
737
     */
738 47
    protected function externalTemplates()
739
    {
740
        // "extrait=bla" => {{citation bloc|bla}}
741 47
        if ($this->hasParamValue('extrait')) {
742 1
            $extrait = $this->getParam('extrait');
743
            // todo bug {{citation bloc}} si "=" ou "|" dans texte de citation
744
            // Legacy : use {{début citation}} ... {{fin citation}}
745 1
            if (preg_match('#[=|]#', $extrait) > 0) {
746
                $this->ouvrage->externalTemplates[] = (object)[
747
                    'template' => 'début citation',
748
                    '1' => '',
749
                    'raw' => '{{Début citation}}'.$extrait.'{{Fin citation}}',
750
                ];
751
                $this->log('{Début citation}');
752
                $this->notCosmetic = true;
753
            } else {
754
                // StdClass
755 1
                $this->ouvrage->externalTemplates[] = (object)[
756 1
                    'template' => 'citation bloc',
757 1
                    '1' => $extrait,
758 1
                    'raw' => '{{Citation bloc|'.$extrait.'}}',
759
                ];
760 1
                $this->log('{Citation bloc}');
761 1
                $this->notCosmetic = true;
762
            }
763
764 1
            $this->unsetParam('extrait');
765 1
            $this->notCosmetic = true;
766
        }
767
768
        // "commentaire=bla" => {{Commentaire biblio|1=bla}}
769 47
        if ($this->hasParamValue('commentaire')) {
770 1
            $commentaire = $this->getParam('commentaire');
771 1
            $this->ouvrage->externalTemplates[] = (object)[
772 1
                'template' => 'commentaire biblio',
773 1
                '1' => $commentaire,
774 1
                'raw' => '{{Commentaire biblio|'.$commentaire.'}}',
775
            ];
776 1
            $this->unsetParam('commentaire');
777 1
            $this->log('{commentaire}');
778 1
            $this->notCosmetic = true;
779
        }
780 47
    }
781
782
    // ----------------------
783
    // ----------------------
784
    // ----------------------
785
786
    /**
787
     * Date->année (nécessaire pour OuvrageComplete).
788
     *
789
     * @throws Exception
790
     */
791 47
    private function moveDate2Year()
792
    {
793 47
        $date = $this->getParam('date') ?? false;
794 47
        if ($date) {
795 3
            if (preg_match('#^-?[12][0-9][0-9][0-9]$#', $date)) {
796 1
                $this->setParam('année', $date);
797 1
                $this->unsetParam('date');
798
                //$this->log('>année');
799
            }
800
        }
801 47
    }
802
803 47
    private function predictFormatByPattern()
804
    {
805 47
        if (($value = $this->getParam('format'))) {
806
            // predict if 'format électronique'
807
            // format electronique lié au champ 'lire en ligne'
808
            // 2015 https://fr.wikipedia.org/wiki/Discussion_mod%C3%A8le:Ouvrage#format,_format_livre,_format_%C3%A9lectronique
809
            //            if (preg_match('#(pdf|epub|html|kindle|audio|\{\{aud|jpg)#i', $value) > 0) {
810
            //
811
            //                $this->setParam('format électronique', $value);
812
            //                $this->unsetParam('format');
813
            //                $this->log('format:électronique?');
814
            //
815
            //                return;
816
            //            }
817
            if (preg_match(
818
                    '#(ill\.|couv\.|in-[0-9]|in-fol|poche|broché|relié|{{unité|{{Dunité|[0-9]{2} ?cm|\|cm}}|vol\.|A4)#i',
819
                    $value
820
                ) > 0
821
            ) {
822
                $this->setParam('format livre', $value);
823
                $this->unsetParam('format');
824
                $this->log('format:livre?');
825
                $this->notCosmetic = true;
826
            }
827
            // Certainement 'format électronique'...
828
        }
829 47
    }
830
831
    /**
832
     * @return bool
833
     * @throws Exception
834
     */
835
    public function checkMajorEdit(): bool
836
    {
837
        // Correction paramètre
838
        if ($this->ouvrage->parametersErrorFromHydrate !== $this->original->parametersErrorFromHydrate) {
839
            return true;
840
        }
841
        // Complétion langue ?
842
        if ($this->hasParamValue('langue') && !$this->original->hasParamValue('langue')
1 ignored issue
show
Deprecated Code introduced by
The function App\Domain\Models\Wiki\A...mplate::hasParamValue() has been deprecated: 17-04-2020 : Scrutinizer doesn't identify as same as !empty(getParam()) For a parameter, check is the value exists (not empty). ( Ignorable by Annotation )

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

842
        if ($this->hasParamValue('langue') && !/** @scrutinizer ignore-deprecated */ $this->original->hasParamValue('langue')

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
843
            && self::WIKI_LANGUAGE !== $this->getParam('langue')
844
        ) {
845
            return true;
846
        }
847
        // TODO replace conditions ci-dessous par event flagMajor()
848
        // Retire le param/value 'langue' (pas major si conversion nom langue)
849
        $datOuvrage = $this->ouvrage->toArray();
850
        $datOriginal = $this->original->toArray();
851
        unset($datOriginal['langue'], $datOuvrage['langue']);
852
853
        // Modification données
854
        if ($datOriginal !== $datOuvrage) {
855
            return true;
856
        }
857
858
        return false;
859
    }
860
861
    /**
862
     * @return array
863
     */
864 1
    public function getSummaryLog(): array
865
    {
866 1
        return $this->summaryLog;
867
    }
868
869
    /**
870
     * @return OuvrageTemplate
871
     */
872 47
    public function getOuvrage(): OuvrageTemplate
873
    {
874 47
        return $this->ouvrage;
875
    }
876
877
    /**
878
     * todo : vérif lien rouge
879
     * todo 'lien éditeur' affiché 1x par page
880
     * opti : Suppression lien éditeur si c'est l'article de l'éditeur.
881
     *
882
     * @throws Exception
883
     */
884 47
    private function processEditeur()
885
    {
886 47
        $editeur = $this->getParam('éditeur');
887 47
        if (empty($editeur)) {
888 42
            return;
889
        }
890
891
        // FIX bug "GEO Art ([[Prisma Media]]) ; [[Le Monde]]"
892 5
        if (preg_match('#\[.*\[.*\[#', $editeur) > 0) {
893 1
            return;
894
        }
895
        // FIX bug "[[Fu|Bar]] bla" => [[Fu|Bar bla]]
896 4
        if (preg_match('#(.+\[\[|\]\].+)#', $editeur) > 0) {
897 1
            return;
898
        }
899
900
        // [[éditeur]]
901 3
        if (preg_match('#\[\[([^|]+)]]#', $editeur, $matches) > 0) {
902 1
            $editeurUrl = $matches[1];
903
        }
904
        // [[bla|éditeur]]
905 3
        if (preg_match('#\[\[([^]|]+)\|.+]]#', $editeur, $matches) > 0) {
906
            $editeurUrl = $matches[1];
907
        }
908
909
        // Todo : traitement/suppression des abréviations communes :
910
        // ['éd. de ', 'éd. du ', 'éd.', 'ed.', 'Éd. de ', 'Éd.', 'édit.', 'Édit.', '(éd.)', '(ed.)', 'Ltd.']
911
912 3
        $editeurStr = WikiTextUtil::unWikify($editeur);
913
        // On garde minuscule sur éditeur, pour nuance Éditeur/éditeur permettant de supprimer "éditeur"
914
        // ex: "éditions Milan" => "Milan"
915
916
        // Déconseillé : 'lien éditeur' (obsolete 2019)
917 3
        if ($this->hasParamValue('lien éditeur')) {
918 2
            if (empty($editeurUrl)) {
919 2
                $editeurUrl = $this->getParam('lien éditeur');
920
            }
921 2
            $this->unsetParam('lien éditeur');
922
        }
923
924 3
        $newEditeur = $editeurStr;
925 3
        if (!empty($editeurUrl)) {
926 3
            $newEditeur = WikiTextUtil::wikilink($editeurStr, $editeurUrl);
927
        }
928
929 3
        if ($newEditeur !== $editeur) {
930 2
            $this->setParam('éditeur', $newEditeur);
931 2
            $this->log('±éditeur');
932 2
            $this->notCosmetic = true;
933
        }
934 3
    }
935
}
936