[]]), ]; } public function sanitizeValue($value, array $field) { // The id of an attachment. Anything else (an id that is gone, text) becomes empty, without a PHP warning. $meta = get_post_meta((int) $value); if (! empty($meta['_wp_attachment_metadata']) || ! empty($meta['_wp_attached_file'])) { return $value; } return ''; } public function usesAssets(): bool { return true; } public function enqueue(array $field): void { wp_enqueue_media(); // Versioned by file date (like ColorPicker), not by the plugin version: a changed script under an // unchanged plugin version would otherwise keep being served from the browser cache. wp_enqueue_script( Plugin::PREFIX . 'media-js', Plugin::assetsUrl() . 'js/' . Plugin::PREFIX . 'media.js', ['wp-i18n'], Enqueue::version('js/' . Plugin::PREFIX . 'media.js'), 'all' ); Enqueue::scriptTranslations(Plugin::PREFIX . 'media-js'); wp_enqueue_style( Plugin::PREFIX . 'media-css', Plugin::assetsUrl() . 'css/' . Plugin::PREFIX . 'media.css', [], Enqueue::version('css/' . Plugin::PREFIX . 'media.css'), 'all' ); } /** * The image (`` with srcset), in the size of `size="..."` (default: full). */ public function displayValue($value, array $field, array $args): string { $id = Display::attachmentId($value); if ($id === 0) { return ''; } return (string) wp_get_attachment_image($id, ($args['size'] ?? '') !== '' ? (string) $args['size'] : 'full'); } public function bindingValue($value, array $field, string $attribute): ?string { $id = Display::attachmentId($value); if ($id === 0) { return null; } switch ($attribute) { case 'url': return (string) wp_get_attachment_image_url($id, 'full'); case 'alt': return (string) get_post_meta($id, '_wp_attachment_image_alt', true); case 'title': return get_the_title($id); case 'id': return (string) $id; case 'content': case 'text': return $this->displayValue($value, $field, []); } return null; } public function render(array $field, $value): void { printf('
', esc_attr(Plugin::PREFIX) . 'media-wrapper'); printf( '
', esc_attr(Plugin::PREFIX) . 'image-preview-wrapper hidden', esc_attr(Plugin::PREFIX) . 'image-preview-box', esc_url_raw(wp_get_attachment_thumb_url($value)) ); printf( '
', esc_attr(Plugin::PREFIX) . 'upload-image', 'button ' . esc_attr(Plugin::PREFIX) . 'upload-image__button', esc_html__('Upload', 'admin-options-pages'), esc_attr($this->mediaTypes($field['extensions'])), // The "Upload files" tab of the media modal does not read `library.type` (that only filters the // "Media Library" tab's query); aop-media.js uses this to restrict it too, via a plupload extension // filter, which matches by file extension rather than by mime type. esc_attr($this->extensionList($field['extensions'])) ); printf( '', esc_attr($field['field_name']), esc_attr($value), esc_attr(Plugin::PREFIX) . 'media-attachment' ); printf( '
%s
', esc_attr(Plugin::PREFIX) . 'delete-image hidden', 'javascript:;', esc_attr(Plugin::PREFIX) . 'delete-image__link', esc_html__('Delete', 'admin-options-pages') ); print('
'); print(wp_kses_post($this->descriptionHtml($field['description'] ?? ''))); } /** * @param array $extensions The stored `extensions` setting: ['types' => ['png' => 'on', ...]]. */ private function mediaTypes($extensions): string { $list = Collection::make([ 'ico' => 'image/x-icon', 'gif' => 'image/gif', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'svg' => 'image/svg+xml' ]); return implode(', ', $list->only($this->selectedExtensions($extensions))->flip()->keys()->all()); } /** * The real file extensions (not mime types) of the allowed types, for the "Upload files" tab (see render()). * ".jpeg .jpg" is one checkbox but two extensions; the rest are one each. * * @param array $extensions The stored `extensions` setting: ['types' => ['png' => 'on', ...]]. */ private function extensionList($extensions): string { $list = Collection::make([ 'ico' => 'ico', 'gif' => 'gif', 'jpeg' => 'jpg,jpeg', 'png' => 'png', 'svg' => 'svg' ]); return implode(',', $list->only($this->selectedExtensions($extensions))->values()->all()); } /** * @param array $extensions The stored `extensions` setting: ['types' => ['png' => 'on', ...]]. * * @return array */ private function selectedExtensions($extensions): array { return Collection::make(Collection::make($extensions)->get('types')) ->keys() ->all(); } }