Zend Framework with multiple schema/databases? - php

I have a few tables that I've defined like the below examples:
class TableA extends Zend_Db_Table_Abstract
{
protected $_schema = 'schema1';
protected $_name = 'tablea';
}
class TableB extends Zend_Db_Table_Abstract
{
protected $_schema = 'schema2';
protected $_name = 'tableb';
}
This seems to work perfectly using one default Db adapter (since the 2 schemas are on the same server).
Code like this works:
$tableA = new TableA();
$select = $tableA->select();
// $select->__toString() outputs: SELECT * FROM `schema1`.`tablea`
However, when I try to use the same models with any of the Zend Framework table relationship functions (ie: findDependantRowset() or findManyToManyRowset()) the query tries to execute using the schema from the default adapter and does not use the appropriate schema that is defined in the model class.
Is this a bug? How can I force ZF to use the schema I have defined in the table class and not the one defined as the default in the default Db adapter?

I think this is related to this bug:
http://framework.zend.com/issues/browse/ZF-1838
It has been fixed in the upstream and should be available in the next release.

I think you can use a database view table to merge data from 2 schemas, and then use Zend Framework to fetch data from that table.

Related

Is it possible to define a function in the table property of Model Laravel?

Colleagues, help out. I have a list_books_hist(?) function in my database (the database is built on a separate scheme, not tied to migrations) (which we will go to the id and it returns a line from the table of outdated books)
class BooksListHist extends Model
{
protected $connection = 'db_main';
protected $table = 'lst_books_hist(?)'; //--> can I do like this?
}
Then how do I build a query by passing an ID card there? Using AddBinding? How can I work with the BooksListHist model in this case ?
BooksListHist::addBinding("id_book", "select")->select() ? But in this case it doesn't work

Eloquent (WITHOUT Laravel) get data from table with dynamic name

I'm sure this is a totally simple question but for the life of me I'm stuck here- we're using Eloquent outside of Laravel due to PHP restrictions. I have a support ticket tracking app that I'm trying to update.
The data structure of this app is such that each ticket is assigned a UUID on submission and a table with that UUID as its name is generated and all changes to the ticket are tracked as new entries in that table.
Following some tutorials on Eloquent I got our models and controllers set up and working but for each one I see that I'm defining the table name in the model itself. IE our ticket model is
namespace Models;
use \Illuminate\Database\Eloquent\Model;
class Ticket extends Model {
protected $table = 'tickets';
protected $fillable = [table columns here];
}
and anything called in the tickets controller correctly and successfully reads and writes data to our tickets table.
So... my question is: how would I go about reading/writing/creating/deleting those previously mentioned UUID tables?
I've tried the built in table selector (ie- DB::table(uuid here) and DB::setTable(uuid here) but to no avail. I get Fatal error: Call to undefined method Models\Database::setTable()
What I'm after is a model/controller that I can reuse for ANY dynamically-named table.
You could create a generic model and dynamically set the table name, like this:
namespace Models;
use \Illuminate\Database\Eloquent\Model;
class FormerUUIDTicket extends Model {
protected $table = 'some_table';
protected $fillable = [table columns here];
}
class SomeController
{
public function someAction()
{
$uuid = $_POST['uuid_field']; //some uuid, the table name
$model = new FormerUUIDTicket;
$model->setTable($uuid);
return $model->get(); //do anything using eloquent with proper table
}
}
Make sure that you always set the table name before use, or it will fail. Don't use static function either, for the same reason.

Zend DbTable get rows from referenced table from other module

