Chartjs::guideEntries()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 10
nc 2
nop 2
dl 0
loc 17
ccs 11
cts 11
cp 1
crap 2
rs 9.9332
c 1
b 0
f 0
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 Chartjs extends BaseDocset
12
{
13
    public const CODE = 'chartjs';
14
    public const NAME = 'Chart.js';
15
    public const URL = 'www.chartjs.org';
16
    public const INDEX = 'docs/latest/index.html';
17
    public const PLAYGROUND = 'https://www.chartjs.org/samples/latest/';
18
    public const ICON_16 = '../../icons/icon.png';
19
    public const ICON_32 = '../../icons/[email protected]';
20
    public const EXTERNAL_DOMAINS = [
21
        'use.typekit.net',
22
    ];
23
24
25
    public function grab(): bool
26
    {
27
        $toIgnore = implode('|', [
28
            '/cdn-cgi',
29
            '/docs/2.9.3',
30
            '/docs/master',
31
            '/samples/master'
32
        ]);
33
34
        $toGet = implode('|', [
35
            '\.css',
36
            '\.ico',
37
            '\.js',
38
            '\.svg',
39
            '/docs',
40
            '/samples'
41
        ]);
42
43
        system(
44
            "echo; wget www.chartjs.org \
45
                --mirror \
46
                --trust-server-names \
47
                --reject-regex='{$toIgnore}' \
48
                --accept-regex='{$toGet}' \
49
                --ignore-case \
50
                --page-requisites \
51
                --adjust-extension \
52
                --convert-links \
53
                --span-hosts \
54
                --domains={$this->externalDomains()} \
55
                --directory-prefix=storage/{$this->downloadedDirectory()} \
56
                -e robots=off \
57
                --quiet \
58
                --show-progress",
59
            $result
60
        );
61
62
        return $result === 0;
63
    }
64
65 16
    public function entries(string $file): Collection
66
    {
67 16
        $crawler = HtmlPageCrawler::create(Storage::get($file));
68
69 16
        $entries = collect();
70
71 16
        $entries = $entries->merge($this->guideEntries($crawler, $file));
72 16
        $entries = $entries->merge($this->sectionEntries($crawler, $file));
73
74 16
        return $entries;
75
    }
76
77 16
    protected function guideEntries(HtmlPageCrawler $crawler, string $file)
78
    {
79 16
        $entries = collect();
80
81 16
        if (Str::contains($file, "{$this->url()}/docs/latest/index.html")) {
82
            $crawler
83 16
                ->filter('.summary > li.chapter:not(:first-child) a')
84 16
                ->each(function (HtmlPageCrawler $node) use ($entries) {
85 16
                    $entries->push([
86 16
                        'name' => $node->text(),
87 16
                        'type' => 'Guide',
88 16
                        'path' => $this->url() . '/docs/latest/' . $this->cleanURL($node->attr('href')),
89
                    ]);
90 16
                });
91
        }
92
93 16
        return $entries;
94
    }
95
96 16
    protected function sectionEntries(HtmlPageCrawler $crawler, string $file)
97
    {
98 16
        $entries = collect();
99
100 16
        $crawler->filter('h2')->each(function (HtmlPageCrawler $node) use ($entries, $file) {
101 16
            $entries->push([
102 16
                'name' => $node->text(),
103 16
                'type' => 'Section',
104 16
                'path' => Str::after($file . '#' . Str::slug($node->text()), $this->innerDirectory())
105
            ]);
106 16
        });
107
108 16
        return $entries;
109
    }
110
111
    /**
112
     * Some links are not converted correctly by wget once
113
     * the download is finished. no idea why, but this cleans
114
     * the few that fail.
115
     */
116 16
    protected function cleanURL($url)
117
    {
118 16
        return Str::after($url, 'https://www.chartjs.org/docs/latest/');
119
    }
120
121 16
    public function format(string $file): string
122
    {
123 16
        $crawler = HtmlPageCrawler::create(Storage::get($file));
124
125 16
        $this->removeLeftSidebar($crawler);
126 16
        $this->removeMenuAndSharingButtons($crawler);
127 16
        $this->removeNavigationFromKeyboard($crawler);
128 16
        $this->fixNavigationLinks($crawler);
129 16
        $this->makeContentFullWidth($crawler);
130 16
        $this->removeSearchResults($crawler);
131
132 16
        $this->removePackageVersionBadges($crawler);
133
134 16
        $this->removeUnwantedCSS($crawler);
135 16
        $this->removeUnwantedJavaScript($crawler);
136
137 16
        $this->insertDashTableOfContents($crawler);
138
139 16
        return $crawler->saveHTML();
140
    }
141
142 16
    protected function removeLeftSidebar(HtmlPageCrawler $crawler)
143
    {
144 16
        $crawler->filter('.book-summary')->remove();
145 16
    }
146
147 16
    protected function removeMenuAndSharingButtons(HtmlPageCrawler $crawler)
148
    {
149 16
        $crawler->filter('body')->after(
150 16
            "<script>$(document).ready(function () { $('.pull-right.js-toolbar-action, .pull-left.btn').hide(); });</script>"
151
        );
152 16
    }
153
154 16
    protected function removeNavigationFromKeyboard(HtmlPageCrawler $crawler)
155
    {
156 16
        $crawler->filter('.navigation-prev')
157 16
            ->removeClass('navigation-prev')
158 16
            ->setStyle('left', '0')
159
        ;
160
161 16
        $crawler->filter('.navigation-next')
162 16
            ->removeClass('navigation-next')
163 16
            ->setStyle('right', '0')
164
        ;
165 16
    }
166
167 16
    protected function fixNavigationLinks(HtmlPageCrawler $crawler)
168
    {
169
        $crawler
170 16
            ->filter('.navigation')
171 16
            ->each(function ($node) {
172 16
                if (Str::contains($node->attr('href'), 'chartjs.org')) {
173 8
                    $node->setAttribute('href', basename($node->attr('href')));
174
                }
175 16
            })
176
        ;
177 16
    }
178
179 16
    protected function makeContentFullWidth(HtmlPageCrawler $crawler)
180
    {
181 16
        $crawler->filter('.book-body')->setStyle('left', '0px !important');
182 16
    }
183
184 16
    protected function removeSearchResults(HtmlPageCrawler $crawler)
185
    {
186 16
        $crawler->filter('.search-results')->remove();
187 16
    }
188
189 16
    protected function removePackageVersionBadges(HtmlPageCrawler $crawler)
190
    {
191
        $crawler
192 16
            ->filter('p > a:first-child > img')
193 16
            ->each(function ($node) {
194 16
                $node->closest('a')->remove();
195 16
            });
196 16
    }
197
198 16
    protected function removeUnwantedCSS(HtmlPageCrawler $crawler)
199
    {
200 16
        $crawler->filter('link[href*="search.css"]')->remove();
201 16
    }
202
203 16
    protected function removeUnwantedJavaScript(HtmlPageCrawler $crawler)
204
    {
205 16
        $crawler->filter('script[src*="search.js"]')->remove();
206 16
    }
207
208 16
    protected function insertDashTableOfContents(HtmlPageCrawler $crawler)
209
    {
210 16
        $crawler->filter('.page-inner')
211 16
            ->before('<a name="//apple_ref/cpp/Section/Top" class="dashAnchor"></a>');
212
213 16
        $crawler->filter('h2, h3')->each(static function (HtmlPageCrawler $node) {
214 16
            $node->before(
215
                '<a id="'
216 16
                . Str::slug($node->text())
217 16
                . '" name="//apple_ref/cpp/Section/'
218 16
                . rawurlencode($node->text())
219 16
                . '" class="dashAnchor"></a>'
220
            );
221 16
        });
222 16
    }
223
}
224