Global variable change to null after calling an action in controller - cakephp

I want to call delete action, but my global variable sets to null.
Controller:
App::uses('AppController', 'Controller');
class WhitelistController extends AppController
{
public $helpers = array('Html', 'Form');
private $deletes;
public function index()
{
if ($this->request->is('post'))
{
$whitelist = $_POST['data']['whitelist']['stylecodes'];
if($whitelist == "")
return $this->Session->setFlash('You did not enter stylecodes. If you send this, it will delete all the shoes from the website.');
$whitelist = preg_replace('/\s+/', '', $whitelist);
$whitelist = explode(",", $whitelist);
$url = 'http://fonda.vps.***********/product_import_json_all_published_products';
$ch = curl_init($url);
curl_setopt( $ch, CURLOPT_POST, 1);
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $ch, CURLOPT_HEADER, 0);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1);
$all = curl_exec($ch);
$all = json_decode($all, true);
print_r($all);
$this->deletes = array_diff($all, $whitelist);
if($this->deletes == $all)
return $this->Session->setFlash('It seems you entered wrong data, what could delete all of the shoes from the website.');
$this->deletes = array_values($this->deletes);
pr($this->deletes);
$this->set('delete', $this->deletes);
$this->render('delete');
}
}
public function delete()
{
if($this->request->is('post'))
{
}else{
$url = 'http://fonda.vps.*******/product_import_json_remove';
$myvars = 'products=' . json_encode($this->deletes);
print_r();
pr($myvars);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $myvars);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
$response = json_decode($response, true);
pr($response);
$removed = count($response['removed']);
$skipped = count($response['skipped']);
$string = $removed . " shoe(s) removed and " . $skipped . " shoe(s) skipped.";
$this->Session->setFlash($string);
if (count($response['error']) != 0) {
$string = "";
echo " ";
foreach ($response['error'] as $key => $value) {
$string .= $key . ": " . $value;
$string .= "\n";
}
$this->Session->setFlash('Error found in following shoe(s): ' . $string);
}
return $this->redirect(array( 'action' => 'index'));
}
}
}
$this->deletes gets null after calling the delete() from the view.
I don't see anything that changes the deletes value.
What is the problem?

I think I figured it out. I removed the global variable, and i put the local variable to a session in the first action:
$this->Session->write('deletes', $delete);
And i read it in the second action like this:
$delete = $this->Session->read('deletes');
so i could work with the $delete in the second action.

Related

Capture data from CSV file contain variable for API request to save in new CSV file

