Completed
Push — master ( a79fb5...bda2d1 )
by Emmanuel
02:07
created

GlW3CValidator::sendToW3C()   B

Complexity

Conditions 8
Paths 27

Size

Total Lines 59
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 14
Bugs 1 Features 4
Metric Value
c 14
b 1
f 4
dl 0
loc 59
rs 7.132
cc 8
eloc 37
nc 27
nop 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 *
4
 * PHP version 5.4
5
 *
6
 * @category  GLICER
7
 * @package   GlValidator
8
 * @author    Emmanuel ROECKER
9
 * @author    Rym BOUCHAGOUR
10
 * @copyright 2015 GLICER
11
 * @license   MIT
12
 * @link      http://dev.glicer.com/
13
 *
14
 * Created : 19/02/15
15
 * File : GlW3CValidator.php
16
 *
17
 */
18
19
namespace GlValidator;
20
21
use Symfony\Component\Finder\SplFileInfo;
22
use Symfony\Component\Finder\Finder;
23
use Symfony\Component\Filesystem\Filesystem;
24
use GuzzleHttp\Client;
25
use GuzzleHttp\Post\PostFile;
26
use GlHtml\GlHtml;
27
28
/**
29
 * Class GlW3CValidator
30
 * @package GlValidator
31
 */
