CityFee > SDK Integration. * cityfee_fs() still stays off when the SDK folder is missing (WordPress.org build). * The public key is public by design (it ships in every build); never put the secret key here. */ if ( ! defined( 'CITYFEE_FS_ID' ) ) { define( 'CITYFEE_FS_ID', '44216' ); } if ( ! defined( 'CITYFEE_FS_PUBLIC_KEY' ) ) { define( 'CITYFEE_FS_PUBLIC_KEY', 'pk_dbd7095c09c9ec7356f9f76642556' ); } /* * Freemius (licensing, payments, upgrades). The SDK lives in /freemius/ and is left out * of the WordPress.org build (build.ps1), which then runs as the free version with no * upsells. The build is premium when the /pro/ folder is present. */ if ( ! function_exists( 'cityfee_fs' ) ) { /** * Freemius instance, or false when the SDK is not bundled or the product is not configured. * * @return Freemius|false */ function cityfee_fs() { global $cityfee_fs; if ( ! isset( $cityfee_fs ) ) { $sdk = CITYFEE_DIR . 'freemius/start.php'; if ( ! file_exists( $sdk ) || '' === CITYFEE_FS_ID || '' === CITYFEE_FS_PUBLIC_KEY ) { $cityfee_fs = false; return $cityfee_fs; } require_once $sdk; $cityfee_fs = fs_dynamic_init( array( 'id' => CITYFEE_FS_ID, 'slug' => 'cityfee', 'premium_slug' => 'cityfee-premium', 'type' => 'plugin', 'public_key' => CITYFEE_FS_PUBLIC_KEY, 'is_premium' => file_exists( CITYFEE_DIR . 'pro/class-cityfee-pro.php' ), 'premium_suffix' => 'Pro', 'has_addons' => false, 'has_paid_plans' => true, 'has_premium_version' => true, 'is_org_compliant' => true, // Trial as proposed by Commercial (AP-2026-013); the plan in the Freemius dashboard is what counts. 'trial' => array( 'days' => 7, 'is_require_payment' => false, ), // Freemius attaches its opt-in, Pricing and Account pages to the hidden page admin.php?page=cityfee. 'menu' => array( 'slug' => 'cityfee', 'first-path' => 'admin.php?page=wc-settings&tab=shipping§ion=cityfee', 'parent' => array( 'slug' => 'woocommerce' ), 'support' => false, 'contact' => false, ), ) ); } return $cityfee_fs; } cityfee_fs(); do_action( 'cityfee_fs_loaded' ); } /** * True when a valid Pro licence (or trial) is active. Always false without Freemius. * * @return bool */ function cityfee_is_pro() { $fs = cityfee_fs(); return $fs && $fs->can_use_premium_code(); } /** * URL of the upgrade / pricing page, or '' when Freemius is not set up (upsells are then hidden). * * @return string */ function cityfee_upgrade_url() { $fs = cityfee_fs(); return $fs ? (string) $fs->get_upgrade_url() : ''; } add_action( 'before_woocommerce_init', function () { if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', CITYFEE_FILE, true ); \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', CITYFEE_FILE, true ); } } ); /** * Translation file to load for a locale, or '' when there is none. * * A language pack from translate.wordpress.org (wp-content/languages/plugins) wins over * the bundled file of the same locale; the WordPress.org build bundles no .mo, so it uses * packs only. Regional locales fall back to the base language: fr_CA, fr_BE, fr_MA... -> * fr_FR, and ary (Moroccan Arabic), ar_* -> ar. * * @param string $locale Locale, for example fr_CA. * @return string Absolute path of the .mo file, or ''. */ function cityfee_translation_file( $locale ) { $locale = (string) $locale; if ( '' === $locale || 'en_US' === $locale ) { return ''; } $base = strtok( $locale, '_' ); $candidates = array_unique( array_filter( array( $locale, 'fr' === $base ? 'fr_FR' : '', 'ar' === $base || 'ary' === $base ? 'ar' : '', ) ) ); foreach ( $candidates as $candidate ) { foreach ( array( WP_LANG_DIR . '/plugins/', CITYFEE_DIR . 'languages/' ) as $dir ) { $mo = $dir . 'cityfee-' . $candidate . '.mo'; if ( is_readable( $mo ) ) { return $mo; } } } return ''; } /** * Load the CityFee translations for a locale (default: the current one) and return the * file loaded, or ''. Runs on init and again when the locale is switched (for example * when WooCommerce sends an email in the customer's language). * * @param string|null $locale Locale; null = determine_locale(). * @return string */ function cityfee_load_translations( $locale = null ) { $locale = null === $locale ? determine_locale() : (string) $locale; $mo = cityfee_translation_file( $locale ); if ( '' === $mo ) { return ''; } // Drop what is loaded for the domain (or a just-in-time "nothing found" placeholder), keep it reloadable. unload_textdomain( 'cityfee', true ); return load_textdomain( 'cityfee', $mo, $locale ) ? $mo : ''; } add_action( 'init', function () { cityfee_load_translations(); }, 1 ); add_action( 'change_locale', function ( $locale ) { cityfee_load_translations( $locale ); } ); require_once CITYFEE_DIR . 'includes/class-cityfee-install.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-cities.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-import.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-migrate.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-starter.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-checkout.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-admin.php'; require_once CITYFEE_DIR . 'includes/class-cityfee-shipping.php'; register_activation_hook( CITYFEE_FILE, array( 'CityFee_Install', 'install' ) ); /** * Remove CityFee data on uninstall: the city and group tables, all cityfee_* options * and transients, and the "Delivery by city" methods in the shipping zones. Order and * customer addresses are kept. Skipped when the owner ticked * "Keep city lists when uninstalling". * * Registered from the main file (not uninstall.php, which Freemius rejects), the same * pattern as OrderProof: Freemius owns the uninstall flow when its SDK is active, so it * gets the function through after_uninstall; otherwise WordPress' uninstall hook runs it. */ function cityfee_uninstall_cleanup() { if ( 'yes' === get_option( 'cityfee_keep_data', 'no' ) ) { return; } CityFee_Install::drop_tables(); CityFee_Install::delete_options(); CityFee_Install::delete_shipping_methods(); } if ( cityfee_fs() ) { cityfee_fs()->add_action( 'after_uninstall', 'cityfee_uninstall_cleanup' ); } else { register_uninstall_hook( CITYFEE_FILE, 'cityfee_uninstall_cleanup' ); } add_action( 'plugins_loaded', function () { if ( ! class_exists( 'WooCommerce' ) ) { return; } CityFee_Install::maybe_upgrade(); CityFee_Checkout::init(); CityFee_Shipping::init(); if ( is_admin() ) { CityFee_Admin::init(); } // Pro features: only in the Freemius build (pro/ present) with a valid licence or trial. if ( cityfee_is_pro() && file_exists( CITYFEE_DIR . 'pro/class-cityfee-pro.php' ) ) { require_once CITYFEE_DIR . 'pro/class-cityfee-pro.php'; CityFee_Pro::init(); } } );