I need the tracking number and order number when every line of Unique ID send the API request to the URL, and capture it to save in the new CSV file altogether with the API response.I really need help for this :/
packet.csv (CSV file contains variable for API request)
- Tracking #,Order #,Unique ID
- AB74832493,0dajKDhsa,478324
- CD78437294,kDHIdsan98,768542
track.csv (API response)
delivered,"2020-04-21 13:10:12"
delivered,"2020-02-29 12:55:51"
delivered,"2020-04-21 12:42:16"
desired track.csv (API response) :
Tracking #,Order#,Status,Date ((get the tracking and order from packet.csv)
0CS7lPuyKzO6,YT2010421266182766,delivered,"2020-04-21 13:10:12"
327231739327,YT7328729173217832,delivered,"2020-02-29 12:55:51"
743287493274,YT7438749327489324,delivered,"2020-04-21 12:42:16"
Controller :
public function getstatusbyid()
{
$csv_file = file('C:\wamp64\www\tetsing\application\csv\packet.csv');
$csv_data = [];
foreach ($csv_file as $line) {
$csv_data[] = str_getcsv($line);
}
$order_no = json_encode(array_column($csv_data, '0'));
$tracking = json_encode(array_column($csv_data, '1'));
$unique_id = array_column($csv_data, '2');
$access_key = 'SOMETHING';
if (FALSE === ($fp = fopen('C:\wamp64\www\testing\application\csv\track.csv', 'w'))) {
die("Error opening CSV file."); // TO DO: handle this better
}
foreach ($unique_id as $i => $id) {
$url = "https://track.my/api/getstatusbyid/$id";
$data = array(
'unique_id' => $id,
'access_key' => $access_key
);
$data_string = json_encode($data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
$result = curl_exec($curl);
curl_close($curl);
$resultinfo = json_decode($result, true);
echo '<pre>';
print_r($resultinfo);
$status = $resultinfo["status"];
$date = $resultinfo["last_action_date_time"];
$resultdata = array();
$resultdata[] = array(
'status' => $status,
'date' => $date
);
if ($status == 'delivered') {
foreach ($resultdata as $fields) {
fputcsv($fp, $fields);
}
}
}
fclose($fp);
}
See this updated code, with comments to describe what's happening. Basically, you need to loop through each line in packet.csv, make the appropriate cURL call, and output the results:
public function getstatusbyid()
{
$access_key = 'SOMETHING';
$url = "https://track.my/api/getstatusbyid/$id";
if (FALSE === ($fp = fopen('C:\wamp64\www\testing\application\csv\track.csv', 'w'))) {
die("Error opening CSV file."); // TO DO: handle this better
}
$csv_file = file('C:\wamp64\www\tetsing\application\csv\packet.csv');
// Loop through each line in packet.csv:
foreach ($csv_file as $line) {
$csv_data = str_getcsv($line); // Get the next line
list( $order_no, $tracking, $id ) = $csv_data; // Split it up
$data = array(
'unique_id' => $id,
'access_key' => $access_key
);
$data_string = json_encode($data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
$result = curl_exec($curl);
curl_close($curl);
$resultinfo = json_decode($result, true);
echo '<pre>';
print_r($resultinfo);
$status = $resultinfo["status"];
$date = $resultinfo["last_action_date_time"];
// Create the array of data to output:
$resultdata = array(
'tracking' => $tracking,
'order' => $order_no,
'status' => $status,
'date' => $date
);
if ($status == 'delivered') {
fputcsv($fp, $resultdata);
}
}
fclose($fp);
}

invalid signature when attempting a sell

I'm try to sell my bitcoin through the API from a specific wallet.
I have the GET calls working correctly, but the POST call is showing "invalid signature"
$API_KEY = '*****';
$API_SECRET = '*****';
$data['amount'] = 10;
$data['currency'] = 'USD';
$data['quote'] = true;
$api_url = '/v2/accounts/593b0285-****-****-****-f0ddcb6c9ccc/sells';
$timestamp = time();
$signature = hash_hmac('SHA256',$timestamp.'POST'.$api_url.json_encode($data),$API_SECRET;
$version = '2017-11-11';
$headers = array('CB-ACCESS-SIGN: '.$signature,
'CB-ACCESS-TIMESTAMP: '.$timestamp,
'CB-ACCESS-KEY: '.$API_KEY,
'CB-VERSION: '.$version);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.coinbase.com'.$api_url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$data = curl_exec($ch);
This is the result I get from Coinbase
stdClass Object
(
[errors] => Array
(
[0] => stdClass Object
(
[id] => authentication_error
[message] => invalid signature
)
)
)
I've changed the currency to BTC to try that.
The account id in the $api_url is the one from when I perform an account API call.
[id] => 593b0285-****-****-****-f0ddcb6c9ccc
[name] => BTC Wallet
[primary] => 1
[type] => wallet
I figured it out, I was missing the Content-Type from my header.
$headers = array('CB-ACCESS-SIGN: '.$signature,
'CB-ACCESS-TIMESTAMP: '.$timestamp,
'CB-ACCESS-KEY: '.$API_KEY,
'CB-VERSION: '.$version,
"Content-Type: application/json");
It all works correctly now

Invalid Signature Coinbase

I'm trying to use the API for Coinbase but I get invalid signature.
So probably I'm actually sign it wrong or I'm missing something.
what should I use on request? should i use POST or GET on method?
$urlapi = "https://api.coinbase.com/v2/time";
$Key = "--------------";
$Secret = "------------";
$fecha = new DateTime();
$timestamp = $fecha->getTimestamp();
$request="";
$body="";
$method="GET";
$Datas = $timestamp . $method . $request . $body;
$hmacSig = hash_hmac('sha256',$Datas,$Secret);
$curl = curl_init($urlapi);
curl_setopt($curl,CURLOPT_HTTPHEADER,array('Content-Type: application/json','CB-ACCESS-KEY: '.$Key,'CB-VERSION: 2015-07-07','CB-ACCESS-TIMESTAMP: '. $timestamp,'CB-ACCESS-SIGN: '.$hmacSig));
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
if(!curl_exec($curl)){
die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
curl_close($curl);
print_r($resp);
Get Current Time is a GET request (ref). The HTTP verb (GET/POST etc.) can be found in the docs for each type of request here:
In your example, the problem is that the $request variable in your message is blank. It should be $request="/v2/time";
hash_hmac returns hex encoded string by default so the hashing part is correct.
define('API_KEY', 'xxxx');
define('API_SECRET', 'xxxxxxxxx');
define('API_BASE', 'https://api.coinbase.com');
define('API_VERSION', '2015-08-31');
$headers = array(
'Content-Type: application/json',
'CB-VERSION: ' . API_VERSION
);
$url = API_BASE.'/v2/time';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
$output = json_decode($response, true);
print_r($output);
will return
Array ( [data] => Array ( [iso] => 2015-12-01T10:35:58Z [epoch] => 1448966158 ) )
You must use GET method, because is just to get some information, authentication is no needed.
This is an easier way:
$time = file_get_contents('https://api.coinbase.com/v2/time');
$time = json_decode($time);
$time = $time->data->epoch;

Not Getting access token from of Gmail Contacts API using Oauth2 while code is in Google App Engine Server

I am using zend-framework2 and google-app-engine server to import all gmail contact list. I am getting authorization code from gmail after login. When hitting curl using this authorization code to get access token, it gives blank array as response.
Also this app is a billed app in google-app-engine. and already set
extension = "curl.so"
in php.ini file. and the credentials which i have given are correct.
// Import Gmail Contacts
$client_id='xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com';
$client_secret='xxxxxxxxxxxxxx-xxxxxxxxx';
$redirect_uri='http://xxxxxxxxxxxxxxx.appspot.com/u/invite/gmailCallback';
$max_results = 1000;
if(isset($_GET["code"]) && $_GET["code"] != '') {
$auth_code = $_GET["code"];
$fields=array(
'code'=> urlencode($auth_code),
'client_id'=> urlencode($client_id),
'client_secret'=> urlencode($client_secret),
'redirect_uri'=> urlencode($redirect_uri),
'grant_type'=> urlencode('authorization_code')
);
$post = '';
foreach($fields as $key=>$value) { $post .= $key.'='.$value.'&'; }
$post = rtrim($post,'&');
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,'https://accounts.google.com/o/oauth2/token');
curl_setopt($curl,CURLOPT_POST,5);
curl_setopt($curl,CURLOPT_POSTFIELDS,$post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,FALSE);
$result = curl_exec($curl);
//$info = curl_getinfo($curl);
//echo "<pre>"; print_r($info); die;
curl_close($curl);
$response = json_decode($result);
//echo "<pre>"; var_dump($response); die;
if(isset($response->access_token) && $response->access_token != '') {
$accesstoken = $response->access_token;
$url = 'https://www.google.com/m8/feeds/contacts/default/full?max-results='.$max_results.'&oauth_token='.$accesstoken;
//$url = 'https://www.google.com/m8/feeds/contacts/default/full?oauth_token='.$accesstoken;
$xmlresponse = $this->curl_file_get_contents($url);
//At times you get Authorization error from Google.
if((strlen(stristr($xmlresponse,'Authorization required'))>0) && (strlen(stristr($xmlresponse,'Error '))>0)) {
//$returnArr['error_msg'] = "Something went wrong to import contacts!!";
echo '<h2>Something went wrong to import contacts !!</h2>';die;
} else {
$xml = new SimpleXMLElement($xmlresponse);
$xml->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005');
$result = $xml->xpath('//gd:email');
//echo "<pre>"; print_r($result); die;
foreach ($result as $title) {
$emailsArr[] = (string) $title->attributes()->address;
}
}
}
}
Please help.
From previous experience (and this answer) I don't think cURL is enabled on App Engine as C extensions aren't supported.
You'll have to use URL Fetch instead e.g.
$data = ['data' => 'this', 'data2' => 'that'];
$data = http_build_query($data);
$context = [
'http' => [
'method' => 'GET',
'header' => "custom-header: custom-value\r\n" .
"custom-header-two: custom-value-2\r\n",
'content' => $data
]
];
$context = stream_context_create($context);
$result = file_get_contents('http://app.com/path?query=update', false, $context);
App engine supports cURL, but it seems to be buggy. I have the same problem with OAuth authentication via Google. The POST cURL call just returns FALSE without any error message. Here is the official bug report: https://code.google.com/p/googleappengine/issues/detail?id=11985
What you can do now, is to switch to url fetch functions. To make a POST request you can use following function:
protected function _call($url, array $params, $method = 'GET', array $headers = [])
{
$query = http_build_query($params);
$headers_str = '';
if ($headers) {
foreach ($headers as $name => $value) {
$headers_str .= $name . ': ' . $value . "\r\n";
}
}
$headers_str .= "Content-type: "."application/x-www-form-urlencoded"."\r\n";
$options =
array('http'=>
array(
'method' => $method,
'header' => $headers_str,
'content' => $query,
'ignore_errors' => true,
)
);
if ($method === 'POST') {
$options['http']['content'] = $query;
} else if ($query) {
$url .= '?' . $query;
}
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
// check for zipped response and decode it
if (array_search('Content-Encoding: gzip', $http_response_header)) {
$response = gzinflate(substr($response, 10, -8));
}
return $response;
}
Or you can try to use this cURL wrapper library https://github.com/azayarni/purl, which was implemented before GAE provided cURL support. Hope it is helpful:)

Send file using multipart/form-data request in php

I have image resource stored in variable which I need to send to server using its http API and PHP. I have to send request with content type multipart/form-data. So, I need to make similiar request as when form with file input and enctype=multipart/form-data attribute is sent.
I tried this:
<?php
$url = 'here_is_url_for_web_API';
$input = fopen('delfin.jpg','r');
$header = array('Content-Type: multipart/form-data');
$resource = curl_init();
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_USERPWD, "user:password");
curl_setopt($resource, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
curl_setopt($resource, CURLOPT_HTTPHEADER, $header);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($resource, CURLOPT_BINARYTRANSFER, true );
curl_setopt($resource, CURLOPT_INFILESIZE, 61631);
curl_setopt($resource, CURLOPT_INFILE, $input);
$result = curl_exec($resource);
curl_close($resource);
var_dump($result);
?>
I don't know how exactly response should look like but this returns:
http status 405
and error report is: The specified HTTP method is not allowed for the requested resource ().
use multipart/form-data and boundaries in POST content with curl.
$filenames = array("/tmp/1.jpg", "/tmp/2.png");
$files = array();
foreach ($filenames as $f){
$files[$f] = file_get_contents($f);
}
// more fields for POST request
$fields = array("f1"=>"value1", "another_field2"=>"anothervalue");
$url = "http://example.com/upload";
$curl = curl_init();
$url_data = http_build_query($data);
$boundary = uniqid();
$delimiter = '-------------' . $boundary;
$post_data = build_data_files($boundary, $fields, $files);
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
//CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_HTTPHEADER => array(
//"Authorization: Bearer $TOKEN",
"Content-Type: multipart/form-data; boundary=" . $delimiter,
"Content-Length: " . strlen($post_data)
)
));
//
$response = curl_exec($curl);
$info = curl_getinfo($curl);
//echo "code: ${info['http_code']}";
//print_r($info['request_header']);
var_dump($response);
$err = curl_error($curl);
echo "error";
var_dump($err);
curl_close($curl);
function build_data_files($boundary, $fields, $files){
$data = '';
$eol = "\r\n";
$delimiter = '-------------' . $boundary;
foreach ($fields as $name => $content) {
$data .= "--" . $delimiter . $eol
. 'Content-Disposition: form-data; name="' . $name . "\"".$eol.$eol
. $content . $eol;
}
foreach ($files as $name => $content) {
$data .= "--" . $delimiter . $eol
. 'Content-Disposition: form-data; name="' . $name . '"; filename="' . $name . '"' . $eol
//. 'Content-Type: image/png'.$eol
. 'Content-Transfer-Encoding: binary'.$eol;
$data .= $eol;
$data .= $content . $eol;
}
$data .= "--" . $delimiter . "--".$eol;
return $data;
}
See the full example here: https://gist.github.com/maxivak/18fcac476a2f4ea02e5f80b303811d5f
If you work with CURL, you have to just:
1, set header 'Content-Type' as 'multipart/form-data;'
2, set option 'RETURNTRANSFER' of curl to true (use option method of curl)
3, set option 'POST' of curl to true (use option method of curl)
4, get source of your file (what you get from fopen in PHP):
$tempFile = tempnam(sys_get_temp_dir(), 'File_');
file_put_contents($tempFile, $source);
$post = array(
"uploadedFile" => "#" . $tempFile, //"#".$tempFile.";type=image/jpeg",
);
5, use post method of CURL with parameter in $post variable

Resources