32
class GlW3CValidator
33
{
34
    const MAX_RETRY = 3;
35
36
    private $types = [
37
        'html' => [
38
            'validator' => '/',
39
            'resulttag' => '#results',
40
            'field'     => 'file',
41
            'css'       => [
42
                '/style.css'
43
            ]
44
        ],
45
        'css'  => [
46
            'validator' => '/validator',
47
            'resulttag' => '#results_container',
48
            'field'     => 'file',
49
            'css'       => [
50
                '/style/base.css',
51
                '/style/results.css'
52
            ]
53
        ]
54
    ];
55
56
    /**
57
     * @var \Symfony\Component\Filesystem\Filesystem
58
     */
59
    private $fs;
60
61
    /**
62
     * @var string
63
     */
64
    private $resultrootdir;
65
66
    /**
67
     * @param string $resultrootdir
68
     * @param string $urlHtmlValidator
69
     * @param string $urlCssValidator
70
     */
71
    public function __construct(
72
        $resultrootdir,
73
        $urlHtmlValidator = "https://validator.w3.org/nu",
74
        $urlCssValidator = "http://jigsaw.w3.org/css-validator"
75
    ) {
76
        $this->fs            = new Filesystem();
77
        $this->resultrootdir = $resultrootdir;
78
79
        $this->types['html']['w3curl'] = $urlHtmlValidator;
80
        $this->types['css']['w3curl']  = $urlCssValidator;
81
82
        if (!($this->fs->exists($resultrootdir))) {
83
            $this->fs->mkdir($resultrootdir);
84
        }
85
    }
86
87
    /**
88
     * @param string $w3curl
89
     * @param string $validator
90
     * @param string $field
91
     * @param string $htmltag
92
     * @param string $file
93
     * @param string $title
94
     * @param array  $csslist
95
     *
96
     * @return string
97
     */
98
    private function sendToW3C($w3curl, $validator, $field, $htmltag, $file, $title, $csslist)
99
    {
100
        $client = new Client();
101
102
        $request  = $client->createRequest('POST', $w3curl . $validator, ['exceptions' => false]);
103
        $postBody = $request->getBody();
104
        $postBody->addFile(
105
                 new PostFile($field, fopen(
106
                     $file,
107
                     'r'
108
                 ))
109
        );
110
111
        $retry    = self::MAX_RETRY;
112
        $response = null;
113
        while ($retry--) {
114
            $response = $client->send($request);
115
            if ($response->getStatusCode() == 200) {
116
                break;
117
            }
118
        }
119
120
        $html = $response->getBody()->getContents();
121
122
        $html = new GlHtml($html);
123
124
        if ($html->get(".success")) {
125
            return null;
126
        }
127
128
        $html->delete('head style');
129
        $style = '<style type="text/css" media="all">';
130
        foreach ($csslist as $css) {
131
            $style .= '@import url("' . $w3curl . $css . '");';
132
        }
133
        $style .= '</style>';
134
        $html->get("head")[0]->add($style);
135
136
137
        $stats = $html->get("p.stats");
138
        if (isset($stats) && count($stats) > 0) {
139
            $stats[0]->delete();
140
        }
141
142
        $head = $html->get("head")[0]->getHtml();
143
144
        $resulttag = $html->get($htmltag);
145
        if (count($resulttag) <= 0) {
146
            $result = '<p class="failure">There were errors.</p>';
147
        } else {
148
            $result = $resulttag[0]->getHtml();
149
        }
150
151
        $view = '<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">' .
152
            $head . "</head><body><h2>$title</h2>" .
153
            $result . "</body></html>";
154
155
        return $view;
156
    }
157
158
    /**
159
     * @param SplFileInfo $fileinfo
160
     *
161
     * @throws \Exception
162
     * @return string
163
     */
164
    private function validateFile(SplFileInfo $fileinfo)
165
    {
166
        $ext   = $fileinfo->getExtension();
167
        $title = strtr($fileinfo->getRelativePathname(), ["\\" => "/"]);
168
        $view  = $this->sendToW3C(
169
                      $this->types[$ext]['w3curl'],
170
                          $this->types[$ext]['validator'],
171
                          $this->types[$ext]['field'],
172
                          $this->types[$ext]['resulttag'],
173
                          strtr($fileinfo->getRealPath(), ["\\" => "/"]),
174
                          $title,
175
                          $this->types[$ext]['css']
176
        );
177
178
        if ($view === null) {
179
            return null;
180
        }
181
182
        $filedir = $this->resultrootdir . '/' . strtr($fileinfo->getRelativepath(), ["\\" => "/"]);
183
        if (!$this->fs->exists($filedir)) {
184
            $this->fs->mkdir($filedir);
185
        }
186
        $resultname = $filedir . "/w3c_" . $ext . "_" . $fileinfo->getBaseName($ext) . 'html';
187
        file_put_contents($resultname, $view);
188
189
        return $resultname;
190
    }
191
192
    /**
193
     * @param array    $files
194
     * @param array    $types
195
     * @param callable $callback
196
     *
197
     * @throws \Exception
198
     * @return array
199
     */
200
    public function validate(array $files, array $types, callable $callback)
201
    {
202
        $filter = '/\.(' . implode('|', $types) . ')$/';
203
204
        $results = [];
205
        foreach ($files as $file) {
206
            if ($file instanceof Finder) {
207
                $this->validateFinder($file, $filter, $callback, $results);
208
            } else {
209
                if (is_string($file)) {
210
                    $this->validateDirect($file, $filter, $callback, $results);
211
                } else {
212
                    throw new \Exception('Must be a string or a finder');
213
                }
214
            }
215
        }
216
217
        return $results;
218
    }
219
220
221
    /**
222
     * @param Finder   $files
223
     * @param string   $filter
224
     * @param callable $callback
225
     * @param array    $result
226
     */
227
    private function validateFinder(Finder $files, $filter, callable $callback, array &$result)
228
    {
229
        $files->name($filter);
230
        /**
231
         * @var SplFileInfo $file
232
         */
233 View Code Duplication
        foreach ($files as $file) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234
            $callback($file);
235
            $result[strtr($file->getRelativePath() . '/' . $file->getFilename(), ["\\" => "/"])] = $this->validateFile(
236
                                                                                                        $file
237
            );
238
        }
239
    }
240
241
    /**
242
     * @param string   $file
243
     * @param string   $filter
244
     * @param callable $callback
245
     * @param array    $result
246
     */
247
    private function validateDirect($file, $filter, callable $callback, array &$result)
248
    {
249
        if (is_dir($file)) {
250
            $finder = new Finder();
251
            $finder->files()->in($file)->name($filter);
252
            /**
253
             * @var SplFileInfo $finderfile
254
             */
255 View Code Duplication
            foreach ($finder as $finderfile) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
                $callback($finderfile);
257
                $result[strtr(
258
                    $finderfile->getRelativePath() . '/' . $finderfile->getFilename(),
259
                    ["\\" => "/"]
260
                )] = $this->validateFile($finderfile);
261
            }
262
        } else {
263
            if (preg_match($filter, $file)) {
264
                $finderfile = new SplFileInfo($file, "", "");
265
                $callback($finderfile);
266
                $result[strtr(
267
                    $finderfile->getRelativePath() . '/' . $finderfile->getFilename(),
268
                    ["\\" => "/"]
269
                )] = $this->validateFile($finderfile);
270
            }
271
        }
272
    }
273
}
274