Accessing data from another database in Joomla 3.2+ - php

I am upgrading my components from Joomla 1.7 to Joomla 3.3 and have to keep the original database. Therefore I need to access the display data from another database as the installation database. I tried a method that I used many times before with Joomla 2.5 but it seems that I cannot get it right this time.
In my model in the getListQuery() method (which overrides the modellist method) I use the following code to access the database from where I want to get my data:
$dbOptions = getDbOptions();
$db = & JDatabase::getInstance($dbOptions);
where the connection details of my old database are contain in $dbOptions.
I continue to use the following code:
$query = $db -> getQuery(true);
$query -> select('*') -> from('table');
return $query;
I do include the following in the beginning:
jimport('joomla.application.component.modellist');
modellist extends JModelLegacy, therefore I do believe that it uses the following:
/libraries/legacy/model/list.php
But it gives me an error that the table newDatabase.table does not exits and therefore the method I am using does not connect to my old database to retrieve the data from oldDatabase.table.
I am unsure about the inclusion of jimport('joomla.application.component.modellist'); though, could be the problem?
Anyone who can help to retrieve the data from my original database?

If old database on same server and active mysql user has access for it you can use such sql query:
$query = $db -> getQuery(true);
$query -> select('*') -> from('old_database.table');
return $query;

If the entire model is just fetching data from the external database you could use JDatabase->setDbo to replace the default database object with your custom one.
public function __construct($config = array())
{
parent::__construct($config);
$options = array();
$options['driver'] = 'mysqli';
$options['host'] = 'localhost';
$options['user'] = 'username';
$options['password'] = 'password';
$options['database'] = 'database';
$options['prefix'] = 'jos_';
$db = JDatabase::getInstance( $options );
parent::setDbo($db);
}
Now you should be able to access the database in getListQuery() just as you would with your default database. E.g.
$db = JFactory::getDbo();

I believe Adam B's code can have some improvement, regarding setting DB.
public function __construct($config = array())
{
$options = array(
'driver' => 'mysqli',
'host' => 'localhost',
'user' => 'username',
'password' => 'password',
'database' => 'database',
'prefix' => 'jos_'
);
//parent construct will handle setting the DB
$config['dbo']=JDatabase::getInstance( $options );
parent::__construct($config);
}
And getting DB: I think JFactory::getDbo(); will give you the wrong DB, you should do:
self:getDbo();

Using Joomla 2.5, this approach worked for me:
$option = array();
$option['driver'] = 'mysql';
$option['host'] = 'localhost';
$option['user'] = 'XXXXXXXX';
$option['password'] = 'XXXXXXXX';
$option['database'] = 'wordpress';
$option['prefix'] = 'jtt_';
$db = JDatabase::getInstance( $option );
$query = "select * from #__categories";
$db->setQuery($query);
I was able to connect to another database just fine.

Related

CakePHP multiple databases connection in foreach loop issue

I am using the Cake for connecting multiple databases in a loop with having same database user config. I just use this method for making different connection on the fly. https://stackoverflow.com/a/6058764/1668476
I just use this in a AppController function and then in all my controller with
Here is the function to connect with database on the fly:
//Used for connecting different databases on the fly
function dbConnect($database, $dataSource = 'default', $prefix = 'mycake_') {
ClassRegistry::init('ConnectionManager');
$database = $prefix.$database;
$nds = $dataSource . '_' . $database;
$db = ConnectionManager::getDataSource($dataSource);
$db->setConfig(array('name' => $nds, 'database' => $database, 'persistent' => false));
if($ds = ConnectionManager::create($nds, $db->config)) return $db->config;
return false;
}
Then in eevery controller is just use useDbConfig like:
$newDbConfig = $this->dbConnect($serverConfig);
$this->Summary->useDbConfig = $newDbConfig['name'];
Problem: Problem is when i try to fetch each of the summary table data in foreach loop. Every time it runs it always keep connects with 1st databases only. Here is the loop:
foreach($this->databases as $key=> $database){
$newDbConfig = $this->dbConnect($database);
$this->Summary->useDbConfig = $newDbConfig['name'];
$this->Summary->cacheQueries = false;
$summary = $this->Summary->findAllByPeriod('1');
debug(count($summary));
}
I tried to use clearCache() or connectionManager:drop() but with no success.
Please help!
Call setSource
The property useDbConfig is not the right/best way to change the datasource of an in-use model. To change the data source at run time, call setDataSource, i.e.:
foreach($this->databases as $key=> $database){
$newDbConfig = $this->dbConnect($database);
$this->Summary->setDataSource($newDbConfig['name']);
...
}

