cmlapi-8.x-1.2/src/Service/XmlParser.php

src/Service/XmlParser.php
<?php

namespace Drupal\cmlapi\Service;

/**
 * Class Xml Parser.
 */
class XmlParser {

  // phpcs:disable
  protected string $queryMap;
  public string | NULL $xmlString = NULL;
  public array $xmlArray = [];
  public array $xmlfind = [];
  public array $stages = [
    'category',
    'svoistvo',
    'product',
    'price',
    'sku',
    'stock',
    'offer',
    'order',
    'image',
  ];

  /**
   * XmlImportMapping.
   */
  public array $xmlImportMapping = [
    'gruppa'   => 'Классификатор/Группы/Группа',
    'category' => 'Классификатор/Категории/Категория',
    'svoistvo'  => 'Классификатор/Свойства/Свойство',
    'price'    => 'Классификатор/ТипыЦен',
    'stock'    => 'Классификатор/Склады',
    'product'  => 'Каталог/Товары/Товар',
  ];

  /**
   * XmlOffersMapping.
   */
  public array $xmlOffersMapping = [
    'price'   => 'ПакетПредложений/ТипыЦен/ТипЦены',
    'stock'   => 'ПакетПредложений/Склады/Склад',
    'svoistvo' => 'Классификатор/Свойства/Свойство',
    'offer'   => 'ПакетПредложений/Предложения/Предложение',
  ];

  /**
   * Stages.
   */
  public array $productMaps = [
    'ЗначенияРеквизитов'   => 'ЗначениеРеквизита',
    'ЗначенияСвойств'      => 'ЗначенияСвойства',
    'ХарактеристикиТовара' => 'ХарактеристикаТовара',
    'СтавкиНалогов'        => 'СтавкаНалога',
    'Цены'                 => 'Цена',
    'Изготовитель'         => '',
  ];
  // phpcs:enable

  /**
   * Constructs a new XmlParser object.
   */
  public function __construct() {

  }

  /**
   * Get Last.
   */
  public function xmlString($uri) {
    $filepath = \Drupal::service('file_system')->realpath($uri);
    return $filepath;
  }

  /**
   * Parse_xml_file.
   */
  public function parseXmlFile($file_uri) : string | NULL {
    $filepath = \Drupal::service('file_system')->realpath($file_uri);
    $this->xmlString = NULL;

    if (is_file($filepath) && is_readable($filepath)) {
      $file = fopen($filepath, "r");
      while ($xml = fread($file, filesize($filepath))) {
        $this->xmlString .= $xml;
      }
      fclose($file);
    }
    else {
      \Drupal::messenger()->addError("$file_uri is not readable");
    }
    return $this->xmlString;
  }

  /**
   * Parse_xml_file .
   */
  public function parseXmlFileHeader($file_uri) : string | NULL {
    $filepath = \Drupal::service('file_system')->realpath($file_uri);
    $xml = "";
    if (is_file($filepath) && is_readable($filepath)) {
      $file = new \SplFileObject($filepath);
      while (!$file->eof()) {
        $line = $file->fgets();
        $xml .= $line;
        if (strpos($line, "</Классификатор>")) {
          $xml .= "</КоммерческаяИнформация>\n";
          break;
        }
      }
      $file = NULL;
    }
    else {
      \Drupal::messenger()->addError("$file_uri is not readable");
    }
    $this->xmlString = $xml;
    return $xml;
  }

  /**
   * Find.
   */
  public function prepare($data, $key, $map) {
    $result = NULL;
    // Skip.
    if (isset($map['skip']) && $map['skip']) {
      return $result;
    }
    // Parse.
    if ($field = $data[$key] ?? FALSE) {
      $type = $this->prepareType($map);
      switch ($type) {
        case 'string':
          $result = $this->prepareString($field);
          break;

        case 'array':
          $result = $this->prepareArray($field, $key);
          break;

        case 'keyval':
          $result = $this->prepareKeyVal($field, $key);
          break;

        case 'attr':
          $result = $this->prepareAttribute($field, $map);
          break;

        default:
          break;
      }

    }

    return $result;
  }

  /**
   * Prepare String.
   */
  public function prepareKeyVal($field, string $key) : array {
    $result = [];
    $map = $this->productMaps[$key] ?? FALSE;
    if (!empty($field && $map !== FALSE)) {
      $value = $field[$map] ?? $field;
      $result = $this->xml2KeyVal($value);
    }
    return $result;
  }

