CakePHP - Setup database with a form - php

I would like to setup the database in CakePHP providing host, login and password with a form (so without writing the database.php file myself). The purpose is some kind of automatic setup of CakePHP (I would use this to provide salt and cypherSeed too).
Is this possible? What's the best way to do go? I read something about writing file via PHP...

If you create/load your database connection from your controller you can have this data variable. I don't think it's a good idea to write database.php file with a form.
So I would do something like this:
//Controller
$this->Formdatabase = ClassRegistry::init('Formdatabase');
$db_host = '';//load from file or DB
$db_user = '';//load from file or DB
$db_pass = '';//load from file or DB
$db_database = '';//load from file or DB
ConnectionManager::create("form_database", array(
'datasource' => 'Database/Mysql',
'driver' => 'mysql',
'persistent' => false,
'host' => $db_host,
'login' => $db_user,
'password' => $db_pass,
'database' => $db_database,
'prefix' => '',
'encoding' => 'UTF8',
'port' => '',
));
$this->Formdatabase->useTable = ''; //table you want to use. (in Model or controller)
//Model
<?php
class Formdatabase extends Model {
public $useDbConfig = 'form_database';
}
?>
//Now you can use $this->Formdatabase->find('...'); ...
Hope I could help, good luck!

Related

Be able to change database connection in runtime with Laravel

So I am making a web application which should be able to upload any SQL statement to any server listed in the database on a schedule. It should connect to the database, execute the statement and make a report based on the information received. Then it can disconnect.
Currently, I have a job in place and it grabs all the information required from the database eg. host, port, DBName etc. I just need to form a connection and then execute the statement.
I am using the Laravel framework.
Edit: I cant modify any database configs as the database information is stored in a table, not a config file.
Thanks
You can set it at runtime this way:
$connKey = 'CustomConnection';
$dbInfo = DatabaseInfo::find($databaseId);
Config::set('database.connections.' . $connKey, array(
'driver' => 'mysql',
'host' => $dbInfo->hostName,
'database' => $dbInfo->database,
'username' => $dbInfo->username,
'password' => $dbInfo->password,
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => '',
));
// Now you can set the new connection to the models
$myModel = new MyModel;
$myModel->setConnection($connKey);
// Or you can use it this way too:
$users = DB::connection($connKey)->select(...);
// Or, also:
$pdo = DB::connection($connKey)->getPdo();
I solved this in a very similar way to one posted :
$connectionName = Crypt::encryptString(str_random(80));
DB::purge("$connectionName");
Config::set("database.connections.$connectionName", [
"driver" => "$Driver",
"port" => "$Port",
"host" => "$Host",
"database" => "$DBName",
"username" => "$UserName",
"password" => "$Password"
]);
$query = DB::connection("$connectionName")->select($statement);
$query= json_decode( json_encode($query), true);
Excel::create("$filename-$mytime", function($excel) use ($query, $filename) {
$excel->sheet("$filename", function($sheet) use ($query){
$sheet->fromArray($query);
});
})->store('xls', storage_path('excel/exports'));
This creates a new connection with a random name (so when in a queue if multiple are executed they wont purge the same database), assigns the details to it, executes the select statement which is defined in the variable $statement. Then creates an excel spreadsheet from that.

Defining configuration values under specific namespaces?

