Files
2025-04-01 00:38:54 +02:00

555 lines
16 KiB
PHP

<?php
/**
* NOTICE OF LICENSE
* With the purchase or the installation of the software in your application
* you accept the license agreement.
*
* You can not resell and redistribute this file.
*
* @author Dalibor Stojcevski <dal_sto@yahoo.com>
* @copyright 2019 Dalibor Stojcevski
* @license Dalibor Stojcevski
*/
/** No max line limit since the lines can be more than 4096. Performance impact is not significant. */
function filter_category_array ($element) {
return (!is_array($element) && $element !== '');
}
define('MAX_LINE_SIZE', 0);
class Import
{
private $json_array = array();
private $product_links = array();
private $settings;
public function __construct($settings)
{
$this->settings = $settings;
}
public function getAllData($path, $test = false)
{
$fields = $this->settings['import_api_field'];
$nested_data = array();
$id_parts = explode('->', $path);
array_shift($id_parts);
foreach ($fields as $field => $value) {
if(!$value) continue;
$field_paths = $value ? html_entity_decode($value, ENT_QUOTES, 'UTF-8') : '';
$field_parts = explode('->', $field_paths);
$nested_data[$field] = $this->getFieldData($this->json_array, $field_parts, $id_parts);
}
if ($test == 'view-raw') {
return $nested_data;
}
$nested_data = $this->checkCombinations($nested_data);
if ($test == 'view-split') {
return $nested_data;
}
$original_product = $this->resolveAllNestedData($nested_data);
if ($test == 'view-grouping') {
return $original_product;
}
$modified = $this->changeOriginal($original_product);
return $modified;
}
public function resolveAllNestedData($nested_data)
{
if (!empty($nested_data['feature_value'])) {
if (empty($nested_data['feature'])) {
if (!empty($this->settings['import_api_modification']['feature'])) {
$nested_data['feature'] = $this->settings['import_api_modification']['feature'];
} else {
$nested_data['feature'] = 'Feature';
}
}
$feature_map = $this->resolveNested($nested_data['feature_value'], $nested_data['feature']);
$nested_data['features'] = array();
foreach ($feature_map as $key => $map) {
$nested_data['features'][$key] = array(
'feature' => $map['parent'],
'feature_value' => $map['value']
);
}
}
$nested_data['attributes'] = array();
for ($i = 1;$i <= 3; $i++) {
if (!empty($nested_data['attribute_value' . $i])) {
if (empty($nested_data['attribute' . $i])) {
if (!empty($this->settings['import_api_modification']['attribute' . $i])) {
$nested_data['attribute' . $i] = $this->settings['import_api_modification']['attribute' . $i];
} else {
$nested_data['attribute' . $i] = 'Select ' . $i;
}
}
$attribute_map = $this->resolveNested($nested_data['attribute_value' . $i], $nested_data['attribute' . $i]);
$attribute_details_par = array('price', 'ean', 'quantity', 'weight');
foreach ($attribute_map as $key => $map) {
foreach ($attribute_details_par as $parameter) {
if (isset($nested_data['attribute_' . $parameter])) {
if (is_array($nested_data['attribute_' . $parameter])) {
if (isset($nested_data['attribute_' . $parameter][$key])) {
$nested_data['attribute_details'][$parameter][$map['value']] = $nested_data['attribute_' . $parameter][$key];
}
} else {
$nested_data['attribute_details'][$parameter][$map['value']] = $nested_data['attribute_' . $parameter];
}
}
}
$nested_data['attributes'][$i][$key] = array(
'attribute' => $map['parent'],
'attribute_value' => $map['value']
);
}
}
}
if (!empty($nested_data['category'])) {
if (!isset($nested_data['category_parent'])) {
$nested_data['category_parent'] = 0; // it is not good idea to put default top category here
}
if ($this->settings['import_api_settings']['category_path'] && is_array($nested_data['category'])) {
$nested_data['category'] = implode('->', array_filter($nested_data['category'], "filter_category_array"));
}
$nested_data['category_path'] = $this->resolveNested($nested_data['category'], $nested_data['category_parent']);
}
$nested_data['options'] = array();
if (!empty($nested_data['option_value'])) {
if (!isset($nested_data['option'])) {
$nested_data['option'] = $this->settings['import_api_default_option'];
}
if (!isset($nested_data['option_price'])) {
$nested_data['option_price'] = 0;
}
if (!isset($nested_data['option_weight'])) {
$nested_data['option_weight'] = 0;
}
$option_map= $this->resolveNested($nested_data['option_value'], $nested_data['option']);
$option_price_map = $this->resolveNested($nested_data['option_price'], $nested_data['option_value']);
$option_weight_map = $this->resolveNested($nested_data['option_weight'], $nested_data['option_value']);
foreach ($option_map as $key => $map) {
if (is_array($nested_data['option_price'])) {
foreach ($option_price_map as $price_map) {
if ($map['value'] == $price_map['parent']) {
$nested_data['options'][$key] = array(
'option' => $map['parent'],
'option_value' => $map['value'],
'price' => $price_map['value']
);
break;
}
}
} else {
$nested_data['options'][$key] = array(
'option' => $map['parent'],
'option_value' => $map['value'],
'price' => $nested_data['option_price']
);
}
if (is_array($nested_data['option_weight'])) {
foreach ($option_weight_map as $weight_map) {
if($map['value'] == $weight_map['parent']){
$nested_data['options'][$key]['weight'] = $weight_map['value'];
break;
}
}
} else {
$nested_data['options'][$key]['weight'] = $nested_data['option_weight'];
}
}
}
return $nested_data;
}
public function getFieldData($tree, $field_parts, $id_parts)
{
while($field_parts) {
if ($this->isSeq($tree)) {
$seq_id = array_shift($id_parts);
$tree = $tree[$seq_id];
} else {
$part = array_shift($field_parts);
$uni_c = array_shift($id_parts);
if($part == $uni_c){
$tree = $tree[$part];
} else {
$field_parts = array_merge([$part], $field_parts); // vrati mu ga
return $this->followDifferentPath($field_parts, $tree);
}
}
}
}
public function followDifferentPath($own_parts, $tree){
$prev= ''; // for test
foreach($own_parts as $part){
//if ($part == 'image') {var_dump($tree);var_dump($own_parts);exit;}
if ($this->isSeq($tree)) {
$ret = array();
foreach($tree as $t){
$ret[] = $this->followDifferentPath($own_parts, $t);
}
return $ret;
} else {
array_shift($own_parts);
$tree = isset($tree[$part]) ? $tree[$part] : '';
}
$prev = $part; //for test
}
if(!is_array($tree)){
return trim($tree);
}
return $tree;
}
public function findUniqueProductsIdentifier($tree, $parts, $identifier, $path = ''){
$tmp_parts = $parts;
foreach ($parts as $part) {
if ($part == $identifier && !$this->isSeq($tree) && isset($tree[$part])) {
if (!empty($tree[$part]) && !is_array($tree[$part])) {
$path .= '->'. $tree[$part];
$this->product_links[] = $path;
}
//exit;
} elseif ($this->isSeq($tree)) {
foreach($tree as $key => $t){
$local_path = $path. '->' . $key;
$this->findUniqueProductsIdentifier($t, $tmp_parts, $identifier, $local_path);
}
return;
} else {
if (isset($tree[$part])) {
$tree = $tree[$part];
$path .= '->'. $part;
}
array_shift($tmp_parts);
}
}
}
public function resolveNested($child_data, $parent_data, $default_parent = 'Value'){
$child_indexes = array();
if(!is_array($child_data)){
$child_data = array($child_data);
}
$this->setIndexPath($child_data, $child_indexes);
$parent_indexes = array();
if(is_array($parent_data)){
$this->setIndexPath($parent_data, $parent_indexes);
} else {
$map = array();
foreach($child_indexes as $child){
$map[] = array(
'value' => $child['value'],
'parent' => $parent_data
);
}
return $map;
}
return $this->addParent($child_indexes, $parent_indexes);
}
public function addParent($children, $parents){
$map = array();
foreach($parents as $parent){
foreach($children as $key => $child){
if(substr($child['key_path'], 0, strlen($parent['key_path'])) === $parent['key_path']){
$map[] = array(
'value' => $child['value'],
'parent' => $parent['value']
);
unset($children[$key]);
}
}
}
return $map;
}
/**
* Takes nested array with unknown nesting levels and return one level array with indexes to values.
*
* @param array $array array with unknown nesting levels
* @param string $key_path string made from array keys
* @return array with values and string from value indexes
*/
public function setIndexPath($array, &$return_values = array(), $key_path = ''){
foreach($array as $key => $array_part){
if(is_array($array_part)){
$this->setIndexPath($array_part, $return_values, $key_path . $key . '.');
} else {
$return_values[] = array(
'key_path' => $key_path . $key . '.',
'value' => $array_part
);
}
}
}
public function changeOriginal($product)
{
$modifications = $this->settings['import_api_modification'];
foreach ($modifications as $field => $modification) {
//if (!$modification) {
if ($modification === '') {
continue;
}
if (in_array($field, ['price']) && !$product[$field]) {
continue;
}
if (!isset($product[$field])) {
$product[$field] = '';
}
if (in_array($field, ['image', 'images', 'cover']) && !$product[$field]) {
continue;
}
$modification = html_entity_decode($modification, ENT_QUOTES, 'UTF-8');
$modified = $this->check_string($modification, $product);
$product[$field] = $modified;
if (in_array($field, ['price', 'quantity', 'option_price','option_quantity', 'special', 'additional_shipping_cost', 'width', 'height', 'depth', 'weight', 'attribute_price', 'attribute_quantity', 'attribute_weight', 'minimal_quantity'])) {
$modified = $this->calculateMath($modified);
$product[$field] = $modified;
}
}
return $product;
}
public function checkCombinations($product)
{
$combinations = $this->settings['import_api_combination'];
foreach ($combinations as $field => $combination) {
if (!$combination || !isset($product[$field])) {
continue;
} else {
$position = 'all';
$parts = explode('##', $combination);
if(isset($parts[1])){
$position = $parts[1];
}
}
$exploded = $this->explodeCombinations($product[$field], $parts[0], $position);
$product[$field] = $exploded;
}
return $product;
}
public function explodeCombinations($value, $separator, $position = 'all')
{
if (!is_array($value)) {
$parts = explode($separator, $value);
if ($position == 'all') {
return $parts;
}
if ($position == 'last') {
return end($parts);
}
if (isset($parts[$position-1])) {
return $parts[$position-1];
}
return $value;
} else {
$ret = array();
foreach ($value as $key => $v) {
$ret[] = $this->explodeCombinations($v, $separator, $position);
}
return $ret;
}
}
public function getProductLinks()
{
return $this->product_links;
}
private function check_string($string, $prod)
{
if ($string) {
preg_match_all('/\[\[([a-z_]*\#?[^\]]*)\]\]/', $string , $match);
if ($match) {
$string = $this->replace_string($string, $match[1], $prod);
}
}
return $string;
}
private function replace_string($string, $keys, $d_array)
{
foreach ($keys as $key) {
$exploded_key = explode('#', $key);
$separator = false;
if (isset($exploded_key[1])) {
$string = str_replace($key, $exploded_key[0], $string);
$key = $exploded_key[0];
$separator = $exploded_key[1];
}
if (isset($d_array[$key])) {
if (is_array($d_array[$key])) {
$string = $this->replace_all_array_strings($d_array[$key], $key, $string, $separator);
} else {
$string = str_replace('[['. $key .']]', $d_array[$key], $string);
}
}
}
return $string;
}
private function replace_all_array_strings($array, $key, $string, $separator = false)
{
$s = array();
foreach ($array as $d_part) {
$s[] = str_replace('[['. $key .']]', $d_part, $string);
}
if ($separator !== false) {
$s = implode($separator, $s);
}
return $s;
}
private function calculateMath($expression)
{
$expression = str_replace(',', '.', $expression);
$expression = str_replace(' ', '', $expression);
$expression = preg_replace('/[^0-9\.\+\-\*\/\(\)]/', '', $expression);
$expression = $this->replaceMathExpession($expression, '*');
$expression = $this->replaceMathExpession($expression, '/');
$expression = $this->replaceMathExpession($expression, '+');
$expression = $this->replaceMathExpession($expression, '-');
return $expression;
}
private function replaceMathExpession($expression, $sign)
{
$patern = '\\' . $sign;
$expression = preg_replace_callback(
'/[0-9]*\.?[0-9]+' . $patern . '[0-9]*\.?[0-9]+(' . $patern . '[0-9]*\.?[0-9]+)*/',
function ($matches) use ($sign) {
if (!empty($matches[0])) {
return $this->calculate_string($matches[0], $sign);
}
}, $expression);
return $expression;
}
private function calculate_string($string, $sign)
{
$parts = explode($sign, $string);
$final = $parts[0];
for ($i = 1; $i < count($parts); $i++) {
if ($sign == '*') {
$final = $final * $parts[$i];
} elseif ($sign == '/') {
$final = $final / $parts[$i];
} elseif ($sign == '+') {
$final = $final + $parts[$i];
} elseif ($sign == '-') {
$final = $final - $parts[$i];
}
}
return $final;
}
public function jsonToArray($json_url)
{
$json_string = @file_get_contents($json_url);
$json_array = json_decode($json_string, true);
return $json_array;
}
public function setJsonArray($json_array)
{
$this->json_array = $json_array;
}
public function isSeq($array)
{
if (is_array($array) ) {
return is_int(array_key_first($array));
}
//return is_array($array) && isset($array[0]);
return false;
}
}