Using str_replace to change text within PHP template - php

I am trying to change some text on my WooCommerce-based WP Website.
Essentially, through a filter using the str_replace I'm trying to change the text '%s reviews for %s' to be something else.
This text is included in the single-product-reviews.php file.
See below:
<h2><?php
if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' && ($count = $product->get_review_count() ) )
printf( _n( '%s review for %s', '%s reviews for %s', $count, 'woocommerce' ), $count, get_the_title() );
else
_e( 'Reviews', 'woocommerce' );
?></h2>
In order to do this I'm trying to use the following, but it doesn't seem to work. I'm not sure what string I should be targetting.
function lnz_replace_content()
{
echo str_replace("%s reviews for %s","%s comments about %s", $product);
}
add_filter('init','lnz_replace_content');'
I've had a go with gettext too but that doesn't seem to work either in this case.
OP Update
I've had a go at using gettext, but it doesn't seem to work in this case.
As previously mentioned, I'm targeting the following code (in single-product-review.php)
<h2><?php
if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' && ( $count = $product->get_review_count() ) )
printf( _n( '%s review for %s', '%s reviews for %s', $count, 'woocommerce' ), $count, get_the_title() );
else
_e( 'Reviews', 'woocommerce' );
?></h2>
If I use 'gettext' to replace 'Reviews' it works fine. If I try and get it to replace '% review for %s' it doesn't work.
Any ideas why.

you can do this with 2 ways:
1) change in language file:
msgid "%s reviews for %s"
msgstr "%s comments about %s"
msgid "%s review for %s"
msgstr "%s comment about %s"
2) chang code:
<h2><?php
if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' && ($count = $product->get_review_count() ) )
printf( _n( '%s review for %s', '%s reviews for %s', $count, 'woocommerce' ), $count, get_the_title() );
else
_e( 'Reviews', 'woocommerce' );
?></h2>
to
<h2><?php
if ( get_option( 'woocommerce_enable_review_rating' ) === 'yes' && ($count = $product->get_review_count() ) )
printf( _n( '%s comment about %s', '%s comment about %s', $count, 'woocommerce' ), $count, get_the_title() );
else
_e( 'Reviews', 'woocommerce' );
?></h2>

You can use the template overrides to override single-product-reviews.php by copying it into your theme's woocommerce folder.
or you can filter gettext from your theme's functions.php
add_filter( 'gettext', 'theme_change_comment_field_names', 20, 3 );
/**
* Change comment form default field names.
*
* #link http://codex.wordpress.org/Plugin_API/Filter_Reference/gettext
*/
function theme_change_comment_field_names( $translated_text, $text, $domain ) {
if ( is_singular() ) {
switch ( $translated_text ) {
case '%s reviews for %s' :
$translated_text = __( '%s comments for %s', 'theme_text_domain' );
break;
case 'Related Products' :
$translated_text = __( 'Related Opportunities', 'theme_text_domain' );
break;
}
}
return $translated_text;
}

Related

How to make changes to a column in WooCommerce admin orders list without modifying the core file