I'm writing a framework, and have just added namespaces. I've had no trouble converting everything, save for configuration values.
I can define constants easily, so single values are not a problem...but what about an array of values?
Take this array, for instance, which is the configuration array to add a connection to Capsule...
[
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'DB_NAME',
'username' => 'USERNAME',
'password' => 'PASSWORD',
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => ''
]
I have been using a file that looks like this for database configuration...
<?php
namespace BareBones;
use Illuminate\Database\Capsule\Manager as Capsule;
$BareBonesCapsule = new Capsule;
$BareBonesCapsule->addConnection([
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'DB_NAME',
'username' => 'USERNAME',
'password' => 'PASSWORD',
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => ''
]);
$BareBonesCapsule->setAsGlobal();
$BareBonesCapsule->bootEloquent();
use Illuminate\Database\Schema\Blueprint as Blueprint;
use Illuminate\Database\Eloquent\Model as Eloquent;
I'm going to start booting Eloquent from my main App class. This will prevent a global variable from doing it. While it is unlikely that $BareBonesCapsule is going to be used, I would still like to keep my framework clean and keep everything in it's namespace.
I could declare a bunch of constants in the configurations file...
<?php
namesapce BareBones;
define("driver", "mysql");
define("host", "localhost");
define("database", "DB_NAME");
/* etc... */
This doesn't seem very clean, and I'm assuming there is a better way to do this. How do other frameworks handle this issue, and what alternative means of configuration do I have while maintaining a separation from the global namespace?
You can use .ini files and break them into sections like so:
; This is a sample configuration file
; Comments start with ';', as in php.ini
[first_section]
one = 1
five = 5
animal = BIRD
[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
[third_section]
phpversion[] = "5.0"
phpversion[] = "5.1"
phpversion[] = "5.2"
phpversion[] = "5.3"
urls[svn] = "http://svn.php.net"
urls[git] = "http://git.php.net"
From: http://php.net/manual/en/function.parse-ini-file.php
Symfony supports XML, PHP and YML and allows you to write your own config decoder.

Using different databases based on user request

I've installed Laravel-4 and jenssegers / Laravel-MongoDB which has the same interface to Eloquent model as Laravel, so everything is pretty transparent and 1 database connection works OK.
what I'm trying to do, is switch to another database based on user request (Consider it as API that decided where to go and grab data).
This is what I did:
App::before(function($request)
{
$dbPrefix = $request->segment(1);
if (!is_null($dbPrefix)) {
$dbName = strtolower($dbPrefix);
$newDb = DB::connection('mongodb_'.$dbName);
}
});
From here.. I don't know what to do.. Is it connected to new database that way? how do I tell my Laravel to use $newDb when I refer to DB constant in Models?
But I want it to happen before application starts, so specifying "$connection" variable in model or using explicit call to other database like DB::connection('mongodb2')->query(...) is no good for me.
Thanks
The solution to this would be:
/app/filters.php:
App::before(function($request)
{
$dbPrefix = $request->segment(1);
if (!is_null($dbPrefix)) {
$connectionName = 'mongodb_'.strtolower($dbPrefix);
Config::set('database.default', $connectionName);
}
});
/config/database.php:
'mongodb_soccer' => array(
'driver' => 'mongodb',
'host' => 'localhost',
'port' => 27017,
'username' => 'user',
'password' => 'password',
'database' => 'SoccerData'
),
'mongodb_tennis' => array(
'driver' => 'mongodb',
'host' => 'localhost',
'port' => 27017,
'username' => 'user',
'password' => 'password',
'database' => 'TennisData'
)
Requests:
site.com/soccer
will get connection mongodb_soccer
site.com/tennis
will get connection mongodb_tennis
You can pre-authorize it in default "admin" database where your users are stored, and then switch to any database connection per user request to get the actual data.
I needed it this way for API development.
Good luck

Cake php Datasource class MySQL could not be found

I have ubuntu 10.04 on server.
I am trying to set up the cake php project but it gives me following error
Cake is NOT able to connect to the database.
Datasource class MySQL could not be found.
I have searched lot on the web regarding it.
my config file looks like this
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/MySQL',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'mypassword',
'database' => 'dbname',
'prefix' => '',
//'encoding' => 'utf8',
);
}
I checked that server has all the things set up to connect as PDO I have run following script and it works fine.
$conn = new PDO('mysql:host=localhost;dbname=dbname', $username, $password);
Then further I have changed in Mysql.php file of cake php which is in the "lib\Cake\Model\Datasource\Database"
I tried to give static connection in Mysql.php but this also doesn't work. I did exit in the Mysql.php and seems like control of page is not getting here.
$this->_connection = new PDO('mysql:host=localhost;dbname=dbname', $username, $password);
$this->connected = true;
Please do let me know if I am missing anything.
Thanks in Advance.
Casing matters, it should be:
'datasource' => 'Database/Mysql'
And not:
'datasource' => 'Database/MySQL'
Mysql is not a supported source try 'datasource' => 'Database/Sqlite',

install kohana website on multiple servers

I have a Kohana 3.0.14 website that i want to put on multiple domains, having associated a virtual host each (different ips).
the difference between my websites is the configuration file and the boostrap file (where i set the language to be used).
All the sites are in production.
How can i 'breakup' the website, how can i include the files so that i would have all the kohana site in a single place, and the config and boostrap on every server, so that when i am fixing an error to be fixed on every site (every domain)?
thanks a lot!
You could do that by setting up an environment variable at the top of you index.php file. Then depending on this variable, you'll set the configuration variables, languages, etc. This is usually how I handle staging/live/local environments, and doing so allows you to keep all the code identical between the various installations.
For example, in index.php:
define("ENV", "staging")
Then in bootstrap.php:
$baseUrl = "http://defaultdomain.com/";
if (ENV == "staging") $baseUrl = "http://staging.somedomain.com/";
Kohana::init(array(
'base_url' => $baseUrl,
));
In database.php:
if (ENV == "live") {
$hostname = ...
$database = ...
$username = ...
$password = ...
} else if (ENV == "staging") {
$hostname = ...
$database = ...
$username = ...
$password = ...
}
return array
(
'default' => array
(
'type' => 'mysql',
'connection' => array(
'hostname' => $hostname,
'database' => $database,
'username' => $username,
'password' => $password,
'persistent' => FALSE,
),
'table_prefix' => '',
'charset' => 'utf8',
'caching' => FALSE,
'profiling' => TRUE,
)
If your hosting options are limited, your best bet is to choose the first primary domain and create an account using that. Then park more domains on top. Then simply get the URL to decide what language etc you want to use.

Categories