PHPGangsta - Der praktische PHP Blog

PHP Blog von PHPGangsta


Archive for the ‘XML’ tag

XML Parsen mit DOMDocument: störende Whitespace-Knoten

with 7 comments

Gestern nach Jahren mal wieder drüber gestolpert, deshalb jetzt hier schriftlich festgehalten:

Bei Nutzung von DOMDocument und der loadXML() Funktion werden standardmäßig erstmal Umbrüche und Whitespace (Leerzeichen, Tabs), die nur zu Formatierungszwecken genutzt werden, auch als Textelemente angesehen. Folgendes Beispielsnippet:

Weiterlesen »

Written by Michael Kliewe

August 10th, 2012 at 10:29 am

Posted in PHP

Tagged with , , , ,

Mit der eBay-API seine Auktionen beobachten

with 3 comments

Nach dem letzten Artikel über die eBay-API und das Erstellen von Auktionen wollen wir nun unsere Auktionen beobachten und Informationen periodisch abfragen. Damit können wir uns selbst beispielsweise eine tägliche Übersicht senden oder die Auktionen auf unserer Webseite darstellen.

Die entsprechende API-Funktion heißt GetSellerList, sie liefert uns Informationen über unsere Auktionen eines bestimmten Zeitraums. Wenn man detaillierte Informationen über bereits verkaufte Artikel haben möchte muss man GetSellerTransactions nutzen. Hier stelle ich erstere vor.

Wie bereits im ersten Artikel stelle ich euch hier ein Basis-Script vor, natürlich sollte man das noch umbauen und erweitern, aber zur Erklärung der Funktionalität reicht es aus. Wir bereiten hier einen XML-Request vor mit den entsprechenden Parametern und erhalten eine XML-Antwort, die wir mittels DomDocument auseinander nehmen und die Informationen extrahieren. Hier also das Script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
<?php
$addItem = new eBayGetSellerList();
$addItem->callEbay();
$addItem->printResult();
 
class eBayGetSellerList
{
    private $_siteId = 77;  // default: Germany
    private $_environment = 'sandbox';   // toggle between sandbox and production
    private $_eBayApiVersion = 661;
    private $_call = 'GetSellerList';
    private $_keys = array(
        'production' => array(
            'DEVID'     => '',
            'AppID'     => '',
            'CertID'    => '',
            'UserToken' => '',
            'ServerUrl' => 'https://api.ebay.com/ws/api.dll'
            ),
        'sandbox' => array(
            'DEVID'     => '6daxxxxxxxxxxxxxxxxxxxxxxxxxx1e4622',
            'AppID'     => 'Mixxxxxxxxxxxxxxxxxxxxxxxxxxxxxx930',
            'CertID'    => '68xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00e',
            'UserToken' => 'AgAxxxxxxxxlaaaangxxxxxxxxxxIrGgYZ',
            'ServerUrl' => 'https://api.sandbox.ebay.com/ws/api.dll'
        )
    );
 
    private function _getRequestBody()
    {
        $apiValues = $this->_keys[$this->_environment];
 
        $dateNow = time();
        $date4weeksAgo = $dateNow-60*60*24*28;
 
        $search = array(
            '%%USER_TOKEN%%', '%%EBAY_API_VERSION%%', '%%STARTTIMEFROM%%', '%%STARTTIMETO%%'
        );
        $replace = array(
            $apiValues['UserToken'], $this->_eBayApiVersion, date('Y-m-d\TH:i:s.000\Z', $date4weeksAgo), date('Y-m-d\TH:i:s.000\Z', $dateNow)
        );
 
        $requestXmlBody = file_get_contents('GetInfo.xml');
        $requestXmlBody = str_replace($search,$replace, $requestXmlBody);
 
        return $requestXmlBody;
    }
 
