1. Go to this page and download the library: Download socialdept/atp-parity library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
socialdept / atp-parity example snippets
use SocialDept\AtpParity\RecordMapper;
use SocialDept\AtpSchema\Data\Data;
use Illuminate\Database\Eloquent\Model;
class PostMapper extends RecordMapper
{
public function recordClass(): string
{
return \SocialDept\AtpSchema\Generated\App\Bsky\Feed\Post::class;
}
public function modelClass(): string
{
return \App\Models\Post::class;
}
protected function recordToAttributes(Data $record): array
{
return [
'content' => $record->text,
'published_at' => $record->createdAt,
];
}
protected function modelToRecordData(Model $model): array
{
return [
'text' => $model->content,
'createdAt' => $model->published_at->toIso8601String(),
];
}
}
class PostMapper extends RecordMapper
{
public function recordClass(): string
{
return Post::class; // Your atp-schema DTO or custom Record
}
public function modelClass(): string
{
return \App\Models\Post::class;
}
protected function recordToAttributes(Data $record): array
{
return ['content' => $record->text];
}
protected function modelToRecordData(Model $model): array
{
return ['text' => $model->content];
}
}
use SocialDept\AtpParity\Support\RecordHelper;
$helper = app(RecordHelper::class);
// Fetch as typed DTO
$record = $helper->fetch('at://did:plc:xxx/app.bsky.feed.post/abc123');
// Fetch and convert to model (unsaved)
$post = $helper->fetchAsModel('at://did:plc:xxx/app.bsky.feed.post/abc123');
// Fetch and sync to database (upsert)
$post = $helper->sync('at://did:plc:xxx/app.bsky.feed.post/abc123');
use SocialDept\AtpParity\Concerns\HasAtpRecord;
class Post extends Model
{
use HasAtpRecord;
protected $fillable = ['content', 'atp_uri', 'atp_cid'];
}
// Get AT Protocol metadata
$post->getAtpUri(); // at://did:plc:xxx/app.bsky.feed.post/rkey
$post->getAtpCid(); // bafyre...
$post->getAtpDid(); // did:plc:xxx (extracted from URI)
$post->getAtpCollection(); // app.bsky.feed.post (extracted from URI)
$post->getAtpRkey(); // rkey (extracted from URI)
// Check sync status
$post->hasAtpRecord(); // true if synced
// Convert to record DTO
$record = $post->toAtpRecord();
// Query scopes
Post::withAtpRecord()->get(); // Only synced posts
Post::withoutAtpRecord()->get(); // Only unsynced posts
Post::whereAtpUri($uri)->first(); // Find by URI
use SocialDept\AtpParity\Concerns\SyncsWithAtp;
class Post extends Model
{
use SyncsWithAtp;
}
// Track sync status
$post->getAtpSyncedAt(); // Last sync timestamp
$post->hasLocalChanges(); // True if updated since last sync
// Mark as synced
$post->markAsSynced($uri, $cid);
// Update from remote
$post->updateFromRecord($record, $uri, $cid);
use SocialDept\AtpParity\Concerns\HasAtpRecord;
use SocialDept\AtpParity\Concerns\HasAtpBlobs;
class Post extends Model
{
use HasAtpRecord, HasAtpBlobs;
protected $casts = ['atp_blobs' => 'array'];
}
// Get URLs for blobs
$url = $post->getAtpBlobUrl('avatar'); // Single blob URL
$urls = $post->getAtpBlobUrls('images'); // Array of URLs
// Download blobs locally
$post->downloadAtpBlobs();
// Check status
$post->hasAtpBlobs(); // Has any blob data
$post->hasLocalBlobs(); // All blobs downloaded locally
use SocialDept\AtpParity\Concerns\AutoSyncsWithAtp;
class Post extends Model
{
use AutoSyncsWithAtp;
public function syncAsDid(): ?string
{
return $this->user->did;
}
public function shouldAutoSync(): bool
{
return $this->status === 'published';
}
}
$post = Post::create(['content' => 'Hello!']); // Syncs to ATP
$post->update(['content' => 'Updated']); // Updates ATP record
$post->delete(); // Removes from ATP
Schema::table('posts', function (Blueprint $table) {
$table->string('atp_uri')->nullable()->unique();
$table->string('atp_cid')->nullable();
$table->timestamp('atp_synced_at')->nullable(); // For SyncsWithAtp
$table->json('atp_blobs')->nullable(); // For HasAtpBlobs
});
use SocialDept\AtpParity\Data\Record;
use Carbon\Carbon;
class PostRecord extends Record
{
public function __construct(
public readonly string $text,
public readonly Carbon $createdAt,
public readonly ?array $facets = null,
) {}
public static function getLexicon(): string
{
return 'app.bsky.feed.post';
}
public static function fromArray(array $data): static
{
return new static(
text: $data['text'],
createdAt: Carbon::parse($data['createdAt']),
facets: $data['facets'] ?? null,
);
}
}