Can't Download File as CSV
I'm trying to export some data as CSV & every time i try to export data i got this error - Call to undefined method Symfony\Component\HttpFoundation\StreamedResponse::header()
I have tried different possible ways but they aren't working
My Function (Controller File)
public function exportd(Request $request)
{
$fileName = 'data.csv';
$data = json_decode($request->data);
$headers = array(
"Content-type" => "text/csv",
"Content-Disposition" => "attachment; filename=$fileName",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$columns = array('Name', 'Gender', 'experrience', 'location', 'Pref Location', 'Salary'
...
);
$callback = function() use($data, $columns) {
$file = fopen('php://output', 'w');
fputcsv($file, $columns);
foreach ($data as $da) {
$row['Name'] = $da->name;
$row['Gender'] = $da->gender;
$row['experrience'] = $task->experrience;
$row['Pref Location'] = $task->pref_loc;
$row['Salary'] = $task->salary;
...
fputcsv($file, array($row['Name'], $row['Gender'],$row['experrience'], $row['location'], $row['Pref Location'], $row['Salary']
...
));
}
fclose($file);
};
return Response()->stream($callback, 200, $headers);
}
My Middleware (AuthCheck)
public function handle(Request $request, Closure $next)
{
if(!session()->has('LoggedUser') && ($request->path() !='auth/login' && $request->path() !='auth/register' )){
return redirect('auth/login')->with('fail','You must be logged in');
}
if(session()->has('LoggedUser') && ($request->path() == 'auth/login' || $request->path() == 'auth/register' ) ){
return back();
}
return $next($request)->header('Cache-Control','no-cache, no-store, max-age=0, must-revalidate')
->header('Pragma','no-cache')
->header('Expires','0');
}
$next($request) is an instance of Symfony\Component\HttpFoundation\StreamedResponse in your scenario.
StreamedResponse does not support ->header(...).
If you want to preserve your ->header(...) call, you must verify that the response is an instance of Illuminate\Http\Response
public function handle(Request $request, Closure $next)
{
if(!session()->has('LoggedUser') && ($request->path() !='auth/login' && $request->path() !='auth/register' )){
return redirect('auth/login')->with('fail','You must be logged in');
}
if(session()->has('LoggedUser') && ($request->path() == 'auth/login' || $request->path() == 'auth/register' ) ){
return back();
}
$response = $next($request);
if($response instanceof \Illuminate\Http\Response) {
return $response->header('Cache-Control','no-cache, no-store, max-age=0, must-revalidate')
->header('Pragma','no-cache')
->header('Expires','0');
}
return $response;
}
Related
How do I deal with failures in Laravel's Concurrent Requests? For example I have 10 requests in a pool and half of them return GuzzleHttp\Exception\ConnectException. I want to catch them and retry with a different proxy server.
<?php
$responses = Illuminate\Support\Facades\Http::pool(
function (Illuminate\Http\Client\Pool $pool) use ($params) {
$url = "https://example.com/api/endpoint?foo=%s";
$return = [];
$proxy = $this->proxyManager->get();
foreach($params as $param) {
// Number of retries
for($i = 0; $i < 10; $i++) {
try {
// This returns GuzzleHttp\Promise\Promise
$return[] = $pool->as($param)
->withOptions(['proxy' => $proxy])
->get(\sprintf($url, $param))
->otherwise(function ($e) {
// This never happens
dd( $e );
});
break;
} catch(\Exception $e) {
$proxy = $this->proxyManager->get();
continue;
}
}
}
return $return;
}
);
// Some fail, some ok
dd( $responses );
Had to use Guzzle with custom Middleware to archive what I wanted:
app/Http/Client/Middleware.php
<?php
namespace App\Http\Client;
final class Middleware
{
public static function retry( callable $decider, callable $delay = null ): callable
{
return static function( callable $handler ) use ( $decider, $delay ): RetryMiddleware
{
return new RetryMiddleware( $decider, $handler, $delay );
};
}
}
app/Http/Client/RetryMiddleware.php
<?php
namespace App\Http\Client;
use GuzzleHttp\Promise as P;
use GuzzleHttp\Promise\PromiseInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class RetryMiddleware
{
private $nextHandler;
private $decider;
private $delay;
public function __construct(callable $decider, callable $nextHandler, callable $delay = null)
{
$this->decider = $decider;
$this->nextHandler = $nextHandler;
$this->delay = $delay ?: __CLASS__ . '::defaultDelay';
}
public static function defaultDelay(int $retries): int
{
return 0;
}
public function __invoke(RequestInterface $request, array $options): PromiseInterface
{
if (!isset($options['retries'])) {
$options['retries'] = 0;
}
$fn = $this->nextHandler;
return $fn($request, $options)
->then(
$this->onFulfilled($request, $options),
$this->onRejected($request, $options)
);
}
private function onFulfilled(RequestInterface $request, array $options): callable
{
return function ($value) use ($request, $options) {
if (!($this->decider)(
$options['retries'],
$request,
$value,
null
)) {
return $value;
}
return $this->doRetry($request, $options, $value);
};
}
private function onRejected(RequestInterface $req, array $options): callable
{
return function ($reason) use ($req, $options) {
if (!($this->decider)(
$options['retries'],
$req,
null,
$reason
)) {
return P\Create::rejectionFor($reason);
}
return $this->doRetry($req, $options);
};
}
private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null): PromiseInterface
{
$options['delay'] = ($this->delay)(++$options['retries'], $response);
// Callback?
if( $options['on_retry'] )
{
\call_user_func_array( $options['on_retry'], [
&$request,
&$options,
$response
] );
}
return $this($request, $options);
}
}
Then make asynchronous requests like this:
<?php
$url = "https://example.com/api/endpoint?foo=%s";
$data = [];
$handlerStack = \GuzzleHttp\HandlerStack::create( new \GuzzleHttp\Handler\CurlMultiHandler() );
$handlerStack->push( \App\Http\Client\Middleware::retry( function( $retries, $request, $response = null, $exception = null )
{
// Limit the number of retries to 10
if( $retries >= 10 )
{
return false;
}
// Retry connection exceptions
if( $exception )
{
return true;
}
return false;
} ) );
$client = new \GuzzleHttp\Client( [
'handler' => $handlerStack,
'on_retry' => function( &$request, &$options )
{
$options['proxy'] = $this->proxyManager->get();
}
] );
$requests = function() use ( $client, $url, $params )
{
foreach( $params as $param )
{
$get = \sprintf( $url, $param );
yield function() use ( $client, $get )
{
return $client->getAsync( $get, [
'proxy' => $this->proxyManager->get()
] );
};
}
};
$pool = new \GuzzleHttp\Pool( $client, $requests(), [
'concurrency' => 5, // maximum number of requests to send concurrently
'fulfilled' => function( \GuzzleHttp\Psr7\Response $response, $index ) use ( &$data )
{
$data[] = json_decode( $response->getBody(), true );
}, // this is delivered each successful response
'rejected' => function( \Exception $e, $index )
{
}, // this is delivered each failed request
] );
$pool->promise()->wait();
If you want to make synchronous requests with retry then Laravel's HttpClient works:
<?php
$url = "https://example.com/api/endpoint";
$response = \Illuminate\Support\Facades\Http::withOptions( [
'proxy' => $this->proxyManager->get(),
'on_retry' => function( &$request, &$options )
{
$options['proxy'] = $this->proxyManager->get();
}
] )
->withMiddleware( \App\Http\Client\Middleware::retry( function( $retries, $request, $response = null, $exception = null )
{
// Limit the number of retries to 10
if( $retries >= 10 )
{
return false;
}
// Retry connection exceptions
if( $exception )
{
return true;
}
return false;
} ) )
->get( $url );
I have this code in a Vue Component:
sendUserData(){
axios.post('/api/saveUser', {
data: {
id: this.id,
name: this.name,
email: this.email,
password: this.password
}
},
{
headers: {
Authorization: 'Bearer ' + localStorage.getItem('token')
}
}
).then(response => {
if(response.data == 'success'){
this.$emit('userSaveSuccess')
} else {
this.$emit('userSaveError')
}
});
}
and I have this in a Laravel Controller:
public function saveUser($name = '', $email = '', $password = ''){
$id = request('data.id', 0);
$name = request('data.name', $name);
$email = request('data.email', $email);
$password = request('data.pswrd', $password);
Log::info(request());
if($id == 0){
$saveUser = new User;
} else {
$saveUser = User::find($id);
if($name == ''){
$name = $saveUser -> name;
}
if($email == ''){
$email = $saveUser -> email;
}
}
$saveUser -> name = $name;
$saveUser -> email = $email;
if($password != ''){
$saveUser -> password = bcrypt($password);
}
if($saveUser->save()){
return 'success';
} else {
return 'error';
}
}
My problem is, that it's output is success, but in the MySQL DB nothing has changed.
In the Log's I got this:
[2019-09-08 12:32:08] local.INFO: array (
'data' =>
array (
'id' => 2,
'name' => 'AdminTest',
'email' => 'admin#test.com',
),
)
(The original name is Admin -> the Laravel function got the request)
I tested it with Postman, too, and that time the save method worked.
What's the problem?
Edit:
Images
Edit2:
console.log(response) image
Replace your saveUser() method with the following and it will work.
/**
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\JsonResponse
*/
public function saveUser(Request $request){
// validate request data
$validator = \Validator::make($request->all(), [
'name' => 'required',
'email' => 'required|email',
'pswrd' => 'required' // add your custom validation rule
]);
// throw an validation error with message
if ($validator->fails())
return response()->json(['message' => 'The given data was invalid.', 'errors' => $validator->errors()], 422);
// best way to get request input values ( laravel docs )
$id = $request->get('id') ?? 0;
$name = $request->name;
$email = $request->email;
$password = $request->psswrd;
// TODO: you can replace the logic with ( updateOrCreate($saveUser) )
if($id == 0){
$saveUser = new User;
} else {
$saveUser = User::find($id);
}
$saveUser -> name = $name;
$saveUser -> email = $email;
if($password != ''){
$saveUser -> password = bcrypt($password);
}
try{
$saveUser->save();
return response()->json(['message' => 'Success.', 'data' => $saveUser], 200);
}catch (\Exception $exception){
return response()->json(['message' => 'Error.', 'data' => $exception->getMessage()], 200);
}
}
I have trouble with Request validation in Laravel, when request data pass validation everything is ok but then data is invalid server response with 404
UserRequest
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'sometimes|required|unique:users,Name|min:5|max:30'
];
}
UserController
public function update(UserRequest $request, $id)
{
$token = JWTAuth::getToken();
$tokenData = JWTAuth::getPayload($token)->toArray();
if ($request->name != null) {
if (User::where('id', $tokenData['idUser'])->update(['Name' => $request->name])) {
$status = true;
} else {
$status = false;
}
}
return response()->json(['status' => $status]);
}
Try with this
public function update(UserRequest $request, $id)
{
$token = JWTAuth::getToken();
$tokenData = JWTAuth::getPayload($token)->toArray();
$validated = $request->validated();
if ($validated) {
if (User::where('id', $tokenData['idUser'])->update(['Name' => $request->name])) {
$status = true;
} else {
$status = false;
}
return response()->json(['status' => $status]);
}
else {
return redirect()->back()->withErrors($validated);
}
}
Hope this helps :)
I have written a code in the controller which is given below. This code is for login page. In this code, the if statement notification is properly working but the else part is not working. It is not redirect to the url given in the redirect() instead it is showing a blank page. Can anyone tell y it is like that and correct it for me ? I have used header() function but also it is not working.I have placed all the code inside the 'kw' folder. This code is properly working in the localhost but when uploaded the same code to the live server, its not working.Is it due to version of the CI ?
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Login extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library('session');
$this->load->library('validation');
$this->load->model('studentsmodel');
}
public function index() {
if (isset($_POST['submit']))
{
$post_data = array('stud_cin' => $this->input->post('stud_cin'),'stud_password' => $this->input->post('stud_password'),
);
$this->validation->set_data($post_data);
$this->validation->set_rules('stud_cin','Cin','required|trim');
$this->validation->set_rules('stud_password','Password','required|trim');
if ($this->validation->run() === FALSE)
{
}
else
{
$this->load->model("studentsmodel");
$this->load->helper('url');
$result = $this->studentsmodel->loginCheck($post_data);
if (!$result){
$this->notifications->notify('Wrong username/password; Login Failed','error');
}
else{
$this->session->set_userdata('student_id', $result['id']);
$this->session->set_userdata('stud_cin', $result['stud_cin']);
$this->session->set_userdata('stud_photopath', $result['stud_photopath']);
redirect('student/profile/edit/id/'.$this->session->userdata('student_id'),'refresh');
//header('location:http://www.website.com/kw/application/controller/student/profile/edit/id/$this->session->userdata("student_id")');
}
}
} $this->load->view("login");
}
}
profile controller edit function
public function index()
{
$student_id=$this->session->userdata('student_id');
$data['profile_data'] =$this->studentsmodel->get_Cinprofile($student_id);
$this->load->view("profileDetails.php", $data);
}
public function edit()
{
$uri = $this->uri->uri_to_assoc(4);
$student_id=$uri['id'];
if(isset($_POST['btn_submit']))
{
//echo "<pre>";print_r($_FILES);exit;
$img_val = $this->studentsmodel->getStudent_photo($student_id);
$photo_val = $img_val['stud_photopath'];
$photo_unlink = "";
if ($_FILES['stud_photopath']['name'] != "")
{
/*echo "in";exit;*/
$photo_chk = explode("photo/", $photo_val);
$photo_unlink = $photo_chk[1];
$photo_path = "";
$flag = "";
$f_type_chk = $_FILES['stud_photopath']['type'];
if ($f_type_chk != "image/gif" && $f_type_chk != "image/jpg" && $f_type_chk != "image/jpeg"
&& $f_type_chk != "image/bmp" && $f_type_chk != "image/png" && $f_type_chk != "")
{
$flag = "Select allowed file type and size for photo";
}
if ($_FILES['stud_photopath']['size'] >= 5242880) { $flag = "Select allowed file type and size for photo"; }
$target_path = getcwd() . "/public/photo/";
$db_path = "photo/";
if ($_FILES['stud_photopath']['name'] != '')
{
$file_name = $_FILES["stud_photopath"]["name"];
$file_size = $_FILES["stud_photopath"]["size"] / 1024;
$file_type = $_FILES["stud_photopath"]["type"];
$file_tmp_name = $_FILES["stud_photopath"]["tmp_name"];
$random = rand(111, 999);
$new_file_name = $random . $file_name;
$newfile_name=$cin."_". $file_name;
$upload_path = $target_path . $newfile_name;;
if (move_uploaded_file($file_tmp_name, $upload_path)) { $photo_path = addslashes($db_path . $newfile_name); } /*end if*/
else { $this->notifications->notify('Photo cannot upload', 'error'); }/*end else var_dump($this->validation->show_errors());*/
}/*end if $_FILES['photo']['name']*/
} /*END OF if ($_FILES['photo']['name'] != "") */
else { $photo_path = $photo_val; } /*END OF ELSE ($_FILES['photo']['name'] != "") */
$this->session->unset_userdata('stud_photopath');
$this->session->set_userdata('stud_photopath', $photo_path);
$data['photo_unlink'] = $photo_unlink;
/* echo $dob_dd = $this->input->post('dob_dd');exit;
$dob_mm = $this->input->post('dob_mm');
$dob_yy = $this->input->post('dob_yy');
$dob = $dob_dd . "-" . $dob_mm . "-" . $dob_yy;*/
$stud_age_dob =$this->input->post('stud_age_dob');
$timestamp = strtotime($stud_age_dob);
$dob = date('Y-m-d', $timestamp);
$validation_data = array(
'stud_name' => $this->input->post('stud_name'),
'stud_gender' => $this->input->post('stud_gender'),
'stud_age_dob' =>$this->input->post('stud_age_dob'),
'stud_mobile' => $this->input->post('stud_mobile'),
'stud_email' => $this->input->post('stud_email'),
);
//echo "<pre>";print_r($validation_data); exit;
$this->validation->set_data($validation_data);
$this->validation->set_rules('stud_name', 'Student Name', 'trim|alpha_space|required');
$this->validation->set_rules('stud_gender', 'Gender', 'required');
$this->validation->set_rules('stud_age_dob', 'DOB', 'required');
$this->validation->set_rules('stud_mobile', 'Mobile number', 'numeric|required');
$this->validation->set_rules('stud_email', 'Email Id', 'trim|required|valid_email|xss_clean');
if ($this->validation->run() === FALSE)
{ /* var_dump($this->validation->show_errors()); */ $this->notifications->notify('Please make all entries', 'error');}
else
{
$updation_data=array(
'stud_name' => $this->input->post('stud_name'),
'stud_gender' => $this->input->post('stud_gender'),
'stud_age_dob' => $this->input->post('stud_age_dob'),
'stud_gaurdian' =>$this->input->post('stud_gaurdian'),
'stud_mother' =>$this->input->post('stud_mother'),
'stud_mobile' => $this->input->post('stud_mobile'),
'stud_email' => $this->input->post('stud_email'),
'stud_tel' => $this->input->post('stud_tel'),
'stud_guardian_address' => $this->input->post('stud_guardian_address'),
'stud_pin' => $this->input->post('stud_pin'),
'stud_photopath' => $photo_path,
'stud_age_dob' => $dob
);
/*echo "<pre>";print_r($updation_data); exit; */
$update_status=$this->studentsmodel->update_profile($updation_data, $student_id);
if($update_status==1)
{
//$this->session->set_userdata('profile_status', 'Yes');
/*$this->session->userdata('profile_status');*/
redirect('student/profile/index/', 'refresh');
}
else
{
$this->notifications->notify('profile updted failed', 'error');
}
$data['profile_data']=$_POST;
}
$data['profile_data']=$_POST;
}
$data['profile_data']=$this->studentsmodel->get_Cinprofile($student_id);
$this->load->view("profile_edit.php",$data);
}
Check if you already load this helper
$this->load->helper('url');
This is the information about the redirect function
redirect($uri = '', $method = 'auto', $code = NULL);
Parameters:
$uri (string) URI string $method (string)
Redirect method (‘auto’,
‘location’ or ‘refresh’)
$code (string) HTTP Response code (usually 302 or 303)
Note:
Don't forget add in the config file the value for base_uri
https://www.codeigniter.com/user_guide/helpers/url_helper.html
https://www.codeigniter.com/userguide3/libraries/config.html
remove /id/ from your redirect()
redirect('student/profile/edit/'.$this->session->userdata('student_id'));
Im trying to send a POST request to an external website, from what iv read so far its not possible due to same origin policy. But i'v also read a proxy can bypass this.
Is this possible AT ALL if I don't have access to the external website? I can't seem to clarify this.
I just want to send an AJAX POST and get the response like when i use Chrome's Advanced REST Client.
Set your header with
Access-Control-Allow-Origin: http://foo.example
To any other noobies in the problem
Slightly modified this:
https://github.com/eslachance/php-transparent-proxy
Now accepts a posting url:
<?php
if(!function_exists('apache_request_headers')) {
// Function is from: http://www.electrictoolbox.com/php-get-headers-sent-from-browser/
function apache_request_headers() {
$headers = array();
foreach($_SERVER as $key => $value) {
if(substr($key, 0, 5) == 'HTTP_') {
$headers[str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;
}
}
return $headers;
}
}
// Figure out requester's IP to shipt it to X-Forwarded-For
$ip = '';
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
//echo "HTTP_CLIENT_IP: ".$ip;
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
//echo "HTTP_X_FORWARDED_FOR: ".$ip;
} else {
$ip = $_SERVER['REMOTE_ADDR'];
//echo "REMOTE_ADDR: ".$ip;
}
//
preg_match('#^(?:http://)?([^/]+)#i', $_SERVER['HTTP_REFERER'], $matches);
$host = $matches[1];
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
$domainName = "{$matches[0]}";
//
//writelog($_POST);
$method = $_SERVER['REQUEST_METHOD'];
$desturl;
// parse the given URL
if($method == "POST") {
$desturl = $_POST['url'];
unset($_POST['url']);
}
else if ($method == "GET") {
$desturl = $_GET['url'];
unset($_GET['url']);
}
$response = proxy_request($desturl, ($method == "GET" ? $_GET : $_POST), $method);
$headerArray = explode("\r\n", $response[header]);
foreach($headerArray as $headerLine) {
header($headerLine);
}
echo $response[content];
function proxy_request($url, $data, $method) {
// Based on post_request from http://www.jonasjohn.de/snippets/php/post-request.htm
global $ip;
// Convert the data array into URL Parameters like a=b&foo=bar etc.
//$data = http_build_query($data);
$data = json_encode($data, JSON_FORCE_OBJECT);
writelog($data);
$datalength = strlen($data);
$url = parse_url($url);
//echo $url;
if ($url['scheme'] != 'http') {
die('Error: Only HTTP request are supported !');
}
// extract host and path:
$host = $url['host'];
$path = $url['path'];
// open a socket connection on port 80 - timeout: 30 sec
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if ($fp){
$out="";
if($method == "POST") {
$out ="POST $path HTTP/1.1\r\n";
} else {
$out ="GET $path?$data HTTP/1.1\r\n";
}
//Todo Get headers and forward them...
$requestHeaders = apache_request_headers();
while ((list($header, $value) = each($requestHeaders))) {
/*if($header !== "Connection" && $header !== "Host" && $header !== "Content-Length"
&& $header !== "Content-Type"
&& $header !== "Origin"
&& $header !== "Referer"
&& $header !== "X-Requested-With"
&& $header !== "Accept-Encoding"
) {
// $out.= "$header: $value\r\n";
writelog("$header: $value\r\n");
}*/
if($header == "Cookie" && $header == "User-Agent" ) {
$out.= "$header: $value\r\n";
//writelog("$header: $value\r\n");
}
}
$out.= "Host: $host\r\n";
$out.= "Content-Type: application/json; charset=UTF-8\r\n";
$out.= "Content-Length: $datalength\r\n";
$out.= "Connection: Close\r\n\r\n";
$out.= $data;
fwrite($fp, $out);
$result = '';
while(!feof($fp)) {
// receive the results of the request
$result .= fgets($fp, 128);
}
}
else {
return array(
'status' => 'err',
'error' => "$errstr ($errno)"
);
}
// close the socket connection:
fclose($fp);
// split the result header from the content
$result = explode("\r\n\r\n", $result, 2);
$header = isset($result[0]) ? $result[0] : '';
$content = isset($result[1]) ? $result[1] : '';
// return as structured array:
return array(
'status' => 'ok',
'header' => $header,
'content' => $content
);
}
?>