Pass e.parameter to array with doPost method - php

Can you pass parameters through DoPost method? I am trying to pass e.parmaters to my array. All I see in return is empty brackets without the value of the parameter I want to push.
Code:
function doPost(e) {
createProcess(e);
createStep();
}
function createProcess(e) {
var app = UiApp.getActiveApplication(); //get the current UI application
process = [];
var sheet = SpreadsheetApp.openById("0AuCblud0Ss7BdHA1bXZgmjYXA0liY0IyekhUQm5vWG02MVE").getActiveSheet( ); //opens spreadsheet
var row = sheet.getLastRow(); //grabs current row
process.push(createStep([e.parameter.DivHeadEmail,]));
process.push(createStep([e.parameter.Director]));
saveProcess(process,sheet,row);
}
function createStep(approvers) {
var sheet = SpreadsheetApp.openById("0AuCblud0Ss7BdHA1bXZjYXhkhkA0Y0IyekhUQm5vWG02MVE").getActiveSheet();
var row = sheet.getLastRow();
var step = new Object();
step['numberOfApprovers'] = approvers.length;
step['approvers'] = approvers.slice(1);
step['status'] = "approved" ;
return step;
}

Yes, you are able to pass parameters to doPost(e) just as you can with doGet(e).
You can check what parameters are being passed to your doPost(e) method by using this inside of it.
var parameters = "";
for (var i in e.parameter) {
parameters += "e.parameter."+i+" = "+e.parameter[i];
}
Logger.log(parameters);

Related

JQuery url GET variable

I there a possible way to use a GET variable in jQuery url. Like in PHP we have something like this:
header('location : path/to/page.php?id='.$id);
And In the page.php we do this:
$id = $_GET['id'];
So in jQuery can we do something like:
window.location.replace(path/to/page.html/* and pass the url query here*/);
I think what you are looking for is to access the query string ($_GET in php) variables in javascript. You can use this function for that.
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
and then call getParameterByName('id') to get ?id=val part of the current URL.
You can also pass data to another page using location.replace:
idVal = 1;
window.location.replace("path/to/page.php?id="+idVal);
Use a js function to do this...
var getUrlVars = function(){
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++){
hash = hashes[i].split('=');
vars.push(decodeURIComponent(hash[0]));
vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
}
if(vars[0] == window.location.href){
vars =[];
}
return vars;
}
Then where ever you wish to use
var params = getUrlVars();
console.log(params["id"]);
console.log(params["whatever"]);
You can use it anywhere you want.
the property 'search' of the 'location' javascript object will give you the querystring parameters of the url, eg:
url: http://www.w3schools.com/submit.htm?email=someone#example.com
console.log(location.search);
// output: ?email=someone#example.com
after that you can parse it as you wish

WooCommerce webhook parsing

Trying to parse the input JSON from the Woocommerce Webhook to Google Spreadsheet via Google App Script.
Used this one :
function doPost(request) {
var json = request.postData.getDataAsString();
var obj = JSON.parse(json);
// getting some of the Woocommerce data just as an example
// Hook was fired after order.created
var id = obj.order.id;
var orderNumber = obj.order.order_number;
var payMethod = obj.order.payment_details.method_title;
// write data in a document, not useful, but straightforward for testing
var doc = DocumentApp.openById('myDocumentId');
doc.appendParagraph("Id: " + id);
doc.appendParagraph("orderNumber: " + orderNumber);
doc.appendParagraph("payMethod: " + payMethod);
}
But receive nothing into the Google Sheets.
And with this one:
function doPost(request) {
var content = JSON.parse(request.postData.contents);
var row = [];
for (var elem in content) {
row.push(content[elem]);
}
var ss = SpreadsheetApp.openById("SHEET ID")
var sheet = ss.getSheetByName("Sheet1");
sheet.appendRow(row);
var result = {"result":"ok"};
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
}
It's receiving data, but it's not parsed:
Is there anyway to fix this and make the data in sheet viewable?
Thanks in advance.
I have found the answer on my question at https://ru.stackoverflow.com/
thanks to Alexander Ivanov
The main thing why the woocommerce webhook not parsed is that the JSON is not valid when WC send it to the spreadsheet macros.
And sheet posting it as one element {order:{}}
so we need to edit the code like this :
var content = JSON.parse(request.postData.contents)[0];
or like this (in my case):
var content = JSON.parse(request.postData.contents)['order'];
in case we have no idea what data will be received, we may try to determine the value:
function doPost(request) {
var result = {
result: undefined
};
try {
var content = JSON.parse(request.postData.contents);
var row = [];
if (content.hasOwnProperty('order')) {
for (var elem in content['order']) {
row.push(content['order'][elem]);
}
} else {
row.push(request.postData.contents);
}
var ss = SpreadsheetApp.openById('SHEET ID')
var sheet = ss.getSheets()[0];
sheet.appendRow(row);
result.result = 'ok';
} catch (err) {
result.result = 'err';
}
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
}

