Skip to content

Commit 5baae1d

Browse files
committed
[~]: use interfaces as return types
-> fix issue #30
1 parent f11616b commit 5baae1d

16 files changed

+1229
-484
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ before_script:
2727
- php -r "var_dump(LIBXML_DOTTED_VERSION);"
2828
- wget https://scrutinizer-ci.com/ocular.phar
2929
- travis_retry composer self-update
30-
- travis_retry composer require satooshi/php-coveralls:1.0.0
30+
- travis_retry composer require satooshi/php-coveralls
31+
- travis_retry composer require phpstan/phpstan-shim
3132
- travis_retry composer install --no-interaction --prefer-source
3233
- composer dump-autoload -o
3334

3435
script:
3536
- mkdir -p build/logs
3637
- php vendor/bin/phpunit -c phpunit.xml
38+
- php vendor/bin/phpstan analyse --level=7 --configuration=phpstan.neon src
3739

3840
after_script:
3941
- php vendor/bin/coveralls -v

CHANGELOG

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
[PHP Simple HTML Dom v4.5.x]
2+
1: fix -> return types
3+
2: add abstract class and interface for "Dom Elements" (SimpleHtmlDom*)
4+
3: and abstract class and interface for "Dom Nodes" (SimpleHtmlDomNode*)
5+
4: fix -> errors reported by phpstan (level 7)
6+
7+
18
[PHP Simple HTML Dom v4.4.x]
29
1: add "findMulti()" method for "SimpleDomParser"
310
2: fix -> phpdoc improvements via phpstan

phpcs.php_cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ return PhpCsFixer\Config::create()
5858
'version',
5959
],
6060
],
61-
'heredoc_to_nowdoc' => false,
62-
'implode_call' => false,
61+
'heredoc_to_nowdoc' => true,
62+
'implode_call' => true,
6363
'include' => true,
64-
'increment_style' => false, // maybe better for readability, so keep it ...
64+
'increment_style' => true,
6565
'indentation_type' => true,
6666
'line_ending' => true,
6767
'linebreak_after_opening_tag' => false,
@@ -185,7 +185,7 @@ return PhpCsFixer\Config::create()
185185
'php_unit_test_case_static_method_calls' => true,
186186
'php_unit_test_class_requires_covers' => false,
187187
'pow_to_exponentiation' => true,
188-
'pre_increment' => false,
188+
'pre_increment' => true,
189189
'protected_to_private' => true,
190190
'return_assignment' => true,
191191
'return_type_declaration' => true,
@@ -206,7 +206,7 @@ return PhpCsFixer\Config::create()
206206
'space_after_semicolon' => true,
207207
'standardize_increment' => false, // maybe better for readability, so keep it ...
208208
'standardize_not_equals' => true,
209-
'static_lambda' => false,
209+
'static_lambda' => true,
210210
'strict_comparison' => true,
211211
'strict_param' => true,
212212
'string_line_ending' => true,