I am currently working an a Zend framework 1.12 based project. I use different modules to keep things separated as good as possible. My data is stored in a mysql database so I set up some db table models inside my project. The relation between the tables should be handled by Zend frameworks Zend_Db_Table Relationships. I added the necessary code to my classes:
class User_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
protected $_name = 'users';
protected $_primary = 'user_id';
protected $_dependentTables = array('Diagnostics_Model_DbTable_Diagnostics');
}
User_Model_DbTable_Users is the parent class and is defined inside the Users module. Diagnostics_Model_DbTable_Diagnostics is the referenced class and is defined inside the Diagnostics module.
class Diagnostics_Model_DbTable_Diagnostics extends Zend_Db_Table_Abstract
{
protected $_name = 'diagnostics';
protected $_primary = 'diagnostic_id';
protected $_referenceMap = array(
'User' => array(
'columns' => array('diagnostic_user'),
'refTableClass' => 'User_Model_DbTable_Users',
'refColumns' => array('user_id')
)
);
}
When I now try to load the referenced Diagnostics for a User row using
$row->findDiagnostics_Model_DbTable_Diagnostics();
I get an error:
File "Diagnostics\Model\DbTable\Diagnostics.php" does not exist or class "Diagnostics_Model_DbTable_Diagnostics" was not found in the
file
When I move the class Diagnostics_Model_DbTable_Diagnostics into the Users module and rename it correspondingly everthing works fine. So it seems to me as if it has something to do with classes beeing defined in different modules. None of the articles I have found during my researches could give me an answer to this.
Maybe I am missing something in the main Bootstrap.php or the application.ini.
You will need to bootstrap the module. Good info: http://akrabat.com/zend-framework/bootstrapping-modules-in-zf-1-8/
I use a simple class as below:
class Diagnostics_Bootstrap extends Zend_Application_Module_Bootstrap {
...
}
Don't bootstrap modules you don't need, I suggest reading http://www.mwop.net/blog/234-Module-Bootstraps-in-Zend-Framework-Dos-and-Donts.html

Zend Db Table Abstract Manipulate select()

is there any chance to set a where statement on any select() request regarding a Zend Db Table Abstract Object?
Example:
We have 2 roles, 1 role 'admin' which is allowed to see all products and 1 role 'supplier' which is allowed to see only their own products.
I don't want to check the role and set the where statement for the Zend Db Table Abstract Object in every ActionController. Is there any chance to do this in the Zend Db Table Abstract?
class ProductsModel extends Zend_Db_Table_Abstract
{
protected $_name = 'artikel';
protected $_primary = 'ID';
protected $_where = ('supplier = ?', $this->_auth->Role ); # SOMETHING LIKE THAT ??
}
Thanks!
M.
There are two definitions in ZF: Model and Table. You should not substitute them. The model describes abstract layer between Controller and Table. The model may work with Table by means of Mapper where you can implement all business logic (where clauses, order, limit and so on).
It all are included into standart ZF example template.

The M of MVC (ZF)

I don't get it how it really works.
I have a database table user and a model User:
<?php
class User extends Zend_Db_Table_Abstract {
protected $_name = 'users';
}
And in the controller I call it: $user = new User()
But how do I get for example all users or a user with the id: 1?
Zend_Db_Table implements the Table Gateway pattern and the associated Zend_Db_Table_Row implements the Row Data Gateway pattern.
This means that as the table class represents your database table, it makes more sense to use a plural class name. Similarly, a singular class name should be used for the row class.
Hence you end up with something like this:
class Model_Users extends Zend_Db_Table_Abstract
{
protected $_name = 'users'; // database table name
protected $_rowClass = 'Model_User'; // row class name
public function fetchAllInLastNameOrder()
{
return $this->fetchAll(null, array('last_name', 'first_name'));
}
public function fetchUserById($id)
{
return $this->_fetchRow('id = '. (int)$id);
}
}
class Model_User extends Zend_Db_Table_Row_Abstract
{
public function getFullName()
{
return trim($this->title . ' '
. $this->first_name . ' '
. $this->last_name);
}
}
The point of creating your own classes is that you can add your own methods that your controllers and views can then use. You should never use the Zend_Db_Table methods directly other than in your model classes. This is because this model design is tightly coupled to the database implentation. Over time, you may find that this isn't flexible enough and want to use a different system. If you have ensured that the rest of your application only ever accesses methods created in Model_Users and Model_User then you should be able to reimplement your model without breaking the rest of your app...
For larger applications and ones with complex business logic, it is rare for a model to be a simple wrapper over a single database table. For better flexibility and maintainability, you can consider creating models which are simple classes and then using a mapper class that maps from the model to the database. This is explored by Matthew Weier O'Phinney in his talk Architecting Your Models, which I highly recommend looking at.
Also, for ideas on how to use the model from within the controller, the Quick Start or my tutorial are good starting points.
Are you looking for $user->find()?
Also, Zend_Db_Table != Model. You can read more about the M of MVC here:
Model Infrastructure
Zend Framework: Surviving the Deep End
Writing Robust PHP Backends with Zend Framework
Try creating a static method in your User class that returns an array of all users.

Categories