Jump to content

[ZF] zend_db_table and inheritance


smoking81

Recommended Posts

Hello everybody! I am totally new to Zend Framework and I'm trying to develop an application by means of it following the book "ZF 1.8 - Web Application Development"..

My first problem is connected to the use of zend_db_table.. I am so confused that I have even problems in formulating a question about my problem..

 

In brief, I have a multilanguage application so in the DB i've created 2 tables such as:

 

product with generic fields such as: productId, insertDate, weight etc

product_locale with fields specific to a certain language such as productId, languageId, name, description, ident (SE friendly string) etc

(there is of course also a table language in the DB)

 

Now, in my model I'd like to have just one class Product which should have methods such as getProductById, getProductByIdent, etc.. What I cannot understand is how can I achieve such a result. As far as I understand, every class which extends Zend_Db_Table is tightly coupled with a single DB table, so I have the feeling I am forced to create 2 distinct classes Product (with methods such as getProductById) and ProductLocale (with methods like getProductByIdent or getProductByID($id, $languageID), etc).. Is that right? How could I then allow ProductLocale to see also the fields stored in product (such as insertDate and weight)?

 

I hope you understood my problem and can help me! I am so frustrated...

 

Thanks soooo much!

Bye!

Link to post
Share on other sites

You would use the _referenceMap field for that.

 

class Product extends Zend_Db_Table {
  protected $_dependentTables = array('ProductLocale');
}

class ProductLocale extends Zend_Db_Table {
  protected $_referenceMap = array(
    'Product' => array(
      'columns' => 'productId',
      'refColumns' => 'id',
      'refTableClass' => 'Product'
    )
  );
}

 

For more information see http://framework.zend.com/manual/en/zend.db.table.relationships.html

Link to post
Share on other sites

hi ignace! Thank you so much for answering! In the meanwhile i've read the documentation and tried to do a few experiments but i am still confused.. At the moment, I'm working with categories rather than products (it's a bit easier): i have a structure like this (in the db):

 

table culture
-------------
cultureId - e.g. 1
locale - e.g. en_US
displayName -e.g. English
flagIcon - eg enUS_flag.jpg
isDefault - eg 1 (default locale)

table category
-----------------
categoryId - e.g. 1
parentId - e.g. 0

table category_locale
---------------------
categoryId - e.g. 1 (refers to category table)
cultureId - e.g. 1 (refers to culture table)
name - e.g. Books
description - e.g. A collection of our Books
ident - books (this is a unique string in DB)

 

I've 3 classes, Culture, Category and CategoryLocale. Their structure is more or less as follows:

class Category extends Zend_Db_Table_Abstract
{
    protected $_name = 'category';
    protected $_primary = 'categoryId';
    protected $_rowClass = 'Category_Item';
    protected $_dependentTables = array ('CategoryLocale');

   protected $_referenceMap = array(
        'SubCategory' => array(
            'columns' => 'parentId',
            'refTableClass' => 'Storefront_Resource_Category',
            'refColumns' => 'categoryId',
        )
    );
    ...
}

class CategoryLocale extends Zend_Db_Table_Abstract
{
    protected $_name = 'category_locale';
    protected $_primary = array('categoryId','cultureId');
    protected $_rowClass = 'CategoryLocale_Item';

    protected $_referenceMap = array(
    'Category' => array(
      'columns' => 'categoryId',
      'refColumns' => 'categoryId',
      'refTableClass' => 'Category'
    	),
    'Language' => array(
      'columns' => 'cultureId',
      'refColumns' => 'cultureId',
      'refTableClass' => 'Culture'
    	)
  	);
  
...
}

class Culture extends Zend_Db_Table_Abstract
{
protected $_name = 'culture';
protected $_primary = 'cultureId';
protected $_rowClass = 'Culture_Item';
protected $_dependentTables = array ('CategoryLocale');
...
}

 

 

In addition, I have a 4th class, Catalog, which contains attributes such as the chosen Culture ($_culture), etc. which is used by Controllers (as well as Action View Helper) to interact with other models... So in this Catalog class I want to have a public method getAllCategories() which will proxy a call to a method getAllCategoriesByLanguage($Culture) of Category..

 

My question is: how can I retrieve a RowSet containing all the relevant fields representing a category (categoryId, parentId, name, description, ident) using zend_db_table functionalities?

 

I am really blocked on this and hope somebody will help me (the doc didn't unfortunately)!

 

Thanks again!

Bye

Link to post
Share on other sites
class CultureDAO extends Zend_Db_Table_Abstract {
    protected $_rowsetClass = 'Cultures';
}

class Cultures extends Zend_Db_Table_Rowset_Abstract {
    protected $_rowClass = 'Culture';
}

class Culture extends Zend_Db_Table_Row_Abstract {
    protected $_id, $_name, $_description;
}

Link to post
Share on other sites

ignace, 1st of all, thanks again for your help! :)

Unfortunately, I am not sure to understand what you mean.. At the moment I have Culture, Category and CategoryLocale which extend Zend_Db_Table_Abstract and act as "catalogs".. Then I have Culture_item, Category_Item and CategoryLocale_item which indeed extend Zend_Db_Table_Row_Abstract and represent a single row in the DB..

 

I cannot understand what you advise me to do, and what is the problem in my design...  :'(

Link to post
Share on other sites

class CultureDAO extends Zend_Db_Table_Abstract {
    protected $_rowClass = 'Culture';
}

class Culture extends Zend_Db_Table_Row_Abstract {}

 

Should work I think. Also apparently you are not comfortable with object-design patterns. Here are a few resources:

 

http://martinfowler.com/eaaCatalog/tableDataGateway.html

http://martinfowler.com/eaaCatalog/rowDataGateway.html

http://martinfowler.com/eaaCatalog/valueObject.html

http://en.wikipedia.org/wiki/Data_Access_Object

Link to post
Share on other sites

class CultureDAO extends Zend_Db_Table_Abstract {
    protected $_rowsetClass = 'Cultures';
}

class Cultures extends Zend_Db_Table_Rowset_Abstract {
    protected $_rowClass = 'Culture';
}

class Culture extends Zend_Db_Table_Row_Abstract {
    protected $_id, $_name, $_description;
}

Hello ignace,

 

I am curious to know why one would want to extend the Zend_Db_Table_Row_Abstract and Zend_Db_Table_Rowset_Abstract classes when the 'standard' method (i.e. extending Zend_Db_Table_Abstract and using select/insert/update etc) of doing things handles everything automatically ?

Link to post
Share on other sites

Because in most cases you would want to tie in business rules. For example a user may only login when he verified his e-mail address.

 

if (!$user->hasVerifiedEmailAddress()) {//can't login, verify e-mail first

Link to post
Share on other sites

hello ignace!

I totally agree with your design suggestion, but there is a problem... I'd like to have an aggregation between my Category and categoryLocale objects (a category is nothing without its localized data such as the name) and after many researches i've understood that having a clean design for this situation in ZF is impossible.. Also if i set the relationships between Row classes as advised here http://framework.zend.com/manual/en/zend.db.table.relationships.html, i can get no advantage from that. In fact, as far as i understood, I am forced to build my objects using joins. For example, a getAllCategoriesByCulture($cultureId) method in my CategoryDAO *must* use Zend_Db_Select join() (which implies to set setIntegrityCheck(false)), so it is not possible to take any benefit from the Zend_Db Relationships among Row items.. I had a discussion in a IRC channel about this and two ZF experts told me that there are no alternatives to joins.. What do you think about this?

 

thanks, bye!

Link to post
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.