Database switch with BindModel in cakePHP - php

I'm working on application in cake PHP which uses multiple database. I need to fetch data from multiple tables and i'm using bindModel for their association. But bindModel does not allow database switch functionality, I need to access data from multiple databases.If anyone has done this type of assignment then plz help me out.

In your AppModel
class AppModel extends Model
{
/**
* Connects to specified database
*/
public function setDatabase($database, $datasource = 'default')
{
$nds = $datasource . '_' . $database;
$db = &ConnectionManager::getDataSource($datasource);
$db->setConfig(array(
'name' => $nds,
'database' => $database,
'persistent' => false
));
if ( $ds = ConnectionManager::create($nds, $db->config) ) {
$this->useDbConfig = $nds;
$this->cacheQueries = false;
return true;
}
return false;
}
}
and in your controller you can use
class CarsController extends AppController
{
public function user()
{
$this->User->setDatabase('testdb1');
$cars = $this->User->find('all');
$this->set('User', $User);
}
public function client()
{
$this->Client->setDatabase('testdb2');
$cars = $this->User->find('all');
$this->set('Client', $Client);
}
}

Related

How to dynamically set table name in Eloquent Model

I am new to Laravel. I am trying to use Eloquent Model to access data in DB.
I have tables that shares similarities such as table name.
So I want to use one Model to access several tables in DB like below but without luck.
Is there any way to set table name dynamically?
Any suggestion or advice would be appreciated. Thank you in advance.
Model:
class ProductLog extends Model
{
public $timestamps = false;
public function __construct($type = null) {
parent::__construct();
$this->setTable($type);
}
}
Controller:
public function index($type, $id) {
$productLog = new ProductLog($type);
$contents = $productLog::all();
return response($contents, 200);
}
Solution For those who suffer from same problem:
I was able to change table name by the way #Mahdi Younesi suggested.
And I was able to add where conditions by like below
$productLog = new ProductLog;
$productLog->setTable('LogEmail');
$logInstance = $productLog->where('origin_id', $carrier_id)
->where('origin_type', 2);
The following trait allows for passing on the table name during hydration.
trait BindsDynamically
{
protected $connection = null;
protected $table = null;
public function bind(string $connection, string $table)
{
$this->setConnection($connection);
$this->setTable($table);
}
public function newInstance($attributes = [], $exists = false)
{
// Overridden in order to allow for late table binding.
$model = parent::newInstance($attributes, $exists);
$model->setTable($this->table);
return $model;
}
}
Here is how to use it:
class ProductLog extends Model
{
use BindsDynamically;
}
Call the method on instance like this:
public function index()
{
$productLog = new ProductLog;
$productLog->setTable('anotherTableName');
$productLog->get(); // select * from anotherTableName
$productLog->myTestProp = 'test';
$productLog->save(); // now saves into anotherTableName
}
I created a package for this: Laravel Dynamic Model
Feel free to use it:
https://github.com/laracraft-tech/laravel-dynamic-model
This basically allows you to do something like this:
$foo = App::make(DynamicModel::class, ['table_name' => 'foo']);
$foo->create([
'col1' => 'asdf',
'col2' => 123
]);
$faz = App::make(DynamicModel::class, ['table_name' => 'faz']);
$faz->create([...]);

How to pass and retrieve data between two controllers in Laravel

I'm trying to get to grips with Laravel and not finding the documentation any help at all. It seems to assume you know so much instead of actually walking new users through each section step by step.
I've got to the point where I need to make an internal call to another class, and sticking with MVC I can't seem to do what should be a simple thing.
My code:
class UsersController extends BaseController {
protected $layout = 'layouts.templates.page';
protected $messages;
public function getIndex()
{
$input = array('where', array('field' => 'email', 'operator' => '=', 'value' => 'tony#fluidstudiosltd.com'));
$request = Request::create('user/read', 'GET');
$users = json_decode(Route::dispatch($request)->getContent());
var_dump($users); exit;
$this->pageTitle = 'Fluid Customer Status :: Admin Users';
$this->content = View::make('layouts.admin.users');
}
}
Class UserController extends Base Controller
public function getRead()
{
$userId = (int) Request::segment(3);
if ($userId)
{
$user = User::findOrFail($userId);
return $user;
}
else
{
$users = new User;
var_dump(Input::all()); exit;
if (Input::has('where'))
{
var_dump(Input::get('where')); exit;
}
return $users->get();
}
}
Why isn't the input data from UsersController#getIndex available in UserController#getRead

