I am confused about the new Google Sheets API v4. My question is: how can I set validation rules for specified column(s) in spreadsheet?
There is no useful tutorial with description how to use appropriate methods.
Result should look like following sample:
That validation should be set before data upload (which works fine).
My current code:
$client = getClient();
$service = new Google_Service_Sheets($client);
$fileId = 'my-document-id';
$body = new Google_Service_Sheets_SetDataValidationRequest(array(
'setRange' => new Google_Service_Sheets_GridRange(
array(
'sheetId'=>'List1',
'startColumnIndex'=>'0',
'endColumnIndex'=>'1'
)
),
'setRule' => new Google_Service_Sheets_DataValidationRule(
array(
'setValues'=>array('YES','NO')
)
)
));
$sheetReq = new Google_Service_Sheets_Request($client);
$sheetReq->setSetDataValidation($body);
$batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest(array(
'requests' => $sheetReq
));
$result = $service->spreadsheets->batchUpdate($fileId, $batchUpdateRequest);
Thank you #random-parts for help, it has brought me to the right track. If someone else will try to solve similar problem in PHP in feature, please find bellow fully working example:
$client = $this->getClient();
$service = new Google_Service_Sheets($client);
$ary_values = ['yes','nope','maybe','never ever'];
foreach( $ary_values AS $d ) {
$cellData = new Google_Service_Sheets_ConditionValue();
$cellData->setUserEnteredValue($d);
$values[] = $cellData;
}
$conditions = new Google_Service_Sheets_BooleanCondition();
$conditions->setType('ONE_OF_LIST');
$conditions->setValues($values);
$setRule= new Google_Service_Sheets_DataValidationRule();
$setRule->setCondition($conditions);
$setRule->setInputMessage('Please set correct value');
$setRule->setShowCustomUi(true);
$range = new Google_Service_Sheets_GridRange();
$range->setStartRowIndex(1);
$range->setEndRowIndex(5);
$range->setStartColumnIndex(1);
$range->setEndColumnIndex(2);
$range->setSheetId(YOUR_SHEET_ID); //replace this by your sheet ID
$valReq = new Google_Service_Sheets_SetDataValidationRequest();
$valReq->setRule($setRule);
$valReq->setRange($range);
$sheetReq = new Google_Service_Sheets_Request();
$sheetReq->setSetDataValidation($valReq);
$bodyReq = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
$bodyReq->setRequests($sheetReq);
$result = $service->spreadsheets->batchUpdate($fileId, $bodyReq);
The DataValidationRule object would look like the following:
"rule": {
"condition": {
"type": "ONE_OF_LIST",
"values": [
{ userEnteredValue: "Yes"},
{ userEnteredValue: "No"}
],
},
"inputMessage": "",
"strict": true,
"showCustomUi": true,
}
You want to use rule.condition.type ONE_OF_LIST and then enter the rule.condition.values you want in the list. showCustomUi will show the dropdown
A full example using google apps script from the Sheets script editor:
function setDataVal () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var validation = {
"setDataValidation": {
"range": {
"sheetId": sheet.getSheetId(),
"startRowIndex": 1,
"endRowIndex": 5,
"startColumnIndex": 1,
"endColumnIndex": 5,
},
"rule": {
"condition": {
"type": "ONE_OF_LIST",
"values": [
{ userEnteredValue: "Yes"},
{ userEnteredValue: "No"}
],
},
"inputMessage": "",
"strict": true,
"showCustomUi": true,
}
},
}
var req = {
"requests": [validation],
"includeSpreadsheetInResponse": false,
}
Sheets.Spreadsheets.batchUpdate(req, ss.getId())
}
Sheets API advanced service will have to be enabled
Related
I'm using following package : 'osiset/Basic-Shopify-API' and need bulk update products by location.
It's only possible with GraphQL. This function should work :
inventoryBulkAdjustQuantityAtLocation Shopify documentation
$shop = 'example.myshopify.com';
$token = 'shppa_admin_api_token';
/ Create options for the API
$options = new Options();
$options->setVersion('2020-04');
// Create the client and session
$api = new BasicShopifyAPI($options);
$api->setSession(new Session($shop, $token));
$products[0]['inventoryItemId'] = '33125243617303';
$products[0]['availableDelta'] = 2000;
$result = $api->graph(
'mutation inventoryBulkAdjustQuantityAtLocation($inventoryItemAdjustments: InventoryAdjustItemInput!,$locationId: ID!)
{inventoryBulkAdjustQuantityAtLocation(inventoryItemAdjustments: $InventoryAdjustItemInput, locationId: $locationId) {userErrors {field message } inventoryLevels { id }}}',
['inventoryItemAdjustments' =>
$products
],
);
But I don't understand how to use it. Could anyone help me ?
Now it works. It's a challenge to understand GraphQL queries if you never used them before.
Here are some more information :
https://www.shopify.com/partners/blog/multi-location_and_graphql
$locationId = "gid://shopify/Location/1";
$inventoryItemAdjustments1['locationId'] = $locationId;
$inventoryItemAdjustments1['inventoryItemAdjustments']['inventoryItemId'] = 'gid://shopify/InventoryItem/1';
$inventoryItemAdjustments1['inventoryItemAdjustments']['availableDelta'] = 500;
$result = $api->graph('mutation inventoryBulkAdjustQuantityAtLocation($inventoryItemAdjustments: [InventoryAdjustItemInput!]!, $locationId: ID!)
{inventoryBulkAdjustQuantityAtLocation(inventoryItemAdjustments: $inventoryItemAdjustments, locationId: $locationId) {userErrors { field message }}}',
$inventoryItemAdjustments1
);
Not so good examples (hardcoded values, aliases - not real life examples) ... graphql variables should be used and they should match mutation requirements ('root' parameters), in this case locationId and inventoryItemAdjustments (array of objects).
You can test this mutation in graphiql/playground using 'query variables' defined like this:
{
locationId: "gid://shopify/Location/1",
inventoryItemAdjustments: [
{
'inventoryItemId': 'gid://shopify/InventoryItem/1',
'availableDelta': 500
},
{
'inventoryItemId': 'gid://shopify/InventoryItem/2',
'availableDelta': 100
}
]
}
... so using php (associative arrays are encoded to json as objects - explicitely declared for readability) it should look more like this:
$locationId = "gid://shopify/Location/1";
$inventoryItemAdjustments = [];
$inventoryItemAdjustments[] = (object)[
'inventoryItemId' => 'gid://shopify/InventoryItem/1',
'availableDelta'] => 500;
];
$inventoryItemAdjustments[] = (object)[
'inventoryItemId' => 'gid://shopify/InventoryItem/2',
'availableDelta'] => 100;
];
$variables = (object)[
'locationId' => $locationId;
'inventoryItemAdjustments' => $inventoryItemAdjustments
];
$result = $api->graph('mutation inventoryBulkAdjustQuantityAtLocation($inventoryItemAdjustments: [InventoryAdjustItemInput!]!, $locationId: ID!)
{inventoryBulkAdjustQuantityAtLocation(inventoryItemAdjustments: $inventoryItemAdjustments, locationId: $locationId) {userErrors { field message }}}',
$variables
);
I would like to show another library that uses this and expand on the last example.
I am using a slightly different library for graphql:
https://github.com/Shopify/shopify-php-api/
Updating the inventory like it was posted here shows a [statusCode:GuzzleHttp\Psr7\Response:private] => 200
So it seems to work but does not reflect in updated inventory. :(
Checking at /admin/products/inventory?location_id=62241177806&query=F11_27781195
would not show the new inventory.
I am using the inventoryid correctly (not product or variantid).
$inventoryItemAdjustments = array();
$inventoryItemAdjustments[] = (object)[
'inventoryItemId' => 'gid://shopify/InventoryItem/43151435235534',
'availableDelta' => 500
];
$inventoryItemAdjustments[] = (object)[
'inventoryItemId' => 'gid://shopify/InventoryItem/43151435268302',
'availableDelta' => 500
];
$variables = array(
'locationId' => ConfigClass::$locationId,
'inventoryItemAdjustments' => $inventoryItemAdjustments
);
$graphqlquery='mutation inventoryBulkAdjustQuantityAtLocation($inventoryItemAdjustments: [InventoryAdjustItemInput!]!, $locationId: ID!)
{inventoryBulkAdjustQuantityAtLocation(inventoryItemAdjustments: $inventoryItemAdjustments, locationId: $locationId) {userErrors { field message }}}';
$response = $client->query(['query' => $graphqlquery, 'variables' => $variables]);
Deleting a product works (and is a good test if the library is initialized well):
$query = <<<QUERY
mutation {
productDelete(input: {id: "gid://shopify/Product/6975310463182"})
{
deletedProductId
}
}
QUERY;
$response = $client->query(["query" => $query]);
print_r($response);
die;
I'm looking to mark an order in Google Shopping as shipped but getting hung up with how to format the lineItems. I'm following the official docs for shipping line items:
https://developers.google.com/shopping-content/v2/reference/v2.1/orders/shiplineitems
And here is my code:
$client = new Google_Client();
$service = new Google_Service_ShoppingContent($client);
// Get Order and Line Items
$order = $service->orders->get('MERCHANT-ID', 'ORDER-ID', array());
$lineItems = $order->getLineItems();
// Prepare Item Info
foreach($lineItems as $item) {
$items = array('lineItemId' => $item->getId(),'productId' => $item->getProduct()->getId(), 'quantity' => $item->quantityPending);
}
// Prepare Shipment Info
$shipment = array('shipmentId' => 'xxx', 'carrier' => 'ups', 'trackingId' => '1234567890');
// Prepare PostBody
$postBody = new Google_Service_ShoppingContent_OrdersShipLineItemsRequest();
$postBody->operationId = rand();
$postBody->lineItems = $items;
$postBody->shipmentInfos = $shipment;
// Mark Google Order as Shipped
$service->orders->shiplineitems('MERCHANT-ID', 'ORDER-ID', $postBody, array());
This produces the following error, but I haven't been able to figured out exactly what is wrong:
Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "invalid", "message": "Invalid value for lineItems: {lineItemId=HI2PTRMVLNCZEXP, productId=online:en:US:d3k3245, quantity=2}", "locationType": "other", "location": "" } ], "code": 400, "message": "Invalid value for lineItems: {lineItemId=HI2PTRMVLNCZEXP, productId=online:en:US:d3k3245, quantity=2}" } }
Any ideas what I'm doing wrong?
The API is expecting an Array of Google_Service_ShoppingContent_OrderShipmentLineItemShipment class.
$lineItemShipments = array();
$lineItemShipment = new Google_Service_ShoppingContent_OrderShipmentLineItemShipment();
$lineItemShipment->setLineItemId($item->getId());
$lineItemShipment->setQuantity($item->quantityPending);
$lineItemShipments[] = $lineItemShipment;
$postBody->setLineItems($lineItemShipments);
I use Google Api PHP Library.
I want to delete rows.
I found it, but how can I use it? https://github.com/google/google-api-php-client-services/blob/master/src/Google/Service/Sheets/DeleteDimensionRequest.php
For example, I use it for adding rows:
// Build the CellData array
$values = array();
foreach( $ary_values AS $d ) {
$cellData = new Google_Service_Sheets_CellData();
$value = new Google_Service_Sheets_ExtendedValue();
$value->setStringValue($d);
$cellData->setUserEnteredValue($value);
$values[] = $cellData;
}
// Build the RowData
$rowData = new Google_Service_Sheets_RowData();
$rowData->setValues($values);
// Prepare the request
$append_request = new Google_Service_Sheets_AppendCellsRequest();
$append_request->setSheetId(0);
$append_request->setRows($rowData);
$append_request->setFields('userEnteredValue');
// Set the request
$request = new Google_Service_Sheets_Request();
$request->setAppendCells($append_request);
// Add the request to the requests array
$requests = array();
$requests[] = $request;
// Prepare the update
$batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest(array(
'requests' => $requests
));
try {
// Execute the request
$response = $sheet_service->spreadsheets->batchUpdate($fileId, $batchUpdateRequest);
if( $response->valid() ) {
// Success, the row has been added
return true;
}
} catch (Exception $e) {
// Something went wrong
error_log($e->getMessage());
print_r($e->getMessage());
}
return false;
Please Try this works for me
$spid = '1lIUtn8WmN1Yhgxv68dt4rylm6rO77o8UX8uZu9PIu2o'; // <=== Remember to update this to your workbook to be updated
$deleteOperation = array(
'range' => array(
'sheetId' => 0, // <======= This mean the very first sheet on worksheet
'dimension' => 'ROWS',
'startIndex'=> 2, //Identify the starting point,
'endIndex' => (3) //Identify where to stop when deleting
)
);
$deletable_row[] = new Google_Service_Sheets_Request(
array('deleteDimension' => $deleteOperation)
);
Then Send the query to google to update your worksheet
$delete_body = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest(array(
'requests' => $deletable_row
)
);
//var_dump($delete_body);
$result = $service->spreadsheets->batchUpdate($spid, $delete_body);
you check here. This assists me when trying to solve google sheet deleting operation.
I hope this helps you. Thanks and keep in touch
I am trying to add members in a cohort but whenever i call the function this is the response i get.I am using drupal rest to make the api call.
{
"exception": "dml_write_exception",
"errorcode": "dmlwriteexception",
"message": "Error writing to database",
"debuginfo": "Column 'role_id' cannot be null\nINSERT INTO mdl_cohort_members (cohortid,userid,timeadded,role_id) VALUES(?,?,?,?)\n[array (\n 0 => '3',\n 1 => '52367',\n 2 => 1460546128,\n 3 => NULL,\n)]"
}
Can somebody direct me towards the solution.
{
$fname = 'core_cohort_add_cohort_members';
/// Paramètres
$member = new stdClass();
$member->cohorttype['type']='id';
$member->cohorttype['value']='3';
$member->usertype['type']='id';
$member->usertype['value']='5';
$members = array($member);
$par = array('members' => $members);
$rest_format = 'json';
$Serve_Url = 'http://dev-lms.teletaleem.net' . '/webservice/rest/server.php'. '?wstoken=' . '7882bb500bcefcd8778de64b8e79a19a' .'&wsfunction='. $fname;
require_once('curl.inc');
$Rest_format = ($rest_format == 'json') ? '&moodlewsrestformat=' . $rest_format : '';
$curl = new curl;
//if rest format == 'xml', then we do not add the param for backward compatibility with Moodle < 2.2
$rep = $curl->post($Serve_Url.$Rest_format, $par);
dpm($rep);
}
Im new to cakephp and have implemented the Webshop Solution Snipcart. When an order is processed by snipcart they send a webhook to our site. The webhook looks like this according to their documentation:
{
eventName: "order:completed",
mode: "Live",
createdOn: "2013-07-04T04:18:44.5538768Z",
content: {
token: "22808196-0eff-4a6e-b136-3e4d628b3cf5",
creationDate: "2013-07-03T19:08:28.993Z",
modificationDate: "2013-07-04T04:18:42.73Z",
status: "Processed",
paymentMethod: "CreditCard",
email: "customer#snipcart.com",
cardHolderName: "Nicolas Cage",
billingAddressName: "Nicolas Cage",
billingAddressCompanyName: "Company name",
billingAddressAddress1: "888 The street",
billingAddressAddress2: "",
billingAddressCity: "Québec",
billingAddressCountry: "CA",
billingAddressProvince: "QC",
billingAddressPostalCode: "G1G 1G1",
billingAddressPhone: "(888) 888-8888",
shippingAddressName: "Nicolas Cage",
shippingAddressCompanyName: "Company name",
shippingAddressAddress1: "888 The street",
shippingAddressAddress2: "",
shippingAddressCity: "Québec",
shippingAddressCountry: "CA",
shippingAddressProvince: "QC",
shippingAddressPostalCode: "G1G 1G1",
shippingAddressPhone: "(888) 888-8888",
shippingAddressSameAsBilling: true,
finalGrandTotal: 310.00,
shippingAddressComplete: true,
creditCardLast4Digits: "4242",
shippingFees: 10.00,
shippingMethod: "Livraison",
items: [{
uniqueId: "eb4c9dae-e725-4dad-b7ae-a5e48097c831",
token: "22808196-0eff-4a6e-b136-3e4d628b3cf5",
id: "1",
name: "Movie",
price: 300.00,
originalPrice: 300.00,
quantity: 1,
url: "https://snipcart.com",
weight: 10.00,
description: "Something",
image: "http://placecage.com/50/50",
customFieldsJson: "[]",
stackable: true,
maxQuantity: null,
totalPrice: 300.0000,
totalWeight: 10.00
}],
subtotal: 610.0000,
totalWeight: 20.00,
hasPromocode: false,
promocodes: [],
willBePaidLater: false
}
}
And the consume the webhooks looks like this:
<?php
$json = file_get_contents('php://input');
$body = json_decode($json, true);
if (is_null($body) or !isset($body['eventName'])) {
// When something goes wrong, return an invalid status code
// such as 400 BadRequest.
header('HTTP/1.1 400 Bad Request');
return;
}
switch ($body['eventName']) {
case 'order:completed':
// This is an order:completed event
// do what needs to be done here.
break;
}
// Return a valid status code such as 200 OK.
header('HTTP/1.1 200 OK');
My question is, how do I do this in CakePHP version 2.4. I've been looking for days now on the internet for a solution, but tho i'm inexperienced I can't find a proper solution.
Solved it:
public function webhooks(){
//check if POST
if ($this->request->is('post')) {
//Allow raw POST's
$url = 'php://input';
//decode
$json = json_decode(file_get_contents($url), true);
if (is_null($json) or !isset($json['eventName'])) {
// When something goes wrong, return an invalid status code
// such as 400 BadRequest.
header('HTTP/1.1 400 Bad Request');
return;
}
//do whatever needs to be done, in this case remove the quantity ordered from the stock in db.
switch ($json['eventName']) {
case 'order:completed':
$id = $json['content']['items'][0]['id'];
$quantity = $json['content']['items'][0]['quantity'];
$query = $this->Shop->findById($id, 'Shop.stock');
$stock = $query['Shop']['stock'];
$stock = $stock - $quantity;
$this->Shop->updateAll(array('Shop.stock' => $stock), array('Shop.id' => $id));
break;
}
header('HTTP/1.1 200 OK');
}
}
the only thing I would add to your answer is a few more "cake" ways of doing some things.
public function webhooks(){
//check if POST
if ($this->request->is('post') || $this->request->is('put')) {
//Allow raw POST's
$url = 'php://input';
//decode
$json = json_decode(file_get_contents($url), true);
if (empty($json) or empty($json['eventName'])) {
throw new BadRequestException('Invalid JSON Information');
}
//do whatever needs to be done, in this case remove the quantity ordered from the stock in db.
switch ($json['eventName']) {
case 'order:completed':
$id = $json['content']['items'][0]['id'];
$quantity = $json['content']['items'][0]['quantity'];
$shop = $this->Shop->find('first', array(
'conditions' => array(
'Shop.id' => $id,
),
'fields' => array(
'Shop.stock',
),
));
if (empty($shop)) {
throw new NotFoundException(__('Invalid Shop Content'));
}
$stock = $shop['Shop']['stock'];
$stock = $stock - $quantity;
$this->Shop->id = $id;
$this->Shop->saveField('stock', $stock);
break;
}