Before asking this question I noticed that there are other similar questions on Stack Overflow without an accepted answer. Although each issue has a different context, I believe there is something in common.
I found these questions but they didn't help:
Overriding WooCommerce function in includes folder
Override woocommerce files from includes folder
How to override a function in Woocommerce WC_Order_Data_Store_CPT Class
I need to make some changes to the WooCommerce core file, but I don't want to touch the original files. So is there a way to override the functions of the files located in the includes folder?
Specifically, the file is this:
https://woocommerce.github.io/code-reference/files/woocommerce-includes-admin-list-tables-class-wc-admin-list-table-orders.html
I need to modify this piece of code (lines 235 and 237), the match would be the last two printf. My question is if this piece of code can be modified with some filter or functions in functions.php file, so if WooCommerce updates I don't lose the changes.
/**
* Render column: order_status.
*/
protected function render_order_status_column() {
$tooltip = '';
$comment_count = get_comment_count( $this->object->get_id() );
$approved_comments_count = absint( $comment_count['approved'] );
if ( $approved_comments_count ) {
$latest_notes = wc_get_order_notes(
array(
'order_id' => $this->object->get_id(),
'limit' => 1,
'orderby' => 'date_created_gmt',
)
);
$latest_note = current( $latest_notes );
if ( isset( $latest_note->content ) && 1 === $approved_comments_count ) {
$tooltip = wc_sanitize_tooltip( $latest_note->content );
} elseif ( isset( $latest_note->content ) ) {
/* translators: %d: notes count */
$tooltip = wc_sanitize_tooltip( $latest_note->content . '<br/><small style="display:block">' . sprintf( _n( 'Plus %d other note', 'Plus %d other notes', ( $approved_comments_count - 1 ), 'woocommerce' ), $approved_comments_count - 1 ) . '</small>' );
} else {
/* translators: %d: notes count */
$tooltip = wc_sanitize_tooltip( sprintf( _n( '%d note', '%d notes', $approved_comments_count, 'woocommerce' ), $approved_comments_count ) );
}
}
if ( $tooltip ) {
printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), wp_kses_post( $tooltip ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) );
} else {
printf( '<mark class="order-status %s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) );
}
}
What you can do is remove the original order-status column, and then add a new custom order-status column in the same location:
function filter_manage_edit_shop_order_columns( $columns ) {
// Loop trough existing columns
foreach ( $columns as $key => $name ) {
// NOT equal
if ( $key !== 'order_status' ) {
$new_columns[$key] = $name;
} else {
// Replace with custom column
$new_columns['my_order_status'] = __( 'Status', 'woocommerce' );
}
}
return $new_columns;
}
add_filter( 'manage_edit-shop_order_columns', 'filter_manage_edit_shop_order_columns', 10, 1 );
Then you take over the existing code, and adjust it where desired:
function action_manage_shop_order_posts_custom_column( $column, $post_id ) {
// Get order
$order = wc_get_order( $post_id );
/**
* Render column: order_status.
*/
if ( $column == 'my_order_status' ) {
$tooltip = '';
$comment_count = get_comment_count( $order->get_id() );
$approved_comments_count = absint( $comment_count['approved'] );
if ( $approved_comments_count ) {
$latest_notes = wc_get_order_notes(
array(
'order_id' => $order->get_id(),
'limit' => 1,
'orderby' => 'date_created_gmt',
)
);
$latest_note = current( $latest_notes );
if ( isset( $latest_note->content ) && 1 === $approved_comments_count ) {
$tooltip = wc_sanitize_tooltip( $latest_note->content );
} elseif ( isset( $latest_note->content ) ) {
/* translators: %d: notes count */
$tooltip = wc_sanitize_tooltip( $latest_note->content . '<br/><small style="display:block">' . sprintf( _n( 'Plus %d other note', 'Plus %d other notes', ( $approved_comments_count - 1 ), 'woocommerce' ), $approved_comments_count - 1 ) . '</small>' );
} else {
/* translators: %d: notes count */
$tooltip = wc_sanitize_tooltip( sprintf( _n( '%d note', '%d notes', $approved_comments_count, 'woocommerce' ), $approved_comments_count ) );
}
}
if ( $tooltip ) {
printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), wp_kses_post( $tooltip ), wp_kses( wc_get_order_status_name( $order->get_status() ) ) );
} else {
printf( '<mark class="order-status %s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), wp_kses( wc_get_order_status_name( $order->get_status() ) ) );
}
}
}
add_action( 'manage_shop_order_posts_custom_column' , 'action_manage_shop_order_posts_custom_column', 10, 2 );
For your specific case you can override the whole class, if you look at the source code it starts with:
if ( class_exists( 'WC_Admin_List_Table_Orders', false ) ) {
return;
}
//rest of the code
That means that when WC loads that .php file if the class already exists it exit and live with your implementation.
This is a good compromise between directly modifying a wc core file and having your chance to edit the code.
Be careful tho, wordpress doesn't offer a real priority system when loading plugins, to have this override have effect you have to include the new file containing your implementation BEFORE wc loading time span.
The best dirty way is to create a plugin called something like "aa-my-wc-override" and make it an easy plugin that just includes a file containing the new WC_Admin_List_Table_Orders class implementation. I suggest this way because Wordpress loads the plugin alphabetically.
Another possibile way, if you just need to edit some HTML, maybe to inject some .js file in the backend that takes care of the needed modification. Maybe using AJAX or pure JS, depending on your needs

Change "You cannot add another (product) to your cart" notice in Woocommerce

