feat(plug): add contract interfaces and Registry::register() method
Some checks failed
CI / PHP 8.3 (push) Failing after 1m55s
CI / PHP 8.4 (push) Failing after 1m55s

Move 8 plug contract interfaces (Authenticable, Commentable, Deletable,
Listable, MediaUploadable, Postable, Readable, Refreshable) from the
Laravel app into the framework under Core\Plug\Contract namespace. Add
register() method to Registry so extracted packages can self-register
their providers without filesystem scanning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Snider 2026-03-09 17:25:40 +00:00
parent a9c1afe492
commit 25df6996e6
9 changed files with 209 additions and 0 deletions

View file

@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for authentication operations.
*
* Covers OAuth2, API key, webhook, and credential-based auth flows.
*/
interface Authenticable
{
/**
* Get provider identifier (e.g., 'twitter', 'bluesky').
*/
public static function identifier(): string;
/**
* Get display name (e.g., 'X', 'Bluesky').
*/
public static function name(): string;
/**
* Get OAuth authorisation URL.
*
* Returns empty string if not OAuth-based.
*/
public function getAuthUrl(): string;
/**
* Exchange credentials/callback params for access token.
*
* @param array $params OAuth callback params or credentials
* @return array Token data or error
*/
public function requestAccessToken(array $params): array;
/**
* Get authenticated account information.
*/
public function getAccount(): Response;
}

View file

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for comment/reply operations.
*/
interface Commentable
{
/**
* Post a comment or reply to existing content.
*
* @param string $text Comment content
* @param string $postId ID of the post to comment on
* @param array $params Platform-specific options
*/
public function comment(string $text, string $postId, array $params = []): Response;
}

View file

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for content deletion operations.
*/
interface Deletable
{
/**
* Delete a post by its external ID.
*/
public function delete(string $id): Response;
}

View file

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for listing entities (pages, boards, publications, etc.).
*
* Used by providers that require selecting a target entity before posting.
* Examples: Meta pages, Pinterest boards, Medium publications.
*/
interface Listable
{
/**
* List available entities for the authenticated user.
*/
public function listEntities(): Response;
}

View file

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for media upload operations.
*/
interface MediaUploadable
{
/**
* Upload media to the platform.
*
* @param array $item Media item with 'path', 'mime_type', 'name', etc.
*/
public function upload(array $item): Response;
}

View file

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
use Illuminate\Support\Collection;
/**
* Contract for content publishing operations.
*/
interface Postable
{
/**
* Publish content to the platform.
*
* @param string $text Post content
* @param Collection $media Media items (may be empty)
* @param array $params Platform-specific options
*/
public function publish(string $text, Collection $media, array $params = []): Response;
}

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for reading posts and content.
*/
interface Readable
{
/**
* Get a single post by ID.
*/
public function get(string $id): Response;
/**
* Get multiple posts (timeline/feed).
*
* @param array $params Pagination and filter options
*/
public function list(array $params = []): Response;
}

View file

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Core\Plug\Contract;
use Core\Plug\Response;
/**
* Contract for token refresh operations.
*/
interface Refreshable
{
/**
* Refresh an expired access token.
*
* @return Response Contains new token data on success
*/
public function refresh(): Response;
}

View file

@ -67,6 +67,21 @@ class Registry
$this->discovered = true;
}
/**
* Register a provider programmatically.
*
* Used by plug packages to self-register without filesystem scanning.
*/
public function register(string $identifier, string $category, string $name, string $namespace): void
{
$this->providers[$identifier] = [
'category' => $category,
'name' => $name,
'namespace' => $namespace,
'path' => null,
];
}
/**
* Get all registered provider identifiers.
*