0
votes

I am making a website using Wordpress - I am integrating the Amazon FBA (Fulfillment By Amazon) service with the woocommerce plugin, using the Amazon MWS PHP API. So far I have figured out how to generate an inventory report and then download it using the PHP sample scripts that come with the API. Now, to integrate the inventory data with the woocommerce plugin - I need to make an XML file that looks like the dummydata.xml file that is provided with the woocommerce plugin. This seems like a fairly straightforward problem, I have written scripts to read and write to files before - but I want to make sure I use the right tool for the job. The inventory text file looks exactly like this after I download it.

item-name item-description listing-id seller-sku price quantity open-date image-url item-is-marketplace product-id-type zshop-shipping-fee item-note item-condition zshop-category1 zshop-browse-path zshop-storefront-feature asin1 asin2 asin3 will-ship-internationally expedited-shipping zshop-boldface product-id bid-for-featured-placement add-delete pending-quantity fulfillment-channel Pioneer HDJ-1000 DJ Headphones [Electronics] 0625OSJKQMG 3U-R7EP-QODZ 89 2014-06-25 12:26:27 PDT y 1 Please note that the color is silver as shown in picture. Unopened manufacturers packaging. 11 B0002DV7Z2 B0002DV7Z2 AMAZON_NA The Eye of God (Sigma Force) [Mass Market Paperback] by Rollins, James 0624OQ2O5MM 86-CK3P-PHK6 4.89 0 2014-06-24 13:36:21 PDT y 1 Excellent condition, slight crease on the cover but very clean. 1 0061785679 1 N 0061785679 0 DEFAULT Founding Brothers: The Revolutionary Generation [Paperback] by Ellis, Joseph J. 0514O4WDGIG NX-USS1-UXRY 3 2014-05-14 08:09:50 PDT y 1 1 0375705244 1 N 0375705244 AMAZON_NA JBL Flip Wireless Bluetooth Speaker (Red) [Personal Computers] 0513O3A7IHY VB-GNYY-PMZS 89 0 2014-05-13 16:19:12 PDT y 1 11 B00DQAPJSY B00DQAPJSY 0 DEFAULT

In an attempt to sift through what all that means - I created another text file that points out what all the data is - the first chunk is just a list of the categories that all the data falls into - I did my best to assign each part of the data to the correct category, the items start with the second chunk:

| item-name | item-description | listing-id | seller-sku | price | quantity | open-date | image-url | item-is-marketplace | product-id-type | zshop-shipping-fee | item-note | item-condition | zshop-category1 | zshop-browse-path | zshop-storefront-feature | asin1 | asin2 | asin3 | will-ship-internationally | expedited-shipping | zshop-boldface | product-id | bid-for-featured-placement | add-delete | pending-quantity | fulfillment-channel |

| item-name: Pioneer HDJ-1000 DJ Headphones [Electronics] | listing-id: 0625OSJKQMG | seller-sku: 3U-R7EP-QODZ | price: 89 | quantity: blank when 0 | open-date: 2014-06-25 12:26:27 PDT | image_url: no image | item-is-marketplace: y | product-id-type: 1 | zshop-shipping-fee: no shipping fee | item-note: Please note that the color is silver as shown in picture. | item-condition: Unopened manufacturers packaging. | zshop-category1?: 11 | asin: B0002DV7Z2 | asin: B0002DV7Z2 | channel: AMAZON_NA |

| item-name: The Eye of God (Sigma Force) [Mass Market Paperback] by Rollins, James | listing-id: 0624OQ2O5MM | seller-sku: 86-CK3P-PHK6 | price: 4.89 | quantity: 0 (this one was there for some reason) | open-date: 2014-06-24 13:36:21 PDT | item-is-mp: y | prod-id-type: 1 | item-condition: Excellent condition, slight crease on the cover but very clean. | zshop-category1: 1 | asin: 0061785679 | ?: 1 | will-ship-international: N | asin: 0061785679 | pending-quantity: 0 | channel: DEFAULT (when merchant) |

| item-name: Founding Brothers: The Revolutionary Generation [Paperback] by Ellis, Joseph J. | listing-id: 0514O4WDGIG | seller-sku: NX-USS1-UXRY | price: 3 | date: 2014-05-14 08:09:50 PDT | is-market: y | product-id-type: 1 | ?: 1 | asin: 0375705244 | ?: 1 | international: N | asin: 0375705244 | channel: AMAZON_NA |

