declare (strict_types=1); namespace ElementorProDeps\DI; use ElementorProDeps\DI\Definition\ArrayDefinitionExtension; use ElementorProDeps\DI\Definition\EnvironmentVariableDefinition; use ElementorProDeps\DI\Definition\Helper\AutowireDefinitionHelper; use ElementorProDeps\DI\Definition\Helper\CreateDefinitionHelper; use ElementorProDeps\DI\Definition\Helper\FactoryDefinitionHelper; use ElementorProDeps\DI\Definition\Reference; use ElementorProDeps\DI\Definition\StringDefinition; use ElementorProDeps\DI\Definition\ValueDefinition; if (!\function_exists('ElementorProDeps\\DI\\value')) { /** * Helper for defining a value. * * @param mixed $value */ function value($value) : ValueDefinition { return new ValueDefinition($value); } } if (!\function_exists('ElementorProDeps\\DI\\create')) { /** * Helper for defining an object. * * @param string|null $className Class name of the object. * If null, the name of the entry (in the container) will be used as class name. */ function create(string $className = null) : CreateDefinitionHelper { return new CreateDefinitionHelper($className); } } if (!\function_exists('ElementorProDeps\\DI\\autowire')) { /** * Helper for autowiring an object. * * @param string|null $className Class name of the object. * If null, the name of the entry (in the container) will be used as class name. */ function autowire(string $className = null) : AutowireDefinitionHelper { return new AutowireDefinitionHelper($className); } } if (!\function_exists('ElementorProDeps\\DI\\factory')) { /** * Helper for defining a container entry using a factory function/callable. * * @param callable $factory The factory is a callable that takes the container as parameter * and returns the value to register in the container. */ function factory($factory) : FactoryDefinitionHelper { return new FactoryDefinitionHelper($factory); } } if (!\function_exists('ElementorProDeps\\DI\\decorate')) { /** * Decorate the previous definition using a callable. * * Example: * * 'foo' => decorate(function ($foo, $container) { * return new CachedFoo($foo, $container->get('cache')); * }) * * @param callable $callable The callable takes the decorated object as first parameter and * the container as second. */ function decorate($callable) : FactoryDefinitionHelper { return new FactoryDefinitionHelper($callable, \true); } } if (!\function_exists('ElementorProDeps\\DI\\get')) { /** * Helper for referencing another container entry in an object definition. */ function get(string $entryName) : Reference { return new Reference($entryName); } } if (!\function_exists('ElementorProDeps\\DI\\env')) { /** * Helper for referencing environment variables. * * @param string $variableName The name of the environment variable. * @param mixed $defaultValue The default value to be used if the environment variable is not defined. */ function env(string $variableName, $defaultValue = null) : EnvironmentVariableDefinition { // Only mark as optional if the default value was *explicitly* provided. $isOptional = 2 === \func_num_args(); return new EnvironmentVariableDefinition($variableName, $isOptional, $defaultValue); } } if (!\function_exists('ElementorProDeps\\DI\\add')) { /** * Helper for extending another definition. * * Example: * * 'log.backends' => DI\add(DI\get('My\Custom\LogBackend')) * * or: * * 'log.backends' => DI\add([ * DI\get('My\Custom\LogBackend') * ]) * * @param mixed|array $values A value or an array of values to add to the array. * * @since 5.0 */ function add($values) : ArrayDefinitionExtension { if (!\is_array($values)) { $values = [$values]; } return new ArrayDefinitionExtension($values); } } if (!\function_exists('ElementorProDeps\\DI\\string')) { /** * Helper for concatenating strings. * * Example: * * 'log.filename' => DI\string('{app.path}/app.log') * * @param string $expression A string expression. Use the `{}` placeholders to reference other container entries. * * @since 5.0 */ function string(string $expression) : StringDefinition { return new StringDefinition($expression); } }
/** * CartFlows Admin Notices. * * @package CartFlows */ // Exit if accessed directly. if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Class Cartflows_Admin_Notices. */ class Cartflows_Admin_Notices { /** * Instance * * @access private * @var object Class object. * @since 1.0.0 */ private static $instance; /** * Initiator * * @since 1.0.0 * @return object initialized object of class. */ public static function get_instance() { if ( ! isset( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * Constructor */ public function __construct() { add_action( 'admin_head', array( $this, 'show_admin_notices' ) ); add_action( 'admin_footer', array( $this, 'show_nps_notice' ), 999 ); add_action( 'admin_enqueue_scripts', array( $this, 'notices_scripts' ) ); add_action( 'wp_ajax_cartflows_ignore_gutenberg_notice', array( $this, 'ignore_gb_notice' ) ); add_action( 'wp_ajax_cartflows_disable_weekly_report_email_notice', array( $this, 'disable_weekly_report_email_notice' ) ); add_filter( 'woo_ca_plugin_review_url', array( $this, 'update_review_link' ), 10, 1 ); } /** * Update review link for cart abandonment. * * @param string $review_link review link. * * @return string URL. */ public function update_review_link( $review_link ) { return 'https://wordpress.org/support/plugin/cartflows/reviews/?filter=5#new-post'; } /** * Show the weekly email Notice * * @return void */ public function show_weekly_report_email_settings_notice() { if ( ! $this->allowed_screen_for_notices() ) { return; } $is_show_notice = get_option( 'cartflows_show_weekly_report_email_notice', 'no' ); if ( 'yes' === $is_show_notice && current_user_can( 'manage_options' ) ) { $setting_url = admin_url( 'admin.php?page=cartflows&path=settings#other_settings' ); /* translators: %1$s Software Title, %2$s Plugin, %3$s Anchor opening tag, %4$s Anchor closing tag, %5$s Software Title. */ $message = sprintf( __( '%1$sCartFlows:%2$s We just introduced an awesome new feature, weekly store revenue reports via email. Now you can see how many revenue we are generating for your store each week, without having to log into your website. You can set the email address for these email from %3$shere.%4$s', 'cartflows' ), '', '', '', '' ); $output = '
'; $output .= '

' . $message . '

'; $output .= '
'; echo wp_kses_post( $output ); } } /** * Disable the weekly email Notice * * @return void */ public function disable_weekly_report_email_notice() { if ( ! current_user_can( 'manage_options' ) ) { return; } check_ajax_referer( 'cartflows-disable-weekly-report-email-notice', 'security' ); delete_option( 'cartflows_show_weekly_report_email_notice' ); wp_send_json_success(); } /** * After save of permalinks. */ public function notices_scripts() { if ( ! $this->allowed_screen_for_notices() || ! current_user_can( 'cartflows_manage_flows_steps' ) ) { return; } wp_enqueue_style( 'cartflows-custom-notices', CARTFLOWS_URL . 'admin/assets/css/notices.css', array(), CARTFLOWS_VER ); wp_enqueue_script( 'cartflows-notices', CARTFLOWS_URL . 'admin/assets/js/ui-notice.js', array( 'jquery' ), CARTFLOWS_VER, true ); $localize_vars = array( 'ignore_gb_notice' => wp_create_nonce( 'cartflows-ignore-gutenberg-notice' ), 'dismiss_weekly_report_email_notice' => wp_create_nonce( 'cartflows-disable-weekly-report-email-notice' ), ); wp_localize_script( 'cartflows-notices', 'cartflows_notices', $localize_vars ); } /** * After save of permalinks. */ public function show_admin_notices() { if ( ! $this->allowed_screen_for_notices() || ! current_user_can( 'cartflows_manage_flows_steps' ) ) { return; } global $wp_version; if ( version_compare( $wp_version, '5.0', '>=' ) && is_plugin_active( 'gutenberg/gutenberg.php' ) ) { add_action( 'admin_notices', array( $this, 'gutenberg_plugin_deactivate_notice' ) ); } add_action( 'admin_notices', array( $this, 'show_weekly_report_email_settings_notice' ) ); } /** * Render CartFlows NPS Survey Notice. * * @since 2.1.6 * @return void */ public function show_nps_notice() { Nps_Survey::show_nps_notice( 'nps-survey-cartflows', array( 'show_if' => $this->should_display_nps_survey_notice(), 'dismiss_timespan' => 2 * WEEK_IN_SECONDS, 'display_after' => 0, 'plugin_slug' => 'cartflows', 'show_on_screens' => array( 'edit-cartflows_flow', 'toplevel_page_cartflows' ), 'message' => array( // Step 1 i.e rating input. 'logo' => esc_url( CARTFLOWS_URL . 'admin-core/assets/images/cartflows-icon.svg' ), 'plugin_name' => __( 'CartFlows', 'cartflows' ), 'nps_rating_message' => __( 'How likely are you to recommend #pluginname to your friends or colleagues?', 'cartflows' ), // Step 2A i.e. positive. 'feedback_content' => __( 'Could you please do us a favor and give us a 5-star rating on WordPress? It would help others choose CartFlows with confidence. Thank you!', 'cartflows' ), 'plugin_rating_link' => esc_url( 'https://wordpress.org/support/plugin/cartflows/reviews/?filter=5#new-post' ), // Step 2B i.e. negative. 'plugin_rating_title' => __( 'Thank you for your feedback', 'cartflows' ), 'plugin_rating_content' => __( 'We value your input. How can we improve your experience?', 'cartflows' ), ), ) ); } /** * Show Deactivate gutenberg plugin notice. * * @since 1.1.19 * * @return void */ public function gutenberg_plugin_deactivate_notice() { $ignore_notice = get_option( 'wcf_ignore_gutenberg_notice', false ); if ( 'yes' !== $ignore_notice ) { printf( '

%s

%s
', wp_kses_post( sprintf( /* translators: %1$s: HTML, %2$s: HTML */ __( 'Heads up! The Gutenberg plugin is not recommended on production sites as it may contain non-final features that cause compatibility issues with CartFlows and other plugins. %1$s Please deactivate the Gutenberg plugin %2$s to ensure the proper functioning of your website.', 'cartflows' ), '', '' ) ), '' ); } } /** * Ignore admin notice. */ public function ignore_gb_notice() { if ( ! current_user_can( 'cartflows_manage_flows_steps' ) ) { return; } check_ajax_referer( 'cartflows-ignore-gutenberg-notice', 'security' ); update_option( 'wcf_ignore_gutenberg_notice', 'yes' ); } /** * Check allowed screen for notices. * * @since 1.0.0 * @return bool */ public function allowed_screen_for_notices() { $screen = get_current_screen(); $screen_id = $screen ? $screen->id : ''; $allowed_screens = array( 'toplevel_page_cartflows', 'dashboard', 'plugins', ); if ( in_array( $screen_id, $allowed_screens, true ) ) { return true; } return false; } /** * Check if the user has completed the onboarding, skipped the onboarding on ready step, and the store checkout is imported. * * @since 2.1.6 * @return bool */ public function should_display_nps_survey_notice() { $is_store_checkout_imported = (bool) get_option( '_cartflows_wizard_store_checkout_set', false ); // Must be true. $onboarding_completed = (bool) get_option( 'wcf_setup_complete', false ); // Must be true. $is_first_funnel_imported = (bool) get_option( 'wcf_first_flow_imported', false ); // Must be true. $total_funnels = intval( wp_count_posts( CARTFLOWS_FLOW_POST_TYPE )->publish ); // Must be greater than or equal to 1. /** * Show the notice in two conditions. * 1. If completed the onboarding steps/process of plugin and sets their first store checkout funnel successfully. * 2. If sets up the first funnel manually and makes it live. */ return ( true === $is_store_checkout_imported && true === $onboarding_completed ) || ( true === $is_first_funnel_imported && ! empty( $total_funnels ) && 1 >= $total_funnels ) || ( ! empty( $total_funnels ) && 1 >= $total_funnels ); } } Cartflows_Admin_Notices::get_instance();/** * Above Footer Styling Loader for Astra theme. * * @package Astra Builder * @link https://www.brainstormforce.com * @since Astra 3.0.0 */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Above Footer Initialization * * @since 3.0.0 */ class Astra_Above_Footer_Component_Loader { /** * Constructor * * @since 3.0.0 */ public function __construct() { add_action( 'customize_preview_init', array( $this, 'preview_scripts' ), 110 ); } /** * Customizer Preview * * @since 3.0.0 */ public function preview_scripts() { /** * Load unminified if SCRIPT_DEBUG is true. */ /* Directory and Extension */ $dir_name = SCRIPT_DEBUG ? 'unminified' : 'minified'; $file_prefix = SCRIPT_DEBUG ? '' : '.min'; wp_enqueue_script( 'astra-footer-above-customizer-preview-js', ASTRA_BUILDER_FOOTER_ABOVE_FOOTER_URI . '/assets/js/' . $dir_name . '/customizer-preview' . $file_prefix . '.js', array( 'customize-preview', 'astra-customizer-preview-js' ), ASTRA_THEME_VERSION, true ); } } /** * Kicking this off by creating the object of the class. */ new Astra_Above_Footer_Component_Loader();/** * Admin functions. * * @package BSF core */ if ( ! function_exists( 'bsf_generate_rand_token' ) ) { /** * Generate 32 characters random token. * * @return string */ function bsf_generate_rand_token() { $valid_characters = 'abcdefghijklmnopqrstuvwxyz0123456789'; $token = ''; $length = 32; for ( $n = 1; $n < $length; $n++ ) { $which_character = wp_rand( 0, strlen( $valid_characters ) - 1 ); $token .= $valid_characters[ $which_character ]; } return $token; } } /** * Update version numbers of all the brainstorm products in options `brainstorm_products` and `brainstrom_bundled_products` * * Current version numbers can be fetched from WordPress at runtime whenever ruquired, * Remote version can only be required when transient for update data is deleted (i hope) */ if ( ! function_exists( 'bsf_update_all_product_version' ) ) { /** * Updates all product versions. * * @return void */ function bsf_update_all_product_version() { $brainstrom_products = get_option( 'brainstrom_products', array() ); $brainstrom_bundled_products = get_option( 'brainstrom_bundled_products', array() ); $bsf_product_themes = array(); if ( ! empty( $brainstrom_products ) ) { $bsf_product_plugins = isset( $brainstrom_products['plugins'] ) ? $brainstrom_products['plugins'] : array(); $bsf_product_themes = isset( $brainstrom_products['themes'] ) ? $brainstrom_products['themes'] : array(); } $bundled_product_updated = false; if ( ! empty( $bsf_product_plugins ) ) { foreach ( $bsf_product_plugins as $key => $plugin ) { if ( ! isset( $plugin['id'] ) || empty( $plugin['id'] ) ) { continue; } if ( ! isset( $plugin['template'] ) || empty( $plugin['template'] ) ) { continue; } if ( ! isset( $plugin['type'] ) || empty( $plugin['type'] ) ) { continue; } $version = isset( $plugin['version'] ) ? $plugin['version'] : ''; $current_version = bsf_get_current_version( $plugin['template'], $plugin['type'] ); $name = bsf_get_current_name( $plugin['template'], $plugin['type'] ); if ( '' !== $name ) { $brainstrom_products['plugins'][ $key ]['product_name'] = $name; } if ( '' !== $current_version ) { if ( version_compare( $version, $current_version ) === - 1 || 1 === version_compare( $version, $current_version ) ) { $brainstrom_products['plugins'][ $key ]['version'] = $current_version; } } } } if ( ! empty( $bsf_product_themes ) ) { foreach ( $bsf_product_themes as $key => $theme ) { if ( ! isset( $theme['id'] ) || empty( $theme['id'] ) ) { continue; } if ( ! isset( $theme['template'] ) || empty( $theme['template'] ) ) { continue; } if ( ! isset( $theme['type'] ) || empty( $theme['type'] ) ) { continue; } $version = isset( $theme['version'] ) ? $theme['version'] : ''; $current_version = bsf_get_current_version( $theme['template'], $theme['type'] ); $name = bsf_get_current_name( $theme['template'], $theme['type'] ); if ( '' !== $name ) { $brainstrom_products['themes'][ $key ]['product_name'] = $name; } if ( '' !== $current_version || false !== $current_version ) { if ( version_compare( $version, $current_version ) === - 1 || 1 === version_compare( $version, $current_version ) ) { $brainstrom_products['themes'][ $key ]['version'] = $current_version; } } } } if ( ! empty( $brainstrom_bundled_products ) ) { foreach ( $brainstrom_bundled_products as $keys => $bps ) { $version = ''; if ( strlen( $keys ) > 1 ) { foreach ( $bps as $key => $bp ) { if ( ! isset( $bp->id ) || '' === $bp->id ) { continue; } $version = $bp->version; $current_version = bsf_get_current_version( $bp->init, $bp->type ); if ( '' !== $current_version && false !== $current_version ) { if ( 1 === - version_compare( $version, $current_version ) || 1 === version_compare( $version, $current_version ) ) { if ( is_object( $brainstrom_bundled_products ) ) { $brainstrom_bundled_products = array( $brainstrom_bundled_products ); } $single_bp = $brainstrom_bundled_products[ $keys ]; $single_bp[ $key ]->version = $current_version; $bundled_product_updated = true; $brainstrom_bundled_products[ $keys ] = $single_bp; } } } } else { if ( ! isset( $bps->id ) || '' === $bps->id ) { continue; } $version = $bps->version; $current_version = bsf_get_current_version( $bps->init, $bps->type ); if ( '' !== $current_version || false !== $current_version ) { if ( - 1 === version_compare( $version, $current_version ) || 1 === version_compare( $version, $current_version ) ) { $brainstrom_bundled_products[ $keys ]->version = $current_version; $bundled_product_updated = true; } } } } } update_option( 'brainstrom_products', $brainstrom_products ); if ( $bundled_product_updated ) { update_option( 'brainstrom_bundled_products', $brainstrom_bundled_products ); } } } add_action( 'admin_init', 'bsf_update_all_product_version', 1000 ); if ( ! function_exists( 'bsf_get_current_version' ) ) { /** * Get current version of plugin / theme. * * @param string $template plugin template/slug. * @param string $type type of product. * * @return float */ function bsf_get_current_version( $template, $type ) { if ( '' === $template ) { return false; } if ( 'theme' === $type || 'themes' === $type ) { $theme = wp_get_theme( $template ); $version = $theme->get( 'Version' ); } elseif ( 'plugin' === $type || 'plugins' === $type ) { $plugin_file = rtrim( WP_PLUGIN_DIR, '/' ) . '/' . $template; if ( ! is_file( $plugin_file ) ) { return false; } $plugin = get_plugin_data( $plugin_file ); $version = $plugin['Version']; } return $version; } } if ( ! function_exists( 'bsf_get_current_name' ) ) { /** * Get name of plugin / theme. * * @param string $template plugin template/slug. * @param string $type type of product. * @return string */ function bsf_get_current_name( $template, $type ) { if ( '' === $template ) { return false; } if ( 'theme' === $type || 'themes' === $type ) { $theme = wp_get_theme( $template ); $name = $theme->get( 'Name' ); } elseif ( 'plugin' === $type || 'plugins' === $type ) { $plugin_file = rtrim( WP_PLUGIN_DIR, '/' ) . '/' . $template; if ( ! is_file( $plugin_file ) ) { return false; } $plugin = get_plugin_data( $plugin_file ); $name = $plugin['Name']; } return $name; } } add_action( 'admin_notices', 'bsf_notices', 1000 ); add_action( 'network_admin_notices', 'bsf_notices', 1000 ); if ( ! function_exists( 'bsf_notices' ) ) { /** * Display admin notices. * * @return bool */ function bsf_notices() { global $pagenow; if ( 'update-core.php' === $pagenow || 'plugins.php' === $pagenow || 'post-new.php' === $pagenow || 'edit.php' === $pagenow || 'post.php' === $pagenow ) { $brainstrom_products = get_option( 'brainstrom_products' ); $brainstrom_bundled_products = get_option( 'brainstrom_bundled_products', array() ); if ( empty( $brainstrom_products ) ) { return false; } $brainstrom_bundled_products_keys = array(); if ( ! empty( $brainstrom_bundled_products ) ) { foreach ( $brainstrom_bundled_products as $bps ) { foreach ( $bps as $bp ) { array_push( $brainstrom_bundled_products_keys, $bp->id ); } } } $mix = array(); $plugins = isset( $brainstrom_products['plugins'] ) ? $brainstrom_products['plugins'] : array(); $themes = isset( $brainstrom_products['themes'] ) ? $brainstrom_products['themes'] : array(); $mix = array_merge( $plugins, $themes ); if ( empty( $mix ) ) { return false; } if ( ( defined( 'BSF_PRODUCTS_NOTICES' ) && ( 'false' === BSF_PRODUCTS_NOTICES || false === BSF_PRODUCTS_NOTICES ) ) ) { return false; } $is_multisite = is_multisite(); $is_network_admin = is_network_admin(); foreach ( $mix as $product ) { if ( ! isset( $product['id'] ) ) { continue; } if ( false === apply_filters( "bsf_display_product_activation_notice_{$product['id']}", true ) ) { continue; } if ( isset( $product['is_product_free'] ) && ( 'true' === $product['is_product_free'] || true === $product['is_product_free'] ) ) { continue; } $constant = strtoupper( str_replace( '-', '_', $product['id'] ) ); $constant_nag = 'BSF_' . $constant . '_NAG'; $constant_notice = 'BSF_' . $constant . '_NOTICES'; if ( defined( $constant_nag ) && ( 'false' === constant( $constant_nag ) || false === constant( $constant_nag ) ) ) { continue; } if ( defined( $constant_notice ) && ( 'false' === constant( $constant_notice ) || false === constant( $constant_notice ) ) ) { continue; } $status = isset( $product['status'] ) ? $product['status'] : false; $type = isset( $product['type'] ) ? $product['type'] : false; if ( ! $type ) { continue; } if ( 'plugin' === $type ) { if ( ! is_plugin_active( $product['template'] ) ) { continue; } } elseif ( 'theme' === $type ) { $theme = wp_get_theme(); if ( $product['template'] !== $theme->template ) { continue; } } else { continue; } if ( BSF_Update_Manager::bsf_is_product_bundled( $product['id'] ) ) { continue; } if ( 'registered' !== $status ) { $url = bsf_registration_page_url( '', $product['id'] ); $message = __( 'Please', 'bsf' ) . ' ' . __( 'activate', 'bsf' ) . ' ' . __( 'your copy of the', 'bsf' ) . ' ' . esc_html( $product['product_name'] ) . ' ' . __( 'to get update notifications, access to support features & other resources!', 'bsf' ); $message = apply_filters( "bsf_product_activation_notice_{$product['id']}", $message, $url, $product['product_name'] ); $allowed_html = array( 'a' => array( 'href' => array(), 'class' => array(), 'title' => array(), 'plugin-slug' => array(), ), 'br' => array(), 'em' => array(), 'strong' => array(), 'i' => array(), ); if ( ( $is_multisite && $is_network_admin ) || ! $is_multisite ) { echo '

' . wp_kses( $message, $allowed_html ) . '

'; } } } } } } // delete bundled products after switch theme. if ( ! function_exists( 'bsf_theme_deactivation' ) ) { /** * Delete transients while switching theme. * * @return void */ function bsf_theme_deactivation() { update_option( 'bsf_force_check_extensions', false ); } } add_action( 'switch_theme', 'bsf_theme_deactivation' ); add_action( 'deactivated_plugin', 'bsf_theme_deactivation' ); if ( ! function_exists( 'bsf_get_free_menu_position' ) ) { /** * Get free theme position. * * @param int $start menu position priority index. * @param float $increment increment number for menu position. * @return int */ function bsf_get_free_menu_position( $start, $increment = 0.3 ) { $menus_positions = []; foreach ( $GLOBALS['menu'] as $key => $menu ) { $menus_positions[] = $key; } if ( ! in_array( $start, $menus_positions, true ) ) { return $start; } /* the position is already reserved find the closet one */ while ( in_array( $start, $menus_positions, true ) ) { $start += $increment; } return $start; } } if ( ! function_exists( 'bsf_get_option' ) ) { /** * Get free theme position. * * @param bool $request return complete option data OR a single variable. * @return array */ function bsf_get_option( $request = false ) { $bsf_options = get_option( 'bsf_options' ); if ( ! $request ) { return $bsf_options; } return isset( $bsf_options[ $request ] ) ? $bsf_options[ $request ] : false; } } if ( ! function_exists( 'bsf_update_option' ) ) { /** * Update bsf option with key and value. * * @param string $request variable key. * @param string $value variable value. * @return bool */ function bsf_update_option( $request, $value ) { $bsf_options = get_option( 'bsf_options' ); $bsf_options[ $request ] = $value; return update_option( 'bsf_options', $bsf_options ); } } if ( ! function_exists( 'bsf_sort' ) ) { /** * Sort array of objects. * * @param string $a The first string. * @param string $b The second string. * @return int */ function bsf_sort( $a, $b ) { return strcmp( strtolower( $a->short_name ), strtolower( $b->short_name ) ); } } Cart - AbayatAB