Skip to content

Commit

Permalink
Added product safety instructions freetext product option.
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisnissle committed Nov 20, 2024
1 parent 0ea0114 commit 4979aa4
Show file tree
Hide file tree
Showing 24 changed files with 364 additions and 11 deletions.
19 changes: 19 additions & 0 deletions assets/css/admin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,25 @@ span.woocommerce-gzd-input-toggle {
margin-right: 1em;
}

.product_data .form-field-wc-gzd-wp-editor {
display: flex;
flex-wrap: wrap;
padding-bottom: 1em;

label {
float: none;
width: 150px;
margin: 0;
padding: 12px;
padding-right: 0;
}

.wc-gzd-product-editor-wrap {
flex-grow: 1;
padding-right: 20px;
}
}

.wc-gzd-pro, .product_tab_gzd_pro a::after, .product_type_gzd_pro::after {
font-size: 9px;
border-radius: 3px;
Expand Down
27 changes: 27 additions & 0 deletions assets/js/blocks/product-elements/component-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,31 @@ registerBlockComponent( {
/* webpackChunkName: "product-defect-description" */ './defect-description/frontend'
)
),
} );

registerBlockComponent( {
blockName: 'woocommerce-germanized/product-manufacturer',
component: lazy( () =>
import(
/* webpackChunkName: "product-manufacturer" */ './manufacturer/frontend'
)
),
} );

registerBlockComponent( {
blockName: 'woocommerce-germanized/product-safety-attachments',
component: lazy( () =>
import(
/* webpackChunkName: "product-safety-attachments" */ './product-safety-attachments/frontend'
)
),
} );

registerBlockComponent( {
blockName: 'woocommerce-germanized/product-safety-instructions',
component: lazy( () =>
import(
/* webpackChunkName: "product-safety-instructions" */ './safety-instructions/frontend'
)
),
} );
1 change: 1 addition & 0 deletions assets/js/blocks/product-elements/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ import './deposit-packaging-type';
import './defect-description';
import './manufacturer';
import './product-safety-attachments';
import './safety-instructions';

export * from './component-init'
19 changes: 19 additions & 0 deletions assets/js/blocks/product-elements/safety-instructions/block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* External dependencies
*/
import { withProductDataContext } from '@woocommerce/shared-hocs';
import PriceLabelBlock from '../shared/price-label-block';
export default ( props ) => {
props = { ...props, 'labelType': 'safety_instructions' };

// It is necessary because this block has to support serveral contexts:
// - Inside `All Products Block` -> `withProductDataContext` HOC
// - Inside `Products Block` -> Gutenberg Context
// - Inside `Single Product Template` -> Gutenberg Context
// - Without any parent -> `WithSelector` and `withProductDataContext` HOCs
// For more details, check https://github.com/woocommerce/woocommerce-blocks/pull/8609
if ( props.isDescendentOfSingleProductTemplate ) {
return <PriceLabelBlock { ...props } />;
}
return withProductDataContext( PriceLabelBlock )( props );
};
65 changes: 65 additions & 0 deletions assets/js/blocks/product-elements/safety-instructions/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* External dependencies
*/
import {
AlignmentToolbar,
BlockControls,
useBlockProps,
} from '@wordpress/block-editor';
import { useEffect } from '@wordpress/element';

/**
* Internal dependencies
*/
import Block from './block';
import { useIsDescendentOfSingleProductTemplate } from '../shared/use-is-descendent-of-single-product-template';
const Edit = ( {
attributes,
setAttributes,
context,
} ) => {
const blockProps = useBlockProps();
const blockAttrs = {
...attributes,
...context,
};
const isDescendentOfQueryLoop = Number.isFinite( context.queryId );

let { isDescendentOfSingleProductTemplate } =
useIsDescendentOfSingleProductTemplate( { isDescendentOfQueryLoop } );

if ( isDescendentOfQueryLoop ) {
isDescendentOfSingleProductTemplate = false;
}

useEffect(
() =>
setAttributes( {
isDescendentOfQueryLoop,
isDescendentOfSingleProductTemplate,
} ),
[
isDescendentOfQueryLoop,
isDescendentOfSingleProductTemplate,
setAttributes,
]
);

return (
<>
<BlockControls>
<AlignmentToolbar
value={ attributes.textAlign }
onChange={ ( textAlign ) => {
setAttributes( { textAlign } );
} }
/>
</BlockControls>
<div { ...blockProps }>
<Block { ...blockAttrs } />
</div>
</>
);
};

