Plugin Directory

Changeset 3377550


Ignore:
Timestamp:
10/13/2025 01:17:39 PM (2 months ago)
Author:
athemes
Message:

v1.1.3

Location:
athemes-starter-sites/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • athemes-starter-sites/trunk/README.txt

    r3367146 r3377550  
    22Tags: athemes, elementor, demos, import, sites
    33Requires at least: 4.0
    4 Tested up to: 6.7.2
     4Tested up to: 6.8.3
    55Requires PHP: 5.4
    6 Stable tag: 1.1.2
     6Stable tag: 1.1.3
    77Contributors: aThemes
    88License: GPLv2 or later
     
    6868
    6969== Changelog ==
     70
     71= 1.1.3 =
     72* Improve content and widget import process
    7073
    7174= 1.1.2 =
  • athemes-starter-sites/trunk/athemes-starter-sites.php

    r3367146 r3377550  
    33 * Plugin Name:       aThemes Starter Sites
    44 * Description:       Starter Sites for Sydney and Botiga
    5  * Version:           1.1.2
     5 * Version:           1.1.3
    66 * Author:            aThemes
    77 * Author URI:        https://athemes.com
  • athemes-starter-sites/trunk/v2/assets/js/script.js

    r3343681 r3377550  
    5050      delete data.log;
    5151      delete data.priority;
    52       $.post(window.atss_localize.ajax_url, data, function (response) {
    53         if (response.success) {
    54           if (response.status && response.status === 'newAJAX') {
    55             step--;
    56           }
    57           setTimeout(function () {
    58             _atssAjaxImportRecursive($form, steps, step);
    59           }, 500);
    60         } else if (response.data) {
    61           $form.find('.atss-import-step-error').addClass('atss-active').siblings().removeClass('atss-active');
    62           $form.find('.atss-import-error-log').html(response.data);
    63           $body.removeClass('atss-import-in-progress');
    64         } else {
    65           var errorLog = window.atss_localize.i18n.import_failed;
    66           if (response) {
    67             errorLog += '<div class="atss-import-error-response">' + _.escape(response) + '</div>';
    68           }
    69           $form.find('.atss-import-step-error').addClass('atss-active').siblings().removeClass('atss-active');
    70           $form.find('.atss-import-error-log').html(errorLog);
    71           $body.removeClass('atss-import-in-progress');
    72         }
    73       }).fail(function () {
    74         $form.find('.atss-import-step-error').addClass('atss-active').siblings().removeClass('atss-active');
    75         $form.find('.atss-import-error-log').html(window.atss_localize.i18n.import_failed);
    76         $body.removeClass('atss-import-in-progress');
    77       });
     52
     53      // Determine if this is a widget import step
     54      var isWidgetStep = data.action === 'atss_import_widgets';
     55
     56      // Set longer timeout for import requests, especially widget imports
     57      var ajaxSettings = {
     58        url: window.atss_localize.ajax_url,
     59        type: 'POST',
     60        data: data,
     61        timeout: isWidgetStep ? 180000 : 120000,
     62        // 3 minutes for widgets, 2 minutes for others
     63        success: function success(response) {
     64          if (response.success) {
     65            if (response.status && response.status === 'newAJAX') {
     66              step--;
     67            }
     68            setTimeout(function () {
     69              _atssAjaxImportRecursive($form, steps, step);
     70            }, 500);
     71          } else if (response.data) {
     72            $form.find('.atss-import-step-error').addClass('atss-active').siblings().removeClass('atss-active');
     73            $form.find('.atss-import-error-log').html(response.data);
     74            $body.removeClass('atss-import-in-progress');
     75          } else {
     76            var errorLog = window.atss_localize.i18n.import_failed;
     77            if (response) {
     78              errorLog += '<div class="atss-import-error-response">' + _.escape(response) + '</div>';
     79            }
     80            $form.find('.atss-import-step-error').addClass('atss-active').siblings().removeClass('atss-active');
     81            $form.find('.atss-import-error-log').html(errorLog);
     82            $body.removeClass('atss-import-in-progress');
     83          }
     84        },
     85        error: function error(xhr, status, _error) {
     86          // Handle timeout and network errors gracefully for widget imports
     87          if (isWidgetStep && (status === 'timeout' || status === 'error')) {
     88            console.log('Widget import timed out or failed, continuing with next step...');
     89
     90            // Continue to next step instead of failing
     91            setTimeout(function () {
     92              _atssAjaxImportRecursive($form, steps, step);
     93            }, 500);
     94          } else {
     95            // For other steps, show error as before
     96            $form.find('.atss-import-step-error').addClass('atss-active').siblings().removeClass('atss-active');
     97            $form.find('.atss-import-error-log').html(window.atss_localize.i18n.import_failed);
     98            $body.removeClass('atss-import-in-progress');
     99          }
     100        }
     101      };
     102      $.ajax(ajaxSettings);
    78103    } else {
    79104      $form.find('.atss-import-progress-label').html(window.atss_localize.i18n.import_finished);
  • athemes-starter-sites/trunk/v2/assets/js/script.min.js

    r3343681 r3377550  
    1 var _dcq=_dcq||[],_dcs=_dcs||{};_dcs.account=5598225,(()=>{var t=document.createElement("script"),s=(t.type="text/javascript",t.async=!0,t.src="//tag.getdrip.com/"+_dcs.account+".js",document.getElementsByTagName("script")[0]);s.parentNode.insertBefore(t,s)})(),(o=>{function d(e,i,a){var t,s,n,r;a++,i.length>a&&i[a]?(n=i[a].log||"",r=Math.max(5,Math.round(100/i.length*a)),e.find(".atss-import-progress-label").html(n),e.find(".atss-import-progress-sublabel").html(r+"%"),e.find(".atss-import-progress-indicator").attr("style","--atss-indicator: "+r+"%;"),n=window.atss_localize.nonce,r=e.find('input[name="demo_id"]').val(),t=(t=e.find('input[name="builder_type"]:checked').val())||"elementor",s=e.find('input[name="content_type"]:checked').val(),delete(n=o.extend({nonce:n,demo_id:r,builder_type:t,content_type:s},i[a])).log,delete n.priority,o.post(window.atss_localize.ajax_url,n,function(t){var s;t.success?(t.status&&"newAJAX"===t.status&&a--,setTimeout(function(){d(e,i,a)},500)):(t.data?(e.find(".atss-import-step-error").addClass("atss-active").siblings().removeClass("atss-active"),e.find(".atss-import-error-log").html(t.data)):(s=window.atss_localize.i18n.import_failed,t&&(s+='<div class="atss-import-error-response">'+_.escape(t)+"</div>"),e.find(".atss-import-step-error").addClass("atss-active").siblings().removeClass("atss-active"),e.find(".atss-import-error-log").html(s)),p.removeClass("atss-import-in-progress"))}).fail(function(){e.find(".atss-import-step-error").addClass("atss-active").siblings().removeClass("atss-active"),e.find(".atss-import-error-log").html(window.atss_localize.i18n.import_failed),p.removeClass("atss-import-in-progress")})):(e.find(".atss-import-progress-label").html(window.atss_localize.i18n.import_finished),e.find(".atss-import-progress-sublabel").html("100%"),e.find(".atss-import-progress-indicator").attr("style","--atss-indicator: 100%;"),r=window.atss_localize.i18n.tweet_text.replace("{0}",m),e.find(".atss-import-finish-tweet-text").html(r),e.find(".atss-import-finish-tweet-button").attr("href","https://twitter.com/intent/tweet?text="+r),setTimeout(function(){e.find(".atss-import-step").removeClass("atss-active"),e.find(".atss-import-step-finish").addClass("atss-active"),p.removeClass("atss-import-in-progress")},250),c.addClass("atss-demo-item-imported").siblings().removeClass("atss-demo-item-imported"),clearInterval(l),m=1),f=!0}var l,c,p=o("body"),m=1,f=!1;o(document).ready(function(){var a,i,n,t=o(".atss-notice"),r=(t.length&&t.find(".notice-dismiss").on("click",function(){t.parent().hide(),o.post(window.atss_localize.ajax_url,{action:"atss_dismissed_handler",nonce:window.atss_localize.nonce})}),o(".atss"));r.length&&(a=r.find(".atss-demo-item"),r.find(".atss-import"),i=r.find(".atss-preview"),r.on("click",".atss-demo-preview-button",function(t){t.preventDefault();var s,t=o(this),e=t.closest(".atss-demo-item"),t={preview:t.attr("href"),info:e.find(".atss-demo-info").html(),actions:e.find(".atss-demo-actions").html()};p.hasClass("atss-preview-show")?(i.find(".atss-preview-iframe").attr("src",t.preview),i.find(".atss-preview-header-info").html(t.info),i.find(".atss-preview-header-actions").html(t.actions)):(s=wp.template("atss-preview"),i.html(s(t))),p.addClass("atss-preview-show"),n=e.index(),r.trigger("atss-nav-click",[n])}),r.on("click",".atss-preview-header-arrow-prev",function(t){t.preventDefault(),o(this).hasClass("atss-disabled")||(n--,a.eq(n).find(".atss-demo-preview-button").trigger("click"))}),r.on("click",".atss-preview-header-arrow-next",function(t){t.preventDefault(),o(this).hasClass("atss-disabled")||(n++,a.eq(n).find(".atss-demo-preview-button").trigger("click"))}),r.on("click",".atss-preview-cancel-button",function(t){t.preventDefault(),p.removeClass("atss-preview-show"),i.empty()}),r.on("atss-nav-click",function(t,s){var e=r.find(".atss-preview-header-arrow-prev"),i=r.find(".atss-preview-header-arrow-next");(0===s?(e.addClass("atss-disabled"),i):(a.length-1===s?i.addClass("atss-disabled"):i.removeClass("atss-disabled"),e)).removeClass("atss-disabled")}),r.on("click",".atss-import-open-button",function(t){t.preventDefault();var t=o(this).data("demo-id"),s=window.atss_localize.demos[t],e=wp.template("atss-import");s&&s.builders.length&&(c=o(this).closest(".atss-demo-item"),s.args={},s.args.demoId=t,s.args.quick=o(this).data("quick")||s.builders.length<2||!1,s.args.builder=o(this).data("builder")||s.builders[0],s.args.imported=window.atss_localize.imported||f,r.find(".atss-import").html(e(s)),p.addClass("atss-import-show"))}),r.on("click",".atss-import-close-button",function(t){t.preventDefault(),p.removeClass("atss-import-show")}),r.on("click",".atss-import-toggle-button",function(t){t.preventDefault(),o(this).parent().toggleClass("atss-active")}),r.on("click",".atss-import-prev-button",function(t){t.preventDefault();t=o(this).closest(".atss-import-step");t.removeClass("atss-active"),t.prev().addClass("atss-active")}),r.on("click",".atss-import-next-button",function(t){t.preventDefault();t=o(this).closest(".atss-import-step");t.removeClass("atss-active"),t.next().addClass("atss-active")}),r.on("change",".atss-import-builder-select input",function(t){r.find(".atss-import-plugin-builder").addClass("atss-hidden"),r.find(".atss-import-plugin-builder input").prop("checked",!1);var s,e=o(this).val();r.find("label[data-plugin-builder]").each(function(){var t=o(this),s=t.attr("data-plugin-builder");s&&s!==e?(t.addClass("atss-hidden"),t.find("input").prop("checked",!1)):s&&s===e&&(t.removeClass("atss-hidden"),t.find("input").prop("checked",!0))}),o(this).is(":checked")&&((s=r.find(".atss-import-plugin-"+o(this).data("builder-plugin"))).removeClass("atss-hidden"),s.find("input").prop("checked",!0))}),r.on("click",".atss-import-with-content-type",function(){var t=!0;o(".atss-import-with-content-type").each(function(){o(this).is(":checked")||(t=!1)}),t?r.find(".atss-import-content-select").removeClass("atss-hidden"):r.find(".atss-import-content-select").addClass("atss-hidden")}),r.on("click",".atss-import-start-button",function(t){t.preventDefault();t=r.find(".atss-import-form");if(o(this).data("subscribe")){var s=t.find(".atss-import-subscribe-field-email"),e=s.val();if(!/^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(e))return void s.addClass("atss-error").attr("placeholder",window.atss_localize.i18n.invalid_email).val("");_dcq.push(["identify",{email:e,tags:[window.atss_localize.theme_name]}])}var s=o(this).closest(".atss-import-step"),i=(s.removeClass("atss-active"),s.next().addClass("atss-active"),[]);t.find("input[data-action]").each(function(t){(o(this).is(":checked")||o(this).is('[type="hidden"]'))&&i.push(o(this).data())}),i=i.sort(function(t,s){return t.priority-s.priority}),m=1,l=setInterval(function(){m++},1e3),p.addClass("atss-import-in-progress"),d(t,i,-1)}))})})(jQuery);
     1var _dcq=_dcq||[],_dcs=_dcs||{};_dcs.account=5598225,(()=>{var t=document.createElement("script"),s=(t.type="text/javascript",t.async=!0,t.src="//tag.getdrip.com/"+_dcs.account+".js",document.getElementsByTagName("script")[0]);s.parentNode.insertBefore(t,s)})(),(d=>{function l(i,a,n){var t,s,o,e,r;n++,a.length>n&&a[n]?(s=a[n].log||"",e=Math.max(5,Math.round(100/a.length*n)),i.find(".atss-import-progress-label").html(s),i.find(".atss-import-progress-sublabel").html(e+"%"),i.find(".atss-import-progress-indicator").attr("style","--atss-indicator: "+e+"%;"),s=window.atss_localize.nonce,e=i.find('input[name="demo_id"]').val(),r=(r=i.find('input[name="builder_type"]:checked').val())||"elementor",t=i.find('input[name="content_type"]:checked').val(),delete(s=d.extend({nonce:s,demo_id:e,builder_type:r,content_type:t},a[n])).log,delete s.priority,o="atss_import_widgets"===s.action,e={url:window.atss_localize.ajax_url,type:"POST",data:s,timeout:o?18e4:12e4,success:function(t){var s;t.success?(t.status&&"newAJAX"===t.status&&n--,setTimeout(function(){l(i,a,n)},500)):(t.data?(i.find(".atss-import-step-error").addClass("atss-active").siblings().removeClass("atss-active"),i.find(".atss-import-error-log").html(t.data)):(s=window.atss_localize.i18n.import_failed,t&&(s+='<div class="atss-import-error-response">'+_.escape(t)+"</div>"),i.find(".atss-import-step-error").addClass("atss-active").siblings().removeClass("atss-active"),i.find(".atss-import-error-log").html(s)),m.removeClass("atss-import-in-progress"))},error:function(t,s,e){!o||"timeout"!==s&&"error"!==s?(i.find(".atss-import-step-error").addClass("atss-active").siblings().removeClass("atss-active"),i.find(".atss-import-error-log").html(window.atss_localize.i18n.import_failed),m.removeClass("atss-import-in-progress")):(console.log("Widget import timed out or failed, continuing with next step..."),setTimeout(function(){l(i,a,n)},500))}},d.ajax(e)):(i.find(".atss-import-progress-label").html(window.atss_localize.i18n.import_finished),i.find(".atss-import-progress-sublabel").html("100%"),i.find(".atss-import-progress-indicator").attr("style","--atss-indicator: 100%;"),r=window.atss_localize.i18n.tweet_text.replace("{0}",u),i.find(".atss-import-finish-tweet-text").html(r),i.find(".atss-import-finish-tweet-button").attr("href","https://twitter.com/intent/tweet?text="+r),setTimeout(function(){i.find(".atss-import-step").removeClass("atss-active"),i.find(".atss-import-step-finish").addClass("atss-active"),m.removeClass("atss-import-in-progress")},250),p.addClass("atss-demo-item-imported").siblings().removeClass("atss-demo-item-imported"),clearInterval(c),u=1),f=!0}var c,p,m=d("body"),u=1,f=!1;d(document).ready(function(){var a,i,n,t=d(".atss-notice"),o=(t.length&&t.find(".notice-dismiss").on("click",function(){t.parent().hide(),d.post(window.atss_localize.ajax_url,{action:"atss_dismissed_handler",nonce:window.atss_localize.nonce})}),d(".atss"));o.length&&(a=o.find(".atss-demo-item"),o.find(".atss-import"),i=o.find(".atss-preview"),o.on("click",".atss-demo-preview-button",function(t){t.preventDefault();var s,t=d(this),e=t.closest(".atss-demo-item"),t={preview:t.attr("href"),info:e.find(".atss-demo-info").html(),actions:e.find(".atss-demo-actions").html()};m.hasClass("atss-preview-show")?(i.find(".atss-preview-iframe").attr("src",t.preview),i.find(".atss-preview-header-info").html(t.info),i.find(".atss-preview-header-actions").html(t.actions)):(s=wp.template("atss-preview"),i.html(s(t))),m.addClass("atss-preview-show"),n=e.index(),o.trigger("atss-nav-click",[n])}),o.on("click",".atss-preview-header-arrow-prev",function(t){t.preventDefault(),d(this).hasClass("atss-disabled")||(n--,a.eq(n).find(".atss-demo-preview-button").trigger("click"))}),o.on("click",".atss-preview-header-arrow-next",function(t){t.preventDefault(),d(this).hasClass("atss-disabled")||(n++,a.eq(n).find(".atss-demo-preview-button").trigger("click"))}),o.on("click",".atss-preview-cancel-button",function(t){t.preventDefault(),m.removeClass("atss-preview-show"),i.empty()}),o.on("atss-nav-click",function(t,s){var e=o.find(".atss-preview-header-arrow-prev"),i=o.find(".atss-preview-header-arrow-next");(0===s?(e.addClass("atss-disabled"),i):(a.length-1===s?i.addClass("atss-disabled"):i.removeClass("atss-disabled"),e)).removeClass("atss-disabled")}),o.on("click",".atss-import-open-button",function(t){t.preventDefault();var t=d(this).data("demo-id"),s=window.atss_localize.demos[t],e=wp.template("atss-import");s&&s.builders.length&&(p=d(this).closest(".atss-demo-item"),s.args={},s.args.demoId=t,s.args.quick=d(this).data("quick")||s.builders.length<2||!1,s.args.builder=d(this).data("builder")||s.builders[0],s.args.imported=window.atss_localize.imported||f,o.find(".atss-import").html(e(s)),m.addClass("atss-import-show"))}),o.on("click",".atss-import-close-button",function(t){t.preventDefault(),m.removeClass("atss-import-show")}),o.on("click",".atss-import-toggle-button",function(t){t.preventDefault(),d(this).parent().toggleClass("atss-active")}),o.on("click",".atss-import-prev-button",function(t){t.preventDefault();t=d(this).closest(".atss-import-step");t.removeClass("atss-active"),t.prev().addClass("atss-active")}),o.on("click",".atss-import-next-button",function(t){t.preventDefault();t=d(this).closest(".atss-import-step");t.removeClass("atss-active"),t.next().addClass("atss-active")}),o.on("change",".atss-import-builder-select input",function(t){o.find(".atss-import-plugin-builder").addClass("atss-hidden"),o.find(".atss-import-plugin-builder input").prop("checked",!1);var s,e=d(this).val();o.find("label[data-plugin-builder]").each(function(){var t=d(this),s=t.attr("data-plugin-builder");s&&s!==e?(t.addClass("atss-hidden"),t.find("input").prop("checked",!1)):s&&s===e&&(t.removeClass("atss-hidden"),t.find("input").prop("checked",!0))}),d(this).is(":checked")&&((s=o.find(".atss-import-plugin-"+d(this).data("builder-plugin"))).removeClass("atss-hidden"),s.find("input").prop("checked",!0))}),o.on("click",".atss-import-with-content-type",function(){var t=!0;d(".atss-import-with-content-type").each(function(){d(this).is(":checked")||(t=!1)}),t?o.find(".atss-import-content-select").removeClass("atss-hidden"):o.find(".atss-import-content-select").addClass("atss-hidden")}),o.on("click",".atss-import-start-button",function(t){t.preventDefault();t=o.find(".atss-import-form");if(d(this).data("subscribe")){var s=t.find(".atss-import-subscribe-field-email"),e=s.val();if(!/^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(e))return void s.addClass("atss-error").attr("placeholder",window.atss_localize.i18n.invalid_email).val("");_dcq.push(["identify",{email:e,tags:[window.atss_localize.theme_name]}])}var s=d(this).closest(".atss-import-step"),i=(s.removeClass("atss-active"),s.next().addClass("atss-active"),[]);t.find("input[data-action]").each(function(t){(d(this).is(":checked")||d(this).is('[type="hidden"]'))&&i.push(d(this).data())}),i=i.sort(function(t,s){return t.priority-s.priority}),u=1,c=setInterval(function(){u++},1e3),m.addClass("atss-import-in-progress"),l(t,i,-1)}))})})(jQuery);
  • athemes-starter-sites/trunk/v2/classes/class-importer.php

    r3169585 r3377550  
    2929     */
    3030    private $microtime;
     31
     32    /**
     33     * The WXR importer instance.
     34     *
     35     * @var ATSS_WXRImporter
     36     */
     37    private $importer;
    3138
    3239    /**
     
    632639        ) );
    633640
     641        // Store importer instance for access in filters
     642        $this->importer = $importer;
     643
    634644        // Logger options for the logger used in the importer.
    635645        $logger_options = apply_filters( 'atss_logger_options', array(
     
    680690        $time = microtime( true ) - $this->microtime;
    681691
    682         // We should make a new ajax call, if the time is right.
    683         if ( $time > apply_filters( 'atss_time_for_one_ajax_call', 300 ) ) {
     692        // Check attachment count for splitting (Option 2: split every X attachments)
     693        $split_after_attachments = apply_filters( 'atss_split_after_attachments', 10 );
     694        $should_split_by_count = false;
     695       
     696        if ( $this->importer && method_exists( $this->importer, 'get_attachment_count' ) ) {
     697            $attachment_count = $this->importer->get_attachment_count();
     698            if ( $attachment_count >= $split_after_attachments ) {
     699                $should_split_by_count = true;
     700            }
     701        }
     702
     703        // We should make a new ajax call, if the time is right OR attachment count is reached.
     704        $time_limit = apply_filters( 'atss_time_for_one_ajax_call', 300 );
     705        if ( $time > $time_limit || $should_split_by_count ) {
    684706
    685707            $response = array(
     
    9851007    public function ajax_import_widgets() {
    9861008
    987         check_ajax_referer( 'nonce', 'nonce' );
     1009        try {
     1010            // Increase time limit for widget import to prevent timeout
     1011            if ( ! ini_get( 'safe_mode' ) ) {
     1012                @set_time_limit( 120 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
     1013            }
     1014
     1015            check_ajax_referer( 'nonce', 'nonce' );
    9881016
    9891017        /**
     
    10141042         * Process widgets.json.
    10151043         */
    1016         // Get JSON data from widgets.json.
    1017         $raw = wp_remote_get( wp_unslash( $file_url ) );
    1018 
    1019         // Abort if widgets.json response code is not successful.
    1020         if ( 200 != wp_remote_retrieve_response_code( $raw ) ) {
    1021             wp_send_json_error( esc_html__( 'Failed to load widget demo file.', 'athemes-starter-sites' ) );
    1022         }
    1023 
    1024         // Clean widget settings.
    1025         $this->clean_widget_settings();
     1044        // Get JSON data from widgets.json with timeout protection.
     1045        $raw = wp_remote_get(
     1046            wp_unslash( $file_url ),
     1047            array(
     1048                'timeout' => 15, // Short timeout to prevent hanging
     1049                'sslverify' => false, // Helps with Playground/CORS issues
     1050            )
     1051        );
     1052
     1053        // Check if fetch failed - log and skip instead of stopping import.
     1054        if ( is_wp_error( $raw ) ) {
     1055            // Log error but continue to next step
     1056            error_log( 'ATSS Widget Import: Failed to fetch widget file - ' . $raw->get_error_message() );
     1057            wp_send_json_success( array( 'message' => esc_html__( 'Widget import skipped (file unavailable)', 'athemes-starter-sites' ) ) );
     1058            return;
     1059        }
     1060
     1061        // Check response code - skip if not successful.
     1062        if ( 200 !== wp_remote_retrieve_response_code( $raw ) ) {
     1063            // Log error but continue to next step
     1064            error_log( 'ATSS Widget Import: Failed to load widget file. HTTP ' . wp_remote_retrieve_response_code( $raw ) );
     1065            wp_send_json_success( array( 'message' => esc_html__( 'Widget import skipped (file unavailable)', 'athemes-starter-sites' ) ) );
     1066            return;
     1067        }
     1068
     1069        // Clean widget settings with timeout protection.
     1070        try {
     1071            $this->clean_widget_settings();
     1072        } catch ( Exception $e ) {
     1073            // Log but don't stop import if cleaning fails
     1074            error_log( 'ATSS Widget Import: Failed to clean widget settings - ' . $e->getMessage() );
     1075        } catch ( Error $e ) {
     1076            // Log but don't stop import if cleaning fails
     1077            error_log( 'ATSS Widget Import: Error cleaning widget settings - ' . $e->getMessage() );
     1078        }
    10261079
    10271080        // Decode raw JSON string to associative array.
    10281081        $data = json_decode( wp_remote_retrieve_body( $raw ) );
    10291082
    1030         $data = map_deep( $data, array( 'Athemes_Starter_Sites_Importer', 'replace_attachment_urls' ) );
     1083        // Check if JSON decode failed - skip if so.
     1084        if ( empty( $data ) ) {
     1085            error_log( 'ATSS Widget Import: Failed to decode widget JSON data' );
     1086            wp_send_json_success( array( 'message' => esc_html__( 'Widget import skipped (invalid data)', 'athemes-starter-sites' ) ) );
     1087            return;
     1088        }
     1089
     1090        // Process data with timeout protection
     1091        try {
     1092            $data = map_deep( $data, array( 'Athemes_Starter_Sites_Importer', 'replace_attachment_urls' ) );
     1093        } catch ( Exception $e ) {
     1094            error_log( 'ATSS Widget Import: Failed to process URLs - ' . $e->getMessage() );
     1095            // Continue with unprocessed data
     1096        } catch ( Error $e ) {
     1097            error_log( 'ATSS Widget Import: Error processing URLs - ' . $e->getMessage() );
     1098            // Continue with unprocessed data
     1099        }
    10311100
    10321101        $widgets = new ATSS_Widget_Importer();
    10331102
    1034         // Import.
     1103        // Import with timeout tracking.
    10351104        $results = $widgets->import( $data );
    10361105
    10371106        if ( is_wp_error( $results ) ) {
     1107            // Log error but continue to next step instead of stopping
    10381108            $error_message = $results->get_error_message();
    1039             wp_send_json_error( $error_message );
    1040         }
    1041 
    1042         /**
    1043          * Action hook.
    1044          */
    1045 
    1046         // Get all available widgets site supports.
    1047         $available_widgets = ATSS_Widget_Importer::available_widgets();
    1048 
    1049         // Get all existing widget instances.
    1050         $widget_instances = array();
    1051 
    1052         foreach ( $available_widgets as $widget_data ) {
    1053             $widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
    1054         }
    1055 
    1056         // Sidebar Widgets
    1057         $sidebar_widgets = get_option( 'sidebars_widgets', array() );
    1058 
    1059         update_option( '_athemes_sites_imported_widgets', $sidebar_widgets, 'no' );
    1060 
    1061         do_action( 'atss_import_widgets', $sidebar_widgets, $widget_instances );
     1109            error_log( 'ATSS Widget Import: Widget import failed - ' . $error_message );
     1110            wp_send_json_success( array( 'message' => esc_html__( 'Widget import completed with errors', 'athemes-starter-sites' ) ) );
     1111            return;
     1112        }
     1113
     1114        /**
     1115         * Action hook - wrapped in timeout protection.
     1116         */
     1117        try {
     1118            // Get all available widgets site supports.
     1119            $available_widgets = ATSS_Widget_Importer::available_widgets();
     1120
     1121            // Get all existing widget instances.
     1122            $widget_instances = array();
     1123
     1124            foreach ( $available_widgets as $widget_data ) {
     1125                if ( is_array( $widget_data ) && isset( $widget_data['id_base'] ) ) {
     1126                    $widget_instances[ $widget_data['id_base'] ] = get_option( 'widget_' . $widget_data['id_base'] );
     1127                }
     1128            }
     1129
     1130            // Sidebar Widgets
     1131            $sidebar_widgets = get_option( 'sidebars_widgets', array() );
     1132
     1133            update_option( '_athemes_sites_imported_widgets', $sidebar_widgets, 'no' );
     1134
     1135            do_action( 'atss_import_widgets', $sidebar_widgets, $widget_instances );
     1136        } catch ( Exception $e ) {
     1137            error_log( 'ATSS Widget Import: Post-import actions failed - ' . $e->getMessage() );
     1138            // Continue to success even if hooks fail
     1139        } catch ( Error $e ) {
     1140            error_log( 'ATSS Widget Import: Post-import actions error - ' . $e->getMessage() );
     1141            // Continue to success even if hooks fail
     1142        }
    10621143
    10631144        /**
     
    10661147        wp_send_json_success();
    10671148
     1149        } catch ( Exception $e ) {
     1150            // Log the error but don't crash the import - treat widget import as optional
     1151            error_log(
     1152                sprintf(
     1153                    'ATSS Widget Import Exception: %1$s in %2$s on line %3$s',
     1154                    $e->getMessage(),
     1155                    basename( $e->getFile() ),
     1156                    $e->getLine()
     1157                )
     1158            );
     1159            wp_send_json_success( array( 'message' => esc_html__( 'Widget import skipped (unexpected error)', 'athemes-starter-sites' ) ) );
     1160        }
     1161
    10681162    }
    10691163
     
    10731167    public function ajax_import_customizer() {
    10741168
    1075         check_ajax_referer( 'nonce', 'nonce' );
     1169        try {
     1170            check_ajax_referer( 'nonce', 'nonce' );
    10761171
    10771172        /**
     
    11341229         */
    11351230        wp_send_json_success();
     1231
     1232        } catch ( Exception $e ) {
     1233            wp_send_json_error(
     1234                sprintf(
     1235                    esc_html__( 'Customizer Import Exception: %1$s in %2$s on line %3$s', 'athemes-starter-sites' ),
     1236                    $e->getMessage(),
     1237                    basename( $e->getFile() ),
     1238                    $e->getLine()
     1239                )
     1240            );
     1241        }
    11361242
    11371243    }
  • athemes-starter-sites/trunk/v2/vendor/wp-content-importer-v2/WXRImporter.php

    r3059802 r3377550  
    1111
    1212class ATSS_WXRImporter extends WP_Importer {
     13   
     14    /**
     15     * Count of attachments processed in current AJAX request
     16     *
     17     * @var int
     18     */
     19    private $attachment_count = 0;
     20
    1321    /**
    1422     * Maximum supported WXR version
     
    19421950    /**
    19431951     * Attempt to download a remote file attachment.
     1952     * ENHANCED: Added error recovery and crash prevention
    19441953     *
    19451954     * @param string $url  URL of item to fetch.
     
    19491958     */
    19501959    protected function fetch_remote_file( $url, $post ) {
    1951         // extract the file name and extension from the url
    1952         $file_name = basename( $url );
    1953 
    1954         // force to use exists file.
    1955         $upload_dir  = wp_upload_dir( $post['upload_date'] );
    1956         $exists_file = $upload_dir['path'] .'/'. $file_name;
    1957         $exists_url  = $upload_dir['url'] .'/'. $file_name;
    1958 
    1959         if ( file_exists( $exists_file ) ) {
    1960             $upload = array(
    1961                 'file' => $exists_file,
    1962                 'url'  => $exists_url,
    1963             );
    1964             return $upload;
    1965         }
    1966 
    1967         // get placeholder file in the upload dir with a unique, sanitized filename
    1968         $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
    1969 
    1970         if ( $upload['error'] ) {
    1971             return new WP_Error( 'upload_dir_error', $upload['error'] );
    1972         }
    1973 
    1974         // fetch the remote url and write it to the placeholder file
    1975         $response = wp_remote_get( $url, array(
    1976             'stream' => true,
    1977             'filename' => $upload['file'],
    1978         ) );
    1979 
    1980         // request failed
    1981         if ( is_wp_error( $response ) ) {
    1982             unlink( $upload['file'] );
    1983             return $response;
    1984         }
    1985 
    1986         $code = (int) wp_remote_retrieve_response_code( $response );
    1987 
    1988         // make sure the fetch was successful
    1989         if ( $code !== 200 ) {
    1990             unlink( $upload['file'] );
    1991             return new WP_Error(
    1992                 'import_file_error',
    1993                 sprintf(
     1960        // Wrap entire download in try-catch to prevent crashes
     1961        try {
     1962            // Increment attachment counter for AJAX splitting
     1963            $this->attachment_count++;
     1964           
     1965            // extract the file name and extension from the url
     1966            $file_name = basename( $url );
     1967
     1968            // force to use exists file.
     1969            $upload_dir  = wp_upload_dir( $post['upload_date'] );
     1970            $exists_file = $upload_dir['path'] .'/'. $file_name;
     1971            $exists_url  = $upload_dir['url'] .'/'. $file_name;
     1972
     1973            if ( file_exists( $exists_file ) ) {
     1974                $upload = array(
     1975                    'file' => $exists_file,
     1976                    'url'  => $exists_url,
     1977                );
     1978                return $upload;
     1979            }
     1980
     1981            // get placeholder file in the upload dir with a unique, sanitized filename
     1982            $upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
     1983
     1984            if ( $upload['error'] ) {
     1985                return new WP_Error( 'upload_dir_error', $upload['error'] );
     1986            }
     1987
     1988            // Set timeout
     1989            $timeout = apply_filters( 'atss_attachment_download_timeout', 30 );
     1990           
     1991            // fetch the remote url and write it to the placeholder file
     1992            $response = wp_remote_get( $url, array(
     1993                'stream'   => true,
     1994                'filename' => $upload['file'],
     1995                'timeout'  => $timeout,
     1996                'blocking' => true,
     1997            ) );
     1998
     1999            // request failed
     2000            if ( is_wp_error( $response ) ) {
     2001                @unlink( $upload['file'] );
     2002                // Return error but don't crash
     2003                return $response;
     2004            }
     2005
     2006            $code = (int) wp_remote_retrieve_response_code( $response );
     2007
     2008            // make sure the fetch was successful
     2009            if ( $code !== 200 ) {
     2010                @unlink( $upload['file'] );
     2011                $error_msg = sprintf(
    19942012                    __( 'Remote server returned %1$d %2$s for %3$s', 'wordpress-importer' ),
    19952013                    $code,
    19962014                    get_status_header_desc( $code ),
    19972015                    $url
    1998                 )
    1999             );
    2000         }
    2001 
    2002         $filesize = @filesize( $upload['file'] );
    2003         $headers = wp_remote_retrieve_headers( $response );
    2004 
    2005         // OCDI fix!
    2006         // Smaller images with server compression do not pass this rule.
    2007         // More info here: https://github.com/proteusthemes/WordPress-Importer/pull/2
    2008         //
    2009         // if ( isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
    2010         //  unlink( $upload['file'] );
    2011         //  return new WP_Error( 'import_file_error', __( 'Remote file is incorrect size', 'wordpress-importer' ) );
    2012         // }
    2013 
    2014         if ( 0 === $filesize ) {
    2015             unlink( $upload['file'] );
    2016             return new WP_Error( 'import_file_error', __( 'Zero size file downloaded', 'wordpress-importer' ) );
    2017         }
    2018 
    2019         $max_size = (int) $this->max_attachment_size();
    2020         if ( ! empty( $max_size ) && $filesize > $max_size ) {
    2021             unlink( $upload['file'] );
    2022             $message = sprintf( __( 'Remote file is too large, limit is %s', 'wordpress-importer' ), size_format( $max_size ) );
    2023             return new WP_Error( 'import_file_error', $message );
    2024         }
    2025 
    2026         return $upload;
     2016                );
     2017                return new WP_Error( 'import_file_error', $error_msg );
     2018            }
     2019
     2020            $filesize = @filesize( $upload['file'] );
     2021            $headers = wp_remote_retrieve_headers( $response );
     2022
     2023            // OCDI fix!
     2024            // Smaller images with server compression do not pass this rule.
     2025            // More info here: https://github.com/proteusthemes/WordPress-Importer/pull/2
     2026            //
     2027            // if ( isset( $headers['content-length'] ) && $filesize !== (int) $headers['content-length'] ) {
     2028            //  unlink( $upload['file'] );
     2029            //  return new WP_Error( 'import_file_error', __( 'Remote file is incorrect size', 'wordpress-importer' ) );
     2030            // }
     2031
     2032            if ( 0 === $filesize ) {
     2033                @unlink( $upload['file'] );
     2034                return new WP_Error( 'import_file_error', __( 'Zero size file downloaded', 'wordpress-importer' ) );
     2035            }
     2036
     2037            $max_size = (int) $this->max_attachment_size();
     2038            if ( ! empty( $max_size ) && $filesize > $max_size ) {
     2039                @unlink( $upload['file'] );
     2040                $message = sprintf( __( 'Remote file is too large, limit is %s', 'wordpress-importer' ), size_format( $max_size ) );
     2041                return new WP_Error( 'import_file_error', $message );
     2042            }
     2043
     2044            return $upload;
     2045           
     2046        } catch ( Exception $e ) {
     2047            // Catch any exceptions instead of crashing
     2048            if ( isset( $upload['file'] ) && file_exists( $upload['file'] ) ) {
     2049                @unlink( $upload['file'] );
     2050            }
     2051            $error_msg = sprintf( 'Exception downloading %s: %s', $url, $e->getMessage() );
     2052            return new WP_Error( 'import_exception', $error_msg );
     2053        } catch ( Error $e ) {
     2054            // Catch PHP 7+ fatal errors
     2055            if ( isset( $upload['file'] ) && file_exists( $upload['file'] ) ) {
     2056                @unlink( $upload['file'] );
     2057            }
     2058            $error_msg = sprintf( 'Error downloading %s: %s', $url, $e->getMessage() );
     2059            return new WP_Error( 'import_error', $error_msg );
     2060        }
    20272061    }
    20282062
     
    26202654        $this->exists['term'][ $exists_key ] = $term_id;
    26212655    }
     2656
     2657    /**
     2658     * Get attachment count for current request
     2659     *
     2660     * @return int
     2661     */
     2662    public function get_attachment_count() {
     2663        return $this->attachment_count;
     2664    }
    26222665}
Note: See TracChangeset for help on using the changeset viewer.