Skip to content

Commit 54ae0ad

Browse files
committed
refactor: use new api
1 parent 9a2c66a commit 54ae0ad

7 files changed

Lines changed: 225 additions & 526 deletions

File tree

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
[![Continuous Integration](https://github.com/Gemorroj/HTMLValidator/workflows/Continuous%20Integration/badge.svg?branch=master)](https://github.com/Gemorroj/HTMLValidator/actions?query=workflow%3A%22Continuous+Integration%22)
44

55

6-
### Not working now
7-
todo: https://validator.w3.org/docs/api.html
6+
#### Rewritten to use the new API https://validator.w3.org/docs/api.html
87

98

109
### Requirements:

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"license": "LGPL-3.0",
66
"require": {
77
"php": ">=7.3",
8-
"ext-dom": "*"
8+
"ext-json": "*"
99
},
1010
"authors": [
1111
{

src/HTMLValidator.php

Lines changed: 70 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,21 @@ class HTMLValidator
99
*
1010
* @var string
1111
*/
12-
protected $validatorUri = 'http://validator.w3.org/check';
12+
private $validatorUri = 'http://validator.w3.org/nu/';
1313

1414
/**
1515
* @var Options
1616
*/
17-
protected $options;
17+
private $options;
18+
19+
/**
20+
* Default context for http request.
21+
*
22+
* @see https://www.php.net/manual/en/context.php
23+
*
24+
* @var array
25+
*/
26+
private $context = [];
1827

1928
public function __construct(Options $options = null)
2029
{
@@ -33,6 +42,18 @@ public function setOptions(Options $options): self
3342
return $this;
3443
}
3544

45+
public function getContext(): array
46+
{
47+
return $this->context;
48+
}
49+
50+
public function setContext(array $context): self
51+
{
52+
$this->context = $context;
53+
54+
return $this;
55+
}
56+
3657
public function getValidatorUri(): string
3758
{
3859
return $this->validatorUri;
@@ -46,15 +67,21 @@ public function setValidatorUri(string $validatorUri): self
4667
}
4768

4869
/**
49-
* @param resource $context
50-
*
5170
* @throws Exception
5271
*/
53-
protected function sendRequest(string $uri, $context = null): string
72+
protected function sendRequest(string $uri, array $context): string
5473
{
55-
$data = \file_get_contents($uri, null, $context);
74+
$context = \array_merge($this->getContext(), $context);
75+
76+
if (isset($context['http']['header'])) {
77+
$context['http']['header'] .= "\r\nUser-Agent: gemorroj/htmlvalidator";
78+
} else {
79+
$context['http']['header'] = 'User-Agent: gemorroj/htmlvalidator';
80+
}
81+
82+
$data = @\file_get_contents($uri, false, \stream_context_create($context));
5683
if (false === $data) {
57-
throw new Exception('Error send request');
84+
throw new Exception(\error_get_last()['message']);
5885
}
5986

6087
return $data;
@@ -68,27 +95,25 @@ protected function sendRequest(string $uri, $context = null): string
6895
*
6996
* @param string $uri The address to the page to validate ex: http://example.com/
7097
*
71-
* @throws Exception
72-
*
73-
* @return Response object HTMLValidator\Response
98+
* @throws Exception|\JsonException
7499
*/
75100
public function validateUri(string $uri): Response
76101
{
77102
$query = \http_build_query(\array_merge(
78103
$this->getOptions()->buildOptions(),
79-
['uri' => $uri]
104+
['doc' => $uri, 'out' => 'json']
80105
));
81106

82-
$context = \stream_context_create([
107+
$context = [
83108
'http' => [
84109
'method' => 'GET',
85-
'header' => 'User-Agent: HTMLValidator',
110+
'header' => 'Content-Type: text/html; charset=utf-8',
86111
],
87-
]);
112+
];
88113

89114
$data = $this->sendRequest($this->validatorUri.'?'.$query, $context);
90115

91-
return $this->parseSOAP12Response($data);
116+
return $this->parseJsonResponse($data);
92117
}
93118

94119
/**
@@ -98,7 +123,7 @@ public function validateUri(string $uri): Response
98123
*
99124
* @param string $file file to be validated
100125
*
101-
* @throws Exception
126+
* @throws Exception|\JsonException
102127
*
103128
* @return Response object HTMLValidator\Response
104129
*/
@@ -111,9 +136,9 @@ public function validateFile(string $file): Response
111136
throw new Exception('File not readable');
112137
}
113138

114-
$data = \file_get_contents($file);
139+
$data = @\file_get_contents($file);
115140
if (false === $data) {
116-
throw new Exception('Failed get file');
141+
throw new Exception(\error_get_last()['message']);
117142
}
118143

119144
return $this->validateFragment($data);
@@ -124,76 +149,62 @@ public function validateFile(string $file): Response
124149
*
125150
* @param string $html full html document fragment
126151
*
127-
* @throws Exception
152+
* @throws Exception|\JsonException
128153
*
129154
* @return Response object HTMLValidator\Response
130155
*/
131156
public function validateFragment(string $html): Response
132157
{
133158
$query = \http_build_query(\array_merge(
134159
$this->getOptions()->buildOptions(),
135-
['fragment' => $html]
160+
['out' => 'json']
136161
));
137162

138-
$context = \stream_context_create([
163+
$context = [
139164
'http' => [
140165
'method' => 'POST',
141-
'header' => "Content-Type: application/x-www-form-urlencoded\r\nUser-Agent: HTMLValidator",
142-
'content' => $query,
166+
'header' => 'Content-Type: text/html; charset=utf-8',
167+
'content' => $html,
143168
],
144-
]);
169+
];
145170

146-
$data = $this->sendRequest($this->validatorUri, $context);
171+
$data = $this->sendRequest($this->validatorUri.'?'.$query, $context);
147172

148-
return $this->parseSOAP12Response($data);
173+
return $this->parseJsonResponse($data);
149174
}
150175

151176
/**
152-
* Parse an XML response from the validator.
177+
* Parse an JSON response from the validator.
153178
*
154-
* This function parses a SOAP 1.2 response xml string from the validator.
179+
* This function parses a JSON response json string from the validator.
155180
*
156-
* @param string $xml the raw soap12 XML response from the validator
157-
*
158-
* @throws Exception
181+
* @param string $json the raw JSON response from the validator
159182
*
160-
* @return Response object HTMLValidator\Response
183+
* @throws Exception|\JsonException
161184
*/
162-
protected function parseSOAP12Response(string $xml): Response
185+
protected function parseJsonResponse(string $json): Response
163186
{
164-
$doc = new \DOMDocument('1.0', 'UTF-8');
165-
166-
if (false === $doc->loadXML($xml)) {
167-
throw new Exception('Failed load xml');
168-
}
187+
$data = \json_decode($json, true, 512, \JSON_THROW_ON_ERROR);
169188

170189
$response = new Response();
171190

172-
// Get the standard CDATA elements
173-
foreach (['uri', 'checkedby', 'doctype', 'charset'] as $var) {
174-
$element = $doc->getElementsByTagName($var);
175-
if ($element->length) {
176-
$response->{'set'.\ucfirst($var)}($element->item(0)->nodeValue);
177-
}
178-
}
191+
$response->setEncoding($data['source']['encoding'] ?? null);
192+
$response->setType($data['source']['type'] ?? null);
193+
$response->setUri($data['url'] ?? null);
179194

180-
// Handle the bool element validity
181-
$element = $doc->getElementsByTagName('validity');
182-
if ($element->length && 'true' === $element->item(0)->nodeValue) {
183-
$response->setValidity(true);
184-
} else {
185-
$response->setValidity(false);
195+
if (isset($data['messages'][0]['type']) && 'non-document-error' === $data['messages'][0]['type']) {
196+
throw new Exception($data['messages'][0]['message']);
186197
}
187198

188-
if (!$response->isValidity()) {
189-
$errors = $doc->getElementsByTagName('error');
190-
foreach ($errors as $error) {
191-
$response->addError(new Error($error));
199+
$response->setValid(true);
200+
foreach ($data['messages'] as $message) {
201+
if ('error' === $message['type']) {
202+
$response->setValid(false);
203+
$response->addError(new Error($message));
204+
}
205+
if ('info' === $message['type']) { // warning
206+
$response->addWarning(new Warning($message));
192207
}
193-
}
194-
$warnings = $doc->getElementsByTagName('warning');
195-
foreach ($warnings as $warning) {
196-
$response->addWarning(new Warning($warning));
197208
}
198209

199210
return $response;

0 commit comments

Comments
 (0)