Using Eloquent ORM from Laravel 4 outside of Laravel - laravel

I created a folder 'eloquent' to start testing/learning the component, and my composer.json file is:
{
"require": {
"php": ">=5.3.0",
"illuminate/database": "4.0.*"
}
}
Below is my test.php file, with credentials removed. It works great, until I add ->remember(10) into the command. I'd like to look into adding the Illuminate Cache next then, if that's what's needed to start using ->remember(). Is anyone aware of any blog posts or tutorials on doing something like this?
<?php
/**
* Testing Laravel's Eloquent ORM
* #see https://github.com/illuminate/database
* #see http://laravel.com/docs/database
*/
require 'vendor/autoload.php';
use Illuminate\Database\Capsule\Manager as Capsule;
$capsule = new Capsule;
$capsule->addConnection(array(
'driver' => '',
'host' => '',
'database' => '',
'username' => '',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
));
//$capsule->bootEloquent();
$capsule->setAsGlobal();
$name = Capsule::table('user')->where('id', 123 )->remember(10)->get();
var_dump( $name );
// PHP Fatal error: Uncaught exception 'ReflectionException' with message 'Class cache does not exist'
I'm not sure what the next step is to get ->remember() working. I tried adding illuminate/cache to the composer.json file and updated. I wasn't sure how to use it with Eloquent, outside of Laravel.

saff33r is right, but just to help someone like me that need "file" cache this is how to:
in your composer.json
"illuminate/cache": "4.0.*",
"illuminate/filesystem": "4.0.*",
in your boot file:
use \Illuminate\Database\Capsule\Manager as Capsule;
use \Illuminate\Cache\CacheManager as CacheManager;
use \Illuminate\Filesystem\Filesystem as Filesystem;
...
$container = $capsule->getContainer();
$container['config']['cache.driver'] = 'file';
$container['config']['cache.path'] = __DIR__ . '/uploads/cache/eloquent';
$container['config']['cache.connection'] = null;
$container['files'] = new Filesystem();
$cacheManager = new CacheManager($container);
$capsule->setCacheManager($cacheManager);
$capsule->bootEloquent();

It should already be pulling in "illuminate/cache", look in vendor and you should see it there.
You need to setup the cache manager, then pass that through by calling
$capsule->setCacheManager(CacheManager $cache);
I've not looked under the hood for details on how to do this but hopefully this will be enough details to get you going forward.
Edit:
Here's what you need to add to get it working:
use Illuminate\Cache\CacheManager as CacheManager;
$container = $capsule->getContainer();
$container->offsetGet('config')->offsetSet('cache.driver', 'array');
$cacheManager = new CacheManager($container);
$capsule->setCacheManager($cacheManager);
Obviously feel free to change the Cache Driver used but keep in mind that changing the Cache Driver will require adding the extra required settings.

Check out https://github.com/Luracast/Laravel-Database it provides full eloquent support outside laravel including artisan migrations and more
4.2 branch contains laravel 4.2.* components
5.2 branch contains laravel 5.2.* components
Disclosure: I'm the author of the above repository

Related

How to send Log event from Laravel to Loggly?

