Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ExtLinkFixer
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 3
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getXPath
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 apply
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3namespace Flow\Parsoid\Fixer;
4
5use Flow\Parsoid\Fixer;
6use MediaWiki\Title\Title;
7use MediaWiki\Utils\UrlUtils;
8
9/**
10 * Parsoid markup didn't always contain class="external" and rel="nofollow" where appropriate.
11 * This is needed for correct styling and to ensure proper indexing,
12 * so we add them here if they are missing.
13 */
14class ExtLinkFixer implements Fixer {
15
16    private UrlUtils $urlUtils;
17
18    public function __construct( UrlUtils $urlUtils ) {
19        $this->urlUtils = $urlUtils;
20    }
21
22    /**
23     * Returns XPath matching elements that need to be transformed
24     *
25     * @return string XPath of elements this acts on
26     */
27    public function getXPath() {
28        return '//a[contains(concat(" ",normalize-space(@rel)," ")," mw:ExtLink ")]';
29    }
30
31    /**
32     * Adds class="external" & rel="nofollow" to external links.
33     *
34     * @param \DOMNode $node Link
35     * @param Title $title
36     */
37    public function apply( \DOMNode $node, Title $title ) {
38        if ( !$node instanceof \DOMElement ) {
39            return;
40        }
41        $nodeClass = $node->getAttribute( 'class' );
42        if ( strpos( ' ' . $nodeClass . ' ', ' external ' ) === false ) {
43            $node->setAttribute( 'class', 'external' .
44                ( $nodeClass !== '' ? ' ' . $nodeClass : '' ) );
45        }
46
47        global $wgNoFollowLinks, $wgNoFollowDomainExceptions;
48        if (
49            $wgNoFollowLinks &&
50            !$this->urlUtils->matchesDomainList( $node->getAttribute( 'href' ), $wgNoFollowDomainExceptions )
51        ) {
52            $oldRel = $node->getAttribute( 'rel' );
53            if ( strpos( ' ' . $oldRel . ' ', ' nofollow ' ) === false ) {
54                $node->setAttribute( 'rel', 'nofollow' . ( $oldRel !== '' ? ' ' . $oldRel : '' ) );
55            }
56        }
57    }
58}