sendOutputTo in Laravel Console - laravel

I scheduled a cronjob through Laravel console. It is working and giving the result in every minute. But I tried to write the output to a file using the sendOutputTo and appendOutputTo method. But this is not writing to the file. My file has write permission.
Below is my code:
Kernel.php
protected function schedule(Schedule $schedule) {
$filePath = base_path() . "\cron\CleanSession.txt";
$schedule->command('cleansession')
->everyMinute()
->sendOutputTo($filePath);
}
Session.php
public function handle() {
$this->info('Display this on the screen');
$onlineCodeObj = new OnlineCode();
if ($onlineCodeObj->cleanSession()) {
echo "SESSION CLEANED : echo" . "\n";
return "SESSION CLEANED: return" . "\n";
}
echo "SESSION CLEANED : echo2" . "\n";
return "SESSION CLEANED: return2" . "\n";
}

Solved the issue. Changed the path
$filePath = base_path() . "\cron\CleanSession.txt"; to $filePath = base_path() . "/cron/CleanSession.txt";

Related

Cannot move image/files temp to public directory Laravel 9

I am trying to upload an image in Laravel. Getting the following error:
"message": "Could not move the file \"C:\\xampp\\tmp\\php84AA.tmp\" to \"F:\\bvend\\bvend-web\\public\\uploads/products\\bvend-product-1666274539.jpg\" (move_uploaded_file(): Unable to move "C:\\xampp\\tmp\\php84AA.tmp" to "F:\\bvend\\bvend-web\\public\\uploads/products\\bvend-product-1666274539.jpg").",
"exception": "Symfony\\Component\\HttpFoundation\\File\\Exception\\FileException",
"file": "F:\\bvend\\bvend-web\\vendor\\symfony\\http-foundation\\File\\UploadedFile.php",
"line": 177,
"trace": [ .... ]
My code is given below:
public function uploadImage($image, $image_path)
{
$path = config('global.' . $image_path . '_image_path');
file_exists($image) && unlink($image);
$image_name = 'bvend-' . $image_path . '-' . time() . '.' . $image->getClientOriginalExtension();
$image->move($path, $image_name); // $path: public_path('uploads/products')
return $image_name;
}
I understand its a simple issue but still no clue where it causing issue.
Edit
#WahidulAlam Please, try removing file_exists($image) && unlink($image);
– steven7mwesigwa - https://stackoverflow.com/posts/comments/130904221?noredirect=1
#WahidulAlam You're essentially deleting the temporary file/image before its copied or moved.
– steven7mwesigwa - https://stackoverflow.com/posts/comments/130904261?noredirect=1
ah this is the catch !! thanks a lot.
– Wahidul Alam - https://stackoverflow.com/posts/comments/130904399?noredirect=1
Specifying A File Name
If you do not want a filename to be automatically assigned to your
stored file, you may use the storeAs method, which receives the
path, the filename, and the (optional) disk as its arguments:
$path = $request->file('avatar')->storeAs(
'avatars', $request->user()->id
);
You may also use the putFileAs method on the Storage facade, which
will perform the same file storage operation as the example above:
$path = Storage::putFileAs(
'avatars', $request->file('avatar'), $request->user()->id
);
Solution
public function uploadImage(\Illuminate\Http\UploadedFile $image, $image_path)
{
return $image->storePubliclyAs(
config('global.' . $image_path . '_image_path'),
'bvend-' . $image_path . '-' . time(),
["disk" => "public"]
);
}
Addendum
Don't forget to create a symbolic link from public/storage to storage/app/public. I.e:
php artisan storage:link.
The Public Disk
Once a file has been stored and the symbolic link has been created,
you can create a URL to the files using the asset helper:
echo asset('storage/file.txt');
In Summary
$savedPath = $request->file("***REQUEST-INPUT-IMAGE-NAME-HERE***")->storePubliclyAs(
"***IMAGE-PATH-HERE***",
"***CUSTOM-FILENAME-HERE***",
["disk" => "public"]
);
I am using this methodology in Laravel 9.
try this:
public function uploadImage($image, $image_path)
{
// $path = config('global.' . $image_path . '_image_path');
file_exists($image) && unlink($image);
$image_name = 'bvend-' . $image_path . '-' . time() . '.' . $image->getClientOriginalExtension();
//$image->move($path, $image_name); // $path: public_path('uploads/products')
$image->move(public_path('/images'), $image_name);
return $image_name;
}

