Laravel Excel - How to avoid export timeout? - laravel

I'm trying to export some data using fromview interface.
public function view(): View
{
$this->view = "admin.reports.price_summary_export";
$this->data = PriceReportController::getData($this->data, $this->filters, $this->rj);
return view($this->view, ["xls" => true, "data" => $this->data, "filters" => $this->filters]);
}
When $this->data is large the code will always timeout at CloseSheet. Is there any way to avoid this error?
Im a beginner in laravel so i dont understand much. So far i've tried extending the timeout to 10 minutes and it can run properly, but i dont like this solution. Im trying to find another solution for this issue

Related

Issue with Integers passing data from Vue to Laravel using FormData

I am successfully updating a database using Vue 2 to a Laravel 8 Controller using Axios. However, I am stuck when attempting to pass an integer to my database.
My database has a column, 'number_of_searches' and it must be an integer.
Laravel Migration looks like this:
$table->integer('number_of_searches')->nullable();
And the model looks something like this:
class Product extends Model
{
protected $fillable = [
'product_title',
'number_of_searches' => 'integer',
];
}
My Vue updateProduct() function used FormData and appends the values coming from the form. It looks like this:
updateProduct(product){
let data = new FormData();
data.append('_method', 'PATCH');
data.append('product_title', product.product_title);
data.append('number_of_searches', product.number_of_searches);
axios.post('/api-route-to-update/product_id/', data)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
My update controller looks like this:
public function update(Request $request, $product_id){
$product = Product::findOrFail($product_id);
$product->update($request->all());
$product->save();
}
I can have as many input fields as I need and it works perfectly as long as they are strings. However, when I use a number input field in my component such as:
<input v-model="product.number_of_searches" type="number" min="1" max="999">
The generated json that will pass from axios into my controller looks like this:
{ "id": 5, "product_title": "The Product Title will work great", "number_of_searches": "222"}
You will notice that 'number_of_searches' is passed as a string, hence my database fails because it is the wrong datatype, it requires an integer. After reading the documentation and other threads, it seems that FormData will always return strings and that I must just deal with this on the server side.
So what I did is, I went into my back-end updateProduct() method and attempted to modify the Request.
First I tried a few methods such as:
//this one
$requestData = $request->all();
$requestData['number_of_searches'] = 123;
//also this one
$request->merge(['number_of_searches' => 123]);
//and this
$data = $request->all();
$data['number_of_searches'] = 123;
After countless hours, I am unable to modify the original request. After doing some research, it seems that requests are protected and cannot be modified, which makes sense. Therefore I attempted to create a new request that clones $request->all(), like this:
$new_request = new Request($request->all());
$new_request->merge(['number_of_searches' => 123]);
But I have failed to force to override 'number_of_searched'
My question is:
Should I stay away from FormData completely in this case? What method do you suggest to pass forms that have integers or floats or other datatypes through axios or fetch? Or what am I doing wrong? I find it hard to believe that FormData would only send strings (making parseInt useless before using axios). I'm sure I am doing something wrong from origin.
On the other hand, maybe I need to completely change my approach in my Controller when receiving the data. I am working on an app with a lot of fields and I love $request->all() because it simplifies what I am trying to do. I wouldn't mind using intval on the server side and that's it, but it seems overly complicated.
On the Vue side, you can use the number modifier on v-model to make sure it's not casting the value to a string:
v-model.number="product.number_of_searches"
On the request side, you can use $request->merge to override the value in a request
$request->merge([
'number_of_searches' => (int) $request->get('number_of_searches');
]);
At the model side in the updating hook within the boot method you can ensure the value is being casted as an int when saving:
static::updating(function ($model) {
$model->number_of_searches = (int) $model->number_of_searches;
});
This should give you the end to end.

Laravel Event Listening

I have an issue similar to this post :
Laravel - last login date and time timestamp
In short, my purpose and question is :
I have a "logrecords" table in my database.
My event listeners in global.php are just working on default "users" table.
I want my event listeners are able to insert data on my "logrecords" table.
How can i do that :
Should i configure my database tables using which are using eloquent ?
Or should i change something in global.php ?
Thanks for your support.
--------------------Update--------------------
I realized that in my auth.php file, default authentication model has been set as :
'model' => 'User'
But i want to listen and work with both User and Logrecord model.So that when i try to listen events in my global.php file, laravel is automatically trying to work with User model. So that i had to configure my event listeners like that :
Part of my global.php file :
//First Example
Event::listen('auth.login', function($user)
{
$userLogRecord = Logrecord::firstOrCreate(array('user_id' => $user->id));
$userLogRecord->user_id = $user->id;
$userLogRecord->login_last_at = date('Y-m-d H:i:s');
$userLogRecord->save();
});
//Second Example
Event::listen('auth.logout', function($user)
{
$userLogRecord = Logrecord::firstOrCreate(array('user_id' => $user->id));
$userLogRecord->user_id = $user->id;
$userLogRecord->logout_last_at = date('Y-m-d H:i:s');
$userLogRecord->save();
});
It is working for now, but I am thinking that it's not a good idea to edit my listeners like that. My purpose is to listen and do some process with both User and Logrecord models. It serves my purpose right now but i feel like i have to improve.
Any ideas ?
#DemonDrake,
If I understand correctly you simply want to add data to a "log" table?
In the most simple form, the answer is "Yes you would use the eloquent ORM for that
class Log extends Eloquent {
protected $table = 'log';
}
or perhaps query builder even.
There are a number of ways this is possible. I personally suggest you check out https://laracasts.com/lessons

How to set a proxy using phpunit and selenium2?

I cant find example with PHPunit. I don't know what function i suppose to use. there are a lot examples for java but i cant find nothing for PHPUnit.
I opened the http://localhost:4444/wd/hub/static/resource/hub.html
and in capabilities there aren't settings for a proxy.
When i used the function setDesiredCapabilities the selenium always opened IE. Below are my "code"
class testtest extends PHPUnit_Extensions_Selenium2TestCase {
protected function setUp()
{
$capabilities=array('browser' => 'firefox');
$this->setDesiredCapabilities($capabilities);
$this->setBrowserUrl('http://www.test.com/');
}
public function testvvatg()
{
$this->url('http://www.test.com');
$url=$this->title();
$this->assertEquals('asdf', $url);
}
}
Please help thanks
While this topic is old, I found it while googling for a solution to the problem, so I figured I'd contribute.
Reading the source of PHPUnit Selenium2TestCase, you can see a link to the format that setDesiredCapabilities requires. In particular, you'd want the Proxy JSON Object format.
For example:
$this->setDesiredCapabilities(array(
"proxy" => array(
"proxyType" => "manual",
"httpProxy" => "proxyhost.com:1337",
"noProxy" => "dontproxy.me/please" //This one is undocumented. I'm not sure how to specify more than one
)
));

Transaction test mode in CodeIgniter

I saw in the docs about CodeIgniter:
"you can optionally put the transaction system into "test mode", which
will cause your queries to be rolled back -- even if the queries
produce a valid result. To use test mode simply set the first
parameter in the $this->db->trans_start() function to TRUE"
I understand that able to use transaction (test_mode) to support database fixture for testing insert, update, delete. But it still affects to Database. I set db_debug is TRUE.
Any idea about this problem? Thanks so much.
Example code in my controller:
public function __construct(){
//load database library and model
$this->load->library('database');
$this->load->model('message_mdl');
}
public function do()
{
$data_insert = array('message' => 'hello');
$this->db->trans_start(true);
$this->message_mdl->insert($data_insert);
$this->db->trans_complete();
}
I tried this its not working for me too. I don't know why! I'll trying to find the reason. 'll get back here with proper method. If you find it out pls let me know too.
But I tried the alternate method, its working fine.
public function dothis()
{
$data_insert = array('message' => 'hello');
$this->db->trans_begin(); //Manually start transaction.
$this->message_mdl->insert($data_insert);
$this->db->trans_rollback(); //Rollback
}
Make sure that you don't use $this->db->trans_off(); at all.

Codeigniter Datamapper not running get rules on fields with NULL values

I'm using Datamapper v1.8.2 with Codeigniter v2.1.2 and have a "get" rule that doesn't seem to run on fields with NULL values. Here's the model:
class Page extends Datamapper {
public $validation = array(
'name' => array(
'rules' => array('required'),
'get_rules' => array('get_page_name')
)
);
function _get_page_name($field)
{
$this->$field = 'TESTING '.$this->id;
}
}
Example code:
$page = new Page();
foreach ($page->get() as $p) echo $p->name;
When the table field name has any non-null value including an empty string it works fine outputting something like TESTING 358, but when the value is NULL (which is the default value for this field), it outputs nothing. There is no difference using get_iterated().
I guess I could work around this by changing the default value, but I'm wondering if I'm doing something wrong or missed something in the documentation, or maybe it's a bug? Does anyone know what the issue is?
Also, if someone could point me to the proper thread in the CI forums for Datamapper 1.8.2 support that would be great, I'm trying to find it and getting lost in a maze of links to threads for old versions of DM.
You need to add the allow_null to the get_rules array to make this work. I'm not sure about the intent of the creator but this is how get_rules are implemented (however i don't see it mentioned in the docs).

Resources