Error displaying the error page: Application Instantiation Error: Could not connect to MySQL

I am using a serversfree.com account to learn joomla. The php version is 5.4
I get this error when I load my address http://kineteco.bugs3.com/
Error displaying the error page: Application Instantiation Error: Could not connect to MySQL.
I have checked and rechecked the configuration file and everything about the database is correct
public $user = 'xxxxxxxxxx_keco';
public $password = 'xxxxxxxx';
public $db = 'xxxxxxxxxx_keco';
public $dbprefix = 'wa3fi_';
public $live_site = '';
public $secret = 'wR8kb4NfHikqN9a0';
public $gzip = '0';
public $error_reporting = 'default';
public $helpurl = 'http://help.joomla.org/proxy/index.php?option=com_help&keyref=Help{major}{minor}:{keyref}';
public $ftp_host = 'ftp://ftp.kineteco.bugs3.com/';
public $ftp_port = '21';
public $ftp_user = 'xxxxxxxxxx';
public $ftp_pass = 'xxxxxxxx';
public $ftp_root = '/home/xxxxxxxxxx';
this is my first joomla website and I am already frustrated. Please help
If you are certain the DB connection settings are correct, next ensure that you assigned the DB user to the database and assigned all privileges to the user. This very simple miss has tripped me up before.
You generally do this in the same area of your hosting account where you established the creation of the database and user. Now just assign the user to the db with all available permissions.

Where do I put database config values in Codeigniter?

I am trying to connect to a different database than what is in my database config file.
I've been able to do this with the following in my model:
$wp['hostname'] = "localhost";
$wp['username'] = "root";
$wp['password'] = "";
$wp['database'] = "transfer";
$wp['dbdriver'] = "mysql";
$wp['dbprefix'] = "";
$wp['pconnect'] = FALSE;
$wp['db_debug'] = TRUE;
$wp['cache_on'] = FALSE;
$wp['cachedir'] = "";
$wp['char_set'] = "utf8";
$wp['dbcollat'] = "utf8_general_ci";
$wpDB = $this->load->database($wp, TRUE);
and then running queries like so: $query = $wpDB->get();
I can only get it to work when the config values are in the model itself (so there would be a lot of duplication). I've tried putting the config array in the constructor, but I get an error that it can't find it.
Where can I put the config array so I don't have to duplicate it and that's available throughout the model?
Database configuration usually goes in config/database.php. You can configure multiple database connections and store them with different group names:
$active_group = 'default';
$active_record = TRUE;
$db['default']['hostname'] = 'host1';
$db['default']['username'] = 'user1';
$db['default']['password'] = '******';
$db['default']['database'] = 'my_db';
$db['other']['hostname'] = 'host2';
$db['other']['username'] = 'user2';
$db['other']['password'] = '******';
$db['other']['database'] = 'my_other_db;
The $active_group refers to the default group when the database class is loaded. To connect to another group in your model, you can use this in the model's __construct method:
$this->db = $this->load->database('other', TRUE);
While this doesn't play nicely with the more flexible $this->load->model('model_name', 'alias', $config) approach, it might be easier.
More info: http://codeigniter.com/user_guide/database/connecting.html
i think that this can help you, directly from codeigniter forum :)
There is a config directory in Code Igniter where you can add your own config file:
system/application/config
In that same directory there is an autoload.php file where you can specify which additional config files you want to load.
You can use the config file from the CodeIgniter.
To retrieve a config var, use:
$this->config->item('item name');
More info in the docs
Since your config data appears to be database related, store them in
system/application/config/database.php

make db connection persistent throught zend framework