laravel snappy pdf: getting an error the file was not created

I have about 1500 students in my database and I need to generate an invoice for each one. For this purpose I am using this library https://github.com/barryvdh/laravel-snappy . When I try to generate I get this error:
The file '/var/www/skmpastebimaslt/public_html/storage/checks/24767 Dominykas Butkevičius 1581703819.pdf' was not created (command: /usr/local/bin/wkhtmltopdf --lowquality '/tmp/knp_snappy5e46e28b5d61f2.13362077.html' '/var/www/skmpastebimaslt/public_html/storage/checks/24767 Dominykas Butkeviius 1581703819.pdf').
https://gyazo.com/3a3f60713601a663a1360cd65fee9914
Invoices are generated for four users then the app crashes. The most interesting thing is that even though the error says the file was not created but it was created, I can find it in my storage folder.
My code:
public function saveCheckPdf(Student $student, Check $check = null, $fileName = null)
{
if (empty($fileName)) {
$fileName = 'kvitas_' . time() . '.pdf';
}
$path = storage_path('checks/' . $fileName . '.pdf');
$this->renderCheckPdf($student, $check)->save($path);
return $path;
}
private function renderCheckPdf(Student $student, Check $check = null)
{
$bills = $this->billRepository->getCurrentSeasonBills($student->id);
$payments = $this->paymentRepository->getCurrentSeasonPayments($student->id);
$fileName = $student->fullname . ' kvitas';
$billsSum = $bills->sum('sum');
$paymentsSum = $payments->sum('sum');
if (empty($check)) {
$check = !empty($student->checks[0]) ? $student->checks[0] : false;
}
return newPDF::loadView('student.check_pdf', compact('student', 'payments', 'bills', 'billsSum', 'paymentsSum', 'fileName', 'check'));
}
Then I just loop through each user and call saveCheckPdf method in my controller like this
$this->pdfService->saveCheckPdf($student, null, $student->id . ' ' . $student->fullname . ' ' . time());
Maybe anyone faced the same problem?

Laravel 5.4 Error: NotReadableException: Image source not readable

