';
} else {
echo '–';
}
}
}
/**
* Marks an ad's currently selected image as used by AdPresso, and un-marks
* its previous image if the ad switched to a different one (and no other
* ad still references the old one).
*
* Hooked to 'adpresso_ad_saved' (fired by AdRepository::save() after this
* save's meta_data is fully persisted) rather than 'save_post' - see hooks().
*
* @param int $post_id The ad's post ID.
* @param int $previous_image_id The ad's image_id meta value before this save (0 if none/new ad).
*/
public function mark_media_as_used( int $post_id, int $previous_image_id = 0 ): void {
$is_image_ad = get_post_meta( $post_id, Constants::META_PREFIX . 'ad_type', true ) === 'image';
$image_id = $is_image_ad ? (int) get_post_meta( $post_id, Constants::META_PREFIX . 'image_id', true ) : 0;
if ( $previous_image_id && $previous_image_id !== $image_id && ! $this->is_image_used_by_another_ad( $previous_image_id, $post_id ) ) {
delete_post_meta( $previous_image_id, self::META_KEY );
}
if ( $image_id ) {
update_post_meta( $image_id, self::META_KEY, 1 );
}
}
/**
* Whether an attachment is still referenced as the image of some OTHER
* image-type ad - used before un-marking an ad's previous image, so a
* shared image doesn't get incorrectly un-flagged while still in use
* elsewhere.
*
* @param int $image_id The attachment ID to check.
* @param int $excluding_ad_id The ad ID to exclude from the check (the one currently being saved).
*
* @return bool
*/
private function is_image_used_by_another_ad( int $image_id, int $excluding_ad_id ): bool {
$others = get_posts( [
'post_type' => Constants::POST_TYPE_AD,
'post_status' => 'any',
'posts_per_page' => 1,
'fields' => 'ids',
'no_found_rows' => true,
'post__not_in' => [ $excluding_ad_id ],
'meta_query' => [
'relation' => 'AND',
[ 'key' => Constants::META_PREFIX . 'ad_type', 'value' => 'image' ],
[ 'key' => Constants::META_PREFIX . 'image_id', 'value' => $image_id ],
],
] );
return ! empty( $others );
}
/**
* Adds a read-only field to the attachment details modal indicating usage in AdPresso.
*
* @param array $fields Existing form fields.
* @param WP_Post $post The attachment post object.
*
* @return array Modified form fields.
*/
public function add_used_in_ads_field( array $fields, WP_Post $post ): array {
if ( get_post_meta( $post->ID, self::META_KEY, true ) ) {
$fields['adpresso_used_for_ad'] = [
'label' => __( 'AdPresso Usage', 'adpresso' ),
'input' => 'html',
'html' => ' ' . 'Used in AdPresso',
'helps' => 'This attachment is currently used in one or more AdPresso items (Ads, Placements, etc.).',
];
}
return $fields;
}
/**
* Adds a filter dropdown to the Media Library list table ("List" mode).
*/
public function add_media_library_filter_dropdown(): void {
$screen = get_current_screen();
if ( ! $screen instanceof WP_Screen || $screen->base !== 'upload' || $screen->post_type !== 'attachment' ) {
return;
}
$selected = Params::get()->getKey( 'adpresso_filter' );
echo '';
echo '';
}
/**
* Modifies the Media Library query based on the selected filter.
*
* @param WP_Query $query The WP_Query instance (passed by reference).
*/
public function filter_media_library_query( WP_Query $query ): void {
if ( ! is_admin() || ! $query->is_main_query() || $query->get( 'post_type' ) !== 'attachment' ) {
return;
}
$filter_value = Params::get()->getString( 'adpresso_filter', '' );
if ( $filter_value === 'adpresso_used' ) {
$meta_query = $query->get( 'meta_query' ) ?: [];
if ( ! empty( $meta_query ) && ! isset( $meta_query['relation'] ) ) {
$meta_query['relation'] = 'AND';
}
$meta_query[] = [
'key' => self::META_KEY,
'compare' => 'EXISTS',
];
$query->set( 'meta_query', $meta_query );
} elseif ( $filter_value === 'adpresso_not_used' ) {
$meta_query = $query->get( 'meta_query' ) ?: [];
if ( ! empty( $meta_query ) && ! isset( $meta_query['relation'] ) ) {
$meta_query['relation'] = 'AND';
}
$meta_query[] = [
'key' => self::META_KEY,
'compare' => 'NOT EXISTS',
];
$query->set( 'meta_query', $meta_query );
}
}
}