View is not exported to file when using Laravel Scheduler - php

I have php file template that I need to fill with some data and export as "rendered_view.php". It need to be done automatically every day. So I'm trying to use the Laravel Scheduler.
So I have:
View "view_to_render.blade.php"
<?
$someVariable = "{{$variable}}";
require_once("includes/php_file.php");
?>
Controller "MiscController.php"
public function testRenderView(){
file_put_contents(public_path('rendered_view.php'), view('view_to_render', ['variable' => '123456'])->render());
}
Route
Route::get('testRenderView', 'MiscController#testRenderView');
Console/Kernel.php
$schedule->call(function() {
(new MiscController())->testRenderView();
})->daily()->at('13:00');
Scenario 1: If I navigate to 127.0.0.1:8000/testRenderView, it's working and file rendered_view.php is saved in public folder with expected content:
<?
$someVariable = "123456";
require_once("includes/php_file.php");
?>
Scenario 2: If It's executed by scheduler (at 13:00), it returns error:
local.ERROR: Illuminate\View\Engines\PhpEngine::main(): Failed opening
required 'includes/php_file.php' (include_path='.:')
{"exception":"[object]
(Symfony\Component\Debug\Exception\FatalErrorException(code: 64):
Illuminate\View\Engines\PhpEngine::main(): Failed opening required
'includes/php_file.php' (include_path='.:')
Looks like when it's executed from Scheduler, Laravel tries to render the view as real view.
I also tried to create artisan commands, but the behaviour is the same. Works fine when I execute the command on console, but doesn't when I call the command from Scheduler. Any idea why it's happening?

Instead of creating a new controller like (new MiscController())->testRenderView();, just do your logic here and replace it with file_put_contents(resource_path('myfile.php'), view('myview')->render()).
Ive just tested it and it works.
You shouldnt try to create controllers in the scheduler just like you did, because they ideally need some sort of request. You are better off with just creating a new class with some functions.

Related

Laravel small standalone one-off script without artisan command?

I need to check something small in Laravel, so I just want to make a small script to check it.
I know that I can do it with
php artisan make:console ...
But It will add a file to the App/Console/Command, and I will need to update app/Console/Kernel.php. It means that I will have do commit it to source control, which is really not needed.
Is there a way to have a standalone laravel script which will give me access to the Laravel Components?
I am using Laravel 5.2, (make:command doesn't exists, only make:console)
Just an example for what I tried:
<?php
use App\User;
use DB;
require __DIR__.'/../vendor/autoload.php';
require __DIR__.'/..//bootstrap/app.php';
echo "hello world\n";
$res=User::where('id',5)->first();
echo "end!\n";
?>
But I am getting an error:
PHP Fatal error: Uncaught Error: Call to a member function connection() on null in /var/www/html/dpriceit/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:3314
Stack trace:
#0 /var/www/html/dpriceit/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(3280): Illuminate\Database\Eloquent\Model::resolveConnection(NULL)
#1 /var/www/html/dpriceit/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1880): Illuminate\Database\Eloquent\Model->getConnection()
#2 /var/www/html/dpriceit/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1853): Illuminate\Database\Eloquent\Model->newBaseQueryBuilder()
#3 /var/www/html/dpriceit/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1823): Illuminate\Database\Eloquent\Model->newQueryWithoutScopes()
#4 /var/www/html/dpriceit/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(3524): Illuminate\Database\Eloquent\Model->newQuery()
UPDATE
I tried creating a console command
php artisan make:console MyTempTest
But when I do php artisan list I don't see its signature in the list of available commands.
To fix the error you're getting, boot up the application's kernel and handle the response like so
app\script.php
<?php
use App\User;
require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
echo "hello world\n";
$res = User::find(5)->name;
var_dump($res);
echo "end!\n";
Then from a terminal, run php app/script.php
Result:
~/Sites/laravel (master ✗) ✹ ★ ᐅ php app/script.php
hello world
string(11) "Khalid Bins"
end!
When I want to try/test something in Laravel, I usually do one of three things:
If the "something" I want to try is a simple one-liner I use Tinker: artisan tinker. This gives you the fully booted Laravel Framework, ready to use any class or function you want. This is usually my go-to when I want to: Test a global helper function I just created; Create a model using a factory, to check if my factory is setup correctly; Check if my $casts array on a model is setup the right way;
Another scenario might involve a bit more code, maybe a few lines to retrieve some data from the database, mutate it and show it on a page. For this you can simply create a closure based route in the file routes/web.php:
Route::get('test-url', function () {
$user = User::where('email', 'user#example.com')->first();
$user->makeAdmin()->save();
// I can see on the page if the attributes have been changed, as a result of the makeAdmin() call.
return $user->getAttributes();
});
The same is possible for console routes. Add a structure like this in your routes/console.php file:
Artisan::command('test:functionality', function () {
$instance = new BusinessLogic();
$result = $instance->someVeryInterestingMethod();
dump($result);
});
You can then call this function from the command line with php artisan test:functionality. You can, of course, call the command whatever you like.
Then the last scenario; when I want to try something new (like a new package, library, plugin) and it will be more than a few lines of code. I create a new test class with php artisan make:test ThrowawayTest (or another randomly chosen name). I can then add a few lines of code and run it with PHPUnit. I have set my editor to launch the test that my cursor is on with the key-combination CTRL-T so that I can re-run it quickly when some code changed.
This means I can let some code stay in its function, and write a new function to elaborate on the things I just learned about the new package. When I am finished I can either leave the code and commit it to the repository, so that I can check the code later on when I need to use some of it again for production code. I can also throw away the test file if it seems like I won't need the code for reference in the future.
This last solution also gives me the added benefit of being able to use assert statements from PHPUnit.
Hope this gives you some insight on the different possibilities with the Laravel Framework when it comes to trying or testing out new stuff.

Laravel 5.6 - How to run job or event with parameters from command line?

I have an App\Jobs\BanUser job which accepts a parameter id to block a bad user by passing their id. That works perfectly if called from a controller like this:
dispatch(new BanUser($id));
But when I try to do that from the tinker command line with the full namespace like this:
dispatch(new App\Jobs\BanUser('1'));
I get this error:
PHP Fatal error: Class 'App/Jobs/BanUser' not found in Psy Shell code
on line 1
Any idea how to accomplish this job with the passed id parameter from the command line?
NOTE: If the solution requires starting up a queue from command line just for this job, maybe it's best to set it as an event? I don't want it to queue, just want to be able to run it in real time by passing parameter and executing the BanUser respective code from command line for either job or event.
Make sure you have correct namespace App\Jobs in your BanUser class.
Also check BanUser class file is placed in right directory.
try
app('Illuminate\Bus\Dispatcher')->dispatch(new App\Jobs\BanUser('1'));
I am not sure if it will work but, you can give it a try.

How laravel classes are included?

I want to run custom php code in laravel directly without using any routes or http requests..
I hope I can make it clear, I mean, like those online tools that runs php code by writing php code in browser, and then run it, and view result..
I found this handy project (Run-PHP-Code) to run PHP in browser directly, but I can't use models of my laravel project in PHP code..
How can I include laravel 's environment, so that I can for example:
$tag= new Tag;
where Tag is a model in laravel project, that would result into:
Fatal error: Class 'Tag' not found in D:\xampp\htdocs\widgetsRepository\app\controllers\Run-PHP-Code-master\index.php(49) : eval()'d code on line 3
Any idea? this would be very useful!
EDIT
I tried Brian suggestion at his answer, but I got this error now:
Call to a member function connection() on null
at vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php
public static function resolveConnection($connection = null)
{
return static::$resolver->connection($connection);
}
so, I think I only need to get database sorted, then I can do experiments easily..
I've never tried to run code from a laravel project directly, I just copy and paste parts of the code into Run PHP Code.
That being said, it should be possible to run the code using the method taken from this StackOverflow question:
The Composer autoload script, to autoload all of your classes:
require __DIR__.'/../bootstrap/autoload.php';
And if you need things from the IoC container, you'll:
$app = require_once __DIR__.'/../bootstrap/start.php';
Then you will be able to do things like:
$post = Post::find(1);

Writing a cron job using CodeIgniter CLI?

Hi I am facing some problems in writing a cron job using CI CLI way. My application has a controller name called manager.php in that there is method called check_status where I am gonna get all the order_ids using one model function. Ever order_id row had a status filed in database which either success or failure.
I have an api if i pass order_id to that it will tell whether order is successfully delivered or not. But here comes the problem I have below line in controller in the top.
<?php if(! defined('BASEPATH') ) exit("NO Direct Script Access Allowed"); ?>
So when i try to run method check_status from CLI in CI it gives me an error stating NO Direct Script Access Allowed.
This is the way i called above method php application/controllers/manager.php check_status
So i decided like this i created an another class file called cron_job.php in that i didn't keep the above error line "No Direct Script Access Allowed". I thought it will give access now when i try to run but it doesn't give an error and even output also.
This is the class which i created and method in that.
<?php
class Cron_job extends CI_Controller {
public function message($to = 'World')
{
echo "Hello {$to}!".PHP_EOL;
}
}
?>
I run this controller form CLI like this php application/controller/cron_job.php message
Note: I am in ROOT directory.
No Output at all. So i tried in another way like this php index.php application/controller/cron_job.php message
Now it gives me error stating that Error 404 page not found.
What i tried in another way now i created a file in views folder and in that i am calling old controller/method url like below.
$result = file_get_contents("http://application_path/controller/method");
echo $result;
Now i am getting output which i defined in the method check_status in manager.php controller.
But here comes another problem now after the above line i will get an array output which had all the order_ids.
I am gonna send this each id to a api to check status. If it is failure it will check whether it is delivered or not. If it's done i need to update that status in the database against that order_id. But now i am in view file, is it possible to call a model file from the view file or is there any way to do this.
Any help?
Note: There is no syntax errors in any controller or any method , which are fully verified and working normally when i am accessing using urls.
You need to read the CodeIgniter help section on Running via the Command Line. It's very easy. Your original approach was correct. But you do not call your controller method directly by its path, instead CD to your project root and then the call the index.php file with the controller and method as parameters.
// This is how you call CI via the command line.
// Use spaces between index.php and your arguments.
$ php index.php <controller> <method> [params]
// And in your instance
$ php index.php manager check_status [param1 param2 param3]
Depending on your host you may need to call the PHP version compiled for CLI.
the ci helper will help you in this.
1 ) Create a helper & create a function in it, that calls your model function
function getUserDetails($userId = '') {
$CI = & get_instance();
$getUserDetailsByUserId = $CI->user_model->getUserDetailsByUserId($userId);
return $getUserDetailsByUserId;
}
2) Now you can call getUserDetails($userId); in your view.

cron job: CodeIgniter2+Doctrine2 How do I get this to work?

I am attempting to use cron to run a PHP file that executes a series of actions. I've done this before with simple procedural PHP, the trick then was doing the cron like this:
/usr/local/php5/bin/php /home/me/fullpath/turnrun.php
and having this at the very top of the PHP file I wanted executed.
#!/usr/local/bin/php -q
I'm using CodeIgniter 2 and Doctrine 2, so I have controllers and classes and all kinds of fancy stuff now, and I can't figure out how to make this work.
When I attempt to run a 'backend_test_turn.php' file I get an error
Parse error: syntax error, unexpected T_STRING in
/home/me/fullpath/application/controllers/backend_test_turn.php
on line 59
This file includes
class Backend_test_turn extends CI_Controller {
// code
$logmsg = new ORM\Dynasties2\Systemlog; // <--- this is line 59
// code
}
Note that when I run this normally (in a browser), the code works fine and does not throw an error.
What am I doing wrong?
You can run the controller code directly from command line like this:
php index.php Backend_test_turn/action/data
OR
php index.php Backend_test_turn action data
You can find more help here.
you can try
$logmsg = new ORM\Dynasties2\Systemlog;
$logmsg = new ORM\Dynasties2\Systemlog(); // <- see difference
Did you try to use CURL instead?
I have an application CI & Doctrine with CRON jobs and I've got many errors like yours while trying to launch controllers via CLI.
Personnaly now I use CURL instead of CI CLI and it works like a charm.

Categories