phpstan.neon

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ parameters:
88
ignoreErrors:
99
- '#on an unknown class voku\\helper\\UTF8#'
1010
- '#function of function call_user_func_array expects callable#'
11-
- '#iterable<voku\\helper\\SimpleHtmlDom>#'
11+
- '#Method voku\\helper\\HtmlDomParser::findOne\(\) should return#'
12+
- '#Method voku\\helper\\HtmlDomParser::findMulti\(\) should return#'
13+
- '#Method voku\\helper\\SimpleHtmlDom::findOne\(\) should return#'
14+
- '#Method voku\\helper\\SimpleHtmlDom::findMulti\(\) should return#'
15+
- '#Method voku\\helper\\SimpleHtmlDomNode::findOne\(\) should return#'
16+
- '#Method voku\\helper\\SimpleHtmlDomNode::findMulti\(\) should return#'
17+
- '#@return with type array<voku\\helper\\SimpleHtmlDomInterface>\|voku\\helper\\SimpleHtmlDomNodeInterface#'
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace voku\helper;
6+
7+
abstract class AbstractSimpleHtmlDom
8+
{
9+
/**
10+
* @var \DOMElement|\DOMNode|null
11+
*/
12+
protected $node;
13+
14+
/**
15+
* @var array
16+
*/
17+
protected static $functionAliases = [
18+
'children' => 'childNodes',
19+
'first_child' => 'firstChild',
20+
'last_child' => 'lastChild',
21+
'next_sibling' => 'nextSibling',
22+
'prev_sibling' => 'previousSibling',
23+
'parent' => 'parentNode',
24+
'outertext' => 'html',
25+
'outerhtml' => 'html',
26+
'innertext' => 'innerHtml',
27+
'innerhtml' => 'innerHtml',
28+
];
29+
30+
/**
31+
* @param string $name
32+
* @param array $arguments
33+
*
34+
* @throws \BadMethodCallException
35+
*
36+
* @return SimpleHtmlDomInterface|string|null
37+
*/
38+
public function __call($name, $arguments)
39+
{
40+
$name = \strtolower($name);
41+
42+
if (isset(self::$functionAliases[$name])) {
43+
return \call_user_func_array([$this, self::$functionAliases[$name]], $arguments);
44+
}
45+
46+
throw new \BadMethodCallException('Method does not exist');
47+
}
48+
49+
/**
50+
* @param string $name
51+
*
52+
* @return array|string|null
53+
*/
54+
public function __get($name)
55+
{
56+
$nameOrig = $name;
57+
$name = \strtolower($name);
58+
59+
switch ($name) {
60+
case 'outerhtml':
61+
case 'outertext':
62+
case 'html':
63+
return $this->html();
64+
case 'innerhtml':
65+
case 'innertext':
66+
return $this->innerHtml();
67+
case 'text':
68+
case 'plaintext':
69+
return $this->text();
70+
case 'tag':
71+
return $this->node ? $this->node->nodeName : '';
72+
case 'attr':
73+
return $this->getAllAttributes();
74+
default:
75+
if ($this->node && \property_exists($this->node, $nameOrig)) {
76+
return $this->node->{$nameOrig};
77+
}
78+
79+
return $this->getAttribute($name);
80+
}
81+
}
82+
83+
/**
84+
* @param string $selector
85+
* @param int $idx
86+
*
87+
* @return SimpleHtmlDomInterface|SimpleHtmlDomInterface[]|SimpleHtmlDomNodeInterface
88+
*/
89+
public function __invoke($selector, $idx = null)
90+
{
91+
return $this->find($selector, $idx);
92+
}
93+
94+
/**
95+
* @param string $name
96+
*
97+
* @return bool
98+
*/
99+
public function __isset($name)
100+
{
101+
$nameOrig = $name;
102+
$name = \strtolower($name);
103+
104+
switch ($name) {
105+
case 'outertext':
106+
case 'outerhtml':
107+
case 'innertext':
108+
case 'innerhtml':
109+
case 'plaintext':
110+
case 'text':
111+
case 'tag':
112+
return true;
113+
default:
114+
if ($this->node && \property_exists($this->node, $nameOrig)) {
115+
return isset($this->node->{$nameOrig});
116+
}
117+
118+
return $this->hasAttribute($name);
119+
}
120+
}
121+
122+
/**
123+
* @param string $name
124+
* @param mixed $value
125+
*
126+
* @return SimpleHtmlDomInterface|null
127+
*/
128+
public function __set($name, $value)
129+
{
130+
$nameOrig = $name;
131+
$name = \strtolower($name);
132+
133+
switch ($name) {
134+
case 'outerhtml':
135+
case 'outertext':
136+
return $this->replaceNodeWithString($value);
137+
case 'innertext':
138+
case 'innerhtml':
139+
return $this->replaceChildWithString($value);
140+
case 'plaintext':
141+
return $this->replaceTextWithString($value);
142+
default:
143+
if ($this->node && \property_exists($this->node, $nameOrig)) {
144+
return $this->node->{$nameOrig} = $value;
145+
}
146+
147+
return $this->setAttribute($name, $value);
148+
}
149+
}
150+
151+
/**
152+
* @return string
153+
*/
154+
public function __toString()
155+
{
156+
return $this->html();
157+
}
158+
159+
/**
160+
* @param string $name
161+
*
162+
* @return void
163+
*/
164+
public function __unset($name)
165+
{
166+
/** @noinspection UnusedFunctionResultInspection */
167+
$this->removeAttribute($name);
168+
}
169+
170+
abstract public function setAttribute(string $name, $value = null, bool $strict = false): SimpleHtmlDomInterface;
171+
172+
abstract protected function replaceNodeWithString(string $string): SimpleHtmlDomInterface;
173+
174+
abstract protected function replaceChildWithString(string $string): SimpleHtmlDomInterface;
175+
176+
abstract protected function replaceTextWithString($string): SimpleHtmlDomInterface;
177+
178+
abstract public function hasAttribute(string $name): bool;
179+
180+
abstract public function find(string $selector, $idx = null);
181+
182+
abstract public function getAttribute(string $name): string;
183+
184+
abstract public function getAllAttributes();
185+
186+
abstract public function text(): string;
187+
188+
abstract public function innerHtml(bool $multiDecodeNewHtmlEntity = false): string;
189+
190+
abstract public function html(bool $multiDecodeNewHtmlEntity = false): string;
191+
192+
abstract public function removeAttribute(string $name): SimpleHtmlDomInterface;
193+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace voku\helper;
6+
7+
abstract class AbstractSimpleHtmlDomNode extends \ArrayObject
8+
{
9+
/** @noinspection MagicMethodsValidityInspection */
10+
11+
/**
12+
* @param string $name
13+
*
14+
* @return array|null
15+
*/
16+
public function __get($name)
17+
{
18+
// init
19+
$name = \strtolower($name);
20+
21+
if ($this->count() > 0) {
22+
$return = [];
23+
24+
foreach ($this as $node) {
25+
if ($node instanceof SimpleHtmlDomInterface) {
26+
$return[] = $node->{$name};
27+
}
28+
}
29+
30+
return $return;
31+
}
32+
33+
if ($name === 'plaintext' || $name === 'outertext') {
34+
return [];
35+
}
36+
37+
return null;
38+
}
39+
40+
/**
41+
* @param string $selector
42+
* @param int|null $idx
43+
*
44+
* @return SimpleHtmlDomNodeInterface|SimpleHtmlDomNodeInterface[]|null
45+
*/
46+
public function __invoke($selector, $idx = null)
47+
{
48+
return $this->find($selector, $idx);
49+
}
50+
51+
/**
52+
* @return string
53+
*/
54+
public function __toString()
55+
{
56+
// init
57+
$html = '';
58+
59+
foreach ($this as $node) {
60+
$html .= $node->outertext;
61+
}
62+
63+
return $html;
64+
}
65+
66+
abstract public function find(string $selector, $idx = null);
67+
}

0 commit comments

Comments
 (0)