Completed
Pull Request — master (#3)
by Colin
14:54 queued 01:45
created

EmailAddressParser::getCharacters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark-extras package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * Original code based on the CommonMark JS reference parser (http://bitly.com/commonmark-js)
9
 *  - (c) John MacFarlane
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace League\CommonMark\Extras\EmailAutolink;
16
17
use League\CommonMark\Inline\Element\Link;
18
use League\CommonMark\Inline\Element\Text;
19
use League\CommonMark\Inline\Parser\AbstractInlineParser;
20
use League\CommonMark\InlineParserContext;
21
use League\CommonMark\Util\RegexHelper;
22
23
class EmailAddressParser extends AbstractInlineParser
24
{
25
    public function getCharacters()
26
    {
27
        return ['@'];
28
    }
29
30
    /**
31
     * @param InlineParserContext $inlineContext
32
     * @return bool
33
     */
34
    public function parse(InlineParserContext $inlineContext)
35
    {
36
        // There must be some text prior to the @
37
        $lastChild = $inlineContext->getContainer()->lastChild();
38
        if (!($lastChild instanceof Text)) {
39
            return false;
40
        }
41
42
        $everythingBeforeTheAtSymbol = $lastChild->getContent();
43
        if ($everythingBeforeTheAtSymbol === '') {
44
            return false;
45
        }
46
47
        // Attempt to parse the mailbox portion, which should exist at the very end of this string
48
        $matches = RegexHelper::matchAll('/[a-zA-Z0-9.!#$%&\'*+\\/=?^_`{|}~-]+$/', $everythingBeforeTheAtSymbol);
49
        if (empty($matches)) {
50
            return false;
51
        }
52
53
        $mailbox = end($matches);
54
55
        // Attempt to parse the '@' symbol and domain name
56
        $domain = $inlineContext->getCursor()->match('/^@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/');
57
        if ($domain === null) {
58
            return false;
59
        }
60
61
        $address = $mailbox . $domain;
62
63
        $inlineContext->getContainer()->appendChild(new Link('mailto:' . $address, $address));
64
65
        // Remove the $mailbox part from $lastChild
66
        $newContent = substr($everythingBeforeTheAtSymbol, 0, 0 - strlen($mailbox));
67
        $lastChild->setContent($newContent);
68
69
        return true;
70
    }
71
}
72