I'm trying to create multiple copies of profile pic in different sizes when a profile is created. But I am constantly getting this error:
" NotReadableException: Image source not readable"
Can somebody point me what I'm missing in my below code:
public function updateprofile(UserProfileRequest $request){
$user_id = Auth::User()->id;
$profile = UserProfile::where('user_id','=',$user_id)->first();
$profile->fullname = $request->fullname;
if ($request->hasFile('img')) {
if($request->file('img')->isValid()) {
$types = array('_original.', '_32.', '_64.', '_128.');
$sizes = array( '32', '64', '128');
$targetPath = 'public/uploads/'.$user_id;
try {
$file = $request->file('img');
$ext = $file->getClientOriginalExtension();
$fName = time();
$original = $fName . array_shift($types) . $ext;
Storage::putFileAs($targetPath, $file, $original);
foreach ($types as $key => $type) {
$newName = $fName . $type . $ext;
Storage::copy($targetPath . $original, $targetPath . $newName);
$newImg = Image::make($targetPath . $newName);
$newImg->resize($sizes[$key], null, function($constraint){
$constraint->aspectRatio();
});
$newImg->save($targetPath . $newName);
}
$profile->img = 'public/uploads/'.$user_id;
} catch (Illuminate\Filesystem\FileNotFoundException $e) {
}
}
}
$profile->save();}
I had the same issue i ran this command and it worked
php artisan storage:link
This command creates a storage directory under the public folder.
Also use public path function to get the public path
$targetPath = public_path('storage/uploads/'. $user_id);
The 'storage' used inside the laravel public_path() function is used to get the storage main folder.
If I'm not mistaken, the path which is provided should be the absolute filepath on your server. For example instead of:
$targetPath = 'public/uploads/'.$user_id;
Use (your actual path will vary depending on your configuration)
$targetPath = '/var/www/sitename/public/uploads/'.$user_id;
Laravel also contains a helper function called public_path() which can be used to obtain the "fully qualified path to the public directory". This would allow you to use something such as:
$targetPath = public_path('uploads/'. $user_id);
Also, on this line, do not forget to place a slash before the new filename:
$newImg = Image::make($targetPath . '/' . $newName);
I would also confirm that the user executing the script (if apache or nginx usually www-data unless altered) has write permissions to your public/uploads/ directory
Finally, I got it working. I made following changes to my code:
Use the full OS path as suggested by commanderZiltoid for the destination path.
Don't use Storage::putFileAs method to save the file. So, remove this line: Storage::putFileAs($targetPath, $file, $original);
Don't use Storage::copy() to copy the file, so, remove this line:
Storage::copy($targetPath . $original, $targetPath . $newName);
For points 2 and 3, use Image::make($file->getRealPath()); This will create the file and remember the path where the file was created. Image->resize method will use this path later.
In the end, save the relative path in the database, as here: $profile->img = 'storage/uploads/'.$user_id.'/img/profile/'.$fName. Since we'll use {{ asset($profile->img) }}, it's necessary to save only the relative path and not the absolute OS path.
if($request->hasFile('img')) {
if($request->file('img')->isValid()) {
$types = array('_original.', '_32.', '_64.', '_128.');
$sizes = array( array('32','32'), array('64','64'), array('128','128'));
$targetPath = '/Users/apple/Documents/_chayyo/chayyo/storage/app/public/uploads/'.$user_id.'/img/profile/';
try {
$file = $request->file('img');
$ext = $file->getClientOriginalExtension();
$fName = time();
$o_name = $fName . array_shift($types) . $ext;
$original = Image::make($file->getRealPath());
$original->save($targetPath . $o_name);
foreach ($types as $key => $type) {
$newName = $fName . $type . $ext;
$newImg = Image::make($file->getRealPath());
$newImg->resize($sizes[$key][0], $sizes[$key][1]);
$newImg->save($targetPath . $newName);
}
$profile->img = 'storage/uploads/'.$user_id.'/img/profile/'.$fName;
}
catch (Illuminate\Filesystem\FileNotFoundException $e) {
}
}
}

How to wait for guzzle request to be completed while doing something else during waiting?

I want to do something in a loop while a guzzle request is going on and then just continue the script when the request ends, for example I want to do something like this :
$client = new \GuzzleHttp\Client();
$promise = $client->headAsync("https://www.google.com");
$promise->then(
function (ResponseInterface $res) {
echo $res->getStatusCode() . "\n";
},
function (RequestException $e) {
echo $e->getMessage() . "\n";
}
);
while($promise->getState() === "pending"){
$queue = \GuzzleHttp\Promise\queue();
$queue->run();
echo "Waiting\n";
sleep(1);
}
and this code just prints "Waiting" for ever. how can I achieve this ?
Was looking for the same answer, so here is what I found, You need to tick the curl request (so that request(s) are actually processes).
Working example:
$curl = new \GuzzleHttp\Handler\CurlMultiHandler();
$handler = \GuzzleHttp\HandlerStack::create($curl);
$client = new \GuzzleHttp\Client(['handler' => $handler]);
$promise = $client->headAsync("https://www.google.com");
$promise->then(
function (ResponseInterface $res) {
echo $res->getStatusCode() . "\n";
},
function (RequestException $e) {
echo $e->getMessage() . "\n";
}
);
$queue = \GuzzleHttp\Promise\queue();
while($promise->getState() === "pending"){
$curl->tick();
//echo "Waiting\n"; Commented out as it prints A LOT without sleep, but sleep slows down the rest.
}
I put this code together after looking at this issue: https://github.com/guzzle/guzzle/issues/1127

laravel 4 artisan command memory issue

