use two databases in a same function in controller CakePHP - php

I am developing an application in CakePHP. I need two databases in same function in same controller. In Invoice I need to to add data in invoices table but need students list to show from another database having students table.
public function add() {
if ($this->request->is('post')) {
$this->Invoice->create();
$this->request->data['Invoice']['created_by'] = $this->Auth->user('id');
if ($this->Invoice->save($this->request->data)) {
$this->Session->setFlash(__('The Invoice has been saved.'), 'default', array('class' => 'alert alert-success'));
}
return $this->redirect(array('action' => 'view',$Invoice_id));
}
// fetch students from different database.
$this->loadModel('Student');
$users = $this->Student->find('list',array('fields'=>array('Student.id','Student.name')));
}
I am using the public $useDbConfig = 'fees'; as second DB configuration but unable to get the data in same function. Please help.
<?php
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'admin',
'database' => 'inventory',
'prefix' => '',
//'encoding' => 'utf8',
);
// fetch students from fees controller.
public $fees = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'admin',
'database' => 'fees',
'prefix' => '',
//'encoding' => 'utf8',
);
}

You need to declare that your Students model will use a different database source. You are saying that you used the public $useDbConfig = 'fees'; with out mentioning in which model you used this property.
Check this link
We can then configure the datasource in our app/Config/database.php
file by adding something like this:
public $faraway = array(
'datasource' => 'FarAwaySource',
'apiKey' => '1234abcd', );
Then use the database config in our models like this:
class MyModel extends AppModel {
public $useDbConfig = 'faraway';
}
So fees looks like some database that should be used on the Invoice model:
class Invoice extends AppModel {
public $useDbConfig = 'fees';
}
and Students models should most probably stay on the default database
class Students extends AppModel {
public $useDbConfig = 'default'; // This line is optional. Even if you don't write this line your model will load data from the default database.
}
Maybe the databases are the other way around but I think you got the point.
You can still configure the database source of your models from inside your Controller by doing the following:
public function add() {
...
$this->Student->useDbConfig = 'fees'
...
}
or most preferable
public function add() {
...
$this->Student->setDataSource('default')
...
}

Related

How to use include function inside Model Codeigniter 4

I have too many function for database inside one model file
See my example :
<?php
namespace App\Models;
use CodeIgniter\Model;
use Medoo\Medoo;
class DBMedoo extends Model {
public $database;
public $maxfolder;
protected $session;
function __construct()
{
include APPPATH . 'ThirdParty/vendor/autoload.php';
$this->session = \Config\Services::session();
$this->session->start();
$this->database = new Medoo([
// [required]
'type' => 'mysql',
'host' => 'localhost',
'database' => 'db_testing',
'username' => 'root',
'password' => '',
// [optional]
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci',
'port' => 3306,
// [optional] Table prefix, all table names will be prefixed as PREFIX_table.
'prefix' => '',
// [optional] Enable logging, it is disabled by default for better performance.
'logging' => true,
// [optional]
// Error mode
// Error handling strategies when error is occurred.
// PDO::ERRMODE_SILENT (default) | PDO::ERRMODE_WARNING | PDO::ERRMODE_EXCEPTION
// Read more from https://www.php.net/manual/en/pdo.error-handling.php.
'error' => \PDO::ERRMODE_SILENT,
// [optional]
// The driver_option for connection.
// Read more from http://www.php.net/manual/en/pdo.setattribute.php.
'option' => [
\PDO::ATTR_CASE => \PDO::CASE_NATURAL
],
// [optional] Medoo will execute those commands after connected to the database.
'command' => [
'SET SQL_MODE=ANSI_QUOTES'
]
]);
}
public function FDatabase() {
return $this->database;
}
public function UpdatePriceAlertPush($idx) {
$this->FDatabase()->update('tb_apppricealert', [
'triggered' => 1,
'ispush' => 1,
'ipaddress' => $_SERVER['REMOTE_ADDR'],
'datetime' => date('Y-m-d H:i:s')
], [
'idx' => $idx
]);
}
include 'Ticker.php'; // Here error
include 'CheckUpdateVersion.php'; // Here error
// and 50 more.....
}
?>
How to separate each public function into every part of file and include in the main model ?
In my example above both :
include 'Ticker.php'; // Here error
include 'CheckUpdateVersion.php'; // Here error
Got error.
This is "Ticker.php"
<?php
// ================================== TICKER
function InsertTicker($array) {
$this->FDatabase()->action(function($database) use (&$array) {
$this->FDatabase()->insert('tb_ticker', [
'ticker' => $array['ticker'],
'company' => $array['company'],
'ipaddress' => $_SERVER['REMOTE_ADDR'],
'datetime' => date('Y-m-d H:i:s')
]);
// If you found something wrong, just return false value to rollback the whole transaction.
if ($this->FDatabase()->error) {
return false;
}
});
}
function SelectAllTicker() {
$Data = $this->FDatabase()->select('tb_ticker', '*');
return $Data;
}
function GetTicker($ticker) {
$Data = $this->FDatabase()->get('tb_ticker', '*', [
'ticker' => $ticker
]);
return $Data;
}
?>
and this is "CheckUpdateVersion.php"
<?php
// ================================== CHECK UPDATE VERSION
function GetUpdateVersion() {
$Data = $this->FDatabase()->get('tb_version', '*', [
'ORDER' => [
'idx' => 'DESC'
]
]);
return $Data;
}
?>
I want to separate every category function to each file. So in my model it is easy to read and find the function. Also the model will look more tidy.
Is there anyway to achieve it ? I don't want to put all public function into one file. It is too long to read and when try to use the function I need to search the name.
If I separate it into some of file base on category. Then it is easy to find and structure data may look tidy.
Remember this is codeigniter 4