I can't find a way to change the Woocommerce default message when you try to add another product to your cart marked as sold individually.
I found out that this is how you edit the default success message when adding products to your cart:
add_filter ( 'wc_add_to_cart_message', 'wc_add_to_cart_message_filter', 10, 2 );
function wc_add_to_cart_message_filter($message, $product_id = null) {
$titles[] = get_the_title( $product_id );
$titles = array_filter( $titles );
$added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', sizeof( $titles ), 'woocommerce' ), wc_format_list_of_items( $titles ) );
$message = sprintf( '%s %s %s',
esc_html( $added_text ),
esc_url( wc_get_page_permalink( 'checkout' ) ),
esc_html__( 'Checkout', 'woocommerce' ),
esc_url( wc_get_page_permalink( 'cart' ) ),
esc_html__( 'View Cart', 'woocommerce' ));
return $message;
}
You can use gettext filter hook to change this notice located in WC_Cart add_to_cart() method:
add_filter( 'gettext', 'change_specific_add_to_cart_notice', 10, 3 );
add_filter( 'ngettext', 'change_specific_add_to_cart_notice', 10, 3 );
function change_specific_add_to_cart_notice( $translated, $text, $domain ) {
if( $text === 'You cannot add another "%s" to your cart.' && $domain === 'woocommerce' && ! is_admin() ){
// Replacement text (where "%s" is the dynamic product name)
$translated = __( 'It is not possible to add again "%s"', $domain );
}
return $translated;
}
Code goes on function.php file of your active child theme (or active theme). Tested and works.

How to resolve Strings should have translatable content in Wordpress?

I am trying to fix the linting issue here is code.
function get_the_breadcrumb() {
if ( ! is_front_page() ) {
// Start the breadcrumb with a link to your homepage.
echo '<div class="o__breadcrumb">';
echo '<a href="';
echo esc_html( get_option( 'home' ) );
echo '"> Home';
echo '</a> <span> ';
echo esc_html( Load::atom( 'icons/breadcrumb_arrow' ) );
echo '</span>';
// Check if the current page is a category, an archive or a single page. If so show the category or archive name.
if ( is_category() || is_single() ) {
the_category( 'title_li=' );
} elseif ( is_archive() || is_single() ) {
if ( is_day() ) {
/* translators: %s: text term */
printf( esc_html( __( '%s', 'text_domain' ) ), esc_html( get_the_date() ) );
} elseif ( is_month() ) {
/* translators: %s: text term */
printf( esc_html( __( '%s', 'text_domain' ) ), get_the_date( _x( 'F Y', 'monthly archives date format', 'text_domain' ) ) );
} elseif ( is_year() ) {
/* translators: %s: text term */
printf( esc_html( __( '%s', 'text_domain' ) ), get_the_date( _x( 'Y', 'yearly archives date format', 'text_domain' ) ) );
} else {
esc_attr_e( 'Blog Archives', 'text_domain' );
}
}
// If the current page is a single post, show its title with the separator.
if ( is_single() ) {
echo '<span>';
echo esc_html( Load::atom( 'icons/breadcrumb_arrow' ) );
echo '</span>';
the_title();
}
// If the current page is a static page, show its title.
if ( is_page() ) {
echo the_title();
}
// if you have a static page assigned to be you posts list page. It will find the title of the static page and display it. i.e Home >> Blog.
if ( is_home() ) {
global $post;
$page_for_posts_id = get_option( 'page_for_posts' );
if ( $page_for_posts_id ) {
$post = get_page( $page_for_posts_id );
setup_postdata( $post );
the_title();
rewind_posts();
}
}
echo '</div>';
}
}
Linting response
FOUND 3 ERRORS AFFECTING 3 LINES
----------------------------------------------------------------------
193 | ERROR | Strings should have translatable content
196 | ERROR | Strings should have translatable content
199 | ERROR | Strings should have translatable content
Line number 193
printf( esc_html( __( '%s', 'text_domain' ) ), esc_html( get_the_date() ) );
Line number 196
printf( esc_html( __( '%s', 'text_domain' ) ), get_the_date( _x( 'F Y', 'monthly archives date format', 'text_domain' ) ) );
Line number 199
printf( esc_html( __( '%s', 'text_domain' ) ), get_the_date( _x( 'Y', 'yearly archives date format', 'text_domain' ) ) );
It's because you have %s as the text inside the translation function call __(...), which is not translatable.
Instead you should have your printf() call inside the translation call, so the translator can actually see what the heck you're trying to translate.
But, you shouldn't be trying to translate the date this way. It won't work because the date is always changing and the way __() translation works is by matching the exact string passed in to a translation. According to this answer, you should use date_i18n
And why are you trying to translate the date formatting strings you are passing to get_the_date, those are code values used by php, they don't change based on where you are. Translating these can only cause you problems.
You also call esc_html twice on line 193.
So, instead you should write your lines of code like so:
Line number 193
esc_html( date_i18n( get_the_date() ) );
Line number 196
esc_html( date_i18n( get_the_date('F Y') ) );
Line number 199
esc_html( date_i18n( get_the_date( 'Y' ) ) );
Note, I don't think the esc_html calls are actually necessary here, since the internals is just WordPress functions that only return dates... no html should be in there

