Commit d00ba4c6 authored by Melroy van den Berg's avatar Melroy van den Berg
Browse files

Add CI/CD

parent aff262e8
Pipeline #2337 failed with stage
in 4 minutes and 33 seconds
composer.phar
vendor/
.php_cs.cache
report/
image: jakzal/phpqa:php7.4-alpine
# Cache between jobs
cache:
paths:
- vendor/
before_script:
- composer install
stages:
- QA
static-code-analysis:
stage: QA
script:
# Use Psalm static analysis tool, see also psalm.xml file
- psalm --no-cache
coding-style:
stage: QA
script:
# Run phpcs (phpcbf can be used to auto-fix the errors/warnings), -n is only showing errors, see also phpcs.xml file.
# Note: phpcs also checks JavaScript & CSS code.
- phpcs -n --standard=phpcs.xml .
phpmetrics:
stage: QA
allow_failure: true
script:
- phpmetrics --config=phpmetrics.json
artifacts:
paths:
- report/
Metacritic API
==============
# Metacritic API
Using this Metacritic API, you are able to search games on [metacritic.com](http://www.metacritic.com).
It will give you back the metacritic score, users score, genres, rating, developers and much more (see below for an example).
......@@ -8,9 +8,8 @@ The output is in [JSON format](http://us.php.net/manual/en/function.json-decode.
By default it uses the URL prefix: "http://www.metacritic.com/game/pc/". If you want to search for Playstation 3 games, just change it to:
"http://www.metacritic.com/game/playstation-3". See [metacritic.php](metacritic.php) file.
## Example
Example
-------
Searching on the PC game called "The Elder Scrolls V: Skyrim",
will give the following JSON output:
......@@ -44,8 +43,8 @@ will give the following JSON output:
}
```
On error
--------
## On error
When for some reason the page couldn't be loaded / found or parsed, you will get the following JSON response:
```json
......@@ -54,8 +53,8 @@ When for some reason the page couldn't be loaded / found or parsed, you will get
Or when metacritic.php is directly called, without input you will get: `{"error": "Game title is empty"}`
Code example
------------
## Code example
Please, see [example.php](example.php)
Another way to access the API is to directly call [metacritic.php](metacritic.php) via the website URL:
......@@ -67,3 +66,13 @@ Be-aware that the game title needs to be [URL encoded](https://www.w3schools.com
Have fun!
## CI/CD
Code quality is checked in GitLab CI/CD, to avoid regression.
Currently in the pipeline:
* [Psalm](https://psalm.dev/) - Static analysis tool for PHP
* [Phpcs](https://github.com/squizlabs/PHP_CodeSniffer) - PHP coding style standard (`phpcbf` command for auto-fix)
* [Phpmetrics](https://phpmetrics.github.io/PhpMetrics/) - PHP metrics for complexity, object oriented, maintainability and more.
* [Latest Metrics Report](https://gitlab.melroy.org/melroy/metacritic_api/-/jobs/artifacts/master/file/report/index.html?job=phpmetrics)
{
"require-dev": {
"vimeo/psalm": "^4.0",
"phpmetrics/phpmetrics": "^2.7"
}
}
This diff is collapsed.
<?php
# Ignore Unirest warning if any (eg. safe mode related)
#error_reporting(E_ERROR | E_PARSE);
include 'metacritic.php';
......@@ -7,5 +8,4 @@ $metacritic_api = new MetacriticAPI();
$metacritic_api->get_metacritic_page("The Elder Scrolls V: Skyrim");
$json_reponse = $metacritic_api->get_metacritic_scores();
echo "Json Output:\n<br/><br/> ". $json_reponse;
?>
echo "Json Output:\n<br/><br/> " . $json_reponse;
<?php
require_once 'libs/Unirest.php';
require_once 'libs/simple_html_dom.php';
class MetacriticAPI
{
private $response_body = "";
private $baseUrl = "http://www.metacritic.com/game/";
private $arrSystems = array();
private $response_body = "";
private $baseUrl = "http://www.metacritic.com/game/";
private $arrSystems = array();
function __construct($system = "pc") {
$this->arrSystems[] = $system;
}
function __construct($system = "pc")
{
$this->arrSystems[] = $system;
}
public function get_metacritic_page($game_name)
{
......@@ -20,31 +22,31 @@ class MetacriticAPI
# Remove &<space>
$game_name = str_replace('& ', '', $game_name);
# lowercase
$game_name = strtolower($game_name);
$game_name = strtolower($game_name);
# Remove all special chars execept a-z, digits, --sign, ?-sign, !-sign
$game_name = preg_replace('/[^a-z\d\?!\-]/', '', $game_name);
# Get the webpage
$i = 0;
do {
$system = $this->arrSystems[$i++];
$url = $this->baseUrl . $system . "/" . $game_name;
$response = Unirest\Request::get($url, $headers = array(), $parameters = null);
} while ($response->code <> 200 and $i<count($this->arrSystems));
# Get the webpage
$i = 0;
do {
$system = $this->arrSystems[$i++];
$url = $this->baseUrl . $system . "/" . $game_name;
$response = Unirest\Request::get($url, $headers = array(), $parameters = null);
} while ($response->code <> 200 and $i < count($this->arrSystems));
if($response->code == 200) {
$returnValue = $response->raw_body;
if ($response->code == 200) {
$returnValue = $response->raw_body;
}
$this->response_body = $returnValue;
$this->response_body = $returnValue;
}
public function get_metacritic_scores()
{
# Get DOM by string content
$html = str_get_html($this->response_body);
# Define json output array
$json_output = array();
$error = false;
$error = false;
# init all vars
$name = "";
$metascritic_score = 0;
......@@ -57,101 +59,87 @@ class MetacriticAPI
$image_url = "";
$cheat_url = "";
if(!$html)
{
$json_output['error'] = "Page could not be loaded!";
$error = true;
}
if(!$error)
{
foreach($html->find('div[class=product_title] span[itemprop=name]') as $element)
{
$name = trim($element->plaintext);
}
foreach($html->find('span[itemprop=ratingValue]') as $element)
{
$metascritic_score = intval($element->plaintext);
}
foreach($html->find("div[class=userscore_wrap] a[class=metascore_anchor] div[class=metascore_w]") as $element)
{
$user_score = floatval($element->plaintext);
}
foreach($html->find('span[itemprop=contentRating]') as $element)
{
$rating = trim($element->plaintext);
}
$genres = array();
foreach($html->find('span[itemprop=genre]') as $element)
{
array_push($genres, trim($element->plaintext));
}
foreach($html->find('li[class=summary_detail developer] span[class=data]') as $element)
{
$developer = trim($element->plaintext);
}
$developers = explode(", ", $developer);
foreach($html->find('li[class=summary_detail publisher] span[itemprop=name]') as $element)
{
$publisher = trim($element->plaintext);
}
foreach($html->find('span[itemprop=datePublished]') as $element)
{
$release_date = trim($element->plaintext);
}
$also_on = array();
$also_on_url = array();
foreach($html->find('li[class=summary_detail product_platforms] span[class=data] a') as $element)
{
array_push($also_on, trim($element->plaintext));
array_push($also_on_url, $element->href);
}
foreach($html->find('img[class=product_image]') as $element)
{
$image_url = $element->src;
}
foreach($html->find('li[class=summary_detail product_cheats] span[class=data] a') as $element)
{
$cheat_url = $element->href;
}
# Prevent memory leak
$html->clear();
unset($html);
# Fill-in the array
$json_output['name'] = $name;
$json_output['metascritic_score'] = $metascritic_score;
$json_output['users_score'] = $user_score;
$json_output['rating'] = $rating;
$json_output['genres'] = $genres;
$json_output['developers'] = $developers;
$json_output['publishers'] = $publisher;
$json_output['release_date'] = $release_date;
$json_output['also_on'] = $also_on;
if (!$html) {
$json_output['error'] = "Page could not be loaded!";
$error = true;
}
if (!$error) {
foreach ($html->find('div[class=product_title] span[itemprop=name]') as $element) {
$name = trim($element->plaintext);
}
foreach ($html->find('span[itemprop=ratingValue]') as $element) {
$metascritic_score = intval($element->plaintext);
}
foreach ($html->find("div[class=userscore_wrap] a[class=metascore_anchor] div[class=metascore_w]") as $element) {
$user_score = floatval($element->plaintext);
}
foreach ($html->find('span[itemprop=contentRating]') as $element) {
$rating = trim($element->plaintext);
}
$genres = array();
foreach ($html->find('span[itemprop=genre]') as $element) {
array_push($genres, trim($element->plaintext));
}
foreach ($html->find('li[class=summary_detail developer] span[class=data]') as $element) {
$developer = trim($element->plaintext);
}
$developers = explode(", ", $developer);
foreach ($html->find('li[class=summary_detail publisher] span[itemprop=name]') as $element) {
$publisher = trim($element->plaintext);
}
foreach ($html->find('span[itemprop=datePublished]') as $element) {
$release_date = trim($element->plaintext);
}
$also_on = array();
$also_on_url = array();
foreach ($html->find('li[class=summary_detail product_platforms] span[class=data] a') as $element) {
array_push($also_on, trim($element->plaintext));
array_push($also_on_url, $element->href);
}
foreach ($html->find('img[class=product_image]') as $element) {
$image_url = $element->src;
}
foreach ($html->find('li[class=summary_detail product_cheats] span[class=data] a') as $element) {
$cheat_url = $element->href;
}
# Prevent memory leak
$html->clear();
unset($html);
# Fill-in the array
$json_output['name'] = $name;
$json_output['metascritic_score'] = $metascritic_score;
$json_output['users_score'] = $user_score;
$json_output['rating'] = $rating;
$json_output['genres'] = $genres;
$json_output['developers'] = $developers;
$json_output['publishers'] = $publisher;
$json_output['release_date'] = $release_date;
$json_output['also_on'] = $also_on;
$json_output['also_on_url'] = $also_on_url;
$json_output['thumbnail_url'] = $image_url;
$json_output['cheat_url'] = $cheat_url;
}
$json_output['thumbnail_url'] = $image_url;
$json_output['cheat_url'] = $cheat_url;
}
# Return JSON format
return json_encode($json_output);
}
}
if($_SERVER['SCRIPT_FILENAME'] == __FILE__)
{
if(isset($_GET['game_title'])) {
if ($_SERVER['SCRIPT_FILENAME'] == __FILE__) {
if (isset($_GET['game_title'])) {
$metacritic_api = new MetacriticAPI();
$metacritic_api->get_metacritic_page($_GET['game_title']);
echo $metacritic_api->get_metacritic_scores();
......@@ -159,4 +147,3 @@ if($_SERVER['SCRIPT_FILENAME'] == __FILE__)
echo json_encode(array("error" => "Game title is empty"));
}
}
?>
\ No newline at end of file
<?xml version="1.0"?>
<ruleset name="MyStandard">
<rule ref="PSR12">
<exclude name="Generic.Files.LineLength" />
</rule>
<exclude-pattern>*/libs/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
</ruleset>
{
"includes": [
"."
],
"exclude": [
"libs",
"vendor"
],
"report": {
"html": "report/"
},
"plugins": {
"git": {
"binary": "git"
}
}
}
<?xml version="1.0"?>
<psalm
errorLevel="4"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<file name="metacritic.php" />
<ignoreFiles>
<directory name="libs" />
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment