Files
wordpress-theme-aksrt/src/Core/FrontSubmitFeatured.php
T
kate522 8241570ca2 feat(users): govern profiles and access
Normalize fixed profile fields, profile actions, and the five-column capability matrix for comments, uploads, and downloads.
2026-08-13 00:24:54 +08:00

184 lines
7.6 KiB
PHP

<?php
/**
* @package AKSRT
*/
namespace AKSRT\Core;
defined('ABSPATH') || exit;
/**
* Featured cover (image / slide / video) for front-end submit.
*/
trait FrontSubmitFeatured {
/**
* @param array<string, mixed> $data
*/
private function save_featured_meta(int $post_id, array $data, int $user_id): void {
if (empty($data['featured_data']) && empty($data['featured_type'])) {
return;
}
$featured = $data['featured_data'] ?? null;
if (is_string($featured)) {
$decoded = json_decode(wp_unslash($featured), true);
$featured = is_array($decoded) ? $decoded : null;
}
if (!is_array($featured)) {
// Flat payload: featured_type + fields.
$featured = [
'type' => sanitize_key((string) ($data['featured_type'] ?? '')),
'data' => $data['featured_payload'] ?? $data,
];
}
$type = sanitize_key((string) ($featured['type'] ?? ''));
$payload = is_array($featured['data'] ?? null) ? $featured['data'] : $featured;
$post_meta = get_post_meta($post_id, DomainModel::POST_META_KEY, true);
if (!is_array($post_meta)) {
$post_meta = DomainModel::default_post_meta();
}
switch ($type) {
case 'video':
if (!$this->user_can_cap('new_post_video_cover', $user_id) && !$this->user_can_cap('new_post_image_cover', $user_id)) {
return;
}
$video = esc_url_raw((string) ($payload['url'] ?? $payload['video'] ?? ''));
$pic = esc_url_raw((string) ($payload['pic'] ?? $payload['poster'] ?? $payload['cover'] ?? ''));
if ($pic !== '' && !$this->user_can_cap('upload_submit_image', $user_id)) {
$pic = '';
}
$post_meta['featured_video'] = $video;
$post_meta['featured_slide'] = '';
if ($pic !== '' && $this->can_use_front_submit_image_url($pic, $user_id)) {
$post_meta['thumbnail_url'] = $pic;
$post_meta['cover_images'] = $pic;
$this->maybe_set_thumbnail_url($post_id, $pic);
}
break;
case 'slide':
if (!$this->user_can_cap('new_post_slide_cover', $user_id) && !$this->user_can_cap('new_post_image_cover', $user_id)) {
return;
}
$ids = $payload['ids'] ?? $payload['slides'] ?? $payload['images'] ?? [];
$urls = [];
if (is_string($ids)) {
$ids = array_filter(array_map('trim', explode(',', $ids)));
}
if (is_array($ids)) {
foreach ($ids as $item) {
if (is_array($item)) {
$u = esc_url_raw((string) ($item['url'] ?? ''));
$attachment_id = absint($item['id'] ?? 0);
if ($attachment_id > 0 && $this->can_use_front_submit_image($attachment_id, $user_id)) {
$src = wp_get_attachment_image_url($attachment_id, 'full');
if ($src) {
$urls[] = $src;
}
} elseif ($u !== '' && $this->user_can_cap('upload_submit_image', $user_id)) {
$urls[] = $u;
}
} elseif (is_numeric($item)) {
$attachment_id = (int) $item;
$src = $this->can_use_front_submit_image($attachment_id, $user_id)
? wp_get_attachment_image_url($attachment_id, 'full')
: false;
if ($src) {
$urls[] = $src;
}
} else {
$u = esc_url_raw((string) $item);
if ($u !== '' && $this->user_can_cap('upload_submit_image', $user_id)) {
$urls[] = $u;
}
}
}
}
$post_meta['featured_slide'] = implode(',', $urls);
$post_meta['featured_video'] = '';
if (!empty($urls[0]) && $this->can_use_front_submit_image_url((string) $urls[0], $user_id)) {
$post_meta['thumbnail_url'] = $urls[0];
$post_meta['cover_images'] = $urls[0];
$this->maybe_set_thumbnail_url($post_id, $urls[0]);
}
break;
case 'image':
if (!$this->user_can_cap('new_post_image_cover', $user_id)) {
return;
}
$url = esc_url_raw((string) ($payload['url'] ?? $payload['image'] ?? ''));
$id = absint($payload['id'] ?? 0);
if ($id > 0 && !$this->can_use_front_submit_image($id, $user_id)) {
return;
}
if ($url === '' && $id > 0) {
$src = wp_get_attachment_image_url($id, 'full');
if ($src) {
$url = $src;
}
}
$post_meta['featured_video'] = '';
$post_meta['featured_slide'] = '';
if ($url !== '' && $this->can_use_front_submit_image_url($url, $user_id)) {
$post_meta['thumbnail_url'] = $url;
$post_meta['cover_images'] = $url;
if ($id > 0) {
set_post_thumbnail($post_id, $id);
} elseif ($this->user_can_cap('upload_submit_image', $user_id)) {
$this->maybe_set_thumbnail_url($post_id, $url);
}
}
break;
case 'close':
case 'none':
case 'clear':
$post_meta['featured_video'] = '';
$post_meta['featured_slide'] = '';
$post_meta['thumbnail_url'] = '';
$post_meta['cover_images'] = '';
delete_post_thumbnail($post_id);
break;
default:
return;
}
update_post_meta($post_id, DomainModel::POST_META_KEY, $post_meta);
}
private function maybe_set_thumbnail_url(int $post_id, string $url): void {
if ($url === '') {
return;
}
// Prefer attachment if URL is local media.
$attach_id = attachment_url_to_postid($url);
if ($attach_id > 0) {
set_post_thumbnail($post_id, $attach_id);
return;
}
$this->set_thumbnail_from_url($post_id, $url);
}
private function can_use_front_submit_image(int $attachment_id, int $user_id): bool {
if ($attachment_id <= 0 || !$this->user_can_cap('upload_submit_image', $user_id)) {
return false;
}
$attachment = get_post($attachment_id);
return $attachment instanceof \WP_Post
&& $attachment->post_type === 'attachment'
&& (int) $attachment->post_author === $user_id
&& wp_attachment_is_image($attachment_id);
}
private function can_use_front_submit_image_url(string $url, int $user_id): bool {
$attachment_id = attachment_url_to_postid($url);
return $attachment_id > 0 && $this->can_use_front_submit_image($attachment_id, $user_id);
}
}