loading xml from a database to be used in multiple functions

I have a database where i'm using php to randomize the information by ID and send it out via xml. My issue is that I only want to grab the xml once and store it for use in at least 2 functions... one function that runs onload to grab the first line of xml, another that will run every time a button is pressed to access the next line of xml until the end. My 2 functions are loadfirst() and loadnext(). loadfirst() works perfectly, but I'm not sure how to pass the xml data to loadnext(). Right now I'm just using loadfirst() on pageload and loadfirst() on button press, but i end up creating new xml from the database each time which causes randomization issues and is incredibly inefficient. Any help would be appreciated.
var places;
var i = 0;
function loadXML(){
downloadUrl("places.php", function(data){
places = data.responseXML;
getFeatured(i);
});
}
function getFeatured(index){
var id = places[index].getAttribute("id");
var name = places[index].getAttribute("name");
var location = places[index].getAttribute("location");
var imgpath = places[index].getAttribute("imgpath");
var tags = places[index].getAttribute("tags");
}
function getPrev() {
i--;
getFeatured(i);
}
function getNext() {
i++;
getFeatured(i);
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
loadnext() will be very similar to loadfirst(), I'm just running into issues with passing the xml data so that i can use it without having to access the database again. Thanks.
Set your xml and i in public scope. Then all you have to do is increment/decrement i and re-read data from XML. Something like this:
var xml;
var xml_idx = 0; // replaces your i counter
function loadXML() {
downloadUrl ("places.php", function(data) {
xml = data.responseXML;
)};
}
function loadItem(index) {
var id = xml[index].getAttribute("id");
var name = xml[index].getAttribute("name");
var location = xml[index].getAttribute("location");
var imgpath = xml[index].getAttribute("imgpath");
var tags = xml[index].getAttribute("tags");
// do something with this data
}
function loadCurrentItem() {
loadItem(xml_idx);
}
function loadNextItem() {
xml_idx++;
loadItem(xml_idx);
}
function loadPreviousItem() {
xml_idx--;
loadItem(xml_idx);
}
// usage
loadXML(); // do this first to populate xml variable
loadItem(xml_idx); // loads first item (i=0)
loadCurrentItem(); // loads i=0
loadNextItem(); // loads i=1
loadNextItem(); // loads i=2
loadPreviousItem(); // loads i=1
If you really want to get fancy (and keep the global namespace cleaner), you could easily make this into a class.
Use global variables (items - items array, iterator - counter) to store data available for all functions.
Try something like this:
items = false;
iterator = 0;
function loadfirst(){
downloadUrl ("places.php", function(data) {
var i = 0;
var xml = data.responseXML;
var places = xml.documentElement.getElementsByTagName("place");
var id = places[i].getAttribute("id");
var name = places[i].getAttribute("name");
var location = places[i].getAttribute("location");
var imgpath = places[i].getAttribute("imgpath");
var tags = places[i].getAttribute("tags");
items = places;
iterator++;
)};
}
function loadnext(){
var i = iterator;
var id = items[i].getAttribute("id");
var name = items[i].getAttribute("name");
var location = items[i].getAttribute("location");
var imgpath = items[i].getAttribute("imgpath");
var tags = items[i].getAttribute("tags");
iterator++;
}
You should wrap all this into a single object to control scope and data state. (Untested code below, which should just illustrate a possible pattern and interface to use.)
function PlacesScroller(url, callback) {
this.url = url;
this.data = null;
this._index = null;
this.length = 0;
var self = this;
downloadURL(this.url, function(result, status) {
if (Math.floor(status/100)===2) {
self.setData(result);
}
if (callback) {
callback(self, result);
}
});
}
PlacesScroller.prototype.setData(xmldom) {
this._index = 0;
// this may require changing; it depends on your xml structure
this.data = [];
var places = xmldom.getElementsByTagName('place');
for (var i=0; i<places.length; i++) {
this.data.push({
id : places[i].getAttribute('id'),
name : places[i].getAttribute('name')
// etc
});
}
}
PlacesScroller.prototype.getPlaceByIndex = function(index) {
if (this.data) {
return this.data[index];
} else {
return null;
}
}
PlacesScroller.prototype.getCurrentFeature = function() {
return this.getPlaceByIndex(this._index);
}
PlacesScroller.prototype.addToIndex(i) {
// This sets the index forward or back
// being careful not to fall off the end of the data
// You can change this to (e.g.) cycle instead
if (this.data===null) {
return null;
}
var newi = i+this._index;
newi = Math.min(newi, this.data.length);
newi = Math.max(0, newi);
this._index = newi;
return this._index;
}
PlacesScroller.prototype.getNextFeature = function() {
this.addToIndex(1);
return this.getCurrentFeature();
}
PlacesScroller.prototype.getPreviousFeature = function() {
this.addToIndex(-1);
return this.getCurrentFeature();
}
Then initialize it and use it like so:
var scroller = new PlacesScroller('places.php', function(scrollerobject, xmlresult){
// put any initialization code for your HTML here, so it can build after
// the scrollerobject gets its data.
// You can also register event handlers here
myNextButton.onclick = function(e){
var placedata = scrollerobject.getNextFeature();
myPictureDisplayingThing.update(placedata);
}
// etc
});

passing arrays from the view to the controller cakephp

Here is a part of my view(a javascript method that is executed on a button click):
function assign()
{
var links_list1 = [];
var links1 = document.getElementById('moderatorUsers').getElementsByTagName('a');
for(var a in links1) {
if(typeof links1[a] == undefined) continue;
links_list1.push(links1[a].innerHTML);} var str1 =links_list1.toString();
var moderators = str1.split(',');
var links_list2 = [];
var links2 = document.getElementById('editorUsers').getElementsByTagName('a');
for(var a in links2) {
if(typeof links2[a] == undefined) continue;
links_list2.push(links2[a].innerHTML);} var str2 =links_list2.toString();
var editors = str2.split(',');
var links_list3 = [];
var links3 = document.getElementById('jEditorUsers').getElementsByTagName('a');
for(var a in links3) {
if(typeof links3[a] == undefined) continue;
links_list3.push(links3[a].innerHTML);} var str3 =links_list3.toString();
var jEditors = str3.split(',');
}
Here is the controller method i need to call using the 3 arrays from the javascript(moderators, editors,jEditors):
function insertPos($moderators,$editors,$jEditors){
$account = new Account();
$account->insertPos($moderators,$editors,$jEditors);
}
I need to know how to execute the controller method insertPos($moderators,$editors,$jEditors) using the 3 arrays in the javascript method...
I used this to send the arrays in the javascript like you told me:
$.post('http://localhost/cakephp/Accounts/insertPos', {
data: {
'moderators': moderators,
'editors': editors,
'jEditors': jEditors
}
});
and in the controller i try to access my arrays like this:
public function insertPos() {
if (!empty($this->request->data)){
print_r($this->request->data);
$moderators = $this->request->data['moderators'];
$editors = $this->request->data['editors'];
$jEditors = $this->request->data['jEditors'];
$account = new Account();
$account->assignPos($moderators,$editors,$jEditors);
}
}
the part inside the if(!empty($this->request->data)) is never executed so that means the arrays have not been sent to the controller.... where is the problem?
thank you....
It looks like you're trying to access a controller class directly. This is not how CakePHP works. You have to go through the dispatch process. Please read: http://book.cakephp.org/2.0/en/getting-started/a-typical-cakephp-request.html
That said, the way you would POST to a CakePHP url is thusly:
// POST to the AccountsController's insertPos method
$.post('/accounts/insertPos');
To pass data, pass it in the data option as specified with jQuery, prefixed with 'data', like data[moderators] so it ends up in Cake's data variable.
$.post('/accounts/insertPos', {
data: {
'data[moderators]': moderators,
'data[editors]': editors,
'data[jEditors]': jEditors
}
});
The data will now end up in $this->request->data in Cake.
Looking at your insertPost() method, though, you are passing them simply as parameters, so instead you would write your ajax like so
// POST is unnecessary here, since you aren't POSTing data
$.get('/accounts/insertPos/'+moderators+'/'+editors+'/'+jEditors);
You will probably need to stringify your JavaScript arrays and use json_decode in your inserPos method to convert them to PHP objects, since you can't just pass arrays from JavaScript to PHP.
don't use array notation in data parameter; just use keys like this:
$.post('/accounts/insertPos', {
data: {
'moderators': moderators,
'editors': editors,
'jEditors': jEditors
}
});
and in your controller access it as $this->request->data[key] not $this->request->data->data[key]
in the view replace your assign function with the following:
var moderators, editors, jEditors;
function assign()
{
var links_list1 = [];
var links1 = document.getElementById('moderatorUsers').getElementsByTagName('a');
for(var a in links1) {
if(typeof links1[a] == undefined) continue;
links_list1.push(links1[a].innerHTML);} var str1 =links_list1.toString();
moderators = str1.split(',');
var links_list2 = [];
var links2 = document.getElementById('editorUsers').getElementsByTagName('a');
for(var a in links2) {
if(typeof links2[a] == undefined) continue;
links_list2.push(links2[a].innerHTML);} var str2 =links_list2.toString();
editors = str2.split(',');
var links_list3 = [];
var links3 = document.getElementById('jEditorUsers').getElementsByTagName('a');
for(var a in links3) {
if(typeof links3[a] == undefined) continue;
links_list3.push(links3[a].innerHTML);} var str3 =links_list3.toString();
jEditors = str3.split(',');
}
Good luck

Access GET directly from JavaScript?

I suppose I could use PHP to access $_GET variables from JavaScript:
<script>
var to = $_GET['to'];
var from = $_GET['from'];
</script>
<script src="realScript" type="text/javascript"></script>
But perhaps it's even simpler. Is there a way to do it directly from JS?
Look at
window.location.search
It will contain a string like this: ?foo=1&bar=2
To get from that into an object, some splitting is all you need to do:
var parts = window.location.search.substr(1).split("&");
var $_GET = {};
for (var i = 0; i < parts.length; i++) {
var temp = parts[i].split("=");
$_GET[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
}
alert($_GET['foo']); // 1
alert($_GET.bar); // 2
Here's another idea:
<script type="text/javascript">
var $_GET = <?php echo json_encode($_GET); ?>;
alert($_GET['some_key']);
// or
alert($_GET.some_key);
</script>
I know this topic is old, but I want to share my own ES6 solution for $_GET in JavaScript.
One Liner
window.$_GET = location.search.substr(1).split("&").reduce((o,i)=>(u=decodeURIComponent,[k,v]=i.split("="),o[u(k)]=v&&u(v),o),{});
Here is the MDN documentation on array.reduce(), arrow functions, the comma operator, destructuring assignment, and short-cicuit evaluation.
So, for a URL like google.com/webhp?q=foo&hl=en&source=lnt&tbs=qdr%3Aw&sa=X&ved=&biw=12 you've got an object:
$_GET = {
q: "foo",
hl: "en",
source: "lnt",
tbs: "qdr:w",
sa: "X",
ved: "",
biw: "12"
}
and you can do things like $_GET.q or $_GET['biw'] to get what you need. Note that this approach replaces duplicated query parameters with the last-given value in the search string, which may be undesired/unexpected
URLSearchParams()
Now we also have URLSearchParams() in new browsers, which lets you do things like:
window.$_GET = new URLSearchParams(location.search);
var value1 = $_GET.get('param1');
I suppose you were thinking this:
<script type="text/javascript">
var to = "<?= $_GET['to']; ?>";
var from = "<?= $_GET['from']; ?>";
</script>
...this would just be syntax-correction of your idea :)
document.get = function (d1,d2,d3) {
var divider1 = (d1 === undefined ? "?" : d1);
var divider2 = (d2 === undefined ? "&" : d2);
var divider3 = (d3 === undefined ? "=" : d3);
var url = window.location.href; //the current url
var pget = url.split(divider1)[1]; //slit the url and assign only the part after the divider 1
var pppget = {}; //define the contenitor object
if (pget.search(divider2) > -1) { //control if there is variable other than the first (?var1=a&var2=b) the var2 in this example
var ppget = pget.split(divider2); //split the divider2
for (i = 0;i==ppget.lenght; i++) { //start a for and stop it when i == at object length
if (ppget[i].search(divider3) > -1) { //control if is an empty var
psget = ppget[i].split(divider3);//if is split in 2 part using divider 3
pppget[psget[0]] = psget[1];//assign to the object the value of first element and for value the second value ex {var1=a,...}
} else {//if is a empty var (?var1&...)
pppget[ppget[i]] = "";//assign only the value of first element with value a blank string
}
}
} else {//if the url don't contain other variable
if (pget.search(divider3) > -1) { //control if is an empty var
var ppget = pget.split(divider3);//if is split in 2 part using divider 3
pppget[ppget[0]] = ppget[1];//assign to the object the value of first element and for value the second value ex {var1=a}
} else {//if is a empty var (?var1)
pppget[pget] = "";//assign only the value of first element with value a blank string
}
}
return pppget;
/* return the object
* the use of the function is like this $_GET=document.get()
* echo $_GET[var]
* or use custom divider the default is setted for php standard divider
*/};
As others have explained you can parse page URL from JS to get the variables.
You could also use AJAX in the page which submits the values. It really depends on what kind of information you're passing and then returning back to the user. (It's definitely not simpler or more direct way of doing it, just an alternative approach)
i use this one for Get request (like $_GET in php):
var urlParams;
(window.onpopstate = function () {
var match,
pl = /\+/g, Regex for replacing addition symbol with a space
search = /([^&=]+)=?([^&]*)/g,
decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); },
query = window.location.search.substring(1);
urlParams = {};
while (match = search.exec(query))
urlParams[decode(match[1])] = decode(match[2]);
})();
class Utils {
static HTTP_GET(key){
let map = this.HTTP_GET_ALL();
if(map.has(key)){
return map.get(key);
}else {
return null;
}
}
static HTTP_GET_ALL(){
let parts = window.location.search.substr(1).split("&");
let map = new Map();
for (let i = 0; i < parts.length; i++) {
let temp = parts[i].split("=");
map.set(decodeURIComponent(temp[0]), decodeURIComponent(temp[1]));
}
return map;
}
}
From what I can see: the URLSearchParams function is a widely-available in-built function gives you to ability to get all of the current query parameters into a single object. You can then access those parameters either individually as a replacement to $_GET, or you can foreach loop over it to make it into an array.
/* Example - Accessing a property with using URLSearchParams in place of $_GET */
const params = new URLSearchParams(window.location.search);
// Expected Output: (string) "true"
console.log(params.get("is_the_cake_a_lie"));
/* Example - Creating a $_GET array using URLSearchParams */
const params = new URLSearchParams(window.location.search);
window.$_GET = {};
for (const [key, value] of params.entries()) {
window.$_GET[key] = value;
}
// Expected Output: (object) { "is_the_cake_a_lie": "true" }, (string) "true"
console.log(window.$_GET, window.$_GET["is_the_cake_a_lie"]);
REF: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

Categories