I wrote an artisan command to export exercises from a database, to standalone packages that can be used in an e-learning system like moodle, ...
It is a huge amount of exercises, and after a while the memory gets exhausted.
I tried to unset variables, activate the garbage collector, disabled the query log, and did some profiling, but till now with no success
I attached my script below, with each exercise I process, the memory usage adds up with 300k
Any idea's what I can do?
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
set_time_limit(0);
class ExerciseExportCommand extends Command {
/**
* The console command name.
*
* #var string
*/
protected $name = 'exercises:export';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Export all exercises of a method or a specific exercise.';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return void
*/
public function fire()
{
try {
DB::disableQueryLog();
ini_set('memory_limit','1024M');
$this->info('Initial: ' . number_format(memory_get_usage(), 0, '.', ',') . " bytes\n");
$base = base_path() . "/export/";
$playerPath = base_path() . "/public/preview/dist/";
$uploadsPath = base_path() . "/public/uploads/";
$methodId = $this->option('method');
$categoryId = $this->option('category');
$exerciseId = $this->option('exercise');
$this->info("Swing baby...");
$this->info("Let's export some exercises, shall we ?");
//we make an array which holds all the exercises we have to export
$exercises = array();
if($methodId === NULL && $categoryId === NULL && $exerciseId === NULL){
//we are here now anyways, let's do all exercises at once...
$this->comment("Nothing specified, let's do all exercises ");
$exercises2 = Exercise::all();
foreach ($exercises2 as $exercise){
array_push($exercises, $exercise->id);
}
unset($exercises2);
}
//get all exercises for given methodId
if($methodId !== NULL){
$method = Method::with('categories.exercises')->find($methodId);
if($method == NULL) break;
$this->comment("We are ready to roll method " . $method->code);
foreach($method->categories as $category){
foreach($category->exercises as $exercise->id){
array_push($exercises, $exercise);
}
}
unset($method);
}
//get all exercises for given categoryId
if($categoryId !== NULL){
$category = Category::with('exercises')->find($categoryId);
if($category == NULL) break;
$this->comment("We are ready to roll category " . $category->name_prefix . " " . $category->name);
foreach($category->exercises as $exercise->id){
array_push($exercises, $exercise);
}
unset($category);
}
if($exerciseId != null){
$exercise = Exercise::find($exerciseId);
if($exercise != NULL) {
array_push($exercises, $exercise->id);
$this->comment("Exercise added for export: " . $exercise->name_prefix . " " . $exercise->name);
} else {
}
unset($exercise);
}
if(empty($exercises)){
$this->error("No exercises could be found for given method/exercise");
exit();
} else {
$this->comment("Currently counting " . count($exercises) . " exerises to export");
}
$fs = new Filesystem();
//loop the exercises and publish like a charm
foreach($exercises as $exerciseId){
$exercise = Exercise::find($exerciseId);
//determine destination
$path = $base . $exercise->getPath();
$this->comment("starting exercise " . $exercise->id);
//check if path exists, if it does, wipe it out
if($fs->exists($path)){
$fs->deleteDirectory($path, true);
$this->comment("wiped out " . $path);
}
//copy player files
//echo "copying " . $path . "<br />";
$fs->copyDirectory($playerPath, $path);
$fs->cleanDirectory($path."styles/skins");
//copy only necesary skin files to save disk space
$method = $exercise->method();
if($fs->exists($playerPath."styles/skins/".$method->code)){
$fs->copyDirectory($playerPath."styles/skins/".$method->code, $path."styles/skins/".$method->code);
} elseif($method->code == "kameleonspelling" || $method->code == "kameleontaalbeschouwing"){
$fs->copyDirectory($playerPath."styles/skins/kameleon", $path."styles/skins/kameleon");
}
if($fs->exists($playerPath."styles/skins/".$method->code.".css")){
$fs->copy($playerPath."styles/skins/".$method->code.".css", $path."styles/skins/".$method->code.".css");
}
$this->comment("copied player files to " . $path);
//copy resources
//echo "copying resources " . $path . "<br />";
$fs->copyDirectory($uploadsPath . $exercise->id . "/", $path);
$this->comment("copied resources to " . $path);
//copy slide resources
$slides = Slide::where('exerciseID',"=",$exercise->id)->get();
mkdir($path."slides/");
foreach ($slides as $slide) {
$image = $slide->image()->first();
if($image != NULL){
$this->info($uploadsPath."slides/".$image->resourceUri);
$this->info($path."slides/".$image->resourceUri);
$fs->copy($uploadsPath."slides/".$image->resourceUri, $path."slides/".$image->resourceUri);
}
unset($image);
}
$this->comment("copied slide resources to " . $path);
//save xml file
$content = Exercise::getXmlContent($exercise->id);
$fs->put($path . "exercise.xml", View::make('xml', $content));
$this->comment("saved xml to " . $path);
$this->info("finished exercise " . $exercise->id);
unset($method);
unset($content);
unset($slides);
gc_collect_cycles();
$this->info('Peak: ' . number_format(memory_get_peak_usage(), 0, '.', ',') . " bytes\n");
$this->info('End: ' . number_format(memory_get_usage(), 0, '.', ',') . " bytes\n");
}
$this->info("Awesome Possum => finished all exercises ");
$this->info('Peak: ' . number_format(memory_get_peak_usage(), 0, '.', ',') . " bytes\n");
$this->info('End: ' . number_format(memory_get_usage(), 0, '.', ',') . " bytes\n");
} catch(Exception $e){
$this->error($e->getMessage());
$this->comment($e->getTraceAsString());
}
}
/**
* Get the console command arguments.
*
* #return array
*/
protected function getArguments()
{
return array(
//array('example', InputArgument::REQUIRED, 'An example argument.'),
);
}
/**
* Get the console command options.
*
* #return array
*/
protected function getOptions()
{
return array(
array('method', null, InputOption::VALUE_OPTIONAL, 'The id of a method for which all the exercises to export.', null),
array('category', null, InputOption::VALUE_OPTIONAL, 'The id of a category for which all the exercises to export.', null),
array('exercise', null, InputOption::VALUE_OPTIONAL, 'The id of an exercise to export.', null),
);
}
}
This is a dump of my xdebug trace command, with the 20 most memory consuming statements:
Showing the 20 most costly calls sorted by 'memory-own'.
Inclusive Own
function #calls time memory time memory
-------------------------------------------------------------------------------------------------------
debug_backtrace 646 0.0420 20353496 0.0420 20353496
Composer\Autoload\ClassLoader->loadClass 259 0.1911 17556224 0.1139 13953824
PDOStatement->execute 743 0.1184 13729408 0.1184 13729408
array_merge 4051 0.1282 3894816 0.1282 3894816
Illuminate\Database\Eloquent\Model->newInstance 1534 0.4715 3806344 0.0791 3732712
PDOStatement->fetchAll 742 0.0323 2364264 0.0323 2364264
Illuminate\Database\Eloquent\Model->newBaseQueryBuilder 738 0.6625 2177352 0.0657 1688968
explode 3396 0.1026 1296960 0.1026 1296960
Illuminate\Database\Eloquent\Model->newFromBuilder 1534 0.6883 5139552 0.0944 1259576
str_replace 10254 0.3176 1228824 0.3176 1228824
compact 920 0.0339 1181384 0.0339 1181384
PDO->prepare 743 0.1403 816488 0.1403 816488
sprintf 2381 0.0741 802968 0.0741 802968
implode 5586 0.1722 536688 0.1722 536688
array_map 864 0.3164 588512 0.0386 477088
get_class_methods 15 0.0059 472296 0.0059 472296
Illuminate\Database\Eloquent\Model->newQuery 738 0.9783 3044352 0.0656 448488
include 263 6.7525 5732672 0.0468 410416
call_user_func_array 1585 0.5734 3937936 0.0659 357056
SplFileInfo->getPathname 2724 0.0847 344768 0.0847 344768
Turns out that DB::disableQueryLog();fixed it after all. !!
At first I thought it didn't help, because memory kept adding up, and I manually cancelled my script each time. Now while debugging with Memtrack I kept my command running and i noticed after a while the memory usage stagnates.
I'm guessing that the garbage collector doesn't clean up the memory until it decides its necesary?
What is your servers memory_limit?
One solution could be that you split up your command in smaller commands, and run them accordingly. Maybe automate that a new command is run after one is completed?
I would also suggest using some sort of queue provider. This way you could split up the workload to a longer period of time. Additionally the workload is not distributed on your server at all.
Laravel has built in support for: Pheanstalk, Amazon SQS and IronMQ.
Heres the doc link: Laravel queue docs

Resources