    public function callEbay()
    {
        $apiValues = $this->_keys[$this->_environment];
 
        $connection = curl_init();
        curl_setopt($connection, CURLOPT_URL, $apiValues['ServerUrl']);
        curl_setopt($connection, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($connection, CURLOPT_SSL_VERIFYHOST, 0);
 
        $headers = array (
            'X-EBAY-API-COMPATIBILITY-LEVEL: ' . $this->_eBayApiVersion,
            'X-EBAY-API-DEV-NAME: ' . $apiValues['DEVID'],
            'X-EBAY-API-APP-NAME: ' . $apiValues['AppID'],
            'X-EBAY-API-CERT-NAME: ' . $apiValues['CertID'],
            'X-EBAY-API-CALL-NAME: ' . $this->_call,
            'X-EBAY-API-SITEID: ' . $this->_siteId,
        );
 
        curl_setopt($connection, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($connection, CURLOPT_POST, 1);
 
        $requestBody = $this->_getRequestBody();
 
        curl_setopt($connection, CURLOPT_POSTFIELDS, $requestBody);
        curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1);
        $responseXml = curl_exec($connection);
        curl_close($connection);
        $this->_responseXml = $responseXml;
        var_dump($responseXml);
    }
 
    public function printResult()
    {
        //Xml string is parsed and creates a DOM Document object
        $responseDoc = new DomDocument();
        $responseDoc->loadXML($this->_responseXml);
 
        //get any error nodes
        $errors = $responseDoc->getElementsByTagName('Errors');
 
        //if there are error nodes
        if($errors->length > 0)
        {
            echo '<P><B>eBay returned the following error(s):</B>';
            //display each error
            //Get error code, ShortMesaage and LongMessage
            $code     = $errors->item(0)->getElementsByTagName('ErrorCode');
            $shortMsg = $errors->item(0)->getElementsByTagName('ShortMessage');
            $longMsg  = $errors->item(0)->getElementsByTagName('LongMessage');
            //Display code and shortmessage
            echo '<P>', $code->item(0)->nodeValue, ' : ', str_replace(">", "&gt;", str_replace("<", "&lt;", $shortMsg->item(0)->nodeValue));
            //if there is a long message (ie ErrorLevel=1), display it
            if(count($longMsg) > 0) {
                echo '<BR>', str_replace(">", "&gt;", str_replace("<", "&lt;", $longMsg->item(0)->nodeValue));
            }
 
        } else { //no errors
            //get results nodes
            $responses = $responseDoc->getElementsByTagName("GetSellerListResponse");
            foreach ($responses as $response) {
                $acks = $response->getElementsByTagName("Ack");
                $ack   = $acks->item(0)->nodeValue;
                echo "Ack = $ack <BR />\n";   // Success if successful
 
                $totalNumberOfEntries  = $response->getElementsByTagName("TotalNumberOfEntries");
                $totalNumberOfEntries  = $totalNumberOfEntries->item(0)->nodeValue;
                echo "totalNumberOfEntries = $totalNumberOfEntries <BR />\n";
 
                $items  = $response->getElementsByTagName("Item");
 
                for($i=0; $i<$totalNumberOfEntries; $i++) {
                    $itemId = $items->item($i)->getElementsByTagName('ItemID')->item(0)->nodeValue;
                    $itemUrl = $items->item($i)->getElementsByTagName('ViewItemURL')->item(0)->nodeValue;
                    $startTime = $items->item($i)->getElementsByTagName('StartTime')->item(0)->nodeValue;
                    $endTime = $items->item($i)->getElementsByTagName('EndTime')->item(0)->nodeValue;
                    $bidCount = $items->item($i)->getElementsByTagName('BidCount')->item(0)->nodeValue;
                    $priceInEUR = $items->item($i)->getElementsByTagName('ConvertedCurrentPrice')->item(0)->nodeValue;
                    $status = $items->item($i)->getElementsByTagName('ListingStatus')->item(0)->nodeValue;
                    $title = $items->item($i)->getElementsByTagName('Title')->item(0)->nodeValue;
                    $watchCount = $items->item($i)->getElementsByTagName('WatchCount')->item(0)->nodeValue;
 
                    echo "itemID = $itemId <BR />\n";
                    echo "itemURL = $itemUrl <BR />\n";
                    echo "startTime = $startTime <BR />\n";
                    echo "endTime = $endTime <BR />\n";
                    echo "bidCount = $bidCount <BR />\n";
                    echo "priceInEUR = $priceInEUR <BR />\n";
                    echo "status = $status <BR />\n";
                    echo "title = $title <BR />\n";
                    echo "watchCount = $watchCount <BR />\n";
                }
            }
        }
    }
}

Die GetInfo.xml sieht folgendermaßen aus:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<GetSellerListRequest xmlns="urn:ebay:apis:eBLBaseComponents">
    <RequesterCredentials>
        <eBayAuthToken>%%USER_TOKEN%%</eBayAuthToken>
    </RequesterCredentials>
    <ErrorLanguage>en_US</ErrorLanguage>
    <Version>%%EBAY_API_VERSION%%</Version>
    <GranularityLevel>Coarse</GranularityLevel>
    <IncludeWatchCount>true</IncludeWatchCount>
    <StartTimeFrom>%%STARTTIMEFROM%%</StartTimeFrom>
    <StartTimeTo>%%STARTTIMETO%%</StartTimeTo>
    <Pagination>
        <EntriesPerPage>200</EntriesPerPage>
        <PageNumber>1</PageNumber>
    </Pagination>
    <WarningLevel>High</WarningLevel>
</GetSellerListRequest>

Bevor es funktioniert muß man natürlich noch seine API-Keys einfügen, siehe erster Artikel. Um die printResult() Funktion besser zu verstehen hier ein Bespiel des $responseXml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="UTF-8"?>
<GetSellerListResponse xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2010-04-3T11:25:37.003Z</Timestamp>
<Ack>Success</Ack>
<Version>661</Version>
<Build>E661_INTL_BUNDLED_10949245_R1</Build>
<PaginationResult>
    <TotalNumberOfPages>1</TotalNumberOfPages>
    <TotalNumberOfEntries>8</TotalNumberOfEntries>
</PaginationResult>
<HasMoreItems>false</HasMoreItems>
<ItemArray>
    <Item>
        <AutoPay>false</AutoPay>
        <BuyerProtection>ItemIneligible</BuyerProtection>
        <Country>US</Country>
        <Currency>USD</Currency>
        <GiftIcon>0</GiftIcon>
        <HitCounter>NoHitCounter</HitCounter>
        <ItemID>110044434434</ItemID>
        <ListingDetails>
            <StartTime>2010-03-27T12:44:13.000Z</StartTime>
            <EndTime>2010-03-28T12:44:13.000Z</EndTime>
            <HasUnansweredQuestions>false</HasUnansweredQuestions>
            <HasPublicMessages>false</HasPublicMessages>
            <BuyItNowAvailable>true</BuyItNowAvailable>
            <ExpressListing>false</ExpressListing>
        </ListingDetails>
        <ListingDuration>Days_1</ListingDuration>
        <Location>San Jose, CA</Location>
        <PrimaryCategory>
            <CategoryID>14111</CategoryID>
            <CategoryName>Everything Else:Test Auctions:General</CategoryName>
        </PrimaryCategory>
        <Quantity>1</Quantity>
        <ReviseStatus>
            <ItemRevised>false</ItemRevised>
        </ReviseStatus>
        <SellingStatus>
            <BidCount>0</BidCount>
            <BidIncrement currencyID="USD">0.25</BidIncrement>
            <ConvertedCurrentPrice currencyID="EUR">1.26</ConvertedCurrentPrice>
            <CurrentPrice currencyID="USD">1.71</CurrentPrice>
            <MinimumToBid currencyID="USD">1.71</MinimumToBid>
            <QuantitySold>0</QuantitySold>
            <SecondChanceEligible>false</SecondChanceEligible>
            <ListingStatus>Completed</ListingStatus>
        </SellingStatus>
        <ShippingDetails>
            <TaxTable/>
        </ShippingDetails>
        <ShipToLocations>US</ShipToLocations>
        <Site>US</Site>
        <TimeLeft>PT0S</TimeLeft>
        <Title>TTTEST IN SANDBOX BEFORE PROD - DO NOT BID</Title>
        <WatchCount>0</WatchCount>
        <PostalCode></PostalCode>
        <PictureDetails>
            <PhotoDisplay>None</PhotoDisplay>
        </PictureDetails>
        <ProxyItem>false</ProxyItem>
        <BuyerGuaranteePrice currencyID="EUR">20000.0</BuyerGuaranteePrice>
        <ReturnPolicy>
            <ReturnsAcceptedOption>ReturnsNotAccepted</ReturnsAcceptedOption>
            <ReturnsAccepted>Returns Not Accepted</ReturnsAccepted>
        </ReturnPolicy>
        <PaymentAllowedSite>US</PaymentAllowedSite>
    </Item>
    .....
    .....
</ItemArray>
<ItemsPerPage>200</ItemsPerPage>
<PageNumber>1</PageNumber>
<ReturnedItemCountActual>8</ReturnedItemCountActual>
</GetSellerListResponse>

Man erkennt natürlich einige Parallelen zur Auktionserstellung und kann das schön in eine Elternklasse auslagern.

Nachdem ich diese Funktion umgesetzt hatte, habe ich noch GetMyeBaySelling gefunden, mit der man die einzelnen Listen (ActiveList, BidList, DeletedFromSoldList, DeletedFromUnsoldList, ScheduledList, SoldList und UnsoldList) erhält, was natürlich sehr viel nützlicher ist.

Written by Michael Kliewe

April 12th, 2010 at 10:29 am

Posted in PHP

Tagged with , , , ,