admin.js 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355
  1. /**
  2. * Admin JavaScript for Studiou WC Product Category Manager
  3. */
  4. (function($) {
  5. 'use strict';
  6. // Safe init wrapper - prevents one form's error from breaking others
  7. function safeInit(name, selector, initFn) {
  8. try {
  9. if ($(selector).length) {
  10. console.log('STUDIOU WC: ' + name + ' found, initializing');
  11. initFn();
  12. }
  13. } catch (e) {
  14. console.error('STUDIOU WC: Error initializing ' + name + ':', e);
  15. }
  16. }
  17. // Initialize admin scripts
  18. $(document).ready(function() {
  19. // Debug: Log that script is loaded
  20. console.log('STUDIOU WC: Admin script loaded v1.5.1');
  21. if (typeof studiouWcpcm === 'undefined') {
  22. console.error('STUDIOU WC: studiouWcpcm object is NOT defined - AJAX will not work');
  23. return;
  24. }
  25. console.log('STUDIOU WC: studiouWcpcm object:', studiouWcpcm);
  26. safeInit('Import form', '#studiou-wcpcm-import-form', initImportForm);
  27. safeInit('Export form', '#studiou-wcpcm-export-form', initExportForm);
  28. safeInit('Move form', '#studiou-wcpcm-move-form', initMoveForm);
  29. safeInit('Batch description form', '#studiou-wcpcm-batch-description-form', initBatchDescriptionForm);
  30. safeInit('Delete products form', '#studiou-wcpcm-delete-products-form', initDeleteProductsForm);
  31. safeInit('Clear media form', '#studiou-wcpcm-clear-media-form', initClearMediaForm);
  32. safeInit('Remove unassigned media form', '#studiou-wcpcm-remove-unassigned-media-form', initRemoveUnassignedMediaForm);
  33. safeInit('Sample download', '#studiou-wcpcm-download-sample', initSampleDownload);
  34. safeInit('Product import form', '#studiou-wcpcm-product-import-form', initProductImportForm);
  35. safeInit('Product export form', '#studiou-wcpcm-product-export-form', initProductExportForm);
  36. });
  37. /**
  38. * Initialize import form
  39. */
  40. function initImportForm() {
  41. $('#studiou-wcpcm-import-form').on('submit', function(e) {
  42. e.preventDefault();
  43. // Show spinner
  44. var $submitBtn = $(this).find('#studiou-wcpcm-import-button');
  45. var $spinner = $(this).find('.spinner');
  46. $submitBtn.prop('disabled', true);
  47. $spinner.css('visibility', 'visible');
  48. // Clear previous notices
  49. $('.studiou-wcpcm-notice-area').empty();
  50. // Create form data
  51. var formData = new FormData(this);
  52. formData.append('action', 'studiou_wcpcm_import');
  53. formData.append('nonce', studiouWcpcm.nonce);
  54. // Send AJAX request
  55. $.ajax({
  56. url: studiouWcpcm.ajaxUrl,
  57. type: 'POST',
  58. data: formData,
  59. processData: false,
  60. contentType: false,
  61. success: function(response) {
  62. if (response.success) {
  63. showNotice('success', studiouWcpcm.i18n.importSuccess);
  64. // Show results
  65. $('#studiou-wcpcm-import-results').text(response.data.message);
  66. $('.studiou-wcpcm-import-results').show();
  67. } else {
  68. showNotice('error', response.data.message);
  69. }
  70. },
  71. error: function() {
  72. showNotice('error', studiouWcpcm.i18n.importError);
  73. },
  74. complete: function() {
  75. // Hide spinner
  76. $submitBtn.prop('disabled', false);
  77. $spinner.css('visibility', 'hidden');
  78. }
  79. });
  80. });
  81. }
  82. /**
  83. * Initialize export form
  84. */
  85. function initExportForm() {
  86. $('#studiou-wcpcm-export-form').on('submit', function(e) {
  87. e.preventDefault();
  88. // Show spinner
  89. var $submitBtn = $(this).find('#studiou-wcpcm-export-button');
  90. var $spinner = $(this).find('.spinner');
  91. $submitBtn.prop('disabled', true);
  92. $spinner.css('visibility', 'visible');
  93. // Clear previous notices
  94. $('.studiou-wcpcm-notice-area').empty();
  95. // Send AJAX request
  96. $.ajax({
  97. url: studiouWcpcm.ajaxUrl,
  98. type: 'POST',
  99. data: {
  100. action: 'studiou_wcpcm_export',
  101. nonce: studiouWcpcm.nonce
  102. },
  103. success: function(response) {
  104. if (response.success) {
  105. showNotice('success', studiouWcpcm.i18n.exportSuccess);
  106. // Show download link
  107. $('#studiou-wcpcm-export-message').text(response.data.message);
  108. $('#studiou-wcpcm-download-export').attr('href', response.data.download_url);
  109. $('.studiou-wcpcm-export-results').show();
  110. } else {
  111. showNotice('error', response.data.message);
  112. }
  113. },
  114. error: function() {
  115. showNotice('error', studiouWcpcm.i18n.exportError);
  116. },
  117. complete: function() {
  118. // Hide spinner
  119. $submitBtn.prop('disabled', false);
  120. $spinner.css('visibility', 'hidden');
  121. }
  122. });
  123. });
  124. }
  125. /**
  126. * Initialize move products form
  127. */
  128. function initMoveForm() {
  129. console.log('STUDIOU WC: Initializing move form handlers');
  130. // Add debug button click handler first
  131. $('#studiou-wcpcm-move-button').on('click', function(e) {
  132. console.log('STUDIOU WC: Move button clicked directly');
  133. });
  134. $('#studiou-wcpcm-move-form').on('submit', function(e) {
  135. e.preventDefault();
  136. // Debug: Log form submission
  137. console.log('STUDIOU WC: Move form submitted');
  138. // Validate that different categories are selected
  139. var sourceCategory = $('#source_category').val();
  140. var targetCategory = $('#target_category').val();
  141. console.log('STUDIOU WC: Source category:', sourceCategory, 'Target category:', targetCategory);
  142. if (!sourceCategory || !targetCategory) {
  143. console.log('STUDIOU WC: Missing category selection');
  144. showNotice('error', 'Please select both source and target categories');
  145. return;
  146. }
  147. if (sourceCategory === targetCategory) {
  148. console.log('STUDIOU WC: Same category selected');
  149. showNotice('error', studiouWcpcm.i18n.selectDifferentCategories);
  150. return;
  151. }
  152. // Show spinner
  153. var $submitBtn = $(this).find('#studiou-wcpcm-move-button');
  154. var $spinner = $(this).find('.spinner');
  155. $submitBtn.prop('disabled', true);
  156. $spinner.css('visibility', 'visible');
  157. // Clear previous notices
  158. $('.studiou-wcpcm-notice-area').empty();
  159. // Debug: Log AJAX request details
  160. console.log('STUDIOU WC: Sending AJAX request to:', studiouWcpcm.ajaxUrl);
  161. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  162. // Send AJAX request
  163. $.ajax({
  164. url: studiouWcpcm.ajaxUrl,
  165. type: 'POST',
  166. data: {
  167. action: 'studiou_wcpcm_move_products',
  168. source_category: sourceCategory,
  169. target_category: targetCategory,
  170. nonce: studiouWcpcm.nonce
  171. },
  172. success: function(response) {
  173. console.log('STUDIOU WC: AJAX response:', response);
  174. if (response.success) {
  175. showNotice('success', studiouWcpcm.i18n.moveSuccess);
  176. // Show results
  177. $('#studiou-wcpcm-move-message').html('<p>' + response.data.message + '</p>');
  178. $('.studiou-wcpcm-move-results').show();
  179. // Refresh the page to update category counts
  180. setTimeout(function() {
  181. location.reload();
  182. }, 3000);
  183. } else {
  184. showNotice('error', response.data.message);
  185. }
  186. },
  187. error: function(xhr, status, error) {
  188. console.error('STUDIOU WC: AJAX error:', status, error);
  189. console.error('STUDIOU WC: Response text:', xhr.responseText);
  190. showNotice('error', studiouWcpcm.i18n.moveError + ': ' + error);
  191. },
  192. complete: function() {
  193. // Hide spinner
  194. $submitBtn.prop('disabled', false);
  195. $spinner.css('visibility', 'hidden');
  196. }
  197. });
  198. });
  199. }
  200. /**
  201. * Initialize batch description form
  202. */
  203. function initBatchDescriptionForm() {
  204. console.log('STUDIOU WC: Initializing batch description form handlers');
  205. // Check all button handler
  206. $('#studiou-wcpcm-check-all').on('click', function(e) {
  207. e.preventDefault();
  208. console.log('STUDIOU WC: Check all button clicked');
  209. $('#categories_list input[type="checkbox"]').prop('checked', true);
  210. });
  211. // Uncheck all button handler
  212. $('#studiou-wcpcm-uncheck-all').on('click', function(e) {
  213. e.preventDefault();
  214. console.log('STUDIOU WC: Uncheck all button clicked');
  215. $('#categories_list input[type="checkbox"]').prop('checked', false);
  216. });
  217. // Form submit handler
  218. $('#studiou-wcpcm-batch-description-form').on('submit', function(e) {
  219. e.preventDefault();
  220. console.log('STUDIOU WC: Batch description form submitted');
  221. // Get selected categories
  222. var selectedCategories = [];
  223. $('#categories_list input[type="checkbox"]:checked').each(function() {
  224. selectedCategories.push($(this).val());
  225. });
  226. var description = $('#category_description').val();
  227. console.log('STUDIOU WC: Selected categories:', selectedCategories);
  228. console.log('STUDIOU WC: Description:', description);
  229. // Validate input
  230. if (selectedCategories.length === 0) {
  231. console.log('STUDIOU WC: No categories selected');
  232. showNotice('error', 'Please select at least one category');
  233. return;
  234. }
  235. // Show spinner
  236. var $submitBtn = $(this).find('#studiou-wcpcm-batch-description-button');
  237. var $spinner = $(this).find('.spinner');
  238. $submitBtn.prop('disabled', true);
  239. $spinner.css('visibility', 'visible');
  240. // Clear previous notices
  241. $('.studiou-wcpcm-notice-area').empty();
  242. // Debug: Log AJAX request details
  243. console.log('STUDIOU WC: Sending batch description AJAX request to:', studiouWcpcm.ajaxUrl);
  244. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  245. // Send AJAX request
  246. $.ajax({
  247. url: studiouWcpcm.ajaxUrl,
  248. type: 'POST',
  249. data: {
  250. action: 'studiou_wcpcm_batch_description',
  251. selected_categories: selectedCategories,
  252. description: description,
  253. nonce: studiouWcpcm.nonce
  254. },
  255. success: function(response) {
  256. console.log('STUDIOU WC: Batch description AJAX response:', response);
  257. if (response.success) {
  258. showNotice('success', studiouWcpcm.i18n.batchDescriptionSuccess || 'Batch description operation successful');
  259. // Show results
  260. $('#studiou-wcpcm-batch-description-message').html('<p>' + response.data.message + '</p>');
  261. $('.studiou-wcpcm-batch-description-results').show();
  262. } else {
  263. showNotice('error', response.data.message);
  264. }
  265. },
  266. error: function(xhr, status, error) {
  267. console.error('STUDIOU WC: Batch description AJAX error:', status, error);
  268. console.error('STUDIOU WC: Response text:', xhr.responseText);
  269. showNotice('error', (studiouWcpcm.i18n.batchDescriptionError || 'Batch description operation error') + ': ' + error);
  270. },
  271. complete: function() {
  272. // Hide spinner
  273. $submitBtn.prop('disabled', false);
  274. $spinner.css('visibility', 'hidden');
  275. }
  276. });
  277. });
  278. }
  279. /**
  280. * Initialize sample CSV download
  281. */
  282. function initSampleDownload() {
  283. $('#studiou-wcpcm-download-sample').on('click', function(e) {
  284. e.preventDefault();
  285. // Sample CSV content
  286. var csvContent = 'name,url-name,parent-name,description,display-type,visibility,protected-passwords,operation\n' +
  287. '"Clothing","clothing","","Top quality clothing","default","public","","A"\n' +
  288. '"Men","men","Clothing","Men\'s clothing","products","public","","A"\n' +
  289. '"Women","women","Clothing","Women\'s clothing","products","protected","password123","A"\n' +
  290. '"Kids","kids","Clothing","Kids clothing","products","public","","U"\n' +
  291. '"Accessories","accessories","","All accessories","default","public","","D"';
  292. // Create download link
  293. var blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  294. var url = URL.createObjectURL(blob);
  295. var link = document.createElement('a');
  296. link.setAttribute('href', url);
  297. link.setAttribute('download', 'sample-product-categories.csv');
  298. link.style.visibility = 'hidden';
  299. document.body.appendChild(link);
  300. link.click();
  301. document.body.removeChild(link);
  302. });
  303. }
  304. /**
  305. * Initialize delete products form
  306. */
  307. function initDeleteProductsForm() {
  308. console.log('STUDIOU WC: Initializing delete products form handlers');
  309. console.log('STUDIOU WC: Form element:', $('#studiou-wcpcm-delete-products-form'));
  310. console.log('STUDIOU WC: Check all button:', $('#studiou-wcpcm-delete-check-all'));
  311. console.log('STUDIOU WC: Delete button:', $('#studiou-wcpcm-delete-products-button'));
  312. // Check all button handler
  313. $('#studiou-wcpcm-delete-check-all').on('click', function(e) {
  314. e.preventDefault();
  315. console.log('STUDIOU WC: Delete check all button clicked');
  316. $('#delete_categories_list input[type="checkbox"]').prop('checked', true);
  317. });
  318. // Uncheck all button handler
  319. $('#studiou-wcpcm-delete-uncheck-all').on('click', function(e) {
  320. e.preventDefault();
  321. console.log('STUDIOU WC: Delete uncheck all button clicked');
  322. $('#delete_categories_list input[type="checkbox"]').prop('checked', false);
  323. });
  324. // Form submit handler
  325. $('#studiou-wcpcm-delete-products-form').on('submit', function(e) {
  326. e.preventDefault();
  327. console.log('STUDIOU WC: Delete products form submitted');
  328. // Get selected categories
  329. var selectedCategories = [];
  330. $('#delete_categories_list input[type="checkbox"]:checked').each(function() {
  331. selectedCategories.push($(this).val());
  332. });
  333. console.log('STUDIOU WC: Selected categories:', selectedCategories);
  334. // Validate input
  335. if (selectedCategories.length === 0) {
  336. console.log('STUDIOU WC: No categories selected');
  337. showNotice('error', studiouWcpcm.i18n.selectAtLeastOneCategory || 'Please select at least one category');
  338. return;
  339. }
  340. // Confirm deletion
  341. if (!confirm(studiouWcpcm.i18n.confirmDelete || 'Are you sure you want to permanently delete ALL products in the selected categories? This action cannot be undone!')) {
  342. console.log('STUDIOU WC: User cancelled deletion');
  343. return;
  344. }
  345. // Show spinner
  346. var $submitBtn = $(this).find('#studiou-wcpcm-delete-products-button');
  347. var $spinner = $(this).find('.spinner');
  348. $submitBtn.prop('disabled', true);
  349. $spinner.css('visibility', 'visible');
  350. // Clear previous notices
  351. $('.studiou-wcpcm-notice-area').empty();
  352. // Hide results, show progress
  353. $('.studiou-wcpcm-delete-results').hide();
  354. $('.studiou-wcpcm-delete-progress').show();
  355. $('#studiou-wcpcm-delete-progress-text').text('Initializing...');
  356. updateProgressBar(0);
  357. // Debug: Log AJAX request details
  358. console.log('STUDIOU WC: Sending delete products AJAX request to:', studiouWcpcm.ajaxUrl);
  359. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  360. // Send AJAX request to get product IDs
  361. $.ajax({
  362. url: studiouWcpcm.ajaxUrl,
  363. type: 'POST',
  364. data: {
  365. action: 'studiou_wcpcm_delete_products',
  366. delete_categories: selectedCategories,
  367. nonce: studiouWcpcm.nonce
  368. },
  369. success: function(response) {
  370. console.log('STUDIOU WC: Delete products AJAX response:', response);
  371. if (response.success) {
  372. var productIds = response.data.product_ids;
  373. var totalCount = response.data.total_count;
  374. console.log('STUDIOU WC: Total products to delete:', totalCount);
  375. if (totalCount === 0) {
  376. showNotice('success', studiouWcpcm.i18n.noProductsFound || 'No products found in selected categories');
  377. $('.studiou-wcpcm-delete-progress').hide();
  378. $submitBtn.prop('disabled', false);
  379. $spinner.css('visibility', 'hidden');
  380. return;
  381. }
  382. // Process products in batches
  383. processDeletionBatches(productIds, totalCount, $submitBtn, $spinner);
  384. } else {
  385. showNotice('error', response.data.message);
  386. $('.studiou-wcpcm-delete-progress').hide();
  387. $submitBtn.prop('disabled', false);
  388. $spinner.css('visibility', 'hidden');
  389. }
  390. },
  391. error: function(xhr, status, error) {
  392. console.error('STUDIOU WC: Delete products AJAX error:', status, error);
  393. console.error('STUDIOU WC: Response text:', xhr.responseText);
  394. showNotice('error', (studiouWcpcm.i18n.deleteError || 'Delete products operation error') + ': ' + error);
  395. $('.studiou-wcpcm-delete-progress').hide();
  396. $submitBtn.prop('disabled', false);
  397. $spinner.css('visibility', 'hidden');
  398. }
  399. });
  400. });
  401. }
  402. /**
  403. * Process deletion in batches
  404. */
  405. function processDeletionBatches(productIds, totalCount, $submitBtn, $spinner) {
  406. var batchSize = 10; // Process 10 products at a time
  407. var batches = [];
  408. var totalDeleted = 0;
  409. var totalFailed = 0;
  410. var failedProducts = [];
  411. // Split products into batches
  412. for (var i = 0; i < productIds.length; i += batchSize) {
  413. batches.push(productIds.slice(i, i + batchSize));
  414. }
  415. console.log('STUDIOU WC: Processing ' + batches.length + ' batches of products');
  416. var currentBatch = 0;
  417. function processBatch() {
  418. if (currentBatch >= batches.length) {
  419. // All batches completed
  420. console.log('STUDIOU WC: All batches completed');
  421. onDeletionComplete(totalDeleted, totalFailed, failedProducts, $submitBtn, $spinner);
  422. return;
  423. }
  424. var batch = batches[currentBatch];
  425. var progress = Math.round((currentBatch / batches.length) * 100);
  426. $('#studiou-wcpcm-delete-progress-text').text(
  427. 'Deleting products... ' + (currentBatch * batchSize) + ' of ' + totalCount + ' processed'
  428. );
  429. updateProgressBar(progress);
  430. // Send batch delete request
  431. $.ajax({
  432. url: studiouWcpcm.ajaxUrl,
  433. type: 'POST',
  434. data: {
  435. action: 'studiou_wcpcm_delete_products_batch',
  436. product_ids: batch,
  437. nonce: studiouWcpcm.nonce
  438. },
  439. success: function(response) {
  440. if (response.success) {
  441. totalDeleted += response.data.deleted_count;
  442. totalFailed += response.data.failed_count;
  443. failedProducts = failedProducts.concat(response.data.failed_products);
  444. console.log('STUDIOU WC: Batch ' + currentBatch + ' completed - Deleted: ' +
  445. response.data.deleted_count + ', Failed: ' + response.data.failed_count);
  446. // Process next batch
  447. currentBatch++;
  448. processBatch();
  449. } else {
  450. showNotice('error', response.data.message);
  451. $('.studiou-wcpcm-delete-progress').hide();
  452. $submitBtn.prop('disabled', false);
  453. $spinner.css('visibility', 'hidden');
  454. }
  455. },
  456. error: function(xhr, status, error) {
  457. console.error('STUDIOU WC: Batch delete AJAX error:', status, error);
  458. showNotice('error', 'Error deleting batch: ' + error);
  459. $('.studiou-wcpcm-delete-progress').hide();
  460. $submitBtn.prop('disabled', false);
  461. $spinner.css('visibility', 'hidden');
  462. }
  463. });
  464. }
  465. // Start processing batches
  466. processBatch();
  467. }
  468. /**
  469. * Handle deletion completion
  470. */
  471. function onDeletionComplete(totalDeleted, totalFailed, failedProducts, $submitBtn, $spinner) {
  472. // Update progress bar to 100%
  473. updateProgressBar(100);
  474. $('#studiou-wcpcm-delete-progress-text').text('Deletion complete!');
  475. // Show results
  476. var message = '<p><strong>Deletion Summary:</strong></p>';
  477. message += '<ul>';
  478. message += '<li>Total products deleted: ' + totalDeleted + '</li>';
  479. if (totalFailed > 0) {
  480. message += '<li>Failed to delete: ' + totalFailed + '</li>';
  481. if (failedProducts.length > 0) {
  482. message += '<li>Failed product IDs: ' + failedProducts.join(', ') + '</li>';
  483. }
  484. }
  485. message += '</ul>';
  486. $('#studiou-wcpcm-delete-message').html(message);
  487. $('.studiou-wcpcm-delete-results').show();
  488. // Hide progress after a delay
  489. setTimeout(function() {
  490. $('.studiou-wcpcm-delete-progress').fadeOut();
  491. }, 2000);
  492. if (totalDeleted > 0) {
  493. showNotice('success', (studiouWcpcm.i18n.deleteSuccess || 'Successfully deleted') + ' ' + totalDeleted + ' products');
  494. // Reload page after 3 seconds
  495. setTimeout(function() {
  496. location.reload();
  497. }, 3000);
  498. } else {
  499. showNotice('error', studiouWcpcm.i18n.deleteError || 'Failed to delete any products');
  500. }
  501. $submitBtn.prop('disabled', false);
  502. $spinner.css('visibility', 'hidden');
  503. }
  504. /**
  505. * Update progress bar
  506. */
  507. function updateProgressBar(percentage) {
  508. $('#studiou-wcpcm-delete-progress-bar').css('width', percentage + '%');
  509. $('#studiou-wcpcm-delete-progress-bar').attr('data-progress', percentage + '%');
  510. }
  511. /**
  512. * Initialize clear media categories form
  513. */
  514. function initClearMediaForm() {
  515. console.log('STUDIOU WC: Initializing clear media form handlers');
  516. // Check all button handler
  517. $('#studiou-wcpcm-clear-media-check-all').on('click', function(e) {
  518. e.preventDefault();
  519. console.log('STUDIOU WC: Clear media check all button clicked');
  520. $('#clear_media_categories_list input[type="checkbox"]').prop('checked', true);
  521. });
  522. // Uncheck all button handler
  523. $('#studiou-wcpcm-clear-media-uncheck-all').on('click', function(e) {
  524. e.preventDefault();
  525. console.log('STUDIOU WC: Clear media uncheck all button clicked');
  526. $('#clear_media_categories_list input[type="checkbox"]').prop('checked', false);
  527. });
  528. // Form submit handler
  529. $('#studiou-wcpcm-clear-media-form').on('submit', function(e) {
  530. e.preventDefault();
  531. console.log('STUDIOU WC: Clear media form submitted');
  532. // Get selected categories
  533. var selectedCategories = [];
  534. $('#clear_media_categories_list input[type="checkbox"]:checked').each(function() {
  535. selectedCategories.push($(this).val());
  536. });
  537. console.log('STUDIOU WC: Selected media categories:', selectedCategories);
  538. // Validate input
  539. if (selectedCategories.length === 0) {
  540. console.log('STUDIOU WC: No media categories selected');
  541. showNotice('error', studiouWcpcm.i18n.selectAtLeastOneCategory || 'Please select at least one category');
  542. return;
  543. }
  544. // Confirm deletion
  545. if (!confirm(studiouWcpcm.i18n.confirmClearMedia || 'Are you sure you want to permanently delete ALL media files in the selected media categories? This action cannot be undone!')) {
  546. console.log('STUDIOU WC: User cancelled clear media');
  547. return;
  548. }
  549. // Show spinner
  550. var $submitBtn = $(this).find('#studiou-wcpcm-clear-media-button');
  551. var $spinner = $(this).find('.spinner');
  552. $submitBtn.prop('disabled', true);
  553. $spinner.css('visibility', 'visible');
  554. // Clear previous notices
  555. $('.studiou-wcpcm-notice-area').empty();
  556. // Hide results, show progress
  557. $('.studiou-wcpcm-clear-media-results').hide();
  558. $('.studiou-wcpcm-clear-media-progress').show();
  559. $('#studiou-wcpcm-clear-media-progress-text').text('Initializing...');
  560. updateClearMediaProgressBar(0);
  561. // Send AJAX request to get media IDs
  562. $.ajax({
  563. url: studiouWcpcm.ajaxUrl,
  564. type: 'POST',
  565. data: {
  566. action: 'studiou_wcpcm_clear_media',
  567. media_categories: selectedCategories,
  568. nonce: studiouWcpcm.nonce
  569. },
  570. success: function(response) {
  571. console.log('STUDIOU WC: Clear media AJAX response:', response);
  572. if (response.success) {
  573. var mediaIds = response.data.media_ids;
  574. var totalCount = response.data.total_count;
  575. console.log('STUDIOU WC: Total media files to delete:', totalCount);
  576. if (totalCount === 0) {
  577. showNotice('success', studiouWcpcm.i18n.noMediaFound || 'No media files found in selected categories');
  578. $('.studiou-wcpcm-clear-media-progress').hide();
  579. $submitBtn.prop('disabled', false);
  580. $spinner.css('visibility', 'hidden');
  581. return;
  582. }
  583. // Process media in batches
  584. processMediaDeletionBatches(mediaIds, totalCount, $submitBtn, $spinner);
  585. } else {
  586. showNotice('error', response.data.message);
  587. $('.studiou-wcpcm-clear-media-progress').hide();
  588. $submitBtn.prop('disabled', false);
  589. $spinner.css('visibility', 'hidden');
  590. }
  591. },
  592. error: function(xhr, status, error) {
  593. console.error('STUDIOU WC: Clear media AJAX error:', status, error);
  594. console.error('STUDIOU WC: Response text:', xhr.responseText);
  595. showNotice('error', (studiouWcpcm.i18n.clearMediaError || 'Clear media operation error') + ': ' + error);
  596. $('.studiou-wcpcm-clear-media-progress').hide();
  597. $submitBtn.prop('disabled', false);
  598. $spinner.css('visibility', 'hidden');
  599. }
  600. });
  601. });
  602. }
  603. /**
  604. * Process media deletion in batches
  605. */
  606. function processMediaDeletionBatches(mediaIds, totalCount, $submitBtn, $spinner) {
  607. var batchSize = 10;
  608. var batches = [];
  609. var totalDeleted = 0;
  610. var totalFailed = 0;
  611. var failedMedia = [];
  612. // Split media into batches
  613. for (var i = 0; i < mediaIds.length; i += batchSize) {
  614. batches.push(mediaIds.slice(i, i + batchSize));
  615. }
  616. console.log('STUDIOU WC: Processing ' + batches.length + ' batches of media files');
  617. var currentBatch = 0;
  618. function processBatch() {
  619. if (currentBatch >= batches.length) {
  620. console.log('STUDIOU WC: All media batches completed');
  621. onMediaDeletionComplete(totalDeleted, totalFailed, failedMedia, $submitBtn, $spinner);
  622. return;
  623. }
  624. var batch = batches[currentBatch];
  625. var progress = Math.round((currentBatch / batches.length) * 100);
  626. $('#studiou-wcpcm-clear-media-progress-text').text(
  627. 'Deleting media files... ' + (currentBatch * batchSize) + ' of ' + totalCount + ' processed'
  628. );
  629. updateClearMediaProgressBar(progress);
  630. $.ajax({
  631. url: studiouWcpcm.ajaxUrl,
  632. type: 'POST',
  633. data: {
  634. action: 'studiou_wcpcm_clear_media_batch',
  635. media_ids: batch,
  636. nonce: studiouWcpcm.nonce
  637. },
  638. success: function(response) {
  639. if (response.success) {
  640. totalDeleted += response.data.deleted_count;
  641. totalFailed += response.data.failed_count;
  642. failedMedia = failedMedia.concat(response.data.failed_media);
  643. console.log('STUDIOU WC: Media batch ' + currentBatch + ' completed - Deleted: ' +
  644. response.data.deleted_count + ', Failed: ' + response.data.failed_count);
  645. currentBatch++;
  646. processBatch();
  647. } else {
  648. showNotice('error', response.data.message);
  649. $('.studiou-wcpcm-clear-media-progress').hide();
  650. $submitBtn.prop('disabled', false);
  651. $spinner.css('visibility', 'hidden');
  652. }
  653. },
  654. error: function(xhr, status, error) {
  655. console.error('STUDIOU WC: Media batch delete AJAX error:', status, error);
  656. showNotice('error', 'Error deleting media batch: ' + error);
  657. $('.studiou-wcpcm-clear-media-progress').hide();
  658. $submitBtn.prop('disabled', false);
  659. $spinner.css('visibility', 'hidden');
  660. }
  661. });
  662. }
  663. processBatch();
  664. }
  665. /**
  666. * Handle media deletion completion
  667. */
  668. function onMediaDeletionComplete(totalDeleted, totalFailed, failedMedia, $submitBtn, $spinner) {
  669. updateClearMediaProgressBar(100);
  670. $('#studiou-wcpcm-clear-media-progress-text').text('Deletion complete!');
  671. var message = '<p><strong>Deletion Summary:</strong></p>';
  672. message += '<ul>';
  673. message += '<li>Total media files deleted: ' + totalDeleted + '</li>';
  674. if (totalFailed > 0) {
  675. message += '<li>Failed to delete: ' + totalFailed + '</li>';
  676. if (failedMedia.length > 0) {
  677. message += '<li>Failed media IDs: ' + failedMedia.join(', ') + '</li>';
  678. }
  679. }
  680. message += '</ul>';
  681. $('#studiou-wcpcm-clear-media-message').html(message);
  682. $('.studiou-wcpcm-clear-media-results').show();
  683. setTimeout(function() {
  684. $('.studiou-wcpcm-clear-media-progress').fadeOut();
  685. }, 2000);
  686. if (totalDeleted > 0) {
  687. showNotice('success', (studiouWcpcm.i18n.clearMediaSuccess || 'Successfully deleted') + ' ' + totalDeleted + ' media files');
  688. setTimeout(function() {
  689. location.reload();
  690. }, 3000);
  691. } else {
  692. showNotice('error', studiouWcpcm.i18n.clearMediaError || 'Failed to delete any media files');
  693. }
  694. $submitBtn.prop('disabled', false);
  695. $spinner.css('visibility', 'hidden');
  696. }
  697. /**
  698. * Update clear media progress bar
  699. */
  700. function updateClearMediaProgressBar(percentage) {
  701. $('#studiou-wcpcm-clear-media-progress-bar').css('width', percentage + '%');
  702. $('#studiou-wcpcm-clear-media-progress-bar').attr('data-progress', percentage + '%');
  703. }
  704. /**
  705. * Initialize remove unassigned media form
  706. */
  707. function initRemoveUnassignedMediaForm() {
  708. console.log('STUDIOU WC: Initializing remove unassigned media form handlers');
  709. $('#studiou-wcpcm-remove-unassigned-media-form').on('submit', function(e) {
  710. e.preventDefault();
  711. console.log('STUDIOU WC: Remove unassigned media form submitted');
  712. if (!confirm(studiouWcpcm.i18n.confirmRemoveUnassigned || 'Are you sure you want to permanently delete ALL unused uncategorized media files? This action cannot be undone!')) {
  713. return;
  714. }
  715. var $submitBtn = $(this).find('#studiou-wcpcm-remove-unassigned-media-button');
  716. var $spinner = $(this).find('.spinner');
  717. $submitBtn.prop('disabled', true);
  718. $spinner.css('visibility', 'visible');
  719. $('.studiou-wcpcm-notice-area').empty();
  720. $('.studiou-wcpcm-remove-unassigned-media-results').hide();
  721. $('.studiou-wcpcm-remove-unassigned-media-progress').show();
  722. $('#studiou-wcpcm-remove-unassigned-media-progress-text').text('Initializing...');
  723. updateRemoveUnassignedProgressBar(0);
  724. $.ajax({
  725. url: studiouWcpcm.ajaxUrl,
  726. type: 'POST',
  727. data: {
  728. action: 'studiou_wcpcm_remove_unassigned_media',
  729. nonce: studiouWcpcm.nonce
  730. },
  731. success: function(response) {
  732. console.log('STUDIOU WC: Remove unassigned media response:', response);
  733. if (response.success) {
  734. var mediaIds = response.data.media_ids;
  735. var totalCount = response.data.total_count;
  736. if (totalCount === 0) {
  737. showNotice('success', studiouWcpcm.i18n.noUnassignedMedia || 'No unused uncategorized media files found');
  738. $('.studiou-wcpcm-remove-unassigned-media-progress').hide();
  739. $submitBtn.prop('disabled', false);
  740. $spinner.css('visibility', 'hidden');
  741. return;
  742. }
  743. processUnassignedMediaBatches(mediaIds, totalCount, $submitBtn, $spinner);
  744. } else {
  745. showNotice('error', response.data.message);
  746. $('.studiou-wcpcm-remove-unassigned-media-progress').hide();
  747. $submitBtn.prop('disabled', false);
  748. $spinner.css('visibility', 'hidden');
  749. }
  750. },
  751. error: function(xhr, status, error) {
  752. console.error('STUDIOU WC: Remove unassigned media error:', status, error);
  753. showNotice('error', (studiouWcpcm.i18n.removeUnassignedError || 'Error') + ': ' + error);
  754. $('.studiou-wcpcm-remove-unassigned-media-progress').hide();
  755. $submitBtn.prop('disabled', false);
  756. $spinner.css('visibility', 'hidden');
  757. }
  758. });
  759. });
  760. }
  761. /**
  762. * Process unassigned media deletion in batches
  763. */
  764. function processUnassignedMediaBatches(mediaIds, totalCount, $submitBtn, $spinner) {
  765. var batchSize = 10;
  766. var batches = [];
  767. var totalDeleted = 0;
  768. var totalFailed = 0;
  769. var failedMedia = [];
  770. for (var i = 0; i < mediaIds.length; i += batchSize) {
  771. batches.push(mediaIds.slice(i, i + batchSize));
  772. }
  773. var currentBatch = 0;
  774. function processBatch() {
  775. if (currentBatch >= batches.length) {
  776. onUnassignedMediaComplete(totalDeleted, totalFailed, failedMedia, $submitBtn, $spinner);
  777. return;
  778. }
  779. var batch = batches[currentBatch];
  780. var progress = Math.round((currentBatch / batches.length) * 100);
  781. $('#studiou-wcpcm-remove-unassigned-media-progress-text').text(
  782. 'Deleting media files... ' + (currentBatch * batchSize) + ' of ' + totalCount + ' processed'
  783. );
  784. updateRemoveUnassignedProgressBar(progress);
  785. $.ajax({
  786. url: studiouWcpcm.ajaxUrl,
  787. type: 'POST',
  788. data: {
  789. action: 'studiou_wcpcm_remove_unassigned_media_batch',
  790. media_ids: batch,
  791. nonce: studiouWcpcm.nonce
  792. },
  793. success: function(response) {
  794. if (response.success) {
  795. totalDeleted += response.data.deleted_count;
  796. totalFailed += response.data.failed_count;
  797. failedMedia = failedMedia.concat(response.data.failed_media);
  798. currentBatch++;
  799. processBatch();
  800. } else {
  801. showNotice('error', response.data.message);
  802. $('.studiou-wcpcm-remove-unassigned-media-progress').hide();
  803. $submitBtn.prop('disabled', false);
  804. $spinner.css('visibility', 'hidden');
  805. }
  806. },
  807. error: function(xhr, status, error) {
  808. console.error('STUDIOU WC: Unassigned media batch error:', status, error);
  809. showNotice('error', 'Error deleting batch: ' + error);
  810. $('.studiou-wcpcm-remove-unassigned-media-progress').hide();
  811. $submitBtn.prop('disabled', false);
  812. $spinner.css('visibility', 'hidden');
  813. }
  814. });
  815. }
  816. processBatch();
  817. }
  818. /**
  819. * Handle unassigned media deletion completion
  820. */
  821. function onUnassignedMediaComplete(totalDeleted, totalFailed, failedMedia, $submitBtn, $spinner) {
  822. updateRemoveUnassignedProgressBar(100);
  823. $('#studiou-wcpcm-remove-unassigned-media-progress-text').text('Deletion complete!');
  824. var message = '<p><strong>Deletion Summary:</strong></p>';
  825. message += '<ul>';
  826. message += '<li>Total media files deleted: ' + totalDeleted + '</li>';
  827. if (totalFailed > 0) {
  828. message += '<li>Failed to delete: ' + totalFailed + '</li>';
  829. if (failedMedia.length > 0) {
  830. message += '<li>Failed media IDs: ' + failedMedia.join(', ') + '</li>';
  831. }
  832. }
  833. message += '</ul>';
  834. $('#studiou-wcpcm-remove-unassigned-media-message').html(message);
  835. $('.studiou-wcpcm-remove-unassigned-media-results').show();
  836. setTimeout(function() {
  837. $('.studiou-wcpcm-remove-unassigned-media-progress').fadeOut();
  838. }, 2000);
  839. if (totalDeleted > 0) {
  840. showNotice('success', (studiouWcpcm.i18n.removeUnassignedSuccess || 'Successfully deleted') + ' ' + totalDeleted + ' media files');
  841. setTimeout(function() {
  842. location.reload();
  843. }, 3000);
  844. } else {
  845. showNotice('error', studiouWcpcm.i18n.removeUnassignedError || 'Failed to delete any media files');
  846. }
  847. $submitBtn.prop('disabled', false);
  848. $spinner.css('visibility', 'hidden');
  849. }
  850. /**
  851. * Update remove unassigned media progress bar
  852. */
  853. function updateRemoveUnassignedProgressBar(percentage) {
  854. $('#studiou-wcpcm-remove-unassigned-media-progress-bar').css('width', percentage + '%');
  855. $('#studiou-wcpcm-remove-unassigned-media-progress-bar').attr('data-progress', percentage + '%');
  856. }
  857. /**
  858. * Show notice message
  859. *
  860. * @param {string} type Notice type (success, error)
  861. * @param {string} message Notice message
  862. */
  863. function showNotice(type, message) {
  864. var $notice = $('<div class="studiou-wcpcm-notice studiou-wcpcm-notice-' + type + '"></div>').text(message);
  865. $('.studiou-wcpcm-notice-area').append($notice);
  866. // Scroll to notice
  867. $('html, body').animate({
  868. scrollTop: $('.studiou-wcpcm-notice-area').offset().top - 50
  869. }, 500);
  870. }
  871. /**
  872. * Initialize product import form
  873. */
  874. function initProductImportForm() {
  875. console.log('STUDIOU WC: Initializing product import form handlers');
  876. // Global variables for batch processing
  877. var importTransientKey = null;
  878. var importTotal = 0;
  879. var importProcessed = 0;
  880. var importSuccess = 0;
  881. var importFailed = 0;
  882. var importSkipped = 0;
  883. var importMessages = [];
  884. var importFailedCsv = '';
  885. $('#studiou-wcpcm-product-import-form').on('submit', function(e) {
  886. e.preventDefault();
  887. console.log('STUDIOU WC: Product import form submitted');
  888. // Validate file is selected
  889. var fileInput = $('#import_file')[0];
  890. if (!fileInput.files || !fileInput.files[0]) {
  891. showNotice('error', 'Please select a CSV file to import');
  892. return;
  893. }
  894. // Show spinner and progress
  895. var $submitBtn = $(this).find('#studiou-wcpcm-product-import-button');
  896. var $spinner = $(this).find('.spinner');
  897. $submitBtn.prop('disabled', true);
  898. $spinner.css('visibility', 'visible');
  899. // Clear previous results
  900. $('.studiou-wcpcm-notice-area').empty();
  901. $('.studiou-wcpcm-product-import-results').hide();
  902. $('.studiou-wcpcm-product-import-failed').hide();
  903. // Reset counters
  904. importTransientKey = null;
  905. importTotal = 0;
  906. importProcessed = 0;
  907. importSuccess = 0;
  908. importFailed = 0;
  909. importSkipped = 0;
  910. importMessages = [];
  911. importFailedCsv = '';
  912. // Show progress bar
  913. $('.studiou-wcpcm-product-import-progress').show();
  914. $('#studiou-wcpcm-product-import-progress-text').text('Parsing CSV file...');
  915. updateProductImportProgressBar(0);
  916. // Step 1: Parse CSV file
  917. var formData = new FormData(this);
  918. formData.append('action', 'studiou_wcpcm_product_import_parse');
  919. formData.append('nonce', studiouWcpcm.nonce);
  920. $.ajax({
  921. url: studiouWcpcm.ajaxUrl,
  922. type: 'POST',
  923. data: formData,
  924. processData: false,
  925. contentType: false,
  926. success: function(response) {
  927. console.log('STUDIOU WC: Product import parse response:', response);
  928. if (response.success) {
  929. importTransientKey = response.data.transient_key;
  930. importTotal = response.data.total;
  931. // Start batch processing
  932. processBatch(0, $submitBtn, $spinner);
  933. } else {
  934. showNotice('error', response.data.message || 'Parse failed');
  935. $('.studiou-wcpcm-product-import-progress').hide();
  936. $submitBtn.prop('disabled', false);
  937. $spinner.css('visibility', 'hidden');
  938. }
  939. },
  940. error: function(xhr, status, error) {
  941. console.error('STUDIOU WC: Product import parse error:', status, error);
  942. console.error('STUDIOU WC: Response text:', xhr.responseText);
  943. showNotice('error', 'Product import error: ' + error);
  944. $('.studiou-wcpcm-product-import-progress').hide();
  945. $submitBtn.prop('disabled', false);
  946. $spinner.css('visibility', 'hidden');
  947. }
  948. });
  949. });
  950. // Process batch of products
  951. function processBatch(offset, $submitBtn, $spinner) {
  952. console.log('STUDIOU WC: Processing batch at offset', offset);
  953. $.ajax({
  954. url: studiouWcpcm.ajaxUrl,
  955. type: 'POST',
  956. data: {
  957. action: 'studiou_wcpcm_product_import_batch',
  958. nonce: studiouWcpcm.nonce,
  959. transient_key: importTransientKey,
  960. offset: offset
  961. },
  962. success: function(response) {
  963. console.log('STUDIOU WC: Batch response:', response);
  964. if (response.success) {
  965. // Accumulate results
  966. importSuccess += response.data.success;
  967. importFailed += response.data.failed;
  968. importSkipped += response.data.skipped;
  969. importProcessed = response.data.processed;
  970. importTotal = response.data.total;
  971. importMessages = importMessages.concat(response.data.messages);
  972. if (response.data.failed_csv) {
  973. importFailedCsv = response.data.failed_csv;
  974. }
  975. // Update progress
  976. var percent = (importProcessed / importTotal) * 100;
  977. updateProductImportProgressBar(percent);
  978. $('#studiou-wcpcm-product-import-progress-text').text(
  979. 'Processing: ' + importProcessed + ' / ' + importTotal + ' products'
  980. );
  981. // Check if complete
  982. if (importProcessed >= importTotal) {
  983. // Import complete
  984. $('#studiou-wcpcm-product-import-progress-text').text('Complete!');
  985. showNotice('success', 'Product import completed!');
  986. // Show results
  987. var message = '<p><strong>Import Summary:</strong></p>';
  988. message += '<ul>';
  989. message += '<li>Successful: ' + importSuccess + '</li>';
  990. message += '<li>Failed: ' + importFailed + '</li>';
  991. message += '<li>Skipped: ' + importSkipped + '</li>';
  992. message += '</ul>';
  993. $('#studiou-wcpcm-product-import-message').html(message);
  994. // Show detailed messages
  995. if (importMessages.length > 0) {
  996. var details = '<pre>' + importMessages.join('\n') + '</pre>';
  997. $('#studiou-wcpcm-product-import-details-content').html(details);
  998. }
  999. $('.studiou-wcpcm-product-import-results').show();
  1000. // Show save failed button if there are failed items
  1001. if (importFailed > 0 && importFailedCsv) {
  1002. window.studiouWcpcmFailedCsv = importFailedCsv;
  1003. $('.studiou-wcpcm-product-import-failed').show();
  1004. }
  1005. // Hide progress after delay
  1006. setTimeout(function() {
  1007. $('.studiou-wcpcm-product-import-progress').fadeOut();
  1008. }, 2000);
  1009. $submitBtn.prop('disabled', false);
  1010. $spinner.css('visibility', 'hidden');
  1011. } else {
  1012. // Process next batch
  1013. processBatch(importProcessed, $submitBtn, $spinner);
  1014. }
  1015. } else {
  1016. showNotice('error', response.data.message || 'Batch processing failed');
  1017. $('.studiou-wcpcm-product-import-progress').hide();
  1018. $submitBtn.prop('disabled', false);
  1019. $spinner.css('visibility', 'hidden');
  1020. }
  1021. },
  1022. error: function(xhr, status, error) {
  1023. console.error('STUDIOU WC: Batch processing error:', status, error);
  1024. showNotice('error', 'Batch processing error: ' + error);
  1025. $('.studiou-wcpcm-product-import-progress').hide();
  1026. $submitBtn.prop('disabled', false);
  1027. $spinner.css('visibility', 'hidden');
  1028. }
  1029. });
  1030. }
  1031. // Save failed products button handler
  1032. $('#studiou-wcpcm-save-failed-products').on('click', function(e) {
  1033. e.preventDefault();
  1034. if (window.studiouWcpcmFailedCsv) {
  1035. var blob = new Blob([window.studiouWcpcmFailedCsv], { type: 'text/csv;charset=utf-8;' });
  1036. var url = URL.createObjectURL(blob);
  1037. var link = document.createElement('a');
  1038. link.setAttribute('href', url);
  1039. link.setAttribute('download', 'failed-products-' + Date.now() + '.csv');
  1040. link.style.visibility = 'hidden';
  1041. document.body.appendChild(link);
  1042. link.click();
  1043. document.body.removeChild(link);
  1044. }
  1045. });
  1046. }
  1047. /**
  1048. * Initialize product export form
  1049. */
  1050. function initProductExportForm() {
  1051. console.log('STUDIOU WC: Initializing product export form handlers');
  1052. // Select all button handler
  1053. $('#studiou-wcpcm-export-select-all').on('click', function(e) {
  1054. e.preventDefault();
  1055. console.log('STUDIOU WC: Export select all button clicked');
  1056. $('#export_categories_list input[type="checkbox"]').prop('checked', true);
  1057. });
  1058. // Deselect all button handler
  1059. $('#studiou-wcpcm-export-deselect-all').on('click', function(e) {
  1060. e.preventDefault();
  1061. console.log('STUDIOU WC: Export deselect all button clicked');
  1062. $('#export_categories_list input[type="checkbox"]').prop('checked', false);
  1063. });
  1064. // Form submit handler
  1065. $('#studiou-wcpcm-product-export-form').on('submit', function(e) {
  1066. e.preventDefault();
  1067. console.log('STUDIOU WC: Product export form submitted');
  1068. // Get selected categories
  1069. var selectedCategories = [];
  1070. $('#export_categories_list input[type="checkbox"]:checked').each(function() {
  1071. selectedCategories.push($(this).val());
  1072. });
  1073. console.log('STUDIOU WC: Selected categories:', selectedCategories);
  1074. // Validate input
  1075. if (selectedCategories.length === 0) {
  1076. console.log('STUDIOU WC: No categories selected');
  1077. showNotice('error', 'Please select at least one category');
  1078. return;
  1079. }
  1080. // Show spinner
  1081. var $submitBtn = $(this).find('#studiou-wcpcm-product-export-button');
  1082. var $spinner = $(this).find('.spinner');
  1083. $submitBtn.prop('disabled', true);
  1084. $spinner.css('visibility', 'visible');
  1085. // Clear previous notices
  1086. $('.studiou-wcpcm-notice-area').empty();
  1087. $('.studiou-wcpcm-product-export-results').hide();
  1088. // Debug: Log AJAX request details
  1089. console.log('STUDIOU WC: Sending product export AJAX request to:', studiouWcpcm.ajaxUrl);
  1090. console.log('STUDIOU WC: Nonce:', studiouWcpcm.nonce);
  1091. // Send AJAX request
  1092. $.ajax({
  1093. url: studiouWcpcm.ajaxUrl,
  1094. type: 'POST',
  1095. data: {
  1096. action: 'studiou_wcpcm_product_export',
  1097. export_categories: selectedCategories,
  1098. nonce: studiouWcpcm.nonce
  1099. },
  1100. success: function(response) {
  1101. console.log('STUDIOU WC: Product export AJAX response:', response);
  1102. if (response.success) {
  1103. showNotice('success', 'Export successful!');
  1104. // Show results
  1105. $('#studiou-wcpcm-product-export-message').html('<p>' + response.data.message + '</p>');
  1106. $('#studiou-wcpcm-download-product-export').attr('href', response.data.download_url);
  1107. $('.studiou-wcpcm-product-export-results').show();
  1108. } else {
  1109. showNotice('error', response.data.message || 'Export failed');
  1110. }
  1111. },
  1112. error: function(xhr, status, error) {
  1113. console.error('STUDIOU WC: Product export AJAX error:', status, error);
  1114. console.error('STUDIOU WC: Response text:', xhr.responseText);
  1115. showNotice('error', 'Product export error: ' + error);
  1116. },
  1117. complete: function() {
  1118. // Hide spinner
  1119. $submitBtn.prop('disabled', false);
  1120. $spinner.css('visibility', 'hidden');
  1121. }
  1122. });
  1123. });
  1124. }
  1125. /**
  1126. * Update product import progress bar
  1127. */
  1128. function updateProductImportProgressBar(percentage) {
  1129. $('#studiou-wcpcm-product-import-progress-bar').css('width', percentage + '%');
  1130. $('#studiou-wcpcm-product-import-progress-bar').attr('data-progress', Math.round(percentage) + '%');
  1131. }
  1132. // Additional debug: Check if elements exist after DOM load
  1133. $(window).on('load', function() {
  1134. console.log('STUDIOU WC: Window loaded');
  1135. console.log('STUDIOU WC: Move form exists:', $('#studiou-wcpcm-move-form').length > 0);
  1136. console.log('STUDIOU WC: Move button exists:', $('#studiou-wcpcm-move-button').length > 0);
  1137. console.log('STUDIOU WC: Source select exists:', $('#source_category').length > 0);
  1138. console.log('STUDIOU WC: Target select exists:', $('#target_category').length > 0);
  1139. console.log('STUDIOU WC: Batch description form exists:', $('#studiou-wcpcm-batch-description-form').length > 0);
  1140. console.log('STUDIOU WC: Batch description button exists:', $('#studiou-wcpcm-batch-description-button').length > 0);
  1141. console.log('STUDIOU WC: Delete products form exists:', $('#studiou-wcpcm-delete-products-form').length > 0);
  1142. console.log('STUDIOU WC: Product import form exists:', $('#studiou-wcpcm-product-import-form').length > 0);
  1143. console.log('STUDIOU WC: Product export form exists:', $('#studiou-wcpcm-product-export-form').length > 0);
  1144. console.log('STUDIOU WC: Clear media form exists:', $('#studiou-wcpcm-clear-media-form').length > 0);
  1145. });
  1146. })(jQuery);