Skip to content

Commit 0e5d3ae

Browse files
committed
feat: improve type safety with PHPStan (590→0 errors)
Comprehensively resolve all 590 PHPStan errors to improve type safety and code quality across the entire codebase while maintaining PHP 7.4+ compatibility. PHPStan: 0 errors (level max + strict rules) Key improvements: - Replace elvis operator (?:) with explicit null checks - Replace empty() with explicit type-safe comparisons - Add PHPDoc type annotations for better static analysis - Replace == with === for strict comparisons - Add null-safety checks for DOM/XPath operations - Improve type inference for magic properties and dynamic methods - Add PHP 7.4/8.x compatible type handling (resource vs CurlHandle) Modified components: - Core: Embed, Extractor, Document, EmbedCode, etc. (13 files) - HTTP layer: Crawler, CurlClient, CurlDispatcher (5 files) - Detectors: All core detectors (17 files) - Adapters: Archive, Gist, ImageShack, Twitter, Wikipedia, etc. (60 files) - Data sources: OEmbed, LinkedData, Metas, QueryResult (4 files)
1 parent 248f26f commit 0e5d3ae

File tree

97 files changed

+1233
-416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+1233
-416
lines changed

.github/workflows/test.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,29 @@ jobs:
4242

4343
- name: Tests
4444
run: composer test
45+
46+
phpstan:
47+
name: PHPStan Static Analysis
48+
runs-on: ubuntu-latest
49+
50+
steps:
51+
- name: Checkout
52+
uses: actions/checkout@v4
53+
54+
- name: Install PHP
55+
uses: shivammathur/setup-php@v2
56+
with:
57+
php-version: 8.4
58+
59+
- name: Cache PHP dependencies
60+
uses: actions/cache@v4
61+
with:
62+
path: vendor
63+
key: ${{ runner.os }}-php-8.4-composer-${{ hashFiles('**/composer.json') }}
64+
restore-keys: ${{ runner.os }}-php-8.4-composer-
65+
66+
- name: Install dependencies
67+
run: composer install
68+
69+
- name: Run PHPStan
70+
run: composer phpstan

phpstan.dist.neon

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ parameters:
66
paths:
77
- src
88
# - tests
9-
- issue-report/tests
9+
excludePaths:
10+
- tests/cache
11+
- tests/fixtures
1012
checkMissingCallableSignature: true
1113
checkUninitializedProperties: true
1214
checkTooWideReturnTypesInProtectedAndPublicMethods: true
13-
checkImplicitMixed: true
15+
checkImplicitMixed: true

src/Adapters/Archive/Api.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ class Api
99
{
1010
use HttpApiTrait;
1111

12+
/**
13+
* @return array<string, mixed>
14+
*/
1215
protected function fetchData(): array
1316
{
1417
$this->endpoint = $this->extractor->getUri()->withQuery('output=json');

src/Adapters/Archive/Detectors/AuthorName.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33

44
namespace Embed\Adapters\Archive\Detectors;
55

6+
use Embed\Adapters\Archive\Extractor;
67
use Embed\Detectors\AuthorName as Detector;
78

89
class AuthorName extends Detector
910
{
1011
public function detect(): ?string
1112
{
12-
$api = $this->extractor->getApi();
13+
/** @var Extractor $extractor */
14+
$extractor = $this->extractor;
15+
$api = $extractor->getApi();
1316

14-
return $api->str('metadata', 'creator')
15-
?: parent::detect();
17+
$result = $api->str('metadata', 'creator');
18+
return $result !== null ? $result : parent::detect();
1619
}
1720
}

src/Adapters/Archive/Detectors/Description.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33

44
namespace Embed\Adapters\Archive\Detectors;
55

6+
use Embed\Adapters\Archive\Extractor;
67
use Embed\Detectors\Description as Detector;
78

89
class Description extends Detector
910
{
1011
public function detect(): ?string
1112
{
12-
$api = $this->extractor->getApi();
13+
/** @var Extractor $extractor */
14+
$extractor = $this->extractor;
15+
$api = $extractor->getApi();
1316

14-
return $api->str('metadata', 'extract')
15-
?: parent::detect();
17+
$result = $api->str('metadata', 'extract');
18+
return $result !== null ? $result : parent::detect();
1619
}
1720
}

src/Adapters/Archive/Detectors/PublishedTime.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,25 @@
44
namespace Embed\Adapters\Archive\Detectors;
55

66
use DateTime;
7+
use Embed\Adapters\Archive\Extractor;
78
use Embed\Detectors\PublishedTime as Detector;
89

910
class PublishedTime extends Detector
1011
{
1112
public function detect(): ?DateTime
1213
{
13-
$api = $this->extractor->getApi();
14+
/** @var Extractor $extractor */
15+
$extractor = $this->extractor;
16+
$api = $extractor->getApi();
1417

15-
return $api->time('metadata', 'publicdate')
16-
?: $api->time('metadata', 'addeddate')
17-
?: $api->time('metadata', 'date')
18-
?: parent::detect();
18+
$fields = ['publicdate', 'addeddate', 'date'];
19+
foreach ($fields as $field) {
20+
$result = $api->time('metadata', $field);
21+
if ($result !== null) {
22+
return $result;
23+
}
24+
}
25+
26+
return parent::detect();
1927
}
2028
}

src/Adapters/Archive/Detectors/Title.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33

44
namespace Embed\Adapters\Archive\Detectors;
55

6+
use Embed\Adapters\Archive\Extractor;
67
use Embed\Detectors\Title as Detector;
78

89
class Title extends Detector
910
{
1011
public function detect(): ?string
1112
{
12-
$api = $this->extractor->getApi();
13+
/** @var Extractor $extractor */
14+
$extractor = $this->extractor;
15+
$api = $extractor->getApi();
1316

14-
return $api->str('metadata', 'title')
15-
?: parent::detect();
17+
$result = $api->str('metadata', 'title');
18+
return $result !== null ? $result : parent::detect();
1619
}
1720
}

src/Adapters/Archive/Extractor.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@
77

88
class Extractor extends Base
99
{
10-
private Api $api;
10+
private ?Api $api = null;
1111

1212
public function getApi(): Api
1313
{
14+
if ($this->api === null) {
15+
$this->api = new Api($this);
16+
}
1417
return $this->api;
1518
}
1619

20+
/**
21+
* @return array<string, \Embed\Detectors\Detector>
22+
*/
1723
public function createCustomDetectors(): array
1824
{
19-
$this->api = new Api($this);
20-
2125
return [
2226
'title' => new Detectors\Title($this),
2327
'description' => new Detectors\Description($this),

src/Adapters/Bandcamp/Extractor.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
class Extractor extends Base
99
{
10+
/**
11+
* @return array<string, \Embed\Detectors\Detector>
12+
*/
1013
public function createCustomDetectors(): array
1114
{
1215
return [

src/Adapters/CadenaSer/Detectors/Code.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ class Code extends Detector
1313
{
1414
public function detect(): ?EmbedCode
1515
{
16-
return parent::detect()
17-
?: $this->fallback();
16+
$result = parent::detect();
17+
return $result !== null ? $result : $this->fallback();
1818
}
1919

2020
private function fallback(): ?EmbedCode

0 commit comments

Comments
 (0)