File: /home/royaltuning/www/public/wp-content/plugins/easysales/includes/EasySales.php
<?php
use EasySales\Request\Request;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class EasySales {
/**
* @var ApiController
*/
private $apiController;
/**
* @var ProductTransformer
*/
private $productTransformer;
/**
* @var OrderTransformer
*/
private $orderTransformer;
/**
* EasySales constructor.
* @param ApiController $apiController
* @param ProductTransformer $productTransformer
* @param OrderTransformer $orderTransformer
*/
public function __construct(ApiController $apiController, ProductTransformer $productTransformer, OrderTransformer $orderTransformer) {
// Hook into the admin menu
add_action('admin_menu', [$this, 'create_plugin_settings_page']);
add_action('admin_init', [$this, 'display_options']);
add_action('rest_api_init', [$this, 'add_api_route']);
// Product hooks
add_action('woocommerce_update_product', [$this, 'update_product']);
// Categories hooks
add_action('created_product_cat', [$this, 'add_category'], 10, 1);
add_action('edited_product_cat', [$this, 'update_category'], 10, 1);
// Attributes hooks
add_action('woocommerce_attribute_added', [$this, 'add_attribute'], 10, 2);
add_action('woocommerce_attribute_updated', [$this, 'update_attribute'], 10, 2);
// Orders hooks
add_action('woocommerce_checkout_order_processed', [$this, 'new_order'], 1, 1);
add_action('woocommerce_order_edit_status', [$this, 'update_order'], 1, 2);
// EAN Variations
add_action('woocommerce_product_after_variable_attributes', [$this, 'variation_ean_field' ], 10, 3);
add_action('woocommerce_save_product_variation', [$this, 'save_variations' ], 10, 2);
// Set easysales api URL
add_option('easysales-api-url', EASYSALES_API_URL);
$this->apiController = $apiController;
$this->apiController->setPluginInstance($this);
$this->productTransformer = $productTransformer;
$this->orderTransformer = $orderTransformer;
}
/**
* Adds easySales 2ea Settings Page
*/
public function create_plugin_settings_page() {
add_menu_page(
'easySales Settings',
'easySales',
'manage_options',
'easysales-settings',
[$this, 'plugin_settings_page_content'],
'dashicons-chart-area',
100
);
}
public function plugin_settings_page_content() {
?>
<div class="wrap">
<h1>easySales Settings</h1>
<div class="card" style="max-width: initial;">
<div class="card-body">
<form method="post" action="options.php">
<?php
do_settings_sections('easysales-options-page');
settings_fields('easysales-options');
// Add the submit button to serialize the options
submit_button();
?>
</form>
</div>
</div>
</div>
<?php
}
public function display_options()
{
//section name, display name, callback to print description of section, page to which section is attached.
add_settings_section('easysales-options', null, null, 'easysales-options-page');
//setting name, display name, callback to print form element, page in which field is displayed, section to which it belongs.
//last field section is optional.
add_settings_field('token', 'Token', [$this, 'display_token_form_element'], 'easysales-options-page', 'easysales-options');
add_settings_field('brand', 'Brand Attribute', [$this, 'display_brand_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('ean-source', 'What should be the EAN source?', [$this, 'display_ean_source_select'], 'easysales-options-page', 'easysales-options');
if ($this->ean_source() == '1') {
add_settings_field('ean', 'EAN Metadata Key', [$this, 'display_ean_metadata_key'], 'easysales-options-page', 'easysales-options');
} else if ($this->ean_source() == '2') {
add_settings_field('ean', 'EAN Attribute', [$this, 'display_ean_select'], 'easysales-options-page', 'easysales-options');
}
add_settings_field('default-brand', 'Default Brand', [$this, 'display_default_brand_form_element'], 'easysales-options-page', 'easysales-options');
add_settings_field('warehouse-location', 'Warehouse Location Attribute', [$this, 'display_warehouse_location_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('sku', 'Generate SKU', [$this, 'display_sku_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('invoice-series', 'Invoice Series', [$this, 'display_invoice_series_form_element'], 'easysales-options-page', 'easysales-options');
add_settings_field('disabled-products', 'Send disabled products', [$this, 'display_disabled_products'], 'easysales-options-page', 'easysales-options');
add_settings_field('private-products', 'Send private products', [$this, 'display_private_products'], 'easysales-options-page', 'easysales-options');
add_settings_field('draft-products', 'Send draft products', [$this, 'display_draft_products'], 'easysales-options-page', 'easysales-options');
add_settings_field('description', 'Description type', [$this, 'display_description_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('order-status-map', 'Order status map', [$this, 'display_order_status_map_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('webhook-completed-status', 'What status to use when order is finalized from easySales?', [$this, 'display_webhook_completed_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('webhook-cancelled-status', 'What status to use when order is cancelled from easySales?', [$this, 'display_webhook_cancelled_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('load-order-tax-from', 'Get order tax from', [$this, 'display_load_order_tax_from_select'], 'easysales-options-page', 'easysales-options');
add_settings_field('country-tax', 'From what country we should use the tax rate?', [$this, 'display_country_tax_select'], 'easysales-options-page', 'easysales-options');
//section name, form element name, callback for sanitization
register_setting('easysales-options', 'easysales-token', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-brand', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-ean-source', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-ean', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-metadata-key', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-warehouse-location', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-generate-sku', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-invoice-series', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-default-brand', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-draft-products', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-disabled-products', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-private-products', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-description-type', [$this, 'sanitize']);
/** Create new setting for each status **/
$orderStatusFields = $this->orderTransformer->getOrderStatusMapFields();
foreach($orderStatusFields as $orderStatusField){
register_setting('easysales-options', $orderStatusField, [$this, 'sanitize']);
}
register_setting('easysales-options', 'easysales-webhook-completed-status', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-webhook-cancelled-status', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-load-order-tax-from', [$this, 'sanitize']);
register_setting('easysales-options', 'easysales-country-tax', [$this, 'sanitize']);
}
public function sanitize($option)
{
//sanitize
$option = sanitize_text_field($option);
return $option;
}
public function display_token_form_element()
{
//id and name of form element should be same as the setting name.
?>
<textarea type="text" name="easysales-token" class="large-text" id="easysales-token"><?php echo get_option('easysales-token');?></textarea>
<p>Insert token generated in easySales platform</p>
<?php
}
public function display_invoice_series_form_element()
{
//id and name of form element should be same as the setting name.
?>
<input type="text" name="easysales-invoice-series" class="large-text" id="easysales-invoice-series" value="<?php echo get_option('easysales-invoice-series');?>" />
<p>Insert Invoice Series</p>
<?php
}
public function display_default_brand_form_element()
{
//id and name of form element should be same as the setting name.
?>
<input type="text" name="easysales-default-brand" class="large-text" id="easysales-default-brand" value="<?php echo get_option('easysales-default-brand');?>" />
<p>Default Brand</p>
<?php
}
public function display_brand_select()
{
?>
<select name="easysales-brand" id="easysales-brand">
<option value="" disabled selected>Select your option</option>
<option value="-1" <?php selected(get_option('easysales-brand'), -1) ?>>None</option>
<?php
$attributes = wc_get_attribute_taxonomies();
foreach ($attributes as $attribute) {
echo '<option value="' . $attribute->attribute_name . '" ' . selected(get_option('easysales-brand'), $attribute->attribute_name) .'>' . $attribute->attribute_label .'</option>';
}
?>
</select>
<p>Select which attribute will be used as brand</p>
<?php
}
public function ean_source()
{
$ean = get_option('easysales-ean');
$ean_source = get_option('easysales-ean-source');
if ($ean == '-1') {
return -1;
} else {
// no saved option yet
if ($ean_source === false) {
return 2;
}
}
return $ean_source;
}
public function display_ean_source_select()
{
$ean_source = $this->ean_source();
?>
<select name="easysales-ean-source" id="easysales-ean-source">
<option value="-1" <?php selected($ean_source, -1); ?>>None</option>
<option value="1" <?php selected($ean_source, 1); ?>>Metadata</option>
<option value="2" <?php selected($ean_source, 2); ?>>Attribute</option>
</select>
<?php
}
public function display_ean_select()
{
?>
<select name="easysales-ean" id="easysales-ean">
<option value="" disabled selected>Select your option</option>
<?php
$attributes = wc_get_attribute_taxonomies();
foreach ($attributes as $attribute) {
echo '<option value="' . esc_attr($attribute->attribute_name) . '" ' . selected(get_option('easysales-ean'), $attribute->attribute_name, false) . '>' . esc_html($attribute->attribute_label) . '</option>';
}
?>
</select>
<p>Select which attribute will be used as EAN</p>
<?php
}
public function display_ean_metadata_key()
{
?>
<input type="text" name="easysales-metadata-key" class="large-text" id="easysales-metadata-key" value="<?php echo get_option('easysales-metadata-key');?>" />
<p>Insert EAN Metadata Key</p>
<?php
}
public function display_sku_select()
{
?>
<select name="easysales-generate-sku" id="easysales-generate-sku">
<option value="" disabled selected>Select your option</option>
<option value="1" <?php selected(get_option('easysales-generate-sku'), 1) ?>>Yes</option>
<option value="0" <?php selected(get_option('easysales-generate-sku'), 0) ?>>No</option>
</select>
<p>Use this option to generate unique variation SKU based on main product reference</p>
<?php
}
public function display_disabled_products()
{
?>
<select name="easysales-disabled-products" id="easysales-disabled-products">
<option value="" disabled selected>Select your option</option>
<option value="1" <?php selected(get_option('easysales-disabled-products'), 1) ?>>Yes</option>
<option value="0" <?php selected(get_option('easysales-disabled-products'), 0) ?>>No</option>
</select>
<p>Use this option to send disabled products.</p>
<?php
}
public function display_private_products()
{
?>
<select name="easysales-private-products" id="easysales-private-products">
<option value="" disabled selected>Select your option</option>
<option value="1" <?php selected(get_option('easysales-private-products'), 1) ?>>Yes</option>
<option value="0" <?php selected(get_option('easysales-private-products'), 0) ?>>No</option>
</select>
<p>Use this option to send private products.</p>
<?php
}
public function display_draft_products()
{
?>
<select name="easysales-draft-products" id="easysales-draft-products">
<option value="" disabled selected>Select your option</option>
<option value="1" <?php selected(get_option('easysales-draft-products'), 1) ?>>Yes</option>
<option value="0" <?php selected(get_option('easysales-draft-products'), 0) ?>>No</option>
</select>
<p>Use this option to send draft products.</p>
<?php
}
public function display_warehouse_location_select()
{
?>
<select name="easysales-warehouse-location" id="easysales-warehouse-location">
<option value="" disabled selected>Select your option</option>
<option value="-1" <?php selected(get_option('easysales-warehouse-location'), -1) ?>>None</option>
<?php
$attributes = wc_get_attribute_taxonomies();
foreach ($attributes as $attribute) {
echo '<option value="' . $attribute->attribute_name . '" ' . selected(get_option('easysales-warehouse-location'), $attribute->attribute_name) .'>' . $attribute->attribute_label .'</option>';
}
?>
</select>
<p>Select which attribute will be used as warehouse location</p>
<?php
}
public function display_description_select()
{
?>
<select name="easysales-description-type" id="easysales-description-type">
<option value="" disabled selected>Select your option</option>
<option value="0" <?php selected(get_option('easysales-description-type'), 0) ?>>Description</option>
<option value="1" <?php selected(get_option('easysales-description-type'), 1) ?>>Short description</option>
</select>
<p>Use this option if you want to send short description to easySales</p>
<?php
}
public function display_order_status_map_select()
{
$defaultStatusMap = $this->orderTransformer->getDefaultStatusMap();
$wooUnmappedStatuses = $this->orderTransformer->getWooUnmappedStatuses();
$easySalesOrderStatuses = $this->orderTransformer->getEasySalesOrderStatuses();
foreach($wooUnmappedStatuses as $unmappedStatus){
$defaultStatusMap[$unmappedStatus] = $easySalesOrderStatuses['New'];
}
?>
<div>
<div style="display: flex;align-items: center; justify-content: flex-start; margin-bottom: 10px;">
<span style="display: block; width: 250px; text-decoration: underline;">woocommerce status</span>
<span style="text-decoration: underline;">easySales status</span>
</div>
<?php foreach (array_keys($defaultStatusMap) as $defaultStatusKey) { ?>
<?php
$statusName = wc_get_order_status_name($defaultStatusKey);
$wooOrderStatuses = wc_get_order_statuses();
if (isset($wooOrderStatuses[$defaultStatusKey]) && $statusName === $defaultStatusKey) {
$statusName = $wooOrderStatuses[$defaultStatusKey];
}
?>
<div style="display: flex;align-items: center; justify-content: flex-start; margin-bottom: 5px;">
<span style="display: block; width: 250px;"><strong><?php echo $statusName; ?></strong></span>
<?php
$mappingKey = $this->orderTransformer->getOrderStatusMapKey($defaultStatusKey);
$existingMapping = get_option($mappingKey);
if($existingMapping === false){
$existingMapping = null;
$existingMapping = $defaultStatusMap[$defaultStatusKey];
}
?>
<select name="<?php echo $mappingKey; ?>" id="<?php echo $mappingKey; ?>">
<option value="" disabled selected>Select your option</option>
<?php foreach ($easySalesOrderStatuses as $easySalesStatusName => $easySalesStatusValue) { ?>
<option
value="<?php echo $easySalesStatusValue; ?>"
<?php selected($existingMapping, $easySalesStatusValue); ?>
>
<?php echo $easySalesStatusName; ?>
</option>
<?php } ?>
</select>
</div>
<?php } ?>
<p>Use this option to map woocommerce statuses with easySales one</p>
</div>
<?php
}
public function display_webhook_completed_select()
{
?>
<select name="easysales-webhook-completed-status" id="easysales-webhook-completed-status">
<option value="" disabled selected>Select your option</option>
<?php
$wooOrderStatuses = wc_get_order_statuses();
foreach ($wooOrderStatuses as $wooOrderStatusKey => $wooOrderStatusLabel) {
echo '<option value="' . $wooOrderStatusKey . '" ' . selected(get_option('easysales-webhook-completed-status'), $wooOrderStatusKey) .'>' . $wooOrderStatusLabel .'</option>';
}
?>
</select>
<?php
}
public function display_webhook_cancelled_select()
{
?>
<select name="easysales-webhook-cancelled-status" id="easysales-webhook-cancelled-status">
<option value="" disabled selected>Select your option</option>
<?php
$wooOrderStatuses = wc_get_order_statuses();
foreach ($wooOrderStatuses as $wooOrderStatusKey => $wooOrderStatusLabel) {
echo '<option value="' . $wooOrderStatusKey . '" ' . selected(get_option('easysales-webhook-cancelled-status'), $wooOrderStatusKey) .'>' . $wooOrderStatusLabel .'</option>';
}
?>
</select>
<?php
}
public function display_load_order_tax_from_select()
{
?>
<select name="easysales-load-order-tax-from" id="easysales-load-order-tax-from">
<option value="0" <?php selected(get_option('easysales-load-order-tax-from'), 0) ?>>Products</option>
<option value="1" <?php selected(get_option('easysales-load-order-tax-from'), 1) ?>>Shipping</option>
</select>
<?php
}
public function display_country_tax_select()
{
?>
<select name="easysales-country-tax" id="easysales-country-tax">
<option value="" disabled selected>Select your option</option>
<?php
$countries = WC()->countries->get_countries();
foreach ($countries as $countryCode => $countryName) {
echo '<option value="' . $countryCode . '" ' . selected(get_option('easysales-country-tax'), $countryCode) .'>' . $countryName .'</option>';
}
?>
</select>
<?php
}
/**
* Add api route
*/
public function add_api_route()
{
register_rest_route('easysales', '/api', [
'methods' => 'GET, POST',
'callback' => [$this, 'api_callback'],
'permission_callback' => [$this, 'check_token'],
'args' => [
'auth' => [
'required' => true,
'sanitize_callback' => 'esc_attr'
],
'request' => [
'required' => true,
'sanitize_callback' => 'esc_attr'
]
]
]);
}
/**
* @param WP_REST_Request $request
* @return WP_REST_Response
*/
public function api_callback(WP_REST_Request $request)
{
$method = $request->get_param('request');
if (!method_exists($this->apiController, $method)) {
return new WP_REST_Response([ 'error' => 'true', 'message' => 'Invalid method' ], 401);
}
$response = $this->apiController->{$method}($request);
if ($response instanceof WP_Error) {
return $this->errorResponse($response);
}
return new WP_REST_Response($response, 200);
}
/**
* Verify if given token match easysales-token
* @param WP_REST_Request $request
* @return bool
*/
public function check_token(WP_REST_Request $request)
{
return base64_decode($request->get_param('auth')) === get_option('easysales-token');
}
/**
* @param WP_Error $response
* @param int $code
* @return WP_REST_Response
*/
private function errorResponse(WP_Error $response, $code = 400)
{
return new WP_REST_Response([
'message' => $response->get_error_message()
], $code);
}
/**
* @param $product_id
*/
public function update_product($product_id)
{
$this->sync_product($product_id, 'update');
}
/**
* @param $product_id
* @param $method
*/
public function sync_product($product_id, $method)
{
$data = [
'website_token' => get_option('easysales-token')
];
$product = wc_get_product($product_id);
$visibility = $product->get_catalog_visibility();
$status = $product->get_status();
if (get_option('easysales-draft-products') != 1 && $status === 'draft') {
return;
}
if (get_option('easysales-private-products') != 1 && $status === 'private') {
return;
}
if (get_option('easysales-disabled-products') != 1 && $visibility === 'hidden') {
return;
}
$response = $this->apiController->getProductByIdentifier([
"product_id" => $product_id
]);
if ($response instanceof WP_Error) {
return $this->errorResponse($response);
}
$data['product'] = $response['product'];
if (isset($response['product'])) {
Request::post('products/save', $data);
}
}
/**
* @param $id
*/
public function add_category($id)
{
$this->sync_category($id, 'add');
}
/**
* @param $id
*/
public function update_category($id)
{
$this->sync_category($id, 'update');
}
/**
* @param $id
* @param $method
*/
public function sync_category($id, $method)
{
$category = get_term($id);
$data = [
'website_token' => get_option('easysales-token'),
'category' => [
'category_website_id' => $category->term_id,
'name' => $category->name
]
];
Request::post('categories/save', $data);
}
/**
* @param $id
* @param $attribute
*/
public function add_attribute($id, $attribute)
{
$this->sync_attribute($id, $attribute, 'add');
}
/**
* @param $id
* @param $attribute
*/
public function update_attribute($id, $attribute)
{
$this->sync_attribute($id, $attribute, 'update');
}
/**
* @param $id
* @param $attribute
* @param $method
*/
public function sync_attribute($id, $attribute, $method)
{
$data = [
'website_token' => get_option('easysales-token'),
'characteristic' => [
'characteristic_website_id' => $id,
'name' => $attribute['attribute_label']
]
];
Request::post('characteristics/save', $data);
}
/**
* @param $id
*/
public function new_order($id)
{
$this->sync_order($id, 'add', null);
}
/**
* @param $id
* @param $status
*/
public function update_order($id, $status)
{
$this->sync_order($id, 'update', $status);
}
/**
* @param $id
* @param $method
* @param $status
*/
public function sync_order($id, $method, $status)
{
$order = wc_get_order($id);
$order = $this->orderTransformer->transform($order);
if ($status) {
$order['status'] = $this->orderTransformer->getStatus($status, $order['payment_mode']);
}
$data = [
'website_token' => get_option('easysales-token'),
'order' => $order
];
Request::post('orders/save', $data);
}
/**
* Save variation settings
*/
public function save_variations( $post_id )
{
$post = $_POST['easysales_var_ean'][ $post_id ];
if( isset( $post ) ) {
update_post_meta( $post_id, 'easysales_var_ean', esc_attr( $post ) );
}
/** Remove empty meta **/
$meta = get_post_meta( $post_id,'easysales_var_ean', true );
if ( empty( $meta ) ) {
delete_post_meta( $post_id, 'easysales_var_ean', '' );
}
}
/**
* Add EAN Field for variations
*/
public function variation_ean_field( $loop, $variation_data, $variation )
{
/** add EAN field for variations **/
woocommerce_wp_text_input(
array(
'id' => 'easysales_var_ean[' . $variation->ID . ']',
'wrapper_class' => 'form-row',
'label' => 'EAN',
'desc_tip' => 'true',
'description' => 'Enter EAN.',
'value' => get_post_meta( $variation->ID, 'easysales_var_ean', true ),
)
);
}
}