I'm using zend framework. currently everytime I need to use the db I go ahead and connect to the DB:
function connect()
{
$connParams = array(
"host" => $host,
"port" => $port,
"username" => $username,
"password" => $password,
"dbname" => $dbname
);
$db = new Zend_Db_Adapter_Pdo_Mysql($connParams);
return $db
}
so I would just call the connect() function everytime I need to use the db
My question is...suppose I want to reuse $db everywhere in my site and only connect once in the very initial stage of the site load and then close the connection right before the site gets sent to the user, what would be the best practice to accomplish this?
Which file in Zend should I save $db in, what method should I use to save it (global variable?), and which file should I do the connection closing in?
If you are using the default project structure (with the application, library, tests and public folders), you should use set up the db parameters in application/configs/application.ini
Example application.ini:
[production]
resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "testuser"
resources.db.params.dbname = "testdb"
resources.db.params.password = "testpasswd"
resources.db.isDefaultTableAdapter = true
In this way zend framework will automatically open and close the connections to the database and you can use the Zend_Db_Table or Zend_Db_Table_Abstract classes to query your tables easily, for example, to retrieve the student's data for a given SSN you could write a model (application/models/Student.php) that looks something like this:
<?php
class Model_Student extends Zend_Db_Table_Abstract
{
protected $_name = "student";
public function fetchRowsBySSN($ssn)
{
$select = $this->select();
$select->where('ssn = ?', $ssn);
return $this->fetchRow($select)->toArray();
}
}
As you can see there's no need to open/close the connection and you get an associative array with the fields and values of the student record.
Your best best may be to move all of your db connection code into a separate class in which you can set a static $db var.
protected static $_db;
public static function connect()
{
if (self::$_db == null) {
$config = Zend_Config_Xml(); // whatever you'd use
self::$_db = Zend_Db::factory($config->database);
self::$_db->setFetchMode(Zend_Db::FETCH_OBJ);
self::$_db->query('SET NAMES UTF8');
Zend_Db_Table::setDefaultAdapter(self::$_db); // optional
}
return self::$_db;
}
public static function close()
{
if (self::$_db != null) {
self::$_db->closeConnection();
}
}
According to Zend:
Normally it is not necessary to close a database connection. PHP automatically cleans up all resources and the end of a request. Database extensions are designed to close the connection as the reference to the resource object is cleaned up.
However, if you have a long-duration PHP script that initiates many database connections, you might need to close the connection, to avoid exhausting the capacity of your RDBMS server. You can use the Adapter's closeConnection() method to explicitly close the underlying database connection.

Wrapper to Zend_Db is failing

All,
I wrote the following wrapper that extends Zend_Db class to provide db connectivity to my entire application. The db connectivity works fine, but it fails to execute queries when invoked from a different class.
class Testapp_DB extends Zend_Db {
//Declare member variables.
public $db = null;
public $db_host = "";
public $db_database = "";
public $db_username = "";
public $db_password = "";
public function __construct()
{
//Read Database Info from Config File
$this->db_host = Testapp_Registry::get('config')->db->mysql->host;
$this->db_database = Testapp_Registry::get('config')->db->mysql->dbname;
$this->db_username = Testapp_Registry::get('config')->db->mysql->username;
$this->db_password = Testapp_Registry::get('config')->db->mysql->password;
$db = Zend_Db::factory('Mysqli', array(
'host' => $this->db_host,
'username' => $this->db_username,
'password' => $this->db_password,
'dbname' => $this->db_database
));
$db->getConnection(); //Works fine
$this->db = $db;
}
}
Trying to execute query in a PHP file that includes Testapp_DB - fails..
<?php
$db = new Testapp_DB();
print_r($db); //I can see the DB object here
$sql = 'SELECT * FROM tb_Log';
$result = $db->fetchAll($sql, 2); //This method fails.. Don't know why. Any ideas?
print_r($result);
?>
Can someone please explain, why the fetchAll method fails?
Thanks
*Zend_Db* doesnt have any method other than factory().
I dont really get, what you are trying to solve this way, but as far as I can see you need to call query() this way
$db->db->query();
Perhaps instead of using your wrapper, try this:
// Note: change your config to have a 'params' entry
$db = Zend_Db::factory(Testapp_Registry::get('config')->db->mysql);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
Zend_Registry::set('database', $db);
// in your config
...mysql.params.host = ...
...mysql.params.dbname = ...
...mysql.params.username = ...
...mysql.params.password = ...
Then, your Zend_Db_Table objects will have connectivity, and in addition you can grab the connection using Zend_Registry::get('database'). And, you'll make only one database connection once per request.
Try to create a SQL file like schema.mysql.sql,
then test it on phpMyAdmin and when it's free of bugs run this code:
$bootstrap = $application->getBootstrap();
$bootstrap->bootstrap(‘db’);
$config = $bootstrap->getResource(‘db’)->getConfig();
$runCommand = “mysql -h “.$config["host"].” -P “.$config["port"].” -u’”.$config["username"].”‘ -p’”.$config["password"].”‘ “.$config["dbname"].” < “.dirname(__FILE__) . ‘/schema.mysql.sql’;
echo $runCommand;
system($runCommand);
Hope this helps! http://www.unexpectedit.com/zend-php/zend-db-exec-a-sql-file

Categories