phpnode.jsgraphqlshopifycodeigniter-3

Insert product using shopify


I'm trying to add a curl product with rest api in shopify using node js with graphql.There is a problem related to the product description part.

In this format I send the description, it also contains html elements. enter image description here

Graphql query const { decode } = require('html-entities'); static create_simple_product(data){

  let decoded_desc = decode(data.body_html);
 
  const prodQuery = `
    mutation {
      productCreate(
        input: {
          title: "${data.title}", 
          productType: "${data.product_type}", 
          vendor: "${data.vendor}",
          status:${statusData},
          bodyHtml: "${decoded_desc.replace(/"/g, '\\"')}",
          tags:"${typeof data.tags !== 'object' ? "" :  data.tags}",
          handle:"${data.handle}",
          seo: {description: "${data.seo_description}", title: "${data.seo_title}"},
          published:true
        }
        media: {originalSource: "${data.images[0]}", mediaContentType: IMAGE, alt: "${data.title}"}
      ) {
        product {
          id
          title
          bodyHtml
          description
          vendor
          productType
          createdAt
          updatedAt
          handle
          status
          totalInventory
          totalVariants
          tracksInventory
          variants(first: 50) {
            nodes {
              id
              inventoryItem {
                id
              }
              title
              price
              compareAtPrice
              createdAt
              updatedAt
              sku
              barcode
              weight
              weightUnit
              inventoryQuantity
              inventoryManagement
              position
              image {
                src
                id
                altText
              }
            }
          }
          options(first: 50) {
            id
            name
            position
            optionValues {
              name
              hasVariants
              id
            }
          }
          images(first: 100, sortKey: POSITION) {
            edges {
              node {
                id
                src
                altText
                height
                width
              }
            }
          }
          media(first: 100) {
            edges {
              node {
                id
                ... on MediaImage {
                  id
                  image {
                    src
                  }
                }
              }
            }
          }
        }
        userErrors {
          field
          message
        }
      }
    }
  `;
  return prodQuery;
}

The api body that I send from php.

 $output_desc_prod = preg_replace('/<([^>]+)(\sstyle=(?P<stq>["\'])(.*)\k<stq>)([^<]*)>/iUs', '<$1$5>', $get_product_data->descriere_produs);
     
        $product_description = htmlentities($output_desc_prod); 
       

        $data_sf_prod = array(
            "api_key" => $site_data->api_key,
            "server_key" =>  $site_data->server_key,
            "title" =>  $get_product_data->nume_produs,
            "body_html" => $product_description,
            "vendor" => strtolower($site_data->den_site),
            "status" => "draft",
            "product_type" => "",
            "tags" => "",
            "images" => $array_images_final,
            "seo_description" => $getMetaData->md,
            "seo_title" => $getMetaData->mt,
            "price" => $priceSelector,
            "sku" => $get_product_data->cod_produs,
            "handle"=> $get_product_data->slug_produs,
            "barcode" =>  $get_product_data->ean === "" ? null : $get_product_data->ean,
            "weight" => 1,
            "weight_unit" => "",
            "compare_at_price" => $priceCompareSelector
        );

I use htmlentities to eliminate any problem, mostly it works, but there are some products that once inserted don't work and display the following error. Create Simple ProductError: syntax error, unexpected invalid token (""") at [9, 25]


Solution

  • This isn't necessarily the answer to the question you're asking, but it might solve your problem. Please don't do string interpolation on your GraphQL operations. You should be passing a query and a variables to your backend. query will use GraphQL variable references, and the variables will be a JSON object with the content.

    This has several benefits, including:

    1. Persisted Queries: at build time, you are able to register your query body and get back a hash. Then, when you make your GraphQL request, you only have to send the hash and the variables. This reduces bytes-over-the-wire and generally increases the speed of the application.
    2. You don't have to worry about string interpolation and quotes (the issue it sounds like you're having). As long as you can correctly JSON-stringify your parts, you don't have to worry about the end result ALSO having to go through JSON-stringification.
    3. Along with #2, you don't have to do "HTML encoding" yourself on the frontend. variables will be run through JSON.stringify, and that function is smarter than I am about what works with JSON and what doesn't.

    Your query:

    mutation CreateAProduct($productInput: ProductCreateInput!, $mediaInput: MediaCreateInput!) {
      productCreate(
        input: $productInput
        media: $mediaInput
      ) {
        # Whatever you want, or
        # ...thisCouldBeAFragment
    }
    

    Your variables

    const variables = {
      productInput: {
        title: data.title,
        productType: data.product_type,
        vendor: data.vendor,
        status: statusData,
        bodyHtml: data.description,
        tags: typeof data.tags !== 'object' ? "" :  data.tags,
        handle: data.handle,
        seo: {description: data.seo_description, title: data.seo_title},
        published: true
      },
      mediaInput: {
        originalSource: data.images[0],
        mediaContentType: "IMAGE",
        alt: data.title
      }
    };
    

    As mentioned in #3, note that I just used data.description. Since variables is going to be run through JSON.stringify, you don't have to "manually figure out yourself" how to make that work as part of your request body.