Retrieving events from Google Calendar - php

I am trying to retrieve the XML data for Google Calendar. Authentication and retrieval all works. However, when I retrieve the events, gd: data isn't included as the protocol reference documents it would be (http://code.google.com/apis/calendar/data/2.0/developers_guide_protocol.html#RetrievingWithoutQuery)
Some error messages I'm running into depending on how I'm referencing the "when" node with attribute "startTime" (my ultimate goal in this anecdote) are as follows:
Fatal error: Call to a member function attributes() on a non-object in .../googlecalendarwrapper.php on line 226
when it looks like 'startTime'=> (string) $cal->when->attributes()->startTime,
GoogleCalendarWrapper_Model::getEventsList() [googlecalendarwrapper-model.geteventslist]: Node no longer exists when it looks like 'startTime'=> strval($cal->when->attributes()->startTime),
strval() [function.strval]: Node no longer exists when it looks like 'startTime'=> strval($cal->when->attributes()), and 'startTime'=> strval($cal->when->attributes('startTime')),
Code looks like:
$xml = new SimpleXMLElement($this->get($url, $header));
$calendars = array();
foreach ($xml->entry as $cal){
$calendars[] = array(
'id'=>strval($cal->id),
'published'=>strval($cal->published),
'updated'=>strval($cal->updated),
'title'=>strval($cal->title),
'content'=>strval($cal->content),
'link'=>strval($cal->link->attributes()->href),
'authorName'=>strval($cal->author->name),
'authorEmail'=>strval($cal->author->email),
'startTime'=> strval($cal->when->attributes()),
);
}
XML:
[0] => SimpleXMLElement Object
(
[id] => http://www.google.com/calendar/feeds/braden.keith%40smartersys.com/private/full/7li4mr2c81mub1hcoqktn73fbo
[published] => 2010-06-08T17:17:43.000Z
[updated] => 2010-06-08T17:17:43.000Z
[category] => SimpleXMLElement Object
(
[#attributes] => Array
(
[scheme] => http://schemas.google.com/g/2005#kind
[term] => http://schemas.google.com/g/2005#event
)
)
[title] => title
[content] => content
[link] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[rel] => alternate
[type] => text/html
[href] => https://www.google.com/calendar/hosted/smartersys.com/event?eid=N2xpNG1yMmM4MW11YjFoY29xa3RuNzNmYm8gYnJhZGVuLmtlaXRoQHNtYXJ0ZXJzeXMuY29t
[title] => alternate
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[rel] => self
[type] => application/atom+xml
[href] => https://www.google.com/calendar/feeds/braden.keith%40smartersys.com/private/full/7li4mr2c81mub1hcoqktn73fbo
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[rel] => edit
[type] => application/atom+xml
[href] => https://www.google.com/calendar/feeds/braden.keith%40smartersys.com/private/full/7li4mr2c81mub1hcoqktn73fbo/63411700663
)
)
)
[author] => SimpleXMLElement Object
(
[name] => Braden Keith
[email] => braden.keith#smartersys.com
)
)

According to this article: http://www.sitepoint.com/blogs/2005/10/20/simplexml-and-namespaces/
You have to approach namespaces a tad differently with SimpleXMLElement. The solution is as follows:
$xml = new SimpleXMLElement($this->get($url, $header));
$xml->asXML();
$calendars = array();
foreach ($xml->entry as $cal){
$ns_gd = $cal->children('http://schemas.google.com/g/2005');
$calendars[] = array(
'id'=>strval($cal->id),
'published'=>strval($cal->published),
'updated'=>strval($cal->updated),
'title'=>strval($cal->title),
'content'=>strval($cal->content),
'link'=>strval($cal->link->attributes()->href),
'authorName'=>strval($cal->author->name),
'authorEmail'=>strval($cal->author->email),
'startTime'=> strval($ns_gd->when->attributes()->startTime),
);
}
Note the $ns_gd = $cal->children('http://schemas.google.com/g/2005'); - this defines the namespace. Then from there, $ns_gd->when->attributes()->startTime gets the attribute from gd:when named startTime.
Man it's been a bloody 2 days. But I figured it out. Hopefully this can help someone down the road.

Related

Simplexml_load_string Entity parser error Start tag expected, '<' not found