export default Edit;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Internal dependencies
*/
import Block from './block';
export default Block;
38 changes: 38 additions & 0 deletions assets/js/blocks/product-elements/safety-instructions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* External dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
import { page, Icon } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
import { getSetting } from '@germanized/settings';

/**
* Internal dependencies
*/
import sharedConfig from '../shared/config';
import edit from './edit';

const { ancestor, ...configuration } = sharedConfig;

const blockConfig = {
...configuration,
apiVersion: 2,
title: __( 'Safety instructions', 'woocommerce-germanized' ) + ( ! getSetting( 'isPro' ) ? ' (Pro)' : '' ),
description: __( 'Inserts the product\'s safety instructions.', 'woocommerce-germanized' ),
usesContext: [ 'query', 'queryId', 'postId' ],
icon: { src: <Icon
icon={ page }
className="wc-block-editor-components-block-icon"
/> },

supports: {
...sharedConfig.supports,
...( {
__experimentalSelector:
'.wp-block-woocommerce-gzd-product-safety-instructions .wc-gzd-block-components-product-safety-instructions',
} )
},
edit,
};

registerBlockType( 'woocommerce-germanized/product-safety-instructions', blockConfig );
9 changes: 9 additions & 0 deletions assets/js/blocks/product-elements/shared/price-label-block.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const getPreviewData = ( labelType, productData, isDescendentOfSingleProductTemp
'deposit_packaging_type_html': '',
'manufacturer_html': '',
'product_safety_attachments_html': '',
'safety_instructions_html': '',
};

const prices = productData.prices;
Expand Down Expand Up @@ -111,6 +112,14 @@ const getPreviewData = ( labelType, productData, isDescendentOfSingleProductTemp
</ul>
</>
);
} else if ( 'safety_instructions' === labelTypeData ) {
formattedPreview = (
<>
<p>
{ _x( 'Sample safety instructions for a certain product.', 'preview', 'woocommerce-germanized' ) }<br/>
</p>
</>
);
}

