load_dependencies();
add_action('admin_init', array($this, 'check_required_plugins'));
add_action('admin_menu', array($this, 'add_admin_menu'), 99);
add_action('admin_enqueue_scripts', array($this, 'register_admin_assets'));
add_action('wp_enqueue_scripts', array($this, 'register_frontend_assets'));
$this->init_components();
add_action('before_woocommerce_init', array($this, 'declare_hpos_compatibility'));
// Override WC core strings with FPP-specific wording (e.g. cart "Estimated total"
// → "Součet" in cs_CZ). Translation lives in our .po so it stays locale-aware.
add_filter('gettext_woocommerce', array($this, 'override_wc_strings'), 10, 2);
}
/**
* Reword selected WooCommerce core strings via our own textdomain so translations
* stay centralized in languages/studiou-wc-free-photo-product-*.po.
*/
public function override_wc_strings($translation, $text) {
if ($text === 'Estimated total') {
return __('Total', 'studiou-wc-free-photo-product');
}
return $translation;
}
private function load_dependencies() {
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-db.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-product.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-upload.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-shortcode.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-single-product.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-cart.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-admin.php';
require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-pricing.php';
}
private function init_components() {
$this->db = new Studiou_WC_FPP_DB();
$this->maybe_upgrade_db();
$this->product = new Studiou_WC_FPP_Product();
$this->upload = new Studiou_WC_FPP_Upload($this->db);
$this->shortcode = new Studiou_WC_FPP_Shortcode();
$this->single_product = new Studiou_WC_FPP_Single_Product($this->db);
$this->cart = new Studiou_WC_FPP_Cart($this->db);
$this->admin = new Studiou_WC_FPP_Admin($this->db);
$this->pricing = new Studiou_WC_FPP_Pricing();
}
/**
* Run dbDelta when the installed schema is older than the current plugin version.
* dbDelta handles adding the batch_token column and its KEY on existing installs.
*/
private function maybe_upgrade_db() {
$installed = get_option('studiou_wcfpp_db_version', '');
if (version_compare((string) $installed, STUDIOU_WCFPP_VERSION, '<')) {
$this->db->create_tables();
}
}
public function check_required_plugins() {
if (!class_exists('WooCommerce')) {
add_action('admin_notices', function () {
echo '
';
echo esc_html__('QDR - Studiou WC Free Photo Product requires WooCommerce to be installed and activated.', 'studiou-wc-free-photo-product');
echo '
';
});
}
if (!self::is_pvtfw_active()) {
add_action('admin_notices', function () {
echo '
';
echo esc_html__('QDR - Studiou WC Free Photo Product requires the "Product Variant Table for WooCommerce" plugin to be installed and activated.', 'studiou-wc-free-photo-product');
echo '
';
});
}
}
/**
* Detects whether the Product Variant Table for WooCommerce (pvtfw) plugin is active,
* regardless of its main file name, by matching the active-plugins list on the folder slug.
*/
public static function is_pvtfw_active() {
$slug = 'product-variant-table-for-woocommerce/';
$active = (array) get_option('active_plugins', array());
foreach ($active as $plugin) {
if (strpos($plugin, $slug) === 0) {
return true;
}
}
if (is_multisite()) {
$network = (array) get_site_option('active_sitewide_plugins', array());
foreach (array_keys($network) as $plugin) {
if (strpos($plugin, $slug) === 0) {
return true;
}
}
}
return false;
}
public function declare_hpos_compatibility() {
if (class_exists('Automattic\WooCommerce\Utilities\FeaturesUtil')) {
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
'custom_order_tables',
__FILE__,
true
);
}
}
public function add_admin_menu() {
if (class_exists('WooCommerce')) {
add_submenu_page(
'edit.php?post_type=product',
__('Free Photo Files', 'studiou-wc-free-photo-product'),
__('Free Photo Files', 'studiou-wc-free-photo-product'),
'manage_woocommerce',
'studiou-fpp-summary',
array($this->admin, 'render_summary_page')
);
}
}
public function register_admin_assets($hook) {
// Product edit page
$screen = get_current_screen();
if ($screen && ($screen->id === 'product' || $screen->post_type === 'product')) {
wp_enqueue_style(
'studiou-wcfpp-admin',
STUDIOU_WCFPP_PLUGIN_URL . 'assets/css/admin.css',
array(),
STUDIOU_WCFPP_VERSION
);
wp_enqueue_script(
'studiou-wcfpp-admin',
STUDIOU_WCFPP_PLUGIN_URL . 'assets/js/admin.js',
array('jquery'),
STUDIOU_WCFPP_VERSION,
true
);
wp_localize_script('studiou-wcfpp-admin', 'studiouWcfpp', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('studiou-wcfpp-nonce'),
'i18n' => array(
'confirmDelete' => __('Are you sure you want to delete the selected files?', 'studiou-wc-free-photo-product'),
'confirmDeleteSingle' => __('Are you sure you want to delete this file?', 'studiou-wc-free-photo-product'),
'confirmDownloadZip' => __('Download selected files as ZIP archive?', 'studiou-wc-free-photo-product'),
'confirmStatusChange' => __('Are you sure you want to change the status of the selected files?', 'studiou-wc-free-photo-product'),
'noFilesSelected' => __('No files selected.', 'studiou-wc-free-photo-product'),
'statusUpdated' => __('Status updated.', 'studiou-wc-free-photo-product'),
'error' => __('An error occurred.', 'studiou-wc-free-photo-product'),
'generatingZip' => __('Generating ZIP archive...', 'studiou-wc-free-photo-product'),
'generatingCsv' => __('Generating CSV file...', 'studiou-wc-free-photo-product'),
'deleting' => __('Deleting...', 'studiou-wc-free-photo-product'),
),
));
}
// Admin summary page
if ('product_page_studiou-fpp-summary' === $hook) {
wp_enqueue_style(
'studiou-wcfpp-admin',
STUDIOU_WCFPP_PLUGIN_URL . 'assets/css/admin.css',
array(),
STUDIOU_WCFPP_VERSION
);
wp_enqueue_script(
'studiou-wcfpp-admin',
STUDIOU_WCFPP_PLUGIN_URL . 'assets/js/admin.js',
array('jquery'),
STUDIOU_WCFPP_VERSION,
true
);
wp_localize_script('studiou-wcfpp-admin', 'studiouWcfpp', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('studiou-wcfpp-nonce'),
'i18n' => array(
'confirmDelete' => __('Are you sure you want to delete the selected files?', 'studiou-wc-free-photo-product'),
'confirmDeleteSingle' => __('Are you sure you want to delete this file?', 'studiou-wc-free-photo-product'),
'confirmDownloadZip' => __('Download selected files as ZIP archive?', 'studiou-wc-free-photo-product'),
'confirmStatusChange' => __('Are you sure you want to change the status of the selected files?', 'studiou-wc-free-photo-product'),
'noFilesSelected' => __('No files selected.', 'studiou-wc-free-photo-product'),
'statusUpdated' => __('Status updated.', 'studiou-wc-free-photo-product'),
'error' => __('An error occurred.', 'studiou-wc-free-photo-product'),
'generatingZip' => __('Generating ZIP archive...', 'studiou-wc-free-photo-product'),
'generatingCsv' => __('Generating CSV file...', 'studiou-wc-free-photo-product'),
'deleting' => __('Deleting...', 'studiou-wc-free-photo-product'),
),
));
}
}
public function register_frontend_assets() {
wp_register_style(
'studiou-wcfpp-frontend',
STUDIOU_WCFPP_PLUGIN_URL . 'assets/css/frontend.css',
array(),
STUDIOU_WCFPP_VERSION
);
wp_register_script(
'studiou-wcfpp-frontend',
STUDIOU_WCFPP_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
STUDIOU_WCFPP_VERSION,
true
);
wp_localize_script('studiou-wcfpp-frontend', 'studiouWcfppFront', array(
'ajaxUrl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('studiou-wcfpp-front-nonce'),
'chunkSize' => STUDIOU_WCFPP_CHUNK_SIZE,
'cartUrl' => wc_get_cart_url(),
'currency' => array(
// WooCommerce returns these with HTML entities (Kč for Kč,
// embedded in priceFormat). Decoded here so the plain-text price formatter
// that fills