✨feature: Initial info gathering
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
Notes/
|
||||
.vscode/
|
||||
phpcs-results.txt
|
||||
data/*.sqlite
|
||||
|
||||
222
agent-info.php
Normal file
222
agent-info.php
Normal file
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
/**
|
||||
* Simple Spacetraders API wrapper usage example.
|
||||
*
|
||||
* Displays authenticated Agent and Ship data.
|
||||
*
|
||||
* @package SpacetradersApi
|
||||
* @author Keith Solomon <keith@keithsolomon.net>
|
||||
* @license MIT License
|
||||
* @link https://git.keithsolomon.net/keith/Spacetraders
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/lib/spacetraders-api.php';
|
||||
require_once __DIR__ . '/lib/spacetraders-storage.php';
|
||||
|
||||
$config = require __DIR__ . '/lib/project-config.php';
|
||||
|
||||
$storage = new SpacetradersStorage( $config['db_path'] );
|
||||
$token = $storage->getAgentToken();
|
||||
$statusMessage = '';
|
||||
$errorMessage = '';
|
||||
|
||||
if (! is_string( $token ) || trim( $token ) === '') {
|
||||
$envToken = getenv( 'SPACETRADERS_TOKEN' );
|
||||
if (is_string( $envToken ) && trim( $envToken ) !== '' ) {
|
||||
$token = trim( $envToken );
|
||||
$storage->setAgentToken( $token );
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_string( $token ) || trim( $token ) === '') {
|
||||
$tokenError = 'No token found. Set one in config.php or SPACETRADERS_TOKEN.';
|
||||
}
|
||||
|
||||
$agent = array();
|
||||
$ships = array();
|
||||
$contracts = array();
|
||||
|
||||
if (! isset( $tokenError ) ) {
|
||||
$client = new SpacetradersApi(
|
||||
trim( $token ),
|
||||
$config['api_base_url'],
|
||||
(int) $config['api_timeout'],
|
||||
$storage,
|
||||
(int) $config['cache_ttl']
|
||||
);
|
||||
|
||||
if (isset( $_GET['accept_contract'] ) && is_string( $_GET['accept_contract'] ) && trim( $_GET['accept_contract'] ) !== '') {
|
||||
try {
|
||||
$client->acceptContract( trim( $_GET['accept_contract'] ) );
|
||||
$storage->clearAllCache();
|
||||
$statusMessage = 'Contract accepted.';
|
||||
} catch (SpacetradersApiException $e) {
|
||||
$errorMessage = 'Unable to accept contract: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (! isset( $tokenError ) ) {
|
||||
$agentResponse = $client->getMyAgent();
|
||||
$shipsResponse = $client->listMyShips();
|
||||
$contractsResponse = $client->listMyContracts();
|
||||
|
||||
$agent = $agentResponse['data'] ?? $agentResponse;
|
||||
$ships = $shipsResponse['data'] ?? $shipsResponse;
|
||||
$contracts = $contractsResponse['data'] ?? $contractsResponse;
|
||||
}
|
||||
} catch (SpacetradersApiException $e) {
|
||||
$error = array(
|
||||
'error' => $e->getMessage(),
|
||||
'code' => $e->getCode(),
|
||||
'payload' => $e->getErrorPayload(),
|
||||
);
|
||||
|
||||
if (PHP_SAPI === 'cli' ) {
|
||||
fwrite( STDERR, json_encode( $error, JSON_PRETTY_PRINT ) . PHP_EOL );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
http_response_code( 500 );
|
||||
header( 'Content-Type: application/json; charset=utf-8' );
|
||||
echo json_encode( $error, JSON_PRETTY_PRINT );
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Spacetraders - Agent Information</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<body class="container mx-auto px-4 py-8 bg-stone-800 text-gray-200">
|
||||
<?php if (isset( $tokenError ) ) : ?>
|
||||
<div class="mb-6 border border-red-500 p-4 rounded">
|
||||
<p class="mb-3 text-red-300"><?php echo htmlspecialchars( $tokenError ); ?></p>
|
||||
<a href="config.php" class="text-blue-400 hover:underline">Open Configuration Page</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php exit; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mb-6">
|
||||
<a href="config.php" class="text-blue-400 hover:underline">Configuration</a>
|
||||
</div>
|
||||
|
||||
<?php if ($statusMessage !== '' ) : ?>
|
||||
<div class="mb-6 border border-green-500 p-4 rounded text-green-300">
|
||||
<?php echo htmlspecialchars( $statusMessage ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($errorMessage !== '' ) : ?>
|
||||
<div class="mb-6 border border-red-500 p-4 rounded text-red-300">
|
||||
<?php echo htmlspecialchars( $errorMessage ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<h1 class="text-3xl font-bold mb-6 underline decoration-gray-300 w-full">Spacetraders Agent and Ships</h1>
|
||||
|
||||
<h2 class="text-2xl font-bold mb-2">
|
||||
Agent: <?php echo htmlspecialchars( ucfirst( strtolower( $agent['symbol'] ) ) ); ?><br>
|
||||
Credits: <span class="font-normal"><?php echo number_format( $agent['credits'] ); ?></span>
|
||||
</h2>
|
||||
|
||||
<h3 class="text-xl font-bold mb-4">
|
||||
Headquarters: <span class="font-normal"><?php echo htmlspecialchars( $agent['headquarters'] ); ?></span><br>
|
||||
Faction: <span class="font-normal"><?php echo htmlspecialchars( ucfirst( strtolower( $agent['startingFaction'] ) ) ); ?></span><br>
|
||||
Ship Count: <span class="font-normal"><?php echo htmlspecialchars( $agent['shipCount'] ); ?></span><br>
|
||||
System: <span class="font-normal"><?php echo htmlspecialchars( $ships[0]['nav']['systemSymbol'] ); ?></span>
|
||||
</h3>
|
||||
|
||||
<h2 class="text-2xl font-bold my-4">Ships</h2>
|
||||
<table class="table-auto border-collapse border border-gray-300">
|
||||
<tr>
|
||||
<th class="border border-gray-300 px-4 py-2">Name</th>
|
||||
<th class="border border-gray-300 px-4 py-2">Role</th>
|
||||
<th class="border border-gray-300 px-4 py-2">Type</th>
|
||||
<th class="border border-gray-300 px-4 py-2">Status</th>
|
||||
<th class="border border-gray-300 px-4 py-2">Flight Mode</th>
|
||||
<th class="border border-gray-300 px-4 py-2">Route</th>
|
||||
</tr>
|
||||
|
||||
<?php foreach ( $ships as $ship ) : ?>
|
||||
<tr>
|
||||
<td class="border border-gray-300 px-4 py-2"><?php echo htmlspecialchars( ucfirst( strtolower( $ship['registration']['name'] ) ) ); ?></td>
|
||||
<td class="border border-gray-300 px-4 py-2"><?php echo htmlspecialchars( ucfirst( strtolower( $ship['registration']['role'] ) ) ); ?></td>
|
||||
<td class="border border-gray-300 px-4 py-2"><?php echo htmlspecialchars( $ship['frame']['name'] ); ?></td>
|
||||
<td class="border border-gray-300 px-4 py-2"><?php echo htmlspecialchars( ucfirst( strtolower( $ship['nav']['status'] ) ) ); ?></td>
|
||||
<?php if ($ship['nav']['status'] !== 'DOCKED' ) : ?>
|
||||
<td class="border border-gray-300 px-4 py-2"><?php echo htmlspecialchars( $ship['nav']['flightMode'] ); ?></td>
|
||||
<td class="border border-gray-300 px-4 py-2"><?php echo htmlspecialchars( $ship['nav']['route']['origin']['symbol'] . ' - ' . $ship['nav']['route']['destination']['symbol'] ); ?></td>
|
||||
<?php else : ?>
|
||||
<td class="border border-gray-300 px-4 py-2">N/A</td>
|
||||
<td class="border border-gray-300 px-4 py-2">N/A</td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
|
||||
<h2 class="text-2xl font-bold my-4">Contracts</h2>
|
||||
<div class="flex flex-col lg:flex-row gap-4">
|
||||
<?php
|
||||
$i = 1;
|
||||
|
||||
foreach ( $contracts as $contract ) :
|
||||
$type = ucfirst( strtolower( str_replace( '_', ' ', $contract['type'] ) ) ) ?? null;
|
||||
$delivery = ucfirst( strtolower( str_replace( '_', ' ', $contract['terms']['deliver'][0]['tradeSymbol'] ) ) ) ?? null;
|
||||
$accepted = $contract['accepted'] ? 'Accepted' : false;
|
||||
$fulfilled = $contract['fulfilled'] ? 'Fulfilled' : false;
|
||||
|
||||
if (! $accepted && ! $fulfilled) {
|
||||
$status = 'Not Accepted';
|
||||
} elseif ($accepted && ! $fulfilled) {
|
||||
$status = 'Accepted';
|
||||
} elseif ($accepted && $fulfilled) {
|
||||
$status = 'Fulfilled';
|
||||
} else {
|
||||
$status = 'Unknown';
|
||||
}
|
||||
?>
|
||||
<div class="mb-4 border border-gray-300 p-4 rounded">
|
||||
<h3 class="text-xl font-bold mb-2 w-full underline decoration-gray-300">Contract <?php echo $i; ?>: <?php echo htmlspecialchars( $type ); ?> - <?php echo htmlspecialchars( $delivery ); ?></h3>
|
||||
|
||||
<p class="mb-0 font-bold">
|
||||
Delivery Details: <span class="font-normal"><?php echo number_format( $contract['terms']['deliver'][0]['unitsRequired'] ); ?> units delivered to <?php echo htmlspecialchars( $contract['terms']['deliver'][0]['destinationSymbol'] ); ?></span>
|
||||
</p>
|
||||
|
||||
<p class="mb-2 font-bold">
|
||||
Payment: <span class="font-normal"><?php echo number_format( $contract['terms']['payment']['onAccepted'] ); ?> on Accept, <?php echo number_format( $contract['terms']['payment']['onFulfilled'] ); ?> on Fulfill</span>
|
||||
</p>
|
||||
|
||||
<p class="mb-0 font-bold">Deadline To Accept: <span class="font-normal"><?php echo htmlspecialchars( date( 'Y-m-d H:i:s', strtotime( $contract['deadlineToAccept'] ) ) ); ?></span></p>
|
||||
<p class="mb-2 font-bold">Deadline: <span class="font-normal"><?php echo htmlspecialchars( date( 'Y-m-d H:i:s', strtotime( $contract['terms']['deadline'] ) ) ); ?></span></p>
|
||||
|
||||
<p class="mb-0 font-bold">
|
||||
Status: <span class="font-normal"><?php echo htmlspecialchars( $status ); ?></span>
|
||||
<?php if ($status === 'Not Accepted' ) : ?>
|
||||
<span class="ml-2">
|
||||
<a
|
||||
href="agent-info.php?accept_contract=<?php echo urlencode( $contract['id'] ); ?>"
|
||||
class="font-normal text-blue-400 hover:underline"
|
||||
>
|
||||
Accept?
|
||||
</a>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$i++;
|
||||
endforeach;
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
94
config.php
Normal file
94
config.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Spacetraders configuration page.
|
||||
*
|
||||
* @package Spacetraders
|
||||
* @author Keith Solomon <keith@keithsolomon.net>
|
||||
* @license MIT License
|
||||
* @link https://git.keithsolomon.net/keith/Spacetraders
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/lib/spacetraders-storage.php';
|
||||
|
||||
$config = require __DIR__ . '/lib/project-config.php';
|
||||
|
||||
$storage = new SpacetradersStorage( $config['db_path'] );
|
||||
$token = $storage->getAgentToken();
|
||||
$statusMessage = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' ) {
|
||||
if (isset( $_POST['agent_token'] ) ) {
|
||||
$submittedToken = trim( (string) $_POST['agent_token'] );
|
||||
if ($submittedToken !== '' ) {
|
||||
$storage->setAgentToken( $submittedToken );
|
||||
$token = $submittedToken;
|
||||
$statusMessage = 'Agent token saved to SQLite settings.';
|
||||
}
|
||||
}
|
||||
|
||||
if (isset( $_POST['clear_cache'] ) ) {
|
||||
$storage->clearAllCache();
|
||||
$statusMessage = 'API cache cleared.';
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_string( $token ) || trim( $token ) === '') {
|
||||
$envToken = getenv( 'SPACETRADERS_TOKEN' );
|
||||
if (is_string( $envToken ) && trim( $envToken ) !== '' ) {
|
||||
$token = trim( $envToken );
|
||||
$storage->setAgentToken( $token );
|
||||
$statusMessage = 'Agent token imported from SPACETRADERS_TOKEN and saved.';
|
||||
}
|
||||
}
|
||||
|
||||
$hasToken = is_string( $token ) && trim( $token ) !== '';
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Spacetraders - Configuration</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<body class="container mx-auto px-4 py-8 bg-stone-800 text-gray-200">
|
||||
<h1 class="text-3xl font-bold mb-6 underline decoration-gray-300 w-full">Spacetraders Configuration</h1>
|
||||
|
||||
<div class="mb-6 border border-gray-600 p-4 rounded">
|
||||
<p class="mb-2 text-sm text-gray-300">
|
||||
API responses are cached in SQLite for
|
||||
<?php echo htmlspecialchars( (string) ( (int) $config['cache_ttl'] / 60 ) ); ?> minutes.
|
||||
</p>
|
||||
|
||||
<?php if ($statusMessage !== '' ) : ?>
|
||||
<p class="mb-3 text-green-300"><?php echo htmlspecialchars( $statusMessage ); ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (! $hasToken ) : ?>
|
||||
<p class="mb-3 text-yellow-300">No token is currently stored.</p>
|
||||
<?php else : ?>
|
||||
<p class="mb-3 text-green-300">Token is configured.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" class="flex flex-wrap gap-3 items-end">
|
||||
<div>
|
||||
<label for="agent_token" class="block text-sm mb-1">Agent Token</label>
|
||||
<input
|
||||
id="agent_token"
|
||||
name="agent_token"
|
||||
type="password"
|
||||
class="px-3 py-2 rounded text-black w-96"
|
||||
placeholder="Paste your Spacetraders token"
|
||||
>
|
||||
</div>
|
||||
<button type="submit" class="px-4 py-2 bg-blue-600 rounded hover:bg-blue-500">Save Token</button>
|
||||
<button type="submit" name="clear_cache" value="1" class="px-4 py-2 bg-gray-600 rounded hover:bg-gray-500">Clear Cache</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<a href="agent-info.php" class="text-blue-400 hover:underline">Back to Agent Info</a>
|
||||
</body>
|
||||
</html>
|
||||
42
index.php
Normal file
42
index.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Spacetraders Playground Index Page
|
||||
*
|
||||
* This file displays a list of all PHP files in the current directory.
|
||||
*
|
||||
* @category Web
|
||||
* @package Spacetraders
|
||||
* @author Keith Solomon <keith@keithsolomon.net>
|
||||
* @license MIT License
|
||||
* @link https://git.keithsolomon.net/keith/Spacetraders
|
||||
*/
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Spacetraders - Agent Information</title>
|
||||
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
|
||||
<body class="container mx-auto px-4 py-8 bg-stone-800 text-gray-200">
|
||||
<?php $files = glob( '*.php' ); ?>
|
||||
|
||||
<h1 class="text-3xl font-bold mb-6 underline decoration-gray-300 w-full">Spacetraders Playground</h1>
|
||||
|
||||
<ol class="list-decimal list-inside">
|
||||
<?php
|
||||
foreach ( $files as $file ) {
|
||||
if ($file === basename( __FILE__ ) ) {
|
||||
continue; // Skip the index.php file itself
|
||||
}
|
||||
|
||||
echo '<li><a href="' . $file . '" class="text-blue-400 hover:underline">' . $file . '</a></li>';
|
||||
}
|
||||
?>
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
13
lib/project-config.php
Normal file
13
lib/project-config.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Project runtime configuration values.
|
||||
*
|
||||
* @package Spacetraders
|
||||
*/
|
||||
|
||||
return array(
|
||||
'api_base_url' => 'https://api.spacetraders.io/v2',
|
||||
'api_timeout' => 30,
|
||||
'cache_ttl' => 600,
|
||||
'db_path' => dirname( __DIR__ ) . '/data/spacetraders.sqlite',
|
||||
);
|
||||
52
lib/spacetraders-api-exception.php
Normal file
52
lib/spacetraders-api-exception.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Spacetraders API Exception Class
|
||||
*
|
||||
* PHP version 7.4
|
||||
*
|
||||
* @category Exception
|
||||
* @package Spacetraders
|
||||
* @author Keith Solomon <keith@keithsolomon.net>
|
||||
* @license MIT License
|
||||
* @link https://github.com/your-repo/spacetraders
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom exception class for Spacetraders API related errors.
|
||||
*
|
||||
* This exception is thrown when API calls to the Spacetraders service
|
||||
* encounter errors such as network issues, invalid responses, authentication
|
||||
* failures, or other API-specific problems.
|
||||
*
|
||||
* @extends RuntimeException
|
||||
*/
|
||||
class SpacetradersApiException extends RuntimeException {
|
||||
/**
|
||||
* Error payload data from the API response.
|
||||
*
|
||||
* @var array<string,mixed>
|
||||
*/
|
||||
protected array $errorPayload = array();
|
||||
|
||||
/**
|
||||
* Constructor for SpacetradersApiException.
|
||||
*
|
||||
* @param string $message The exception message.
|
||||
* @param int $code The exception code (default: 0).
|
||||
* @param array<string,mixed> $errorPayload The error payload from API response (default: empty array).
|
||||
*/
|
||||
public function __construct( string $message, int $code = 0, array $errorPayload = array() ) {
|
||||
parent::__construct( $message, $code );
|
||||
$this->errorPayload = $errorPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error payload from the API response.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function getErrorPayload(): array {
|
||||
return $this->errorPayload;
|
||||
}
|
||||
}
|
||||
465
lib/spacetraders-api.php
Normal file
465
lib/spacetraders-api.php
Normal file
@@ -0,0 +1,465 @@
|
||||
<?php
|
||||
/**
|
||||
* Spacetraders API Client Library
|
||||
*
|
||||
* This library provides a simple interface to interact with the Spacetraders API,
|
||||
* allowing you to manage your agents, ships, and other resources in the game.
|
||||
* It includes methods for authentication, making API requests, and handling responses,
|
||||
* making it easier to integrate Spacetraders into your applications or scripts.
|
||||
*
|
||||
* @package SpacetradersAPI
|
||||
* @author Keith Solomon <keith@keithsolomon.net>
|
||||
* @license MIT License
|
||||
* @version GIT: <git_id>
|
||||
* @link https://spacetraders.io
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/spacetraders-api-exception.php';
|
||||
require_once __DIR__ . '/spacetraders-storage.php';
|
||||
|
||||
/**
|
||||
* Spacetraders API Client
|
||||
*
|
||||
* Main client class for interacting with the Spacetraders API. Provides methods
|
||||
* for authentication, managing agents, ships, contracts, systems, and performing
|
||||
* various game actions like navigation, trading, and resource extraction.
|
||||
*
|
||||
* @package SpacetradersAPI
|
||||
*/
|
||||
class SpacetradersApi {
|
||||
/**
|
||||
* The base URL for the Spacetraders API.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $baseUrl;
|
||||
|
||||
/**
|
||||
* The authentication token for API requests.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private ?string $token;
|
||||
|
||||
/**
|
||||
* The timeout for HTTP requests in seconds.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private int $timeout;
|
||||
/**
|
||||
* Optional SQLite storage for settings and cache.
|
||||
*
|
||||
* @var SpacetradersStorage|null
|
||||
*/
|
||||
private ?SpacetradersStorage $storage;
|
||||
|
||||
/**
|
||||
* Default cache lifetime in seconds.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private int $cacheTtl;
|
||||
|
||||
/**
|
||||
* Constructor for SpacetradersApi.
|
||||
*
|
||||
* @param string|null $token The authentication token for API requests ( default: null ).
|
||||
* @param string $baseUrl The base URL for the Spacetraders API ( default: 'https://api.spacetraders.io/v2' ).
|
||||
* @param int $timeout The timeout for HTTP requests in seconds ( default: 30 ).
|
||||
* @param SpacetradersStorage|null $storage Optional SQLite storage object for settings and caching.
|
||||
* @param int $cacheTtl API cache lifetime in seconds (default: 600).
|
||||
*/
|
||||
public function __construct(
|
||||
?string $token = null,
|
||||
string $baseUrl = 'https://api.spacetraders.io/v2',
|
||||
int $timeout = 30,
|
||||
?SpacetradersStorage $storage = null,
|
||||
int $cacheTtl = 600
|
||||
) {
|
||||
$this->baseUrl = rtrim( $baseUrl, '/' );
|
||||
$this->token = $token;
|
||||
$this->timeout = $timeout;
|
||||
$this->storage = $storage;
|
||||
$this->cacheTtl = max( 1, $cacheTtl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the authentication token for API requests.
|
||||
*
|
||||
* @param string $token The authentication token to set.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setToken( string $token ): void {
|
||||
$this->token = trim( $token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current authentication token.
|
||||
*
|
||||
* @return string|null The authentication token or null if not set.
|
||||
*/
|
||||
public function getToken(): ?string {
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach storage for API caching and persisted settings.
|
||||
*
|
||||
* @param SpacetradersStorage|null $storage Storage handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setStorage( ?SpacetradersStorage $storage ): void {
|
||||
$this->storage = $storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache lifetime for cached API calls in seconds.
|
||||
*
|
||||
* @param int $cacheTtl Cache lifetime in seconds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCacheTtl( int $cacheTtl ): void {
|
||||
$this->cacheTtl = max( 1, $cacheTtl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an HTTP request to the Spacetraders API.
|
||||
*
|
||||
* @param string $method The HTTP method (GET, POST, etc.).
|
||||
* @param string $endpoint The API endpoint to call.
|
||||
* @param array<string,mixed> $payload The request payload data.
|
||||
* @param array<string,mixed> $query The query parameters.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
* @throws SpacetradersApiException When cURL fails to initialize, JSON encoding fails, network errors occur, or API returns an error response.
|
||||
*/
|
||||
public function request(
|
||||
string $method,
|
||||
string $endpoint,
|
||||
array $payload = array(),
|
||||
array $query = array()
|
||||
): array {
|
||||
$url = $this->_buildUrl( $endpoint, $query );
|
||||
$method = strtoupper( $method );
|
||||
$cacheKey = $this->_buildCacheKey( $method, $url, $payload );
|
||||
|
||||
if ($method === 'GET' && $this->storage !== null ) {
|
||||
$cachedResponse = $this->storage->getCache( $cacheKey );
|
||||
if (is_array( $cachedResponse ) ) {
|
||||
return $cachedResponse;
|
||||
}
|
||||
}
|
||||
|
||||
$ch = curl_init( $url );
|
||||
|
||||
if ($ch === false ) {
|
||||
throw new SpacetradersApiException( 'Unable to initialize cURL.' );
|
||||
}
|
||||
|
||||
$headers = array( 'Accept: application/json' );
|
||||
$jsonPayload = null;
|
||||
|
||||
if (! empty( $this->token ) ) {
|
||||
$headers[] = 'Authorization: Bearer ' . $this->token;
|
||||
}
|
||||
|
||||
if (! empty( $payload ) ) {
|
||||
$jsonPayload = json_encode( $payload );
|
||||
if ($jsonPayload === false ) {
|
||||
throw new SpacetradersApiException( 'Unable to encode request payload as JSON.' );
|
||||
}
|
||||
|
||||
$headers[] = 'Content-Type: application/json';
|
||||
}
|
||||
|
||||
curl_setopt_array(
|
||||
$ch,
|
||||
array(
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
CURLOPT_TIMEOUT => $this->timeout,
|
||||
)
|
||||
);
|
||||
|
||||
if ($jsonPayload !== null ) {
|
||||
curl_setopt( $ch, CURLOPT_POSTFIELDS, $jsonPayload );
|
||||
}
|
||||
|
||||
$rawResponse = curl_exec( $ch );
|
||||
|
||||
if ($rawResponse === false ) {
|
||||
$error = curl_error( $ch );
|
||||
curl_close( $ch );
|
||||
throw new SpacetradersApiException( 'Network error: ' . $error );
|
||||
}
|
||||
|
||||
$statusCode = (int) curl_getinfo( $ch, CURLINFO_HTTP_CODE );
|
||||
curl_close( $ch );
|
||||
|
||||
$decoded = json_decode( $rawResponse, true );
|
||||
if (! is_array( $decoded ) ) {
|
||||
throw new SpacetradersApiException(
|
||||
'API returned an invalid JSON response.',
|
||||
$statusCode
|
||||
);
|
||||
}
|
||||
|
||||
if ($statusCode >= 400 ) {
|
||||
$message = $decoded['error']['message'] ?? 'Unknown API error.';
|
||||
$errorCode = (int) ( $decoded['error']['code'] ?? $statusCode );
|
||||
throw new SpacetradersApiException( $message, $errorCode, $decoded );
|
||||
}
|
||||
|
||||
if ($method === 'GET' && $this->storage !== null ) {
|
||||
$this->storage->setCache( $cacheKey, $decoded, $this->cacheTtl );
|
||||
$this->storage->purgeExpiredCache();
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new agent and returns the API response.
|
||||
*
|
||||
* @param array<string,mixed> $options Optional registration options: `symbol`, `faction`, and `email`.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function registerAgent( array $options ): array {
|
||||
return $this->request( 'POST', '/register', $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current agent's information.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function getMyAgent(): array {
|
||||
return $this->request( 'GET', '/my/agent' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all ships owned by the current agent.
|
||||
*
|
||||
* @param array<string,mixed> $query
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function listMyShips( array $query = array() ): array {
|
||||
return $this->request( 'GET', '/my/ships', array(), $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a specific ship owned by the current agent.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to retrieve.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function getShip( string $shipSymbol ): array {
|
||||
return $this->request( 'GET', '/my/ships/' . rawurlencode( $shipSymbol ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all contracts for the current agent.
|
||||
*
|
||||
* @param array<string,mixed> $query
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function listMyContracts( array $query = array() ): array {
|
||||
return $this->request( 'GET', '/my/contracts', array(), $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a contract for the current agent.
|
||||
*
|
||||
* @param string $contractId The ID of the contract to accept.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function acceptContract( string $contractId ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/contracts/' . rawurlencode( $contractId ) . '/accept'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all systems in the universe.
|
||||
*
|
||||
* @param array<string,mixed> $query
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function listSystems( array $query = array() ): array {
|
||||
return $this->request( 'GET', '/systems', array(), $query );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a specific system.
|
||||
*
|
||||
* @param string $systemSymbol The symbol of the system to retrieve.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function getSystem( string $systemSymbol ): array {
|
||||
return $this->request( 'GET', '/systems/' . rawurlencode( $systemSymbol ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of waypoints in a specific system.
|
||||
*
|
||||
* @param string $systemSymbol The symbol of the system to retrieve waypoints from.
|
||||
* @param array<string,mixed> $query
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function listWaypoints( string $systemSymbol, array $query = array() ): array {
|
||||
return $this->request(
|
||||
'GET',
|
||||
'/systems/' . rawurlencode( $systemSymbol ) . '/waypoints',
|
||||
array(),
|
||||
$query
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate a ship to a specific waypoint.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to navigate.
|
||||
* @param string $waypointSymbol The symbol of the waypoint to navigate to.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function navigateShip( string $shipSymbol, string $waypointSymbol ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/ships/' . rawurlencode( $shipSymbol ) . '/navigate',
|
||||
array( 'waypointSymbol' => $waypointSymbol )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a ship into orbit around its current waypoint.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to put into orbit.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function orbitShip( string $shipSymbol ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/ships/' . rawurlencode( $shipSymbol ) . '/orbit'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dock a ship at its current waypoint.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to dock.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function dockShip( string $shipSymbol ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/ships/' . rawurlencode( $shipSymbol ) . '/dock'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract resources from the current waypoint using the specified ship.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to use for resource extraction.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function extractResources( string $shipSymbol ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/ships/' . rawurlencode( $shipSymbol ) . '/extract'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purchase cargo for a specific ship at its current waypoint.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to purchase cargo for.
|
||||
* @param string $tradeSymbol The symbol of the trade good to purchase.
|
||||
* @param int $units The number of units to purchase.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function purchaseCargo( string $shipSymbol, string $tradeSymbol, int $units ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/ships/' . rawurlencode( $shipSymbol ) . '/purchase',
|
||||
array(
|
||||
'symbol' => $tradeSymbol,
|
||||
'units' => $units,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sell cargo from a specific ship at its current waypoint.
|
||||
*
|
||||
* @param string $shipSymbol The symbol of the ship to sell cargo from.
|
||||
* @param string $tradeSymbol The symbol of the trade good to sell.
|
||||
* @param int $units The number of units to sell.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
public function sellCargo( string $shipSymbol, string $tradeSymbol, int $units ): array {
|
||||
return $this->request(
|
||||
'POST',
|
||||
'/my/ships/' . rawurlencode( $shipSymbol ) . '/sell',
|
||||
array(
|
||||
'symbol' => $tradeSymbol,
|
||||
'units' => $units,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the full URL for an API endpoint with optional query parameters.
|
||||
*
|
||||
* @param string $endpoint The API endpoint path.
|
||||
* @param array<string,mixed> $query The query parameters to append.
|
||||
*
|
||||
* @return string The complete URL.
|
||||
*/
|
||||
private function _buildUrl( string $endpoint, array $query = array() ): string {
|
||||
$url = $this->baseUrl . '/' . ltrim( $endpoint, '/' );
|
||||
|
||||
if (! empty( $query ) ) {
|
||||
$url .= '?' . http_build_query( $query );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a deterministic cache key for an API request.
|
||||
*
|
||||
* @param string $method HTTP method.
|
||||
* @param string $url Full URL.
|
||||
* @param array<string,mixed> $payload Request payload.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _buildCacheKey( string $method, string $url, array $payload ): string {
|
||||
$payloadJson = json_encode( $payload );
|
||||
if ($payloadJson === false ) {
|
||||
$payloadJson = '';
|
||||
}
|
||||
|
||||
return hash( 'sha256', $method . '|' . $url . '|' . $payloadJson );
|
||||
}
|
||||
}
|
||||
245
lib/spacetraders-storage.php
Normal file
245
lib/spacetraders-storage.php
Normal file
@@ -0,0 +1,245 @@
|
||||
<?php
|
||||
/**
|
||||
* Spacetraders SQLite storage for configuration and API cache.
|
||||
*
|
||||
* @category Storage
|
||||
* @package SpacetradersAPI
|
||||
* @author Keith Solomon <keith@keithsolomon.net>
|
||||
* @license MIT License
|
||||
* @link https://git.keithsolomon.net/keith/Spacetraders
|
||||
*/
|
||||
|
||||
/**
|
||||
* Spacetraders SQLite storage for configuration and API cache.
|
||||
*
|
||||
* @package SpacetradersAPI
|
||||
*/
|
||||
class SpacetradersStorage {
|
||||
/**
|
||||
* Database handle.
|
||||
*
|
||||
* @var PDO
|
||||
*/
|
||||
private PDO $db;
|
||||
|
||||
/**
|
||||
* Create storage and initialize schema.
|
||||
*
|
||||
* @param string $dbPath Absolute or project-relative SQLite database path.
|
||||
*/
|
||||
public function __construct( string $dbPath ) {
|
||||
$directory = dirname( $dbPath );
|
||||
if (! is_dir( $directory ) ) {
|
||||
mkdir( $directory, 0777, true );
|
||||
}
|
||||
|
||||
$this->db = new PDO( 'sqlite:' . $dbPath );
|
||||
$this->db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
|
||||
$this->db->setAttribute( PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC );
|
||||
|
||||
$this->_initializeSchema();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create required tables if they do not exist.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function _initializeSchema(): void {
|
||||
$this->db->exec(
|
||||
'CREATE TABLE IF NOT EXISTS settings (
|
||||
setting_key TEXT PRIMARY KEY,
|
||||
setting_value TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
)'
|
||||
);
|
||||
|
||||
$this->db->exec(
|
||||
'CREATE TABLE IF NOT EXISTS api_cache (
|
||||
cache_key TEXT PRIMARY KEY,
|
||||
response_json TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL,
|
||||
expires_at INTEGER NOT NULL
|
||||
)'
|
||||
);
|
||||
|
||||
$this->db->exec(
|
||||
'CREATE INDEX IF NOT EXISTS idx_api_cache_expires
|
||||
ON api_cache (expires_at)'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a generic setting.
|
||||
*
|
||||
* @param string $key Setting key.
|
||||
* @param string $value Setting value.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setSetting( string $key, string $value ): void {
|
||||
$stmt = $this->db->prepare(
|
||||
'INSERT INTO settings (setting_key, setting_value, updated_at)
|
||||
VALUES (:key, :value, :updated_at)
|
||||
ON CONFLICT(setting_key) DO UPDATE SET
|
||||
setting_value = excluded.setting_value,
|
||||
updated_at = excluded.updated_at'
|
||||
);
|
||||
|
||||
$stmt->execute(
|
||||
array(
|
||||
':key' => $key,
|
||||
':value' => $value,
|
||||
':updated_at' => time(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a generic setting.
|
||||
*
|
||||
* @param string $key Setting key.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSetting( string $key ): ?string {
|
||||
$stmt = $this->db->prepare(
|
||||
'SELECT setting_value FROM settings WHERE setting_key = :key LIMIT 1'
|
||||
);
|
||||
$stmt->execute( array( ':key' => $key ) );
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if (! is_array( $row ) || ! isset( $row['setting_value'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string) $row['setting_value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the agent token in settings.
|
||||
*
|
||||
* @param string $token Agent token.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAgentToken( string $token ): void {
|
||||
$this->setSetting( 'agent_token', $token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stored agent token, if available.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getAgentToken(): ?string {
|
||||
return $this->getSetting( 'agent_token' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a valid cached response by cache key.
|
||||
*
|
||||
* @param string $cacheKey Cache key.
|
||||
*
|
||||
* @return array<string,mixed>|null
|
||||
*/
|
||||
public function getCache( string $cacheKey ): ?array {
|
||||
$stmt = $this->db->prepare(
|
||||
'SELECT response_json, expires_at
|
||||
FROM api_cache
|
||||
WHERE cache_key = :cache_key
|
||||
LIMIT 1'
|
||||
);
|
||||
$stmt->execute( array( ':cache_key' => $cacheKey ) );
|
||||
$row = $stmt->fetch();
|
||||
|
||||
if (! is_array( $row ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((int) $row['expires_at'] <= time() ) {
|
||||
$this->deleteCache( $cacheKey );
|
||||
return null;
|
||||
}
|
||||
|
||||
$decoded = json_decode( (string) $row['response_json'], true );
|
||||
if (! is_array( $decoded ) ) {
|
||||
$this->deleteCache( $cacheKey );
|
||||
return null;
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store API response in cache.
|
||||
*
|
||||
* @param string $cacheKey Cache key.
|
||||
* @param array<string,mixed> $response API response payload.
|
||||
* @param int $ttl Time to live in seconds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setCache( string $cacheKey, array $response, int $ttl = 600 ): void {
|
||||
$json = json_encode( $response );
|
||||
if ($json === false ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$createdAt = time();
|
||||
$expiresAt = $createdAt + max( 1, $ttl );
|
||||
|
||||
$stmt = $this->db->prepare(
|
||||
'INSERT INTO api_cache (cache_key, response_json, created_at, expires_at)
|
||||
VALUES (:cache_key, :response_json, :created_at, :expires_at)
|
||||
ON CONFLICT(cache_key) DO UPDATE SET
|
||||
response_json = excluded.response_json,
|
||||
created_at = excluded.created_at,
|
||||
expires_at = excluded.expires_at'
|
||||
);
|
||||
|
||||
$stmt->execute(
|
||||
array(
|
||||
':cache_key' => $cacheKey,
|
||||
':response_json' => $json,
|
||||
':created_at' => $createdAt,
|
||||
':expires_at' => $expiresAt,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove one cache row.
|
||||
*
|
||||
* @param string $cacheKey Cache key.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCache( string $cacheKey ): void {
|
||||
$stmt = $this->db->prepare(
|
||||
'DELETE FROM api_cache WHERE cache_key = :cache_key'
|
||||
);
|
||||
$stmt->execute( array( ':cache_key' => $cacheKey ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all expired cache rows.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function purgeExpiredCache(): void {
|
||||
$stmt = $this->db->prepare(
|
||||
'DELETE FROM api_cache WHERE expires_at <= :now'
|
||||
);
|
||||
$stmt->execute( array( ':now' => time() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all cached API rows.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearAllCache(): void {
|
||||
$this->db->exec( 'DELETE FROM api_cache' );
|
||||
}
|
||||
}
|
||||
27
phpcs.xml
27
phpcs.xml
@@ -12,25 +12,36 @@
|
||||
<exclude-pattern>node_modules/</exclude-pattern>
|
||||
|
||||
<rule ref="PEAR">
|
||||
<exclude name="PEAR.Classes.ClassDeclaration"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingAuthorTag"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingCategoryTag"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingLicenseTag"/>
|
||||
<exclude name="PEAR.Commenting.FileComment.MissingCategoryTag"/>
|
||||
<exclude name="PEAR.Commenting.FileComment.MissingVersion"/>
|
||||
<exclude name="PEAR.Functions.FunctionDeclaration"/>
|
||||
<exclude name="Generic.Files.LineLength.TooLong"/>
|
||||
<exclude name="Generic.Functions.CallTimePassByReference"/>
|
||||
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent.SpacesUsed"/>
|
||||
<exclude name="Generic.WhiteSpace.DisallowTabIndent.TabsUsed"/>
|
||||
<exclude name="PEAR.Classes.ClassDeclaration"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingAuthorTag"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingCategoryTag"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingLicenseTag"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingLinkTag"/>
|
||||
<exclude name="PEAR.Commenting.ClassComment.MissingPackageTag"/>
|
||||
<exclude name="PEAR.Commenting.FileComment.MissingCategoryTag"/>
|
||||
<exclude name="PEAR.Commenting.FileComment.MissingVersion"/>
|
||||
<exclude name="PEAR.Commenting.FunctionComment.MissingParamComment"/>
|
||||
<exclude name="PEAR.Functions.FunctionDeclaration"/>
|
||||
<exclude name="PEAR.NamingConventions.ValidVariableName.PrivateNoUnderscore"/>
|
||||
<exclude name="Squiz.Commenting.FileComment.MissingPackageTag"/>
|
||||
<exclude name="Squiz.Commenting.FileComment.Missing"/>
|
||||
<exclude name="Squiz.Commenting.FileComment.WrongStyle"/>
|
||||
<exclude name="Squiz.Commenting.InlineComment.InvalidEndChar"/>
|
||||
<exclude name="WordPress.Security.EscapeOutput.ExceptionNotEscaped"/>
|
||||
</rule>
|
||||
|
||||
<rule ref="Internal.NoCodeFound">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PSR2.Methods.MethodDeclaration.Underscore">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="WordPress">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
</ruleset>
|
||||
|
||||
Reference in New Issue
Block a user