PluginProbe
Unique Headers / trunk
Unique Headers vtrunk
2.1.3 2.1 2.1.1 2.0.1 trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1 1.2 1.2.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.7 1.3.8 1.3.9 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 All 54 releases
unique-headers / src / DisplayModule.php

DisplayModule.php in Unique Headers trunk, at src/DisplayModule.php

318 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace RyanHellyer\UniqueHeaders;
6
7 use RyanHellyer\UniqueHeaders\Vendor\Inpsyde\Modularity\Module\ExecutableModule;
8 use RyanHellyer\UniqueHeaders\Vendor\Psr\Container\ContainerInterface;
9
10 class DisplayModule implements ExecutableModule
11 {
12 private AttachmentHelper $attachmentHelper;
13 private string $name = 'custom-header-image';
14 private string $nameUnderscores;
15
16 public function __construct(AttachmentHelper $attachmentHelper)
17 {
18 $this->attachmentHelper = $attachmentHelper;
19 $this->nameUnderscores = str_replace('-', '_', $this->name);
20 }
21
22 public function id(): string
23 {
24 return 'unique-headers-display';
25 }
26
27 public function run(ContainerInterface $container): bool
28 {
29 add_filter('theme_mod_header_image', [$this, 'postHeaderImageFilter'], 20);
30 add_filter('wp_calculate_image_srcset', [$this, 'headerSrcsetFilter'], 20, 5);
31 add_filter('theme_mod_header_image_data', [$this, 'postModifyHeaderImageData']);
32
33 if (function_exists('get_term_meta')) {
34 add_action('admin_init', [$this, 'addTaxonomyFields']);
35 add_filter('theme_mod_header_image', [$this, 'taxonomyHeaderImageFilter'], 5);
36 add_filter('theme_mod_header_image_data', [$this, 'taxonomyModifyHeaderImageData']);
37 }
38
39 return true;
40 }
41
42 /**
43 * @param string|array<mixed> $url
44 * @return string|array<mixed>
45 */
46 public function postHeaderImageFilter($url)
47 {
48 if (!is_string($url)) {
49 return $url;
50 }
51
52 if (!is_single() && !is_page() && !is_home()) {
53 return $url;
54 }
55
56 $postId = is_home() ? (int) get_option('page_for_posts') : (int) get_the_ID();
57 $attachmentId = $this->attachmentHelper->getId($postId, $this->nameUnderscores);
58
59 if ($attachmentId) {
60 $url = $this->attachmentHelper->getSrc($attachmentId);
61 }
62
63 return $url;
64 }
65
66 /**
67 * @param object|null $data
68 * @return object|null
69 */
70 public function postModifyHeaderImageData($data)
71 {
72 if (!is_single() && !is_page() && !is_home()) {
73 return $data;
74 }
75
76 $postId = is_home() ? (int) get_option('page_for_posts') : (int) get_the_ID();
77
78 return $this->setAttachmentData($data, $this->attachmentHelper->getId($postId, $this->nameUnderscores));
79 }
80
81 /**
82 * @param string|array<mixed> $url
83 * @return string|array<mixed>
84 */
85 public function taxonomyHeaderImageFilter($url)
86 {
87 if (!is_string($url)) {
88 return $url;
89 }
90
91 $taxId = $this->getCurrentTaxonomyId();
92 if (!$taxId) {
93 return $url;
94 }
95
96 $attachmentId = $this->getTaxonomyAttachmentId($taxId);
97 if ($attachmentId) {
98 return esc_url($this->attachmentHelper->getSrc($attachmentId));
99 }
100
101 $legacy = get_metadata('taxonomy', $taxId, 'taxonomy-header-image', true);
102 if (is_string($legacy) && $legacy !== '') {
103 return esc_url($legacy);
104 }
105
106 return $url;
107 }
108
109 /**
110 * @param object|null $data
111 * @return object|null
112 */
113 public function taxonomyModifyHeaderImageData($data)
114 {
115 if (!is_tag() && !is_tax() && !is_category()) {
116 return $data;
117 }
118
119 $taxId = $this->getCurrentTaxonomyId();
120 if (!$taxId) {
121 return $data;
122 }
123
124 return $this->setAttachmentData($data, $this->getTaxonomyAttachmentId($taxId));
125 }
126
127 /**
128 * @param array<int, array{url: string}>|string $srcset
129 * @param array<int, int> $sizeArray
130 * @param string $imageSrc
131 * @param array<string, mixed> $imageMeta
132 * @param int $attachmentId
133 * @return array<int, array{url: string}>|string
134 */
135 public function headerSrcsetFilter($srcset, $sizeArray, $imageSrc, $imageMeta, int $attachmentId = 0)
136 {
137 if (
138 !isset(get_custom_header()->attachment_id)
139 || get_custom_header()->attachment_id !== $attachmentId
140 ) {
141 return $srcset;
142 }
143
144 if (!is_array($srcset)) {
145 return $srcset;
146 }
147
148 $currentUrl = $this->getCurrentHeaderUrl();
149 if ($currentUrl === '') {
150 return $srcset;
151 }
152
153 foreach ($srcset as $size => $set) {
154 $srcset[$size]['url'] = $currentUrl;
155 }
156
157 return $srcset;
158 }
159
160 public function addTaxonomyFields(): void
161 {
162 if (!is_admin()) {
163 return;
164 }
165
166 foreach (get_taxonomies(['public' => true]) as $taxonomy) {
167 add_action($taxonomy . '_edit_form_fields', [$this, 'extraFields'], 1);
168 add_action('edit_' . $taxonomy, [$this, 'storeTaxonomyData']);
169 }
170 }
171
172 public function storeTaxonomyData(): void
173 {
174 if (
175 !isset($_POST[$this->name . '-nonce'])
176 || !isset($_POST[$this->name . '-id'])
177 || !isset($_POST['tag_ID'])
178 ) {
179 return;
180 }
181
182 $nonce = sanitize_key(wp_unslash($_POST[$this->name . '-nonce']));
183 if (!wp_verify_nonce($nonce, $this->name)) {
184 return;
185 }
186
187 $tagId = absint(wp_unslash($_POST['tag_ID']));
188
189 if (!current_user_can('edit_term', $tagId)) {
190 return;
191 }
192
193 $attachmentId = absint(wp_unslash($_POST[$this->name . '-id']));
194
195 update_term_meta($tagId, 'taxonomy-header-image', $attachmentId);
196 }
197
198 public function extraFields(\WP_Term $term): void
199 {
200 $tagId = $term->term_id;
201 $attachmentId = $this->getTaxonomyAttachmentId($tagId);
202
203 if ($attachmentId) {
204 $url = $this->attachmentHelper->getSrc($attachmentId);
205 $title = $this->attachmentHelper->getTitle($attachmentId);
206 } else {
207 $legacy = get_metadata('taxonomy', $tagId, 'taxonomy-header-image', true);
208 $url = is_string($legacy) ? $legacy : '';
209 $title = '';
210 $attachmentId = $legacy;
211 }
212
213 $name = $this->name;
214 ?>
215 <tr valign="top">
216 <th scope="row"><?php echo esc_html__('Upload header image', 'unique-headers'); ?></th>
217 <td>
218 <div id="unique-header" class="postbox">
219 <div class="inside">
220 <?php require __DIR__ . '/../views/meta-box.php'; ?>
221 </div>
222 </div>
223 </td>
224 </tr>
225 <?php
226 }
227
228 private function getCurrentHeaderUrl(): string
229 {
230 $postId = 0;
231
232 if (is_home()) {
233 $postId = (int) get_option('page_for_posts');
234 } elseif (is_single() || is_page()) {
235 $postId = (int) get_the_ID();
236 }
237
238 if ($postId) {
239 $attachmentId = $this->attachmentHelper->getId($postId, $this->nameUnderscores);
240 if ($attachmentId) {
241 return $this->attachmentHelper->getSrc($attachmentId);
242 }
243 }
244
245 $taxId = $this->getCurrentTaxonomyId();
246 if ($taxId) {
247 $attachmentId = $this->getTaxonomyAttachmentId($taxId);
248 if ($attachmentId) {
249 return $this->attachmentHelper->getSrc($attachmentId);
250 }
251 }
252
253 return '';
254 }
255
256 private function getCurrentTaxonomyId(): int
257 {
258 if (is_category()) {
259 return (int) get_query_var('cat');
260 }
261
262 if (is_tag() || is_tax()) {
263 foreach (get_taxonomies(['public' => true]) as $taxonomy) {
264 if ($taxonomy === 'category') {
265 continue;
266 }
267
268 $slug = $taxonomy === 'post_tag' ? get_query_var('tag') : get_query_var($taxonomy);
269
270 if ($slug) {
271 $term = get_term_by('slug', $slug, $taxonomy);
272 if (isset($term->term_id)) {
273 return (int) $term->term_id;
274 }
275 }
276 }
277 }
278
279 return 0;
280 }
281
282 private function getTaxonomyAttachmentId(int $taxId): int
283 {
284 $attachmentId = get_term_meta($taxId, 'taxonomy-header-image', true);
285
286 if (is_numeric($attachmentId)) {
287 return (int) $attachmentId;
288 }
289
290 $legacy = get_metadata('taxonomy', $taxId, 'taxonomy-header-image', true);
291
292 return is_numeric($legacy) ? (int) $legacy : 0;
293 }
294
295 /**
296 * @param object|null $data
297 * @return object|null
298 */
299 private function setAttachmentData($data, int $attachmentId)
300 {
301 if (!$attachmentId) {
302 return $data;
303 }
304
305 if ($data === null) {
306 $data = (object) null;
307 }
308
309 if (is_object($data)) {
310 $data->attachment_id = $attachmentId;
311 $data->width = $this->attachmentHelper->getDimensions($attachmentId, 'width');
312 $data->height = $this->attachmentHelper->getDimensions($attachmentId, 'height');
313 }
314
315 return $data;
316 }
317 }
318