I have following Data:
Database name = ThisDatabase
Table name = InfoData
cakePHP3 convert the names in
ThisDatabase = this_database
InfoData = info_data
My problem is that I have no chance to rename the DB or Table names so I have to disable or bypass the name converting in cakePHP3.
But I have no clue how I can do this.
How can i disable the converting? So I can use the actual names (ThisDatabase and InfoData).
You should follow naming convention for your files and cakephp to work properly, and specify the table name in initialize function inside your App\Model\Table\ArticlesTable.php
Here you can find related documentation
That's easy, CakePHP offers you a way to change the name of the table as you wish.
For the database, in the app config, set the database name :
...
'Datasources' => [
'default' => [
...
'username' => 'username',
'password' => 'password',
'database' => 'ThisDatabase', // Here you can set the database name
'encoding' => 'utf8',
..
]
],
...
Here is some doc
For the table name : In your table definition, change the table name
class Infodata extends Table
{
public function initialize(array $config)
{
$this->table('InfoData');
}
}
Here is is the doc
Related
I am building the admission portal in laravel,
I have super admin database which has a schools table with 100 rows,
schools table structure
1.id
2.school_name
3.database details
I want to connect to the school database with its database details by its id.
technically
1.I will pass the school id from url
2.it will select that row from school table
3.after selecting the database details of particular school
4.will connect to the school database for further use.
I went through https://laracasts.com/discuss/channels/tips/set-up-dynamic-database-connection-globally
http://fideloper.com/laravel-multiple-database-connections
but no luck
please help to sort it out.
Actually you dont want multiple connections, but rather change existing connection.
public function setSchoolConnection($id) {
$school = School::find($id);
if ( $school ) {
config(['database.mysql' => [
'database' => $school->database,
'username' => $school->username,
'password' => $school->password
]]);
}
}
Now the default connection has been changed. I think.
If you don't want to change existing connection, just create a new connectio
config(['database.school' => [
'driver' => 'mysql',
'database' => $school->database,
'username' => $school->username,
'password' => $school->password
]]);
and use it like this
$users = DB::connection('school')->select(...);
Have you tried setting the connection in the School model? Laravel will take care of the rest, even if you have relations with different connection.
In your School model, I will override the constructor like so:
public function __construct(array $attributes = [])
{
$this->setConnection(env('DB_SCHOOL_CONNECTION'));
parent::__construct($attributes);
}
The one thing to be careful of is if you have a relation with a different connection, using whereHas or has in your query/builder wont work. as laravel will not be able to set the connection in the query generated.
In Cake 2 you could save a model and specify which fields you wanted to restrict the save to.
Is there a built-in way to do this simply in Cake 3? For example, if the request data is being put straight into a new entity which is then saved, how can I tell the method to only save the fields I allow?
Simplified Example
// User makes a request; their POST data goes directly into the entity
$customer = $this->Customers->newEntity($this->request->data);
$this->Customers->save($customer);
The obvious danger here is that I can set any properties I like on that customer entity, via the request. In reality, I only want to allowing saving of a couple of specific fields.
That's what mass assignment protection is there for, in the form of the $_accessible entity property
class Customer extends Entity
{
// allow only `first_name` and `last_name` to be mass assigned
protected $_accessible = [
'first_name' => true,
'last_name' => true
];
}
and the fieldList and accessibleFields options for Table::newEntity/newEntities/patchEntity/patchEntities()
// allow only `first_name` and `last_name` to be mass assigned,
// ignoring the entity accessible defaults
$customer = $this->Customers->newEntity($this->request->data(), [
'fieldList' => [
'first_name',
'last_name'
]
]);
The accessibleFields option will change the accessibility of the specified fields only. Also it will actually modify the entity, ie unlike fieldList, which the marshaller will simply use as the whitelist instead of the entity defaults, accessibleFields will change the values of the entities $_accessible property!
See
Cookbook > Database Access & ORM > Entities > Mass Assignment
Cookbook > Database Access & ORM > Saving Data > Changing Accessible Fields
API > \Cake\ORM\Table::newEntity()
API > \Cake\ORM\Table::patchEntity()
There are two ways of protecting you against this problem. The first one is by setting the default columns that can be safely set from a request using the Mass Assignment feature in the entities.
The _accessible property allows you to provide a map of properties and whether or not they can be mass-assigned. The values true and false indicate whether a field can or cannot be mass-assigned:
http://book.cakephp.org/3.0/en/orm/entities.html#entities-mass-assignment
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Article extends Entity
{
protected $_accessible = [
'title' => true,
'body' => true,
'*' => false,
];
}
The second way is by using the fieldList option when creating or merging data into an entity:
// Contains ['user_id' => 100, 'title' => 'Hacked!'];
$data = $this->request->data;
// Only allow title to be changed
$entity = $this->patchEntity($entity, $data, [
'fieldList' => ['title']
]);
$this->save($entity);
You can also control which properties can be assigned for associations:
// Only allow changing the title and tags
// and the tag name is the only column that can be set
$entity = $this->patchEntity($entity, $data, [
'fieldList' => ['title', 'tags'],
'associated' => ['Tags' => ['fieldList' => ['name']]]
]);
$this->save($entity);
Using this feature is handy when you have many different functions your users can access and you want to let your users edit different data based on their privileges.
The fieldList options is also accepted by the newEntity(), newEntities() and patchEntities() methods.
For more :http://book.cakephp.org/3.0/en/orm/saving-data.html
I have yii application,, and i want to change the database connection..
first, my app is connect to 'trackstar' database, and later i want to change to 'taskmanagement' database..
So i just simply change the dbname in my code :
<?php
// This is the configuration for yiic console application.
// Any writable CConsoleApplication properties can be configured here.
return array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'name'=>'My Console Application',
// application components
'components'=>array(
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=taskmanagement',
'emulatePrepare' => true,
'username' => 'root',
'password' => '',
'charset' => 'utf8',
),
'authManager'=>array(
'class'=>'CDbAuthManager',
'connectionID'=>'db',
'itemTable' => 'tbl_auth_item',
'itemChildTable' => 'tbl_auth_item_child',
'assignmentTable' => 'tbl_auth_assignment',
),
),
);
but when i run the app i got error :
CDbCommand failed to execute the SQL statement: SQLSTATE[42S02]: Base
table or view not found: 1146 Table 'trackstar.tbl_auth_assignment'
doesn't exist. The SQL statement executed was: SELECT * FROM
tbl_auth_assignment
WHERE userid=:userid
the thing i dont understand is that why is still connect to trackstar database eventhough i just change the dbname to taskmanagement
thx before :)
I guess one your model queries written as straight SQL query.
EX:
SELECT * FROM databaseName.tableName
So, Even you change the database name in the config file these kinds of queries may not work. Please check your code in this way.
You are only configure the console.php Configuration . But Yii Web application use the main.php
Check your main.php file
its located on Your App folder -> Protected -> config ->main.php
Change Db connection on this file
You can use below code to update database dynamically
if ($city == 'ABC') {
$databse = 'db_abc';
} elseif ($city == 'BCD') {
$databse = 'db_bcd';
} else {
$databse = 'default_db';
}
$db = Yii::$app->getDb();
$db->dsn = "mysql:host=localhost;dbname=$databse";
Hope this help to override database connection string
I would like to connect to a second database with Yii at runtime. The database name would come from a database table after the user to login.
I saw in a tutorial I should do this:
$db2 = Yii::createComponent(array(
'class' => 'EMongoClient',
'server' => 'mongodb://127.0.0.1:27017',
'db' => $emp['database']
));
Yii::app()->setComponent('db2',$db2);
But in my controler when I access Yii::app()->db2 get the error:
Property "CWebApplication.db2" is not defined
What am I doing wrong?
The following works for me:
Yii::app()->mongodb->setActive(false);
Yii::app()->mongodb->setServer('mongodb://localhost:27017');
Yii::app()->mongodb->setDb('db1');
Yii::app()->mongodb->setActive(true);
UPDATED: Try, instead instance, pass configurations:
Yii::app()->setComponent( 'db2', array(
'class' => 'EMongoClient',
'server' => 'mongodb://127.0.0.1:27017',
'db' => $emp['database']
)
);
Or, you may create special index on params in configurations, such as:
...
'params' => array(
'db2' => null,
),
And the use Yii::app()->params['db2'] = $db2
From this comment:
My problem is not with the creation of the component. Soon after
creating if I access Yii::app()->db2 its works, but when I try to
access via another model or controller I get the error
I think you are setting this component only once somewhere, and then making subsequent requests to different controllers.
You need to put the code, somewhere it is being called EVERYTIME, on every Request. thats how PHP works, there is no "global application state"
by default Yii comes with protected/components/controller.php has base controller for the rest of the app.
my suggestion would be to put your code on the init() method of that controller, so that it always gets called.
You mentioned the database name comes from a table once the user logs in, so you need to save that value in the session, in other to be able to access it in the other requests:
<?php
// After login in
Yii::app()->user->setState('db_name', $db_name);
// in protected/components/controller.php
public function init()
{
if (!Yii::app()->user->isGuest) {
$db2 = Yii::createComponent(array(
'class' => 'EMongoClient',
'server' => 'mongodb://127.0.0.1:27017',
'db' => Yii::app()->user->getState('db_name')
));
Yii::app()->setComponent('db2',$db2);
}
}
Hope it helps, I am assuming many things here :)
I need to update an application which is built on Zend Framework.
Most of the text is hard-coded in views scripts, forms, etc.
The application will be available in say, 3 languages AND is language specific (the content is not the same for all) and will have one domain per language (ie: mygreatsite.com, monsupersite.com, ilmiosupersite.com, etc.)
First question:
What is the best way to "handle" this kind of application?
I can imagine several solution like:
One copy per language, using different db, etc... (probably not the best way for maintenance)
Only one application, handling different content, db, etc, depending on the locale (based on the route)
Second question:
What should I need to know about the existing code to start the "migration"?
What about any best practice when building a i18n website?
What are the best adapter? (I already used gettext() and I think it's the best)
I am by no means an expert but this is what I do.
I use array as my translation adapter because it’s easier for my clients to update as they are just regular Joes. And I use translation keys instead of sentences. For example
Some people would use
$this->translate(‘Some sentence to translate’);
I use
$this->translate(‘default-index-dashboard-title’);
This makes it far easier for me to know where the text I’m looking for is to change. I don’t know if there are any advantages other than that though.
You will need to setup your translation adapter and translation cache (if you want) in your bootstrap. I do mine like this:
protected function _initLocale()
{
$locale = new Zend_Locale(Zend_Locale::BROWSER);
$config = Zend_Registry::get('config');
Zend_Registry::set('Zend_Locale', $locale->toString());
return $locale;
}
protected function _initTranslation()
{
try{
$translate = new Zend_Translate(array('adapter' => 'array', 'content' => ROOT . '/callmanagement/languages/' . strtolower(Zend_Registry::get('Zend_Locale')) . '.php'));
}catch(Exception $e){
$translate = new Zend_Translate(array('adapter' => 'array', 'content' => ROOT . '/callmanagement/languages/en_gb.php'));
}
Zend_Registry::set('Zend_Translate', $translate);
return $translate;
}
I would use a single code base unless the sites are completely different and store the shared data in one database and have other databases for the site specific stuff.
You can setup multiple db adapters either in the bootstrap or in the congfig.
$dbLocal = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => 'localhost',
'username' => $result['user'],
'password' => $result['password'],
'dbname' => $result['database']
));
Zend_Db_Table_Abstract::setDefaultAdapter($dbLocal);
$dbShared = new Zend_Db_Adapter_Pdo_Mysql(array(
'host' => 'localhost',
'username' => ‘root’,
'password' => 'pass',
'dbname' => 'dbname'
));
Zend_Registry::set('db_local', $dbLocal);
Zend_Registry::set('db_shared', $dbShared);
return $dbLocal;
You can get Zend Form to translate for you just put your translation key into the label field.
$this->addElement(‘text’, ‘test’, array(‘label’ => ‘translation-key’, ‘required’ => true)); etc.
Then if you are using Zend_Db_Table_Abstract classes you can change the default schema and database connection like this:
class Default_Model_Table_Topics extends Zend_Db_Table_Abstract
{
protected $_name = 'topics';
protected $_id = 'topic_id';
protected $_rowClass = 'Default_Model_Topic';
protected $_schema = 'dbname';
protected $_adapter = 'db_shared';
}
If you need any more examples I’ll try and help.