Sorting sheets in Google Drive Spreadsheet using PHP API - php

I have a SpreadSheet on Google Drive and I'm updating the content using PHP API (https://developers.google.com/sheets/api/guides/values).
I store here reports from my projects. Each project has its sheet.
When the project has no sheet (new project), I create a new sheet for this project called by the name of a new project.
The sheets is created as a last one.
This is my current code to create a new Sheet:
$body = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest(
['requests' => ['addSheet' => ['properties' => ['title' => $project_name]]]]
);
$result = $service->spreadsheets->batchUpdate($spreadsheetId, $body);
I would like to have sheets sorted alphabetically. Excluding the first sheet, where are some global statistics.
Is there any way to change the order of the sheets using Google SpreadSheet API?

This would be the workflow:
Each time after creating a new sheet use the method spreadsheets.get and retrieve the sheets of the spreadsheet
Retrieve the ids and titles of the sheets, pass the ids into an array and sort the position of the ids as a function of title, as performed here
Perform an UpdateSheetPropertiesRequest, specifying the SheetProperty "index" - which will move the sheet to a position corresponding to the position of the sheetId in the alpahabetically sorted array.

I just found the solution ;-)
$requests = [
new Google_Service_Sheets_Request([
'updateSheetProperties' => [
'fields' => 'index',
'properties' => [
'sheetId' => $sheet_id,
'index' => $i,
],
],
])
];
$batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest([
'requests' => $requests
]);
$result = $service->spreadsheets->batchUpdate($spreadsheetId, $batchUpdateRequest);

Related

Setting spreadsheet title with Guzzle in PHP

I am connected to my Google sheets, when I run a post request for https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create and set no properties, it creates a new spreadsheet.
I would love to add a title so I did this
$options = [
'form_params' => [
'properties' => [
'title' => 'A new title'
]
]
];
$client->post('v4/spreadsheets', $options);
I am using Guzzle to make this call. As a response I'm getting HTTP status code 400 (Bad Request) when adding title to form params.
How can I solve this?
You really should be using Google's SDK for this since they already have support for one in PHP.
According to their docs, sheet properties are set in a Google_Service_Sheets_SpreadsheetProperties instance which takes the title property.
An example from their docs:
<?php
$spreadsheet = new Google_Service_Sheets_Spreadsheet([
'properties' => [
'title' => $title
]
]);
$spreadsheet = $service->spreadsheets->create($spreadsheet, [
'fields' => 'spreadsheetId'
]);
printf("Spreadsheet ID: %s\n", $spreadsheet->spreadsheetId);

Upload a File to a Task on Cerb API