I receive this warning when I try to get data from a call, I've tried with some solution for the same topic in stackoverflow but it doesn't work.
[2] simplexml_load_string(): Entity: line 4: parser error : Start tag expected, '<' not found
simplexml_load_string(): ^
the php code is as follow
$api = new MktApi();
$arr = array();
$xlm = $api->handleResponse($api->getBrands());
print_r($xlm);
$xml = simplexml_load_string($xlm);
and the print I have is like this
SimpleXMLElement Object ( [Head] => SimpleXMLElement Object ( [RequestId] => SimpleXMLElement Object ( ) [RequestAction] => GetBrands [ResponseType] => Brands [Timestamp] => 2017-05-04T16:29:44-0500 ) [Body] => SimpleXMLElement Object ( [Brands] => SimpleXMLElement Object ( [Brand] => Array ( [0] => SimpleXMLElement Object ( [BrandId] => 22912 [Name] => DC Comics [GlobalIdentifier] => 101020216193 ) [1] => SimpleXMLElement Object ( [BrandId] => 23324 [Name] => MIOS [GlobalIdentifier] => 101020216475 ) [2] => SimpleXMLElement Object ( [BrandId] => 32298 [Name] => 988 [GlobalIdentifier] => SimpleXMLElement Object ( ) ) [3] => SimpleXMLElement Object ( [BrandId] => 30015 [Name] => About Time [GlobalIdentifier] => SimpleXMLElement Object ( ) )
it's look like correct XML, I've tried to add the xml header but I still have the same issue.
It looks like $api->handleResponse(...) returns a SimpleXMLElement object. You don't need to parse it again.

Getting objects instead of object properties in array

When I set $sales like so $sales = $response->xml->transactions the contents look like:
SimpleXMLElement Object
(
[transaction] => Array
(
[0] => SimpleXMLElement Object
(
[transId] => 9999999999
[submitTimeUTC] => 2016-03-16T21:57:54Z
[submitTimeLocal] => 2016-03-16T14:57:54
[transactionStatus] => capturedPendingSettlement
[invoiceNumber] => 4b1008a87f5262f0c867
[firstName] => Foo
[lastName] => Bar
[accountType] => Visa
[accountNumber] => XXXX1414
[settleAmount] => 155.00
[marketType] => eCommerce
[product] => Card Not Present
)
[1] => SimpleXMLElement Object
(
[transId] =>
So ->transaction contains an array. But if I do this:
$sales = $response->xml->transactions->transaction;
foreach ($sales as $s) {
$list[]= $s->invoiceNumber;
}
$list contains
Array
(
[0] => SimpleXMLElement Object
(
[0] => ac502c094fe1722ba100
)
[1] => SimpleXMLElement Object
(
[0] => e2eb58351c87155e3720
)
[2] => SimpleXMLElement Object
(
[0] => 0bca2bb6d5a13e641b67
)
What am I doing wrong? Where are the SimpleXMLElement Objects coming from where I just expected the invoiceNumber string?
The reason you are getting the SimpleXMLElement type objects is because when you are doing $list[]= $s->invoiceNumber; you are adding the element as it is. Since it is part of the SimpleXMLElement object it has that type internally. This comes up a lot when working with SimpleXML so its good to keep in mind.
As mentioned in the comments casting to a string will give you just the value:
$list[] = (string) $s->invoiceNumber;

PHP - How to read data from SOAP XML

I have code for read XML SOAP 1.2 from web service.
Im using this: https://stackoverflow.com/a/18580428/2629513
I get this code below:
SimpleXMLElement Object
(
[OdkazyResponse] => SimpleXMLElement Object
(
[OdkazyResult] => SimpleXMLElement Object
(
[odkazy] => SimpleXMLElement Object
(
[odkaz] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[kod_zbozi] => 31400001
[typ] => OBR1
[popis] => Oki ML 280 - foto
[url] => http://www.atcomp.cz/katalog/31400001/ML280.gif
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[kod_zbozi] => EC376123GB
[typ] => OBR1
[popis] => Malý obrázek
[url] => http://www.atcomp.cz/katalog/EC376123GB/lq-680_-_maly.jpg
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[kod_zbozi] => EC376123GB
[typ] => OBR2
[popis] => Velký obrázek
[url] => http://www.atcomp.cz/katalog/EC376123GB/lq-680_-_velky.jpg
)
)
And how I can read the [kod_zbozi], [typ], [popis], [url] attributes? I need to save it into my mysql database (this is not problem, the problem is read the data from this format XML). Thanks.
Well, the very first thing you might want to do is to convert that object into an array (to avoid naming problems)
You can use this function to do that:
function object2array($object) {
return json_decode(json_encode($object), true);
}
then something like this:
$data = object2array(simplexml_load_string('....'));
print_r($data); // Its regular array now, use it keys to access values, then simply insert them into db

I'm trying to find an attribute using simpleXML

I have a simpleXML output of:
SimpleXMLElement Object
(
[#attributes] => Array
(
[version] => 2
)
[currentTime] => 2013-02-05 21:26:09
[result] => SimpleXMLElement Object
(
[rowset] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => characters
[key] => characterID
[columns] => name,characterID,corporationName,corporationID
)
[row] => Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Wrytha Cy
[characterID] => 209668693
[corporationName] => Deep Core Mining Inc.
[corporationID] => 1000006
)
)
[1] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Eve Mae
[characterID] => 624980803
[corporationName] => Viziam
[corporationID] => 1000066
)
)
[2] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Wrytha
[characterID] => 709227913
[corporationName] => The Flying Tigers
[corporationID] => 669350666
)
)
)
)
)
[cachedUntil] => 2013-02-05 21:35:04
)
I would like to loop through with my php loop and get "name' and "characterID". I've trying something like:
$simpleXML = simplexml_load_string($xml);
foreach ($simpleXML->result->rowset->row as $row) {
print_r($row);
$name = $row['#attributes']['name'];
echo $name.'<br>';
}
but $name is not being set. It's gonna be something simple, just not seeing it in my haste and first time with simpleXML.
Attributes are accessed using the syntax $element['attribute_name'], so in your case, you need $row['name'].
It's important to remember that SimpleXML objects are kind of magic - the $element->child, $element_list[0] and $element['foo'] syntax overloads the normal PHP logic to be useful. Similarly, (string)$element will give you the full textual content of an element, however it is broken up in the actual XML.
As such, the print_r output will not give you a "real" view of the object, so should be used with care. There are a couple of alternative debug functions I've written here which give a more accurate idea of how the object will behave.

How can I properly parse a SimpleXML Object in PHP?

I'm using the CloudFusion class to get Amazon.com data and my code is simple:
$items = $pas->item_search( "shoes", array(
"ResponseGroup" => "Small",
"SearchIndex" => "Blended" ));
$items = $items->body->Items;
echo "<pre>";
print_r( $items );
echo "</pre>";
This returns the following:
SimpleXMLElement Object (
[Request] => SimpleXMLElement Object
(
[IsValid] => True
[ItemSearchRequest] => SimpleXMLElement Object
(
[Keywords] => shoes
[ResponseGroup] => Small
[SearchIndex] => Blended
)
)
[TotalResults] => 737435
[TotalPages] => 245816
[SearchResultsMap] => SimpleXMLElement Object
(
[SearchIndex] => Array
(
[0] => SimpleXMLElement Object
(
[IndexName] => Kitchen
....
)
[Item] => Array
(
[0] => SimpleXMLElement Object
(
[ASIN] => B0001Z95QY
[DetailPageURL] => http://www.amazon.com/Household-Essentials-MS6030-Seasonal-Storage/dp/B0001Z95QY%3FSubscriptionId%3D0WASFFPR5B82TH4ZQB82%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB0001Z95QY
[ItemLinks] => SimpleXMLElement Object
(
[ItemLink] => Array
(
[0] => SimpleXMLElement Object
(
[Description] => Technical Details
[URL] => http://www.amazon.com/Household-Essentials-MS6030-Seasonal-Storage/dp/tech-data/B0001Z95QY%3FSubscriptionId%3D0WASFFPR5B82TH4ZQB82%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3DB0001Z95QY
) ....................
)
[1] => SimpleXMLElement Object
(
[ASIN] => B001ACNBZ8
[DetailPageURL] => http://www.amazon.com/Peet-Shoe-Dryer-Boot-Original/dp/B001ACNBZ8%3FSubscriptionId%3D0WASFFPR5B82TH4ZQB82%26tag%3Dws%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB001ACNBZ8
[ItemLinks] => SimpleXMLElement Object
(...................
)
)
What I'd like to do is get down to the "Item" level, then run a foreach to get each individual entry. I tried $items = $items->Item, but this returns only the first entry.
Any ideas?
First of all, you should avoid using print_r() on SimpleXMLElement, instead just take a look at the XML using asXML(). That's also what you should post here, instead of print_r()'s output.
I can't decipher the code you have posted so I'll take a wild guess and suggest that you try something like:
foreach ($items->body->Items->Item as $Item)
{
}
At any rate, if you want to iterate over something, foreach is the answer.

Categories