studiou-wc-free-photo-product.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <?php
  2. /**
  3. * Plugin Name: QDR - Studiou WC Free Photo Product
  4. * Plugin URI: https://www.quadarax.com/plugins/studiou-wc-free-photo-product
  5. * Description: Allows publishing special WooCommerce products with variants and custom raw image upload for photo printing
  6. * Version: 1.1.5
  7. * Requires at least: 6.9.4
  8. * Requires PHP: 8.2
  9. * Author: Dalibor Votruba
  10. * Author URI: https://www.quadarax.com
  11. * License: GPL v2 or later
  12. * License URI: https://www.gnu.org/licenses/gpl-2.0.html
  13. * Text Domain: studiou-wc-free-photo-product
  14. * Domain Path: /languages
  15. * WC requires at least: 10.0
  16. * WC tested up to: 10.6
  17. * Woo: 12346:a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4
  18. */
  19. if (!defined('WPINC')) {
  20. die;
  21. }
  22. if (!defined('STUDIOU_WCFPP_VERSION')) define('STUDIOU_WCFPP_VERSION', '1.1.5');
  23. if (!defined('STUDIOU_WCFPP_PLUGIN_DIR')) define('STUDIOU_WCFPP_PLUGIN_DIR', plugin_dir_path(__FILE__));
  24. if (!defined('STUDIOU_WCFPP_PLUGIN_URL')) define('STUDIOU_WCFPP_PLUGIN_URL', plugin_dir_url(__FILE__));
  25. if (!defined('STUDIOU_WCFPP_PLUGIN_BASENAME')) define('STUDIOU_WCFPP_PLUGIN_BASENAME', plugin_basename(__FILE__));
  26. if (!defined('STUDIOU_WCFPP_CHUNK_SIZE')) define('STUDIOU_WCFPP_CHUNK_SIZE', 1024 * 1024); // 1MB chunks
  27. class Studiou_WC_Free_Photo_Product {
  28. /** @var Studiou_WC_FPP_DB */
  29. private $db;
  30. /** @var Studiou_WC_FPP_Product */
  31. private $product;
  32. /** @var Studiou_WC_FPP_Upload */
  33. private $upload;
  34. /** @var Studiou_WC_FPP_Shortcode */
  35. private $shortcode;
  36. /** @var Studiou_WC_FPP_Single_Product */
  37. private $single_product;
  38. /** @var Studiou_WC_FPP_Cart */
  39. private $cart;
  40. /** @var Studiou_WC_FPP_Admin */
  41. private $admin;
  42. public function __construct() {
  43. $this->load_dependencies();
  44. add_action('admin_init', array($this, 'check_required_plugins'));
  45. add_action('admin_menu', array($this, 'add_admin_menu'), 99);
  46. add_action('admin_enqueue_scripts', array($this, 'register_admin_assets'));
  47. add_action('wp_enqueue_scripts', array($this, 'register_frontend_assets'));
  48. $this->init_components();
  49. add_action('before_woocommerce_init', array($this, 'declare_hpos_compatibility'));
  50. }
  51. private function load_dependencies() {
  52. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-db.php';
  53. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-product.php';
  54. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-upload.php';
  55. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-shortcode.php';
  56. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-single-product.php';
  57. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-cart.php';
  58. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-admin.php';
  59. }
  60. private function init_components() {
  61. $this->db = new Studiou_WC_FPP_DB();
  62. $this->product = new Studiou_WC_FPP_Product();
  63. $this->upload = new Studiou_WC_FPP_Upload($this->db);
  64. $this->shortcode = new Studiou_WC_FPP_Shortcode();
  65. $this->single_product = new Studiou_WC_FPP_Single_Product();
  66. $this->cart = new Studiou_WC_FPP_Cart($this->db);
  67. $this->admin = new Studiou_WC_FPP_Admin($this->db);
  68. }
  69. public function check_required_plugins() {
  70. if (!class_exists('WooCommerce')) {
  71. add_action('admin_notices', function () {
  72. echo '<div class="notice notice-error"><p>';
  73. echo esc_html__('QDR - Studiou WC Free Photo Product requires WooCommerce to be installed and activated.', 'studiou-wc-free-photo-product');
  74. echo '</p></div>';
  75. });
  76. }
  77. }
  78. public function declare_hpos_compatibility() {
  79. if (class_exists('Automattic\WooCommerce\Utilities\FeaturesUtil')) {
  80. \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
  81. 'custom_order_tables',
  82. __FILE__,
  83. true
  84. );
  85. }
  86. }
  87. public function add_admin_menu() {
  88. if (class_exists('WooCommerce')) {
  89. add_submenu_page(
  90. 'edit.php?post_type=product',
  91. __('Free Photo Files', 'studiou-wc-free-photo-product'),
  92. __('Free Photo Files', 'studiou-wc-free-photo-product'),
  93. 'manage_woocommerce',
  94. 'studiou-fpp-summary',
  95. array($this->admin, 'render_summary_page')
  96. );
  97. }
  98. }
  99. public function register_admin_assets($hook) {
  100. // Product edit page
  101. $screen = get_current_screen();
  102. if ($screen && ($screen->id === 'product' || $screen->post_type === 'product')) {
  103. wp_enqueue_style(
  104. 'studiou-wcfpp-admin',
  105. STUDIOU_WCFPP_PLUGIN_URL . 'assets/css/admin.css',
  106. array(),
  107. STUDIOU_WCFPP_VERSION
  108. );
  109. wp_enqueue_script(
  110. 'studiou-wcfpp-admin',
  111. STUDIOU_WCFPP_PLUGIN_URL . 'assets/js/admin.js',
  112. array('jquery'),
  113. STUDIOU_WCFPP_VERSION,
  114. true
  115. );
  116. wp_localize_script('studiou-wcfpp-admin', 'studiouWcfpp', array(
  117. 'ajaxUrl' => admin_url('admin-ajax.php'),
  118. 'nonce' => wp_create_nonce('studiou-wcfpp-nonce'),
  119. 'i18n' => array(
  120. 'confirmDelete' => __('Are you sure you want to delete the selected files?', 'studiou-wc-free-photo-product'),
  121. 'confirmDeleteSingle' => __('Are you sure you want to delete this file?', 'studiou-wc-free-photo-product'),
  122. 'noFilesSelected' => __('No files selected.', 'studiou-wc-free-photo-product'),
  123. 'statusUpdated' => __('Status updated.', 'studiou-wc-free-photo-product'),
  124. 'error' => __('An error occurred.', 'studiou-wc-free-photo-product'),
  125. 'generatingZip' => __('Generating ZIP archive...', 'studiou-wc-free-photo-product'),
  126. 'deleting' => __('Deleting...', 'studiou-wc-free-photo-product'),
  127. ),
  128. ));
  129. }
  130. // Admin summary page
  131. if ('product_page_studiou-fpp-summary' === $hook) {
  132. wp_enqueue_style(
  133. 'studiou-wcfpp-admin',
  134. STUDIOU_WCFPP_PLUGIN_URL . 'assets/css/admin.css',
  135. array(),
  136. STUDIOU_WCFPP_VERSION
  137. );
  138. wp_enqueue_script(
  139. 'studiou-wcfpp-admin',
  140. STUDIOU_WCFPP_PLUGIN_URL . 'assets/js/admin.js',
  141. array('jquery'),
  142. STUDIOU_WCFPP_VERSION,
  143. true
  144. );
  145. wp_localize_script('studiou-wcfpp-admin', 'studiouWcfpp', array(
  146. 'ajaxUrl' => admin_url('admin-ajax.php'),
  147. 'nonce' => wp_create_nonce('studiou-wcfpp-nonce'),
  148. 'i18n' => array(
  149. 'confirmDelete' => __('Are you sure you want to delete the selected files?', 'studiou-wc-free-photo-product'),
  150. 'confirmDeleteSingle' => __('Are you sure you want to delete this file?', 'studiou-wc-free-photo-product'),
  151. 'noFilesSelected' => __('No files selected.', 'studiou-wc-free-photo-product'),
  152. 'statusUpdated' => __('Status updated.', 'studiou-wc-free-photo-product'),
  153. 'error' => __('An error occurred.', 'studiou-wc-free-photo-product'),
  154. 'generatingZip' => __('Generating ZIP archive...', 'studiou-wc-free-photo-product'),
  155. 'deleting' => __('Deleting...', 'studiou-wc-free-photo-product'),
  156. ),
  157. ));
  158. }
  159. }
  160. public function register_frontend_assets() {
  161. wp_register_style(
  162. 'studiou-wcfpp-frontend',
  163. STUDIOU_WCFPP_PLUGIN_URL . 'assets/css/frontend.css',
  164. array(),
  165. STUDIOU_WCFPP_VERSION
  166. );
  167. wp_register_script(
  168. 'studiou-wcfpp-frontend',
  169. STUDIOU_WCFPP_PLUGIN_URL . 'assets/js/frontend.js',
  170. array('jquery'),
  171. STUDIOU_WCFPP_VERSION,
  172. true
  173. );
  174. wp_localize_script('studiou-wcfpp-frontend', 'studiouWcfppFront', array(
  175. 'ajaxUrl' => admin_url('admin-ajax.php'),
  176. 'nonce' => wp_create_nonce('studiou-wcfpp-front-nonce'),
  177. 'chunkSize' => STUDIOU_WCFPP_CHUNK_SIZE,
  178. 'cartUrl' => wc_get_cart_url(),
  179. 'i18n' => array(
  180. 'uploading' => __('Uploading...', 'studiou-wc-free-photo-product'),
  181. 'uploadComplete' => __('Upload complete', 'studiou-wc-free-photo-product'),
  182. 'processing' => __('Processing...', 'studiou-wc-free-photo-product'),
  183. 'uploadError' => __('Upload failed. Please try again.', 'studiou-wc-free-photo-product'),
  184. 'fileTooLarge' => __('File is too large. Maximum size: %s MB', 'studiou-wc-free-photo-product'),
  185. 'selectVariant' => __('Please select a variant.', 'studiou-wc-free-photo-product'),
  186. 'uploadFile' => __('Please upload a file.', 'studiou-wc-free-photo-product'),
  187. 'addedToCart' => __('Product added to cart!', 'studiou-wc-free-photo-product'),
  188. 'addToCartError' => __('Could not add to cart. Please try again.', 'studiou-wc-free-photo-product'),
  189. 'dragDropText' => __('Drag & drop your file here or click to browse', 'studiou-wc-free-photo-product'),
  190. 'removeFile' => __('Remove', 'studiou-wc-free-photo-product'),
  191. ),
  192. ));
  193. }
  194. public static function activate() {
  195. require_once STUDIOU_WCFPP_PLUGIN_DIR . 'includes/class-studiou-wc-fpp-db.php';
  196. $db = new Studiou_WC_FPP_DB();
  197. $db->create_tables();
  198. // Create chunks temp directory
  199. $upload_dir = wp_upload_dir();
  200. $chunks_dir = $upload_dir['basedir'] . '/studiou-fpp-chunks';
  201. if (!file_exists($chunks_dir)) {
  202. wp_mkdir_p($chunks_dir);
  203. file_put_contents($chunks_dir . '/.htaccess', 'deny from all');
  204. file_put_contents($chunks_dir . '/index.php', '<?php // Silence is golden');
  205. }
  206. }
  207. public static function deactivate() {
  208. // Clean up temp chunks
  209. $upload_dir = wp_upload_dir();
  210. $chunks_dir = $upload_dir['basedir'] . '/studiou-fpp-chunks';
  211. if (is_dir($chunks_dir)) {
  212. $files = glob($chunks_dir . '/*');
  213. foreach ($files as $file) {
  214. if (is_file($file) && basename($file) !== '.htaccess' && basename($file) !== 'index.php') {
  215. unlink($file);
  216. }
  217. }
  218. }
  219. }
  220. }
  221. // Activation/deactivation hooks
  222. register_activation_hook(__FILE__, array('Studiou_WC_Free_Photo_Product', 'activate'));
  223. register_deactivation_hook(__FILE__, array('Studiou_WC_Free_Photo_Product', 'deactivate'));
  224. function run_studiou_wc_free_photo_product() {
  225. static $initialized = false;
  226. if ($initialized) {
  227. return;
  228. }
  229. $initialized = true;
  230. load_plugin_textdomain(
  231. 'studiou-wc-free-photo-product',
  232. false,
  233. dirname(plugin_basename(__FILE__)) . '/languages/'
  234. );
  235. new Studiou_WC_Free_Photo_Product();
  236. }
  237. add_action('plugins_loaded', 'run_studiou_wc_free_photo_product');