diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dde1fe35..09bb75c1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ["7.4", "8.0", "8.1", "8.2", "8.3", "8.4", "8.5"] + php-version: ["7.4", "8.0", "8.1", "8.2", "8.3", "8.4", "8.5"] services: mysql: image: mariadb:11.4 @@ -43,6 +43,11 @@ jobs: run: | install-php-extensions mysqli gd bcmath || echo "Extensions may already be installed." + - name: Install Xdebug for Coverage + if: matrix.php-version == '8.3' + run: | + install-php-extensions xdebug || echo "Xdebug may already be installed." + - name: Self-update Composer run: | composer self-update || echo "Composer update skipped due to permission issue." @@ -67,15 +72,24 @@ jobs: rm -rf /tmp/wordpress-tests-lib /tmp/wordpress/ bash bin/install-wp-tests.sh wordpress_test root root mysql latest + - name: Run PHPUnit Tests + if: matrix.php-version != '8.3' + run: vendor/bin/phpunit + - name: Run PHPUnit Tests with Coverage - run: vendor/bin/phpunit --coverage-clover=coverage.xml + if: matrix.php-version == '8.3' + run: | + php -d zend_extension=xdebug.so -d xdebug.mode=coverage \ + vendor/bin/phpunit --coverage-clover=coverage.xml --coverage-text \ + | tee coverage-summary.txt - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 + - name: Upload coverage to Codecov + if: matrix.php-version == '8.3' + uses: codecov/codecov-action@v5 with: file: ./coverage.xml flags: unittests - name: codecov-umbrella + name: php-${{ matrix.php-version }} fail_ci_if_error: false env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/assets/js/functions.js b/assets/js/functions.js index 62e3539f..ff05ce7c 100644 --- a/assets/js/functions.js +++ b/assets/js/functions.js @@ -3,267 +3,320 @@ /* global wu_settings, wu_input_masks, wu_money_input_masks, Cleave, ClipboardJS, wu_fields, tinymce, wu_media_frame, fontIconPicker */ window.wu_initialize_tooltip = function() { - jQuery('[role="tooltip"]').tipTip({ - attribute: 'aria-label', - }); + jQuery('[role="tooltip"]').tipTip({ + attribute: 'aria-label', + }); }; // end wu_initialize_tooltip; window.wu_initialize_editors = function() { - jQuery('textarea[data-editor]').each(function() { + jQuery('textarea[data-editor]').each(function() { - tinymce.remove('#' + jQuery(this).attr('id')); + tinymce.remove('#' + jQuery(this).attr('id')); - tinymce.init({ - selector: '#' + jQuery(this).attr('id'), // change this value according to your HTML - menubar: '', - theme: 'modern', - ...wp.editor.getDefaultSettings().tinymce, - }); + tinymce.init({ + selector: '#' + jQuery(this).attr('id'), // change this value according to your HTML + menubar: '', + theme: 'modern', + ...wp.editor.getDefaultSettings().tinymce, + }); - }); + }); }; // end wu_initialize_editors window.wu_initialize_imagepicker = function() { - jQuery('.wu-wrapper-image-field').each(function() { + jQuery('.wu-wrapper-image-field').each(function() { - const that = jQuery(this); + const that = jQuery(this); - that.find('img').css({ - maxWidth: '100%', - }); + that.find('img').css({ + maxWidth: '100%', + }); - const value = that.find('img').attr('src'); + const value = that.find('img').attr('src'); - if (value) { + if (value) { - that.find('.wu-wrapper-image-field-upload-actions').show(); + that.find('.wu-wrapper-image-field-upload-actions').show(); - } else { - - that.find('.wu-add-image-wrapper').show(); - - } // end if; + } else { - that.on('click', 'a.wu-add-image', function() { + that.find('.wu-add-image-wrapper').show(); - if (typeof wu_media_frame !== 'undefined') { + } // end if; - wu_media_frame.open(); + that.on('click', 'a.wu-add-image', function() { - return; + if (typeof wu_media_frame !== 'undefined') { - } // end if; + wu_media_frame.open(); - wu_media_frame = wp.media({ - title: wu_fields.l10n.image_picker_title, - multiple: false, - button: { - text: wu_fields.l10n.image_picker_button_text, - }, - }); + return; - wu_media_frame.on('select', function() { + } // end if; - const mediaObject = wu_media_frame.state().get('selection').first().toJSON(); + wu_media_frame = wp.media({ + title: wu_fields.l10n.image_picker_title, + multiple: false, + button: { + text: wu_fields.l10n.image_picker_button_text, + }, + }); - const img_el = that.find('img'); + wu_media_frame.on('select', function() { - that.find('img').removeClass('wu-absolute').attr('src', mediaObject.url); + const mediaObject = wu_media_frame.state().get('selection').first().toJSON(); - that.find('.wubox').attr('href', mediaObject.url); + const img_el = that.find('img'); - that.find('input').val(mediaObject.id); + that.find('img').removeClass('wu-absolute').attr('src', mediaObject.url); - that.find('.wu-add-image-wrapper').hide(); + that.find('.wubox').attr('href', mediaObject.url); - img_el.on('load', function() { + that.find('input').val(mediaObject.id); - that.find('.wu-wrapper-image-field-upload-actions').show(); + that.find('.wu-add-image-wrapper').hide(); - }); + img_el.on('load', function() { - }); + that.find('.wu-wrapper-image-field-upload-actions').show(); - wu_media_frame.open(); + }); - }); + }); - that.find('.wu-remove-image').on('click', function(e) { + wu_media_frame.open(); - e.preventDefault(); + }); - that.find('img').removeAttr('src').addClass('wu-absolute'); + that.find('.wu-remove-image').on('click', function(e) { - that.find('input').val(''); + e.preventDefault(); - that.find('.wu-wrapper-image-field-upload-actions').hide(); + that.find('img').removeAttr('src').addClass('wu-absolute'); - that.find('.wu-add-image-wrapper').show(); + that.find('input').val(''); - }); + that.find('.wu-wrapper-image-field-upload-actions').hide(); - }); + that.find('.wu-add-image-wrapper').show(); + + }); + + }); }; // end wu_initialize_imagepicker window.wu_initialize_colorpicker = function() { - jQuery(document).ready(function() { + jQuery(document).ready(function() { - jQuery('.wu_color_field').each(function() { + jQuery('.wu_color_field').each(function() { - jQuery(this).wpColorPicker(); + jQuery(this).wpColorPicker(); - }); + }); - }); + }); }; // end wu_initialize_colorpicker; window.wu_initialize_iconfontpicker = function() { - jQuery(document).ready(function() { + jQuery(document).ready(function() { - if (jQuery('.wu_select_icon').length) { + if (jQuery('.wu_select_icon').length) { - jQuery('.wu_select_icon').fontIconPicker({ - theme: 'wu-theme', - }); + jQuery('.wu_select_icon').fontIconPicker({ + theme: 'wu-theme', + }); - } + } - }); + }); }; // end wu_initialize_iconfontpicker; window.wu_initialize_clipboardjs = function() { - new ClipboardJS('.wu-copy'); + // Prevent page jump on copy link click + jQuery(document).off('click.wu-copy').on('click.wu-copy', 'a.wu-copy[href="#"]', function(e) { + e.preventDefault(); + }); + + // Destroy previous instance to avoid duplicate handlers on repeated calls + if (window._wu_clipboard_instance) { + window._wu_clipboard_instance.destroy(); + } + + function showCopyFeedback(trigger) { + const $trigger = jQuery(trigger); + const $textNodes = $trigger.contents().filter(function() { + return this.nodeType === 3 && this.textContent.trim().length > 0; + }); + + if ($textNodes.length) { + const node = $textNodes[ 0 ]; + const originalText = node.textContent; + node.textContent = ' Copied!'; + setTimeout(function() { + node.textContent = originalText; + }, 2000); + } + } + + if (typeof ClipboardJS !== 'undefined') { + window._wu_clipboard_instance = new ClipboardJS('.wu-copy'); + + window._wu_clipboard_instance.on('success', function(e) { + showCopyFeedback(e.trigger); + e.clearSelection(); + }); + + window._wu_clipboard_instance.on('error', function(e) { + const text = e.trigger.getAttribute('data-clipboard-text'); + if (text && navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(text).then(function() { + showCopyFeedback(e.trigger); + }); + } + }); + } else { + // Fallback when ClipboardJS is not available + jQuery(document).off('click.wu-copy-fallback').on('click.wu-copy-fallback', '.wu-copy', function() { + const text = jQuery(this).attr('data-clipboard-text'); + const trigger = this; + if (text && navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(text).then(function() { + showCopyFeedback(trigger); + }); + } + }); + } }; // end wu_initialize_clipboardjs; // DatePicker; window.wu_initialize_datepickers = function() { - jQuery('.wu-datepicker, [wu-datepicker]').each(function() { + jQuery('.wu-datepicker, [wu-datepicker]').each(function() { - const $this = jQuery(this); + const $this = jQuery(this); - const format = $this.data('format'), - allow_time = $this.data('allow-time'); + const format = $this.data('format'), + allow_time = $this.data('allow-time'); - $this.flatpickr({ - animate: false, - // locale: wpu.datepicker_locale, - time_24hr: true, - enableTime: typeof allow_time === 'undefined' ? true : allow_time, - dateFormat: format, - allowInput: true, - defaultDate: $this.val(), - }); + $this.flatpickr({ + animate: false, + // locale: wpu.datepicker_locale, + time_24hr: true, + enableTime: typeof allow_time === 'undefined' ? true : allow_time, + dateFormat: format, + allowInput: true, + defaultDate: $this.val(), + }); - }); + }); }; // end wu_initialize_datepickers; window.wu_update_clock = function() { - // eslint-disable-next-line no-undef - const yourTimeZoneFrom = wu_ticker.server_clock_offset; // time zone value where you are at + // eslint-disable-next-line no-undef + const yourTimeZoneFrom = wu_ticker.server_clock_offset; // time zone value where you are at - const d = new Date(); - //get the timezone offset from local time in minutes + const d = new Date(); + //get the timezone offset from local time in minutes - // eslint-disable-next-line no-mixed-operators - const tzDifference = yourTimeZoneFrom * 60 + d.getTimezoneOffset(); + // eslint-disable-next-line no-mixed-operators + const tzDifference = yourTimeZoneFrom * 60 + d.getTimezoneOffset(); - //convert the offset to milliseconds, add to targetTime, and make a new Date - const offset = tzDifference * 60 * 1000; + //convert the offset to milliseconds, add to targetTime, and make a new Date + const offset = tzDifference * 60 * 1000; - function callback_update_clock() { + function callback_update_clock() { - const tDate = new Date(new Date().getTime() + offset); + const tDate = new Date(new Date().getTime() + offset); - const in_years = tDate.getFullYear(); + const in_years = tDate.getFullYear(); - let in_months = tDate.getMonth() + 1; + let in_months = tDate.getMonth() + 1; - let in_days = tDate.getDate(); + let in_days = tDate.getDate(); - let in_hours = tDate.getHours(); + let in_hours = tDate.getHours(); - let in_minutes = tDate.getMinutes(); + let in_minutes = tDate.getMinutes(); - let in_seconds = tDate.getSeconds(); + let in_seconds = tDate.getSeconds(); - if (in_months < 10) { + if (in_months < 10) { - in_months = '0' + in_months; + in_months = '0' + in_months; - } + } - if (in_days < 10) { + if (in_days < 10) { - in_days = '0' + in_days; + in_days = '0' + in_days; - } + } - if (in_minutes < 10) { + if (in_minutes < 10) { - in_minutes = '0' + in_minutes; + in_minutes = '0' + in_minutes; - } + } - if (in_seconds < 10) { + if (in_seconds < 10) { - in_seconds = '0' + in_seconds; + in_seconds = '0' + in_seconds; - } + } - if (in_hours < 10) { + if (in_hours < 10) { - in_hours = '0' + in_hours; + in_hours = '0' + in_hours; - } + } - jQuery('#wu-ticker').text(in_years + '-' + in_months + '-' + in_days + ' ' + in_hours + ':' + in_minutes + ':' + in_seconds); + jQuery('#wu-ticker').text(in_years + '-' + in_months + '-' + in_days + ' ' + in_hours + ':' + in_minutes + ':' + in_seconds); - } + } - function start_clock() { + function start_clock() { - setInterval(callback_update_clock, 500); + setInterval(callback_update_clock, 500); - } + } - start_clock(); + start_clock(); }; // eslint-disable-next-line no-unused-vars function wu_on_load() { - wu_initialize_tooltip(); + wu_initialize_tooltip(); - wu_initialize_datepickers(); + wu_initialize_datepickers(); - wu_initialize_colorpicker(); + wu_initialize_colorpicker(); - wu_initialize_iconfontpicker(); + wu_initialize_iconfontpicker(); - wu_initialize_editors(); + wu_initialize_editors(); - wu_update_clock(); + wu_update_clock(); - wu_initialize_clipboardjs(); + wu_initialize_clipboardjs(); - wu_initialize_imagepicker(); + wu_initialize_imagepicker(); - wu_image_preview(); + wu_image_preview(); } // end wu_on_load; @@ -272,178 +325,178 @@ window.wu_on_load = wu_on_load; // eslint-disable-next-line no-unused-vars window.wu_block_ui = function(el) { - jQuery(el).wu_block({ - message: '
', - overlayCSS: { - backgroundColor: '#FFF', - opacity: 0.6, - }, - css: { - padding: 0, - margin: 0, - width: '50%', - fontSize: '14px !important', - top: '40%', - left: '35%', - textAlign: 'center', - color: '#000', - border: 'none', - backgroundColor: 'none', - cursor: 'wait', - }, - }); - - const el_instance = jQuery(el); - - el_instance.unblock = jQuery(el).wu_unblock; - - return el_instance; + jQuery(el).wu_block({ + message: '', + overlayCSS: { + backgroundColor: '#FFF', + opacity: 0.6, + }, + css: { + padding: 0, + margin: 0, + width: '50%', + fontSize: '14px !important', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: 'none', + backgroundColor: 'none', + cursor: 'wait', + }, + }); + + const el_instance = jQuery(el); + + el_instance.unblock = jQuery(el).wu_unblock; + + return el_instance; }; function wu_format_money(value) { - value = parseFloat(value.toString().replace(/[^0-9\.]/g, '')); + value = parseFloat(value.toString().replace(/[^0-9\.]/g, '')); - const settings = wp.hooks.applyFilters('wu_format_money', { - currency: { - symbol: wu_settings.currency_symbol, // default currency symbol is '$' - format: wu_settings.currency_position, // controls output: %s = symbol, %v = value/number (can be object: see below) - decimal: wu_settings.decimal_separator, // decimal point separator - thousand: wu_settings.thousand_separator, // thousands separator - precision: wu_settings.precision, // decimal places - }, - number: { - precision: 0, // default precision on numbers is 0 - thousand: ',', - decimal: ',', - }, - }); + const settings = wp.hooks.applyFilters('wu_format_money', { + currency: { + symbol: wu_settings.currency_symbol, // default currency symbol is '$' + format: wu_settings.currency_position, // controls output: %s = symbol, %v = value/number (can be object: see below) + decimal: wu_settings.decimal_separator, // decimal point separator + thousand: wu_settings.thousand_separator, // thousands separator + precision: wu_settings.precision, // decimal places + }, + number: { + precision: 0, // default precision on numbers is 0 + thousand: ',', + decimal: ',', + }, + }); - accounting.settings = settings; + accounting.settings = settings; - return accounting.formatMoney(value); + return accounting.formatMoney(value); } // end wu_format_money; window.wu_image_preview = function() { - const xOffset = 10; + const xOffset = 10; - const yOffset = 30; + const yOffset = 30; - const preview_el = '#wu-image-preview'; + const preview_el = '#wu-image-preview'; - // eslint-disable-next-line eqeqeq - const selector = wu_settings.disable_image_zoom == true ? '.wu-image-preview:not(img)' : '.wu-image-preview'; + // eslint-disable-next-line eqeqeq + const selector = wu_settings.disable_image_zoom == true ? '.wu-image-preview:not(img)' : '.wu-image-preview'; - const el_id = preview_el.replace('#', ''); + const el_id = preview_el.replace('#', ''); - if (jQuery(preview_el).length === 0) { + if (jQuery(preview_el).length === 0) { - jQuery('body').append( - "',overlayCSS:{backgroundColor:"#FFF",opacity:.6},css:{padding:0,margin:0,width:"50%",fontSize:"14px !important",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"none",backgroundColor:"none",cursor:"wait"}});var i=jQuery(e);return i.unblock=jQuery(e).wu_unblock,i},window.wu_image_preview=function(){let t="#wu-image-preview";var e=1==wu_settings.disable_image_zoom?".wu-image-preview:not(img)":".wu-image-preview",i=t.replace("#","");0===jQuery(t).length&&jQuery("body").append(""),jQuery(e).hover(function(e){this.t=this.title,this.title="";var i=jQuery(this).data("image");jQuery(t).find("img").attr("src",i).attr("alt",this.t).end().css({position:"absolute",display:"none"}).css("top",e.pageY-10+"px").css("left",e.pageX+30+"px").fadeIn("fast")},function(){this.title=this.t,jQuery(t).fadeOut("fast")}),jQuery(e).mousemove(function(e){jQuery(t).css("top",e.pageY-10+"px").css("left",e.pageX+30+"px")})},window.wu_initialize_code_editors=function(){jQuery("[data-code-editor]").length&&(void 0===window.wu_editor_instances&&(window.wu_editor_instances={}),jQuery("[data-code-editor]").each(function(){var e=jQuery(this),i=e.attr("id");void 0===window.wu_editor_instances[i]&&e.is(":visible")&&(window.wu_editor_instances[i]=wp.codeEditor.initialize(i,{codemirror:{mode:e.data("code-editor"),lint:!0,autoCloseBrackets:!0,matchBrackets:!0,indentUnit:2,indentWithTabs:!0,lineNumbers:!0,lineWrapping:!0,styleActiveLine:!0,continueComments:!0,inputStyle:"contenteditable",direction:"ltr",gutters:[],extraKeys:{"Ctrl-Space":"autocomplete","Ctrl-/":"toggleComment","Cmd-/":"toggleComment","Alt-F":"findPersistent"}}}))}))},window.wu_moment=function(e){return moment.tz(e,"Etc/UTC")}; \ No newline at end of file diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..89b1e1e8 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,33 @@ +codecov: + require_ci_to_pass: false + +coverage: + status: + project: + default: + target: auto + threshold: 0% + informational: false + patch: + default: + target: 80% + threshold: 0% + informational: false + +comment: + layout: "reach,diff,flags,files" + behavior: default + require_changes: false + require_base: false + require_head: true + after_n_builds: 1 + show_carryforward_flags: true + +ignore: + - "inc/ui/**" + - "inc/views/**" + - "inc/assets/**" + - "inc/development/**" + - "inc/site-exporter/**" + - "tests/**" + - "vendor/**" diff --git a/inc/admin-pages/class-event-list-admin-page.php b/inc/admin-pages/class-event-list-admin-page.php index f7c0323f..feff7a08 100644 --- a/inc/admin-pages/class-event-list-admin-page.php +++ b/inc/admin-pages/class-event-list-admin-page.php @@ -64,7 +64,7 @@ class Event_List_Admin_Page extends List_Admin_Page { */ public function init(): void { - add_action('init', [$this, 'set_badge_count']); + add_action('admin_init', [$this, 'set_badge_count']); } /** diff --git a/inc/admin-pages/class-product-edit-admin-page.php b/inc/admin-pages/class-product-edit-admin-page.php index dd6b0637..6a4a1f2c 100644 --- a/inc/admin-pages/class-product-edit-admin-page.php +++ b/inc/admin-pages/class-product-edit-admin-page.php @@ -983,7 +983,9 @@ public function action_links() { 'label' => __('Click to copy Shareable Link', 'ultimate-multisite'), 'icon' => 'wu-attachment', 'classes' => 'wu-copy', - 'attrs' => 'data-clipboard-text="' . esc_attr($shareable_link) . '"', + 'attrs' => [ + 'data-clipboard-text' => $shareable_link, + ], ]; } diff --git a/inc/builders/block-editor/class-block-editor-widget-manager.php b/inc/builders/block-editor/class-block-editor-widget-manager.php index 01d37168..f18ec29e 100644 --- a/inc/builders/block-editor/class-block-editor-widget-manager.php +++ b/inc/builders/block-editor/class-block-editor-widget-manager.php @@ -34,7 +34,9 @@ public function init(): void { if (\WP_Ultimo\Compat\Gutenberg_Support::get_instance()->should_load()) { add_action('wu_element_loaded', [$this, 'handle_element']); - add_action('init', [$this, 'register_scripts']); + if (is_admin()) { + add_action('init', [$this, 'register_scripts']); + } add_filter('wu_element_is_preview', [$this, 'is_block_preview']); } diff --git a/inc/class-current.php b/inc/class-current.php index cf07e644..9297bfbe 100644 --- a/inc/class-current.php +++ b/inc/class-current.php @@ -222,6 +222,13 @@ public static function get_manage_url($id, $type = 'site') { */ public function load_currents(): void { + // On the wp hook, only re-run if we're on the frontend + // (query var overrides from pretty URLs only work there). + // On admin or AJAX, the init run already set everything. + if (did_action('init') && $this->site && (is_admin() || wp_doing_ajax())) { + return; + } + $site = false; /** diff --git a/inc/class-wp-ultimo.php b/inc/class-wp-ultimo.php index 1ff69b9a..9eee0c2a 100644 --- a/inc/class-wp-ultimo.php +++ b/inc/class-wp-ultimo.php @@ -670,167 +670,119 @@ function () { */ protected function load_admin_pages(): void { /* - * Migration Wizard Alert - */ - new WP_Ultimo\Admin_Pages\Migration_Alert_Admin_Page(); - - /* - * Loads the Dashboard admin page. - */ - new WP_Ultimo\Admin_Pages\Dashboard_Admin_Page(); - - /* - * The top admin navigation bar. + * These classes register hooks that fire on both frontend and admin + * (admin bar menus, nav menu filters), so they must always be loaded. */ new WP_Ultimo\Admin_Pages\Top_Admin_Nav_Menu(); - /* - * Initialize magic links for admin bar My Sites menu. - */ \WP_Ultimo\SSO\Admin_Bar_Magic_Links::get_instance(); + \WP_Ultimo\SSO\Nav_Menu_Subsite_Links::get_instance(); + /* - * Initialize subsite links for nav menus. + * My_Sites registers an admin_bar_menu hook for customer-owned sites, + * which fires on frontend for logged-in users. */ - \WP_Ultimo\SSO\Nav_Menu_Subsite_Links::get_instance(); + new WP_Ultimo\Admin_Pages\Customer_Panel\My_Sites_Admin_Page(); /* - * Loads the Checkout Form admin page. + * The remaining admin pages only register admin menu items, + * admin-only forms, and wp_ajax_ handlers. They are not needed + * on frontend requests. */ + if (is_admin() || wp_doing_ajax()) { + $this->load_admin_only_pages(); + } + + do_action('wp_ultimo_admin_pages'); + } + + /** + * Loads admin pages that are only needed on admin or AJAX requests. + * + * @since 2.5.0 + * @return void + */ + protected function load_admin_only_pages(): void { + + new WP_Ultimo\Admin_Pages\Migration_Alert_Admin_Page(); + + new WP_Ultimo\Admin_Pages\Dashboard_Admin_Page(); + new WP_Ultimo\Admin_Pages\Checkout_Form_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Checkout_Form_Edit_Admin_Page(); - /* - * Loads the Product Pages - */ new WP_Ultimo\Admin_Pages\Product_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Product_Edit_Admin_Page(); - /* - * Loads the Memberships Pages - */ new WP_Ultimo\Admin_Pages\Membership_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Membership_Edit_Admin_Page(); - /* - * Loads the Payments Pages - */ new WP_Ultimo\Admin_Pages\Payment_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Payment_Edit_Admin_Page(); - /* - * Loads the Customers Pages - */ new WP_Ultimo\Admin_Pages\Customer_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Customer_Edit_Admin_Page(); - /* - * Loads the Site Pages - */ new WP_Ultimo\Admin_Pages\Site_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Site_Edit_Admin_Page(); - /* - * Loads the Domain Pages - */ new WP_Ultimo\Admin_Pages\Domain_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Domain_Edit_Admin_Page(); - /* - * Loads the Discount Code Pages - */ new WP_Ultimo\Admin_Pages\Discount_Code_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Discount_Code_Edit_Admin_Page(); - /* - * Loads the Broadcast Pages - */ new WP_Ultimo\Admin_Pages\Broadcast_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Broadcast_Edit_Admin_Page(); - /* - * Loads the Broadcast Pages - */ new WP_Ultimo\Admin_Pages\Email_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Email_Edit_Admin_Page(); new WP_Ultimo\Admin_Pages\Email_Template_Customize_Admin_Page(); - /* - * Loads the Settings - */ new WP_Ultimo\Admin_Pages\Settings_Admin_Page(); new WP_Ultimo\Admin_Pages\Invoice_Template_Customize_Admin_Page(); new WP_Ultimo\Admin_Pages\Template_Previewer_Customize_Admin_Page(); - /* - * Loads the Hosting Integration - */ new WP_Ultimo\Admin_Pages\Hosting_Integration_Wizard_Admin_Page(); - /* - * Loads the Events Pages - */ new WP_Ultimo\Admin_Pages\Event_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Event_View_Admin_Page(); - /* - * Loads the Webhooks Pages - */ new WP_Ultimo\Admin_Pages\Webhook_List_Admin_Page(); new WP_Ultimo\Admin_Pages\Webhook_Edit_Admin_Page(); - /* - * Loads the Jobs Pages - */ new WP_Ultimo\Admin_Pages\Jobs_List_Admin_Page(); - /* - * Loads the System Info Pages - */ new WP_Ultimo\Admin_Pages\System_Info_Admin_Page(); - /* - * Loads the Shortcodes Page - */ new WP_Ultimo\Admin_Pages\Shortcodes_Admin_Page(); - /* - * Loads the View Logs Pages - */ new WP_Ultimo\Admin_Pages\View_Logs_Admin_Page(); - /* - * Loads the View Logs Pages - */ new WP_Ultimo\Admin_Pages\Customer_Panel\Account_Admin_Page(); - new WP_Ultimo\Admin_Pages\Customer_Panel\My_Sites_Admin_Page(); new WP_Ultimo\Admin_Pages\Customer_Panel\Add_New_Site_Admin_Page(); new WP_Ultimo\Admin_Pages\Customer_Panel\Checkout_Admin_Page(); new WP_Ultimo\Admin_Pages\Customer_Panel\Template_Switching_Admin_Page(); - /* - * Loads the Tax Pages - */ new WP_Ultimo\Tax\Dashboard_Taxes_Tab(); new WP_Ultimo\Admin_Pages\Addons_Admin_Page(); - - do_action('wp_ultimo_admin_pages'); } /** diff --git a/inc/helpers/class-arr.php b/inc/helpers/class-arr.php index aa328f2e..c60659b7 100644 --- a/inc/helpers/class-arr.php +++ b/inc/helpers/class-arr.php @@ -139,10 +139,9 @@ public static function set(&$array_to_modify, $key, $value) { return $array_to_modify = $value; // phpcs:ignore } - $keys = explode('.', $key); - $keys_count = count($keys); + $keys = explode('.', $key); - while ($keys_count > 1) { + while (count($keys) > 1) { $key = array_shift($keys); if ( ! isset($array_to_modify[ $key ]) || ! is_array($array_to_modify[ $key ])) { diff --git a/inc/helpers/class-wp-config.php b/inc/helpers/class-wp-config.php index fd1cbc96..ece41ab1 100644 --- a/inc/helpers/class-wp-config.php +++ b/inc/helpers/class-wp-config.php @@ -105,8 +105,16 @@ public function get_wp_config_path() { } elseif (@file_exists(dirname(ABSPATH) . '/wp-config.php') && ! @file_exists(dirname(ABSPATH) . '/wp-settings.php')) { return (dirname(ABSPATH) . '/wp-config.php'); } elseif (defined('WP_TESTS_MULTISITE') && constant('WP_TESTS_MULTISITE') === true) { - return '/tmp/wordpress-tests-lib/wp-tests-config.php'; + $tests_dir = getenv('WP_TESTS_DIR'); + + if (! $tests_dir) { + $tests_dir = rtrim(sys_get_temp_dir(), '/\\') . '/wordpress-tests-lib'; + } + + return $tests_dir . '/wp-tests-config.php'; } + + return ABSPATH . 'wp-config.php'; } /** diff --git a/inc/models/class-base-model.php b/inc/models/class-base-model.php index ee53f7a1..7f3de75c 100644 --- a/inc/models/class-base-model.php +++ b/inc/models/class-base-model.php @@ -736,12 +736,9 @@ public function get_meta($key, $default_value = false, $single = true) { } $meta_type = $this->get_meta_type_name(); + $value = get_metadata_raw($meta_type, $this->get_id(), $key, $single); - if (metadata_exists($meta_type, $this->get_id(), $key)) { - return get_metadata($meta_type, $this->get_id(), $key, $single); - } - - return $default_value; + return ! is_null($value) ? $value : $default_value; } /** diff --git a/package.json b/package.json index c1296d1c..33e2f3ac 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "cleancss": "node scripts/cleancss.js", "makepot": "node scripts/makepot.js", "test": "vendor/bin/phpunit", - "test:coverage": "vendor/bin/phpunit --coverage-html=coverage-html --coverage-clover=coverage.xml", + "test:coverage": "php -d zend_extension=xdebug -d xdebug.mode=coverage vendor/bin/phpunit --coverage-html=coverage-html --coverage-clover=coverage.xml --coverage-text", "test:watch": "vendor/bin/phpunit --watch", "lint": "run-p lint:php lint:js lint:css", "lint:php": "vendor/bin/phpcs", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0efc6388..cf5f552b 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,5 +1,5 @@ -