I want to send Monolog logs from my Laravel 5.1 application to Loggly.com online log management service. From all possible environment, including local development.
I have found some outdated libs and complicated ways to do this. So I ended up with very simple solution. Actually, Laravel Monolog Handler already have Loggly Handler out of the box.
Add config info to config/services.php:
'loggly' => array(
'key' => 'ENTER_YOUR_LOGGLY_TOKEN_HERE',
'tag' => 'ProjectName_' .strtolower(env('APP_ENV')),
),
Than add Monolog handler in bootstrap/app.php, before $app is returned:
/*
|--------------------------------------------------------------------------
| Setup Loggly Handler
|--------------------------------------------------------------------------
*/
$app->configureMonologUsing(function($monolog) {
$handler = new \Monolog\Handler\LogglyHandler(config('services.loggly.key'),\Monolog\Logger::DEBUG);
$handler->setTag(config('services.loggly.tag'));
$monolog->pushHandler($handler);
});
Voila! You are getting your Monolog Logs in Loggly dashboard.
UPDATE: (thanks #thitami)
Based on laravel.com/docs/5.6/upgrade
The configureMonologUsing Method
If you were using the configureMonologUsing method to customize the Monolog instance for your application, you should now create a custom Log channel. For more information on how to create custom channels, check out the full logging documentation.
I was able to manage having Laravel's default local log behaviour, and pushing to Loggly in the same time, by tweaking mladen-janjetovic's code a bit. Tested on Laravel 5.3
config/services.php:
'loggly' => [
'key' => 'ENTER_YOUR_LOGGLY_TOKEN_HERE',
'tag' => 'ProjectName_' .strtolower(env('APP_ENV')),
],
bootstrap/app.php:
/*
|--------------------------------------------------------------------------
| Push to Loggly, and save locally.
|--------------------------------------------------------------------------
*/
$app->configureMonologUsing(function($monolog) use ($app) {
$log = $app->make(Illuminate\Log\Writer::class);
$logglyHandler = new \Monolog\Handler\LogglyHandler(config('services.loggly.key'));
$logglyHandler->setTag(config('services.loggly.tag'));
if (config('app.env') == 'production')
{
// Push to Loggly and save local if in production
$log->getMonolog()->pushHandler($logglyHandler);
$log->useFiles(storage_path('/logs/laravel.log'));
}
else
{
// Otherwise, save only locally
$log->useFiles(storage_path('/logs/laravel.log'));
}
});
Alternatively, you may use Monolog-Cascade to do this.
Monolog-Cascade is a Monolog extension that allows you to set up and configure multiple loggers and handlers from a single config file.
Here is a sample config file for Monolog-Cascade using Loggly. This would log to you stdOut and to Loggly:
---
handlers:
console:
class: Monolog\Handler\StreamHandler
level: DEBUG
stream: php://stdout
error_loggly_handler:
class: Monolog\Handler\LogglyHandler
level: ERROR
token: xxxx-xxxx-xxxxxxxx
tags: [cascade, waterfall]
loggers:
my_logger:
handlers: [console, error_loggly_handler]
If you're interested, here is a blog post on Cascade => https://medium.com/orchard-technology/enhancing-monolog-699efff1051d
[Disclaimer]: I am the main contributor of Monolog-Cascade.
Got mine working with little configuration with Laravel 8.
Just use the built-in monolog handler for Loggly.
Edit your app/config/logging.php
use Monolog\Handler\LogglyHandler;
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single', 'loggly'],
'ignore_exceptions' => false,
],
'loggly' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => LogglyHandler::class,
'with' => [
'token' => env('LOGGLY_TOKEN'),
],
],
]
For more advanced logging (for my case I need to set the tag as it was missing in the built-in handler's constructor.
Copy the built-in handler where you can find it within vendor folder
(e.g: vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php) into your app folder of choice (e.g: app/Logging/CustomLogglyHandler.php).
Modify the constructor to set the tags, and you need to change some of the imports as we're on different namespaces.
// app/Logging/CustomLogglyHandler.php
namespace App\Logging;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Handler\MissingExtensionException;
use Monolog\Logger;
use Monolog\Formatter\FormatterInterface;
use Monolog\Formatter\LogglyFormatter;
use function array_key_exists;
use CurlHandle;
use Monolog\Handler\Curl\Util as CurlUtil;
public function __construct(string $token, array|string $tag = [], $level = Logger::DEBUG, bool $bubble = true)
{
if (!extension_loaded('curl')) {
throw new MissingExtensionException('The curl extension is needed to use the LogglyHandler');
}
$this->token = $token;
if (is_array($tag)) {
$this->tag = $tag;
} else {
$this->tag = [$tag];
}
parent::__construct($level, $bubble);
}
// config/logging.php
'loggly' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => CustomLogglyHandler::class,
'with' => [
'token' => env('LOGGLY_TOKEN'),
'tag' => strtolower(env('APP_NAME', 'Laravel')) . '_' . strtolower(env('APP_ENV', 'production'))
],
],
To expand on Hassan's contribution (posting as an answer, as I still don't have enough reputation to post a comment).
If you have a need to use daily logs locally, you could use following code:
$logFile = 'laravel'.'.txt';
$log->useDailyFiles(storage_path().'/logs/'.$logFile);
Of course, logfile name is totally arbitrary. In this example, format will be as such:
laravel-YYYY-MM-DD.txt
Edit:
with an upgrade to 5.4 this line does not work anymore:
$log = $app->make(Illuminate\Log\Writer::class);
As a workaround, you can create Writer instance manually, injecting $monolog available from configureMonologUsing closure:
$log = new Illuminate\Log\Writer($monolog);