  /**
   * Conv 1c data to key-val.
   */
  private function xml2KeyVal(array $arr) : array {
    $result = [];
    $keys = [
      'Ид',
      'Наименование',
    ];
    $values = [
      'Значение',
      'Ставка',
    ];
    if (!empty($arr)) {
      foreach ($this->arrayNormalize($arr) as $value) {
        $dat = array_values($value);
        $dat[1] = is_string($dat[1]) ? $dat[1] : "";
        if (count($dat) == 2) {
          $result[$dat[0]] = $dat[1];
        }
      }
    }
    return $result;
  }

  /**
   * Conv 1c data to key-val.
   */
  public function xml2Val($arr) {
    $result = [];
    if (!empty($arr)) {
      foreach ($this->arrayNormalize($arr) as $value) {
        $dat = array_values($value);
        if (count($dat) == 2) {
          $result[] = $dat[1];
        }
      }
    }
    return $result;
  }

  /**
   * Prepare String.
   */
  private function prepareType($map) {
    $type = 'string';
    if (isset($map['type'])) {
      $type = $map['type'];
      if (is_array($type)) {
        $type = 'array';
      }
    }
    return $type;
  }

  /**
   * Prepare String.
   */
  private function prepareString($field) {
    $result = '';
    if (!is_array($field)) {
      $result = $field;
    }
    return $result;
  }

  /**
   * Prepare String.
   */
  private function prepareAttribute($field, $map) {
    $result = '';
    if (isset($map['attr'])) {
      $attr = $map['attr'];
      if (isset($field['@attributes'][$attr])) {
        $result = $field['@attributes'][$attr];
      }
    }
    return $result;
  }

  /**
   * Prepare Array.
   */
  private function prepareArray($field, $key) {
    $result = [];
    if (isset($this->productMaps[$key]) && $m = $this->productMaps[$key]) {
      $result = $this->arrayNormalize($field[$m]);
    }
    elseif ($key == 'Группы') {
      foreach ($this->arrayNormalize($field) as $group) {
        $result[] = $group['Ид'];
      }
    }
    else {
      if (isset($map['type']['inside'])) {
        $result = $this->arrayNormalize($field[$map['type']['inside']]);
      }
      else {
        $result = $this->arrayNormalize($field);
      }
      // Выводим только значения определнного поля.
      if (isset($map['type']['list'])) {
        $buffer = [];
        foreach ($result as $index => $row) {
          if (isset($row[$map['type']['list']])) {
            $buffer[] = $row[$map['type']['list']];
          }
        }
        if (count($result) == count($buffer)) {
          $result = $buffer;
        }
        else {
          $result = NULL;
        }
      }
      // Преобразуем в json.
      if (isset($map['type']['json']) && $jsonStatement = $map['type']['json']) {
        $result = json_encode($result, JSON_UNESCAPED_UNICODE);
      }
    }
    return $result;
  }

  /**
   * Find.
   */
  public function find($map) : array {
    $query = explode("/", $map);
    $result = [];
    $this->xmlfind = $this->xmlArray;
    foreach ($query as $q) {
      if (isset($this->xmlfind[$q])) {
        $this->xmlfind = $this->xmlfind[$q];
      }
      else {
        $this->xmlfind = [];
      }
    }
    $result = $this->xmlfind;
    return $result;
  }

  /**
   * Find.
   */
  public function get($type, $key) : array {
    $map = FALSE;
    if ($type == 'import') {
      $mapping = $this->xmlImportMapping;
    }
    elseif ($type == 'offers') {
      $mapping = $this->xmlOffersMapping;
    }
    if (isset($mapping[$key])) {
      $map = $mapping[$key];
      $this->queryMap = $map;
    }
    $data = $this->find($map);
    if (is_string($data['Ид'] ?? FALSE)) {
      $data = [$data];
    }
    return $data;
  }

  /**
   * Parse xml string to array.
   */
  public function parseXmlString(string $xml_string) : XmlParser {
    $xml = simplexml_load_string($xml_string);
    if (!$xml) {
      \Drupal::messenger()->addError("Data can not be parsed");
      return [];
    }
    $json = json_encode($xml, JSON_FORCE_OBJECT);
    $this->xmlArray = json_decode($json, TRUE);
    $this->xmlString = 'parse DONE && string remove';
    return $this;
  }

  /**
   * HELPER: Array Normalize.
   */
  public function mapMerge($array1, $array2) {
    if (!is_array($array1)) {
      $array1 = [];
    }
    if (!is_array($array2)) {
      $array2 = [];
    }
    $map = array_merge($array1, $array2);
    return $map;
  }

  /**
   * HELPER: Array Normalize.
   */
  public function arrayNormalize($array) : array {
    $norm = FALSE;
    if (!is_array($array)) {
      $norm = FALSE;
    }
    else {
      foreach ($array as $key => $value) {
        if (is_numeric($key)) {
          $norm = TRUE;
        }
      }
    }

    if ($norm) {
      return $array;
    }
    else {
      return [$array];
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc