When creating a composer package that is meant to be run in the Laravel 4 framework, I want to create a default database connection set that looks something like this:
// File Location: LARAVEL4_ROOT/vendor/my/package/src/config/database.php
return array(
'connections' => array(
'reporting' => array(
'driver' => 'mysql',
'host' => getenv('REPORTING_HOST'),
'database' => getenv('REPORTING_DBNAME'),
'username' => getenv('REPORTING_USER'),
'password' => getenv('REPORTING_PASS'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
),
);
According to all the documentation I can find online, once I have registered my project using the Service Provider pattern and call $this->package('my/package'); Laravel 4 is supposed to magically load this file and give me access to it in the configuration.
And I have verified that I can call
Config::get('package::database.connections.reporting')
and it returns the array above.
However, when I construct my Eloquent Model file, and try to set the connection using
protected $connection = 'package::database.connections.reporting';
It doesn't work. I get an exception saying:
InvalidArgumentException: Database [package::database.connections.reporting] not configured.
Is there some magic string format I need to use to get the Connection Resolver to connect to my database using the default config in my package?
Thanks for your help!
Okay, I found a solution:
It appears that the connection handling in Laravel 4 as of this writing is not consistent with the the syntax that the Config facade uses. Therefore using:
protected $connection = 'package::database.connections.reporting';
... will not work because the DatabaseManager class ONLY searches the configuration loaded from laravelroot/app/config/database.php
So, at the time of this writing, the only way to establish a connection defined in my package configuration is to modify the previously loaded configuration array in my package service provider, like so:
public function boot()
{
$this->package('vendor/package');
include __DIR__."/routes.php";
// Add my database configurations to the default set of configurations
$this->app['config']['database.connections'] = array_merge(
$this->app['config']['database.connections']
,Config::get('reporting::database.connections')
);
}
This could easily be handled by the framework by modifying the DatabaseManager class to look at the provided connection name and resolve the configuration details in the same way as the Config facade does. But that is not implemented at the time of this writing.
I have forked the framework and submitted a pull request with a potential fix. We'll see how that goes. For now, you can use the above work around in your package service provider, and then just set the name of your connection in your model like this:
protected $connection = 'reporting';
Since the array of connections defined in my package config have been merged with the default connections defined in laravelroot/app/config/database.php, it's as if the connection was actually created there in the app config, so there is no need for package resolution in the connection name inside your model.
Hopefully, this will be automated in future releases of laravel 4, or a more intuitive way of loading package database config files in the package service provider will be implemented.
Related
I recently added laravel/nexmo-notification-channel to my laravel project which also installed Nexmo/nexmo-laravel.
After installing, I published vendor files so that I get config/nexmo.php and in there I noted that it looks in the .env file for NEXMO_KEY and NEXMO_SECRET.
So I went ahead and created these within my .env file
NEXMO_KEY=[my_key]
NEXMO_SECRET=[my secret]
NEXMO_SIGNATURE_SECRET=[my signature secret]
After this, I added Nexmo to my service providers in app.php:
'providers' => [
...,
Nexmo\Laravel\NexmoServiceProvider::class
]
and also added the following in config/services.php:
'nexmo' => [
'key' => env('NEXMO_KEY', ''),
'secret' => env('NEXMO_SECRET', ''),
'sms_from' => '[my number]'
],
But I still get the following error when thrying to send an SMS using the use Illuminate\Notifications\Messages\NexmoMessage; class:
"message": "Provide either nexmo.api_secret or nexmo.signature_secret",
I can use these same credentials to send an SMS from CLI, so why can't I send it from laravel?
There have been a couple of workarounds for this that are valid, but at first glance it looks like the Nexmo package does the work to bring in the ENV secrets into Laravel's config. Because of caching problems, you should never call env() within Laravel, instead you should be using config() - so in this case, config(nexmo.api_secret).
My main point here though is that I can't look into the "correct" solution for you because the package is abandoned. Nexmo is no longer Nexmo, it's Vonage, and Laravel core team have subsequently updated the notification-channel package.
For supported use to integrate Vonage services (SMS), please use the following package:
https://github.com/laravel/vonage-notification-channel
I'm not sure exactly why, but, Vonage/Nexmo doesn't pick details from the .ENV.
Instead, use a global constant to fetch the secrets:
Create a global.php file in the config folder, and add your secrets from the env like this:
<?php
return [
// Other constants values
'SMS_API_KEY' => env('SMS_API_KEY', ''),
'SMS_API_SECRET' => env('SMS_API_SECRET', ''),
]
?>
Then, you can use the constants in your controller as usual:
'key' => config('global.SMS_API_KEY'),
'secret' => config('global.SMS_API_SECRET')
then: recache, php artisan config:cache
I am trying to configure cakephp ver 2.6.0 to use redis engine by default. but somehow i am not able to make it work. any help will be highly appreciated.
Things Which i have tried so far..
Configured app/config folder 2 files , core.php and bootstrap.php. , according to the guidelines provided here in this blog configure cake with redis and this blog too Another cake-redis config setup
but i keep on getting errors like.
Fatal error: Uncaught exception 'CacheException' with message 'Cache engine session is not properly configured.' in C:\wamp\www\project\cakephp\cakephp_2.6.0\lib\Cake\Cache\Cache.php on line 181
CacheException: Cache engine session is not properly configured. in C:\wamp\www\project\cakephp\cakephp_2.6.0\lib\Cake\Cache\Cache.php on line 181
Any help will be highly appreciated.
I was having the same exact issue today while trying to setup CakePHP to use Redis as the cache engine.
Coincidentally, I also read the same setup instructions from the two blogs you linked to.
The reason was that I had copied pasted the Configure::write(...) code block from the Another cake-redis config setup blog post as it is and pasted it into the file without first commenting out the Configure::write(...) code block that was already in the core.php file.
I'm assuming that you have already successfully setup Redis on Windows and have installed the PHPRedis extension without any issues.
I am using the instructions from Another cake-redis config setup here.
In your app/Config/core.php file, comment out the following block: (this was starting at line 218 in my core.php)
Configure::write('Session', array(
'defaults' => 'php'
));
Instead, you can put this in: (You can change the values to suit your particular needs)
Configure::write('Session', array(
'defaults' => 'cache',
'timeout' => 100,
'start' => true,
'checkAgent' => false,
'handler' => array(
'config' => 'session'
)
));
After this, change the value of $engine to 'Redis', so it becomes:
$engine = 'Redis';
And then, put this code in, I put this in at the very end of the file: (Again, your values can be different depending on what your setup is)
Cache::config ('session', array (
'Engine' => $engine,
'Prefix' => $prefix . 'cake_session_',
'Duration' => $duration
));
And that's it. You're done! No need to change anything else.
To make sure that Redis is working properly with CakePHP, I ran the RedisEngine Test Suite that comes with CakePHP. You need to have PHPUnit installed for this to work.
It can be accessed via http://your-cakephp-project/test.php
Click on 'Tests' under Core and then click on 'Cache/Engine/RedisEngine'
If everything is working successfully, you should see all the tests pass.
Alternatively, you can use redis-cli at the command prompt to confirm that Redis is storing keys properly.
Once you have logged in by typing redis-cli, type KEYS *
This should give you a list of keys related to your CakePHP setup.
An example would be the "myapp_cake_core_object_map" key.
Hope this helps.
This is what I did:
I downloaded the yii2 advanced template.
Ran php init.
Configured each of main-local.php files in
environments/dev/common/config
environments/prod/common/config
common/config
I added the following to the 'components'
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'sqlite:/path/to/sqlitedbs/yayr.sq3',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
I configured the apache vhosts as explained in the readme.
Running yii migrate created the sqlite database file in the configured location with no errors.
What breaks is when I go to the frontend app and try to submit the sign up form, it gives me this error:
Exception
Database Exception – yii\db\Exception
SQLSTATE[28000] [1045] Access denied for user 'root'#'localhost' (using password: NO)
↵
Caused by: PDOException
SQLSTATE[28000] [1045] Access denied for user 'root'#'localhost' (using password: NO)
in /home/johnsmith/dev/test/yayr/vendor/yiisoft/yii2/db/Connection.php at line 579
The full stack trace can be seen: http://pastebin.com/KEKH1zbM
I have used my IDE to search for every location that a mysql dsn exists. The only place is in /tests/codeception/config/config.php which should not be called by submitting a form. To double check, I commented out the config, and it didn't help.
I also tried setting 'driverName' => 'sqlite', in the config, but that did not make any difference. Neither did commenting out the username, password, or charset parameters.
None of the functions referenced by the stack trace appear to manually call MySQL. They all look for the configured dsn.
So, why does Yii think it can even try to connect to MySQL? Doesn't ActiveRecord abstract out all the SQL so that it won't matter if I'm using MySQL or sqlite?
How do I get past this issue? Using sqlite would make initial development a lot easier.
Thanks!
Basics of the Yii2 advanced template
You have the environments-folder containing you actual config files
The frontend- and backend-folders hold copies of those "local"-files, depending on which environment you selected, they get copied from dev or prod
Now what does that mean? If you perform changes on ANY file within the envirnments folder, you have to re-init your application. You simply do this by opening a console, navigate to the base folder of your application and call the init-command. You will then be asked which envirnment you want and what files to overwrite.
After that you should see your changes beeing reflected in the frontend- and backend-folder. The idea behind this is to prevent if/else-structures within the config files and have a clean application. By the way: the index.php within the web-folders gets copied the same way. That way you could even customize this...and therefore the way the application gets loaded initially.
Back to your problem
For me it looks like you changed the settings within the environments/.../local-...-configfile, which is right...but then didn't re-init the application. That way the config file within the front- and backend still contain your old settings.
Documantation of the advanced template
Everything is very well documented here:
https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md
After init command
Create a new database and add it in common/config/main-local.php
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=your-db',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
Apply yii migrate in console command!
It'll create the tables for the application to work
I currently have two applications that run on the same server, under separate virtualhosts. The first is a Laravel 4 app and the second is a older PHP project that doesn't use a framework, but follows a rough MVC pattern.
I'd like to find a way to interact with and use some of the models from the Laravel app inside of the older PHP project.
Obviously it's not going to be as simple as just including the model files, as they will have various dependencies, so are there any general approaches or patterns that I should be looking at when trying to do this?
You can add illuminate/database to your composer.json. That way you can use database module of laravel without installing whole framework.
Read the instructions in README.md for code examples and more details.
Can Vural is right, you can just use these components, take a look at http://www.slimframework.com/news/slim-and-laravel-eloquent-orm.
Here are the main extracts:
INSTALLATION
First, prepare the composer.json file so it will pull down and install the Slim Framework and the Eloquent ORM. The composer.json file should look like this:
{
"require": {
"slim/slim": "*",
"illuminate/database": "*"
}
}
When this is done, run composer install to install the application dependencies.
BOOTSTRAP THE ELOQUENT ORM
Next, I tell Composer to autoload the application’s dependencies by requiring Composer’s autoload.php file.
<?php
// Autoload our dependencies with Composer
require '../vendor/autoload.php';
And now I bootstrap the Eloquent ORM and pass it my database connection information (be sure you add your own username, password, and database name).
<?php
// Database information
$settings = array(
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => '',
'username' => '',
'password' => '',
'collation' => 'utf8_general_ci',
'prefix' => ''
);
// Bootstrap Eloquent ORM
$connFactory = new \Illuminate\Database\Connectors\ConnectionFactory();
$conn = $connFactory->make($settings);
$resolver = new \Illuminate\Database\ConnectionResolver();
$resolver->addConnection('default', $conn);
$resolver->setDefaultConnection('default');
\Illuminate\Database\Eloquent\Model::setConnectionResolver($resolver);
Now that the Eloquent ORM is bootstrapped, I can create and use models that extend the Eloquent abstract model. This example assumes your database contains a table named books with columns title and author.
<?php
class Book extends \Illuminate\Database\Eloquent\Model
{
}
Extract taken from the website mentioned above, this is so if it gets removed the information still remains.
To load from a different project, you will most likely have to autoload the models with a custom autoloader. Or include the autoloader from the Laravel framework if you have dependencies within the models.
I have gotten the latest CakePHP (2.1.0) and MongoDB Datasource Plugin both from git, and have followed the configuration settings as best as I can. I have placed the MonogoDB plugin in the plugins directory, and updated both my database.php and bootstrap.php files:
bootstrap.php:
CakePlugin::load('Mongodb');
database.php:
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Mongodb.MongodbSource',
'database' => 'database',
'host' => 'staff.mongohq.com',
'port' => 10070,
'login' => 'user',
'password' => 'secret'
);
}
I'm afraid I'm missing something stupid, but I keep getting the error:
Datasource class MongodbSource could not be found.
Which to me, implies it can find the plugin, but not the datasource class. Anyone seen this before? I've also tried to connect to a locally installed MongoDB, but same error persists.
Use this command to pull the plugin so it pulls the cake2.0 branch instead (which uses the correct cake 2.x directory naming conventions):
git clone -b cake2.0 git://github.com/ichikaway/cakephp-mongodb.git Mongodb
Please make sure that you are using the CakePHP-Mongo plugin for CakePHP 2.0 and not CakePHP 1.3