diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..3199cf1
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,42 @@
+name: Test
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ test:
+ name: Test with PHP ${{ matrix.php-versions }}
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php-versions: [8.1, 8.2, 8.3] # TODO - Add 8.4 once all tools/dependencies support it
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php-versions }}
+
+ - name: Install dependencies
+ uses: ramsey/composer-install@v3
+
+ - name: Run PHP-CS-Fixer
+ run: composer phpcs:check
+
+ - name: Run PHPStan
+ run: composer phpstan
+
+ - name: Run PHPUnit
+ run: composer test
diff --git a/.gitignore b/.gitignore
index 2942141..77387d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,12 @@
.idea/
composer.lock
vendor/
+
+###> friendsofphp/php-cs-fixer ###
+/.php-cs-fixer.cache
+###< friendsofphp/php-cs-fixer ###
+
+###> phpunit/phpunit ###
+/phpunit.xml
+/.phpunit.cache
+###< phpunit/phpunit ###
diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php
new file mode 100644
index 0000000..70b81c3
--- /dev/null
+++ b/.php-cs-fixer.php
@@ -0,0 +1,35 @@
+in(__DIR__);
+
+return (new PhpCsFixer\Config())
+ ->setParallelConfig(ParallelConfigFactory::detect())
+ ->setRules([
+ '@PHP81Migration' => true,
+ '@Symfony' => true,
+ '@Symfony:risky' => true,
+ 'declare_strict_types' => true,
+ 'header_comment' => [
+ 'header' => 'Copyright (c) Fusonic GmbH. All rights reserved.'.\PHP_EOL.'Licensed under the MIT License. '.
+ 'See LICENSE file in the project root for license information.',
+ 'location' => 'after_open',
+ ],
+ 'no_useless_else' => true,
+ 'no_useless_return' => true,
+ 'php_unit_strict' => true,
+ 'single_line_throw' => false,
+ 'strict_comparison' => true,
+ 'strict_param' => true,
+ ])
+ ->setFinder($finder)
+ ->setRiskyAllowed(true);
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index 30a9fcf..0000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-build:
- environment:
- php:
- version: 7.4
- tests:
- override:
- -
- command: 'vendor/bin/phpunit --coverage-clover coverage-report'
- coverage:
- file: 'coverage-report'
- format: 'clover'
-
-tools:
- php_code_sniffer:
- enabled: true
- config:
- standard: PSR2
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6dcf4bd..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-language: php
-php:
- - 7.4
- - 8.0
-install: composer install
-script: vendor/bin/phpunit
diff --git a/CHANGELOG.md b/CHANGELOG-2.x.md
similarity index 100%
rename from CHANGELOG.md
rename to CHANGELOG-2.x.md
diff --git a/CHANGELOG-3.x.md b/CHANGELOG-3.x.md
new file mode 100644
index 0000000..dd7cff8
--- /dev/null
+++ b/CHANGELOG-3.x.md
@@ -0,0 +1,16 @@
+# CHANGELOG for 3.x
+
+## 3.0.0
+
+- Bumped the required PHP version from `^7.4 || ^8.0` to `^8.1`
+- Bumped the compatible Symfony version from `^3.0 || ^4.0 || ^5.0 || ^6.0` to `^5.4 || ^6.4 || ^7.1`
+- Upgraded PHPUnit from `^9.0` to `^11.4` and updated tests accordingly
+ - Added `composer test` script for running tests
+- Installed `friendsofphp/php-cs-fixer` and applied Fusonic's code style
+ - Added `composer phpcs:check` script for validating code style
+ - Added `composer phpcs:fix` script for fixing code style violations
+- Installed `phpstan/phpstan`, `phpstan/phpstan-deprecation-rules`, `phpstan/phpstan-phpunit` and
+ `phpstan/phpstan-strict-rules` and fixed reported errors
+ - Added `composer phpstan` script for validating code
+- Updated documentation
+- Switched to GitHub actions for automated testing
diff --git a/LICENSE b/LICENSE
index 46c173a..bb8f68c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014 Fusonic GmbH (http://www.fusonic.net)
+Copyright (c) 2014-2024 Fusonic GmbH (https://www.fusonic.net)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
index b256cac..11e8acf 100644
--- a/README.md
+++ b/README.md
@@ -1,59 +1,64 @@
# fusonic/opengraph
-[![Latest Stable Version](https://poser.pugx.org/fusonic/opengraph/v/stable)](https://packagist.org/packages/fusonic/opengraph)
-[![Total Downloads](https://poser.pugx.org/fusonic/opengraph/downloads)](https://packagist.org/packages/fusonic/opengraph)
-[![Build Status](https://api.travis-ci.org/fusonic/opengraph.svg)](https://travis-ci.org/fusonic/opengraph)
-[![License](https://poser.pugx.org/fusonic/opengraph/license)](https://packagist.org/packages/fusonic/opengraph)
+[![GitHub Release](https://img.shields.io/github/v/release/fusonic/opengraph)](https://github.com/fusonic/opengraph/releases/latest)
+[![Packagist Downloads](https://img.shields.io/packagist/dt/fusonic/opengraph?color=blue)](https://packagist.org/packages/fusonic/opengraph)
+[![Packagist License](https://img.shields.io/packagist/l/fusonic/opengraph)](https://github.com/fusonic/opengraph/blob/master/LICENSE)
+[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/fusonic/opengraph/test)](https://github.com/fusonic/opengraph/actions/workflows/test.yml)
-A simple library to read Open Graph data from the web and generate HTML code to publish your own Open Graph objects. A fallback mode enables you to read data from websites that do not implement the Open Graph protocol.
+A simple library to read Open Graph data from the web and generate HTML code to publish your own Open Graph objects. A
+fallback mode enables you to read data from websites that do not implement the Open Graph protocol.
-Using this library you can easily retrieve stuff like meta data, video information from YouTube or Vimeo or image information from Flickr without using site-specific APIs since they all implement the Open Graph protocol.
+Using this library you can easily retrieve stuff like metadata, video information from YouTube or Vimeo or image
+information from Flickr without using site-specific APIs since they all implement the Open Graph protocol.
-See [ogp.me](http://ogp.me) for information on the Open Graph protocol.
+See [ogp.me](https://ogp.me) for information on the Open Graph protocol.
## Requirements
-* PHP 7.4+
-* [fusonic/linq](https://github.com/fusonic/linq)
-* [symfony/css-selector](https://github.com/symfony/CssSelector)
-* [symfony/dom-crawler](https://github.com/symfony/DomCrawler)
-* [psr/http-client](https://github.com/php-fig/http-client), [psr/http-factory](https://github.com/php-fig/http-factory) and compatible implementation such as [guzzle/guzzle](https://github.com/guzzle/guzzle)
+* PHP 8.1+
+* [symfony/css-selector](https://github.com/symfony/css-selector)
+* [symfony/dom-crawler](https://github.com/symfony/dom-crawler)
+* [psr/http-client](https://github.com/php-fig/http-client)
+* [psr/http-factory](https://github.com/php-fig/http-factory)
+* and compatible implementation such as [symfony/http-client](https://github.com/symfony/http-client)
## Installation
The most flexible installation method is using Composer:
-``` bash
+```bash
composer require fusonic/opengraph
```
-Install composer and run install command:
-``` bash
+Install Composer and run the `install` command:
+```bash
curl -s http://getcomposer.org/installer | php
php composer.phar install
```
-Once installed, include vendor/autoload.php in your script.
+Once installed, include `vendor/autoload.php` in your script.
``` php
-require "vendor/autoload.php";
+require 'vendor/autoload.php';
```
## Usage
### Retrieve Open Graph data from a URL
-``` php
+```php
+loadUrl("http://www.youtube.com/watch?v=P422jZg50X4");
+$object = $consumer->loadUrl('https://www.youtube.com/watch?v=P422jZg50X4');
// Basic information of the object
echo "Title: " . $object->title; // Getting started with Facebook Open Graph
echo "Site name: " . $object->siteName; // YouTube
echo "Description: " . $object->description; // Originally recorded at the Facebook World ...
-echo "Canonical URL: " . $object->url; // http://www.youtube.com/watch?v=P422jZg50X4
+echo "Canonical URL: " . $object->url; // https://www.youtube.com/watch?v=P422jZg50X4
// Images
$image = $object->images[0];
@@ -63,7 +68,7 @@ echo "Image[0] width: " . $image->width; // null (May return width in pi
// Videos
$video = $object->videos[0];
-echo "Video URL: " . $video->url; // http://www.youtube.com/v/P422jZg50X4?version=3&autohide=1
+echo "Video URL: " . $video->url; // https://www.youtube.com/v/P422jZg50X4?version=3&autohide=1
echo "Video height: " . $video->height; // 1080
echo "Video width: " . $video->width; // 1920
echo "Video type: " . $video->type; // application/x-shockwave-flash
@@ -73,7 +78,9 @@ _There are some more properties but these are the basic and most commonly used o
### Publish own Open Graph data
-``` php
+```php
+title = "Getting started with Facebook Open Graph";
$object->siteName = "YouTube";
$object->description = "Originally recorded at the Facebook World ..."
-$object->url = "http://www.youtube.com/watch?v=P422jZg50X4";
+$object->url = "https://www.youtube.com/watch?v=P422jZg50X4";
// Images
$image = new Image("https://i1.ytimg.com/vi/P422jZg50X4/maxresdefault.jpg");
$object->images[] = $image;
// Videos
-$video = new Video("http://www.youtube.com/v/P422jZg50X4?version=3&autohide=1");
+$video = new Video("https://www.youtube.com/v/P422jZg50X4?version=3&autohide=1");
$video->height = 1080;
$video->width = 1920;
$video->type = "application/x-shockwave-flash";
@@ -125,18 +132,20 @@ _HTML code is formatted just for displaying purposes. You may choose between HTM
## Running tests
-You can run the test suite by running `phpunit` from the command line.
+You can run the test suite by running `composer test` from the command line.
## FAQ
**I don't get any information from a webpage, but Facebook shows information for the same URL. What do I do wrong?**
-It seems that some pages (like Twitter) only publish OpenGraph information if Facebook's user agent string `facebookexternalhit/1.1` is used (see #28). So you should configure your PSR-18 client to use this user agent string:
+It seems that some pages (like Twitter/X) only publish Open Graph information if Facebook's user agent string
+`facebookexternalhit/1.1` is used (see [#28](https://github.com/fusonic/opengraph/issues/28)). So you should configure
+your PSR-18 client to use this user agent string:
```php
-$client = new Psr18Client(new NativeHttpClient([ "headers" => [ "User-Agent" => "facebookexternalhit/1.1" ] ]));
+$client = new Psr18Client(new NativeHttpClient(['headers' => ['User-Agent' => 'facebookexternalhit/1.1']]));
```
## License
-This library is licensed under the MIT license.
+fusonic/opengraph is licensed under the MIT license. See [LICENSE](LICENSE) for more information.
diff --git a/UPGRADE-3.0.md b/UPGRADE-3.0.md
new file mode 100644
index 0000000..8bb9fef
--- /dev/null
+++ b/UPGRADE-3.0.md
@@ -0,0 +1,5 @@
+# UPGRADE FROM 2.2 TO 3.0
+
+## Requirements
+- Bumped the required PHP version from `^7.4 || ^8.0` to `^8.1`
+- Bumped the compatible Symfony version from `^3.0 || ^4.0 || ^5.0 || ^6.0` to `^5.4 || ^6.4 || ^7.1`
diff --git a/composer.json b/composer.json
index b74deba..b5e19e1 100644
--- a/composer.json
+++ b/composer.json
@@ -1,9 +1,11 @@
{
"name": "fusonic/opengraph",
"description": "PHP library for consuming and publishing Open Graph resources.",
- "keywords": ["opengraph"],
+ "keywords": [
+ "opengraph"
+ ],
"type": "library",
- "homepage": "https://github.com/fusonic/fusonic-opengraph",
+ "homepage": "https://github.com/fusonic/opengraph",
"license": "MIT",
"authors": [
{
@@ -22,20 +24,34 @@
}
},
"require": {
- "php": "^7.4|^8.0",
+ "php": "^8.1",
"ext-dom": "*",
- "symfony/dom-crawler": "^3.0|^4.0|^5.0|^6.0",
- "symfony/css-selector": "^3.0|^4.0|^5.0|^6.0",
+ "symfony/css-selector": "^5.4 || ^6.4 || ^7.1",
+ "symfony/dom-crawler": "^5.4 || ^6.4 || ^7.1",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0"
},
"require-dev": {
- "phpunit/phpunit": "^9.0",
- "symfony/http-client": "^6.0",
- "nyholm/psr7": "^1.2"
+ "friendsofphp/php-cs-fixer": "^3.65",
+ "nyholm/psr7": "^1.8",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-deprecation-rules": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-strict-rules": "^2.0",
+ "phpunit/phpunit": "^10.5 || ^11.4",
+ "symfony/http-client": "^5.4 || ^6.4 || ^7.1"
},
"suggest": {
- "symfony/http-client": "^5.0",
- "nyholm/psr7": "^1.2"
+ "symfony/http-client": "^5.4 || ^6.4 || ^7.1",
+ "nyholm/psr7": "^1.8"
+ },
+ "scripts": {
+ "phpcs:check": "XDEBUG_MODE=off vendor/bin/php-cs-fixer check -v --diff",
+ "phpcs:fix": "XDEBUG_MODE=off vendor/bin/php-cs-fixer fix -v",
+ "phpstan": "XDEBUG_MODE=off php -d memory_limit=2048M vendor/bin/phpstan analyse",
+ "test": "XDEBUG_MODE=off vendor/bin/phpunit --testdox"
+ },
+ "config": {
+ "sort-packages": true
}
}
diff --git a/examples/consume_website.php b/examples/consume_website.php
index 275cbfb..d46ce27 100644
--- a/examples/consume_website.php
+++ b/examples/consume_website.php
@@ -1,18 +1,25 @@
[ "User-Agent" => "facebookexternalhit/1.1" ] ]));
+// package, but you can use any implementation provided by your framework of choice.
+$client = new Psr18Client(new NativeHttpClient(['headers' => ['User-Agent' => 'facebookexternalhit/1.1']]));
// Create a new crawler
$crawler = new Fusonic\OpenGraph\Consumer($client, $client);
// Crawl the desired URL and retrieve a Fusonic\OpenGraph\Object in response
-$object = $crawler->loadUrl("https://github.com");
+$object = $crawler->loadUrl('https://github.com');
var_dump($object);
diff --git a/examples/publish_website.php b/examples/publish_website.php
index b419765..71d9653 100644
--- a/examples/publish_website.php
+++ b/examples/publish_website.php
@@ -1,43 +1,51 @@
url = "http://www.fusonic.net";
-$website->title = "Fusonic - Intranet & Mobile Applications from Austria";
-$website->description = "Creators of the awesome fusonic-opengraph library.";
-$website->siteName = "Fusonic";
-$website->locale = "en_GB";
+$website->url = 'https://www.fusonic.net';
+$website->title = 'Fusonic - Intranet & Mobile Applications from Austria';
+$website->description = 'Creators of the awesome fusonic-opengraph library.';
+$website->siteName = 'Fusonic';
+$website->locale = 'en_GB';
// Attach an image
-$image = new Image("http://www.fusonic.net/en/assets/images/logo.png");
+$image = new Image('https://www.fusonic.net/en/assets/images/logo.png');
$image->width = 140;
$image->height = 41;
-$image->type = "image/png";
+$image->type = 'image/png';
$website->images[] = $image;
// Attach a video
-$video = new Video("http://www.fusonic.net/en/we-dont-have-no-video.mp4");
+$video = new Video('https://www.fusonic.net/en/we-dont-have-no-video.mp4');
$video->width = 1920;
$video->height = 1080;
-$video->type = "video/mp4";
+$video->type = 'video/mp4';
$website->videos[] = $video;
// Attach an audio
-$audio = new Audio("http://www.fusonic.net/en/we-dont-have-no-audio.mp3");
-$audio->type = "audio/mp3";
+$audio = new Audio('https://www.fusonic.net/en/we-dont-have-no-audio.mp3');
+$audio->type = 'audio/mp3';
$website->audios[] = $audio;
// Create Publisher object and echo HTML code
$publisher = new Publisher();
$publisher->doctype = Publisher::DOCTYPE_HTML5;
+
echo $publisher->generateHtml($website);
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..558a859
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,11 @@
+parameters:
+ level: 8
+ paths:
+ - src
+ - tests
+
+includes:
+ - vendor/phpstan/phpstan-deprecation-rules/rules.neon
+ - vendor/phpstan/phpstan-phpunit/extension.neon
+ - vendor/phpstan/phpstan-phpunit/rules.neon
+ - vendor/phpstan/phpstan-strict-rules/rules.neon
diff --git a/phpunit.xml b/phpunit.xml
deleted file mode 100644
index 0d9aeef..0000000
--- a/phpunit.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-