WP get locale in plugin code

Hy i am trying to get current language inside of plugin code. I have try with get_locale() but it always give me just en_us. I have try to find solution on WordPress code references but did not found anything that work.
In question is plugin WooCommerce, file wc-cart-functions.php
There are lines:
$added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', sizeof( $titles ), 'woocommerce' ), wc_format_list_of_items( $titles ) );
and
$message = sprintf( '%s %s', esc_url( wc_get_page_permalink( 'cart' ) ), esc_html__( 'View Cart', 'woocommerce' ), esc_html( $added_text ) );
I want to get this result:
if($language == 'hr') { $added_text = sprintf( _n( '%s je dodan u košaricu.', '%s su dodani u košaricu.', sizeof( $titles ), 'woocommerce' ), wc_format_list_of_items( $titles ) );
} else { $added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', sizeof( $titles ), 'woocommerce' ), wc_format_list_of_items( $titles ) ); }
if($language == 'hr') { $message = sprintf( '%s %s', esc_url( home_url().'/kosarica' ), esc_html__( 'Pogledaj košaricu', 'woocommerce' ), esc_html( $added_text ) );
} else { $message = sprintf( '%s %s', esc_url( wc_get_page_permalink( 'cart' ) ), esc_html__( 'View Cart', 'woocommerce' ), esc_html( $added_text ) ); }
Normally, i would solve this by geting language from URL, but that website doesnt have language in URL.
If your using the polylang plugin, see this site: https://polylang.wordpress.com/documentation/documentation-for-developers/functions-reference/ .. you probably need to use pll_current_language() which should return current language.
<?php
$language = pll_current_language('slug');
if($language == 'hr') {
$added_text = sprintf( _n( '%s je dodan u košaricu.', '%s su dodani u košaricu.', sizeof( $titles ), 'woocommerce' ), wc_format_list_of_items( $titles ) );} else {
$added_text = sprintf( _n( '%s has been added to your cart.', '%s have been added to your cart.', sizeof( $titles ), 'woocommerce' ), wc_format_list_of_items( $titles ) ); }
if($language == 'hr') {
$message = sprintf( '%s %s', esc_url( home_url().'/kosarica' ), esc_html__( 'Pogledaj košaricu', 'woocommerce' ), esc_html( $added_text ) );} else {
$message = sprintf( '%s %s', esc_url( wc_get_page_permalink( 'cart' ) ), esc_html__( 'View Cart', 'woocommerce' ), esc_html( $added_text ) ); }

Woocommerce display taxonomy title in current taxonomy archive page

So, I have in the menu a link to a taxonomy archive that shows every product associated with that taxonomy.
Wordpress shows the correct page-title in category/tag archive, instead it shows the latest product title in the taxonomy page, that is nonsense.
I know that there's something about archive.php
elseif ( is_category() )
$title = sprintf( __( 'Category Archives: %s', 'mirage' ), '<span>' . single_cat_title( '', false ) . '</span>' );
elseif ( is_tag() )
$title = sprintf( __( 'Tag Archives: %s', 'mirage' ), '<span>' . single_tag_title( '', false ) . '</span>' );
elseif ( is_day() )
$title = sprintf( __( 'Daily Archives: %s', 'mirage' ), '<span>' . get_the_date() . '</span>' );
I tried to add an is_tax() etc. but nothing seems to reflect on the frontend.
I need to get the current taxonomy name and put it in the same page title.
Hope I made it clear. Thanks.
You can use:
elseif ( is_product_taxonomy() )
single_term_title();
endif;

Categories