/** * Construct object */ public function __construct() { /* Just to prepare taxonomies */ $this->prepareAndGet(); /* List of taxonomies which will be filtered by language */ add_filter('pll_get_taxonomies', array($this, 'manageTaxonomiesTranslation')); if (Utilities::woocommerce_version_check('2.6')) { /* List of taxonomies to be copied/synced with exact same value */ $metas = Meta::getProductMetaToCopy(); // Shipping Class taxonomy translation is not supported after WooCommerce 2.6 if (in_array('product_shipping_class', $metas)) { $this->tax_to_copy[] = 'product_shipping_class'; } add_filter('pll_copy_taxonomies', array($this, 'copy_taxonomies'), 10, 2); } }
/** * Change the product stock in the given order item. * * @param array $item the order data * @param string $action STOCK_REDUCE_ACTION | STOCK_INCREASE_ACTION */ protected function change(array $item, $action = self::STOCK_REDUCE_ACTION) { $productID = $item['product_id']; $productObject = wc_get_product($productID); $productLang = pll_get_post_language($productID); $variationID = $item['variation_id']; /* Handle Products */ if ($productObject && $productLang) { /* Get the translations IDS */ $translations = Utilities::getProductTranslationsArrayByObject($productObject); /* Remove the current product from translation array */ unset($translations[$productLang]); $isManageStock = $productObject->managing_stock(); $isVariation = $variationID && $variationID > 0; $method = $action === self::STOCK_REDUCE_ACTION ? 'reduce_stock' : 'increase_stock'; $change = $action === self::STOCK_REDUCE_ACTION ? $item['qty'] : $item['change']; /* Sync stock for all translation */ foreach ($translations as $ID) { /* Only if product is managing stock */ if ($isManageStock) { if ($translation = wc_get_product($ID)) { $translation->{$method}($change); } } $general = Settings::getOption('general', MetasList::getID(), array('total_sales')); if (in_array('total_sales', $general)) { update_post_meta($ID, 'total_sales', get_post_meta($productID, 'total_sales', true)); } } /* Handle variation */ if ($isVariation) { $posts = Variation::getRelatedVariation($variationID); foreach ($posts as $post) { if ($post->ID == $variationID) { continue; } $variation = wc_get_product($post); if ($variation && $variation->managing_stock()) { $variation->{$method}($change); } } } } }
/** * Correct the locale for orders emails , Othe emails must be handled * correctly out of the box * * @global \Polylang $polylang * @global \WooCommerce $woocommerce * * @param string $locale current locale * * @return string locale */ public function correctLocal($locale) { global $polylang, $woocommerce; if (!$polylang || !$woocommerce) { return $locale; } $refer = isset($_GET['action']) && esc_attr($_GET['action'] === 'woocommerce_mark_order_status'); if (!is_admin() && !isset($_REQUEST['ipn_track_id']) || defined('DOING_AJAX') && !$refer) { return $locale; } if ('GET' === filter_input(INPUT_SERVER, 'REQUEST_METHOD') && !$refer) { return $locale; } $ID = false; if (!isset($_REQUEST['ipn_track_id'])) { $search = array('post', 'post_ID', 'pll_post_id', 'order_id'); foreach ($search as $value) { if (isset($_REQUEST[$value])) { $ID = esc_attr($_REQUEST[$value]); break; } } } else { $ID = $this->getOrderIDFromIPNRequest(); } if (get_post_type($ID) !== 'shop_order' && !$refer) { return $locale; } $orderLanguage = Order::getOrderLangauge($ID); if ($orderLanguage) { $entity = Utilities::getLanguageEntity($orderLanguage); if ($entity) { $polylang->curlang = $polylang->model->get_language($entity->locale); $GLOBALS['text_direction'] = $entity->is_rtl ? 'rtl' : 'ltr'; if (class_exists('WP_Locale')) { $GLOBALS['wp_locale'] = new \WP_Locale(); } return $entity->locale; } } return $locale; }
/** * Helper function - Gets the shipping methods enabled in the shop * * @return array $active_methods The id and respective plugin id of all active methods */ private function get_active_shipping_methods() { $active_methods = array(); if (Utilities::woocommerce_version_check('2.6')) { // WooCommerce 2.6 intoduces the concept of Shipping Zones // Format: $shipping_methods[zone_name_method_id] => shipping_method_object // where zone_name is e.g. domestic, europe, rest_of_the_world, and // methods_id is e.g. flat_rate, free_shiping, local_pickup, etc $shipping_methods = $this->get_zones_shipping_methods(); } else { // Format: $shipping_methods[method_id] => shipping_method_object // where methods_id is e.g. flat_rate, free_shiping, local_pickup, etc $shipping_methods = WC()->shipping->load_shipping_methods(); } foreach ($shipping_methods as $id => $shipping_method) { if (isset($shipping_method->enabled) && 'yes' === $shipping_method->enabled) { $active_methods[$id] = $shipping_method->plugin_id; } } return $active_methods; }
/** * Collect products from category translations * * Add all products in the given category translations * * @param array $productIDS array of products in the given category * @param integer $categoryID category ID * * @return array array of producs in the given category and its translations */ public function addProductsInCategoryTranslations($productIDS, $categoryID) { if (static::isCombine()) { /* Find the category translations */ $translations = Utilities::getTermTranslationsArrayByID($categoryID); foreach ($translations as $slug => $ID) { if ($ID === $categoryID) { continue; } $termIDS = get_term_children($ID, 'product_cat'); $termIDS[] = $ID; $productIDS = array_merge($productIDS, (array) get_objects_in_term($termIDS, 'product_cat')); } } return $productIDS; }
/** * Sync the product type selection (e.g. Simple product, Grouped product, Variable * product, etc ) in the dropdown list in the Product Data settings box * * @param integer $ID Product Id */ protected function sync_product_type_selection($ID = null) { /* * First we add save_post action to save the product type * as post meta * * This is step is important so we can get the right product type */ add_action('save_post', function ($_ID) { $product = wc_get_product($_ID); if ($product && !isset($_GET['from_post'])) { update_post_meta($_ID, '_translation_porduct_type', $product->product_type); } }); /* * If the _translation_porduct_type meta is found then we add the * js script to sync the product type selection * * TODO: Change the product type in the DB instead with * wp_set_object_terms( $product_id, 'the new product type', 'product_type' ); * */ if ($ID && ($type = get_post_meta($ID, '_translation_porduct_type'))) { add_action('admin_print_scripts', function () use($type) { $jsID = 'product-type-sync'; $code = sprintf('// <![CDATA[ %1$s' . ' addLoadEvent(function () { %1$s' . ' jQuery("#product-type option")' . ' .removeAttr("selected");%1$s' . ' jQuery("#product-type option[value=\\"%2$s\\"]")' . ' .attr("selected", "selected");%1$s' . '})' . '// ]]>', PHP_EOL, $type[0]); Utilities::jsScriptWrapper($jsID, $code, false); }, 11); } }
/** * {@inheritdocs} */ protected function doGetFields() { $fields = array(array('name' => 'fields-locker', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Fields Locker', 'woopoly'), 'desc' => __('Fields locker makes it easy for user to know which field to translate and which to ignore ', 'woopoly')), array('name' => 'emails', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Emails', 'woopoly'), 'desc' => __('Use order language whenever woocommerce sends order emails', 'woopoly')), array('name' => 'reports', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Reports', 'woopoly'), 'desc' => __('Enable reports language filtering and combining', 'woopoly')), array('name' => 'coupons', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Coupons Sync', 'woopoly'), 'desc' => __('Apply coupons rules for products and their translations', 'woopoly')), array('name' => 'stock', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Stock Sync', 'woopoly'), 'desc' => __('Sync stock for products and their translations', 'woopoly')), array('name' => 'categories', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Translate Categories', 'woopoly'), 'desc' => __('Enable categories translation', 'woopoly')), array('name' => 'tags', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Translate Tags', 'woopoly'), 'desc' => __('Enable tags translation', 'woopoly')), array('name' => 'attributes', 'type' => 'checkbox', 'default' => 'on', 'label' => __('Translate Attributes', 'woopoly'), 'desc' => __('Enable Attributes translation', 'woopoly')), array('name' => 'shipping-class', 'type' => 'checkbox', 'default' => 'off', 'label' => __('Translate Shipping Classes', 'woopoly'), 'desc' => __('Enable Shipping Classes translation' . (Utilities::woocommerce_version_check('2.6') ? ' (not supported for WooCommerce versions >= 2.6)' : ''), 'woopoly'))); return $fields; }
/** * Add a button before the attributes table to let the user know how to * translate the attributes labels * * @global type $pagenow * * @return boolean false if not attributes page */ public function addAttrsTranslateLinks() { global $pagenow; if ($pagenow !== 'edit.php') { return false; } $isAttrPage = isset($_GET['page']) && esc_attr($_GET['page']) === 'product_attributes'; if (!$isAttrPage) { return false; } $stringTranslationURL = add_query_arg(array('page' => 'mlang', 'tab' => 'strings', 'group' => __('Woocommerce Attributes', 'woo-poly-integration')), admin_url('options-general.php')); /* Add attribute translate button */ $buttonID = 'attrs-label-translation-button'; $buttonCode = sprintf('$("<a href=\'%s\' class=\'button button-primary button-large\'>%s</a><br><br>")' . ' .insertBefore(".attributes-table");', $stringTranslationURL, __('Translate Attributes Lables', 'woo-poly-integration')); /* Add attribute translate search link */ $searchLinkID = 'attr-label-translate-search-link'; $searchLinkCode = sprintf("\$('.attributes-table .row-actions').each(function () {\n" . ' var $this = $(this);' . ' var attrName = $this.parent().find("strong a").text();' . ' var attrTranslateUrl = "%s&s="+attrName ;' . ' var attrTranslateHref = ' . ' "<span class=\'translate\'>"' . ' + "| "' . ' + "<a href=\'"+attrTranslateUrl+"\'>%s</a>"' . ' + "</span>";' . ' $this.append(attrTranslateHref);' . "\n});\n", $stringTranslationURL, __('Translate', 'woo-poly-integration')); /* Output code */ Utilities::jsScriptWrapper($buttonID, $buttonCode); Utilities::jsScriptWrapper($searchLinkID, $searchLinkCode); }
/** * Check if we have to disable the language switcher in the polylang setting * page */ public function shouldDisableLangSwitcher() { add_action('current_screen', function () { $screen = get_current_screen(); if ($screen->id !== 'settings_page_mlang') { return false; } $count = wp_count_posts('product_variation'); if (!($count && $count->publish > 0)) { return false; } add_action('admin_print_scripts', function () { $jsID = 'disable-lang-switcher'; $code = sprintf('$("#options-lang #default_lang")' . '.css({' . ' "opacity": .5,' . ' "pointer-events": "none"' . '});' . ' $("#options-lang").prepend(' . ' "<p class=\'update-nag\'>%s</p>"' . ');', __('You can not change the default language, when adding variable products', 'woopoly')); Utilities::jsScriptWrapper($jsID, $code); }, 100); }); }
/** * Get array of term translations IDS. * * @param int $ID the term ID * * @return array array contains all translation IDS for the given term */ protected function getProductTermTranslationIDS($ID) { $IDS = Utilities::getTermTranslationsArrayByID($ID); return $IDS ? $IDS : array($ID); }
/** * Replace products in cart with translation of the product in the current * language * * @param \WC_Product|\WC_Product_Variation $cart_item_data Product data * @param array $cart_item Cart item * * @return \WC_Product|\WC_Product_Variation */ public function translate_cart_item_product($cart_item_data, $cart_item) { $cart_product_id = isset($cart_item['product_id']) ? $cart_item['product_id'] : 0; $cart_variation_id = isset($cart_item['variation_id']) ? $cart_item['variation_id'] : 0; // By default, returns the same input $cart_item_data_translation = $cart_item_data; switch ($cart_item_data->product_type) { case 'variation': $variation_translation = $this->get_variation_translation($cart_variation_id); $cart_item_data_translation = $variation_translation ? $variation_translation : $cart_item_data_translation; break; case 'simple': default: $product_translation = Utilities::getProductTranslationByID($cart_product_id); $cart_item_data_translation = $product_translation ? $product_translation : $cart_item_data_translation; break; } return $cart_item_data_translation; }
/** * Do sync category custom fields * * @param integer $ID the term ID * @param string $key the key * @param mixed $value the value */ public function doSyncProductCatCustomFields($ID, $key, $value = '') { $translations = Utilities::getTermTranslationsArrayByID($ID); foreach ($translations as $translation) { update_woocommerce_term_meta($translation, $key, $value); } }