run:R W Run
DIR
2026-03-11 16:18:51
R W Run
2.86 KB
2026-03-11 16:18:51
R W Run
758 By
2026-03-11 16:18:51
R W Run
6.24 KB
2026-03-11 16:18:51
R W Run
2.95 KB
2026-03-11 16:18:51
R W Run
5.66 KB
2026-03-11 16:18:51
R W Run
2.04 KB
2026-03-11 16:18:51
R W Run
11.32 KB
2026-03-11 16:18:51
R W Run
3.01 KB
2026-03-11 16:18:51
R W Run
9.54 KB
2026-03-11 16:18:51
R W Run
3.4 KB
2026-03-11 16:18:51
R W Run
2.85 KB
2026-03-11 16:18:51
R W Run
1.28 KB
2026-03-11 16:18:51
R W Run
61.15 KB
2026-03-11 16:18:51
R W Run
23.12 KB
2026-03-11 16:18:51
R W Run
3.35 KB
2026-03-11 16:18:51
R W Run
1.18 KB
2026-03-11 16:18:51
R W Run
1.98 KB
2026-03-11 16:18:51
R W Run
288.41 KB
2026-03-11 16:18:51
R W Run
109.69 KB
2026-03-11 16:18:51
R W Run
111.46 KB
2026-03-11 16:18:51
R W Run
47.14 KB
2026-03-11 16:18:51
R W Run
70.05 KB
2026-03-11 16:18:51
R W Run
27.41 KB
2026-03-11 16:18:51
R W Run
27.02 KB
2026-03-11 16:18:51
R W Run
8.65 KB
2026-03-11 16:18:51
R W Run
37.12 KB
2026-03-11 16:18:51
R W Run
15.13 KB
2026-03-11 16:18:51
R W Run
41.61 KB
2026-03-11 16:18:51
R W Run
13.14 KB
2026-03-11 16:18:51
R W Run
44 KB
2026-03-11 16:18:51
R W Run
12.78 KB
2026-03-11 16:18:51
R W Run
7.67 KB
2026-03-11 16:18:51
R W Run
5.41 KB
2026-03-11 16:18:51
R W Run
3.65 KB
2026-03-11 16:18:51
R W Run
39.98 KB
2026-03-11 16:18:51
R W Run
15.15 KB
2026-03-11 16:18:51
R W Run
20.17 KB
2026-03-11 16:18:51
R W Run
9.41 KB
2026-03-11 16:18:51
R W Run
7.61 KB
2026-03-11 16:18:51
R W Run
2.93 KB
2026-03-11 16:18:51
R W Run
23.09 KB
2026-03-11 16:18:51
R W Run
890 By
2026-03-11 16:18:51
R W Run
423 By
2026-03-11 16:18:51
R W Run
3.89 KB
2026-03-11 16:18:51
R W Run
1.7 KB
2026-03-11 16:18:51
R W Run
1.27 KB
2026-03-11 16:18:51
R W Run
611 By
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
1.13 KB
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
2.38 KB
2026-03-11 16:18:51
R W Run
61.15 KB
2026-03-11 16:18:51
R W Run
30.06 KB
2026-03-11 16:18:51
R W Run
4.14 KB
2026-03-11 16:18:51
R W Run
1.1 KB
2026-03-11 16:18:51
R W Run
1.31 KB
2026-03-11 16:18:51
R W Run
847 By
2026-03-11 16:18:51
R W Run
6.92 KB
2026-03-11 16:18:51
R W Run
2.35 KB
2026-03-11 16:18:51
R W Run
38.68 KB
2026-03-11 16:18:51
R W Run
18.4 KB
2026-03-11 16:18:51
R W Run
18.49 KB
2026-03-11 16:18:51
R W Run
6.6 KB
2026-03-11 16:18:51
R W Run
10.67 KB
2026-03-11 16:18:51
R W Run
5.03 KB
2026-03-11 16:18:51
R W Run
33.92 KB
2026-03-11 16:18:51
R W Run
17.97 KB
2026-03-11 16:18:51
R W Run
876 By
2026-03-11 16:18:51
R W Run
620 By
2026-03-11 16:18:51
R W Run
13.15 KB
2026-03-11 16:18:51
R W Run
6.13 KB
2026-03-11 16:18:51
R W Run
6.1 KB
2026-03-11 16:18:51
R W Run
2.2 KB
2026-03-11 16:18:51
R W Run
3.2 KB
2026-03-11 16:18:51
R W Run
1.53 KB
2026-03-11 16:18:51
R W Run
10.88 KB
2026-03-11 16:18:51
R W Run
3 KB
2026-03-11 16:18:51
R W Run
5.64 KB
2026-03-11 16:18:51
R W Run
2.22 KB
2026-03-11 16:18:51
R W Run
5.96 KB
2026-03-11 16:18:51
R W Run
2.41 KB
2026-03-11 16:18:51
R W Run
24.77 KB
2026-03-11 16:18:51
R W Run
11.43 KB
2026-03-11 16:18:51
R W Run
54.94 KB
2026-03-11 16:18:51
R W Run
26.51 KB
2026-03-11 16:18:51
R W Run
109.37 KB
2026-03-11 16:18:51
R W Run
47.31 KB
2026-03-11 16:18:51
R W Run
17.91 KB
2026-03-11 16:18:51
R W Run
7.81 KB
2026-03-11 16:18:51
R W Run
2.25 KB
2026-03-11 16:18:51
R W Run
676 By
2026-03-11 16:18:51
R W Run
22.56 KB
2026-03-11 16:18:51
R W Run
12.31 KB
2026-03-11 16:18:51
R W Run
7.52 KB
2026-03-11 16:18:51
R W Run
1.49 KB
2026-03-11 16:18:51
R W Run
740 By
2026-03-11 16:18:51
R W Run
458 By
2026-03-11 16:18:51
R W Run
error_log
📄privacy-tools.js
1/**
2 * Interactions used by the User Privacy tools in WordPress.
3 *
4 * @output wp-admin/js/privacy-tools.js
5 */
6
7// Privacy request action handling.
8jQuery( function( $ ) {
9 var __ = wp.i18n.__,
10 copiedNoticeTimeout;
11
12 function setActionState( $action, state ) {
13 $action.children().addClass( 'hidden' );
14 $action.children( '.' + state ).removeClass( 'hidden' );
15 }
16
17 function clearResultsAfterRow( $requestRow ) {
18 $requestRow.removeClass( 'has-request-results' );
19
20 if ( $requestRow.next().hasClass( 'request-results' ) ) {
21 $requestRow.next().remove();
22 }
23 }
24
25 function appendResultsAfterRow( $requestRow, classes, summaryMessage, additionalMessages ) {
26 var itemList = '',
27 resultRowClasses = 'request-results';
28
29 clearResultsAfterRow( $requestRow );
30
31 if ( additionalMessages.length ) {
32 $.each( additionalMessages, function( index, value ) {
33 itemList = itemList + '<li>' + value + '</li>';
34 });
35 itemList = '<ul>' + itemList + '</ul>';
36 }
37
38 $requestRow.addClass( 'has-request-results' );
39
40 if ( $requestRow.hasClass( 'status-request-confirmed' ) ) {
41 resultRowClasses = resultRowClasses + ' status-request-confirmed';
42 }
43
44 if ( $requestRow.hasClass( 'status-request-failed' ) ) {
45 resultRowClasses = resultRowClasses + ' status-request-failed';
46 }
47
48 $requestRow.after( function() {
49 return '<tr class="' + resultRowClasses + '"><th colspan="5">' +
50 '<div class="notice inline notice-alt ' + classes + '" role="alert">' +
51 '<p>' + summaryMessage + '</p>' +
52 itemList +
53 '</div>' +
54 '</td>' +
55 '</tr>';
56 });
57 }
58
59 $( '.export-personal-data-handle' ).on( 'click', function( event ) {
60 var $this = $( this ),
61 $action = $this.parents( '.export-personal-data' ),
62 $requestRow = $this.parents( 'tr' ),
63 $progress = $requestRow.find( '.export-progress' ),
64 $rowActions = $this.parents( '.row-actions' ),
65 requestID = $action.data( 'request-id' ),
66 nonce = $action.data( 'nonce' ),
67 exportersCount = $action.data( 'exporters-count' ),
68 sendAsEmail = $action.data( 'send-as-email' ) ? true : false;
69
70 event.preventDefault();
71 event.stopPropagation();
72
73 $rowActions.addClass( 'processing' );
74
75 $action.trigger( 'blur' );
76 clearResultsAfterRow( $requestRow );
77 setExportProgress( 0 );
78
79 function onExportDoneSuccess( zipUrl ) {
80 var summaryMessage = __( 'This user&#8217;s personal data export link was sent.' );
81
82 if ( 'undefined' !== typeof zipUrl ) {
83 summaryMessage = __( 'This user&#8217;s personal data export file was downloaded.' );
84 }
85
86 setActionState( $action, 'export-personal-data-success' );
87
88 appendResultsAfterRow( $requestRow, 'notice-success', summaryMessage, [] );
89
90 if ( 'undefined' !== typeof zipUrl ) {
91 window.location = zipUrl;
92 } else if ( ! sendAsEmail ) {
93 onExportFailure( __( 'No personal data export file was generated.' ) );
94 }
95
96 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
97 }
98
99 function onExportFailure( errorMessage ) {
100 var summaryMessage = __( 'An error occurred while attempting to export personal data.' );
101
102 setActionState( $action, 'export-personal-data-failed' );
103
104 if ( errorMessage ) {
105 appendResultsAfterRow( $requestRow, 'notice-error', summaryMessage, [ errorMessage ] );
106 }
107
108 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
109 }
110
111 function setExportProgress( exporterIndex ) {
112 var progress = ( exportersCount > 0 ? exporterIndex / exportersCount : 0 ),
113 progressString = Math.round( progress * 100 ).toString() + '%';
114
115 $progress.html( progressString );
116 }
117
118 function doNextExport( exporterIndex, pageIndex ) {
119 $.ajax(
120 {
121 url: window.ajaxurl,
122 data: {
123 action: 'wp-privacy-export-personal-data',
124 exporter: exporterIndex,
125 id: requestID,
126 page: pageIndex,
127 security: nonce,
128 sendAsEmail: sendAsEmail
129 },
130 method: 'post'
131 }
132 ).done( function( response ) {
133 var responseData = response.data;
134
135 if ( ! response.success ) {
136 // e.g. invalid request ID.
137 setTimeout( function() { onExportFailure( response.data ); }, 500 );
138 return;
139 }
140
141 if ( ! responseData.done ) {
142 setTimeout( doNextExport( exporterIndex, pageIndex + 1 ) );
143 } else {
144 setExportProgress( exporterIndex );
145 if ( exporterIndex < exportersCount ) {
146 setTimeout( doNextExport( exporterIndex + 1, 1 ) );
147 } else {
148 setTimeout( function() { onExportDoneSuccess( responseData.url ); }, 500 );
149 }
150 }
151 }).fail( function( jqxhr, textStatus, error ) {
152 // e.g. Nonce failure.
153 setTimeout( function() { onExportFailure( error ); }, 500 );
154 });
155 }
156
157 // And now, let's begin.
158 setActionState( $action, 'export-personal-data-processing' );
159 doNextExport( 1, 1 );
160 });
161
162 $( '.remove-personal-data-handle' ).on( 'click', function( event ) {
163 var $this = $( this ),
164 $action = $this.parents( '.remove-personal-data' ),
165 $requestRow = $this.parents( 'tr' ),
166 $progress = $requestRow.find( '.erasure-progress' ),
167 $rowActions = $this.parents( '.row-actions' ),
168 requestID = $action.data( 'request-id' ),
169 nonce = $action.data( 'nonce' ),
170 erasersCount = $action.data( 'erasers-count' ),
171 hasRemoved = false,
172 hasRetained = false,
173 messages = [];
174
175 event.preventDefault();
176 event.stopPropagation();
177
178 $rowActions.addClass( 'processing' );
179
180 $action.trigger( 'blur' );
181 clearResultsAfterRow( $requestRow );
182 setErasureProgress( 0 );
183
184 function onErasureDoneSuccess() {
185 var summaryMessage = __( 'No personal data was found for this user.' ),
186 classes = 'notice-success';
187
188 setActionState( $action, 'remove-personal-data-success' );
189
190 if ( false === hasRemoved ) {
191 if ( false === hasRetained ) {
192 summaryMessage = __( 'No personal data was found for this user.' );
193 } else {
194 summaryMessage = __( 'Personal data was found for this user but was not erased.' );
195 classes = 'notice-warning';
196 }
197 } else {
198 if ( false === hasRetained ) {
199 summaryMessage = __( 'All of the personal data found for this user was erased.' );
200 } else {
201 summaryMessage = __( 'Personal data was found for this user but some of the personal data found was not erased.' );
202 classes = 'notice-warning';
203 }
204 }
205 appendResultsAfterRow( $requestRow, classes, summaryMessage, messages );
206
207 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
208 }
209
210 function onErasureFailure() {
211 var summaryMessage = __( 'An error occurred while attempting to find and erase personal data.' );
212
213 setActionState( $action, 'remove-personal-data-failed' );
214
215 appendResultsAfterRow( $requestRow, 'notice-error', summaryMessage, [] );
216
217 setTimeout( function() { $rowActions.removeClass( 'processing' ); }, 500 );
218 }
219
220 function setErasureProgress( eraserIndex ) {
221 var progress = ( erasersCount > 0 ? eraserIndex / erasersCount : 0 ),
222 progressString = Math.round( progress * 100 ).toString() + '%';
223
224 $progress.html( progressString );
225 }
226
227 function doNextErasure( eraserIndex, pageIndex ) {
228 $.ajax({
229 url: window.ajaxurl,
230 data: {
231 action: 'wp-privacy-erase-personal-data',
232 eraser: eraserIndex,
233 id: requestID,
234 page: pageIndex,
235 security: nonce
236 },
237 method: 'post'
238 }).done( function( response ) {
239 var responseData = response.data;
240
241 if ( ! response.success ) {
242 setTimeout( function() { onErasureFailure(); }, 500 );
243 return;
244 }
245 if ( responseData.items_removed ) {
246 hasRemoved = hasRemoved || responseData.items_removed;
247 }
248 if ( responseData.items_retained ) {
249 hasRetained = hasRetained || responseData.items_retained;
250 }
251 if ( responseData.messages ) {
252 messages = messages.concat( responseData.messages );
253 }
254 if ( ! responseData.done ) {
255 setTimeout( doNextErasure( eraserIndex, pageIndex + 1 ) );
256 } else {
257 setErasureProgress( eraserIndex );
258 if ( eraserIndex < erasersCount ) {
259 setTimeout( doNextErasure( eraserIndex + 1, 1 ) );
260 } else {
261 setTimeout( function() { onErasureDoneSuccess(); }, 500 );
262 }
263 }
264 }).fail( function() {
265 setTimeout( function() { onErasureFailure(); }, 500 );
266 });
267 }
268
269 // And now, let's begin.
270 setActionState( $action, 'remove-personal-data-processing' );
271
272 doNextErasure( 1, 1 );
273 });
274
275 // Privacy Policy page, copy action.
276 $( document ).on( 'click', function( event ) {
277 var $parent,
278 range,
279 $target = $( event.target ),
280 copiedNotice = $target.siblings( '.success' );
281
282 clearTimeout( copiedNoticeTimeout );
283
284 if ( $target.is( 'button.privacy-text-copy' ) ) {
285 $parent = $target.closest( '.privacy-settings-accordion-panel' );
286
287 if ( $parent.length ) {
288 try {
289 var documentPosition = document.documentElement.scrollTop,
290 bodyPosition = document.body.scrollTop;
291
292 // Setup copy.
293 window.getSelection().removeAllRanges();
294
295 // Hide tutorial content to remove from copied content.
296 range = document.createRange();
297 $parent.addClass( 'hide-privacy-policy-tutorial' );
298
299 // Copy action.
300 range.selectNodeContents( $parent[0] );
301 window.getSelection().addRange( range );
302 document.execCommand( 'copy' );
303
304 // Reset section.
305 $parent.removeClass( 'hide-privacy-policy-tutorial' );
306 window.getSelection().removeAllRanges();
307
308 // Return scroll position - see #49540.
309 if ( documentPosition > 0 && documentPosition !== document.documentElement.scrollTop ) {
310 document.documentElement.scrollTop = documentPosition;
311 } else if ( bodyPosition > 0 && bodyPosition !== document.body.scrollTop ) {
312 document.body.scrollTop = bodyPosition;
313 }
314
315 // Display and speak notice to indicate action complete.
316 copiedNotice.addClass( 'visible' );
317 wp.a11y.speak( __( 'The suggested policy text has been copied to your clipboard.' ) );
318
319 // Delay notice dismissal.
320 copiedNoticeTimeout = setTimeout( function() {
321 copiedNotice.removeClass( 'visible' );
322 }, 3000 );
323 } catch ( er ) {}
324 }
325 }
326 });
327
328 // Label handling to focus the create page button on Privacy settings page.
329 $( 'body.options-privacy-php label[for=create-page]' ).on( 'click', function( e ) {
330 e.preventDefault();
331 $( 'input#create-page' ).trigger( 'focus' );
332 } );
333
334 // Accordion handling in various new Privacy settings pages.
335 $( '.privacy-settings-accordion' ).on( 'click', '.privacy-settings-accordion-trigger', function() {
336 var isExpanded = ( 'true' === $( this ).attr( 'aria-expanded' ) );
337
338 if ( isExpanded ) {
339 $( this ).attr( 'aria-expanded', 'false' );
340 $( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', true );
341 } else {
342 $( this ).attr( 'aria-expanded', 'true' );
343 $( '#' + $( this ).attr( 'aria-controls' ) ).attr( 'hidden', false );
344 }
345 } );
346});
347