get_results( $wpdb->prepare( 'SELECT m.id,m.entry_id,m.actor_id,m.context,e.growoff_id,e.group_id FROM %i m LEFT JOIN %i e ON e.id=m.entry_id' . " WHERE ( %d = 0 OR m.id<%d ) AND ( %s = 'all' OR ( %s = 'avatars' AND m.context='profile_avatar' )" . " OR ( %s = 'covers' AND m.context='profile_cover' ) OR ( %s = 'growoffs' AND m.context='entry' AND e.growoff_id>0 )" . " OR ( %s = 'groups' AND m.context='entry' AND e.group_id>0 AND e.growoff_id=0 )" . " OR ( %s = 'posts' AND m.context='entry' AND e.group_id=0 AND e.growoff_id=0 ) ) ORDER BY m.id DESC LIMIT 100", $wpdb->prefix . 'affsc_media', $wpdb->prefix . 'affsc_entries', $before, $before, $folder, $folder, $folder, $folder, $folder, $folder ), ARRAY_A ); return is_array( $rows ) && ! $wpdb->last_error ? $rows : null; } /** * One page of protected photos the current user may read, newest first, with where each came from in Community. * * @param int $before Show photos older than this record (0 for the newest). * @param string $folder all, posts, growoffs, groups, avatars or covers. * @return array|\WP_Error The photos and the next page's cursor, or why they cannot be listed. */ public static function listing( int $before = 0, string $folder = 'all' ) { if ( ! current_user_can( 'manage_options' ) || ! current_user_can( 'upload_files' ) ) { return new \WP_Error( 'afsd_im_private_forbidden', __( 'Site image management permission required.', 'affstackdev-image-manager' ) ); } if ( ! defined( 'AFFSC_VERSION' ) || version_compare( AFFSC_VERSION, '0.1.0.12', '<' ) || ! class_exists( 'AffStackDev\\Community\\Media' ) ) { return new \WP_Error( 'afsd_im_private_provider', __( 'Activate Community 0.1.0.12 or newer to browse its protected photos.', 'affstackdev-image-manager' ) ); } $folders = array( 'all', 'posts', 'growoffs', 'groups', 'avatars', 'covers' ); if ( $before < 0 || ! in_array( $folder, $folders, true ) ) { return new \WP_Error( 'afsd_im_private_input', __( 'Invalid image folder or cursor.', 'affstackdev-image-manager' ) ); } $actor = get_current_user_id(); $access = \AffStackDev\Community\Access::require_read( $actor ); if ( is_wp_error( $access ) ) { return $access; } global $wpdb; $rows = self::query_rows( $before, $folder ); if ( null === $rows ) { return new \WP_Error( 'afsd_im_private_read', __( 'Protected image records are temporarily unavailable.', 'affstackdev-image-manager' ) ); } $items = array(); $cursor = 0; $used = 0; foreach ( $rows as $row ) { $cursor = (int) $row['id']; ++$used; $descriptor = null; $label = ''; if ( $row['context'] === 'entry' ) { $entry = \AffStackDev\Community\Community::entry( $actor, (int) $row['entry_id'] ); if ( is_wp_error( $entry ) ) { continue; } foreach ( $entry['media'] ?? array() as $item ) { if ( (int) $item['id'] === $cursor ) { $descriptor = $item; } } /* translators: %d: grow-off or group ID in AffStackDev Community. */ $label = ! empty( $row['growoff_id'] ) ? sprintf( __( 'Grow-offs / #%d', 'affstackdev-image-manager' ), (int) $row['growoff_id'] ) : ( ! empty( $row['group_id'] ) ? sprintf( __( 'Groups / #%d', 'affstackdev-image-manager' ), (int) $row['group_id'] ) : __( 'Posts', 'affstackdev-image-manager' ) ); } elseif ( in_array( $row['context'], array( 'profile_avatar', 'profile_cover' ), true ) ) { $profile = \AffStackDev\Community\Media::profile_descriptors( $actor, (int) $row['actor_id'] ); if ( is_wp_error( $profile ) ) { continue; } $descriptor = $profile[ $row['context'] === 'profile_avatar' ? 'avatar' : 'cover' ] ?? null; $label = $row['context'] === 'profile_avatar' ? __( 'Profile pictures', 'affstackdev-image-manager' ) : __( 'Profile covers', 'affstackdev-image-manager' ); } if ( ! $descriptor || (int) $descriptor['id'] !== $cursor ) { continue; } $items[] = array( 'id' => $cursor, /* translators: %s: Community folder, such as Posts or Profile pictures. */ 'folder' => sprintf( __( 'Community / %s', 'affstackdev-image-manager' ), $label ), 'media' => $descriptor, ); if ( count( $items ) === 24 ) { break; } } return array( 'items' => $items, 'next_before' => ( $used < count( $rows ) || count( $rows ) === 100 ) ? $cursor : 0, ); } /** * Print the Protected Community photos screen with its folder links and pages. */ public static function render(): void { $folder = isset( $_GET['im_private_folder'] ) && is_string( $_GET['im_private_folder'] ) ? sanitize_key( wp_unslash( $_GET['im_private_folder'] ) ) : 'all'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only folder/pagination filter on an admin listing; value is sanitized and changes no state $before = isset( $_GET['im_private_before'] ) && is_scalar( $_GET['im_private_before'] ) ? absint( $_GET['im_private_before'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only folder/pagination filter on an admin listing; value is sanitized and changes no state echo '

' . esc_html__( 'Protected Community photos', 'affstackdev-image-manager' ) . '

' . esc_html__( 'New photos appear here automatically in their Community folders. Visibility follows the current post, grow-off and profile rules. Open Community to edit or remove them.', 'affstackdev-image-manager' ) . '

'; foreach ( array( 'all' => __( 'All', 'affstackdev-image-manager' ), 'posts' => __( 'Posts', 'affstackdev-image-manager' ), 'growoffs' => __( 'Grow-offs', 'affstackdev-image-manager' ), 'groups' => __( 'Groups', 'affstackdev-image-manager' ), 'avatars' => __( 'Profile pictures', 'affstackdev-image-manager' ), 'covers' => __( 'Profile covers', 'affstackdev-image-manager' ), ) as $key => $label ) { echo '' . esc_html( $label ) . ''; } echo '
'; $data = self::listing( $before, $folder ); if ( is_wp_error( $data ) ) { echo '

' . esc_html( $data->get_error_message() ) . '

'; return; } echo '
'; foreach ( $data['items'] as $row ) { $m = $row['media']; echo '
'
				. esc_attr( sprintf( /* translators: %d: Community photo ID. */__( 'Protected Community photo #%d', 'affstackdev-image-manager' ), (int) $row['id'] ) )
				. '
' . esc_html( $row['folder'] ) . '

#' . (int) $row['id'] . ' · ' . esc_html( $m['mime'] ) . ' · ' . esc_html( size_format( $m['bytes'] ) ) . '

'; } echo '
'; if ( ! $data['items'] ) { echo '

' . esc_html__( 'No photos visible in this part of the folder.', 'affstackdev-image-manager' ) . '

'; } if ( $data['next_before'] ) { echo '' . esc_html__( 'Older photos', 'affstackdev-image-manager' ) . ''; } echo ''; } }