I am trying to retrieve information on users using the Microsoft Graph Library for PHP.
But this code runs into the error Trying to get property 'getGivenName' of non-object.
$user = $graph->createRequest("GET", "/users")
->setReturnType(Model\User::class)
->execute();
This is due to the fact, that $user is an array instead of an object!? What is wrong with the SDK (or my code)?
Is there any better documentation for the SDK???
This is due to the fact, that $user is an array instead of an object!?
That's right, since the endpoint GET Users returns the list of users, in the provided example:
$users = $graph->createRequest("GET", "/users")
->setReturnType(\Microsoft\Graph\Model\User::class)
->execute();
$users contains an array of objects of Microsoft\Graph\Model\User type, and
$givenName = $users[0]->getGivenName();
gives GivenName property of first item in array.
A specific user could be requested via GET /users/{id | userPrincipalName} endpoint:
$user = $graph->createRequest("GET", "/users/{$userId}")
->setReturnType(\Microsoft\Graph\Model\User::class)
->execute();
In that case $user object is of Microsoft\Graph\Model\User type:
$givenName = $user->getGivenName();
Update
setReturnType function accept Microsoft Graph API entity type name, in your example it appears Model\User points to type which doesn't belong to Microsoft\Graph\Model namespace and as a result JSON response is not getting deserialized into class instance.
Instead of
setReturnType(Model\User::class)
try to specify fully qualified class name:
setReturnType(\Microsoft\Graph\Model\User::class)
Related
Situation:
We have an old application that is creating events in outlook (via MAPI). To identify the events the custom property 'CTOID' is set with a specific value by which the events can be found again.
For a newer application we would like to use the Graph API but the application should still be able to read/find the events created by the old application. So I created a test event with a specific CTOID and I can already use the graph client to get the mentioned event with the according property and its value (queryOptions is just some start-/enddate restrictions).
// Initialize the GraphServiceClient.
GraphServiceClient client = await m_MicrosoftGraphClient.GetGraphServiceClient();
// Load user events.
var request = client.Users[userId].CalendarView.Request(queryOptions).Expand("singleValueExtendedProperties($filter=id%20eq%20'Double%20{00020329-0000-0000-C000-000000000046}%20Name%20CTOID')");
var result = await request.GetAsync();
var calendarEvents = result.CurrentPage;
Result:
The event gets fetched correctly including the value for the CTOID property.
Problem:
I can "Expand" events so they contain the value for the CTOID property. But how do I find an event with a specific CTOID value? And specifically, how do I do this with the Graph client in C#?
According to the documentation and this Stackoverflow post, the following REST call should work:
GET /users/{id|userPrincipalName}/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq '{id_value}' and ep/value eq '{property_value}')
So I tried this in the online Graph Explorer:
https://graph.microsoft.com/v1.0/users/[MY_USER_ID]/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq 'Double {00020329-0000-0000-C000-000000000046} Name CTOID' and ep/value eq '229236')
But all I get as response is:
{
"error": {
"code": "ErrorInvalidUrlQueryFilter",
"message": "The filter expression for $filter does not match to a single extended property and a value restriction.",
"innerError": {
"date": "2020-08-03T12:44:05",
"request-id": "33e82c77-92ea-4865-a8d0-00cfc2f99154"
}
}
}
What am I doing wrong? I'm out of ideas and any help would be greatly appreciated.
(Also if you have any idea how to do this with the Graph client in C# and not just the bare REST call).
Additional Information:
Don't know if it's important, but the following permissions are set for our application:
In your filter you need to cast the value to a Double eg
https://graph.microsoft.com/v1.0/users/[MY_USER_ID]/events?$filter=singleValueExtendedProperties/Any(ep: ep/id eq 'Double {00020329-0000-0000-C000-000000000046} Name CTOID' and cast(ep/value, Edm.Double) eq 229236)
For anything other then a String in a filter you need to do this
$user = $graph->createRequest("GET", "/me")
->setReturnType(Model\User::class)
->execute();
How can I know the return type of /me call is Model\User::class?
To determine endpoint entity type the following approach could be considered. Set Accept header to odata.metadata=full to return #odata.type property along with data in response payload(refer OData spec for a more details)
Example
$resp = $client->createRequest("GET", "/me")
->addHeaders(array(
"Accept" => "application/json;odata.metadata=full;odata.streaming=true"
))
->execute();
$entity = $resp->getBody();
$entityType = $entity["#odata.type"];
Result
For the provide example $entityType returns #microsoft.graph.user which corresponds to Microsoft\Graph\Model\User type from msgraph-sdk-php
According to the document, I can list the Office 365 Groups by using the following Graph API:
GET https://graph.microsoft.com/v1.0/groups
I have a C# Web application, and there is a input for searching by the Group DisplayName. Any idea how to query groups based on the DisplayName?
I have tried the following URL: https://graph.microsoft.com/v1.0/groups?$search="displayName:Test" in the MS Graph Explorer which didn't work.
I get the following error.
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "This query is not supported.",
"innerError": {
"request-id": "35d90412-03f3-44e7-a7a4-d33cee155101",
"date": "2018-10-25T05:32:53"
}
}
Any suggestion is welcomed.
Thanks in advance.
According to your description, I assume you want to search the Group by the DisplayName using the search parameters.
Based on this document, we can currently search only message and person collections. So we couldn't use the search parameter.
We can use the filter query parameter to search the Group by DisplayName. For example, we can search the groups whose displayName is start with 'Test',the request url like this:
https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'Test')
Here is C# code that I wrote to get a group using the DisplayName. This code requires a reference to the OfficeDevPnP.Core.
private static async Task<Group> GetGroupByName(string accessToken, string groupName)
{
var graphClient = GraphUtility.CreateGraphClient(accessToken);
var targetGroupCollection = await graphClient.Groups.Request()
.Filter($"startsWith(displayName,'{groupName}')")
.GetAsync();
var targetGroup = targetGroupCollection.ToList().Where(g => g.DisplayName == groupName).FirstOrDefault();
if (targetGroup != null)
return targetGroup;
return null;
}
UPDATE
I see that the answer has already been accepted, but I came across the same issue and found that this answer is out of date. For the next person, this is the update:
The 'search' functionality does work. Whether it was fixed along the way or always has, I am not sure.
'groups' support search,
both the v1 and beta api support search,
search only works on 'displayName' and 'description' fields,
searching on 'directory objects' require a special header: 'ConsistencyLevel: eventual'
Point number 4 is what tripped me up!
Your request would look like this:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Test"
With the request header:
ConsistencyLevel: eventual
There is another catch: You can only specify the first 21 characters and the search always uses 'startsWith'. You're out of luck if you specify more than that: The search always fails.
I'm trying to use Facebook iOS SDK 3.5 for publishing an Open Graph action. My action is:
take a photo, and photo has an additional required string property named filter.
I am creating my graph object (all values are valid and working):
NSMutableDictionary<FBOpenGraphObject> *object =
[FBGraphObject openGraphObjectForPostWithType:#"tonerapp:photo"
title:#"photo"
image:imageData
url:nil
description:title];
Then I add my filter:
object[#"tonerapp:filter"] = filterName;
I try to post the object, and I can confirm that my filter property is there (enabled FBSetting logging behavior for URL requests to show request data):
Body (w/o attachments):
object: {"description":"","type":"tonerapp:photo",
"tonerapp:filter":"classic","data":{},
"fbsdk:create_object":true,
"image":{"url":"fbstaging:\/\/graph.facebook.com\/staging_resources\/MDExMDE1MjkzNzU1Njc3MDE0MjoxNTM4NzgwNjUy","user_generated":"true"},
"title":"photo"}
I can see my filter property there, but the response is this:
error = {
code = 100;
message = "(#100) Object Missing a Required Value:
Object at URL '' of type 'tonerapp:photo' is invalid because
a required property 'tonerapp:filter' of type 'string' was not provided.";
type = OAuthException;
};
Well, it IS there. I tried all possible combinations such as:
object[#"data"] = #{#"tonerapp:filter": filterName}; //wrapping into the data object
object[#"data"] = #{#"filter": filterName}; //wrapping into data and removing namespace
object[#"toner:filter"] = filterName; //app name instead of namespace name
object[#"filter"] = filterName; //no namespace name at all
[object setObject:filterName forKey:#"tonerapp:filter"]; //setobject notation
[object setValue:filterName forKey:#"tonerapp:filter"]; //setvalue notation
[object setObject:filterName forKey:#"filter"]; //setobject AND without namespace...
and possibly more. I've tried everything, but the API always fails with the same error. I can verify the rest of the object is correct, if I go to my app in Facebook and set filter as optional instead of required, it posts successfully. Is it a bug/insufficient documentation with the Graph API, or am I so blind that I can't see something obvious here?
Thanks,
Can.
just put them under "data"
object[#"data"][#"youcustomproperty"] = #"smth";
Be sure your filterName is URL encoded. I had the same kind of issue with the name of a movie which was also a custom action on the graph. Try just to post a manual value only a simple string and let us know.
I'm accessing the Google places API using HTTParty. Here's my code.
query = GOOGLE_API["search"].merge(:location => latlng.join(","))
response = HTTParty.get(GOOGLE_API["search"]["url"], :query => query)
#businessInfo = response
#business info contains a string of data from Google as expected, however, when I try to acccess the items using #businessInfo.index(0).item like I would with data from my database, I get nil.
This is a sample of what is contained in the variable -- {"html_attributions"=>[], "results"=>[{"geometry"=>{"location"=>{"lat"=>33.762835, "lng"=>-84.392724}}, "icon"=>"http://maps.gstatic.com/mapfiles/place_api/icons/art_gallery-71.png", "id"=>"c551a5fdc78c273e6f498aa920733037199ebe01", "name"=>"World of Coca-Cola", "reference"=>"CnRoAAAAvpKSnn971Ur5ABYStk-EJfMvyFFFlBtd9LzwRT4H-PF50vS0CQtDCGkoW0QqKLHwFHV7Qmj32bgg-KjthkVENsBpGPxNAq_vcg4do-TQyi97y6mKxf3qUgoGxzGHePEAcqg15aATTl6Xdsq7Pl2b6hIQpzVIr4KO4ZDSx4tIqcH-ARoUPn-9yBSLi35lBM7gFm2KTPGREa0", "types"=>["art_gallery", "store", "establishment"], "vicinity"=>"Baker Street Northwest, Atlanta"}, {"geometry"=>{"location"=>{"lat"=>33.759925, "lng"=>-84.387158}}, "icon"=>"http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png", "id"=>"32815dbf0963cb55dee871b96cc5100335f40400", "name"=>"Hard Rock Cafe Atlanta", "reference"=>"CnRtAAAApKIX3M3emqAzdsN3f0ntsi-M-
My question is, What syntax do I use to access the items and values so that I can work with them.
Thanks.
Your response object is an hash so you can access your response content in the following way:
puts response["results"]