Using Laravel Facades outside Laravel

I have a Laravel application which I use as an API to a much larger application built in Joomla. I really love using Laravel and decided to use Eloquent within the Joomla application. I got this working by importing the bootstrap\autoload.php file in the Laravel application and creating a Capsule
require JPATH_ROOT.'/../laravel_app/bootstrap/autoload.php';
$capsule = new Capsule();
$config = new JConfig();
$capsule->addConnection([
'driver' => 'mysql',
'host' => $config->host,
'database' => $config->db,
'username' => $config->user,
'password' => $config->password,
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => $config->dbprefix,
'strict' => false
]);
$capsule->setAsGlobal();
$capsule->bootEloquent();
This works great and I can use Eloquent. It loads the Eloquent models from the app directly.
What I want to know is how I get the rest of the Laravel app working inside my Joomla app, including using Facades.
For example I have the use of Config.get('key') within one of the Eloquent models, works fine when called in Laravel, but throws and error when called in Joomla.
Fatal error: Class 'Config' not found in laravel_app/app/Model.php on line 192
I have looked at laravel_site/public/index.php to see how it initiates the application and so far so good this seems to be a working solution:
require JPATH_ROOT.'/../laravel_site/bootstrap/autoload.php';
$app = require_once JPATH_ROOT.'/../laravel_site/bootstrap/app.php';
$kernel = $app->make('Illuminate\Contracts\Http\Kernel');
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
//$response->send();
//$kernel->terminate($request, $response);
Facades now appear to be working fine. I've purposely left out $response->send(); and $kernel->terminate($request, $response); so that the routing does not take place and override Joomla's own routing.
I also no longer need to instantiate the Capsule as Laravel is doing that for me now.
I haven't tested this fully so I do not know how robust it is or what features will work but all is good so far.

Symfony2 like database creation command in laravel console?

