diff --git a/composer.json b/composer.json index 5df473acfe..823f981a54 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,8 @@ "WeDevs\\Dokan\\": "includes/" }, "files": [ - "includes/functions-rest-api.php" + "includes/functions-rest-api.php", + "includes/functions-dashboard-navigation.php" ] }, "scripts": { diff --git a/includes/Dashboard/Templates/Dashboard.php b/includes/Dashboard/Templates/Dashboard.php index 11861d956a..77f9b3e9c3 100644 --- a/includes/Dashboard/Templates/Dashboard.php +++ b/includes/Dashboard/Templates/Dashboard.php @@ -35,7 +35,7 @@ public function __construct() { } /** - * Get Seller Dhasboard Notice + * Get Seller Dashboard Notice * * @since 2.4 * @@ -55,6 +55,10 @@ public function show_seller_dashboard_notice() { * @return void */ public function get_big_counter_widgets() { + if ( ! apply_filters( 'dokan_dashboard_widget_applicable', true, 'reports' ) ) { + return; + } + if ( ! current_user_can( 'dokan_view_sales_overview' ) ) { return; } @@ -81,6 +85,10 @@ public function get_big_counter_widgets() { * @return void */ public function get_orders_widgets() { + if ( ! apply_filters( 'dokan_dashboard_widget_applicable', true, 'orders' ) ) { + return; + } + if ( ! current_user_can( 'dokan_view_order_report' ) ) { return; } @@ -190,6 +198,10 @@ public function get_orders_widgets() { * @return void */ public function get_products_widgets() { + if ( ! apply_filters( 'dokan_dashboard_widget_applicable', true, 'products' ) ) { + return; + } + if ( ! current_user_can( 'dokan_view_product_status_report' ) ) { return; } @@ -232,6 +244,10 @@ public function get_products_widgets() { * @return void */ public function get_sales_report_chart_widget() { + if ( ! apply_filters( 'dokan_dashboard_widget_applicable', true, 'reports' ) ) { + return; + } + if ( ! current_user_can( 'dokan_view_sales_report_chart' ) ) { return; } diff --git a/includes/ReverseWithdrawal/Hooks.php b/includes/ReverseWithdrawal/Hooks.php index b39f2e9a3e..80fe4bf9be 100644 --- a/includes/ReverseWithdrawal/Hooks.php +++ b/includes/ReverseWithdrawal/Hooks.php @@ -40,7 +40,7 @@ public function __construct() { add_action( 'woocommerce_order_status_changed', [ $this, 'process_order_status_changed' ], 10, 3 ); // vendor dashboard navigation url - add_filter( 'dokan_get_dashboard_nav', [ $this, 'add_reverse_withdrawal_nav' ], 10, 2 ); + add_filter( 'dokan_get_dashboard_nav', [ $this, 'add_reverse_withdrawal_nav' ], 10 ); } /** diff --git a/includes/Shortcodes/Dashboard.php b/includes/Shortcodes/Dashboard.php index b1edd85b18..552b6ce499 100644 --- a/includes/Shortcodes/Dashboard.php +++ b/includes/Shortcodes/Dashboard.php @@ -32,7 +32,22 @@ public function render_shortcode( $atts ) { ob_start(); - if ( isset( $wp->query_vars['products'] ) ) { + /** + * Filter query var before rendering dokan vendor shortcode + */ + $query_vars = apply_filters( 'dokan_dashboard_shortcode_query_vars', $wp->query_vars ); + + if ( is_wp_error( $query_vars ) ) { + dokan_get_template_part( + 'global/dokan-error', '', [ + 'deleted' => false, + 'message' => $query_vars->get_error_message(), + ] + ); + return ob_get_clean(); + } + + if ( isset( $query_vars['products'] ) ) { if ( ! current_user_can( 'dokan_view_product_menu' ) ) { dokan_get_template_part( 'global/no-permission' ); } else { @@ -42,7 +57,7 @@ public function render_shortcode( $atts ) { return ob_get_clean(); } - if ( isset( $wp->query_vars['new-product'] ) ) { + if ( isset( $query_vars['new-product'] ) ) { if ( ! current_user_can( 'dokan_add_product' ) ) { dokan_get_template_part( 'global/no-permission' ); } else { @@ -52,7 +67,7 @@ public function render_shortcode( $atts ) { return ob_get_clean(); } - if ( isset( $wp->query_vars['orders'] ) ) { + if ( isset( $query_vars['orders'] ) ) { if ( ! current_user_can( 'dokan_view_order_menu' ) ) { dokan_get_template_part( 'global/no-permission' ); } else { @@ -62,7 +77,7 @@ public function render_shortcode( $atts ) { return ob_get_clean(); } - if ( isset( $wp->query_vars['withdraw'] ) ) { + if ( isset( $query_vars['withdraw'] ) ) { if ( ! current_user_can( 'dokan_view_withdraw_menu' ) ) { dokan_get_template_part( 'global/no-permission' ); } else { @@ -72,7 +87,7 @@ public function render_shortcode( $atts ) { return ob_get_clean(); } - if ( isset( $wp->query_vars['reverse-withdrawal'] ) ) { + if ( isset( $query_vars['reverse-withdrawal'] ) ) { if ( ! current_user_can( 'dokan_view_withdraw_menu' ) ) { dokan_get_template_part( 'global/no-permission' ); } else { @@ -82,13 +97,13 @@ public function render_shortcode( $atts ) { return ob_get_clean(); } - if ( isset( $wp->query_vars['settings'] ) ) { + if ( isset( $query_vars['settings'] ) ) { dokan_get_template_part( 'settings/store' ); return ob_get_clean(); } - if ( isset( $wp->query_vars['page'] ) ) { + if ( isset( $query_vars['page'] ) ) { if ( ! current_user_can( 'dokan_view_overview_menu' ) ) { dokan_get_template_part( 'global/no-permission' ); } else { @@ -97,13 +112,13 @@ public function render_shortcode( $atts ) { return ob_get_clean(); } - if ( isset( $wp->query_vars['edit-account'] ) ) { + if ( isset( $query_vars['edit-account'] ) ) { dokan_get_template_part( 'dashboard/edit-account' ); return ob_get_clean(); } - do_action( 'dokan_load_custom_template', $wp->query_vars ); + do_action( 'dokan_load_custom_template', $query_vars ); return ob_get_clean(); } diff --git a/includes/functions-dashboard-navigation.php b/includes/functions-dashboard-navigation.php new file mode 100644 index 0000000000..57577759b4 --- /dev/null +++ b/includes/functions-dashboard-navigation.php @@ -0,0 +1,302 @@ + [ + 'title' => __( 'Dashboard', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url(), + 'pos' => 10, + 'permission' => 'dokan_view_overview_menu', + ], + 'products' => [ + 'title' => __( 'Products', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url( 'products' ), + 'pos' => 30, + 'permission' => 'dokan_view_product_menu', + ], + 'orders' => [ + 'title' => __( 'Orders', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url( 'orders' ), + 'pos' => 50, + 'permission' => 'dokan_view_order_menu', + ], + 'withdraw' => [ + 'title' => __( 'Withdraw', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url( 'withdraw' ), + 'pos' => 70, + 'permission' => 'dokan_view_withdraw_menu', + ], + 'settings' => [ + 'title' => __( 'Settings', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url( 'settings/store' ), + 'pos' => 200, + ], + ]; + + $settings_sub = [ + 'store' => [ + 'title' => __( 'Store', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url( 'settings/store' ), + 'pos' => 30, + 'permission' => 'dokan_view_store_settings_menu', + ], + 'payment' => [ + 'title' => __( 'Payment', 'dokan-lite' ), + 'icon' => '', + 'url' => dokan_get_navigation_url( 'settings/payment' ), + 'pos' => 50, + 'permission' => 'dokan_view_store_payment_menu', + ], + ]; + + /** + * Filter to get the seller dashboard settings navigation. + * + * @since 2.2 + * + * @param array. + */ + $menus['settings']['submenu'] = apply_filters( 'dokan_get_dashboard_settings_nav', $settings_sub ); + + /** + * Filters nav menu items. + * + * @param array $menus + */ + $nav_menus = apply_filters( 'dokan_get_dashboard_nav', $menus ); + + foreach ( $nav_menus as $nav_key => $menu ) { + if ( ! isset( $menu['pos'] ) ) { + $nav_menus[ $nav_key ]['pos'] = 190; + } + + $submenu_items = empty( $menu['submenu'] ) ? [] : $menu['submenu']; + + /** + * Filters the vendor dashboard submenu item for each menu. + * + * @since 3.7.7 + * + * @param array $submenu_items Associative array of submenu items. + * @param string $menu_key Key of the corresponding menu. + */ + $submenu_items = apply_filters( 'dokan_dashboard_nav_submenu', $submenu_items, $nav_key ); + + if ( empty( $submenu_items ) ) { + continue; + } + + foreach ( $submenu_items as $key => $submenu ) { + if ( ! isset( $submenu['pos'] ) ) { + $submenu['pos'] = 200; + } + + $submenu_items[ $key ] = $submenu; + } + + // Sort items according to positional value + uasort( $submenu_items, 'dokan_nav_sort_by_pos' ); + + // Filter items according to permissions + $submenu_items = array_filter( $submenu_items, 'dokan_check_menu_permission' ); + + // Manage a menu with submenus after permission check + if ( count( $submenu_items ) < 1 ) { + unset( $nav_menus[ $nav_key ] ); + } else { + $nav_menus[ $nav_key ]['submenu'] = $submenu_items; + } + } + + // Sort items according to positional value + uasort( $nav_menus, 'dokan_nav_sort_by_pos' ); + + // Filter the main menu according to permission + $nav_menus = array_filter( $nav_menus, 'dokan_check_menu_permission' ); + + return $nav_menus; +} + +/** + * Checking menu permissions + * + * @since 2.7.3 + * @since DOKAN_SINCE moved this method from includes/template-tags.php + * + * @return boolean + */ +function dokan_check_menu_permission( $menu ) { + if ( isset( $menu['permission'] ) && ! current_user_can( $menu['permission'] ) ) { + return false; + } + + return true; +} + +/** + * Renders the Dokan dashboard menu + * + * For settings menu, the active menu format is `settings/menu_key_name`. + * The active menu will be split at `/` and the `menu_key_name` will be matched + * with a settings sub menu array. If it's a match, the settings menu will be shown + * only. Otherwise, the main navigation menu will be shown. + * + * @since DOKAN_SINCE moved this method from includes/template-tags.php + * + * @param string $active_menu + * + * @return string rendered menu HTML + */ +function dokan_dashboard_nav( $active_menu = '' ) { + $nav_menu = dokan_get_dashboard_nav(); + $active_menu_parts = explode( '/', $active_menu ); + $active_submenu = ''; + + if ( $active_menu && false !== strpos( $active_menu, '/' ) ) { + $active_menu = $active_menu_parts[0]; + $active_submenu = $active_menu_parts[1]; + } + + $menu = ''; + $hamburger_menu = apply_filters( 'dokan_load_hamburger_menu', true ); + + if ( $hamburger_menu ) { + $menu .= '
'; + $hamburger = apply_filters( + 'dokan_vendor_dashboard_menu_hamburger', + '' + ); + + $menu .= $hamburger; + } + + $menu .= '
    '; + + foreach ( $nav_menu as $key => $item ) { + // If switched off from menu manager + if ( isset( $item['is_switched_on'] ) && ! $item['is_switched_on'] ) { + continue; + } + /** + * Filters a menu key according to slug if needed. + * + * @since DOKAN_PRO_SINCE + * + * @param string $menu_key + */ + $filtered_key = apply_filters( 'dokan_dashboard_nav_menu_key', $key ); + + $class = $active_menu === $filtered_key || 0 === stripos( $active_menu, $filtered_key ) ? 'active ' . $key : $key; // checking starts with the key + $title = __( 'No Title', 'dokan-lite' ); + if ( ! empty( $item['menu_manager_title'] ) ) { + $title = $item['menu_manager_title']; + } elseif ( ! empty( $item['title'] ) ) { + $title = $item['title']; + } + $menu_slug = $filtered_key; + $submenu = ''; + + if ( ! empty( $item['submenu'] ) ) { + $class .= ' has-submenu'; + $title .= ' '; + $submenu = sprintf( ''; + + // Building parent menu slug pointing to the first submenu item + if ( isset( $subkey_slugs[0] ) ) { + $menu_slug = trailingslashit( $menu_slug ) . $subkey_slugs[0]; + } + } + + $menu .= sprintf( + '
  • %s %s%s
  • ', + $class, + isset( $item['url'] ) ? $item['url'] : dokan_get_navigation_url( $menu_slug ), + isset( $item['icon'] ) ? $item['icon'] : '', + $title, + $submenu + ); + } + + $common_links = ''; + + $menu .= apply_filters( 'dokan_dashboard_nav_common_link', $common_links ); + + $menu .= '
'; + + if ( $hamburger_menu ) { + $menu .= '
'; + } + + return $menu; +} diff --git a/includes/functions.php b/includes/functions.php index 42f0ff66f6..f68e2b465e 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -1131,18 +1131,17 @@ function dokan_redirect_to_register() { /** * Check if the seller is enabled * + * @since DOKAN_SINCE New filter added `dokan_is_seller_enabled` + * * @param int $user_id * * @return bool */ -function dokan_is_seller_enabled( $user_id ) { - $selling = get_user_meta( $user_id, 'dokan_enable_selling', true ); - - if ( $selling === 'yes' ) { - return true; - } - - return false; +function dokan_is_seller_enabled( $user_id ): bool { + return apply_filters( + 'dokan_is_seller_enabled', + 'yes' === get_user_meta( $user_id, 'dokan_enable_selling', 'no' ) + ); } /** diff --git a/includes/template-tags.php b/includes/template-tags.php index 4b8b595032..01fd7a62e2 100755 --- a/includes/template-tags.php +++ b/includes/template-tags.php @@ -384,275 +384,6 @@ function dokan_order_listing_status_filter() { array( - 'title' => __( 'Dashboard', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url(), - 'pos' => 10, - 'permission' => 'dokan_view_overview_menu', - ), - 'products' => array( - 'title' => __( 'Products', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url( 'products' ), - 'pos' => 30, - 'permission' => 'dokan_view_product_menu', - ), - 'orders' => array( - 'title' => __( 'Orders', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url( 'orders' ), - 'pos' => 50, - 'permission' => 'dokan_view_order_menu', - ), - 'withdraw' => array( - 'title' => __( 'Withdraw', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url( 'withdraw' ), - 'pos' => 70, - 'permission' => 'dokan_view_withdraw_menu', - ), - 'settings' => array( - 'title' => __( 'Settings', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url( 'settings/store' ), - 'pos' => 200, - ), - ); - - $settings_sub = array( - 'store' => array( - 'title' => __( 'Store', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url( 'settings/store' ), - 'pos' => 30, - 'permission' => 'dokan_view_store_settings_menu', - ), - 'payment' => array( - 'title' => __( 'Payment', 'dokan-lite' ), - 'icon' => '', - 'url' => dokan_get_navigation_url( 'settings/payment' ), - 'pos' => 50, - 'permission' => 'dokan_view_store_payment_menu', - ), - ); - - /** - * Filter to get the seller dashboard settings navigation. - * - * @since 2.2 - * - * @param array. - */ - $menus['settings']['submenu'] = apply_filters( 'dokan_get_dashboard_settings_nav', $settings_sub ); - - /** - * Filters nav menu items. - * - * @param array $menus - */ - $nav_menus = apply_filters( 'dokan_get_dashboard_nav', $menus ); - - foreach ( $nav_menus as $nav_key => $menu ) { - if ( ! isset( $menu['pos'] ) ) { - $nav_menus[ $nav_key ]['pos'] = 190; - } - - $submenu_items = empty( $menu['submenu'] ) ? [] : $menu['submenu']; - - /** - * Filters the vendor dashboard submenu item for each menu. - * - * @since 3.7.7 - * - * @param array $submenu_items Associative array of submenu items. - * @param string $menu_key Key of the corresponding menu. - */ - $submenu_items = apply_filters( 'dokan_dashboard_nav_submenu', $submenu_items, $nav_key ); - - if ( empty( $submenu_items ) ) { - continue; - } - - foreach ( $submenu_items as $key => $submenu ) { - if ( ! isset( $submenu['pos'] ) ) { - $submenu['pos'] = 200; - } - - $submenu_items[ $key ] = $submenu; - } - - // Sort items according to positional value - uasort( $submenu_items, 'dokan_nav_sort_by_pos' ); - - // Filter items according to permissions - $submenu_items = array_filter( $submenu_items, 'dokan_check_menu_permission' ); - - // Manage menu with submenus after permission check - if ( count( $submenu_items ) < 1 ) { - unset( $nav_menus[ $nav_key ] ); - } else { - $nav_menus[ $nav_key ]['submenu'] = $submenu_items; - } - } - - // Sort items according to positional value - uasort( $nav_menus, 'dokan_nav_sort_by_pos' ); - - // Filter main menu according to permission - $nav_menus = array_filter( $nav_menus, 'dokan_check_menu_permission' ); - - return $nav_menus; -} - -/** - * Checking menu permissions - * - * @since 2.7.3 - * - * @return boolean - */ -function dokan_check_menu_permission( $menu ) { - if ( isset( $menu['permission'] ) && ! current_user_can( $menu['permission'] ) ) { - return false; - } - - return true; -} - -/** - * Renders the Dokan dashboard menu - * - * For settings menu, the active menu format is `settings/menu_key_name`. - * The active menu will be splitted at `/` and the `menu_key_name` will be matched - * with settings sub menu array. If it's a match, the settings menu will be shown - * only. Otherwise the main navigation menu will be shown. - * - * @param string $active_menu - * - * @return string rendered menu HTML - */ -function dokan_dashboard_nav( $active_menu = '' ) { - $nav_menu = dokan_get_dashboard_nav(); - $active_menu_parts = explode( '/', $active_menu ); - $active_submenu = ''; - - if ( $active_menu && false !== strpos( $active_menu, '/' ) ) { - $active_menu = $active_menu_parts[0]; - $active_submenu = $active_menu_parts[1]; - } - - $menu = ''; - $hamburger_menu = apply_filters( 'dokan_load_hamburger_menu', true ); - - if ( $hamburger_menu ) { - $menu .= '
'; - $hamburger = apply_filters( - 'dokan_vendor_dashboard_menu_hamburger', - '' - ); - - $menu .= $hamburger; - } - - $menu .= '
    '; - - foreach ( $nav_menu as $key => $item ) { - /** - * Filters menu key according to slug if needed. - * - * @since DOKAN_PRO_SINCE - * - * @param string $menu_key - */ - $filtered_key = rawurlencode_deep( apply_filters( 'dokan_dashboard_nav_menu_key', $key ) ); - - $class = $active_menu === $filtered_key || 0 === stripos( $active_menu, $filtered_key ) ? 'active ' . $key : $key; // checking starts with the key - $title = isset( $item['title'] ) ? $item['title'] : __( 'No title', 'dokan-lite' ); - $menu_slug = $filtered_key; - $submenu = ''; - - if ( ! empty( $item['submenu'] ) ) { - $class .= ' has-submenu'; - $title .= ' '; - $submenu = sprintf( ''; - - // Building parent menu slug pointing to the first submenu item - if ( isset( $subkey_slugs[0] ) ) { - $menu_slug = trailingslashit( $menu_slug ) . $subkey_slugs[0]; - } - } - - $menu .= sprintf( - '
  • %s %s%s
  • ', - $class, - isset( $item['url'] ) ? $item['url'] : dokan_get_navigation_url( $menu_slug ), - isset( $item['icon'] ) ? $item['icon'] : '', - $title, - $submenu - ); - } - - $common_links = ''; - - $menu .= apply_filters( 'dokan_dashboard_nav_common_link', $common_links ); - - $menu .= '
'; - - if ( $hamburger_menu ) { - $menu .= '
'; - } - - return $menu; -} - - if ( ! function_exists( 'dokan_store_category_menu' ) ) : /** diff --git a/package.json b/package.json index b3d30ec331..e40adc7380 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "vue-template-compiler": "^2.7.14", "vue-wp-list-table": "^1.3.0", "vue2-daterange-picker": "^0.6.8", - "wp-readme-to-markdown": "^1.0.1" + "wp-readme-to-markdown": "^1.0.1", + "vuedraggable": "^2.24.3" } } diff --git a/src/admin/components/Fields.vue b/src/admin/components/Fields.vue index 7fa859e746..83c5a996a9 100644 --- a/src/admin/components/Fields.vue +++ b/src/admin/components/Fields.vue @@ -448,6 +448,7 @@ import FieldHeading from './FieldHeading.vue'; import SecretInput from './SecretInput.vue'; import WithdrawCharges from './Fields/WithdrawCharges.vue' + let Mapbox = dokan_get_lib('Mapbox'); let TextEditor = dokan_get_lib('TextEditor'); let GoogleMaps = dokan_get_lib('GoogleMaps'); @@ -501,6 +502,14 @@ }); }, + watch: { + fieldValue: { + handler() { + }, + deep: true, + } + }, + computed: { shouldShow(e) { let shouldShow = true; diff --git a/src/admin/pages/Settings.vue b/src/admin/pages/Settings.vue index 0b08be66f2..b6da8af607 100644 --- a/src/admin/pages/Settings.vue +++ b/src/admin/pages/Settings.vue @@ -72,7 +72,17 @@ :dokanAssetsUrl="dokanAssetsUrl" /> -

+

+ +

@@ -134,6 +144,7 @@ disbursementSchedule: {}, isSaveConfirm: false, dokanAssetsUrl: dokan.urls.assetsUrl, + disableSubmit: false, } }, @@ -576,6 +587,11 @@ this.settingFields = dokan.settings_fields; window.addEventListener( 'scroll', this.handleScroll ); }, + mounted() { + this.$root.$on('setting-submit-status', ( status ) => { + this.disableSubmit = status; + } ); + }, }; diff --git a/src/utils/Bootstrap.js b/src/utils/Bootstrap.js index b409984750..5a5c20dc95 100644 --- a/src/utils/Bootstrap.js +++ b/src/utils/Bootstrap.js @@ -53,6 +53,7 @@ import AdminNotice from "../admin/components/AdminNotice.vue"; import CardFunFact from "../admin/components/CardFunFact.vue"; import "vue-multiselect/dist/vue-multiselect.min.css" +import Vuedraggable from "vuedraggable/src/vuedraggable"; Vue.use(Notifications) @@ -121,6 +122,7 @@ window.dokan.libs['RefreshSettingOptions'] = RefreshSettingOptions; window.dokan.libs['AdminNotice'] = AdminNotice; window.dokan.libs['CardFunFact'] = CardFunFact; window.dokan.libs['papaparse'] = parse; +window.dokan.libs['Vuedraggable'] = Vuedraggable; window.dokan.libs['ContentLoading'] = { VclCode,