At the moment I am adding a task to Cerb using the API (Docs: https://cerb.ai/docs/api/). I can add and edit comments on the task.
An extension is to add file uploads. The API documentation seems to be extremely limited in terms of file uploads and isn't helping much. I have based my current code on https://cerb.ai/docs/api/endpoints/records/#update, using a custom field linked to the task and posting directly to the API.
The process is as follows:
1 - User inserts information on a Laravel form
2 - Form is submitted, task is created
3 - If the user entered a comment or description, the controller then uses the ID from the newly created task toa dd the comment
4 - If the user adds a file, the controller should then use the same ID from the task to attach the file
Task and comment adding has been done through models, which were previously done directly through the API and reformatted once they worked.
Add Task:
$params = [
'title' => $request->input('title'),
'links' => ['project:'.$request->input('project')],
'priority' => $request->input('priority'),
'status_id' => 2
];
$due_date = $request->input('due');
if(!empty($due_date)){
$params['due'] = strtotime($due_date);
}
$success_task = $task->addUpdateRecord('tasks.add', $params);
Add Comment:
$params = [
'author__context' => 'bot',
'author_id' => 3,
'comment' => empty($comment_input) ? request()->comment : $comment_input,
'target__context' => 'task',
'target_id' => $task_id,
'author' => Auth::user()->name // custom field
];
$success = $comment->addUpdateRecord('comments.add', $params);
The addUpdateRecord() essentially does the same thing as the file upload as below:
$cerb = new CerbApi();
$out = $cerb->put($root.'records/file_bundle/1054.json?expand=custom_', $putfields);
$putfields contains a normal file upload object.
I'm getting the following error on request:
array:2 [▼
"__status" => "error"
"message" => "Unknown command (root/records/task/1054.json)"
]
(root removed for confidentiality)
Has anyone worked with this? Anyone able to assist?
Ended up getting it right by using the attachments record type https://cerb.ai/docs/records/types/attachment/ and creating a model for it with its own addUpdateRecord() method.
I then used the records API to do the post for the file as the first step instead of the last one:
$file_upload = new File;
// Get file contents
$data = file_get_contents($file);
// Base64 encode contents
$data = base64_encode($data);
$file_params = [
'name' => $file->getClientOriginalName(),
'content' => $data
];
// Do upload
$file_success = $file_upload->addUpdateRecord('files.add', $file_params);
// Only need to return the file ID to link it to the task
return $file_success["data"]["id"];
And then using the ID that was being returned to link it to the task:
$task = new Task();
$params = [
'title' => $request->input('title'),
'links' => [
'project:'.$request->input('project'),
'file:'.$file_id
],
'priority' => $request->input('priority'),
'status_id' => 2
];
I hope this helps someone in the future.
Note: Cerb API Version 9.2.0

incrementing a field in firestore (php)

I am looking for a way to increment a field in firestore like in this documentation.
shard_ref.update("count", firebase.firestore.FieldValue.increment(1));
The only caveat is that I am trying to use firestore Client Sdk or the Admin Sdk for php.
What is a clean solution for incrementing a field in php. Does it require both read and write operations or is it possible with only write operation?
Firestore Client Sdk has the ability to increment a field. (use negative values to decrement).
You can use it in the following way to update the field with $field_name:
$data = [
[
'path' => $field_name,
'value' => \Google\Cloud\Firestore\FieldValue::increment($increment_value);
]
];
$doc_ref->update($data);
If you are using a batching you call it as follows
$data[$field_name] = \Google\Cloud\Firestore\FieldValue::increment($increment_value);
$batch->add_to_batch('update', $doc_ref, $data);
Here is additional reference
if you have more data you can do
$data = [
'name' => $name,
'email' => $email,
'likes'=> \Google\Cloud\Firestore\FieldValue::increment(1) // Add + 1
] ;

google classroom announcements create + php api (materials)

I am using google Classroom google API and Google APIs Client Library for PHP.
I can add announcement, but I cannot add materials.
I would like to add files to Google Drive, but I have errors even with "link"
My code so far:
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setApplicationName("test classroom");
$client->setAuthConfig($KEY_FILE_LOCATION);
$client->setScopes(['https://www.googleapis.com/auth/classroom.courses',
"https://www.googleapis.com/auth/classroom.rosters",
"https://www.googleapis.com/auth/classroom.announcements",
"https://www.googleapis.com/auth/classroom.coursework.students",
"https://www.googleapis.com/auth/classroom.coursework.me",
]);
// $service implements the client interface, has to be set before auth call
$service = new Google_Service_Classroom($client);
$text="some text";
$link="http://someurl";
$glink = new Google_Service_Classroom_Link($link);
$glink->setUrl($link);
$params = [
"text" => $text,
"materials" => [
"link" => $glink,
],
];
$params_obj = new Google_Service_Classroom_Announcement($params);
$service->courses_announcements->create($course_classid, $params_obj);
//tried also with:
$params = [
"text" => $text,
"materials" => [
"link" => ((new Google_Service_Classroom_Material())->setLink($glink)) ,
],
];
the error:
"message": "materials: Link materials must have a URL.",
So off the top, it seems odd here that you are creating params associative arrays at all. The PHP client has methods for adding all parameters, all the way down to the leaf level. So you shouldn't see any arrays in your code. Continue to use the methods instead and it will help clean things up. If you're still having problems, I may have some time to dig on this particular item.
Your limk must be array with three entry
$params = [
"text" => 'Please, do your homeworks until Monday',
"materials"=>['link'=>['url'=>'https://www.examaker.com',
'title'=>'HW',
'thumbnailUrl'=>'https://examaker.com/apps/imgs/logo_40.png']
]
];

Channel-wise Google adsense information

I am using adsense Management API and followed everything there to generate a demo report as it is described in the example on their site.
The information I am currently fetching uses this information :
$startDate = '2012-03-01';
$endDate = '2012-04-18';
$optParams = array(
'filter' => array(
'AD_CLIENT_ID==' . $adClientId
),
'metric' => array(
'CLICKS', 'PAGE_VIEWS','COST_PER_CLICK','EARNINGS'
),
'dimension' => array('DATE'),
'sort' => 'DATE'
);
What I have to ask is is it possible to arrange this data according to the channels So that I get channel-wise information on EARNING, COST_PER_CLICK and PAGE_VIEWS. And how?
Assuming you're talking about custom channels, all you have to do is add one of the following to your list of dimensions, depending on what you prefer:
CUSTOM_CHANNEL_NAME
CUSTOM_CHANNEL_ID
CUSTOM_CHANNEL_CODE
You can think of dimensions as groups, that is, what you're organising your data by.
You can check this blog post for some more info.

Categories