| item-name: JBL Flip Wireless Bluetooth Speaker (Red) [Personal Computers] | list-id: 0513O3A7IHY | sku: VB-GNYY-PMZS | price: 89 | quantity: 0 | date: 2014-05-13 16:19:12 PDT | is-market: y | prod-id-type: 1 | zshop-category?: 11 | asin: B00DQAPJSY | asin: B00DQAPJSY | ?: 0 | channel: DEFAULT |

This is what the dummydata.xml file looks like at the beginning - and I included the XML for one item:

<?xml version="1.0" encoding="UTF-8" ?>
<!-- This is a WordPress eXtended RSS file generated by WordPress as an export of your site. -->
<!-- It contains information about your site's posts, pages, comments, categories, and other content. -->
<!-- You may use this file to transfer that content from one site to another. -->
<!-- This file is not intended to serve as a complete backup of your site. -->

<!-- To import this information into a WordPress site follow these steps: -->
<!-- 1. Log in to that site as an administrator. -->
<!-- 2. Go to Tools: Import in the WordPress admin panel. -->
<!-- 3. Install the "WordPress" importer from the list. -->
<!-- 4. Activate & Run Importer. -->
<!-- 5. Upload this file using the form provided on that page. -->
<!-- 6. You will first be asked to map the authors in this export file to users -->
<!--    on the site. For each author, you may choose to map to an -->
<!--    existing user on the site or to create a new user. -->
<!-- 7. WordPress will then import each of the posts, pages, comments, categories, etc. -->
<!--    contained in this file into your site. -->

<!-- generator="WordPress/3.5.1" created="2013-06-14 12:35" -->
<rss version="2.0"
    xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:wp="http://wordpress.org/export/1.2/"
>