I have used symfony2 console to create database. If I want to create a database named "symfony" I usually mentioned that name in parameters.yml file and run the below command in console
php app/console doctrine:database:create
But when came to laravel, I don't find similar command to create database in laravel. Can anyone help me to find out those command to create database directly from Laravel Console.
You can do that but you will have to create your own command.
First, run php artisan command:make CreateDatabase --command=database:create to generate app/commands/CreateDatabase.php
Then open that file and change it to this: (I left out all comments, but you can obviously keep them in there)
class CreateDatabase extends Command {
protected $name = 'database:create';
protected $description = 'Command description.';
public function fire()
{
DB::statement('CREATE DATABASE '.$this->argument('name'));
}
protected function getArguments()
{
return array(
array('name', InputArgument::REQUIRED, 'Database name'),
);
}
}
Now you only have to register the command in app/start/artisan.php:
Artisan::add(new CreateDatabase);
and you're good to go.
That's how you call it:
php artisan database:create your-desired-database-name
Alternative: artisan tinker
You can always use php artisan tinker to run PHP code (with Laravel bootstrapped):
php artisan tinker
> DB::statement('CREATE DATABASE your-desired-database-name');
As far as I know, you can use php artisan migrate to make migrations including creating tables from Laravel Console. However, you need to create and modify migration files first, where you can create or drop tables.
So if you want to create a table directly from Laravel Console using something like php artisan create database table ***, it is not possible.
I think you can not create database through command so go to app/config/database.php and set your database configuration. details here
'mysql' => array(
'read' => array(
'host' => '192.168.1.1',
),
'write' => array(
'host' => '196.168.1.2'
),
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
after setting you can create table through command
php artisan migrate:make create_user_table --table=users
it will generate a file to app/database/migrations name create_users_table. . . . . then you create your table following this link
and finally run this command php artisan migrate

Using require-dev with composer and laravel

I was using require-dev for my development tools dependencies. Like the laravel debugbar, the barryvdh ide-helper, etc...
When i get to my production server and run "composer update --no-dev --no-scripts" everything seems to be OK.
Then, you realize that you must remove your "dev providers" from the app.php array.
So whats the point of using require-dev? there isnt a "providers-dev" array?
UPDATE:
I was that i get it fixed but it's not working.
I create the file app/config/local/app.php with this:
<?php
return array(
'providers' => append_config(array(
'Barryvdh\Debugbar\ServiceProvider',
'Way\Generators\GeneratorsServiceProvider',
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
'Barryvdh\Debugbar\ServiceProvider',
))
);
and on the top of app/start/global.php
$env = $app->detectEnvironment(function(){
$hosts = array(
'localhost' => 'local',
'127.0.0.1' => 'local',
);
if(isset($hosts[$_SERVER['SERVER_NAME']])){
return $hosts[$_SERVER['SERVER_NAME']];
}
});
I tried echoing the $env variable and it returns 'local' so it's working. When i open my site i can't see the debugbar but everything else is working.
Any tip?
Just add your dev providers to app/config/local/app.php and use append_config:
'providers' => append_config(array(
'Barryvdh\Debugbar\ServiceProvider',
))

DB:seed file for Laravel 4 working fine on local host, not working on Mediatemple gridserver?

I have a Laravel 4 db:seed file that I am trying to use on mediatemple gridserver. I was able to run a migration with artisan fine (php artisan migrate), and make the tables, but I am not able to seed the tables. This database seeding worked fine on local host. It is only now on a live server that I am experiencing any issues with it. Here is the seed file:
ArtistsTableSeeder.php:
class ArtistsTableSeeder extends Seeder {
public function run()
{
// Uncomment the below to wipe the table clean before populating
// DB::table('artists')->delete();
$artists = array(
);
$Artists = [
['stage_name' => 'Blah', 'city' => 'Blah', 'state' => 'blah', 'video_path' => 'youtube.com', 'image_path' => 'filepickerimage', 'soundcloud_profile' => 'https://soundcloud.com/', 'description' => '', 'created_at' => new DateTime, 'updated_at' => new DateTime]
];
// Uncomment the below to run the seeder
DB::table('artists')->insert($Artists);
}
}
It is spitting out this error:
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"syntax error, unexpected '['","file":"\/nfs\/c09\/h04\/mnt\/139243\/domains\/crowdsets.com\/html\/app\/database\/seeds\/ArtistsTableSeeder.php","linemichaelsutyak.com#n26:/home/139243/domains/crowdsets.com/html$ php artisan db:seed
It is complaining about the line that starts the array:
$Artists = [
I have no idea why this is happening. A little help would be appreciated. Thank you!
That syntax error you get is probably caused by a feature that has been added in PHP 5.4 (short array syntax), so I'd guess your hoster still runs 5.3.x.
You should check the PHP version on the mediatemple grid server and update it if necessary.

Resources