return {
Expand Down
2 changes: 2 additions & 0 deletions assets/js/static/add-to-cart-variation.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@
form.getElementOrBlock( form, 'manufacturer-heading', '.wc-gzd-product-manufacturer-heading' ).wc_gzd_set_content( variation.manufacturer_heading );
form.getElementOrBlock( form, 'product_safety_attachments', '.product-safety-attachments' ).wc_gzd_set_content( variation.product_safety_attachments );
form.getElementOrBlock( form, 'product-safety-attachments-heading', '.wc-gzd-product-safety-attachments-heading' ).wc_gzd_set_content( variation.product_safety_attachments_heading );
form.getElementOrBlock( form, 'safety_instructions', '.safety-instructions' ).wc_gzd_set_content( variation.safety_instructions );
form.getElementOrBlock( form, 'safety-instructions-heading', '.wc-gzd-product-safety-instructions-heading' ).wc_gzd_set_content( variation.safety_instructions_heading );

form.getElementOrBlock( form, 'deposit', '.deposit-amount' ).wc_gzd_set_content( hasDisplayPrice ? variation.deposit_amount : '' );
form.getElementOrBlock( form, 'deposit-packaging-type', '.deposit-packaging-type' ).wc_gzd_set_content( hasDisplayPrice ? variation.deposit_packaging_type : '' );
Expand Down
21 changes: 20 additions & 1 deletion includes/abstracts/abstract-wc-gzd-product.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public function get_manufacturer_slug( $context = 'view' ) {
}

public function has_product_safety_information() {
return apply_filters( 'woocommerce_gzd_product_has_safety_information', ( $this->get_safety_attachment_ids() || $this->get_manufacturer() ) );
return apply_filters( 'woocommerce_gzd_product_has_safety_information', ( $this->get_safety_attachment_ids() || $this->get_manufacturer() || $this->get_safety_instructions() ) );
}

public function set_manufacturer_slug( $slug ) {
Expand Down Expand Up @@ -666,6 +666,21 @@ public function get_defect_description( $context = 'view' ) {
return $this->get_prop( 'defect_description', $context );
}

public function get_safety_instructions( $context = 'view' ) {
return $this->get_prop( 'safety_instructions', $context );
}

/**
* @return string
*/
public function get_formatted_safety_instructions( $context = 'view' ) {
if ( $instructions = $this->get_safety_instructions( $context ) ) {
return wpautop( do_shortcode( wp_kses_post( htmlspecialchars_decode( $instructions ) ) ) );
}

return '';
}

public function get_cart_description( $context = 'view' ) {
return $this->get_mini_desc();
}
Expand Down Expand Up @@ -908,6 +923,10 @@ public function set_food_description( $description ) {
$this->set_prop( 'food_description', $description );
}

public function set_safety_instructions( $instructions ) {
$this->set_prop( 'safety_instructions', $instructions );
}

public function set_unit_price( $price ) {
$this->set_prop( 'unit_price', wc_format_decimal( $price ) );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,11 @@ public static function output( $loop, $variation_data, $variation ) {
?>
</p>

<p class="form-row form-row-full">
<label for="variable_safety_instructions<?php echo esc_attr( $loop ); ?>"><?php echo esc_html__( 'Safety instructions', 'woocommerce-germanized' ); ?></label>
<textarea rows="2" style="width: 100%" name="variable_safety_instructions[<?php echo esc_attr( $loop ); ?>]" placeholder="<?php echo esc_attr( $gzd_parent_product ? $gzd_parent_product->get_safety_instructions( 'edit' ) : '' ); ?>" id="variable_safety_instructions<?php echo esc_attr( $loop ); ?>"><?php echo wp_kses_post( htmlspecialchars_decode( $gzd_product->get_safety_instructions( 'edit' ) ) ); ?></textarea>
</p>

<p class="form-row form-row-full">
<label><?php esc_html_e( 'Safety documents', 'woocommerce-germanized' ); ?></label>

Expand Down Expand Up @@ -585,6 +590,7 @@ public static function save( $variation_id, $i ) {
'_gtin' => '',
'_mpn' => '',
'_safety_attachment_ids' => '',
'_safety_instructions' => '',
'_warranty_attachment_id' => '',
'_nutrient_ids' => '',
'_nutrient_reference_value' => '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,24 @@ public static function output() {
<?php self::manufacturer_select_field( array( 'term' => $manufacturer ) ); ?>
</p>

<div class="form-field form-field-wc-gzd-wp-editor">
<label for="_safety_instructions"><?php esc_html_e( 'Safety instructions', 'woocommerce-germanized' ); ?></label>
<div class="wc-gzd-product-editor-wrap">
<?php
wp_editor(
htmlspecialchars_decode( $_gzd_product->get_safety_instructions( 'edit' ) ),
'_safety_instructions',
array(
'textarea_name' => '_safety_instructions',
'textarea_rows' => 2,
'media_buttons' => false,
'teeny' => apply_filters( 'woocommerce_gzd_product_wp_editor_use_teeny', true ),
)
);
?>
</div>
</div>

<p class="form-field wc-gzd-product-upload-wrapper" id="safety_attachments">
<label for="upload_safety_attachment_ids"><?php esc_html_e( 'Safety documents', 'woocommerce-germanized' ); ?></label>

Expand Down Expand Up @@ -982,6 +1000,7 @@ public static function get_fields() {
'_defect_description' => '',
'_warranty_attachment_id' => '',
'_safety_attachment_ids' => '',
'_safety_instructions' => '',
'_gtin' => '',
'_mpn' => '',
'delivery_time' => '',
Expand Down Expand Up @@ -1020,6 +1039,7 @@ protected static function get_field_sanitization_type( $field ) {
'_food_place_of_origin',
'_ingredients',
'_defect_description',
'_safety_instructions',
'_mini_desc',
);

Expand Down Expand Up @@ -1361,6 +1381,10 @@ public static function save_product_data( &$product, $data, $is_variation = fals
$gzd_product->set_defect_description( '' === $data['_defect_description'] ? '' : wc_gzd_sanitize_html_text_field( $data['_defect_description'] ) );
}

if ( isset( $data['_safety_instructions'] ) ) {
$gzd_product->set_safety_instructions( '' === $data['_safety_instructions'] ? '' : wc_gzd_sanitize_html_text_field( $data['_safety_instructions'] ) );
}

if ( isset( $data['_nutrient_ids'] ) ) {
$gzd_product->set_nutrient_ids( (array) wc_clean( $data['_nutrient_ids'] ) );
}
Expand Down
1 change: 1 addition & 0 deletions includes/class-wc-gzd-product-variation.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class WC_GZD_Product_Variation extends WC_GZD_Product {
'warranty_attachment_id',
'manufacturer_slug',
'safety_attachment_ids',
'safety_instructions',
'gtin',
'mpn',
'deposit_type',
Expand Down
13 changes: 13 additions & 0 deletions includes/class-wc-gzd-shortcodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public static function init() {
'gzd_product_safety_information' => __CLASS__ . '::gzd_product_safety_information',
'gzd_product_manufacturer' => __CLASS__ . '::gzd_product_manufacturer',
'gzd_product_safety_attachments' => __CLASS__ . '::gzd_product_safety_attachments',
'gzd_product_safety_instructions' => __CLASS__ . '::gzd_product_safety_instructions',
'gzd_product_deposit' => __CLASS__ . '::gzd_product_deposit',
'gzd_product_deposit_packaging_type' => __CLASS__ . '::gzd_product_deposit_packaging_type',
'gzd_email_legal_page_attachments' => __CLASS__ . '::gzd_email_legal_page_attachments',
Expand Down Expand Up @@ -181,6 +182,18 @@ public static function gzd_product_safety_attachments( $atts ) {
return apply_filters( 'woocommerce_gzd_shortcode_product_safety_attachments_html', self::get_gzd_product_shortcode( $atts, 'woocommerce_gzd_template_single_product_safety_attachments' ), $atts );
}

public static function gzd_product_safety_instructions( $atts ) {
/**
* Filter shortcode product safety instructions output.
*
* @param string $html The output.
* @param array $atts The shortcode arguments.
*
* @since 3.18.0
*/
return apply_filters( 'woocommerce_gzd_shortcode_product_safety_instructions_html', self::get_gzd_product_shortcode( $atts, 'woocommerce_gzd_template_single_safety_instructions' ), $atts );
}

public static function gzd_product_manufacturer( $atts ) {
/**
* Filter shortcode product manufacturer output.
Expand Down
3 changes: 2 additions & 1 deletion includes/export/class-wc-gzd-product-export.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public function get_columns() {
'unit' => _x( 'Unit', 'exporter', 'woocommerce-germanized' ),
'manufacturer' => _x( 'Manufacturer', 'exporter', 'woocommerce-germanized' ),
'safety_attachment_ids' => _x( 'Safety attachments ids', 'exporter', 'woocommerce-germanized' ),
'safety_instructions' => _x( 'Safety instructions', 'exporter', 'woocommerce-germanized' ),
'unit_base' => _x( 'Unit base', 'exporter', 'woocommerce-germanized' ),
'unit_product' => _x( 'Unit product', 'exporter', 'woocommerce-germanized' ),
'mini_desc' => _x( 'Cart description', 'exporter', 'woocommerce-germanized' ),
Expand Down Expand Up @@ -242,7 +243,7 @@ public function export_column( $value, $product ) {
$filter = current_filter();
$column_name = str_replace( 'woocommerce_product_export_product_column_', '', $filter );
$gzd_product = wc_gzd_get_product( $product );
$is_html_field = in_array( $column_name, array( 'ingredients', 'food_description', 'food_place_of_origin', 'food_distributor', 'defect_description', 'mini_desc' ), true );
$is_html_field = in_array( $column_name, array( 'ingredients', 'food_description', 'food_place_of_origin', 'food_distributor', 'defect_description', 'mini_desc', 'safety_instructions' ), true );

/**
* Delivery time needs special handling
Expand Down
Loading

0 comments on commit 4979aa4

Please sign in to comment.