pass variable between functions in same controller

class AppointmentsController extends AppController {
public function view($id = null) {
if (!$this->Appointment->exists($id)) {
throw new NotFoundException(__('Invalid appointment'));
}
$options = array('conditions' => array('Appointment.' . $this->Appointment->primaryKey => $id));
$this->set('appointment', $this->Appointment->find('first', $options));
$kk = $this->Appointment->find('first', array('fields' => 'status', 'conditions' => array('Appointment.id' => $id)));
$ss = reset($kk);
$stats = reset($ss);
}
}
I have set $stats via getting value from DB and i want to use in in another function in same controller
then I want to use like this
class AppointmentsController extends AppController {
function confirm(){
$stats = 'New';
}
}
Seeing that it's the same class, have you tried using $this->stats instead of a local variable?
You can call another function in your first function like
$this->confirm($status); // calling confirm function
function confirm($status)
{
//use status as you want
}
Or you can set status as global variable then this can you accessible in any function.
I think, you've to create function in the model that will return the value of the field by id.
<?php
// model/AppModel.php
public function getFieldById($field='id', $id){
return $this->field($field, array('id' => $id));
}
// in controller function you can access this like.
$status = $this->Appointment->getFieldById('status', $id); // $id will be appointment id.
?>

How to get access to the model in the view - Symfony 2

I have the following model:
class Person
{
public $name;
function __Construct( $name )
{
$this->name = $name;
}
}
I have the following controller:
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', $people);
}
}
How do I get access to the model array in the view. Is there a way to access the model directly or do I have to assign a property like so:?
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', array( "model" => $people ) );
}
}
View:
<?php
foreach( $model as $person )
{
echo $person->title;
}
?>
The problem with the above will be that it can be changed by a user to
return $this->render( 'FrameworkBundle:Navigation:index.html.php', array( "marybloomingpoppin" => $people ) );
With the example view you used, you already had the correct implementation:
class NavigationController extends Controller
{
public function indexAction()
{
$people = array(
new Person("James"),
new Person("Bob")
);
return $this->render('FrameworkBundle:Navigation:index.html.php', array( "model" => $people ) );
}
}
You mentioned the concern that somebody could change the assignment in the controller, but this is something you always have if somebody changes the name of a variable only in one place and not in all. So I don't think this is an issue.

Problem loading models with modules in Zend Framework

I have a folder structure like this and I'm trying to load the News model inside my controller:
<?php
/**
* Login
*/
class Admin_NewsController extends Zend_Controller_Action {
public function preDispatch() {
$layout = Zend_Layout::getMvcInstance();
$layout->setLayout('admin');
}
public function init() {
$this->db = new Application_Admin_Model_DbTable_News();
}
public function indexAction() {
}
public function addAction() {
//$this->getHelper('viewRenderer')->setNoRender();
// Calls the Request object
$request = $this->getRequest();
if ($request->isPost()) {
// Retrieves form data
$data = array(
"new_title" => $request->getParam('txtTitle'),
"new_text" => htmlentities($request->getParam('txtNews')),
"new_image" => $request->getParam('upName'),
"new_published" => 1
);
// Inserts in the database
if ($this->db->addNews($data)) {
$this->view->output = 1;
} else {
$this->view->output = 0;
}
} else {
$this->view->output = 0;
}
$this->_helper->layout->disableLayout();
}
}
And my model:
<?php
class Application_Admin_Model_DbTable_News extends Zend_Db_Table_Abstract
{
protected $_name = 'news';
public function addNews($data) {
$this->insert($data);
}
}
Althoug I'm getting this error:
Since your News class belongs to the module, its name should be Admin_Model_DbTable_News, without Application_ prefix.
See more on autoloading within modules at http://framework.zend.com/manual/en/zend.loader.autoloader-resource.html#zend.loader.autoloader-resource.module

Categories