<channel>
    <title>WooCommerce Dummy Data</title>
    <link>http://demo2.woothemes.com/woocommerce</link>
    <description>Just another WooThemes Demo site</description>
    <pubDate>Fri, 14 Jun 2013 12:35:54 +0000</pubDate>
    <language>en-US</language>
    <wp:wxr_version>1.2</wp:wxr_version>
    <wp:base_site_url>http://demo2.woothemes.com/</wp:base_site_url>
    <wp:base_blog_url>http://demo2.woothemes.com/woocommerce</wp:base_blog_url>

    <wp:term><wp:term_id>17</wp:term_id><wp:term_taxonomy>pa_color</wp:term_taxonomy><wp:term_slug>black</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[Black]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>19</wp:term_id><wp:term_taxonomy>pa_color</wp:term_taxonomy><wp:term_slug>blue</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[Blue]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>12</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>cancelled</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[cancelled]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>10</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>completed</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[completed]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>5</wp:term_id><wp:term_taxonomy>product_type</wp:term_taxonomy><wp:term_slug>external</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[external]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>7</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>failed</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[failed]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>16</wp:term_id><wp:term_taxonomy>pa_color</wp:term_taxonomy><wp:term_slug>green</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[Green]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>3</wp:term_id><wp:term_taxonomy>product_type</wp:term_taxonomy><wp:term_slug>grouped</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[grouped]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>8</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>on-hold</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[on-hold]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>6</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>pending</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[pending]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>9</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>processing</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[processing]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>11</wp:term_id><wp:term_taxonomy>shop_order_status</wp:term_taxonomy><wp:term_slug>refunded</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[refunded]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>2</wp:term_id><wp:term_taxonomy>product_type</wp:term_taxonomy><wp:term_slug>simple</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[simple]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>4</wp:term_id><wp:term_taxonomy>product_type</wp:term_taxonomy><wp:term_slug>variable</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[variable]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>14</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>clothing</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[Clothing]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>18</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>hoodies</wp:term_slug><wp:term_parent>clothing</wp:term_parent><wp:term_name><![CDATA[Hoodies]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>13</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>music</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[Music]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>20</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>posters</wp:term_slug><wp:term_parent></wp:term_parent><wp:term_name><![CDATA[Posters]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>21</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>singles</wp:term_slug><wp:term_parent>music</wp:term_parent><wp:term_name><![CDATA[Singles]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>15</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>t-shirts</wp:term_slug><wp:term_parent>clothing</wp:term_parent><wp:term_name><![CDATA[T-shirts]]></wp:term_name></wp:term>
    <wp:term><wp:term_id>22</wp:term_id><wp:term_taxonomy>product_cat</wp:term_taxonomy><wp:term_slug>albums</wp:term_slug><wp:term_parent>music</wp:term_parent><wp:term_name><![CDATA[Albums]]></wp:term_name></wp:term>

    <generator>http://wordpress.org/?v=3.5.1</generator>

    <item>
        <title>T_1_front</title>
        <link>http://demo2.woothemes.com/woocommerce/product/woo-logo/t_1_front/</link>
        <pubDate>Fri, 07 Jun 2013 10:35:28 +0000</pubDate>
        <dc:creator>wooteam</dc:creator>
        <guid isPermaLink="false">http://demo2.woothemes.com/dummydata/files/2013/06/T_1_front.jpg</guid>
        <description></description>
        <content:encoded><![CDATA[]]></content:encoded>
        <excerpt:encoded><![CDATA[]]></excerpt:encoded>
        <wp:post_id>16</wp:post_id>
        <wp:post_date>2013-06-07 10:35:28</wp:post_date>
        <wp:post_date_gmt>2013-06-07 10:35:28</wp:post_date_gmt>
        <wp:comment_status>open</wp:comment_status>
        <wp:ping_status>open</wp:ping_status>
        <wp:post_name>t_1_front</wp:post_name>
        <wp:status>inherit</wp:status>
        <wp:post_parent>15</wp:post_parent>
        <wp:menu_order>0</wp:menu_order>
        <wp:post_type>attachment</wp:post_type>
        <wp:post_password></wp:post_password>
        <wp:is_sticky>0</wp:is_sticky>
        <wp:attachment_url>http://demo2.woothemes.com/woocommerce/files/2013/06/T_1_front.jpg</wp:attachment_url>
        <wp:postmeta>
            <wp:meta_key>_wp_attached_file</wp:meta_key>
            <wp:meta_value><![CDATA[2013/06/T_1_front.jpg]]></wp:meta_value>
        </wp:postmeta>
        <wp:postmeta>
            <wp:meta_key>_wp_attachment_metadata</wp:meta_key>
            <wp:meta_value><![CDATA[a:5:{s:5:"width";i:1000;s:6:"height";i:1000;s:4:"file";s:21:"2013/06/T_1_front.jpg";s:5:"sizes";a:6:{s:9:"thumbnail";a:4:{s:4:"file";s:21:"T_1_front-150x150.jpg";s:5:"width";i:150;s:6:"height";i:150;s:9:"mime-type";s:10:"image/jpeg";}s:6:"medium";a:4:{s:4:"file";s:21:"T_1_front-300x300.jpg";s:5:"width";i:300;s:6:"height";i:300;s:9:"mime-type";s:10:"image/jpeg";}s:14:"post-thumbnail";a:4:{s:4:"file";s:21:"T_1_front-624x624.jpg";s:5:"width";i:624;s:6:"height";i:624;s:9:"mime-type";s:10:"image/jpeg";}s:14:"shop_thumbnail";a:4:{s:4:"file";s:19:"T_1_front-90x90.jpg";s:5:"width";i:90;s:6:"height";i:90;s:9:"mime-type";s:10:"image/jpeg";}s:12:"shop_catalog";a:4:{s:4:"file";s:21:"T_1_front-150x150.jpg";s:5:"width";i:150;s:6:"height";i:150;s:9:"mime-type";s:10:"image/jpeg";}s:11:"shop_single";a:4:{s:4:"file";s:21:"T_1_front-300x300.jpg";s:5:"width";i:300;s:6:"height";i:300;s:9:"mime-type";s:10:"image/jpeg";}}s:10:"image_meta";a:10:{s:8:"aperture";i:0;s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";i:0;s:9:"copyright";s:0:"";s:12:"focal_length";i:0;s:3:"iso";i:0;s:13:"shutter_speed";i:0;s:5:"title";s:0:"";}}]]></wp:meta_value>
        </wp:postmeta>
    </item>

So, I need to take the necessary stuff out of the inventory report - and put it in the right places in that XML file. What would be the best way to approach this problem? Thanks.

UPDATE

I have some control over the format of the inventory report with this php function in the script that gets the report:

/**
  * Get Report Action Sample
  * The GetReport operation returns the contents of a report. Reports can potentially be
  * very large (>100MB) which is why we only return one report at a time, and in a
  * streaming fashion.
  *   
  * @param MarketplaceWebService_Interface $service instance of MarketplaceWebService_Interface
  * @param mixed $request MarketplaceWebService_Model_GetReport or array of parameters
  */
  function invokeGetReport(MarketplaceWebService_Interface $service, $request) 
  {
      try {
              $response = $service->getReport($request);
              
                echo ("Service Response\n");
                echo ("=============================================================================\n");

                echo("        GetReportResponse\n");
                if ($response->isSetGetReportResult()) {
                  $getReportResult = $response->getGetReportResult(); 
                  echo ("            GetReport");
                  
                  if ($getReportResult->isSetContentMd5()) {
                    echo ("                ContentMd5");
                    echo ("                " . $getReportResult->getContentMd5() . "\n");
                  }
                }
                if ($response->isSetResponseMetadata()) { 
                    echo("            ResponseMetadata\n");
                    $responseMetadata = $response->getResponseMetadata();
                    if ($responseMetadata->isSetRequestId()) 
                    {
                        echo("                RequestId\n");
                        echo("                    " . $responseMetadata->getRequestId() . "\n");
                    }
                }
                
                echo ("        Report Contents\n");
                echo (stream_get_contents($request->getReport()) . "\n");

                echo("            ResponseHeaderMetadata: " . $response->getResponseHeaderMetadata() . "\n");
     } catch (MarketplaceWebService_Exception $ex) {
         echo("Caught Exception: " . $ex->getMessage() . "\n");
         echo("Response Status Code: " . $ex->getStatusCode() . "\n");
         echo("Error Code: " . $ex->getErrorCode() . "\n");
         echo("Error Type: " . $ex->getErrorType() . "\n");
         echo("Request ID: " . $ex->getRequestId() . "\n");
         echo("XML: " . $ex->getXML() . "\n");
         echo("ResponseHeaderMetadata: " . $ex->getResponseHeaderMetadata() . "\n");
     }
 }

Does anyone have any suggestions for what delimiters to put in, and where - so that I can parse the data efficiently and reliably?

The important line seems to be:

echo (stream_get_contents($request->getReport()) . "\n");

I need a way to edit the contents of the stream so that I can add delimiters, I think...

UPDATE

I read the manual for stream_get_contents and there is a parameter you can use to tell it how many bytes to get - as well as an offset parameter - couldn't I use stream_get_contents multiple times - each time specifying what chunk I want, so I can keep track of what the data is that way?

1
that input file is essentially useless. there's no delimeters between any of the sections. how can you tell where one "section" ends and another starts? with the ID-ish information it's fairly obvious, but the rest? who knows.Marc B
@MarcB - yes I realize it is just a jumble of info - I did my best to assign things - but you are right it isn't well formatted - i guess this is just part of the problem - i dont see any other way to get the inventory from amazon except in a report that comes like this - I can write it to any kind of file btw - and it also appears in the browser once i run the script but that isnt formatted well either.ewizard
@MarcB Also - not everything in the inventory file is relevant - I only need to get the important things like price/quantity - there has to be a way to do this...I mean I'm pretty sure I could write some simple file reading and writing script and just put in enough conditionals so it gets the right stuff but that seems like it would be a pain and maybe there is a better way.ewizard
yeah, but without delimiters to say which bits are which, you'd be stuck with something like "The $5 footlong, by S. Ubway, price $19.99". which one is the actual item price, and which is part of the title? You and I know the price is 19.99, but how do you get your code to differentiate?Marc B
@MarcB wouldn't I kind of painstakingly have to figure out creative ways to make the computer count the correct number of characters before getting what is needed? is that possible?ewizard

1 Answers

0
votes

I realized that the .txt file was tab delimited which made things go from super hard to really easy - it seems like it is basically a .csv but for some reason Amazon outputs it as a tab delimited .txt file. I found this stack question, which lays out the perfect way to handle the amazon inventory reports you can generate and download (if anyone else is having this specific problem).

I found that if I added a counter to that code for the while loop - I could keep track of what line it was looking at - and then I did this:

if ($counter === 0 ) {
    echo implode(" ", $data);
}

$data represents the parsed line in the form of an array. It turns out that line 0 is just all of the descriptions for each column - like this:

item-name item-description listing-id seller-sku price quantity open-date image-url item-is-marketplace product-id-type zshop-shipping-fee item-note item-condition zshop-category1 zshop-browse-path zshop-storefront-feature asin1 asin2 asin3 will-ship-internationally expedited-shipping zshop-boldface product-id bid-for-featured-placement add-delete pending-quantity fulfillment-channel

When I output line 1, much to my delight, it was all the info for the first item in his inventory:

The Eye of God (Sigma Force) [Mass Market Paperback] by Rollins, James XXXXXX XXXXXX X.XX 0 2014-06-24 13:36:21 PDT y 1 Excellent condition, slight crease on the cover but very clean. 1 0061785679 1 N 0061785679 0 DEFAULT

I then found that line 2 represented the second item, and so on...so it is all very neatly packaged - at least if you are using str_getcsv PHP function.

Because everything is tab delimited - it than becomes trivial to get any of the info you need from the report, because even if the column is empty - there will still be a tab there to represent that it is empty...nice and neat.