Yii db connection issue

I am getting this error message:
The table "Permissionactions" for active record class
"Permissionactions" cannot be found in the database.
/var/www/html/YII/framework/db/ar/CActiveRecord.php(2310)
private $_model;
/**
* Constructor.
* #param CActiveRecord $model the model instance
*/
public function __construct($model)
{
$this->_model=$model;
$tableName=$model->tableName();
if(($table=$model->getDbConnection()->getSchema()->getTable($tableName))===null)
throw new CDbException(Yii::t('yii','The table "{table}" for active record class "{class}" cannot be found in the database.',
array('{class}'=>get_class($model),'{table}'=>$tableName)));
if($table->primaryKey===null)
{
$table->primaryKey=$model->primaryKey();
if(is_string($table->primaryKey) && isset($table->columns[$table->primaryKey]))
$table->columns[$table->primaryKey]->isPrimaryKey=true;
elseif(is_array($table->primaryKey))
{
foreach($table->primaryKey as $name)
{
if(isset($table->columns[$name]))
$table->columns[$name]->isPrimaryKey=true;
There is no any Permissionactions named table in my db. This is the main.php connection:
'db' => array(
'connectionString' => 'mysql:host=xxxxxxxxx;dbname=xxxxx',
'emulatePrepare' => true,
'username' => 'xxxxxxxx',
'password' => 'xxxxxxxxxxx',
'charset' => 'utf8',
),
'dbpermissions' => array(
'connectionString' => "mysql:host=xxxxxxxx;dbname=xxxxx",
'emulatePrepare' => true,
'username' => 'xxxxxxxx',
'password' => 'xxxxxxxxxxxxxxx',
'charset' => 'utf8',
'class' => 'CDbConnection'
),
Any idea why am I getting this ?
UPDATE:
This is the controller:
class MainController extends Controller {
public $model;
public function init(){
$this->model = Permissionactions::model();
}
...
and the Permissionsactions class (model):
class Permissionactions extends ActiveRecord{
private $connection_permission;
//private $connection_invetory;
/**
* #see db connections from config/main.php
*/
public function __construct(){
$this->connection_permission = Yii::app()->dbpermissions;
}
public static function model($className=__CLASS__){
return parent::model($className);
}
....
On my localhost it works. But now I put it on a server and it shows me this error.
Search thru your Code with your Editor/IDE function Search in Files / search in Project and locate the String
Permissionactions
Provide some more Information about your Issue and your Config.

Multiple database in cakephp console app

Following is my cake console code to generate database schema. I have to manage multiple database schema migration. When I am calling generateDb function it creates a master schema after that i am switching database connection to client database, but client schema is not generating. its again generating master schema.
class HelloShell extends AppShell {
public $uses = array('ClientDbdetail');
public function generateDb() {
$runCommand = shell_exec(APP.'Console/cake schema generate -f master');
if ($runCommand) {
$sessionArray = $this->ClientDbdetail->find('first', array('recursive' => -1));
$this->__switchDb($sessionArray['ClientDbdetail']);
shell_exec(APP.'Console/cake schema generate -f client');
$this->out('Schema generated');
} else {
$this->out('Schema not generated');
}
}
private function __switchDb(array $userDetail) {
$username = 'default';
$settings = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'port' => 3306,
'login' => $userDetail['user_dbuser'],
'password' => $userDetail['user_dbpwd'],
'database' => $userDetail['user_dbname'],
'prefix' => ''
);
ConnectionManager::drop($username);
ConnectionManager::create($username, $settings);
ConnectionManager::getDataSource($username);
}
}
From CakePHP book there is an example.
public $connection = 'default';
public function before($event = array()) {
$db = ConnectionManager::getDataSource($this->connection);
$db->cacheSources = false;
return true;
}
and after :
public function before($event = array()) {
$articles = ClassRegistry::init('Articles', array(
'ds' => $this->connection
));
// Do things with articles.
}
see this : http://book.cakephp.org/2.0/en/console-and-shells/schema-management-and-migrations.html

Change database on the fly in Cakephp 1.2 just in some Models

I have an application in CakePhp 1.2, where depends on the domain, SOME of the models have to change dinamically the database.
So I need to find an easy way to:
Check the domain.
Set $useDbConfig on SOME models the database
required.
This function on database.php change the database depending just on the domain, but not on the model:
public function __construct(){
if (strpos(env('HTTP_HOST'), 'site_one') !== false) {
// use site_one database config
$this->default = $this->site_one;
} elseif (strpos(env('HTTP_HOST'), 'site_two') !== false) {
// use site_two database config
$this->default = $this->site_two; }
}
How can I change the database depending also on the model?
Thanks in advance.
What if you used your code, but had an additional database config for those models that don't change? This additional database config would not be changed by the function you posted. In those models that you don't want to change, add the line
var $useDbConfig = 'static';
or whatever the name of your database config is that doesn't change. Then those that do change, you leave using the default config.
write in your database.php
var $default = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'first-database-name',
'prefix' => '',
);
var $otherdatabase = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'other-database-name',
'prefix' => '',
);
and in model
class Modelname extends AppModel {
var $name = 'Modelname';
var $useTable = 'tablename from other-database';
var $useDbConfig = 'otherdatabase ';
.......... .......... .........

NO QUERY using CakePHP Authentication component

I'm using CakePHP 2.2.4, and I have started to work with Atuh Componenet.
This is my AppController:
class AppController extends Controller {
public $components = array('Auth', 'Session');
public function beforeFilter() {
$this->Auth->authorize = array('Controller');
$this->Auth->authenticate = array(
'Form' => array (
'scope' => array('User.active' => 1),
'fields' => array('username' => 'email', 'password' => 'password'),
)
);
}
public function isAuthorized($user) {
debug($user);
return true;
}
}
This is my User.php model
class User extends AppModel {
public $name = 'User';
/* Relazioni */
public $hasOne = 'Profile';
public $belongsTo = 'Role';
public $hasMany = array(
'Lead' => array(
'className' => 'Lead'
)
);
}
and this is my UserController.php
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController
{
public $name = 'Users';
public $uses = array();
public function beforeFilter()
{
parent::beforeFilter();
}
public function login()
{
if ($this->request->is('post'))
{
if ($this->Auth->login())
{
debug('Logged');
}
else
{
$this->Session->setFlash('Login non autorizzato', 'default', array('class' => 'errore'), 'login');
}
}
}
public function logout()
{
$this->redirect($this->Auth->logout());
}
}
I have a strange problem using Auth Component, because at the end of the layout I have sql_dump element, that prints NO QUERY.
However, If i put correct values I do not login
Why does Auth component is not working ?
EDIT:
The data of the request is:
Array
(
[User] => Array
(
[email] => test#test.it
[pwd] => abc
)
)
Your code in AppController is wrong
public function beforeFilter() {
$this->Auth->authorize = array('Controller');
$this->Auth->authenticate = array(
'Form' => array (
'scope' => array('User.active' => 1),
// password != pwd as you post it
'fields' => array('username' => 'email', 'password' => 'password'),
)
);
}
Change it to
'fields' => array('username' => 'email', 'password' => 'pwd'),
or make sure to post password instead of pwd in your form
Please see https://github.com/cakephp/cakephp/blob/master/lib/Cake/Controller/Component/Auth/FormAuthenticate.php for documentation on the matter
I'd like to post-fix this answer for anyone arriving here, who is unable to get logged in using Auth for which this example does not DIRECTLY Apply.
An important thing to remember is that Auth is expecting the underlying database columns to be "username" and "password". If for whatever reason you defer from this, for example if you want to validate on a users email (very common) and you change the table's column name to reflect this, than you must tell Auth about this.
The reason is because the underlying query will fail. Ultimately all that's happening behind the scene is a simply query matching the specified fields. For example (not exact - simply for demonstration purposes -- select *'s are bad):
SELECT * FROM users WHERE username = 'blahblahblah' AND password = 'someInsan31yh4sh3dpassw0rd'
If your underlying table is missing a "username" column in loo of an "email" column, than this query will obviously fail. Resulting in the inability to login and usually with no indication that the query failed (it is even omitted from the SQL dump). The following code in your AppController however will solve you issues:
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'columnUsedForValidatingUsername', 'password' => 'columnUserForValidatingPassword')
)
)
)
);
Jippi's answer was completely correct in this case. But I feel as though as an answerER on StackOverflow you owe it to anyone finding this to explain WHY the problem is occurring and provide an unspecific answer.
Cheers

Categories