Changeset 2739048
- Timestamp:
- 06/08/2022 07:01:58 AM (4 years ago)
- Location:
- wc-fields-factory
- Files:
-
- 2 edited
-
tags/4.0.1/includes/wcff_dao.php (modified) (1 diff)
-
trunk/includes/wcff_dao.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wc-fields-factory/tags/4.0.1/includes/wcff_dao.php
r2739039 r2739048 12 12 */ 13 13 class wcff_dao { 14 15 /*16 * 17 * Namespace for WCFF related post meta18 * "wccpf_" for Custom product page Fields ( Front end product page )19 * "wccaf_" for Custom admin page fields ( for Admin Products )20 * "wccvf_" for Custom admin page fields ( for Variation Fields )21 * "wcccf_" for Custom admin page fields ( for Checkout Fields )22 * 23 **/24 private $wcff_key_prefix = "wccpf_";25 26 /* Holds all the supported field's specific configuration meta */27 private $fields_meta = array();28 29 /* Holds all the configuration meta that are common to all fields ( both Product as well as Admin ) */30 private $common_meta = array();31 32 /* Holds all the configuration meta that are common to Admin Fields */33 private $wccaf_common_meta = array();34 35 /**/36 public $has_variable_tab_fields = false;37 38 /*39 * 40 * Cusdtom post meta Keys that are used by WCFF for various purposes41 * 42 * */43 public $special_keys = array(44 'fee_rules',45 'layout_meta',46 'field_rules',47 'group_rules',48 'pricing_rules',49 'location_rules',50 'condition_rules', 51 'show_group_title',52 'use_custom_layout',53 'product_tab_title',54 'product_tab_priority',55 'is_this_group_clonable',56 'fields_label_alignement',57 'field_location_on_product',58 'field_location_on_archive', 59 'is_this_group_for_authorized_only',60 'wcff_group_preference_target_roles'61 );62 63 public function __construct() {64 /* Wordpress's Save Post action hook65 * This is where we would save all the rules for the Fields Group ( post ) that is being saved */66 add_action( 'save_post', array($this, 'on_save_post' ), 1, 3 );67 }68 69 /**70 *71 * Set the current post type properties,<br/>72 * based on this only all the subsequent fields related operation will happen<br/>73 * this option could be either 'wccpf' for product fields or 'wccaf' for admin fields.74 *75 * @param string $_type76 *77 */78 public function set_current_post_type($_type = "wccpf") {79 $this->wcff_key_prefix = $_type . "_";80 }81 82 /**83 *84 * Return the Fields config meta for Factory View<br/>85 * Contains entire (specific to each fields) config meta list for each field type.86 *87 * @return array88 *89 */90 public function get_fields_meta() {91 /* Make sure the meta is loaded */92 $this->load_core_meta();93 return $this->fields_meta;94 }95 96 /**97 *98 * Return the Fields config common meta for Factory View<br/>99 * Contains entire (common for all fields) config meta list for each field type.100 *101 * @return array102 *103 */104 public function get_fields_common_meta() {105 /* Make sure the meta is loaded */106 $this->load_core_meta();107 return $this->common_meta;108 }109 110 /**111 *112 * Return the Admin Fields config common meta for Factory View<br/>113 * Contains entire (common for all admin fields) config meta list for each field type.114 *115 * @return array116 *117 */118 public function get_admin_fields_comman_meta() {119 /* Make sure the meta is loaded */120 $this->load_core_meta();121 return $this->wccaf_common_meta;122 }123 124 /**125 *126 * Loads Fields configuration meta from the file system<br>127 * Fields specific configuration meta from 'meta/wcff-meta.php'<br>128 * Common configuration meta from 'meta/wcff-common-meta.php'<br>129 * Common admin configuration meta from 'meta/wcff-common-wccaf-meta.php'130 *131 */132 private function load_core_meta() {133 /* Load core fields config meta */134 if (!is_array($this->fields_meta) || empty( $this->fields_meta)) {135 $this->fields_meta = include('meta/wcff-meta.php');136 }137 /* Load common config meta for all fields */138 if (!is_array($this->common_meta) || empty($this->common_meta)) {139 $this->common_meta = include('meta/wcff-common-meta.php');140 }141 /* Load common config meta for admin fields */142 if (!is_array($this->wccaf_common_meta) || empty($this->wccaf_common_meta)) {143 $this->wccaf_common_meta = include('meta/wcff-common-wccaf-meta.php');144 }145 }146 147 /**148 *149 * Called whenever user 'Update' or 'Save' post from wp-admin single post view<br/>150 * This is where the various (Product, Cat, Location ... ) rules for the fields group will be stored in their respective post meta.151 *152 * @param integer $_pid153 * @param WP_Post $_post154 * @param boolean $_update155 * @return void|boolean156 *157 */158 public function on_save_post($_pid, $_post, $_update) {159 /* Maje sure the post types are valid */160 if (!$_pid || ! $_post || ($_post->post_type != "wccpf" && $_post->post_type != "wccaf" && $_post->post_type != "wccvf" && $_post->post_type != "wcccf")) {161 return false;162 }163 164 $_pid = absint($_pid);165 166 /* Prepare the post type prefix for meta key */167 $this->wcff_key_prefix = $_post->post_type . "_";168 169 /* Conditional rules - determine which fields group belongs to which products */170 if (isset($_REQUEST["wcff_condition_rules"])) {171 delete_post_meta($_pid, $this->wcff_key_prefix .'condition_rules');172 add_post_meta($_pid, $this->wcff_key_prefix .'condition_rules', $_REQUEST["wcff_condition_rules"]);173 }174 175 /* Location rules - specific to Admin Fields */176 if (isset($_REQUEST["wcff_location_rules"])) {177 delete_post_meta($_pid, $this->wcff_key_prefix .'location_rules');178 add_post_meta($_pid, $this->wcff_key_prefix .'location_rules', $_REQUEST["wcff_location_rules"]);179 }180 181 /**/182 if (isset($_REQUEST["wcff_layout_meta"])) {183 delete_post_meta($_pid, $this->wcff_key_prefix .'layout_meta');184 add_post_meta($_pid, $this->wcff_key_prefix .'layout_meta', $_REQUEST["wcff_layout_meta"]);185 }186 187 if (isset($_REQUEST["wcff_use_custom_layout"])) { 188 delete_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout');189 add_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout', "yes");190 } else {191 delete_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout');192 add_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout', "no");193 }194 195 /* Field location for each field's group */196 if (isset($_REQUEST["field_location_on_product"])) {197 delete_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_product');198 add_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_product', $_REQUEST["field_location_on_product"]);199 delete_post_meta($_pid, $this->wcff_key_prefix .'product_tab_title');200 delete_post_meta($_pid, $this->wcff_key_prefix .'product_tab_priority');201 if ($_REQUEST["field_location_on_product"] == "woocommerce_single_product_tab" && isset($_REQUEST["product_tab_config_title"])) {202 add_post_meta($_pid, $this->wcff_key_prefix .'product_tab_title', $_REQUEST["product_tab_config_title"]);203 add_post_meta($_pid, $this->wcff_key_prefix .'product_tab_priority', $_REQUEST["product_tab_config_priority"]);204 }205 }206 207 /* Field location for archive page */208 if (isset($_REQUEST["field_location_on_archive"])) {209 delete_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_archive');210 add_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_archive', $_REQUEST["field_location_on_archive"]);211 }212 213 /* Group level cloning option */214 if (isset($_REQUEST["wcff_group_clonable_radio"])) {215 delete_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_clonable');216 add_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_clonable', $_REQUEST["wcff_group_clonable_radio"]); 217 }218 219 /* Group title display option */220 if (isset($_REQUEST["wcff_group_title_radio"])) {221 delete_post_meta($_pid, $this->wcff_key_prefix .'show_group_title');222 add_post_meta($_pid, $this->wcff_key_prefix .'show_group_title', $_REQUEST["wcff_group_title_radio"]);223 }224 225 /**/226 if (isset($_REQUEST["wcff_label_alignment_radio"])) {227 delete_post_meta($_pid, $this->wcff_key_prefix .'fields_label_alignement');228 add_post_meta($_pid, $this->wcff_key_prefix .'fields_label_alignement', $_REQUEST["wcff_label_alignment_radio"]);229 }230 231 /* Authorized users only option */232 if (isset($_REQUEST["wcff_group_authorized_only_radio"])) { 233 delete_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_for_authorized_only');234 add_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_for_authorized_only', $_REQUEST["wcff_group_authorized_only_radio"]); 235 }236 237 /* Target roles option */238 if (isset($_REQUEST["wcff_group_preference_target_roles"])) {239 delete_post_meta($_pid, $this->wcff_key_prefix .'wcff_group_preference_target_roles');240 add_post_meta($_pid, $this->wcff_key_prefix .'wcff_group_preference_target_roles', json_encode($_REQUEST["wcff_group_preference_target_roles"])); 241 }242 243 /* Update the fields order */244 $this->update_fields_order($_pid);245 246 /* Update the dirty fields meta */247 if (isset($_REQUEST["wcff_dirty_fields_configuration"]) && !empty($_REQUEST["wcff_dirty_fields_configuration"])) { 248 $fields = json_decode(str_replace('\"','"', $_REQUEST["wcff_dirty_fields_configuration"]), true);249 foreach ($fields as $fkey => $meta) {250 if (!isset($meta["updated"])) {251 /* Only update if no 'updated' property found */252 $this->update_field($_pid, $meta);253 } 254 } 255 } 256 257 return true;258 }259 260 /**261 *262 * Update the fields sequence order properties for all fields on a given group (represented by $_pid)<br/>263 * Called when Fields Group got saved or updated.264 *265 * @param integer $_pid266 * @return boolean267 *268 */269 public function update_fields_order($_pid = 0) { 270 $fields = $this->load_fields($_pid, false);271 /* Update each fields order property */272 foreach ($fields as $key => $field) {273 if (isset($_REQUEST[$key."_order"])) {274 $field["order"] = $_REQUEST[$key."_order"];275 update_post_meta($_pid, $key, wp_slash(json_encode($field)));276 }277 }278 279 return true;280 }281 282 /**283 *284 * Load conditional rules for given Fields Group Post285 *286 * @param integer $_pid287 * @return mixed288 *289 */290 public function load_target_products_rules($_pid = 0) {291 $condition = array();292 if ($_pid) {293 $_pid = absint( $_pid );294 /* Since we have renamed 'group_rules' meta as 'condition_rules' we need to make sure it is upto date295 * and we remove the old 'group_rules' meta as well296 **/297 $rules = get_post_meta($_pid, $this->wcff_key_prefix .'group_rules', true);298 if ($rules && $rules != "") {299 delete_post_meta($_pid, $this->wcff_key_prefix .'group_rules');300 update_post_meta($_pid, $this->wcff_key_prefix .'condition_rules', $rules);301 }302 $condition = get_post_meta($_pid, $this->wcff_key_prefix .'condition_rules', true);303 304 if ($condition != "") {305 $condition = json_decode($condition, true);306 }307 }308 return apply_filters($this->wcff_key_prefix .'condition_rules', $condition, $_pid);309 }310 311 public function load_layout_meta($_pid = 0) {312 $layout = array();313 if ($_pid) {314 $_pid = absint($_pid);315 $layout = get_post_meta($_pid, $this->wcff_key_prefix .'layout_meta', true);316 if ($layout != "") {317 $layout = json_decode($layout, true);318 }319 } 320 return apply_filters($this->wcff_key_prefix .'layout_meta', $layout, $_pid);321 }322 323 public function load_use_custom_layout($_pid) {324 $_pid = absint($_pid);325 $use_custom_layout = get_post_meta($_pid, ($this->wcff_key_prefix ."use_custom_layout"), true);326 return ($use_custom_layout != "") ? $use_custom_layout : "no";327 }328 329 /**330 *331 * Load locational rules for given Admin Fields Group Post332 *333 * @param integer $_pid334 * @return mixed335 *336 */337 public function load_location_rules($_pid = 0) {338 $location = "";339 if ($_pid) {340 $_pid = absint($_pid);341 $location = get_post_meta($_pid, $this->wcff_key_prefix .'location_rules', true);342 } 343 return apply_filters( $this->wcff_key_prefix .'location_rules', $location, $_pid );344 }345 346 /**347 *348 * Load locational rules for entire admin fields posts349 *350 * @return mixed351 *352 */353 public function load_all_wccaf_location_rules() {354 $location_rules = array();355 $wcffs = get_posts(array(356 'post_type' => "wccaf",357 'posts_per_page' => -1,358 'order' => 'ASC')359 );360 if (count($wcffs) > 0) {361 foreach ($wcffs as $wcff) {362 $temp_rules = get_post_meta($wcff->ID, 'wccaf_location_rules', true);363 $location_rules[] = json_decode($temp_rules, true); 364 }365 }366 367 return apply_filters( 'wccaf_all_location_rules', $location_rules );368 }369 370 /**371 *372 * Used to load all woocommerce products<br/>373 * Used in "Conditions" Widget374 *375 * @return ARRAY of products ( ids & titles )376 *377 */378 public function load_all_products() {379 $productsList = array();380 $products = get_posts(array(381 'post_type' => 'product',382 'posts_per_page' => -1,383 'order' => 'ASC')384 );385 386 if (count($products) > 0) {387 foreach ($products as $product) {388 $productsList[] = array("id" => $product->ID, "title" => $product->post_title);389 }390 }391 392 return apply_filters( 'wcff_products', $productsList );393 }394 395 /**396 *397 * Used to load all woocommerce products<br/>398 * Used in "Conditions" Widget399 *400 * @return ARRAY of products ( ids & titles )401 *402 */403 public function load_variable_products() {404 $productsList = array();405 $products = get_posts(array(406 'post_type' => 'product',407 'posts_per_page' => -1,408 'order' => 'ASC')409 );410 411 if (count($products) > 0) {412 $wcG3 = version_compare(WC()->version, '2.2.0', '<');413 foreach ($products as $product) {414 $product_ob = $wcG3 ? get_product($product->ID) : wc_get_product($product->ID); 415 if ($product_ob->is_type( 'variable' )){416 $productsList[] = array("id" => $product->ID, "title" => $product->post_title);417 }418 }419 }420 421 return apply_filters( 'wcff_products_with_variation', $productsList );422 }423 424 /**425 *426 * Used to load all woocommerce product category<br/>427 * Used in "Conditions" Widget428 *429 * @return ARRAY of product categories ( ids & titles )430 *431 */432 public function load_product_categories() {433 $product_cats = array();434 $pcat_terms = get_terms('product_cat', 'orderby=count&hide_empty=0');435 436 foreach ($pcat_terms as $pterm) {437 $product_cats[] = array("id" => $pterm->slug, "title" => $pterm->name);438 }439 440 return apply_filters( 'wcff_product_categories', $product_cats );441 }442 443 /**444 *445 * Used to load all woocommerce product tags<br/>446 * Used in "Conditions" Widget447 *448 * @return ARRAY of product tags ( ids & titles )449 *450 */451 public function load_product_tags() {452 $product_tags = array();453 $ptag_terms = get_terms('product_tag', 'orderby=count&hide_empty=0');454 455 foreach ($ptag_terms as $pterm) {456 $product_tags[] = array("id" => $pterm->slug, "title" => $pterm->name);457 }458 459 return apply_filters( 'wcff_product_tags', $product_tags );460 }461 462 /**463 *464 * Used to load all woocommerce product types<br/>465 * Used in "Conditions" Widget466 *467 * @return ARRAY of product types ( slugs & titles )468 *469 */470 public function load_product_types() {471 $product_types = array();472 $all_types = array (473 'simple' => __( 'Simple product', 'woocommerce' ),474 'grouped' => __( 'Grouped product', 'woocommerce' ),475 'external' => __( 'External/Affiliate product', 'woocommerce' ),476 'variable' => __( 'Variable product', 'woocommerce' )477 );478 479 foreach ($all_types as $key => $value) {480 $product_types[] = array("id" => $key, "title" => $value);481 }482 483 return apply_filters( 'wcff_product_types', $product_types );484 }485 486 /**487 *488 * Used to load all woocommerce product types<br/>489 * Used in "Conditions" Widget490 *491 * @return ARRAY of product types ( slugs & titles )492 *493 */494 public function load_product_variations($parent = 0) {495 $products_variation_list = array();496 $variations = array();497 $arg = array (498 'post_type' => 'product_variation',499 'posts_per_page' => -1,500 'order' => 'ASC'501 );502 if ($parent != 0) {503 $arg['post_parent'] = $parent;504 }505 $variations = get_posts($arg);506 foreach ($variations as $product) {507 $products_variation_list[] = array("id" => $product->ID, "title" => $product->post_title);508 }509 return apply_filters( 'wcff_product_variations', $products_variation_list );510 }511 512 /**513 *514 * Used to load all woocommerce product tabs<br/>515 * Used in "Location" Widget516 *517 * @return ARRAY of product tabs ( titles & tab slugs )518 *519 */520 public function load_product_tabs() {521 return apply_filters( 'wcff_product_tabs', array (522 "General Tab" => "woocommerce_product_options_general_product_data",523 "Inventory Tab" => "woocommerce_product_options_inventory_product_data",524 "Shipping Tab" => "woocommerce_product_options_shipping",525 "Attributes Tab" => "woocommerce_product_options_attributes",526 "Related Tab" => "woocommerce_product_options_related",527 "Advanced Tab" => "woocommerce_product_options_advanced",528 "Variable Tab" => "woocommerce_product_after_variable_attributes"529 ));530 }531 532 /**533 *534 * Used to load all wp context used for meta box<br/>535 * Used for laying Admin Fields536 *537 * @return ARRAY of meta contexts ( slugs & titles )538 *539 */540 public function load_metabox_contexts() {541 return apply_filters( 'wcff_metabox_contexts', array (542 "normal" => __( "Normal", "wc-fields-factory" ),543 "advanced" => __( "Advanced", "wc-fields-factory" ),544 "side" => __( "Side", "wc-fields-factory" )545 ));546 }547 548 /**549 *550 * Used to load all wp priorities used for meta box<br/>551 * Used for laying Admin Fields552 *553 * @return ARRAY of meta priorities ( slugs & titles )554 *555 */556 public function load_metabox_priorities() { 557 return apply_filters( 'wcff_metabox_priorities', array (558 "low" => __( "Low", "wc-fields-factory" ),559 "high" => __( "High", "wc-fields-factory" ),560 "core" => __( "Core", "wc-fields-factory" ),561 "default" => __( "Default", "wc-fields-factory" )562 ));563 }564 565 /**566 *567 * Used to load all woocommerce form fields validation types, to built Checkout Fields568 *569 * @return ARRAY of validation types570 *571 */572 public function load_wcccf_validation_types() {573 return apply_filters( 'wcccf_validation_types', array (574 "required" => __( "Required", "wc-fields-factory" ),575 "phone" => __( "Phone", "wc-fields-factory" ),576 "email" => __( "Email", "wc-fields-factory" ),577 "postcode" => __( "Post Code", "wc-fields-factory" )578 ));579 }580 581 public function load_target_contexts() {582 return apply_filters( "wcff_target_context", array (583 array("id" => "product", "title" => __("Product", "wc-fields-factory")),584 array("id" => "product_cat", "title" => __("Product Category", "wc-fields-factory")),585 array("id" => "product_tag", "title" => __("Product Tag", "wc-fields-factory")),586 array("id" => "product_type", "title" => __("Product Type", "wc-fields-factory")),587 array("id" => "product_variation", "title" => __("Product Variation", "wc-fields-factory"))588 ));589 }590 591 public function load_target_logics() {592 return apply_filters( "wcff_target_logic", array (593 array("id"=>"==", "title"=>__("is equal to", "wc-fields-factory")),594 array("id"=>"!=", "title"=>__("is not equal to", "wc-fields-factory"))595 ));596 }597 598 public function search_posts($_payload = array()) {599 600 global $wpdb;601 $res = array(); 602 $posts = array();603 604 $parent = isset($_payload["parent"]) ? $_payload["parent"] : 0;605 $search = isset($_payload["search"]) ? $_payload["search"] : ""; 606 $post_type = isset($_payload["post_type"]) ? $_payload["post_type"] : "";607 608 if (absint($parent) != 0) {609 $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM $wpdb->posts WHERE post_type='%s' AND post_parent=%d AND post_status='publish' AND post_excerpt LIKE '%s'", $post_type, $parent, '%'. $wpdb->esc_like($search) .'%'));610 } else {611 $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM $wpdb->posts WHERE post_type='%s' AND post_status='publish' AND post_title LIKE '%s'", $post_type, '%'. $wpdb->esc_like($search) .'%'));612 } 613 614 if ($post_type != "product") {615 foreach ($posts as $post) {616 $res[] = array( "id" => $post->{"ID"}, "title" => $post->{"post_title"});617 }618 } else {619 $wcG3 = version_compare(WC()->version, '2.2.0', '<');620 foreach ($posts as $post) {621 $product = $wcG3 ? get_product($post->{"ID"}) : wc_get_product($post->{"ID"});622 if ($product->is_type('variable')) {623 $res[] = array( "id" => $post->{"ID"}, "title" => $post->{"post_title"});624 } 625 }626 } 627 return $res;628 }629 630 public function insert_wccvf_map_varioation_level($_payload = array()) {631 632 $res = false; 633 634 if (!isset($_payload["rules"]) || !is_array($_payload["rules"]) || empty($_payload["rules"])) { 635 return false;636 }637 638 foreach ($_payload["rules"] as $gpid => $new_rules) {639 $all_rules = $this->load_target_products_rules($gpid);640 if (!is_array($all_rules)) {641 $all_rules = array();642 }643 /* Append the new rule entry */ 644 foreach ($new_rules as $new_rule) {645 if (!in_array($new_rule, $all_rules)) {646 $all_rules[] =$new_rule; 647 } 648 }649 /* Update the condition rules */650 delete_post_meta($gpid, $this->wcff_key_prefix .'condition_rules');651 $res = add_post_meta($gpid, $this->wcff_key_prefix .'condition_rules', json_encode($all_rules));652 } 653 654 return $res ? true : false;655 656 }657 658 public function remove_wccvf_map_variation_level($_payload = array()) {659 660 if (!isset($_payload["pid"]) && empty($_payload["pid"])) {661 return false;662 }663 if (!isset($_payload["vid"]) || empty($_payload["vid"])) {664 return false;665 } 666 667 /* Retrive the current condition rules */668 $all_rules = $this->load_target_products_rules($_payload["pid"]);669 670 if (is_array($all_rules)) {671 foreach ($all_rules as $aIndex => $rules) {672 foreach ($rules as $rIndex => $rule) { 673 if ($rule["endpoint"] == $_payload["vid"]) {674 unset($all_rules[$aIndex][$rIndex]); 675 } 676 }677 /* Remove the group if it is empty */678 if (empty($all_rules[$aIndex])) {679 unset($all_rules[$aIndex]);680 }681 }682 }683 684 /* Update the condition rules */685 delete_post_meta($_payload["pid"], $this->wcff_key_prefix .'condition_rules');686 return add_post_meta($_payload["pid"], $this->wcff_key_prefix .'condition_rules', json_encode($all_rules));687 688 }689 690 /**691 * 692 * This routine does some reverse pulkling data extraction693 * 694 * @return array695 */696 public function load_map_wccvf_variations() {697 698 $flag = false;699 $result = array();700 $vproducts = array();701 702 $all_rules = array();703 $wccvf_rules = array(); 704 705 $wcG3 = version_compare(WC()->version, '2.2.0', '<'); 706 $products = get_posts(array('post_type' => 'product', 'posts_per_page' => -1)); 707 $wccvfs = get_posts(array('post_type' => "wccvf", 'posts_per_page' => -1));708 709 /**710 * 711 * Step 1. 712 * Consolidating all rules, from all wccvf post 713 * 714 */ 715 foreach ($wccvfs as $wccvf) {716 717 $wccvf_rules = get_post_meta($wccvf->ID, 'wccvf_condition_rules', true);718 if ($wccvf_rules != null) {719 $wccvf_rules = json_decode($wccvf_rules, true);720 721 /* Well this is a two dimentional array */722 foreach ($wccvf_rules as $rules) {723 if (is_array($rules)) {724 foreach ($rules as $rule) {725 if (is_array($rule)) {726 727 $rule["group_id"] = $wccvf->ID;728 $rule["group_title"] = $wccvf->post_title;729 $all_rules[] = $rule;730 731 }732 }733 }734 }735 } 736 737 }738 739 /**740 * 741 * Step 2.742 * Fetching all products with variations.743 * 744 */745 foreach ($products as $post) {746 747 $product = $wcG3 ? get_product($post->ID) : wc_get_product($post->ID);748 if ($product->is_type( 'variable' )) {749 $wp_query = new WP_Query(array(750 'post_type' => 'product_variation',751 'post_status' => 'publish',752 'post_parent' => $post->ID,753 'posts_per_page' => -1,754 'fields' => array('ID', 'post_title')755 ));756 $vproducts[] = array("id" => $post->ID, "title" => $post->post_title, "variations" => $wp_query->posts);757 }758 759 }760 761 foreach ($vproducts as $product) {762 if (is_array($product["variations"])) {763 $variations = array();764 765 foreach ($product["variations"] as $variation) {766 $flag = false;767 $fgroups = array();768 769 foreach ($all_rules as $rule) {770 if (absint($rule["endpoint"]) == absint($variation->ID)) {771 $flag = true;772 $fgroups[] = array("gid" => $rule["group_id"], "gtitle" => $rule["group_title"]);773 }774 if ($flag) {775 $variations[$variation->ID] = array("variation_title" => $variation->post_excerpt, "groups" => $fgroups);776 }777 }778 if (!empty($variations)) {779 $result[$product["id"]] = array("product_title" => $product["title"], "variations" => $variations);780 }781 }782 783 }784 }785 786 return $result;787 788 }789 790 public function check_product_for_variation_mappings($_pid, $_type) {791 792 if ($_pid) {793 794 $_pid = absint($_pid); 795 $this->wcff_key_prefix = $_type . "_";796 797 $wp_query = new WP_Query(array(798 'post_type' => 'product_variation',799 'post_status' => 'publish',800 'post_parent' => $_pid,801 'posts_per_page' => -1,802 'fields' => array('ID', 'post_title')803 ));804 805 $wccvfs = get_posts(array('post_type' => $_type, 'posts_per_page' => -1)); 806 foreach ($wccvfs as $wccvf) {807 808 $wccvf_rules = get_post_meta($wccvf->ID, $_type .'_condition_rules', true);809 if ($wccvf_rules != null) {810 $wccvf_rules = json_decode($wccvf_rules, true);811 812 /* Well this is a two dimentional array */813 foreach ($wccvf_rules as $rules) {814 if (is_array($rules)) {815 foreach ($rules as $rule) {816 if (is_array($rule)) { 817 foreach ($wp_query->posts as $variation) {818 if (isset($rule["endpoint"]) && absint($rule["endpoint"]) == absint($variation->ID)) {819 $this->has_variable_tab_fields = true;820 return true;821 } 822 } 823 }824 }825 }826 }827 }828 } 829 }830 831 return false;832 833 }834 835 /**836 *837 * This function is used to load all wcff fields (actualy post meta) for a single WCFF post<br/>838 * Mostly used in editing wccpf fields in admin screen839 *840 * @param integer $pid - WCFF Post Id841 * @param boolean $sort - Whether returning fields should be sorted842 * @return array843 *844 */845 public function load_fields($_pid = 0, $_sort = true) {846 847 $fields = array(); 848 if ($_pid) {849 $_pid = absint($_pid); 850 $meta = get_post_meta($_pid);851 852 $excluded_keys = $this->prepare_special_keys();853 foreach ($meta as $key => $val) {854 /* Exclude special purpose custom meta */855 if (!in_array($key, $excluded_keys) && (strpos($key, $this->wcff_key_prefix) === 0)) {856 $fields[$key] = json_decode($val[0], true);857 }858 }859 860 if ($_sort) {861 $this->usort_by_column($fields, "order");862 }863 }864 865 return apply_filters( $this->wcff_key_prefix .'fields', $fields, $_pid, $_sort );866 867 }868 869 /**870 *871 * Loads all fields of the given Fields Group Post872 *873 * @param number $_pid874 * @param string $_mkey875 * @return mixed876 *877 */878 public function load_field($_pid = 0, $_mkey = "") {879 $_pid = absint($_pid);880 $post = get_post($_pid);881 $field = get_post_meta($_pid, $_mkey, true);882 if ($field === "") {883 $field = "{}";884 } 885 $field = json_decode($field, true);886 return apply_filters( $post->post_type .'_field', $field, $_pid, $_mkey );887 }888 889 /**890 * 891 * Create a Unique ID for the field and store with initial data892 * 893 * @param number $_pid894 * @param string $_type895 * @return string|boolean896 */897 public function create_field($_pid, $_type, $_order) {898 $_pid = absint($_pid);899 900 $id = $this->generate_unique_id();901 $id = apply_filters("wcff_new_field_id", $id);902 903 $meta = array (904 "id" => $id,905 "type" => $_type,906 "label" => "",907 "order" => $_order,908 "status" => true909 ); 910 if (add_post_meta($_pid, ($this->wcff_key_prefix . $id), wp_slash(json_encode($meta)))) {911 return ($this->wcff_key_prefix . $id);912 } 913 return false;914 }915 916 /**917 *918 * Save the given field's config meta as the post meta on a given Fields Group Post.919 *920 * @param number $_pid921 * @param object $_payload922 * @return number|false923 *924 */925 public function save_field($_pid, $_payload) {926 $_pid = absint($_pid);927 $_payload= apply_filters( 'wcff_before_save_'. $this->wcff_key_prefix .'field', $_payload, $_pid );928 if (!isset($_payload["name"]) || $_payload["name"] == "_" || $_payload["name"] != "") {929 $_payload["key"] = $this->wcff_key_prefix . $this->url_slug($_payload["name"], array('delimiter' => '_'));930 }931 $flg = add_post_meta($_pid, $_payload["key"], wp_slash(json_encode($_payload))) == false ? false : true;932 return $flg;933 }934 935 public function update_field($_pid, $_payload) {936 $msg = "";937 $res = true;938 $_pid = absint($_pid);939 if (isset($_payload["key"])) {940 delete_post_meta($_pid, $_payload["key"]);941 if (add_post_meta($_pid, $_payload["key"], wp_slash(json_encode($_payload))) == false) {942 $res = false;943 $msg = __( "Failed to update the custom field", "wc-fields-factory" );944 }945 } 946 return array("res" => $res, "msg" => $msg);947 }948 949 public function toggle_field($_pid, $_key, $_status) {950 $msg = "";951 $res = true;952 $meta_val = get_post_meta($_pid, $_key, true);953 if ($meta_val && !empty($meta_val)) {954 $field = json_decode(wp_unslash($meta_val), true);955 if (isset($field["is_enable"])) {956 $field["is_enable"] = $_status;957 delete_post_meta($_pid, $_key);958 if (add_post_meta($_pid, $_key, wp_slash(json_encode($field))) == false) {959 $res = false;960 $msg = __( "Failed to update.!", "wc-fields-factory" );961 }962 } else {963 $res = false;964 $msg = __( "Failed to update, Key is missing.!", "wc-fields-factory" );965 }966 } else {967 $res = false;968 $msg = __( "Failed to update, Meta is empty.!", "wc-fields-factory" );969 }970 return array("res" => $res, "msg" => $msg);971 }972 973 public function clone_group($_pid = 0, $_post_type = "") {974 global $wpdb; 975 $_pid = ($_pid == 0) ? (isset($_REQUEST["post"]) ? $_REQUEST["post"] : 0) : 0;976 $_post_type = ($_post_type == "") ? (isset($_REQUEST["post_type"]) ? $_REQUEST["post_type"] : "") : "";977 if (isset($_pid) && $_pid > 0) {978 $post = get_post($_pid);979 $new_post_id = wp_insert_post(array(980 'comment_status' => $post->comment_status,981 'ping_status' => $post->ping_status,982 'post_author' => $post->post_author,983 'post_content' => $post->post_content,984 'post_excerpt' => $post->post_excerpt,985 'post_name' => $post->post_name,986 'post_parent' => $post->post_parent,987 'post_password' => $post->post_password,988 'post_status' => 'publish',989 'post_title' => "Copy - ". $post->post_title,990 'post_type' => $post->post_type,991 'to_ping' => $post->to_ping,992 'menu_order' => $post->menu_order993 ));994 995 $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$_pid");996 if (count($post_meta_infos)!=0) {997 $sql_query_sel = array();998 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";999 foreach ($post_meta_infos as $meta_info) {1000 $meta_key = $meta_info->meta_key;1001 if( $meta_key == '_wp_old_slug' ) continue;1002 $meta_value = addslashes($meta_info->meta_value);1003 $sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'";1004 }1005 $sql_query.= implode(" UNION ALL ", $sql_query_sel);1006 $wpdb->query($sql_query);1007 }1008 }1009 if ($_post_type != "wccvf") {1010 wp_redirect( admin_url('edit.php?post_type='. $_post_type));1011 } else {1012 wp_redirect( admin_url('edit.php?post_type=wccpf&page=variation_fields_config'));1013 } 1014 exit;1015 }1016 1017 public function clone_field($_pid, $_fkey) {1018 $_pid = absint($_pid);1019 $id = $this->generate_unique_id();1020 $id = apply_filters("wcff_new_field_id", $id);1021 $cloned = $this->load_field($_pid, $_fkey); 1022 if (is_array($cloned)) {1023 $cloned["id"] = $id;1024 $cloned["label"] = "Copy - ". $cloned["label"];1025 if (add_post_meta($_pid, ($this->wcff_key_prefix . $id), wp_slash(json_encode($cloned)))) {1026 return ($this->wcff_key_prefix . $id);1027 }1028 }1029 return false;1030 }1031 1032 /**1033 *1034 * Remove the given field from Fields Group Post1035 *1036 * @param number $_pid1037 * @param string $_mkey1038 * @return boolean1039 *1040 */1041 public function remove_field($_pid, $_mkey) {1042 if ($_pid) {1043 $_pid = absint($_pid);1044 $post = get_post($_pid);1045 do_action($post->post_type .'_before_remove_field', $_mkey, $_pid);1046 /* Update the layout meta */1047 $layout = $this->load_layout_meta($_pid);1048 if (!empty($layout)) {1049 /* Row update */1050 foreach ($layout["rows"] as $rIndex => $row) {1051 foreach($row as $fIndex => $fkey) {1052 if ($_mkey == $fkey) {1053 if (count($row) == 1) {1054 /* Could be only one field */1055 unset($layout["rows"][$rIndex]);1056 } else {1057 $current_field_width = floatval($layout["columns"][$_mkey]["width"]);1058 /* Could be first field */1059 if ($fIndex == 0) {1060 $next_field_width = floatval($layout["columns"][$layout["rows"][$rIndex][$fIndex+1]]["width"]);1061 $layout["columns"][$layout["rows"][$rIndex][$fIndex+1]]["width"] = ($current_field_width + $next_field_width);1062 } else {1063 /* Could be last or middle */1064 $prev_field_width = floatval($layout["columns"][$layout["rows"][$rIndex][$fIndex-1]]["width"]);1065 $layout["columns"][$layout["rows"][$rIndex][$fIndex-1]]["width"] = ($current_field_width + $prev_field_width);1066 }1067 unset($layout["rows"][$rIndex][$fIndex]);1068 }1069 }1070 }1071 }1072 /* Column update */1073 unset($layout["columns"][$_mkey]);1074 1075 delete_post_meta($_pid, $this->wcff_key_prefix .'layout_meta');1076 add_post_meta($_pid, $this->wcff_key_prefix .'layout_meta', json_encode($layout));1077 }1078 1079 return delete_post_meta($_pid, $_mkey);1080 }1081 1082 return false;1083 }1084 1085 /**1086 * 1087 * @param integer $_pid1088 * @param string $_type1089 * @param string $_template1090 * @param string $_fields_location1091 * 1092 */1093 public function load_fields_groups_for_product($_pid, $_type = "wccpf", $_template = "single-product", $_fields_location = "", $_is_variation_template = false) {1094 /* Holds custom post meta */1095 $meta = array();1096 /* Holds the fields list */1097 $fields = array();1098 /**/1099 $groups = array();1100 /* Holds the final list of fields */1101 $all_fields = array(); 1102 /* Location rules flag */1103 $location_passed = false; 1104 /* Condition rules flag */1105 $target_product_passed = false;1106 /**/1107 $admin_target_location = array();1108 1109 $_pid = absint($_pid);1110 $this->wcff_key_prefix = $_type . "_"; 1111 $wcff_options = wcff()->option->get_options();1112 1113 /* Reset variable tab field flaq */1114 $this->has_variable_tab_fields = false;1115 1116 /* Special keys that is not part of fields meta */1117 $excluded_keys = $this->prepare_special_keys();1118 1119 /* Fields on archive template Flaq */1120 $fields_on_archive = isset($wcff_options["fields_on_archive"]) ? $wcff_options["fields_on_archive"] : "no";1121 1122 /* Fields location on single product page */1123 $global_location_single = isset($wcff_options["field_location"]) ? $wcff_options["field_location"] : "woocommerce_before_add_to_cart_button";1124 /* Check user wants custom location */1125 if ($global_location_single == "woocommerce_product_custom_location") {1126 $global_location_single = isset($wcff_options["custom_product_fields_location"]) ? $wcff_options["custom_product_fields_location"] : "";1127 }1128 1129 /* Fields location for archive product */1130 $global_location_archive = isset($wcff_options["field_archive_location"]) ? $wcff_options["field_archive_location"] : "woocommerce_before_shop_loop_item";1131 /* Check user wants custom location */1132 if ($global_location_archive == "woocommerce_archive_custom_location") {1133 $global_location_archive = isset($wcff_options["custom_archive_fields_location"]) ? $wcff_options["custom_archive_fields_location"] : "";1134 }1135 1136 /* Check whether the request for Archive template and fields on archive is enabled */1137 if ($_template == "archive-product" && $fields_on_archive == "no") {1138 /* No need to go further */1139 return apply_filters( 'wcff_fields_for_product', array(), $_pid, $_type, $_template, $_fields_location );1140 }1141 1142 /* Fetch the group posts */1143 $group_posts = get_posts(1144 array(1145 "post_type" => $_type, 1146 "posts_per_page" => -1, 1147 "order" => "ASC",1148 "post_status" => array('publish') 1149 )1150 ); 1151 1152 if (count($group_posts) > 0) {1153 /* Loop through all group posts */1154 foreach ($group_posts as $g_post) {1155 1156 $all_fields = array(); 1157 /* Get all custom meta */1158 $fields = get_post_meta($g_post->ID);1159 1160 /* Check whether this group is for Authorized users only */1161 $authorized_only = get_post_meta($g_post->ID, $this->wcff_key_prefix."is_this_group_for_authorized_only", true);1162 $authorized_only = (!$authorized_only || $authorized_only == "") ? "no" : $authorized_only;1163 if ($authorized_only == "yes" && !is_user_logged_in()) {1164 continue;1165 }1166 1167 /* Retrive the group level role assignment */1168 $targeted_roles = get_post_meta($g_post->ID, $this->wcff_key_prefix ."wcff_group_preference_target_roles", true);1169 1170 if ($targeted_roles) {1171 $targeted_roles = json_decode($targeted_roles, true);1172 } else {1173 $targeted_roles = array();1174 } 1175 1176 /* If it is for authorized only fields, then check for the roles */1177 if ($authorized_only == "yes" && !$this->check_for_roles($targeted_roles)) {1178 continue;1179 }1180 1181 if ($_template != "any" && $_template != "variable") {1182 /* Check for single-product location rule */1183 if ($_template == "single-product") {1184 /* Group level Location */1185 $field_group_location_single = get_post_meta($g_post->ID, $this->wcff_key_prefix."field_location_on_product", true);1186 $field_group_location_single = empty($field_group_location_single) ? "use_global_setting" : $field_group_location_single;1187 1188 if ($field_group_location_single == "use_global_setting") {1189 if ($_fields_location == "any" || $global_location_single == $_fields_location) {1190 $location_passed = true;1191 } 1192 } else if ($_fields_location == "any" || $field_group_location_single == $_fields_location) {1193 $location_passed = true;1194 } else {1195 /* Ignore */1196 } 1197 } else if ($_template == "archive-product") {1198 /* Check for archive-product location rule */ 1199 $field_group_location_archive = get_post_meta($g_post->ID, $this->wcff_key_prefix."field_location_on_archive", true);1200 $field_group_location_archive = empty( $field_group_location_archive ) ? "none" : $field_group_location_archive;1201 1202 if ($field_group_location_archive == "use_global_setting") {1203 if ($_fields_location == "any" || $global_location_archive == $_fields_location) {1204 $location_passed = true;1205 }1206 } else if ($_fields_location == "any" || $global_location_archive == $_fields_location) {1207 $location_passed = true;1208 } else {1209 /* Ignore */1210 }1211 } else if ($_template == "admin") {1212 $location_passed = true;1213 $field_group_locations_admin = get_post_meta($g_post->ID, $this->wcff_key_prefix."location_rules", true); 1214 $field_group_locations_admin = json_decode( $field_group_locations_admin, true );1215 if ($_fields_location != "any") {1216 $location_passed = $this->check_for_location($field_group_locations_admin, $_fields_location);1217 } 1218 }1219 } else {1220 $location_passed = true;1221 }1222 1223 if ($_type == "wccaf") {1224 $admin_target_location = get_post_meta($g_post->ID, $_type .'_location_rules', true); 1225 $admin_target_location = json_decode($admin_target_location, true);1226 } 1227 1228 /* Check for 'variation_tab' location, needs to exclude admin fields which has location of variable tab */1229 if ($_type == "wccaf" && ($_template == "single-product" || $_template == "archive-product")) { 1230 if ($admin_target_location["endpoint"] == "woocommerce_product_after_variable_attributes") { 1231 $location_passed = false;1232 $this->has_variable_tab_fields = true;1233 } 1234 }1235 1236 /* Needs to includes admin fields which has variable tab as target location */1237 if ($_type == "wccaf" && $_is_variation_template) {1238 $location_passed = false;1239 if ($admin_target_location["endpoint"] == "woocommerce_product_after_variable_attributes") {1240 $location_passed = true; 1241 } 1242 }1243 1244 /* Finally check for the target products */1245 $product_map_rules = $this->load_target_products_rules($g_post->ID);1246 1247 if (is_array($product_map_rules)) {1248 $target_product_passed = true;1249 if ($_pid > 0) {1250 $target_product_passed = $this->check_for_product($_pid, $product_map_rules);1251 } 1252 } else {1253 $target_product_passed = false;1254 } 1255 1256 /* By passing flaq for variation fields (especially from admin fields group - variable tab) */1257 if (($target_product_passed || $_is_variation_template) && $location_passed) {1258 /* Well prepare the field list */1259 foreach ($fields as $key => $meta) {1260 /* Exclude special purpose custom meta */1261 if (!in_array($key, $excluded_keys) && (strpos($key, $this->wcff_key_prefix) === 0)) {1262 1263 $field = json_decode($meta[0], true);1264 if (!isset($field["key"])) {1265 continue;1266 }1267 1268 /* If it is admin field and the template is for front end, then check for the "show_on_product_page" flaq */1269 if (($_type == "wccaf" && isset($field["show_on_product_page"])) && ($_template == "single-product" || $_template == "archive-product" || $_template == "variable")) {1270 if ($field["show_on_product_page"] == "no") {1271 continue;1272 } 1273 }1274 1275 /* Check for authorized user only flaq */1276 $authorized_only = isset($field["login_user_field"]) ? $field["login_user_field"] : "no"; 1277 if ($authorized_only == "yes") {1278 $targeted_roles = isset($field["show_for_roles"]) ? $field["show_for_roles"] : array(); 1279 /* If it is for authorized only fields, then check for the roles */1280 if (!$this->check_for_roles($targeted_roles)) {1281 continue;1282 }1283 } 1284 1285 if(isset($field["is_enable"])) {1286 if ($field["is_enable"]) {1287 $all_fields[] = $field;1288 } 1289 } else {1290 $all_fields[] = $field;1291 }1292 }1293 }1294 1295 /* Sort the fields */1296 $this->usort_by_column($all_fields, "order");1297 1298 $groups[] = array(1299 "id" => $g_post->ID,1300 "type" => $_type,1301 "fields" => $all_fields,1302 "title" => get_the_title($g_post->ID),1303 "layout" => $this->load_layout_meta($g_post->ID),1304 "use_custom_layout" => $this->load_use_custom_layout($g_post->ID),1305 "show_title" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."show_group_title"), true),1306 "is_clonable" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."is_this_group_clonable"), true), 1307 "label_alignment" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."fields_label_alignement"), true),1308 "template_single_location" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."field_location_on_product"), true),14 15 /* 16 * 17 * Namespace for WCFF related post meta 18 * "wccpf_" for Custom product page Fields ( Front end product page ) 19 * "wccaf_" for Custom admin page fields ( for Admin Products ) 20 * "wccvf_" for Custom admin page fields ( for Variation Fields ) 21 * "wcccf_" for Custom admin page fields ( for Checkout Fields ) 22 * 23 **/ 24 private $wcff_key_prefix = "wccpf_"; 25 26 /* Holds all the supported field's specific configuration meta */ 27 private $fields_meta = array(); 28 29 /* Holds all the configuration meta that are common to all fields ( both Product as well as Admin ) */ 30 private $common_meta = array(); 31 32 /* Holds all the configuration meta that are common to Admin Fields */ 33 private $wccaf_common_meta = array(); 34 35 /**/ 36 public $has_variable_tab_fields = false; 37 38 /* 39 * 40 * Cusdtom post meta Keys that are used by WCFF for various purposes 41 * 42 * */ 43 public $special_keys = array( 44 'fee_rules', 45 'layout_meta', 46 'field_rules', 47 'group_rules', 48 'pricing_rules', 49 'location_rules', 50 'condition_rules', 51 'show_group_title', 52 'use_custom_layout', 53 'product_tab_title', 54 'product_tab_priority', 55 'is_this_group_clonable', 56 'fields_label_alignement', 57 'field_location_on_product', 58 'field_location_on_archive', 59 'is_this_group_for_authorized_only', 60 'wcff_group_preference_target_roles' 61 ); 62 63 public function __construct() { 64 /* Wordpress's Save Post action hook 65 * This is where we would save all the rules for the Fields Group ( post ) that is being saved */ 66 add_action( 'save_post', array($this, 'on_save_post' ), 1, 3 ); 67 } 68 69 /** 70 * 71 * Set the current post type properties,<br/> 72 * based on this only all the subsequent fields related operation will happen<br/> 73 * this option could be either 'wccpf' for product fields or 'wccaf' for admin fields. 74 * 75 * @param string $_type 76 * 77 */ 78 public function set_current_post_type($_type = "wccpf") { 79 $this->wcff_key_prefix = $_type . "_"; 80 } 81 82 /** 83 * 84 * Return the Fields config meta for Factory View<br/> 85 * Contains entire (specific to each fields) config meta list for each field type. 86 * 87 * @return array 88 * 89 */ 90 public function get_fields_meta() { 91 /* Make sure the meta is loaded */ 92 $this->load_core_meta(); 93 return $this->fields_meta; 94 } 95 96 /** 97 * 98 * Return the Fields config common meta for Factory View<br/> 99 * Contains entire (common for all fields) config meta list for each field type. 100 * 101 * @return array 102 * 103 */ 104 public function get_fields_common_meta() { 105 /* Make sure the meta is loaded */ 106 $this->load_core_meta(); 107 return $this->common_meta; 108 } 109 110 /** 111 * 112 * Return the Admin Fields config common meta for Factory View<br/> 113 * Contains entire (common for all admin fields) config meta list for each field type. 114 * 115 * @return array 116 * 117 */ 118 public function get_admin_fields_comman_meta() { 119 /* Make sure the meta is loaded */ 120 $this->load_core_meta(); 121 return $this->wccaf_common_meta; 122 } 123 124 /** 125 * 126 * Loads Fields configuration meta from the file system<br> 127 * Fields specific configuration meta from 'meta/wcff-meta.php'<br> 128 * Common configuration meta from 'meta/wcff-common-meta.php'<br> 129 * Common admin configuration meta from 'meta/wcff-common-wccaf-meta.php' 130 * 131 */ 132 private function load_core_meta() { 133 /* Load core fields config meta */ 134 if (!is_array($this->fields_meta) || empty( $this->fields_meta)) { 135 $this->fields_meta = include('meta/wcff-meta.php'); 136 } 137 /* Load common config meta for all fields */ 138 if (!is_array($this->common_meta) || empty($this->common_meta)) { 139 $this->common_meta = include('meta/wcff-common-meta.php'); 140 } 141 /* Load common config meta for admin fields */ 142 if (!is_array($this->wccaf_common_meta) || empty($this->wccaf_common_meta)) { 143 $this->wccaf_common_meta = include('meta/wcff-common-wccaf-meta.php'); 144 } 145 } 146 147 /** 148 * 149 * Called whenever user 'Update' or 'Save' post from wp-admin single post view<br/> 150 * This is where the various (Product, Cat, Location ... ) rules for the fields group will be stored in their respective post meta. 151 * 152 * @param integer $_pid 153 * @param WP_Post $_post 154 * @param boolean $_update 155 * @return void|boolean 156 * 157 */ 158 public function on_save_post($_pid, $_post, $_update) { 159 /* Maje sure the post types are valid */ 160 if (!$_pid || ! $_post || ($_post->post_type != "wccpf" && $_post->post_type != "wccaf" && $_post->post_type != "wccvf" && $_post->post_type != "wcccf")) { 161 return false; 162 } 163 164 $_pid = absint($_pid); 165 166 /* Prepare the post type prefix for meta key */ 167 $this->wcff_key_prefix = $_post->post_type . "_"; 168 169 /* Conditional rules - determine which fields group belongs to which products */ 170 if (isset($_REQUEST["wcff_condition_rules"])) { 171 delete_post_meta($_pid, $this->wcff_key_prefix .'condition_rules'); 172 add_post_meta($_pid, $this->wcff_key_prefix .'condition_rules', $_REQUEST["wcff_condition_rules"]); 173 } 174 175 /* Location rules - specific to Admin Fields */ 176 if (isset($_REQUEST["wcff_location_rules"])) { 177 delete_post_meta($_pid, $this->wcff_key_prefix .'location_rules'); 178 add_post_meta($_pid, $this->wcff_key_prefix .'location_rules', $_REQUEST["wcff_location_rules"]); 179 } 180 181 /**/ 182 if (isset($_REQUEST["wcff_layout_meta"])) { 183 delete_post_meta($_pid, $this->wcff_key_prefix .'layout_meta'); 184 add_post_meta($_pid, $this->wcff_key_prefix .'layout_meta', $_REQUEST["wcff_layout_meta"]); 185 } 186 187 if (isset($_REQUEST["wcff_use_custom_layout"])) { 188 delete_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout'); 189 add_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout', "yes"); 190 } else { 191 delete_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout'); 192 add_post_meta($_pid, $this->wcff_key_prefix .'use_custom_layout', "no"); 193 } 194 195 /* Field location for each field's group */ 196 if (isset($_REQUEST["field_location_on_product"])) { 197 delete_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_product'); 198 add_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_product', $_REQUEST["field_location_on_product"]); 199 delete_post_meta($_pid, $this->wcff_key_prefix .'product_tab_title'); 200 delete_post_meta($_pid, $this->wcff_key_prefix .'product_tab_priority'); 201 if ($_REQUEST["field_location_on_product"] == "woocommerce_single_product_tab" && isset($_REQUEST["product_tab_config_title"])) { 202 add_post_meta($_pid, $this->wcff_key_prefix .'product_tab_title', $_REQUEST["product_tab_config_title"]); 203 add_post_meta($_pid, $this->wcff_key_prefix .'product_tab_priority', $_REQUEST["product_tab_config_priority"]); 204 } 205 } 206 207 /* Field location for archive page */ 208 if (isset($_REQUEST["field_location_on_archive"])) { 209 delete_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_archive'); 210 add_post_meta($_pid, $this->wcff_key_prefix .'field_location_on_archive', $_REQUEST["field_location_on_archive"]); 211 } 212 213 /* Group level cloning option */ 214 if (isset($_REQUEST["wcff_group_clonable_radio"])) { 215 delete_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_clonable'); 216 add_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_clonable', $_REQUEST["wcff_group_clonable_radio"]); 217 } 218 219 /* Group title display option */ 220 if (isset($_REQUEST["wcff_group_title_radio"])) { 221 delete_post_meta($_pid, $this->wcff_key_prefix .'show_group_title'); 222 add_post_meta($_pid, $this->wcff_key_prefix .'show_group_title', $_REQUEST["wcff_group_title_radio"]); 223 } 224 225 /**/ 226 if (isset($_REQUEST["wcff_label_alignment_radio"])) { 227 delete_post_meta($_pid, $this->wcff_key_prefix .'fields_label_alignement'); 228 add_post_meta($_pid, $this->wcff_key_prefix .'fields_label_alignement', $_REQUEST["wcff_label_alignment_radio"]); 229 } 230 231 /* Authorized users only option */ 232 if (isset($_REQUEST["wcff_group_authorized_only_radio"])) { 233 delete_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_for_authorized_only'); 234 add_post_meta($_pid, $this->wcff_key_prefix .'is_this_group_for_authorized_only', $_REQUEST["wcff_group_authorized_only_radio"]); 235 } 236 237 /* Target roles option */ 238 if (isset($_REQUEST["wcff_group_preference_target_roles"])) { 239 delete_post_meta($_pid, $this->wcff_key_prefix .'wcff_group_preference_target_roles'); 240 add_post_meta($_pid, $this->wcff_key_prefix .'wcff_group_preference_target_roles', json_encode($_REQUEST["wcff_group_preference_target_roles"])); 241 } 242 243 /* Update the fields order */ 244 $this->update_fields_order($_pid); 245 246 /* Update the dirty fields meta */ 247 if (isset($_REQUEST["wcff_dirty_fields_configuration"]) && !empty($_REQUEST["wcff_dirty_fields_configuration"])) { 248 $fields = json_decode(str_replace('\"','"', $_REQUEST["wcff_dirty_fields_configuration"]), true); 249 foreach ($fields as $fkey => $meta) { 250 if (!isset($meta["updated"])) { 251 /* Only update if no 'updated' property found */ 252 $this->update_field($_pid, $meta); 253 } 254 } 255 } 256 257 return true; 258 } 259 260 /** 261 * 262 * Update the fields sequence order properties for all fields on a given group (represented by $_pid)<br/> 263 * Called when Fields Group got saved or updated. 264 * 265 * @param integer $_pid 266 * @return boolean 267 * 268 */ 269 public function update_fields_order($_pid = 0) { 270 $fields = $this->load_fields($_pid, false); 271 /* Update each fields order property */ 272 foreach ($fields as $key => $field) { 273 if (isset($_REQUEST[$key."_order"])) { 274 $field["order"] = $_REQUEST[$key."_order"]; 275 update_post_meta($_pid, $key, wp_slash(json_encode($field))); 276 } 277 } 278 279 return true; 280 } 281 282 /** 283 * 284 * Load conditional rules for given Fields Group Post 285 * 286 * @param integer $_pid 287 * @return mixed 288 * 289 */ 290 public function load_target_products_rules($_pid = 0) { 291 $condition = array(); 292 if ($_pid) { 293 $_pid = absint( $_pid ); 294 /* Since we have renamed 'group_rules' meta as 'condition_rules' we need to make sure it is upto date 295 * and we remove the old 'group_rules' meta as well 296 **/ 297 $rules = get_post_meta($_pid, $this->wcff_key_prefix .'group_rules', true); 298 if ($rules && $rules != "") { 299 delete_post_meta($_pid, $this->wcff_key_prefix .'group_rules'); 300 update_post_meta($_pid, $this->wcff_key_prefix .'condition_rules', $rules); 301 } 302 $condition = get_post_meta($_pid, $this->wcff_key_prefix .'condition_rules', true); 303 304 if ($condition != "") { 305 $condition = json_decode($condition, true); 306 } 307 } 308 return apply_filters($this->wcff_key_prefix .'condition_rules', $condition, $_pid); 309 } 310 311 public function load_layout_meta($_pid = 0) { 312 $layout = array(); 313 if ($_pid) { 314 $_pid = absint($_pid); 315 $layout = get_post_meta($_pid, $this->wcff_key_prefix .'layout_meta', true); 316 if ($layout != "") { 317 $layout = json_decode($layout, true); 318 } 319 } 320 return apply_filters($this->wcff_key_prefix .'layout_meta', $layout, $_pid); 321 } 322 323 public function load_use_custom_layout($_pid) { 324 $_pid = absint($_pid); 325 $use_custom_layout = get_post_meta($_pid, ($this->wcff_key_prefix ."use_custom_layout"), true); 326 return ($use_custom_layout != "") ? $use_custom_layout : "no"; 327 } 328 329 /** 330 * 331 * Load locational rules for given Admin Fields Group Post 332 * 333 * @param integer $_pid 334 * @return mixed 335 * 336 */ 337 public function load_location_rules($_pid = 0) { 338 $location = ""; 339 if ($_pid) { 340 $_pid = absint($_pid); 341 $location = get_post_meta($_pid, $this->wcff_key_prefix .'location_rules', true); 342 } 343 return apply_filters( $this->wcff_key_prefix .'location_rules', $location, $_pid ); 344 } 345 346 /** 347 * 348 * Load locational rules for entire admin fields posts 349 * 350 * @return mixed 351 * 352 */ 353 public function load_all_wccaf_location_rules() { 354 $location_rules = array(); 355 $wcffs = get_posts(array( 356 'post_type' => "wccaf", 357 'posts_per_page' => -1, 358 'order' => 'ASC') 359 ); 360 if (count($wcffs) > 0) { 361 foreach ($wcffs as $wcff) { 362 $temp_rules = get_post_meta($wcff->ID, 'wccaf_location_rules', true); 363 $location_rules[] = json_decode($temp_rules, true); 364 } 365 } 366 367 return apply_filters( 'wccaf_all_location_rules', $location_rules ); 368 } 369 370 /** 371 * 372 * Used to load all woocommerce products<br/> 373 * Used in "Conditions" Widget 374 * 375 * @return ARRAY of products ( ids & titles ) 376 * 377 */ 378 public function load_all_products() { 379 $productsList = array(); 380 $products = get_posts(array( 381 'post_type' => 'product', 382 'posts_per_page' => -1, 383 'order' => 'ASC') 384 ); 385 386 if (count($products) > 0) { 387 foreach ($products as $product) { 388 $productsList[] = array("id" => $product->ID, "title" => $product->post_title); 389 } 390 } 391 392 return apply_filters( 'wcff_products', $productsList ); 393 } 394 395 /** 396 * 397 * Used to load all woocommerce products<br/> 398 * Used in "Conditions" Widget 399 * 400 * @return ARRAY of products ( ids & titles ) 401 * 402 */ 403 public function load_variable_products() { 404 $productsList = array(); 405 $products = get_posts(array( 406 'post_type' => 'product', 407 'posts_per_page' => -1, 408 'order' => 'ASC') 409 ); 410 411 if (count($products) > 0) { 412 $wcG3 = version_compare(WC()->version, '2.2.0', '<'); 413 foreach ($products as $product) { 414 $product_ob = $wcG3 ? get_product($product->ID) : wc_get_product($product->ID); 415 if ($product_ob->is_type( 'variable' )){ 416 $productsList[] = array("id" => $product->ID, "title" => $product->post_title); 417 } 418 } 419 } 420 421 return apply_filters( 'wcff_products_with_variation', $productsList ); 422 } 423 424 /** 425 * 426 * Used to load all woocommerce product category<br/> 427 * Used in "Conditions" Widget 428 * 429 * @return ARRAY of product categories ( ids & titles ) 430 * 431 */ 432 public function load_product_categories() { 433 $product_cats = array(); 434 $pcat_terms = get_terms('product_cat', 'orderby=count&hide_empty=0'); 435 436 foreach ($pcat_terms as $pterm) { 437 $product_cats[] = array("id" => $pterm->slug, "title" => $pterm->name); 438 } 439 440 return apply_filters( 'wcff_product_categories', $product_cats ); 441 } 442 443 /** 444 * 445 * Used to load all woocommerce product tags<br/> 446 * Used in "Conditions" Widget 447 * 448 * @return ARRAY of product tags ( ids & titles ) 449 * 450 */ 451 public function load_product_tags() { 452 $product_tags = array(); 453 $ptag_terms = get_terms('product_tag', 'orderby=count&hide_empty=0'); 454 455 foreach ($ptag_terms as $pterm) { 456 $product_tags[] = array("id" => $pterm->slug, "title" => $pterm->name); 457 } 458 459 return apply_filters( 'wcff_product_tags', $product_tags ); 460 } 461 462 /** 463 * 464 * Used to load all woocommerce product types<br/> 465 * Used in "Conditions" Widget 466 * 467 * @return ARRAY of product types ( slugs & titles ) 468 * 469 */ 470 public function load_product_types() { 471 $product_types = array(); 472 $all_types = array ( 473 'simple' => __( 'Simple product', 'woocommerce' ), 474 'grouped' => __( 'Grouped product', 'woocommerce' ), 475 'external' => __( 'External/Affiliate product', 'woocommerce' ), 476 'variable' => __( 'Variable product', 'woocommerce' ) 477 ); 478 479 foreach ($all_types as $key => $value) { 480 $product_types[] = array("id" => $key, "title" => $value); 481 } 482 483 return apply_filters( 'wcff_product_types', $product_types ); 484 } 485 486 /** 487 * 488 * Used to load all woocommerce product types<br/> 489 * Used in "Conditions" Widget 490 * 491 * @return ARRAY of product types ( slugs & titles ) 492 * 493 */ 494 public function load_product_variations($parent = 0) { 495 $products_variation_list = array(); 496 $variations = array(); 497 $arg = array ( 498 'post_type' => 'product_variation', 499 'posts_per_page' => -1, 500 'order' => 'ASC' 501 ); 502 if ($parent != 0) { 503 $arg['post_parent'] = $parent; 504 } 505 $variations = get_posts($arg); 506 foreach ($variations as $product) { 507 $products_variation_list[] = array("id" => $product->ID, "title" => $product->post_title); 508 } 509 return apply_filters( 'wcff_product_variations', $products_variation_list ); 510 } 511 512 /** 513 * 514 * Used to load all woocommerce product tabs<br/> 515 * Used in "Location" Widget 516 * 517 * @return ARRAY of product tabs ( titles & tab slugs ) 518 * 519 */ 520 public function load_product_tabs() { 521 return apply_filters( 'wcff_product_tabs', array ( 522 "General Tab" => "woocommerce_product_options_general_product_data", 523 "Inventory Tab" => "woocommerce_product_options_inventory_product_data", 524 "Shipping Tab" => "woocommerce_product_options_shipping", 525 "Attributes Tab" => "woocommerce_product_options_attributes", 526 "Related Tab" => "woocommerce_product_options_related", 527 "Advanced Tab" => "woocommerce_product_options_advanced", 528 "Variable Tab" => "woocommerce_product_after_variable_attributes" 529 )); 530 } 531 532 /** 533 * 534 * Used to load all wp context used for meta box<br/> 535 * Used for laying Admin Fields 536 * 537 * @return ARRAY of meta contexts ( slugs & titles ) 538 * 539 */ 540 public function load_metabox_contexts() { 541 return apply_filters( 'wcff_metabox_contexts', array ( 542 "normal" => __( "Normal", "wc-fields-factory" ), 543 "advanced" => __( "Advanced", "wc-fields-factory" ), 544 "side" => __( "Side", "wc-fields-factory" ) 545 )); 546 } 547 548 /** 549 * 550 * Used to load all wp priorities used for meta box<br/> 551 * Used for laying Admin Fields 552 * 553 * @return ARRAY of meta priorities ( slugs & titles ) 554 * 555 */ 556 public function load_metabox_priorities() { 557 return apply_filters( 'wcff_metabox_priorities', array ( 558 "low" => __( "Low", "wc-fields-factory" ), 559 "high" => __( "High", "wc-fields-factory" ), 560 "core" => __( "Core", "wc-fields-factory" ), 561 "default" => __( "Default", "wc-fields-factory" ) 562 )); 563 } 564 565 /** 566 * 567 * Used to load all woocommerce form fields validation types, to built Checkout Fields 568 * 569 * @return ARRAY of validation types 570 * 571 */ 572 public function load_wcccf_validation_types() { 573 return apply_filters( 'wcccf_validation_types', array ( 574 "required" => __( "Required", "wc-fields-factory" ), 575 "phone" => __( "Phone", "wc-fields-factory" ), 576 "email" => __( "Email", "wc-fields-factory" ), 577 "postcode" => __( "Post Code", "wc-fields-factory" ) 578 )); 579 } 580 581 public function load_target_contexts() { 582 return apply_filters( "wcff_target_context", array ( 583 array("id" => "product", "title" => __("Product", "wc-fields-factory")), 584 array("id" => "product_cat", "title" => __("Product Category", "wc-fields-factory")), 585 array("id" => "product_tag", "title" => __("Product Tag", "wc-fields-factory")), 586 array("id" => "product_type", "title" => __("Product Type", "wc-fields-factory")), 587 array("id" => "product_variation", "title" => __("Product Variation", "wc-fields-factory")) 588 )); 589 } 590 591 public function load_target_logics() { 592 return apply_filters( "wcff_target_logic", array ( 593 array("id"=>"==", "title"=>__("is equal to", "wc-fields-factory")), 594 array("id"=>"!=", "title"=>__("is not equal to", "wc-fields-factory")) 595 )); 596 } 597 598 public function search_posts($_payload = array()) { 599 600 global $wpdb; 601 $res = array(); 602 $posts = array(); 603 604 $parent = isset($_payload["parent"]) ? $_payload["parent"] : 0; 605 $search = isset($_payload["search"]) ? $_payload["search"] : ""; 606 $post_type = isset($_payload["post_type"]) ? $_payload["post_type"] : ""; 607 608 if (absint($parent) != 0) { 609 $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM $wpdb->posts WHERE post_type='%s' AND post_parent=%d AND post_status='publish' AND post_excerpt LIKE '%s'", $post_type, $parent, '%'. $wpdb->esc_like($search) .'%')); 610 } else { 611 $posts = $wpdb->get_results($wpdb->prepare("SELECT ID, post_title FROM $wpdb->posts WHERE post_type='%s' AND post_status='publish' AND post_title LIKE '%s'", $post_type, '%'. $wpdb->esc_like($search) .'%')); 612 } 613 614 if ($post_type != "product") { 615 foreach ($posts as $post) { 616 $res[] = array( "id" => $post->{"ID"}, "title" => $post->{"post_title"}); 617 } 618 } else { 619 $wcG3 = version_compare(WC()->version, '2.2.0', '<'); 620 foreach ($posts as $post) { 621 $product = $wcG3 ? get_product($post->{"ID"}) : wc_get_product($post->{"ID"}); 622 if ($product->is_type('variable')) { 623 $res[] = array( "id" => $post->{"ID"}, "title" => $post->{"post_title"}); 624 } 625 } 626 } 627 return $res; 628 } 629 630 public function insert_wccvf_map_varioation_level($_payload = array()) { 631 632 $res = false; 633 634 if (!isset($_payload["rules"]) || !is_array($_payload["rules"]) || empty($_payload["rules"])) { 635 return false; 636 } 637 638 foreach ($_payload["rules"] as $gpid => $new_rules) { 639 $all_rules = $this->load_target_products_rules($gpid); 640 if (!is_array($all_rules)) { 641 $all_rules = array(); 642 } 643 /* Append the new rule entry */ 644 foreach ($new_rules as $new_rule) { 645 if (!in_array($new_rule, $all_rules)) { 646 $all_rules[] =$new_rule; 647 } 648 } 649 /* Update the condition rules */ 650 delete_post_meta($gpid, $this->wcff_key_prefix .'condition_rules'); 651 $res = add_post_meta($gpid, $this->wcff_key_prefix .'condition_rules', json_encode($all_rules)); 652 } 653 654 return $res ? true : false; 655 656 } 657 658 public function remove_wccvf_map_variation_level($_payload = array()) { 659 660 if (!isset($_payload["pid"]) && empty($_payload["pid"])) { 661 return false; 662 } 663 if (!isset($_payload["vid"]) || empty($_payload["vid"])) { 664 return false; 665 } 666 667 /* Retrive the current condition rules */ 668 $all_rules = $this->load_target_products_rules($_payload["pid"]); 669 670 if (is_array($all_rules)) { 671 foreach ($all_rules as $aIndex => $rules) { 672 foreach ($rules as $rIndex => $rule) { 673 if ($rule["endpoint"] == $_payload["vid"]) { 674 unset($all_rules[$aIndex][$rIndex]); 675 } 676 } 677 /* Remove the group if it is empty */ 678 if (empty($all_rules[$aIndex])) { 679 unset($all_rules[$aIndex]); 680 } 681 } 682 } 683 684 /* Update the condition rules */ 685 delete_post_meta($_payload["pid"], $this->wcff_key_prefix .'condition_rules'); 686 return add_post_meta($_payload["pid"], $this->wcff_key_prefix .'condition_rules', json_encode($all_rules)); 687 688 } 689 690 /** 691 * 692 * This routine does some reverse pulkling data extraction 693 * 694 * @return array 695 */ 696 public function load_map_wccvf_variations() { 697 698 $flag = false; 699 $result = array(); 700 $vproducts = array(); 701 702 $all_rules = array(); 703 $wccvf_rules = array(); 704 705 $wcG3 = version_compare(WC()->version, '2.2.0', '<'); 706 $products = get_posts(array('post_type' => 'product', 'posts_per_page' => -1)); 707 $wccvfs = get_posts(array('post_type' => "wccvf", 'posts_per_page' => -1)); 708 709 /** 710 * 711 * Step 1. 712 * Consolidating all rules, from all wccvf post 713 * 714 */ 715 foreach ($wccvfs as $wccvf) { 716 717 $wccvf_rules = get_post_meta($wccvf->ID, 'wccvf_condition_rules', true); 718 if ($wccvf_rules != null) { 719 $wccvf_rules = json_decode($wccvf_rules, true); 720 721 /* Well this is a two dimentional array */ 722 foreach ($wccvf_rules as $rules) { 723 if (is_array($rules)) { 724 foreach ($rules as $rule) { 725 if (is_array($rule)) { 726 727 $rule["group_id"] = $wccvf->ID; 728 $rule["group_title"] = $wccvf->post_title; 729 $all_rules[] = $rule; 730 731 } 732 } 733 } 734 } 735 } 736 737 } 738 739 /** 740 * 741 * Step 2. 742 * Fetching all products with variations. 743 * 744 */ 745 foreach ($products as $post) { 746 747 $product = $wcG3 ? get_product($post->ID) : wc_get_product($post->ID); 748 if ($product->is_type( 'variable' )) { 749 $wp_query = new WP_Query(array( 750 'post_type' => 'product_variation', 751 'post_status' => 'publish', 752 'post_parent' => $post->ID, 753 'posts_per_page' => -1, 754 'fields' => array('ID', 'post_title') 755 )); 756 $vproducts[] = array("id" => $post->ID, "title" => $post->post_title, "variations" => $wp_query->posts); 757 } 758 759 } 760 761 foreach ($vproducts as $product) { 762 if (is_array($product["variations"])) { 763 $variations = array(); 764 765 foreach ($product["variations"] as $variation) { 766 $flag = false; 767 $fgroups = array(); 768 769 foreach ($all_rules as $rule) { 770 if (absint($rule["endpoint"]) == absint($variation->ID)) { 771 $flag = true; 772 $fgroups[] = array("gid" => $rule["group_id"], "gtitle" => $rule["group_title"]); 773 } 774 if ($flag) { 775 $variations[$variation->ID] = array("variation_title" => $variation->post_excerpt, "groups" => $fgroups); 776 } 777 } 778 if (!empty($variations)) { 779 $result[$product["id"]] = array("product_title" => $product["title"], "variations" => $variations); 780 } 781 } 782 783 } 784 } 785 786 return $result; 787 788 } 789 790 public function check_product_for_variation_mappings($_pid, $_type) { 791 792 if ($_pid) { 793 794 $_pid = absint($_pid); 795 $this->wcff_key_prefix = $_type . "_"; 796 797 $wp_query = new WP_Query(array( 798 'post_type' => 'product_variation', 799 'post_status' => 'publish', 800 'post_parent' => $_pid, 801 'posts_per_page' => -1, 802 'fields' => array('ID', 'post_title') 803 )); 804 805 $wccvfs = get_posts(array('post_type' => $_type, 'posts_per_page' => -1)); 806 foreach ($wccvfs as $wccvf) { 807 808 $wccvf_rules = get_post_meta($wccvf->ID, $_type .'_condition_rules', true); 809 if ($wccvf_rules != null) { 810 $wccvf_rules = json_decode($wccvf_rules, true); 811 812 /* Well this is a two dimentional array */ 813 foreach ($wccvf_rules as $rules) { 814 if (is_array($rules)) { 815 foreach ($rules as $rule) { 816 if (is_array($rule)) { 817 foreach ($wp_query->posts as $variation) { 818 if (isset($rule["endpoint"]) && absint($rule["endpoint"]) == absint($variation->ID)) { 819 $this->has_variable_tab_fields = true; 820 return true; 821 } 822 } 823 } 824 } 825 } 826 } 827 } 828 } 829 } 830 831 return false; 832 833 } 834 835 /** 836 * 837 * This function is used to load all wcff fields (actualy post meta) for a single WCFF post<br/> 838 * Mostly used in editing wccpf fields in admin screen 839 * 840 * @param integer $pid - WCFF Post Id 841 * @param boolean $sort - Whether returning fields should be sorted 842 * @return array 843 * 844 */ 845 public function load_fields($_pid = 0, $_sort = true) { 846 847 $fields = array(); 848 if ($_pid) { 849 $_pid = absint($_pid); 850 $meta = get_post_meta($_pid); 851 852 $excluded_keys = $this->prepare_special_keys(); 853 foreach ($meta as $key => $val) { 854 /* Exclude special purpose custom meta */ 855 if (!in_array($key, $excluded_keys) && (strpos($key, $this->wcff_key_prefix) === 0)) { 856 $fields[$key] = json_decode($val[0], true); 857 } 858 } 859 860 if ($_sort) { 861 $this->usort_by_column($fields, "order"); 862 } 863 } 864 865 return apply_filters( $this->wcff_key_prefix .'fields', $fields, $_pid, $_sort ); 866 867 } 868 869 /** 870 * 871 * Loads all fields of the given Fields Group Post 872 * 873 * @param number $_pid 874 * @param string $_mkey 875 * @return mixed 876 * 877 */ 878 public function load_field($_pid = 0, $_mkey = "") { 879 $_pid = absint($_pid); 880 $post = get_post($_pid); 881 $field = get_post_meta($_pid, $_mkey, true); 882 if ($field === "") { 883 $field = "{}"; 884 } 885 $field = json_decode($field, true); 886 return apply_filters( $post->post_type .'_field', $field, $_pid, $_mkey ); 887 } 888 889 /** 890 * 891 * Create a Unique ID for the field and store with initial data 892 * 893 * @param number $_pid 894 * @param string $_type 895 * @return string|boolean 896 */ 897 public function create_field($_pid, $_type, $_order) { 898 $_pid = absint($_pid); 899 900 $id = $this->generate_unique_id(); 901 $id = apply_filters("wcff_new_field_id", $id, $_pid, $_type); 902 903 $meta = array ( 904 "id" => $id, 905 "type" => $_type, 906 "label" => "", 907 "order" => $_order, 908 "status" => true 909 ); 910 if (add_post_meta($_pid, ($this->wcff_key_prefix . $id), wp_slash(json_encode($meta)))) { 911 return ($this->wcff_key_prefix . $id); 912 } 913 return false; 914 } 915 916 /** 917 * 918 * Save the given field's config meta as the post meta on a given Fields Group Post. 919 * 920 * @param number $_pid 921 * @param object $_payload 922 * @return number|false 923 * 924 */ 925 public function save_field($_pid, $_payload) { 926 $_pid = absint($_pid); 927 $_payload= apply_filters( 'wcff_before_save_'. $this->wcff_key_prefix .'field', $_payload, $_pid ); 928 if (!isset($_payload["name"]) || $_payload["name"] == "_" || $_payload["name"] != "") { 929 $_payload["key"] = $this->wcff_key_prefix . $this->url_slug($_payload["name"], array('delimiter' => '_')); 930 } 931 $flg = add_post_meta($_pid, $_payload["key"], wp_slash(json_encode($_payload))) == false ? false : true; 932 return $flg; 933 } 934 935 public function update_field($_pid, $_payload) { 936 $msg = ""; 937 $res = true; 938 $_pid = absint($_pid); 939 if (isset($_payload["key"])) { 940 delete_post_meta($_pid, $_payload["key"]); 941 if (add_post_meta($_pid, $_payload["key"], wp_slash(json_encode($_payload))) == false) { 942 $res = false; 943 $msg = __( "Failed to update the custom field", "wc-fields-factory" ); 944 } 945 } 946 return array("res" => $res, "msg" => $msg); 947 } 948 949 public function toggle_field($_pid, $_key, $_status) { 950 $msg = ""; 951 $res = true; 952 $meta_val = get_post_meta($_pid, $_key, true); 953 if ($meta_val && !empty($meta_val)) { 954 $field = json_decode(wp_unslash($meta_val), true); 955 if (isset($field["is_enable"])) { 956 $field["is_enable"] = $_status; 957 delete_post_meta($_pid, $_key); 958 if (add_post_meta($_pid, $_key, wp_slash(json_encode($field))) == false) { 959 $res = false; 960 $msg = __( "Failed to update.!", "wc-fields-factory" ); 961 } 962 } else { 963 $res = false; 964 $msg = __( "Failed to update, Key is missing.!", "wc-fields-factory" ); 965 } 966 } else { 967 $res = false; 968 $msg = __( "Failed to update, Meta is empty.!", "wc-fields-factory" ); 969 } 970 return array("res" => $res, "msg" => $msg); 971 } 972 973 public function clone_group($_pid = 0, $_post_type = "") { 974 global $wpdb; 975 $_pid = ($_pid == 0) ? (isset($_REQUEST["post"]) ? $_REQUEST["post"] : 0) : 0; 976 $_post_type = ($_post_type == "") ? (isset($_REQUEST["post_type"]) ? $_REQUEST["post_type"] : "") : ""; 977 if (isset($_pid) && $_pid > 0) { 978 $post = get_post($_pid); 979 $new_post_id = wp_insert_post(array( 980 'comment_status' => $post->comment_status, 981 'ping_status' => $post->ping_status, 982 'post_author' => $post->post_author, 983 'post_content' => $post->post_content, 984 'post_excerpt' => $post->post_excerpt, 985 'post_name' => $post->post_name, 986 'post_parent' => $post->post_parent, 987 'post_password' => $post->post_password, 988 'post_status' => 'publish', 989 'post_title' => "Copy - ". $post->post_title, 990 'post_type' => $post->post_type, 991 'to_ping' => $post->to_ping, 992 'menu_order' => $post->menu_order 993 )); 994 995 $post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$_pid"); 996 if (count($post_meta_infos)!=0) { 997 $sql_query_sel = array(); 998 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) "; 999 foreach ($post_meta_infos as $meta_info) { 1000 $meta_key = $meta_info->meta_key; 1001 if( $meta_key == '_wp_old_slug' ) continue; 1002 $meta_value = addslashes($meta_info->meta_value); 1003 $sql_query_sel[]= "SELECT $new_post_id, '$meta_key', '$meta_value'"; 1004 } 1005 $sql_query.= implode(" UNION ALL ", $sql_query_sel); 1006 $wpdb->query($sql_query); 1007 } 1008 } 1009 if ($_post_type != "wccvf") { 1010 wp_redirect( admin_url('edit.php?post_type='. $_post_type)); 1011 } else { 1012 wp_redirect( admin_url('edit.php?post_type=wccpf&page=variation_fields_config')); 1013 } 1014 exit; 1015 } 1016 1017 public function clone_field($_pid, $_fkey) { 1018 $_pid = absint($_pid); 1019 $id = $this->generate_unique_id(); 1020 $id = apply_filters("wcff_new_field_id", $id, $_pid, null); 1021 $cloned = $this->load_field($_pid, $_fkey); 1022 if (is_array($cloned)) { 1023 $cloned["id"] = $id; 1024 $cloned["label"] = "Copy - ". $cloned["label"]; 1025 if (add_post_meta($_pid, ($this->wcff_key_prefix . $id), wp_slash(json_encode($cloned)))) { 1026 return ($this->wcff_key_prefix . $id); 1027 } 1028 } 1029 return false; 1030 } 1031 1032 /** 1033 * 1034 * Remove the given field from Fields Group Post 1035 * 1036 * @param number $_pid 1037 * @param string $_mkey 1038 * @return boolean 1039 * 1040 */ 1041 public function remove_field($_pid, $_mkey) { 1042 if ($_pid) { 1043 $_pid = absint($_pid); 1044 $post = get_post($_pid); 1045 do_action($post->post_type .'_before_remove_field', $_mkey, $_pid); 1046 /* Update the layout meta */ 1047 $layout = $this->load_layout_meta($_pid); 1048 if (!empty($layout)) { 1049 /* Row update */ 1050 foreach ($layout["rows"] as $rIndex => $row) { 1051 foreach($row as $fIndex => $fkey) { 1052 if ($_mkey == $fkey) { 1053 if (count($row) == 1) { 1054 /* Could be only one field */ 1055 unset($layout["rows"][$rIndex]); 1056 } else { 1057 $current_field_width = floatval($layout["columns"][$_mkey]["width"]); 1058 /* Could be first field */ 1059 if ($fIndex == 0) { 1060 $next_field_width = floatval($layout["columns"][$layout["rows"][$rIndex][$fIndex+1]]["width"]); 1061 $layout["columns"][$layout["rows"][$rIndex][$fIndex+1]]["width"] = ($current_field_width + $next_field_width); 1062 } else { 1063 /* Could be last or middle */ 1064 $prev_field_width = floatval($layout["columns"][$layout["rows"][$rIndex][$fIndex-1]]["width"]); 1065 $layout["columns"][$layout["rows"][$rIndex][$fIndex-1]]["width"] = ($current_field_width + $prev_field_width); 1066 } 1067 unset($layout["rows"][$rIndex][$fIndex]); 1068 } 1069 } 1070 } 1071 } 1072 /* Column update */ 1073 unset($layout["columns"][$_mkey]); 1074 1075 delete_post_meta($_pid, $this->wcff_key_prefix .'layout_meta'); 1076 add_post_meta($_pid, $this->wcff_key_prefix .'layout_meta', json_encode($layout)); 1077 } 1078 1079 return delete_post_meta($_pid, $_mkey); 1080 } 1081 1082 return false; 1083 } 1084 1085 /** 1086 * 1087 * @param integer $_pid 1088 * @param string $_type 1089 * @param string $_template 1090 * @param string $_fields_location 1091 * 1092 */ 1093 public function load_fields_groups_for_product($_pid, $_type = "wccpf", $_template = "single-product", $_fields_location = "", $_is_variation_template = false) { 1094 /* Holds custom post meta */ 1095 $meta = array(); 1096 /* Holds the fields list */ 1097 $fields = array(); 1098 /**/ 1099 $groups = array(); 1100 /* Holds the final list of fields */ 1101 $all_fields = array(); 1102 /* Location rules flag */ 1103 $location_passed = false; 1104 /* Condition rules flag */ 1105 $target_product_passed = false; 1106 /**/ 1107 $admin_target_location = array(); 1108 1109 $_pid = absint($_pid); 1110 $this->wcff_key_prefix = $_type . "_"; 1111 $wcff_options = wcff()->option->get_options(); 1112 1113 /* Reset variable tab field flaq */ 1114 $this->has_variable_tab_fields = false; 1115 1116 /* Special keys that is not part of fields meta */ 1117 $excluded_keys = $this->prepare_special_keys(); 1118 1119 /* Fields on archive template Flaq */ 1120 $fields_on_archive = isset($wcff_options["fields_on_archive"]) ? $wcff_options["fields_on_archive"] : "no"; 1121 1122 /* Fields location on single product page */ 1123 $global_location_single = isset($wcff_options["field_location"]) ? $wcff_options["field_location"] : "woocommerce_before_add_to_cart_button"; 1124 /* Check user wants custom location */ 1125 if ($global_location_single == "woocommerce_product_custom_location") { 1126 $global_location_single = isset($wcff_options["custom_product_fields_location"]) ? $wcff_options["custom_product_fields_location"] : ""; 1127 } 1128 1129 /* Fields location for archive product */ 1130 $global_location_archive = isset($wcff_options["field_archive_location"]) ? $wcff_options["field_archive_location"] : "woocommerce_before_shop_loop_item"; 1131 /* Check user wants custom location */ 1132 if ($global_location_archive == "woocommerce_archive_custom_location") { 1133 $global_location_archive = isset($wcff_options["custom_archive_fields_location"]) ? $wcff_options["custom_archive_fields_location"] : ""; 1134 } 1135 1136 /* Check whether the request for Archive template and fields on archive is enabled */ 1137 if ($_template == "archive-product" && $fields_on_archive == "no") { 1138 /* No need to go further */ 1139 return apply_filters( 'wcff_fields_for_product', array(), $_pid, $_type, $_template, $_fields_location ); 1140 } 1141 1142 /* Fetch the group posts */ 1143 $group_posts = get_posts( 1144 array( 1145 "post_type" => $_type, 1146 "posts_per_page" => -1, 1147 "order" => "ASC", 1148 "post_status" => array('publish') 1149 ) 1150 ); 1151 1152 if (count($group_posts) > 0) { 1153 /* Loop through all group posts */ 1154 foreach ($group_posts as $g_post) { 1155 1156 $all_fields = array(); 1157 /* Get all custom meta */ 1158 $fields = get_post_meta($g_post->ID); 1159 1160 /* Check whether this group is for Authorized users only */ 1161 $authorized_only = get_post_meta($g_post->ID, $this->wcff_key_prefix."is_this_group_for_authorized_only", true); 1162 $authorized_only = (!$authorized_only || $authorized_only == "") ? "no" : $authorized_only; 1163 if ($authorized_only == "yes" && !is_user_logged_in()) { 1164 continue; 1165 } 1166 1167 /* Retrive the group level role assignment */ 1168 $targeted_roles = get_post_meta($g_post->ID, $this->wcff_key_prefix ."wcff_group_preference_target_roles", true); 1169 1170 if ($targeted_roles) { 1171 $targeted_roles = json_decode($targeted_roles, true); 1172 } else { 1173 $targeted_roles = array(); 1174 } 1175 1176 /* If it is for authorized only fields, then check for the roles */ 1177 if ($authorized_only == "yes" && !$this->check_for_roles($targeted_roles)) { 1178 continue; 1179 } 1180 1181 if ($_template != "any" && $_template != "variable") { 1182 /* Check for single-product location rule */ 1183 if ($_template == "single-product") { 1184 /* Group level Location */ 1185 $field_group_location_single = get_post_meta($g_post->ID, $this->wcff_key_prefix."field_location_on_product", true); 1186 $field_group_location_single = empty($field_group_location_single) ? "use_global_setting" : $field_group_location_single; 1187 1188 if ($field_group_location_single == "use_global_setting") { 1189 if ($_fields_location == "any" || $global_location_single == $_fields_location) { 1190 $location_passed = true; 1191 } 1192 } else if ($_fields_location == "any" || $field_group_location_single == $_fields_location) { 1193 $location_passed = true; 1194 } else { 1195 /* Ignore */ 1196 } 1197 } else if ($_template == "archive-product") { 1198 /* Check for archive-product location rule */ 1199 $field_group_location_archive = get_post_meta($g_post->ID, $this->wcff_key_prefix."field_location_on_archive", true); 1200 $field_group_location_archive = empty( $field_group_location_archive ) ? "none" : $field_group_location_archive; 1201 1202 if ($field_group_location_archive == "use_global_setting") { 1203 if ($_fields_location == "any" || $global_location_archive == $_fields_location) { 1204 $location_passed = true; 1205 } 1206 } else if ($_fields_location == "any" || $global_location_archive == $_fields_location) { 1207 $location_passed = true; 1208 } else { 1209 /* Ignore */ 1210 } 1211 } else if ($_template == "admin") { 1212 $location_passed = true; 1213 $field_group_locations_admin = get_post_meta($g_post->ID, $this->wcff_key_prefix."location_rules", true); 1214 $field_group_locations_admin = json_decode( $field_group_locations_admin, true ); 1215 if ($_fields_location != "any") { 1216 $location_passed = $this->check_for_location($field_group_locations_admin, $_fields_location); 1217 } 1218 } 1219 } else { 1220 $location_passed = true; 1221 } 1222 1223 if ($_type == "wccaf") { 1224 $admin_target_location = get_post_meta($g_post->ID, $_type .'_location_rules', true); 1225 $admin_target_location = json_decode($admin_target_location, true); 1226 } 1227 1228 /* Check for 'variation_tab' location, needs to exclude admin fields which has location of variable tab */ 1229 if ($_type == "wccaf" && ($_template == "single-product" || $_template == "archive-product")) { 1230 if ($admin_target_location["endpoint"] == "woocommerce_product_after_variable_attributes") { 1231 $location_passed = false; 1232 $this->has_variable_tab_fields = true; 1233 } 1234 } 1235 1236 /* Needs to includes admin fields which has variable tab as target location */ 1237 if ($_type == "wccaf" && $_is_variation_template) { 1238 $location_passed = false; 1239 if ($admin_target_location["endpoint"] == "woocommerce_product_after_variable_attributes") { 1240 $location_passed = true; 1241 } 1242 } 1243 1244 /* Finally check for the target products */ 1245 $product_map_rules = $this->load_target_products_rules($g_post->ID); 1246 1247 if (is_array($product_map_rules)) { 1248 $target_product_passed = true; 1249 if ($_pid > 0) { 1250 $target_product_passed = $this->check_for_product($_pid, $product_map_rules); 1251 } 1252 } else { 1253 $target_product_passed = false; 1254 } 1255 1256 /* By passing flaq for variation fields (especially from admin fields group - variable tab) */ 1257 if (($target_product_passed || $_is_variation_template) && $location_passed) { 1258 /* Well prepare the field list */ 1259 foreach ($fields as $key => $meta) { 1260 /* Exclude special purpose custom meta */ 1261 if (!in_array($key, $excluded_keys) && (strpos($key, $this->wcff_key_prefix) === 0)) { 1262 1263 $field = json_decode($meta[0], true); 1264 if (!isset($field["key"])) { 1265 continue; 1266 } 1267 1268 /* If it is admin field and the template is for front end, then check for the "show_on_product_page" flaq */ 1269 if (($_type == "wccaf" && isset($field["show_on_product_page"])) && ($_template == "single-product" || $_template == "archive-product" || $_template == "variable")) { 1270 if ($field["show_on_product_page"] == "no") { 1271 continue; 1272 } 1273 } 1274 1275 /* Check for authorized user only flaq */ 1276 $authorized_only = isset($field["login_user_field"]) ? $field["login_user_field"] : "no"; 1277 if ($authorized_only == "yes") { 1278 $targeted_roles = isset($field["show_for_roles"]) ? $field["show_for_roles"] : array(); 1279 /* If it is for authorized only fields, then check for the roles */ 1280 if (!$this->check_for_roles($targeted_roles)) { 1281 continue; 1282 } 1283 } 1284 1285 if(isset($field["is_enable"])) { 1286 if ($field["is_enable"]) { 1287 $all_fields[] = $field; 1288 } 1289 } else { 1290 $all_fields[] = $field; 1291 } 1292 } 1293 } 1294 1295 /* Sort the fields */ 1296 $this->usort_by_column($all_fields, "order"); 1297 1298 $groups[] = array( 1299 "id" => $g_post->ID, 1300 "type" => $_type, 1301 "fields" => $all_fields, 1302 "title" => get_the_title($g_post->ID), 1303 "layout" => $this->load_layout_meta($g_post->ID), 1304 "use_custom_layout" => $this->load_use_custom_layout($g_post->ID), 1305 "show_title" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."show_group_title"), true), 1306 "is_clonable" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."is_this_group_clonable"), true), 1307 "label_alignment" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."fields_label_alignement"), true), 1308 "template_single_location" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."field_location_on_product"), true), 1309 1309 "template_archive_location" => get_post_meta($g_post->ID, ($this->wcff_key_prefix ."field_location_on_archive"), true) 1310 );1311 }1312 1313 }1314 } 1315 return apply_filters('wcff_fields_for_product', $groups, $_pid, $_type, $_template, $_fields_location); 1316 }1317 1318 1319 /**1320 *1321 * WCFF Product Mapping Rules Engine, This is function used to determine whether or not to include<br/>1322 * a particular wccpf group fields to a particular Product1323 *1324 * @param integer $_pid - Product Id1325 * @param array $_groups1326 * @return boolean1327 *1328 */1329 public function check_for_product($_pid, $_groups) {1330 1331 $matches = array();1332 $final_matches = array();1333 1334 $post_type = "";1335 $p = get_post($_pid);1336 if ($p && $p->post_type) {1337 $post_type = $p->post_type;1338 }1339 1340 foreach ($_groups as $rules) {1341 1342 $ands = array();1343 foreach ($rules as $rule) {1344 1345 /* Special case scenario only for Product Variations */1346 if (wcff()->request && $rule["context" ] != "product_variation" && wcff()->request["context"] == "wcff_variation_fields") {1347 return false;1348 }1349 1350 if ($rule["context"] == "product" && $post_type == "product") {1351 if ($rule["endpoint"] == -1) {1352 $ands[] = ($rule["logic"] == "==");1353 } else {1354 if ($rule["logic"] == "==") {1355 $ands[] = ($_pid == $rule["endpoint"]);1356 } else {1357 $ands[] = ($_pid != $rule["endpoint"]);1358 }1359 }1360 } else if ($rule["context"] == "product_variation" && $post_type == "product_variation") {1361 if ($rule["endpoint"] == -1) {1362 if (get_post_type($_pid) == "product_variation") {1363 $ands[] = ($rule["logic"] == "==");1364 } else {1365 $ands[] = false;1366 }1367 } else {1368 if ($rule["logic"] == "==") {1369 if (get_post_type($_pid) == "product_variation") {1370 $ands[] = ($_pid == $rule["endpoint"]);1371 } else {1372 $ands[] = false;1373 }1374 } else {1375 if (get_post_type($_pid) == "product_variation") {1376 $ands[] = ($_pid != $rule["endpoint"]);1377 } else {1378 $ands[] = false;1379 }1380 }1381 }1382 } else if ($rule["context"] == "product_cat") {1383 if ($rule["endpoint"] == -1) {1384 $ands[] = ($rule["logic"] == "==");1385 } else {1386 if ($rule["logic"] == "==") {1387 $ands[] = has_term($rule["endpoint"], 'product_cat', $_pid);1388 } else {1389 $ands[] = !has_term($rule["endpoint"], 'product_cat', $_pid);1390 }1391 }1392 } else if ($rule["context"] == "product_tag") {1393 if ($rule["endpoint"] == -1) {1394 $ands[] = ($rule["logic"] == "==");1395 } else {1396 if ($rule["logic"] == "==") {1397 $ands[] = has_term($rule["endpoint"], 'product_tag', $_pid);1398 } else {1399 $ands[] = !has_term($rule["endpoint"], 'product_tag', $_pid);1400 }1401 }1402 } else if ($rule["context"] == "product_type") {1403 if ($rule["endpoint"] == -1) {1404 $ands[] = ($rule["logic"] == "==");1405 } else {1406 $ptype = wp_get_object_terms($_pid, 'product_type');1407 if (!empty($ptype)) {1408 $ands[] = ($ptype[0]->slug == $rule["endpoint"]);1409 } 1410 }1411 }1412 1413 }1414 1415 $matches[] = $ands;1416 1417 } 1418 1419 foreach ($matches as $match) {1420 if (!empty($match)) {1421 $final_matches[] = !in_array(false, $match);1422 } 1423 } 1424 1425 return in_array(true, $final_matches);1426 1427 }1428 1429 /**1430 *1431 * WCFF Location Rules Engine, This is function used to determine where does the particular wccaf fields group<br/>1432 * to be placed. in the product view, product cat view or one of any product data sections ( Tabs )<br/>1433 * applicable only for wccaf post_type.1434 *1435 * @param integer $_pid1436 * @param array $_groups1437 * @param string $_location1438 *1439 */1440 public function check_for_location($_rule, $_location) {1441 1442 if ($_rule["context"] == "location_product_data") {1443 if ($_rule["endpoint"] == $_location) {1444 return true;1445 }1446 }1447 if ($_rule["context"] == "location_product" && $_location == "admin_head-post.php") {1448 return true; 1449 } 1450 if ($_rule["context"] == "location_product_cat" && ($_location == "product_cat_add_form_fields" || $_location == "product_cat_edit_form_fields")) {1451 return true;1452 }1453 1454 return false;1455 }1456 1457 private function check_for_roles($_targeted_roles) { 1458 1459 global $wp_roles;1460 1461 $all_roles = array();1462 foreach ($wp_roles->roles as $handle => $role) {1463 $all_roles[] = $handle;1464 }1465 1466 if (!$_targeted_roles || empty($_targeted_roles)) {1467 $_targeted_roles = $all_roles;1468 }1469 1470 $user = wp_get_current_user(); 1471 $intersect = array_intersect($_targeted_roles, (array) $user->roles);1472 return (count($intersect) > 0);1473 1474 }1475 1476 /**1477 *1478 * Order the array for the given property.1479 *1480 * @param array $_arr1481 * @param string $_col1482 * @param string $_dir1483 *1484 */1485 public function usort_by_column(&$_arr, $_col, $_dir = SORT_ASC) {1486 $sort_col = array();1487 foreach ($_arr as $key=> $row) {1488 $sort_col[$key] = $row[$_col];1489 }1490 array_multisort($sort_col, $_dir, $_arr);1491 }1492 1493 /**1494 * 1495 */1496 public function migrate_for_version_4xxx() {1497 1498 /* Check wccpf */ 1499 $this->migrate_fields("wccpf"); 1500 /* Check wccaf */1501 $this->migrate_fields("wccaf");1502 /* Check wccvf */1503 $this->migrate_fields("wccvf");1504 /* Check wcccf */1505 //$this->migrate_fields("wcccf");1506 1507 wcff()->option->update_option("version", wcff()->info["version"]);1508 wcff()->option->update_option("enable_custom_pricing", "yes");1509 1510 }1511 1512 private function migrate_fields($_ptype = "") {1513 1514 $this->wcff_key_prefix = $_ptype . "_";1515 /* Special keys that is not part of fields meta */1516 $excluded_keys = $this->prepare_special_keys();1517 1518 /* Fetch the group posts */1519 $group_posts = get_posts(1520 array(1521 "post_type" => $_ptype, 1522 "posts_per_page" => -1, 1523 "order" => "ASC" 1524 )1525 ); 1526 1527 if (count($group_posts) > 0) {1528 /* Loop through all group posts */1529 foreach ($group_posts as $g_post) {1530 1531 /* Get all custom meta */1532 $fields = get_post_meta($g_post->ID);1533 1534 foreach ($fields as $fkey => $meta) { 1535 /* Exclude special purpose custom meta */1536 if (!in_array($fkey, $excluded_keys) && (strpos($fkey, $this->wcff_key_prefix) === 0)) {1537 1538 $field = json_decode($meta[0], true);1539 1540 /* Check is_enabled property */1541 if (!isset($field["is_enable"]) || !$field["is_enable"]) { 1542 $field["is_enable"] = true;1543 }1544 /* Check key property */1545 if (!isset($field["key"]) && isset($field["name"])) {1546 $field["key"] = $field["name"];1547 }1548 1549 if ($field["type"] == "checkbox" && isset($field["pricing_rules"]) && is_array($field["pricing_rules"])) { 1550 foreach ($field["pricing_rules"] as $pkey => $rule) {1551 $field["pricing_rules"][$pkey]["old_logic"] = $field["pricing_rules"][$pkey]["logic"];1552 $field["pricing_rules"][$pkey]["logic"] = "has-options";1553 }1554 }1555 if ($field["type"] == "checkbox" && isset($field["fee_rules"]) && is_array($field["fee_rules"])) { 1556 foreach ($field["fee_rules"] as $pkey => $rule) {1557 $field["fee_rules"][$pkey]["old_logic"] = $field["fee_rules"][$pkey]["logic"];1558 $field["fee_rules"][$pkey]["logic"] = "has-options";1559 }1560 }1561 if ($field["type"] == "checkbox" && isset($field["field_rules"]) && is_array($field["field_rules"])) {1562 foreach ($field["field_rules"] as $pkey => $rule) {1563 $field["field_rules"][$pkey]["old_logic"] = $field["field_rules"][$pkey]["logic"];1564 $field["field_rules"][$pkey]["logic"] = "has-options";1565 }1566 }1567 1568 if (isset($field["field_rules"]) && is_array($field["field_rules"])) {1569 foreach ($field["field_rules"] as $pkey => $rule) {1570 if (isset($rule["field_rules"])) {1571 foreach ($rule["field_rules"] as $frkey => $fval) {1572 1573 $fname = $frkey;1574 /* Prior to V4 check box key has suffix of [] - so we need to remove this */1575 if ($this->endsWith($frkey, "[]")) {1576 $fname = substr($frkey, 0, strlen($frkey) - 2);1577 } 1578 1579 $field["field_rules"][$pkey]["field_rules"][ $this->wcff_key_prefix . $fname ] = $fval;1580 unset($field["field_rules"][$pkey]["field_rules"][$frkey]);1581 1582 }1583 }1584 }1585 }1586 1587 update_post_meta($g_post->ID, $fkey, wp_slash(json_encode($field))); 1588 1589 }1590 }1591 1592 /* Update the admin location rules for wccaf */1593 if ($_ptype == "wccaf" && isset($fields["wccaf_location_rules"])) {1594 1595 $lrules = json_decode($fields["wccaf_location_rules"][0], true);1596 if (is_array($lrules[0]) && is_array($lrules[0][0])) {1597 update_post_meta($g_post->ID, "wccaf_location_rules", wp_slash(json_encode($lrules[0][0])));1598 } 1599 1600 }1601 1602 }1603 }1604 1605 }1606 1607 private function get_fields_count($_pid) {1608 $count =0;1609 $keys = get_post_custom_keys($_pid); 1610 if ($keys) {1611 foreach ($keys as $key) {1612 if ((strpos($key, 'wccpf_') !== false ||1613 strpos($key, 'wccaf_') !== false ||1614 strpos($key, 'wccvf_') !== false) &&1615 (strpos($key, 'group_rules') === false &&1616 strpos($key, 'condition_rules') === false &&1617 strpos($key, 'fee_rules') === false &&1618 strpos($key, 'field_rules') === false &&1619 strpos($key, 'location_rules') === false &&1620 strpos($key, 'product_tab_title') === false &&1621 strpos($key, 'product_tab_priority') === false &&1622 strpos($key, 'field_location_on_product') === false &&1623 strpos($key, 'field_location_on_archive') === false &&1624 strpos($key, 'is_this_group_clonable') === false)) {1625 $count++;1626 }1627 }1628 }1629 return $count;1630 }1631 1632 function endsWith($haystack, $needle) {1633 return substr_compare($haystack, $needle, -strlen($needle)) === 0;1634 }1635 1636 /**1637 * 1638 * @return string1639 */1640 private function generate_unique_id() {1641 $token = '';1642 $token_length = 12;1643 $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";1644 $alphabet .= "abcdefghijklmnopqrstuvwxyz";1645 $alphabet .= "0123456789";1646 $alphabetLength = strlen($alphabet); 1647 for ($i = 0; $i < $token_length; $i++) {1648 $randomKey = $this->get_random_number(0, $alphabetLength);1649 $token .= $alphabet[$randomKey];1650 }1651 return $token;1652 }1653 1654 /**1655 * 1656 * @param number $_min1657 * @param number $_max1658 * @return number1659 */1660 private function get_random_number($_min = 0, $_max = 0) {1661 $range = ($_max - $_min);1662 if ($range < 0) {1663 return $_min;1664 }1665 $log = log($range, 2);1666 $bytes = (int) ($log / 8) + 1;1667 $bits = (int) $log + 1;1668 $filter = (int) (1 << $bits) - 1;1669 do {1670 $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));1671 $rnd = $rnd & $filter;1672 } while ($rnd >= $range);1673 return ($_min + $rnd);1674 }1675 1676 private function prepare_special_keys() {1677 $excluded_keys = array();1678 if ($this->wcff_key_prefix != "") {1679 foreach ($this->special_keys as $key) {1680 $excluded_keys[] = $this->wcff_key_prefix . $key;1681 }1682 }1683 return $excluded_keys;1684 }1685 1686 /**1687 *1688 * Create a web friendly URL slug from a string.1689 *1690 * @author Sean Murphy <sean@iamseanmurphy.com>1691 * @copyright Copyright 2012 Sean Murphy. All rights reserved.1692 * @license http://creativecommons.org/publicdomain/zero/1.0/1693 *1694 * @param string $str1695 * @param array $options1696 * @return string1697 *1698 */1699 function url_slug($_str, $_options = array()) { 1700 // Make sure string is in UTF-8 and strip invalid UTF-8 characters1701 $_str = mb_convert_encoding((string) $_str, 'UTF-8', mb_list_encodings());1702 1703 $defaults = array (1704 'delimiter' => '-',1705 'limit' => null,1706 'lowercase' => true,1707 'replacements' => array(),1708 'transliterate' => false,1709 );1710 1711 // Merge options1712 $_options = array_merge($defaults, $_options);1713 1714 $char_map = array (1715 // Latin1716 'À' => 'A', '�' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Ã…' => 'A', 'Æ' => 'AE', 'Ç' => 'C',1717 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'ÃŒ' => 'I', '�' => 'I', 'ÃŽ' => 'I', '�' => 'I',1718 '�' => 'D', 'Ñ' => 'N', 'Ã’' => 'O', 'Ó' => 'O', '�' => 'O', 'Õ' => 'O', 'Ö' => 'O', '�' => 'O',1719 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ű' => 'U', '�' => 'Y', 'Þ' => 'TH',1720 'ß' => 'ss',1721 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'Ã¥' => 'a', 'æ' => 'ae', 'ç' => 'c',1722 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'ÃÂÂ' => 'i', 'î' => 'i', 'ï' => 'i',1723 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'Å‘' => 'o',1724 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ű' => 'u', 'ý' => 'y', 'þ' => 'th',1725 'ÿ' => 'y',1726 // Latin symbols1727 '©' => '(c)',1728 // Greek1729 'Α' => 'A', 'Î’' => 'B', 'Γ' => 'G', '�' => 'D', 'Ε' => 'E', 'Ζ' => 'Z', 'ÃŽâ€â€�' => 'H', 'ÃŽËœ' => '8',1730 'ÃŽâ„¢' => 'I', 'ÃŽÅ¡' => 'K', 'Λ' => 'L', 'ÃŽÅ“' => 'M', '�' => 'N', 'Ξ' => '3', 'Ο' => 'O', 'Π' => 'P',1731 'Ρ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'ÃŽÂ¥' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'PS', 'Ω' => 'W',1732 'Ά' => 'A', 'Έ' => 'E', 'ÃŽÅ ' => 'I', 'ÃŽÅ’' => 'O', 'ÎŽ' => 'Y', 'Ή' => 'H', '�' => 'W', 'Ϊ' => 'I',1733 'Ϋ' => 'Y',1734 'α' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd', 'ε' => 'e', 'ζ' => 'z', 'η' => 'h', 'θ' => '8',1735 'ι' => 'i', 'κ' => 'k', 'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => '3', 'ο' => 'o', '�€' => 'p',1736 '��' => 'r', '�ƒ' => 's', '�„' => 't', '�…' => 'y', '�†' => 'f', '�‡' => 'x', '�ˆ' => 'ps', '�‰' => 'w',1737 'ά' => 'a', 'ÃŽÂÂ' => 'e', 'ί' => 'i', '�Œ' => 'o', '��' => 'y', 'ή' => 'h', '�Ž' => 'w', '�‚' => 's',1738 '�Š' => 'i', 'ΰ' => 'y', '�‹' => 'y', '�' => 'i',1739 // Turkish1740 'Åž' => 'S', 'İ' => 'I', 'Ç' => 'C', 'Ü' => 'U', 'Ö' => 'O', 'Äž' => 'G',1741 'ÅŸ' => 's', 'ı' => 'i', 'ç' => 'c', 'ü' => 'u', 'ö' => 'o', 'ÄŸ' => 'g',1742 // Russian1743 '��' => 'A', '�‘' => 'B', '�’' => 'V', '�“' => 'G', '��' => 'D', '�•' => 'E', '��' => 'Yo', '�–' => 'Zh',1744 'Ã�â€â€�' => 'Z', '�˜' => 'I', '�™' => 'J', '�š' => 'K', '�›' => 'L', '�œ' => 'M', '��' => 'N', '�ž' => 'O',1745 '�Ÿ' => 'P', '� ' => 'R', '�¡' => 'S', '�¢' => 'T', '�£' => 'U', '�¤' => 'F', '�¥' => 'H', '�¦' => 'C',1746 '�§' => 'Ch', '�¨' => 'Sh', '�©' => 'Sh', '�ª' => '', '�«' => 'Y', '�¬' => '', 'Ã�ÂÂ' => 'E', '�®' => 'Yu',1747 '�¯' => 'Ya',1748 '�°' => 'a', '�±' => 'b', '�²' => 'v', '�³' => 'g', '�´' => 'd', '�µ' => 'e', 'Ñ‘' => 'yo', '�¶' => 'zh',1749 '�·' => 'z', '�¸' => 'i', '�¹' => 'j', '�º' => 'k', '�»' => 'l', '�¼' => 'm', '�½' => 'n', '�¾' => 'o',1750 '�¿' => 'p', 'Ñ€' => 'r', '�' => 's', 'Ñ‚' => 't', 'у' => 'u', 'Ñ„' => 'f', 'Ñ…' => 'h', 'ц' => 'c',1751 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sh', 'ÑŠ' => '', 'Ñ‹' => 'y', 'ÑŒ' => '', '�' => 'e', 'ÑŽ' => 'yu',1752 '�' => 'ya',1753 // Ukrainian1754 '�„' => 'Ye', '�†' => 'I', '�‡' => 'Yi', 'Ò�' => 'G',1755 '�' => 'ye', 'Ñ–' => 'i', 'Ñâ€â€�' => 'yi', 'Ò‘' => 'g',1756 // Czech1757 'ÄŒ' => 'C', 'ÄŽ' => 'D', 'Äš' => 'E', 'Ň' => 'N', 'Ã…Ëœ' => 'R', 'Å ' => 'S', 'Ť' => 'T', 'Å®' => 'U',1758 'Ž' => 'Z',1759 '�' => 'c', '�' => 'd', 'Ä›' => 'e', 'ň' => 'n', 'Ã…â„¢' => 'r', 'Å¡' => 's', 'Ã…Â¥' => 't', 'ů' => 'u',1760 'ž' => 'z',1761 // Polish1762 'Ä„' => 'A', 'Ć' => 'C', 'Ę' => 'e', '�' => 'L', 'Ã…Æ’' => 'N', 'Ó' => 'o', 'Ã…Å¡' => 'S', 'Ź' => 'Z',1763 'Å»' => 'Z',1764 'Ä…' => 'a', 'ć' => 'c', 'Ä™' => 'e', 'Å‚' => 'l', 'Å„' => 'n', 'ó' => 'o', 'Å›' => 's', 'ź' => 'z',1765 'ż' => 'z',1766 // Latvian1767 'Ä€' => 'A', 'ÄŒ' => 'C', 'Ä’' => 'E', 'Ä¢' => 'G', 'Ī' => 'i', 'Ķ' => 'k', 'Ä»' => 'L', 'Å…' => 'N',1768 'Å ' => 'S', 'Ū' => 'u', 'Ž' => 'Z',1769 '�' => 'a', '�' => 'c', 'Ä“' => 'e', 'Ä£' => 'g', 'Ä«' => 'i', 'Ä·' => 'k', 'ļ' => 'l', 'ņ' => 'n',1770 'Å¡' => 's', 'Å«' => 'u', 'ž' => 'z'1771 );1772 1773 // Make custom replacements1774 $_str = preg_replace(array_keys($_options['replacements']), $_options['replacements'], $_str);1775 1776 // Transliterate characters to ASCII1777 if ($_options['transliterate']) {1778 $_str = str_replace(array_keys($char_map), $char_map, $_str);1779 }1780 1781 // Replace non-alphanumeric characters with our delimiter1782 $_str = preg_replace('/[^\p{L}\p{Nd}]+/u', $_options['delimiter'], $_str);1783 1784 // Remove duplicate delimiters1785 $_str = preg_replace('/('. preg_quote($_options['delimiter'], '/') .'){2,}/', '$1', $_str);1786 1787 // Truncate slug to max. characters1788 $_str= mb_substr($_str, 0, ($_options['limit'] ? $_options['limit'] : mb_strlen($_str, 'UTF-8')), 'UTF-8');1789 1790 // Remove delimiter from ends1791 $_str = trim($_str, $_options['delimiter']);1792 1793 return $_options['lowercase'] ? mb_strtolower($_str, 'UTF-8') : $_str; 1794 }1795 1310 ); 1311 } 1312 1313 } 1314 } 1315 return apply_filters('wcff_fields_for_product', $groups, $_pid, $_type, $_template, $_fields_location); 1316 } 1317 1318 1319 /** 1320 * 1321 * WCFF Product Mapping Rules Engine, This is function used to determine whether or not to include<br/> 1322 * a particular wccpf group fields to a particular Product 1323 * 1324 * @param integer $_pid - Product Id 1325 * @param array $_groups 1326 * @return boolean 1327 * 1328 */ 1329 public function check_for_product($_pid, $_groups) { 1330 1331 $matches = array(); 1332 $final_matches = array(); 1333 1334 $post_type = ""; 1335 $p = get_post($_pid); 1336 if ($p && $p->post_type) { 1337 $post_type = $p->post_type; 1338 } 1339 1340 foreach ($_groups as $rules) { 1341 1342 $ands = array(); 1343 foreach ($rules as $rule) { 1344 1345 /* Special case scenario only for Product Variations */ 1346 if (wcff()->request && $rule["context" ] != "product_variation" && wcff()->request["context"] == "wcff_variation_fields") { 1347 return false; 1348 } 1349 1350 if ($rule["context"] == "product" && $post_type == "product") { 1351 if ($rule["endpoint"] == -1) { 1352 $ands[] = ($rule["logic"] == "=="); 1353 } else { 1354 if ($rule["logic"] == "==") { 1355 $ands[] = ($_pid == $rule["endpoint"]); 1356 } else { 1357 $ands[] = ($_pid != $rule["endpoint"]); 1358 } 1359 } 1360 } else if ($rule["context"] == "product_variation" && $post_type == "product_variation") { 1361 if ($rule["endpoint"] == -1) { 1362 if (get_post_type($_pid) == "product_variation") { 1363 $ands[] = ($rule["logic"] == "=="); 1364 } else { 1365 $ands[] = false; 1366 } 1367 } else { 1368 if ($rule["logic"] == "==") { 1369 if (get_post_type($_pid) == "product_variation") { 1370 $ands[] = ($_pid == $rule["endpoint"]); 1371 } else { 1372 $ands[] = false; 1373 } 1374 } else { 1375 if (get_post_type($_pid) == "product_variation") { 1376 $ands[] = ($_pid != $rule["endpoint"]); 1377 } else { 1378 $ands[] = false; 1379 } 1380 } 1381 } 1382 } else if ($rule["context"] == "product_cat") { 1383 if ($rule["endpoint"] == -1) { 1384 $ands[] = ($rule["logic"] == "=="); 1385 } else { 1386 if ($rule["logic"] == "==") { 1387 $ands[] = has_term($rule["endpoint"], 'product_cat', $_pid); 1388 } else { 1389 $ands[] = !has_term($rule["endpoint"], 'product_cat', $_pid); 1390 } 1391 } 1392 } else if ($rule["context"] == "product_tag") { 1393 if ($rule["endpoint"] == -1) { 1394 $ands[] = ($rule["logic"] == "=="); 1395 } else { 1396 if ($rule["logic"] == "==") { 1397 $ands[] = has_term($rule["endpoint"], 'product_tag', $_pid); 1398 } else { 1399 $ands[] = !has_term($rule["endpoint"], 'product_tag', $_pid); 1400 } 1401 } 1402 } else if ($rule["context"] == "product_type") { 1403 if ($rule["endpoint"] == -1) { 1404 $ands[] = ($rule["logic"] == "=="); 1405 } else { 1406 $ptype = wp_get_object_terms($_pid, 'product_type'); 1407 if (!empty($ptype)) { 1408 $ands[] = ($ptype[0]->slug == $rule["endpoint"]); 1409 } 1410 } 1411 } 1412 1413 } 1414 1415 $matches[] = $ands; 1416 1417 } 1418 1419 foreach ($matches as $match) { 1420 if (!empty($match)) { 1421 $final_matches[] = !in_array(false, $match); 1422 } 1423 } 1424 1425 return in_array(true, $final_matches); 1426 1427 } 1428 1429 /** 1430 * 1431 * WCFF Location Rules Engine, This is function used to determine where does the particular wccaf fields group<br/> 1432 * to be placed. in the product view, product cat view or one of any product data sections ( Tabs )<br/> 1433 * applicable only for wccaf post_type. 1434 * 1435 * @param integer $_pid 1436 * @param array $_groups 1437 * @param string $_location 1438 * 1439 */ 1440 public function check_for_location($_rule, $_location) { 1441 1442 if ($_rule["context"] == "location_product_data") { 1443 if ($_rule["endpoint"] == $_location) { 1444 return true; 1445 } 1446 } 1447 if ($_rule["context"] == "location_product" && $_location == "admin_head-post.php") { 1448 return true; 1449 } 1450 if ($_rule["context"] == "location_product_cat" && ($_location == "product_cat_add_form_fields" || $_location == "product_cat_edit_form_fields")) { 1451 return true; 1452 } 1453 1454 return false; 1455 } 1456 1457 private function check_for_roles($_targeted_roles) { 1458 1459 global $wp_roles; 1460 1461 $all_roles = array(); 1462 foreach ($wp_roles->roles as $handle => $role) { 1463 $all_roles[] = $handle; 1464 } 1465 1466 if (!$_targeted_roles || empty($_targeted_roles)) { 1467 $_targeted_roles = $all_roles; 1468 } 1469 1470 $user = wp_get_current_user(); 1471 $intersect = array_intersect($_targeted_roles, (array) $user->roles); 1472 return (count($intersect) > 0); 1473 1474 } 1475 1476 /** 1477 * 1478 * Order the array for the given property. 1479 * 1480 * @param array $_arr 1481 * @param string $_col 1482 * @param string $_dir 1483 * 1484 */ 1485 public function usort_by_column(&$_arr, $_col, $_dir = SORT_ASC) { 1486 $sort_col = array(); 1487 foreach ($_arr as $key=> $row) { 1488 $sort_col[$key] = $row[$_col]; 1489 } 1490 array_multisort($sort_col, $_dir, $_arr); 1491 } 1492 1493 /** 1494 * 1495 */ 1496 public function migrate_for_version_4xxx() { 1497 1498 /* Check wccpf */ 1499 $this->migrate_fields("wccpf"); 1500 /* Check wccaf */ 1501 $this->migrate_fields("wccaf"); 1502 /* Check wccvf */ 1503 $this->migrate_fields("wccvf"); 1504 /* Check wcccf */ 1505 //$this->migrate_fields("wcccf"); 1506 1507 wcff()->option->update_option("version", wcff()->info["version"]); 1508 wcff()->option->update_option("enable_custom_pricing", "yes"); 1509 1510 } 1511 1512 private function migrate_fields($_ptype = "") { 1513 1514 $this->wcff_key_prefix = $_ptype . "_"; 1515 /* Special keys that is not part of fields meta */ 1516 $excluded_keys = $this->prepare_special_keys(); 1517 1518 /* Fetch the group posts */ 1519 $group_posts = get_posts( 1520 array( 1521 "post_type" => $_ptype, 1522 "posts_per_page" => -1, 1523 "order" => "ASC" 1524 ) 1525 ); 1526 1527 if (count($group_posts) > 0) { 1528 /* Loop through all group posts */ 1529 foreach ($group_posts as $g_post) { 1530 1531 /* Get all custom meta */ 1532 $fields = get_post_meta($g_post->ID); 1533 1534 foreach ($fields as $fkey => $meta) { 1535 /* Exclude special purpose custom meta */ 1536 if (!in_array($fkey, $excluded_keys) && (strpos($fkey, $this->wcff_key_prefix) === 0)) { 1537 1538 $field = json_decode($meta[0], true); 1539 1540 /* Check is_enabled property */ 1541 if (!isset($field["is_enable"]) || !$field["is_enable"]) { 1542 $field["is_enable"] = true; 1543 } 1544 /* Check key property */ 1545 if (!isset($field["key"]) && isset($field["name"])) { 1546 $field["key"] = $field["name"]; 1547 } 1548 1549 if ($field["type"] == "checkbox" && isset($field["pricing_rules"]) && is_array($field["pricing_rules"])) { 1550 foreach ($field["pricing_rules"] as $pkey => $rule) { 1551 $field["pricing_rules"][$pkey]["old_logic"] = $field["pricing_rules"][$pkey]["logic"]; 1552 $field["pricing_rules"][$pkey]["logic"] = "has-options"; 1553 } 1554 } 1555 if ($field["type"] == "checkbox" && isset($field["fee_rules"]) && is_array($field["fee_rules"])) { 1556 foreach ($field["fee_rules"] as $pkey => $rule) { 1557 $field["fee_rules"][$pkey]["old_logic"] = $field["fee_rules"][$pkey]["logic"]; 1558 $field["fee_rules"][$pkey]["logic"] = "has-options"; 1559 } 1560 } 1561 if ($field["type"] == "checkbox" && isset($field["field_rules"]) && is_array($field["field_rules"])) { 1562 foreach ($field["field_rules"] as $pkey => $rule) { 1563 $field["field_rules"][$pkey]["old_logic"] = $field["field_rules"][$pkey]["logic"]; 1564 $field["field_rules"][$pkey]["logic"] = "has-options"; 1565 } 1566 } 1567 1568 if (isset($field["field_rules"]) && is_array($field["field_rules"])) { 1569 foreach ($field["field_rules"] as $pkey => $rule) { 1570 if (isset($rule["field_rules"])) { 1571 foreach ($rule["field_rules"] as $frkey => $fval) { 1572 1573 $fname = $frkey; 1574 /* Prior to V4 check box key has suffix of [] - so we need to remove this */ 1575 if ($this->endsWith($frkey, "[]")) { 1576 $fname = substr($frkey, 0, strlen($frkey) - 2); 1577 } 1578 1579 $field["field_rules"][$pkey]["field_rules"][ $this->wcff_key_prefix . $fname ] = $fval; 1580 unset($field["field_rules"][$pkey]["field_rules"][$frkey]); 1581 1582 } 1583 } 1584 } 1585 } 1586 1587 update_post_meta($g_post->ID, $fkey, wp_slash(json_encode($field))); 1588 1589 } 1590 } 1591 1592 /* Update the admin location rules for wccaf */ 1593 if ($_ptype == "wccaf" && isset($fields["wccaf_location_rules"])) { 1594 1595 $lrules = json_decode($fields["wccaf_location_rules"][0], true); 1596 if (is_array($lrules[0]) && is_array($lrules[0][0])) { 1597 update_post_meta($g_post->ID, "wccaf_location_rules", wp_slash(json_encode($lrules[0][0]))); 1598 } 1599 1600 } 1601 1602 } 1603 } 1604 1605 } 1606 1607 private function get_fields_count($_pid) { 1608 $count =0; 1609 $keys = get_post_custom_keys($_pid); 1610 if ($keys) { 1611 foreach ($keys as $key) { 1612 if ((strpos($key, 'wccpf_') !== false || 1613 strpos($key, 'wccaf_') !== false || 1614 strpos($key, 'wccvf_') !== false) && 1615 (strpos($key, 'group_rules') === false && 1616 strpos($key, 'condition_rules') === false && 1617 strpos($key, 'fee_rules') === false && 1618 strpos($key, 'field_rules') === false && 1619 strpos($key, 'location_rules') === false && 1620 strpos($key, 'product_tab_title') === false && 1621 strpos($key, 'product_tab_priority') === false && 1622 strpos($key, 'field_location_on_product') === false && 1623 strpos($key, 'field_location_on_archive') === false && 1624 strpos($key, 'is_this_group_clonable') === false)) { 1625 $count++; 1626 } 1627 } 1628 } 1629 return $count; 1630 } 1631 1632 function endsWith($haystack, $needle) { 1633 return substr_compare($haystack, $needle, -strlen($needle)) === 0; 1634 } 1635 1636 /** 1637 * 1638 * @return string 1639 */ 1640 private function generate_unique_id() { 1641 $token = ''; 1642 $token_length = 12; 1643 $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 1644 $alphabet .= "abcdefghijklmnopqrstuvwxyz"; 1645 $alphabet .= "0123456789"; 1646 $alphabetLength = strlen($alphabet); 1647 for ($i = 0; $i < $token_length; $i++) { 1648 $randomKey = $this->get_random_number(0, $alphabetLength); 1649 $token .= $alphabet[$randomKey]; 1650 } 1651 return $token; 1652 } 1653 1654 /** 1655 * 1656 * @param number $_min 1657 * @param number $_max 1658 * @return number 1659 */ 1660 private function get_random_number($_min = 0, $_max = 0) { 1661 $range = ($_max - $_min); 1662 if ($range < 0) { 1663 return $_min; 1664 } 1665 $log = log($range, 2); 1666 $bytes = (int) ($log / 8) + 1; 1667 $bits = (int) $log + 1; 1668 $filter = (int) (1 << $bits) - 1; 1669 do { 1670 $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); 1671 $rnd = $rnd & $filter; 1672 } while ($rnd >= $range); 1673 return ($_min + $rnd); 1674 } 1675 1676 private function prepare_special_keys() { 1677 $excluded_keys = array(); 1678 if ($this->wcff_key_prefix != "") { 1679 foreach ($this->special_keys as $key) { 1680 $excluded_keys[] = $this->wcff_key_prefix . $key; 1681 } 1682 } 1683 return $excluded_keys; 1684 } 1685 1686 /** 1687 * 1688 * Create a web friendly URL slug from a string. 1689 * 1690 * @author Sean Murphy <sean@iamseanmurphy.com> 1691 * @copyright Copyright 2012 Sean Murphy. All rights reserved. 1692 * @license http://creativecommons.org/publicdomain/zero/1.0/ 1693 * 1694 * @param string $str 1695 * @param array $options 1696 * @return string 1697 * 1698 */ 1699 function url_slug($_str, $_options = array()) { 1700 // Make sure string is in UTF-8 and strip invalid UTF-8 characters 1701 $_str = mb_convert_encoding((string) $_str, 'UTF-8', mb_list_encodings()); 1702 1703 $defaults = array ( 1704 'delimiter' => '-', 1705 'limit' => null, 1706 'lowercase' => true, 1707 'replacements' => array(), 1708 'transliterate' => false, 1709 ); 1710 1711 // Merge options 1712 $_options = array_merge($defaults, $_options); 1713 1714 $char_map = array ( 1715 // Latin 1716 'À' => 'A', '�' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Ã…' => 'A', 'Æ' => 'AE', 'Ç' => 'C', 1717 'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'ÃŒ' => 'I', '�' => 'I', 'ÃŽ' => 'I', '�' => 'I', 1718 '�' => 'D', 'Ñ' => 'N', 'Ã’' => 'O', 'Ó' => 'O', '�' => 'O', 'Õ' => 'O', 'Ö' => 'O', '�' => 'O', 1719 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ű' => 'U', '�' => 'Y', 'Þ' => 'TH', 1720 'ß' => 'ss', 1721 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'Ã¥' => 'a', 'æ' => 'ae', 'ç' => 'c', 1722 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'ÃÂÂ' => 'i', 'î' => 'i', 'ï' => 'i', 1723 'ð' => 'd', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'Å‘' => 'o', 1724 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'ű' => 'u', 'ý' => 'y', 'þ' => 'th', 1725 'ÿ' => 'y', 1726 // Latin symbols 1727 '©' => '(c)', 1728 // Greek 1729 'Α' => 'A', 'Î’' => 'B', 'Γ' => 'G', '�' => 'D', 'Ε' => 'E', 'Ζ' => 'Z', 'ÃŽâ€â€�' => 'H', 'ÃŽËœ' => '8', 1730 'ÃŽâ„¢' => 'I', 'ÃŽÅ¡' => 'K', 'Λ' => 'L', 'ÃŽÅ“' => 'M', '�' => 'N', 'Ξ' => '3', 'Ο' => 'O', 'Π' => 'P', 1731 'Ρ' => 'R', 'Σ' => 'S', 'Τ' => 'T', 'ÃŽÂ¥' => 'Y', 'Φ' => 'F', 'Χ' => 'X', 'Ψ' => 'PS', 'Ω' => 'W', 1732 'Ά' => 'A', 'Έ' => 'E', 'ÃŽÅ ' => 'I', 'ÃŽÅ’' => 'O', 'ÎŽ' => 'Y', 'Ή' => 'H', '�' => 'W', 'Ϊ' => 'I', 1733 'Ϋ' => 'Y', 1734 'α' => 'a', 'β' => 'b', 'γ' => 'g', 'δ' => 'd', 'ε' => 'e', 'ζ' => 'z', 'η' => 'h', 'θ' => '8', 1735 'ι' => 'i', 'κ' => 'k', 'λ' => 'l', 'μ' => 'm', 'ν' => 'n', 'ξ' => '3', 'ο' => 'o', '�€' => 'p', 1736 '��' => 'r', '�ƒ' => 's', '�„' => 't', '�…' => 'y', '�†' => 'f', '�‡' => 'x', '�ˆ' => 'ps', '�‰' => 'w', 1737 'ά' => 'a', 'ÃŽÂÂ' => 'e', 'ί' => 'i', '�Œ' => 'o', '��' => 'y', 'ή' => 'h', '�Ž' => 'w', '�‚' => 's', 1738 '�Š' => 'i', 'ΰ' => 'y', '�‹' => 'y', '�' => 'i', 1739 // Turkish 1740 'Åž' => 'S', 'İ' => 'I', 'Ç' => 'C', 'Ü' => 'U', 'Ö' => 'O', 'Äž' => 'G', 1741 'ÅŸ' => 's', 'ı' => 'i', 'ç' => 'c', 'ü' => 'u', 'ö' => 'o', 'ÄŸ' => 'g', 1742 // Russian 1743 '��' => 'A', '�‘' => 'B', '�’' => 'V', '�“' => 'G', '��' => 'D', '�•' => 'E', '��' => 'Yo', '�–' => 'Zh', 1744 'Ã�â€â€�' => 'Z', '�˜' => 'I', '�™' => 'J', '�š' => 'K', '�›' => 'L', '�œ' => 'M', '��' => 'N', '�ž' => 'O', 1745 '�Ÿ' => 'P', '� ' => 'R', '�¡' => 'S', '�¢' => 'T', '�£' => 'U', '�¤' => 'F', '�¥' => 'H', '�¦' => 'C', 1746 '�§' => 'Ch', '�¨' => 'Sh', '�©' => 'Sh', '�ª' => '', '�«' => 'Y', '�¬' => '', 'Ã�ÂÂ' => 'E', '�®' => 'Yu', 1747 '�¯' => 'Ya', 1748 '�°' => 'a', '�±' => 'b', '�²' => 'v', '�³' => 'g', '�´' => 'd', '�µ' => 'e', 'Ñ‘' => 'yo', '�¶' => 'zh', 1749 '�·' => 'z', '�¸' => 'i', '�¹' => 'j', '�º' => 'k', '�»' => 'l', '�¼' => 'm', '�½' => 'n', '�¾' => 'o', 1750 '�¿' => 'p', 'Ñ€' => 'r', '�' => 's', 'Ñ‚' => 't', 'у' => 'u', 'Ñ„' => 'f', 'Ñ…' => 'h', 'ц' => 'c', 1751 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sh', 'ÑŠ' => '', 'Ñ‹' => 'y', 'ÑŒ' => '', '�' => 'e', 'ÑŽ' => 'yu', 1752 '�' => 'ya', 1753 // Ukrainian 1754 '�„' => 'Ye', '�†' => 'I', '�‡' => 'Yi', 'Ò�' => 'G', 1755 '�' => 'ye', 'Ñ–' => 'i', 'Ñâ€â€�' => 'yi', 'Ò‘' => 'g', 1756 // Czech 1757 'ÄŒ' => 'C', 'ÄŽ' => 'D', 'Äš' => 'E', 'Ň' => 'N', 'Ã…Ëœ' => 'R', 'Å ' => 'S', 'Ť' => 'T', 'Å®' => 'U', 1758 'Ž' => 'Z', 1759 '�' => 'c', '�' => 'd', 'Ä›' => 'e', 'ň' => 'n', 'Ã…â„¢' => 'r', 'Å¡' => 's', 'Ã…Â¥' => 't', 'ů' => 'u', 1760 'ž' => 'z', 1761 // Polish 1762 'Ä„' => 'A', 'Ć' => 'C', 'Ę' => 'e', '�' => 'L', 'Ã…Æ’' => 'N', 'Ó' => 'o', 'Ã…Å¡' => 'S', 'Ź' => 'Z', 1763 'Å»' => 'Z', 1764 'Ä…' => 'a', 'ć' => 'c', 'Ä™' => 'e', 'Å‚' => 'l', 'Å„' => 'n', 'ó' => 'o', 'Å›' => 's', 'ź' => 'z', 1765 'ż' => 'z', 1766 // Latvian 1767 'Ä€' => 'A', 'ÄŒ' => 'C', 'Ä’' => 'E', 'Ä¢' => 'G', 'Ī' => 'i', 'Ķ' => 'k', 'Ä»' => 'L', 'Å…' => 'N', 1768 'Å ' => 'S', 'Ū' => 'u', 'Ž' => 'Z', 1769 '�' => 'a', '�' => 'c', 'Ä“' => 'e', 'Ä£' => 'g', 'Ä«' => 'i', 'Ä·' => 'k', 'ļ' => 'l', 'ņ' => 'n', 1770 'Å¡' => 's', 'Å«' => 'u', 'ž' => 'z' 1771 ); 1772 1773 // Make custom replacements 1774 $_str = preg_replace(array_keys($_options['replacements']), $_options['replacements'], $_str); 1775 1776 // Transliterate characters to ASCII 1777 if ($_options['transliterate']) { 1778 $_str = str_replace(array_keys($char_map), $char_map, $_str); 1779 } 1780 1781 // Replace non-alphanumeric characters with our delimiter 1782 $_str = preg_replace('/[^\p{L}\p{Nd}]+/u', $_options['delimiter'], $_str); 1783 1784 // Remove duplicate delimiters 1785 $_str = preg_replace('/('. preg_quote($_options['delimiter'], '/') .'){2,}/', '$1', $_str); 1786 1787 // Truncate slug to max. characters 1788 $_str= mb_substr($_str, 0, ($_options['limit'] ? $_options['limit'] : mb_strlen($_str, 'UTF-8')), 'UTF-8'); 1789 1790 // Remove delimiter from ends 1791 $_str = trim($_str, $_options['delimiter']); 1792 1793 return $_options['lowercase'] ? mb_strtolower($_str, 'UTF-8') : $_str; 1794 } 1795 1796 1796 } 1797 1797 -
wc-fields-factory/trunk/includes/wcff_dao.php
r2739039 r2739048 899 899 900 900 $id = $this->generate_unique_id(); 901 $id = apply_filters("wcff_new_field_id", $id );901 $id = apply_filters("wcff_new_field_id", $id, $_pid, $_type); 902 902 903 903 $meta = array ( … … 1018 1018 $_pid = absint($_pid); 1019 1019 $id = $this->generate_unique_id(); 1020 $id = apply_filters("wcff_new_field_id", $id );1020 $id = apply_filters("wcff_new_field_id", $id, $_pid, null); 1021 1021 $cloned = $this->load_field($_pid, $_fkey); 1022 1022 if (is_array($cloned)) {
Note: See TracChangeset
for help on using the changeset viewer.