Promptrepository - Source Excerpt 05
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Domain/PromptRepository.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Domain/PromptRepository.php
$posts = get_posts(
[
'name' => sanitize_title($slug),
'post_type' => self::POST_TYPE,
'post_status' => ['publish', 'draft', 'pending', 'private'],
'posts_per_page' => 1,
]
);
if (empty($posts[0]) || !$posts[0] instanceof WP_Post) {
return [];
}
return $this->get((int) $posts[0]->ID, $viewer_user_id);
}
/**
* Finds a managed system prompt by its source slug.
*/
public function find_by_source_slug(string $source_slug, int $viewer_user_id = 0): array
{
$posts = get_posts(
[
'post_type' => self::POST_TYPE,
'post_status' => ['publish', 'draft', 'pending', 'private'],
'posts_per_page' => 1,
'meta_query' => [
[
'key' => $this->meta_key('source_slug'),
'value' => sanitize_title($source_slug),
],
],
]
);
if (empty($posts[0]) || !$posts[0] instanceof WP_Post) {
return [];
}
return $this->get((int) $posts[0]->ID, $viewer_user_id);
}
/**
* Finds a managed prompt that already exists under the filesystem slug or a WordPress suffix variant.
*/
public function find_managed_slug_candidate(string $slug, int $viewer_user_id = 0): array
{
foreach ($this->find_slug_duplicate_candidates($slug, $viewer_user_id) as $candidate) {
if ($this->is_managed_prompt_record($candidate)) {
return $candidate;
}
}
return [];
}
/**
* Finds records whose slug is either the canonical slug or a WordPress-generated numeric variant.
*
* @return array<int,array<string,mixed>>
*/
public function find_slug_duplicate_candidates(string $slug, int $viewer_user_id = 0): array
{
global $wpdb;
$slug = sanitize_title($slug);
if ($slug === '') {
return [];
}
$like = $wpdb->esc_like($slug . '-') . '%';
$sql = $wpdb->prepare(
"SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = %s AND post_status IN ('publish', 'draft', 'pending', 'private') AND (post_name = %s OR post_name LIKE %s) ORDER BY ID ASC",
self::POST_TYPE,
$slug,
$like
);
$rows = $wpdb->get_results($sql, ARRAY_A);
if (!is_array($rows)) {
return [];
}
$pattern = '/^' . preg_quote($slug, '/') . '(?:-[0-9]+)?$/';
$records = [];
foreach ($rows as $row) {
$post_name = (string) ($row['post_name'] ?? '');
if (!preg_match($pattern, $post_name)) {
continue;
}
$record = $this->get((int) ($row['ID'] ?? 0), $viewer_user_id);
if (!empty($record)) {
$records[] = $record;
}
}
usort(
$records,
function (array $left, array $right) use ($slug): int {
return $this->duplicate_candidate_score($right, $slug) <=> $this->duplicate_candidate_score($left, $slug);
}
);
return $records;
}
/**
* Lists prompts for the public or authenticated libraries.
*/
public function list(array $args = [], int $viewer_user_id = 0): array
{
$query_args = [
'post_type' => self::POST_TYPE,
'post_status' => ['publish', 'private', 'draft', 'pending'],
'posts_per_page' => isset($args['limit']) ? max(1, (int) $args['limit']) : 20,
'orderby' => 'modified',
'order' => 'DESC',
];
if (!empty($args['owner_user_id'])) {
$query_args['author'] = (int) $args['owner_user_id'];
}
if (!empty($args['search'])) {
$query_args['s'] = sanitize_text_field((string) $args['search']);
}
if (!empty($args['include'])) {
$query_args['post__in'] = array_values(array_map('intval', (array) $args['include']));
$query_args['orderby'] = 'post__in';
}
$posts = get_posts($query_args);
$records = [];
foreach ($posts as $post) {
if (!$post instanceof WP_Post) {
continue;
}
$records[] = $this->get((int) $post->ID, $viewer_user_id);
}
return $records;
}
/**
* Lists only public, published prompts that are not hidden by moderation.
*/
public function list_public(array $args = [], int $viewer_user_id = 0): array
{
$requested_limit = isset($args['limit']) ? max(1, (int) $args['limit']) : 100;
$query_limit = !empty($args['include']) ? $requested_limit : min(max($requested_limit * 2, $requested_limit), 240);
$query_args = [
'post_type' => self::POST_TYPE,
'post_status' => ['publish'],
'posts_per_page' => $query_limit,
'orderby' => 'modified',
'order' => 'DESC',
'ignore_sticky_posts' => true,
'no_found_rows' => true,
'update_post_meta_cache' => true,
'update_post_term_cache' => true,
'meta_query' => [
'relation' => 'AND',
[
'key' => $this->meta_key('visibility'),
'value' => 'public',
],
[
'key' => $this->meta_key('prompt_status'),
'value' => 'published',
],
[
'relation' => 'OR',
[
'key' => $this->meta_key('moderation_status'),
'compare' => 'NOT EXISTS',
],
[
'key' => $this->meta_key('moderation_status'),
'value' => ['restricted', 'restricted_review', 'reverted', 'archived'],
'compare' => 'NOT IN',
],
],
[
'relation' => 'OR',
[
'key' => $this->meta_key('soft_deleted_at'),
'compare' => 'NOT EXISTS',
],
[
'key' => $this->meta_key('soft_deleted_at'),
'value' => '',
'compare' => '=',
],
],
],
];
if (!empty($args['search'])) {
$query_args['s'] = sanitize_text_field((string) $args['search']);
}
if (!empty($args['include'])) {
$query_args['post__in'] = array_values(array_map('intval', (array) $args['include']));
$query_args['orderby'] = 'post__in';
}
$posts = get_posts($query_args);
$records = [];
foreach ($posts as $post) {
if (!$post instanceof WP_Post) {
continue;
}
$records[] = $this->get((int) $post->ID, $viewer_user_id);
}
return array_slice($this->dedupe_public_records($records), 0, $requested_limit);
}
/**
* @param array<int,array<string,mixed>> $records
* @return array<int,array<string,mixed>>
*/
private function dedupe_public_records(array $records): array
{
$deduped = [];
foreach ($records as $record) {
if (empty($record)) {
continue;
}
$key = $this->public_dedupe_key($record);
if ($key === '') {
$deduped[] = $record;
continue;
}
if (
!isset($deduped[$key])
|| $this->duplicate_candidate_score($record, $this->numeric_slug_base((string) ($record['slug'] ?? ''))) > $this->duplicate_candidate_score($deduped[$key], $this->numeric_slug_base((string) ($deduped[$key]['slug'] ?? '')))
) {
$deduped[$key] = $record;
}
}
return array_values($deduped);
}
/**
* @param array<string,mixed> $record
*/
private function public_dedupe_key(array $record): string
{
$source_slug = sanitize_title((string) ($record['source_slug'] ?? ''));
if ($source_slug !== '') {
return 'source:' . $source_slug;
}
$slug = sanitize_title((string) ($record['slug'] ?? ''));
if ($slug === '') {
return '';
}