_init(); //admin interface if (is_admin()) { add_action("woocommerce_product_write_panel_tabs", array($this, "yofla_360_tab_options_tab")); add_action("woocommerce_product_data_panels", array($this, "yofla_360_tab_options")); add_action("woocommerce_process_product_meta", array($this, "yofla_360_save_product")); add_action("admin_enqueue_scripts", array($this, "yofla_360_admin_scripts")); } else { // apply yofla_360_replace_product_image filter on product images if ($this->is_woocommerce_2x) { //for wocommerce 2.x add_filter("woocommerce_single_product_image_html", array( $this, "yofla_360_replace_product_image" )); } else { //for wocommerce 1.x, 3.x, ... // add product image add_filter("woocommerce_single_product_image_thumbnail_html", array( $this, "yofla_360_replace_product_image" )); // css add_filter("woocommerce_single_product_image_gallery_classes", array( $this, "yofla_360_add_gallery_styles" )); } //woocommerce specific javascript and styles add_action('wp_enqueue_scripts', array($this, 'yofla_360_frontend_scripts')); } } /** * Includes javascript and css files for variable products functionality * */ public function yofla_360_frontend_scripts() { if (false == $this->_is_360_view()) { return; } $js_client_file = 'y360-woocommerce-client.js'; // register javascript wp_register_script('yofla_360_woocommerce_client', YOFLA_360_PLUGIN_URL . 'js/' . $js_client_file, [ 'jquery', 'woocommerce' ], '1.0.1'); // add javascript wp_enqueue_script('yofla_360_woocommerce_client'); // add styles wp_enqueue_style('yofla_360_woocommerce_styles', YOFLA_360_PLUGIN_URL . 'styles/y360-woocommerce-styles.css'); $thumbUrl = get_option('yofla_360_options')['woocommerce_360thumb_url']; if (isset($thumbUrl) && strlen($thumbUrl) > 5) { if (function_exists('wp_add_inline_script')) { $script = 'window.Yofla360_woocommerce_360thumb_url = "' . $thumbUrl . '";'; wp_add_inline_script('yofla_360_woocommerce_client', $script); } } } /** * Includes javascript and css files for admin zone * */ public function yofla_360_admin_scripts() { wp_enqueue_style('yofla_360_woocommerce_admin_styles', YOFLA_360_PLUGIN_URL . 'styles/y360-woocommerce-admin-styles.css'); } /** * HTML of the 360 Product Tab Tab * */ public function yofla_360_tab_options_tab() { echo '
  •   360° View
  • '; } /** * HTML of the 360 Product Tab Content * */ public function yofla_360_tab_options() { echo '
    '; //list of 360 views $products_list = $this->_get_products_list(); $upload_url = admin_url('upload.php?page=yofla-360-media'); //no product uploaded yet if (sizeof($products_list) == 1) { echo 'No 360° views found. Do you wish to add one now?'; } //a product is uploaded else { if ($this->_is_variable_product()) { $variants = $this->_get_product_variants(); foreach ($variants as $variant) { $variant_name = $variant["name"]; $variant_id = $variant["id"]; $variant_value = $this->_get_variant_value($variant_id); echo "$variant_name"; woocommerce_wp_select(array( "id" => "_y360path_variant_" . $variant_id, "name" => "_y360path_variants[$variant_id]", "label" => "Please choose a 360° view", "placeholder" => "", "value" => "$variant_value", "desc_tip" => true, "description" => sprintf("Upload new 360 views in Media page."), "options" => $products_list )); } } else { woocommerce_wp_select(array( "id" => "_y360path", "name" => "_y360path", "label" => "Please choose a 360° view", "placeholder" => "", "desc_tip" => true, "description" => sprintf("Upload new 360 views in Media page."), "options" => $products_list )); woocommerce_wp_text_input(array( "id" => "_y360path_url", "name" => "_y360path_url", "label" => "OR choose absolute url of the product", "placeholder" => "", "desc_tip" => true, "description" => sprintf("Absolute url path to folder with 360 view"), )); } } echo "
    "; } /** * Saving path parameter when product is saved/updated * * @param $post_id */ public function yofla_360_save_product($post_id) { if (isset($_POST["_y360path"])) { update_post_meta($post_id, "_y360path", sanitize_text_field($_POST["_y360path"])); } if (isset($_POST["_y360path_url"])) { update_post_meta($post_id, "_y360path_url", $_POST["_y360path_url"]); } if (isset ($_POST["_y360path_variants"])) { update_post_meta($post_id, "_y360path_variants", $_POST["_y360path_variants"]); } } /** * Callback function for the filter that modifies the output for the product image * * @param $content * @return string */ public function yofla_360_replace_product_image($content) { global $post; $y360_options = get_option( 'yofla_360_options' ); //read options stored in WP options database $replaceMethod = 'default'; // [default|htmlvar] htmlvar: 360 view code is injected using JS $is_woocommerce_alternate_embedding = !empty($y360_options['woocommerce_alternate_embedding']); if ($is_woocommerce_alternate_embedding) { $replaceMethod = 'htmlvar'; } if (false == $this->_is_360_view()) { // if is NOT a 360 view return $content; } else { if ($this->_is_variable_product()) { /** * Variable Product */ $new_content = $this->_get_360player_variableProduct_code($replaceMethod); } else { /** * Simple Product */ $_y360path = (get_post_meta($post->ID, "_y360path", true)); $_y360path_url = (get_post_meta($post->ID, "_y360path_url", true)); $path = ($_y360path_url) ? $_y360path_url : $_y360path; $new_content = $this->_get_360player_embed_code($path, $replaceMethod); } } /** * */ if (self::$thumbCounter == 1) { self::$thumbCounter++; return $new_content . $content; return $content; } else { return $content; } } /** * Adds styles to enclosing product-gallery div * * @param $prevStyles * @return array */ public function yofla_360_add_gallery_styles($prevStyles) { if (false == $this->_is_360_view()) { $prevStyles; } return array_merge($prevStyles, ["yofla_360_has_360_view"]); } /** * Initializes the class variables */ private function _init() { $this->is_woocommerce_2x = substr($this->_get_woo_version_number(), 0, 1) == '2'; } /** * Returns true, if the product (simple or variable) has a 360 view defined * */ private function _is_360_view() { global $post; if (isset($this->is_360_view)) { return $this->is_360_view; } else { if ($this->_is_variable_product()) { $is_360_view = sizeof($this->_defined_360_variant_views()) > 0; } else { $_y360path = (get_post_meta($post->ID, "_y360path", true)); $_y360path_url = (get_post_meta($post->ID, "_y360path_url", true)); $is_360_view = !empty($_y360path) || !empty($_y360path_url); } $this->is_360_view = $is_360_view; return $is_360_view; } } /** * Returns the product object of current product * * @return bool|WC_Product */ private function _get_product_instance() { if (!isset($this->product)) { $_pf = new WC_Product_Factory(); $this->product = $_pf->get_product(get_the_ID()); } return $this->product; } /** * HTML output for simple product * * @param $_y360path * @param null $elementId * @return bool|string */ private function _get_360player_embed_code($_y360path, $method = 'none') { $viewData = new YoFLA360ViewData(); $viewData->set_src($_y360path); $viewData->width = '100%'; $viewData->height = '100%'; // null; //set by y360-woocommerce-styles.css //iframe embedding by default $output = YoFLA360()->Frontend()->get_embed_iframe_html($viewData, null); $output = ""; //output if ($method == 'htmlvar') { $htmlVarOutput = ' '; return $htmlVarOutput; } else { return $output; } } /** * HTML output for variable product * * @return string */ private function _get_360player_variableProduct_code($method = 'none') { global $post; $output = ''; //output if ($method == 'htmlvar') { $htmlVarOutput = ' '; return $htmlVarOutput; } else { return $output; } } /** * Returns a list of uploaded products, that can be assigned as a 360 view * for this product. * * Output format is an array for the woocommerce_wp_select function * * * @see yofla_360_tab_options * @see YoFLA360Utils */ private function _get_products_list() { $result = array(); $result[''] = 'No 360° view is assigned'; $list_raw = YoFLA360()->Utils()->get_yofla360_directories_list(false); foreach ($list_raw as $key => $value) { $result[YOFLA_360_PRODUCTS_FOLDER . '/' . $value['name']] = $value['name']; } return $result; } /** * Returns false if product has no variations. * Returns array of variation ids, if product has variations * * @return bool|mixed */ private function _is_variable_product() { if (isset($this->is_variable_product)) { return $this->is_variable_product; } else { $this->is_variable_product = (sizeof($this->_get_product_variants()) > 0); return $this->is_variable_product; } } /** * Returns an array with names and ids of the product's variants * Returns an empty array if product has no variations specified * * @return array [["id"=>12,"name"=>"Name"]] */ private function _get_product_variants() { if (isset($this->product_variants)) { return $this->product_variants; } else { $product = $this->_get_product_instance(); if ($product && get_class($product) == 'WC_Product_Variable') { $variations = $product->get_available_variations(); $result = array(); foreach ($variations as $key => $value) { if ($value['variation_is_active']) { $id = $value['variation_id']; $name = isset($value['name']) ? $value['name'] : null; if (!$name) { $name = 'Variation: '; $variants = []; foreach ($value['attributes'] as $attribute_name => $attribute_value) { $variants[] = $attribute_value; } $name .= implode($variants, ', '); } $result[] = array("id" => $id, "name" => $name); } } } //no variable product else { $result = []; } //save value $this->product_variants = $result; //return variants return $result; } } /** * Returns the selected 360 view for provided variant id * * * @param $variant_id * @return string */ private function _get_variant_value($variant_id) { global $post; if (empty($post->ID)) { return ''; } $_y360path_variants = (get_post_meta($post->ID, "_y360path_variants", true)); if (isset($_y360path_variants[$variant_id])) { return $_y360path_variants[$variant_id]; } else { return ''; } } /** * Returns a list of defined 360 views vor variant images * * @return array example: ['50' => 'yofla360/vespa_green'] */ private function _defined_360_variant_views() { global $post; $result = []; if (empty($post->ID)) { return $result; } //list of all variants with $_variants = (get_post_meta($post->ID, "_y360path_variants", true)); //filter variants, that have a 360 view defined, add to results if ($_variants && sizeof($_variants) > 0) { foreach ($_variants as $key => $value) { if (!empty($value)) { $result[$key] = $value; } } } //return return $result; } private function _get_woo_version_number() { // If get_plugins() isn't available, require it if (!function_exists('get_plugins')) { require_once(ABSPATH . 'wp-admin/includes/plugin.php'); } // Create the plugins folder and file variables $plugin_folder = get_plugins('/' . 'woocommerce'); $plugin_file = 'woocommerce.php'; // If the plugin version number is set, return it if (isset($plugin_folder[$plugin_file]['Version'])) { return $plugin_folder[$plugin_file]['Version']; } else { // Otherwise return null return NULL; } } }//class