Is there a way to change the shop URL
from: https://example.com/shop/productpage/
to: https://example.com/productpage/
make a new plugin with code below or add to functions.php in theme. REMEMBER update permalink
function wndev_remove_slug( $post_link, $post ) {
if ( !in_array( get_post_type($post), array( 'product' ) ) || 'publish' != $post->post_status ) {
return $post_link;
}
if('product' == $post->post_type){
$post_link = str_replace( '/shop/', '/', $post_link );
}else{
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
}
return $post_link;
}
add_filter( 'post_type_link', 'wndev_remove_slug', 10, 2 );
function wndev_woo_product_rewrite_rules($flash = false) {
global $wp_post_types, $wpdb;
$siteLink = esc_url(home_url('/'));
foreach ($wp_post_types as $type=>$custom_post) {
if($type == 'product'){
if ($custom_post->_builtin == false) {
$querystr = "SELECT {$wpdb->posts}.post_name, {$wpdb->posts}.ID
FROM {$wpdb->posts}
WHERE {$wpdb->posts}.post_status = 'publish'
AND {$wpdb->posts}.post_type = '{$type}'";
$posts = $wpdb->get_results($querystr, OBJECT);
foreach ($posts as $post) {
$current_slug = get_permalink($post->ID);
$base_product = str_replace($siteLink,'',$current_slug);
add_rewrite_rule($base_product.'?$', "index.php?{$custom_post->query_var}={$post->post_name}", 'top');
add_rewrite_rule($base_product.'comment-page-([0-9]{1,})/?$', 'index.php?'.$custom_post->query_var.'='.$post->post_name.'&cpage=$matches[1]', 'top');
add_rewrite_rule($base_product.'(?:feed/)?(feed|rdf|rss|rss2|atom)/?$', 'index.php?'.$custom_post->query_var.'='.$post->post_name.'&feed=$matches[1]','top');
}
}
}
}
if ($flash == true)
flush_rewrite_rules(false);
}
add_action('init', 'wndev_woo_product_rewrite_rules');
function wndev_woo_new_product_post_save($post_id){
global $wp_post_types;
$post_type = get_post_type($post_id);
foreach ($wp_post_types as $type=>$custom_post) {
if ($custom_post->_builtin == false && $type == $post_type) {
wndev_woo_product_rewrite_rules(true);
}
}
}
add_action('wp_insert_post', 'wndev_woo_new_product_post_save');
Related
I want to place ads after second paragraph of the posts located under a specific category. For this I am trying to run the following piece of codes but it is not working. Kindly help me out.
//Insert ads after second paragraph of single post content.
$catarray = get_the_category( $post->ID );
foreach ($catarray as $cat) {
$catid = $cat->term_id;
if ($catid == 124);
add_filter( 'the_content', 'prefix_insert_post_ads' );
function prefix_insert_post_ads( $content ) {
$ad_code = '<div>Insert Ad code here</div>';
if ( is_single() && ! is_admin() ) {
return prefix_insert_after_paragraph( $ad_code, 2, $content );
}
}
return $content;
}
// Parent Function that makes the magic happen
function prefix_insert_after_paragraph( $insertion, $paragraph_id, $content ) {
$closing_p = '</p>';
$paragraphs = explode( $closing_p, $content );
foreach ($paragraphs as $index => $paragraph) {
if ( trim( $paragraph ) ) {
$paragraphs[$index] .= $closing_p;
}
if ( $paragraph_id == $index + 1 ) {
$paragraphs[$index] .= $insertion;
}
}
return implode( '', $paragraphs );
}
you can use this code for it
add_filter('the_content', 'ak_the_content_filter', 10, 1);
function ak_the_content_filter($content)
{
$catarray = get_the_category( $post->ID );
foreach ($catarray as $cat) {
$catid = $cat->term_id;
if ($catid != 124) { return $content; }
else{
$parags = explode('</p>', $content);
$parags[1] .= '<br>'.do_shortcode('[SHORTCODE HERE]');// add whatever you want after first paragraph
$content_new = '';
foreach ($parags as $parag) {
$content_new .= $parag;
}
return $content_new;
}
}
}
When Ajax add to cart functionality is active on my WooCommerce store, on Ajax add to cart first click It shows a checked icon symbol like:
The code below changes the add to button cart text to "Seçildi !" if product is already in to cart, only after refreshing page like:
//Rename the button on the Product page
add_filter( 'woocommerce_product_single_add_to_cart_text', 'ts_product_add_cart_button' );
function ts_product_add_cart_button( $label ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
$product = $values['data'];
if( get_the_ID() == $product->get_id() ) {
$label = __('Seçildi !', 'woocommerce');
}
}
return $label;
}
//Rename the button on the Shop page
add_filter( 'woocommerce_product_add_to_cart_text', 'ts_shop_add_cart_button', 99, 2 );
function ts_shop_add_cart_button( $label, $product ) {
if ( $product->get_type() == 'simple' && $product->is_purchasable() && $product->is_in_stock() )
{
foreach( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( get_the_ID() == $_product->get_id() ) {
$label = __('Seçildi !', 'woocommerce');
}
}
}
return $label;
}
But if you don't refresh the page the button remains like before with the checked icon symbol.
What I would like is to change add to cart button with the quantity that has been added for this product like:
Is this possible? What do I need to change? Any help is appreciated.
You can use WC woocommerce_product_add_to_cart_text action hook and you can get wc cart loop through all products and compare path second params $prodcuct object. check below code. code will go active theme functions.php file.
function change_add_to_cart_text_if_product_already_in_cart( $add_to_cart_text, $product ) {
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product->get_id() == $_product_id ) {
$add_to_cart_text = '('.$cart_item['quantity'].')'.' Already in cart';
break;
}
}
}
}
return $add_to_cart_text;
}
add_filter( 'woocommerce_product_add_to_cart_text', 'change_add_to_cart_text_if_product_already_in_cart', 10, 2 );
add_filter( 'woocommerce_product_single_add_to_cart_text', 'change_add_to_cart_text_if_product_already_in_cart', 10, 2 );
Updated ( as per OP request how to change text quick on click with quantity ).
There is two way You can do this.
you can use woocommerce_loop_add_to_cart_args and add product qty attribute and based on that you can display.
function add_product_qty( $args, $product ){
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product->get_id() == $_product_id ) {
$args['attributes']['data-product-qty'] = $cart_item['quantity'];
}else{
$args['attributes']['data-product-qty'] = 0;
}
}
}else{
$args['attributes']['data-product-qty'] = 0;
}
}
return $args;
}
add_filter( 'woocommerce_loop_add_to_cart_args', 'add_product_qty', 10, 2 );
add_action( 'wp_footer', 'ajax_button_text_quick_change_js_script' );
function ajax_button_text_quick_change_js_script() {
?>
<script>
(function($) {
$(document.body).on('click', '.ajax_add_to_cart', function(event){
$this = $(this);
var product_qty = parseInt($this.attr('data-product-qty')) + 1;
$this.attr('data-product-qty',product_qty);
var buttonText = '<span class="add_to_cart_text product-is-added">('+product_qty+') Already in cart</span><i class="cart-icon pe-7s-cart"></i>';
$this.html(buttonText).attr('data-tip','('+product_qty+') Already in cart');
});
})(jQuery);
</script>
<?php
}
You can use added_to_cart jQuery event that triggers after adding to the cart you call ajax and get add_to_cart_text in response.
add_action( 'wp_footer', 'ajax_button_text_js_script' );
function ajax_button_text_js_script() {
?>
<script>
(function($) {
$(document.body).on('added_to_cart', function(event, fragments, cart_hash, button){
var product_id = button.data('product_id'),
product_qty = button.data('quantity');
button.addClass('loading');
$.ajax({
url: "<?php //echo admin_url('admin-ajax.php'); ?>",
method: 'POST',
data:{action:'change_add_to_cart_text',product_id:product_id},
dataType: "json",
success: function( response ){
var buttonText = '<span class="add_to_cart_text product-is-added">'+response.data.button_text+'</span><i class="cart-icon pe-7s-cart"></i>';
button.html(buttonText).attr('data-tip',response.data.button_text);
button.removeClass('loading');
},error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg);
},
});
});
})(jQuery);
</script>
<?php
}
add_action('wp_ajax_change_add_to_cart_text', 'change_add_to_cart_text');
add_action('wp_ajax_nopriv_change_add_to_cart_text', 'change_add_to_cart_text');
function change_add_to_cart_text(){
$product_id = $_POST['product_id'];
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product_id == $_product_id ) {
$add_to_cart_text = '('.$cart_item['quantity'].')'.' Already in cart';
break;
}
}
}
}
wp_send_json_success(array(
'button_text' => $add_to_cart_text
));
}
This below code only for OP site.
add_filter( 'woocommerce_loop_add_to_cart_link', 'custom_add_quantity_fields', 99, 2 );
function custom_add_quantity_fields($html, $product) {
//add quantity field only to simple products
if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
if ( WC()->cart ) {
$cart = WC()->cart; // Get cart
if ( ! $cart->is_empty() ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$_product_id = $cart_item['product_id'];
if ( $product->get_id() == $_product_id ) {
$data_product_qty = $cart_item['quantity'];
}else{
$data_product_qty = 0;
}
}
}else{
$data_product_qty = 0;
}
}
//rewrite form code for add to cart button
$html = '<form action="' . esc_url( $product->add_to_cart_url() ) . '" class="cart" method="post" enctype="multipart/form-data">';
$html .= woocommerce_quantity_input( array(), $product, false );
$html .= '<button type="submit" data-quantity="1" data-product_id="' . $product->get_id() . '" class="button alt ajax_add_to_cart add_to_cart_button product_type_simple" data-product-qty="'.$data_product_qty.'">' . esc_html( $product->add_to_cart_text() ) . '</button>';
$html .= '</form>';
}
return $html;
}
Tested and works.
woocommerce order page in, I want to filter orders by vendor. I am using the wcfm marketplace plugin.
Vendor name appears here. but when I filter, the orders are not listed.
please help :(woocommerce order page
function wcmp_admin_filter_by_vendor() {
global $typenow;
if ($typenow == 'shop_order') {
$admin_dd_html = '<select name="admin_order_vendor" id="dropdown_admin_order_vendor"><option value="">'.__("Show All Vendors", "dc-woocommerce-multi-vendor").'</option>';
$vendors = get_wcmp_vendors();
if($vendors) :
foreach ($vendors as $vendor) {
$admin_dd_html .= '<option value="'.$vendor->term_id.'">'.$vendor->page_title.'</option>';
}
endif;
$admin_dd_html .= '</select>';
echo $admin_dd_html;
}
}
add_action( 'restrict_manage_posts', 'wcmp_admin_filter_by_vendor');
function get_vendor_parent_order($id) {
$vendor_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_vendor_id',
'meta_value' => $id,
'post_type' => 'shop_order',
'post_status' => 'any',
) );
foreach( $vendor_orders as $vendor_order ) {
$parent_order = wp_get_post_parent_id( $vendor_order->ID );
$parent_orders[] = $parent_order;
}
return $parent_orders;
}
function filter_orders_by_vendor_in_admin_dashboard( $query ) {
if (current_user_can('administrator') && !empty($_REQUEST['admin_order_vendor'])) {
$vendor_term_id = isset($_GET['admin_order_vendor'])?$_GET['admin_order_vendor']:'';
$vendor = get_wcmp_vendor_by_term($vendor_term_id);
$parent_orders = get_vendor_parent_order($vendor->id);
$query['post__in'] = $parent_orders;
return $query;
}
return $query;
}
add_filter( 'wcmp_shop_order_query_request', 'filter_orders_by_vendor_in_admin_dashboard');
function remove_wcmp_order_hook() {
global $WCMp;
remove_action( 'manage_shop_order_posts_custom_column', array($WCMp->order, 'wcmp_show_shop_order_columns'), 99, 2 );
}
add_action('init', 'remove_wcmp_order_hook');
function wcmp_show_shop_order_columns($column, $post_id) {
global $WCMp;
switch ($column) {
case 'wcmp_suborder' :
$wcmp_suborders = $WCMp->order->get_suborders($post_id);
if ($wcmp_suborders) {
echo '<ul class="wcmp-order-vendor" style="margin:0px;">';
foreach ($wcmp_suborders as $suborder) {
$vendor = get_wcmp_vendor(get_post_field('post_author', $suborder->get_id()));
$vendor->ID = get_post_field('post_author', $suborder->get_id());
$vendor_term_id = isset($_GET['admin_order_vendor'])?$_GET['admin_order_vendor']:'';
$filter_vendor = get_wcmp_vendor_by_term($vendor_term_id);
$filter_vendor_id = isset($filter_vendor->id)?$filter_vendor->id:'';
if( $vendor->ID == $filter_vendor_id || $filter_vendor_id == '' ) {
$order_uri = apply_filters('wcmp_admin_vendor_shop_order_edit_url', esc_url('post.php?post=' . $suborder->get_id() . '&action=edit'), $suborder->get_id());
printf('<li><mark class="%s tips" data-tip="%s">%s</mark> <strong>#%s</strong> – <small class="wcmp-order-for-vendor">%s %s</small></li>', sanitize_title($suborder->get_status()), $suborder->get_status(), $suborder->get_status(), $order_uri, $suborder->get_order_number(), _x('for', 'Order table details', 'dc-woocommerce-multi-vendor'), $vendor->page_title
);
}
do_action('wcmp_after_suborder_details', $suborder);
}
echo '<ul>';
} else {
echo '<span class="na">–</span>';
}
break;
}
}
add_action('manage_shop_order_posts_custom_column', 'wcmp_show_shop_order_columns', 99, 2);
My code counts p tags, then insert ads code after x-th p tag.
If I want to count img tags, then insert ads code after x-th img tag how should I do it?
add_filter( 'the_content', 'prefix_insert_post_ads2' );
function prefix_insert_post_ads2( $content ) {
$imgs = preg_match_all("#<img.+>#U", $content, $matches);
$ad_codea = "ads code";
if ( is_single() && ! is_admin() && $imgs >= 4) {
return prefix_insert_after_paragraph2( $ad_codea, 3, $content );
}
return $content;
}
function prefix_insert_after_paragraph2( $insertion, $paragraph_id, $content ) {
$closing_p = '></p>';
$paragraphs = explode( $closing_p, $content );
foreach ($paragraphs as $index => $paragraph) {
if ( trim( $paragraph ) ) {
$paragraphs[$index] .= $closing_p;
}
if ( $paragraph_id == $index + 1 ) {
$paragraphs[$index] .= $insertion;
}
}
return implode( '', $paragraphs );
}
I have solved by myself.
add_filter( 'the_content', 'prefix_insert_post_ads2' );
function prefix_insert_post_ads2( $content ) {
$imgs = preg_match_all("#<img.+>#U", $content, $matches);
preg_match_all('/<img[^>]+>/i',$content, $result);
$ad_codea = '123';
if ($imgs < 4 ) {$result[0][1]='';}
if ( is_single() && ! is_admin()) {
return str_replace($result[0][1], $result[0][1].$ad_codea, $content);
}
}
I have a “gallery” as custom_post_type and “albums” as taxonomry_name
How can i achieve this structure :
mydomain.com/gallery/albums/{taxonomy_term}/{post}
I've tried something like the example below but it didn't work or perhaps i haven't used it properly
add_filter('rewrite_rules_array', 'mmp_rewrite_rules');
function mmp_rewrite_rules($rules) {
$newRules = array();
$newRules['basename/(.+)/(.+)/(.+)/?$'] = 'index.php?gallery=$matches[3]'; // my custom structure will always have the post name as the 4th uri segment
$newRules['basename/(.+)/?$'] = 'index.php?albums=$matches[1]';
return array_merge($newRules, $rules);
}
function filter_post_type_link($link, $post)
{
if ($post->post_type != 'gallery')
return $link;
if ($cats = get_the_terms($post->ID, 'albums'))
{
$link = str_replace('%albums%', get_taxonomy_parents(array_pop($cats)->term_id, 'albums', false, '/', true), $link); // see custom function defined below
}
return $link;
}
add_filter('post_type_link', 'filter_post_type_link', 10, 2);
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = '/', $nicename = false, $visited = array()) {
$chain = '';
$parent = &get_term($id, $taxonomy);
if (is_wp_error($parent)) {
return $parent;
}
if ($nicename)
$name = $parent -> slug;
else
$name = $parent -> name;
if ($parent -> parent && ($parent -> parent != $parent -> term_id) && !in_array($parent -> parent, $visited)) {
$visited[] = $parent -> parent;
$chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $separator, $nicename, $visited);
}
if ($link) {
// nothing, can't get this working :(
} else
$chain .= $name . $separator;
return $chain;
}
I solved my problem by using the code below:
// Add our custom permastructures for custom taxonomy and post
add_action( 'wp_loaded', 'add_album_permastructure' );
function add_album_permastructure() {
global $wp_rewrite;
add_permastruct( 'albums', 'gallery/%albums%', false );
add_permastruct( 'gallery', 'gallery/%albums%/%gallery%', false );
}
// Make sure that all links on the site, include the related texonomy terms
add_filter( 'post_type_link', 'gallery_permalinks', 10, 2 );
function gallery_permalinks( $permalink, $post ) {
if ( $post->post_type !== 'gallery' )
return $permalink;
$terms = get_the_terms( $post->ID, 'albums' );
if ( ! $terms )
return str_replace( '%albums%/', '', $permalink );
$post_terms = array();
foreach ( $terms as $term )
$post_terms[] = $term->slug;
return str_replace( '%albums%', implode( ',', $post_terms ) , $permalink );
}
// Make sure that all term links include their parents in the permalinks
add_filter( 'term_link', 'add_term_parents_to_permalinks', 10, 2 );
function add_term_parents_to_permalinks( $permalink, $term ) {
$term_parents = get_term_parents( $term );
foreach ( $term_parents as $term_parent )
$permlink = str_replace( $term->slug, $term_parent->slug . ',' . $term->slug, $permalink );
return $permlink;
}
// Helper function to get all parents of a term
function get_term_parents( $term, &$parents = array() ) {
$parent = get_term( $term->parent, $term->taxonomy );
if ( is_wp_error( $parent ) )
return $parents;
$parents[] = $parent;
if ( $parent->parent )
get_term_parents( $parent, $parents );
return $parents;
}
Added this to fucntions.php and then refreshed my permalink structure from the Settings -> Permalink