Add fields in Json Response of Posts REST API - php

I want to add a custom field in a response of posts, but when I add new fields after a while it is deleted from the file what I do.
The file that I modify its class-wp-rest-posts-controller.php and I add the new field in prepare_item_for_response function
I add this lines, that works well, but it's deleted after a time
foreach ( $taxonomies as $taxonomy ) {
$base = "other";
$terms = get_the_terms( $post, $taxonomy->name );
$datres = $terms ? array_values( wp_list_pluck( $terms, 'name' ) ) : array();
$data[ $base ] = implode(" ", $datres);
}
Any idea why this happens?

In WordPress you shold not edit core files or core plugins, your changes are deleted becuase the files are updated. The right way do to it is thrugh Hooks and functions from a child theme / your own plugin.
WP Child theme
WP Rest api custom end point docs

Related

How to set product brand when programatically importing WooCommerce product?

I am working on a script to import products from a plain text file that is provided to me by a 3rd party.
I have successfuly imported the products by using WC_Product object, for instance:
//new product
$objProduct = new WC_Product();
$objProduct->set_status("publish");
$objProduct->set_catalog_visibility('visible');
$objProduct->set_sku($product[SKU]);
//and so on
//edit existing product
$product_id = wc_get_product_id_by_sku($product[SKU]);
$objProduct = wc_get_product( $product_id );
$objProduct->set_status("publish");
//...
The problem I'm facing is that I can't seem to find a way to add the brand to the products. When importing from a csv file I managed to import the brand by using a code snippet that I found on the web that runs on the woocommerce_product_import_inserted_product_object hook:
public function process_import( $object, $data ) {
if( isset( $data['product_brand'] ) ){
wp_delete_object_term_relationships( $object->get_id(), 'product_brand' );
$brands = explode( ',', $data['product_brand'] );
foreach( $brands as $brand ) wp_set_object_terms( $object->get_id(), $brand, 'product_brand', true );
}
return $object;
}
I tried using wp_set_object_terms but I get an "invalid taxonomy" error. And I also tried different ways and none of them work and there's no documentation about it.
These are some of the ways I tried:
$objProduct->set_attributes(['product_brand' => $brandId]);
$objProduct->set_attributes(['product_brand' => array($brandId) ]);
$objProduct->set_meta_data(['product_brand' => $brandId]);
$objProduct->set_meta_data(['product_brand' => array($brandId) ]);
$objProduct->set_prop('product_brand', $brandId);
$objProduct->set_prop('product_brand', array($brandId));
Any ideas on how can I set the brand? I'm already clueless and got stuck there.
PS: I tried using both, id and brand name (string).
PS2: My script runs on add_action( 'init', function(){//...}) so everything should be available.
Thanks!
I finally managed to add the custom taxonomy to the product. The problem was that taxonomies were not registered during init hook.
I changed it to wp_loaded hook instead. At that point plugins, theme, etc is ready.
The method I used to set it is wp_set_post_terms.

Usable woocommerce template for custom taxonomy

I created a custom taxonomy book-author for my Woocommerce store, and now I'm trying to conjoint an archive template for it to display frontend like normal Woo archive. Yesterday I found this code, which helped me bring the taxonomy out of the 404 error when clicked, but it returned a shop page with No product notice (though I'd clicked on one of the existed taxonomies).
The point is, book-author taxonomy is a mother of small tags, or "authors", so I need to fix this tag or find a way to make it universal to the mother book-author and all its kids/authors.
add_filter('template_include', 'team_set_template');
function team_set_template( $template ){
if(is_tax('book-author')) :
$taxonomy = 'book-author';
$term = get_query_var($taxonomy);
$prod_term = get_terms($taxonomy, 'slug='.$term.'');
$term_slug = $prod_term[0]->slug;
$t_id = $prod_term[0]->term_id;
$term_meta = get_option( "taxonomy_$t_id" );
$term_meta['bookauthor_access_pin'];
wc_get_template( 'archive-product.php' );
else :
wc_get_template( 'archive-product.php' );
endif;
}
I've tried copying archive-product.php, renaming it taxonomy-book-author.php and putting it in my child theme folder. This seems to be a more better approach, but there was no result - still 404.
The reason why book-author is a tag, not a category because there is no hierarchy for an author. And I know there's plugin for this (Toolset), but they upgraded there free version to paid ones so I'm trying to find a more manual and permanent way.
Thank you in advance, guys.
There is many errors just when reviewing and trying your code…
Note: A filter hooked function needs always to return something.
In your code:
- get_query_var($taxonomy) will return always a term "slug"
- $term_meta['bookauthor_access_pin']; is not usefull and I really don't know what is for.
You say "The reason why book-author is a tag, not a category"… If you have created a custom taxonomy book-author, this can't be a product category or either a product tag (woocommerce custom taxonomies)…
So you should try the following code instead (without any guaranty, as you don't provide all your related code, and this can't be tested):
add_filter('template_include', 'team_set_template');
function team_set_template( $template ){
$taxonomy = 'book-author';
if( ! is_tax( $taxonomy ) ) return $template;
$term_slug = get_query_var($taxonomy);
if ( empty( $term_slug ) ) return $template;
$term = get_term_by('slug', $term_slug, $taxonomy );
if ( is_wp_error( $term ) ) return $template;
$term_id = $prod_term->term_id;
$term_meta = get_option( 'taxonomy_'. $term_id );
// $term_meta['bookauthor_access_pin']; // ???
return wc_locate_template( 'archive-product.php' );
}

Woocommerce Multiple single product templates using single-product.php to redirect

I've been pulling my hair out with this all day, please forgive the short description, I just need to validate my sanity!!
As the title says, I'm trying to create two or three different single-product layouts within woocommerce. The minimum is trying to achieve would be to have multiple single-product folders each with their own name and configurations.
No matter which way I try to override the single-product.php and make this file use logic to check for the product_cat and give out templates accordingly, I either the page not loading or what I write is skipped over and the default is loaded.
So far I've been through the following methods multiple times, trying to piece together what may be outdated code or otherwise causing all the fuss:
WooCommerce - How to create multiple single product template based on category?
Woocommerce single product - template by categories
Creating a different template file for certain Product Categories - Wordpress/Woocommerce?
I was more hoping someone may know something about this that I'm obviously missing as there are many articles out there on what to try and most claim success but I'm unable to do so.
[Update] using template_include code from #helgatheviking
No success just yet but here's where I'm up to;
File structure
team-shops is the category I'm trying to get
/mytheme/woocommerce/single-product.php - no changes
/mytheme/woocommerce/content-single-product.php
/mytheme/woocommerce/single-product-team-shops.php - changed line 37 to<?php wc_get_template_part( 'content', 'single-product-team-shops' ); ?>
/mytheme/woocommerce/content-single-product-team-shops.php - added additional id to #product-id (line 39)
/mytheme/woocommerce/single-product-team-shops/ folder with all single product files to change.
As I said above this isn't working but hopefully with what I've provided the problem may be more obvious.
Thanks again for any help :)
[Think I've got it]
Ok so I think I've something that works, at least for now it seems to, still have some further testing to do but any thoughts more than welcome, this is what I've got so far along with a single-product-team-shops folder in my theme
add_filter( 'woocommerce_locate_template', 'so_25789472_locate_template', 10, 3 );
function so_25789472_locate_template( $template, $template_name, $template_path ){
$term_id = 2854;
$taxonomy_name = 'product_cat';
$term_children = get_term_children( $term_id, $taxonomy_name );
foreach ( $term_children as $child ) {
// on single posts with mock category and only for single-product/something.php templates
if( is_product() && has_term( $child, 'product_cat' ) && strpos( $template_name, 'single-product/') !== false ){
// replace single-product with single-product-mock in template name
$mock_template_name = str_replace("single-product/", "single-product-team-shops/", $template_name );
// look for templates in the single-product-mock/ folder
$mock_template = locate_template(
array(
trailingslashit( $template_path ) . $mock_template_name,
$mock_template_name
)
);
// if found, replace template with that in the single-product-mock/ folder
if ( $mock_template ) {
$template = $mock_template;
}
}}
return $template;
}
Use a single-product-custom.php template for any product in the "custom" category:
add_filter( 'template_include', 'so_43621049_template_include' );
function so_43621049_template_include( $template ) {
if ( is_singular('product') && (has_term( 'custom', 'product_cat')) ) {
$template = get_stylesheet_directory() . '/woocommerce/single-product-custom.php';
}
return $template;
}
NB: If you use the same action hooks in your single-product-custom.php template you will get the same look as the default single-product.php. You could 'rename' all the hooks and then could add existing functions (such as those for add to cart buttons, etc) to the new hooks in order to achieve a totally custom look.

woo commerece short codes not working on all posts

I have created a short code to display short description in woo commerce but it is not working on all posts. It is displaying the short description on some posts and not on others.
Function to create that short code in functions.php
function product_shortdesc_shortcode( $atts ){
// use shortcode_atts() to set defaults then extract() to variables
extract( shortcode_atts( array( 'id' => false ), $atts ) );
// if an $id was passed, and we could get a Post for it, and it's a product....
if ( ! empty( $id ) && null != ( $product = get_post( $id ) ) && $product->post_type = 'product' ){
// apply woocommerce filter to the excerpt
echo apply_filters( 'woocommerce_short_description', $product->post_excerpt );
}
}
// process [product_shortdesc] using product_shortdesc_shortcode()
add_shortcode( 'product_shortdesc', 'product_shortdesc_shortcode' );
The way i am getting the data in my single.php file
$custom = get_post_custom(get_the_ID());
$my_custom_field = $custom['woo_id'];
foreach ( $my_custom_field as $key => $value ) {
echo do_shortcode('[product_shortdesc id='.$value.']');
}
PS: in my normal post i have a custom field which has the value of product id of the product in woo commerece.
Your issue is that you are expecting shortcodes to function which no longer exist. On new installs, these pages won't be created, but if you are updating you may already have those pages in place.
Although the upgrade script does attempt to trash them for you, this might not have happened if they were customised. Delete them. Delete edit-account and change password, then go to your 'my account' page and click the change password/edit account links. You'll be taken to and endpoint which offers the same functionality.
Thanks
Short Code must not echo code instead return the things that needs to be rendered
Change this
echo apply_filters( 'woocommerce_short_description', $product->post_excerpt );
to
return apply_filters( 'woocommerce_short_description', $product->post_excerpt );

Pulling data for WordPress Jetpack plugin contact form

I have a small form on my website, which I created using Jetpack plugin (it has built-in contact form creator).
I want to pull options for select input from my custom-post-type "artist" (using the titles of the posts). Is there a way to do it?
[contact-field label='Artist' type='select' required='1' options='i want my titles go here separated by commas plus "other" option'/]
The code for the field looks like this. I believe I need to do some php+jquery stuff in this page template, but I can't seem to get it.
With some creativity, yes, it's possible :)
We create another Shortcode to create a "virtual" JetPack shortcode.
I tested this using the default post post_type.
add_shortcode( 'my-jet-form', 'so_14003883_jet_form' );
function so_14003883_jet_form( $atts, $content )
{
// Query our post type, change accordingly
$posts = get_posts( array(
'post_type' => 'post',
'numberposts' => -1,
'post_status' => 'publish'
) );
// Build an array of post titles
$titles = array();
foreach( $posts as $post )
{
$titles[] = $post->post_title;
}
// Convert array into comma sepparated string
$posts_select = implode( ',', $titles );
// Make JetPack shortcode
$return = do_shortcode( '[contact-form][contact-field label="Name" type="name" required="1"/][contact-field label="Artist" type="select" options="' . $posts_select . '"/][/contact-form]' );
return $return;
}
Usage:
adjust the desired post type
adjust the do_shortcode part to suit your original shortcode
put the shortcode [my-jet-form] wherever you want
voilà

Categories