/** * Function for recounting product terms, ignoring hidden products. * * @param array $terms * @param string $taxonomy * @param bool $callback * @param bool $terms_are_term_taxonomy_ids */ function _wc_term_recount($terms, $taxonomy, $callback = true, $terms_are_term_taxonomy_ids = true) { global $wpdb; // Standard callback if ($callback) { _update_post_term_count($terms, $taxonomy); } // Stock query if (get_option('woocommerce_hide_out_of_stock_items') == 'yes') { $stock_join = "LEFT JOIN {$wpdb->postmeta} AS meta_stock ON posts.ID = meta_stock.post_id"; $stock_query = "\n\t\tAND meta_stock.meta_key = '_stock_status'\n\t\tAND meta_stock.meta_value = 'instock'\n\t\t"; } else { $stock_query = $stock_join = ''; } // Main query $count_query = "\n\t\tSELECT COUNT( DISTINCT posts.ID ) FROM {$wpdb->posts} as posts\n\t\tLEFT JOIN {$wpdb->postmeta} AS meta_visibility ON posts.ID = meta_visibility.post_id\n\t\tLEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID\n\t\tLEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )\n\t\tLEFT JOIN {$wpdb->terms} AS term USING( term_id )\n\t\tLEFT JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\n\t\t{$stock_join}\n\t\tWHERE \tpost_status = 'publish'\n\t\tAND \tpost_type \t= 'product'\n\t\tAND \tmeta_visibility.meta_key = '_visibility'\n\t\tAND \tmeta_visibility.meta_value IN ( 'visible', 'catalog' )\n\t\t{$stock_query}\n\t"; // Pre-process term taxonomy ids if (!$terms_are_term_taxonomy_ids) { // We passed in an array of TERMS in format id=>parent $terms = array_filter((array) array_keys($terms)); } else { // If we have term taxonomy IDs we need to get the term ID $term_taxonomy_ids = $terms; $terms = array(); foreach ($term_taxonomy_ids as $term_taxonomy_id) { $term = get_term_by('term_taxonomy_id', $term_taxonomy_id, $taxonomy->name); $terms[] = $term->term_id; } } // Exit if we have no terms to count if (empty($terms)) { return; } // Ancestors need counting if (is_taxonomy_hierarchical($taxonomy->name)) { foreach ($terms as $term_id) { $terms = array_merge($terms, get_ancestors($term_id, $taxonomy->name)); } } // Unique terms only $terms = array_unique($terms); // Count the terms foreach ($terms as $term_id) { $terms_to_count = array(absint($term_id)); if (is_taxonomy_hierarchical($taxonomy->name)) { // We need to get the $term's hierarchy so we can count its children too if (($children = get_term_children($term_id, $taxonomy->name)) && !is_wp_error($children)) { $terms_to_count = array_unique(array_map('absint', array_merge($terms_to_count, $children))); } } // Generate term query $term_query = 'AND term_id IN ( ' . implode(',', $terms_to_count) . ' )'; // Get the count $count = $wpdb->get_var($count_query . $term_query); // Update the count update_woocommerce_term_meta($term_id, 'product_count_' . $taxonomy->name, absint($count)); } delete_transient('wc_term_counts'); }
/** * Perform term count update immediately. * * @since 2.5.0 * * @param array $terms The term_taxonomy_id of terms to update. * @param string $taxonomy The context of the term. * @return true Always true when complete. */ function wp_update_term_count_now($terms, $taxonomy) { $terms = array_map('intval', $terms); $taxonomy = get_taxonomy($taxonomy); if (!empty($taxonomy->update_count_callback)) { call_user_func($taxonomy->update_count_callback, $terms, $taxonomy); } else { $object_types = (array) $taxonomy->object_type; foreach ($object_types as &$object_type) { if (0 === strpos($object_type, 'attachment:')) { list($object_type) = explode(':', $object_type); } } if ($object_types == array_filter($object_types, 'post_type_exists')) { // Only post types are attached to this taxonomy _update_post_term_count($terms, $taxonomy); } else { // Default count updater _update_generic_term_count($terms, $taxonomy); } } clean_term_cache($terms, '', false); return true; }
/** * Function for recounting product terms, ignoring hidden products. * * @access public * @param mixed $term * @param mixed $taxonomy * @return void */ function _woocommerce_term_recount($terms, $taxonomy, $callback = true, $terms_are_term_taxonomy_ids = true) { global $wpdb; // Standard callback if ($callback) { _update_post_term_count($terms, $taxonomy); } // Stock query if (get_option('woocommerce_hide_out_of_stock_items') == 'yes') { $stock_join = "LEFT JOIN {$wpdb->postmeta} AS meta_stock ON posts.ID = meta_stock.post_id"; $stock_query = "\n\t\tAND (\n\t\t\tmeta_stock.meta_key = '_stock_status'\n\t\t\tAND\n\t\t\tmeta_stock.meta_value = 'instock'\n\t\t)"; } else { $stock_query = $stock_join = ''; } // Main query $count_query = $wpdb->prepare("\n\t\tSELECT COUNT( DISTINCT posts.ID ) FROM {$wpdb->posts} as posts\n\n\t\tLEFT JOIN {$wpdb->postmeta} AS meta_visibility ON posts.ID = meta_visibility.post_id\n\t\tLEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_ID\n\t\tLEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )\n\t\tLEFT JOIN {$wpdb->terms} AS term USING( term_id )\n\t\t{$stock_join}\n\n\t\tWHERE \tposts.post_status \t= 'publish'\n\t\tAND \tposts.post_type \t= 'product'\n\t\tAND \t(\n\t\t\tmeta_visibility.meta_key = '_visibility'\n\t\t\tAND\n\t\t\tmeta_visibility.meta_value IN ( 'visible', 'catalog' )\n\t\t)\n\t\tAND \ttax.taxonomy\t= %s\n\t\t{$stock_query}\n\t", $taxonomy->name); // Store terms + counts here $term_counts = array(); $counted_terms = array(); $maybe_count_parents = array(); // Pre-process term taxonomy ids if ($terms_are_term_taxonomy_ids) { $term_ids = array(); foreach ((array) $terms as $term) { $the_term = $wpdb->get_row("SELECT term_id, parent FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = {$term} AND taxonomy = '{$taxonomy->name}'"); $term_ids[$the_term->term_id] = $the_term->parent; } $terms = $term_ids; } // Count those terms! foreach ((array) $terms as $term_id => $parent_id) { $term_ids = array(); if (is_taxonomy_hierarchical($taxonomy->name)) { // Grab the parents to count later $parent = $parent_id; while (!empty($parent) && $parent > 0) { $maybe_count_parents[] = $parent; $parent_term = get_term_by('id', $parent, $taxonomy->name); if ($parent_term) { $parent = $parent_term->parent; } else { $parent = 0; } } // We need to get the $term's hierarchy so we can count its children too $term_ids = get_term_children($term_id, $taxonomy->name); } $term_ids[] = absint($term_id); // Generate term query $term_query = 'AND term.term_id IN ( ' . implode(',', $term_ids) . ' )'; // Get the count $count = $wpdb->get_var($count_query . $term_query); update_woocommerce_term_meta($term_id, 'product_count_' . $taxonomy->name, absint($count)); $counted_terms[] = $term_id; } // Re-count parents if (is_taxonomy_hierarchical($taxonomy->name)) { $terms = array_diff($maybe_count_parents, $counted_terms); foreach ((array) $terms as $term) { $term_ids = get_term_children($term, $taxonomy->name); $term_ids[] = $term; // Generate term query $term_query = 'AND term.term_id IN ( ' . implode(',', $term_ids) . ' )'; // Get the count $count = $wpdb->get_var($count_query . $term_query); update_woocommerce_term_meta($term, 'product_count_' . $taxonomy->name, absint($count)); } } }
public static function status_tools() { global $wpdb; $tools = self::get_tools(); if (!empty($_GET['action']) && !empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'debug_action')) { switch ($_GET['action']) { case 'clear_transients': delete_transient('jigoshop_addons_data'); delete_transient('jigoshop_report_coupon_usage'); delete_transient('jigoshop_report_customer_list'); delete_transient('jigoshop_report_customers'); delete_transient('jigoshop_report_low_in_stock'); delete_transient('jigoshop_report_most_stocked'); delete_transient('jigoshop_report_out_of_stock'); delete_transient('jigoshop_report_sales_by_category'); delete_transient('jigoshop_report_sales_by_date'); delete_transient('jigoshop_report_sales_by_product'); delete_transient('jigoshop_widget_cache'); $query = new WP_User_Query(array('fields' => 'ids')); $users = $query->get_results(); foreach ($users as $user) { delete_transient('jigo_usercart_' . $user); } echo '<div class="updated"><p>' . __('Jigoshop transients cleared', 'jigoshop') . '</p></div>'; break; case 'clear_expired_transients': // http://w-shadow.com/blog/2012/04/17/delete-stale-transients/ $rows = $wpdb->query("\n\t\t\t\t\t\tDELETE\n\t\t\t\t\t\t\ta, b\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t{$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ta.option_name LIKE '_transient_%' AND\n\t\t\t\t\t\t\ta.option_name NOT LIKE '_transient_timeout_%' AND\n\t\t\t\t\t\t\tb.option_name = CONCAT(\n\t\t\t\t\t\t\t\t'_transient_timeout_',\n\t\t\t\t\t\t\t\tSUBSTRING(\n\t\t\t\t\t\t\t\t\ta.option_name,\n\t\t\t\t\t\t\t\t\tCHAR_LENGTH('_transient_') + 1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tAND b.option_value < UNIX_TIMESTAMP()\n\t\t\t\t\t"); $rows2 = $wpdb->query("\n\t\t\t\t\t\tDELETE\n\t\t\t\t\t\t\ta, b\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t{$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ta.option_name LIKE '_site_transient_%' AND\n\t\t\t\t\t\t\ta.option_name NOT LIKE '_site_transient_timeout_%' AND\n\t\t\t\t\t\t\tb.option_name = CONCAT(\n\t\t\t\t\t\t\t\t'_site_transient_timeout_',\n\t\t\t\t\t\t\t\tSUBSTRING(\n\t\t\t\t\t\t\t\t\ta.option_name,\n\t\t\t\t\t\t\t\t\tCHAR_LENGTH('_site_transient_') + 1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tAND b.option_value < UNIX_TIMESTAMP()\n\t\t\t\t\t"); echo '<div class="updated"><p>' . sprintf(__('%d transients rows cleared', 'jigoshop'), $rows + $rows2) . '</p></div>'; break; case 'reset_roles': // Remove then re-add caps and roles /** @var $wp_roles WP_Roles */ global $wp_roles; $capabilities = jigoshop_get_core_capabilities(); foreach ($capabilities as $cap_group) { foreach ($cap_group as $cap) { $wp_roles->remove_cap('administrator', $cap); $wp_roles->remove_cap('shop_manager', $cap); } } remove_role('customer'); remove_role('shop_manager'); // Add roles back jigoshop_roles_init(); echo '<div class="updated"><p>' . __('Roles successfully reset', 'jigoshop') . '</p></div>'; break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _update_post_term_count($product_cats, get_taxonomy('product_cat')); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _update_post_term_count($product_tags, get_taxonomy('product_tag')); echo '<div class="updated"><p>' . __('Terms successfully recounted', 'jigoshop') . '</p></div>'; break; case 'delete_taxes': $options = Jigoshop_Base::get_options(); $options->set('jigoshop_tax_rates', ''); $options->update_options(); echo '<div class="updated"><p>' . __('Tax rates successfully deleted', 'jigoshop') . '</p></div>'; break; default: $action = esc_attr($_GET['action']); if (isset($tools[$action]['callback'])) { $callback = $tools[$action]['callback']; $return = call_user_func($callback); if ($return === false) { if (is_array($callback)) { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s::%s', 'jigoshop'), get_class($callback[0]), $callback[1]) . '</p></div>'; } else { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s', 'jigoshop'), $callback) . '</p></div>'; } } } break; } } // Display message if settings settings have been saved if (isset($_REQUEST['settings-updated'])) { echo '<div class="updated"><p>' . __('Your changes have been saved.', 'jigoshop') . '</p></div>'; } $template = jigoshop_locate_template('admin/status/tools'); /** @noinspection PhpIncludeInspection */ include $template; }
/** * Function for recounting product terms, ignoring hidden products. * @param array $terms * @param string $taxonomy * @param bool $callback * @param bool $terms_are_term_taxonomy_ids */ function _wc_term_recount($terms, $taxonomy, $callback = true, $terms_are_term_taxonomy_ids = true) { global $wpdb, $wc_allow_term_recount; // Don't recount unless CRUD is calling this. if (empty($wc_allow_term_recount)) { return; } // Standard callback if ($callback) { _update_post_term_count($terms, $taxonomy); } // Main query $count_query = "\n\t\tSELECT COUNT( DISTINCT posts.ID ) FROM {$wpdb->posts} as posts\n\t\tLEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID\n\t\tLEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )\n\t\tWHERE \tpost_status = 'publish'\n\t\tAND \tpost_type \t= 'product'\n\t"; $product_visibility_term_ids = wc_get_product_visibility_term_ids(); if ($product_visibility_term_ids['exclude-from-catalog']) { $count_query .= " AND term_taxonomy_id !=" . $product_visibility_term_ids['exclude-from-catalog']; } if ('yes' === get_option('woocommerce_hide_out_of_stock_items') && $product_visibility_term_ids['outofstock']) { $count_query .= " AND term_taxonomy_id !=" . $product_visibility_term_ids['outofstock']; } // Pre-process term taxonomy ids if (!$terms_are_term_taxonomy_ids) { // We passed in an array of TERMS in format id=>parent $terms = array_filter((array) array_keys($terms)); } else { // If we have term taxonomy IDs we need to get the term ID $term_taxonomy_ids = $terms; $terms = array(); foreach ($term_taxonomy_ids as $term_taxonomy_id) { $term = get_term_by('term_taxonomy_id', $term_taxonomy_id, $taxonomy->name); $terms[] = $term->term_id; } } // Exit if we have no terms to count if (empty($terms)) { return; } // Ancestors need counting if (is_taxonomy_hierarchical($taxonomy->name)) { foreach ($terms as $term_id) { $terms = array_merge($terms, get_ancestors($term_id, $taxonomy->name)); } } // Unique terms only $terms = array_unique($terms); // Count the terms foreach ($terms as $term_id) { $terms_to_count = array(absint($term_id)); if (is_taxonomy_hierarchical($taxonomy->name)) { // We need to get the $term's hierarchy so we can count its children too if (($children = get_term_children($term_id, $taxonomy->name)) && !is_wp_error($children)) { $terms_to_count = array_unique(array_map('absint', array_merge($terms_to_count, $children))); } } // Generate term query $term_query = ' AND term_id IN ( ' . implode(',', $terms_to_count) . ' )'; // Get the count $count = $wpdb->get_var($count_query . $term_query); // Update the count update_woocommerce_term_meta($term_id, 'product_count_' . $taxonomy->name, absint($count)); } delete_transient('wc_term_counts'); }
/** * Term Count Callback that applies custom filter * Allows Workflow State counts to include non-published posts * @since 1.2.1 * @param unknown $terms * @param unknown $taxonomy */ function term_count_cb($terms, $taxonomy) { add_filter('query', array(&$this, 'term_count_query_filter')); _update_post_term_count($terms, $taxonomy); remove_filter('query', array(&$this, 'term_count_query_filter')); }