PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.15
Yatra – Travel Booking & Tour Operator Software v3.0.15
3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 2.0.10 All 83 releases
yatra / resources / js / hooks / useWordPressMedia.ts

useWordPressMedia.ts in Yatra – Travel Booking & Tour Operator Software 3.0.15, at resources/js/hooks/useWordPressMedia.ts

242 lines 6.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * WordPress Media Library Hook
3 * Provides functionality to open WordPress media library and select/upload images
4 */
5
6 import { useCallback } from "react";
7 import { __ } from "../lib/i18n";
8 import { prepareWordPressMediaFrameOpen } from "../lib/wp-media-open";
9
10 declare global {
11 interface Window {
12 wp?: {
13 media: {
14 (options?: any): any;
15 model?: any;
16 view?: any;
17 controller?: any;
18 frames?: any;
19 };
20 };
21 jQuery?: any;
22 yatraWpMedia?: any; // Preserved reference to wp.media
23 }
24 }
25
26 interface MediaAttachment {
27 id: number;
28 url: string;
29 alt?: string;
30 title?: string;
31 caption?: string;
32 description?: string;
33 sizes?: {
34 [key: string]: {
35 url: string;
36 width: number;
37 height: number;
38 };
39 };
40 }
41
42 interface UseWordPressMediaOptions {
43 title?: string;
44 buttonText?: string;
45 multiple?: boolean;
46 library?: {
47 type?: string;
48 };
49 }
50
51 interface UseWordPressMediaReturn {
52 openMediaLibrary: (
53 callback: (attachment: MediaAttachment | MediaAttachment[]) => void,
54 ) => void;
55 }
56
57 /**
58 * Hook to interact with WordPress media library
59 */
60 export const useWordPressMedia = (
61 options: UseWordPressMediaOptions = {},
62 ): UseWordPressMediaReturn => {
63 const {
64 title = "Select or Upload Image",
65 buttonText = "Use this image",
66 multiple = false,
67 library = { type: "image" },
68 } = options;
69
70 const openMediaLibrary = useCallback(
71 (callback: (attachment: MediaAttachment | MediaAttachment[]) => void) => {
72 // Get WordPress media object from global scope
73 // Use multiple methods to access wp.media (bypasses window.wp overwrite)
74 const getWpMedia = (): any => {
75 // Method 1: Use preserved reference (safest, set by inline script before React loads)
76 if (typeof (window as any).yatraWpMedia === "function") {
77 return (window as any).yatraWpMedia;
78 }
79
80 // Method 2: Access wp in global scope using Function constructor (bypasses window.wp overwrite)
81 try {
82 const wpMedia = new Function(
83 'return (typeof wp !== "undefined" && typeof wp.media === "function") ? wp.media : null',
84 )();
85 if (wpMedia) {
86 return wpMedia;
87 }
88 } catch (e) {
89 // Continue to next method
90 }
91
92 // Method 3: Try accessing through window.wp if it's an object
93 try {
94 if (
95 typeof (window as any).wp === "object" &&
96 (window as any).wp !== null &&
97 typeof (window as any).wp.media === "function"
98 ) {
99 return (window as any).wp.media;
100 }
101 } catch (e) {
102 // Continue to next method
103 }
104
105 // Method 4: Use eval to access in global scope (last resort)
106 try {
107 const wpMedia = eval(
108 '(typeof wp !== "undefined" && typeof wp.media === "function") ? wp.media : null',
109 );
110 if (wpMedia) {
111 return wpMedia;
112 }
113 } catch (e) {
114 // Ignore
115 }
116
117 return null;
118 };
119
120 // Wait for media library to be available
121 const ensureMediaLibrary = (retries = 50, delay = 100): Promise<any> => {
122 return new Promise((resolve, reject) => {
123 let attempt = 0;
124
125 const checkMedia = () => {
126 attempt++;
127 const wpMedia = getWpMedia();
128
129 if (wpMedia && typeof wpMedia === "function") {
130 resolve(wpMedia);
131 return;
132 }
133
134 if (retries > 0) {
135 retries--;
136 setTimeout(checkMedia, delay);
137 } else {
138 reject(
139 new Error(
140 __(
141 "WordPress media library is not available. Please refresh the page.",
142 "yatra",
143 ),
144 ),
145 );
146 }
147 };
148
149 // Start checking after DOM is ready with longer delay for scripts to load
150 if (typeof window.jQuery !== "undefined") {
151 window.jQuery(document).ready(() => {
152 // Give more time for media scripts to initialize
153 setTimeout(checkMedia, 500);
154 });
155 } else if (
156 document.readyState === "complete" ||
157 document.readyState === "interactive"
158 ) {
159 setTimeout(checkMedia, 500);
160 } else {
161 document.addEventListener("DOMContentLoaded", () => {
162 setTimeout(checkMedia, 500);
163 });
164 // Fallback: also start checking after a delay
165 setTimeout(checkMedia, 1000);
166 }
167 });
168 };
169
170 // Open media library
171 ensureMediaLibrary()
172 .then((wpMedia) => {
173 // Create media frame
174 const frame = wpMedia({
175 title,
176 button: {
177 text: buttonText,
178 },
179 multiple,
180 library,
181 });
182
183 if (!frame) {
184 throw new Error(__("Failed to create media frame.", "yatra"));
185 }
186
187 // Handle selection when user clicks the button
188 frame.on("select", () => {
189 const selection = frame.state().get("selection");
190 const attachments = selection.toJSON();
191
192 if (multiple) {
193 const formattedAttachments: MediaAttachment[] = attachments.map(
194 (attachment: any) => ({
195 id: attachment.id,
196 url: attachment.url,
197 alt: attachment.alt || "",
198 title: attachment.title || "",
199 caption: attachment.caption || "",
200 description: attachment.description || "",
201 sizes: attachment.sizes || {},
202 }),
203 );
204 callback(formattedAttachments);
205 } else {
206 const attachment = attachments[0];
207 if (attachment) {
208 const formattedAttachment: MediaAttachment = {
209 id: attachment.id,
210 url: attachment.url,
211 alt: attachment.alt || "",
212 title: attachment.title || "",
213 caption: attachment.caption || "",
214 description: attachment.description || "",
215 sizes: attachment.sizes || {},
216 };
217 callback(formattedAttachment);
218 }
219 }
220 });
221
222 prepareWordPressMediaFrameOpen();
223 // Open the media library popup
224 frame.open();
225 })
226 .catch((error) => {
227 console.error("Error opening WordPress media library:", error);
228 alert(
229 error.message ||
230 __(
231 "WordPress media library is not available. Please refresh the page.",
232 "yatra",
233 ),
234 );
235 });
236 },
237 [title, buttonText, multiple, library],
238 );
239
240 return { openMediaLibrary };
241 };
242