Passed
Push — master ( a4dc57...71107e )
by Guillaume
10:07
created

Alfred4::insertOnlineRedirection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
namespace App\Docsets;
4
5
use Godbout\DashDocsetBuilder\Docsets\BaseDocset;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Facades\Storage;
8
use Illuminate\Support\Str;
9
use Wa72\HtmlPageDom\HtmlPageCrawler;
10
11
class Alfred4 extends BaseDocset
12
{
13
    public const CODE = 'alfred-4';
14
    public const NAME = 'Alfred 4';
15
    public const URL = 'www.alfredapp.com';
16
    public const INDEX = 'help/index.html';
17
    public const PLAYGROUND = '';
18
    public const ICON_16 = '../../icons/icon.png';
19
    public const ICON_32 = '../../icons/[email protected]';
20
    public const EXTERNAL_DOMAINS = [
21
        'fonts.googleapis.com',
22
    ];
23
24
25
    public function grab(): bool
26
    {
27
        $toGet = implode('|', [
28
           '\.css',
29
            '\.ico',
30
            '\.js',
31
            '\.png',
32
            '\.svg',
33
            '/css',
34
            '/help'
35
        ]);
36
37
        system(
38
            "echo; wget www.alfredapp.com/help \
39
                --mirror \
40
                --trust-server-names \
41
                --accept-regex='{$toGet}' \
42
                --ignore-case \
43
                --page-requisites \
44
                --adjust-extension \
45
                --convert-links \
46
                --span-hosts \
47
                --domains={$this->externalDomains()} \
48
                --directory-prefix=storage/{$this->downloadedDirectory()} \
49
                -e robots=off \
50
                --quiet \
51
                --show-progress",
52
            $result
53
        );
54
55
        return $result === 0;
56
    }
57
58
    public function entries(string $file): Collection
59
    {
60
        $crawler = HtmlPageCrawler::create(Storage::get($file));
61
62
        $entries = collect();
63
        $entries = $entries->merge($this->guideEntries($crawler, $file));
64
        $entries = $entries->merge($this->sectionEntries($crawler, $file));
65
66
        return $entries;
67
    }
68
69
    protected function guideEntries(HtmlPageCrawler $crawler, string $file)
70
    {
71
        $entries = collect();
72
73
        if (Str::contains($file, $this->index())) {
74
            $crawler->filter('#helpmenu a')->each(function (HtmlPageCrawler $node) use ($entries) {
75
                $entries->push([
76
                    'name' => trim($node->text()),
77
                    'type' => 'Guide',
78
                    'path' => $this->url() . '/help/' . $node->attr('href'),
79
                ]);
80
            });
81
        }
82
83
        return $entries;
84
    }
85
86
    protected function sectionEntries(HtmlPageCrawler $crawler, string $file)
87
    {
88
        $entries = collect();
89
90
        $crawler->filter('h1:not(:first-child), h2')->each(function (HtmlPageCrawler $node) use ($entries, $file) {
91
            $entries->push([
92
                'name' => trim($node->text()),
93
                'type' => 'Section',
94
                'path' => Str::after($file, $this->innerDirectory())
95
            ]);
96
        });
97
98
        return $entries;
99
    }
100
101
    public function format(string $file): string
102
    {
103
        $crawler = HtmlPageCrawler::create(Storage::get($file));
104
105
        $this->removeMainNav($crawler);
106
        $this->removeSubNav($crawler);
107
        $this->removeHelpMenu($crawler);
108
        $this->removeLatestBlogPostBanner($crawler);
109
        $this->removeFooter($crawler);
110
        $this->removeFooterMeta($crawler);
111
112
        $this->removeUnwantedJavaScript($crawler);
113
114
        $this->insertOnlineRedirection($crawler, $file);
115
        $this->insertDashTableOfContents($crawler);
116
117
        return $crawler->saveHTML();
118
    }
119
120
    protected function removeMainNav(HtmlPageCrawler $crawler)
121
    {
122
        $crawler->filter('#mainnav')->remove();
123
    }
124
125
    protected function removeSubNav(HtmlPageCrawler $crawler)
126
    {
127
        $crawler->filter('#subnav')->remove();
128
    }
129
130
    protected function removeHelpMenu(HtmlPageCrawler $crawler)
131
    {
132
        $crawler->filter('#helpmenu')->remove();
133
    }
134
135
    protected function removeLatestBlogPostBanner(HtmlPageCrawler $crawler)
136
    {
137
        $crawler->filter('#latestblogpost')->remove();
138
    }
139
140
    protected function removeFooter(HtmlPageCrawler $crawler)
141
    {
142
        $crawler->filter('#footer')->remove();
143
    }
144
145
    protected function removeFooterMeta(HtmlPageCrawler $crawler)
146
    {
147
        $crawler->filter('#footermeta')->remove();
148
    }
149
150
    protected function removeUnwantedJavaScript(HtmlPageCrawler $crawler)
151
    {
152
        $crawler->filterXPath("//script[text()[contains(.,'google-analytics.com')]]")->remove();
153
    }
154
155
    protected function insertOnlineRedirection(HtmlPageCrawler $crawler, string $file)
156
    {
157
        $onlineUrl = Str::substr(Str::after($file, $this->innerDirectory()), 1, -11);
158
159
        $crawler->filter('html')->prepend("<!-- Online page at $onlineUrl -->");
160
    }
161
162
    protected function insertDashTableOfContents($crawler)
163
    {
164
        $crawler->filter('head')
165
            ->before('<a name="//apple_ref/cpp/Section/Top" class="dashAnchor"></a>');
166
167
        $crawler->filter('h1:not(:first-child), h2, h3')->each(static function (HtmlPageCrawler $node) {
168
            $node->before(
169
                '<a id="' . Str::slug($node->text()) . '" name="//apple_ref/cpp/Section/' . rawurlencode($node->text()) . '" class="dashAnchor"></a>'
170
            );
171
        });
172
    }
173
}
174