2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4 // +----------------------------------------------------------------------+
5 // | Akelos Framework - http://www.akelos.org |
6 // +----------------------------------------------------------------------+
7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez |
8 // | Released under the GNU Lesser General Public License, see LICENSE.txt|
9 // +----------------------------------------------------------------------+
12 * @package ActiveRecord
13 * @subpackage Associations
14 * @author Bermi Ferrer <bermi a.t akelos c.om>
15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
19 require_once(AK_LIB_DIR
.DS
.'AkActiveRecord'.DS
.'AkObserver.php');
21 class AkAssociation
extends AkObserver
24 var $options = array();
25 var $models = array();
27 function AkAssociation(&$Owner)
29 $this->Owner
=& $Owner;
30 $this->observe($this->Owner
);
31 $this->_setAssociationAccesorAliasReferences();
34 function initializeAssociated($options)
36 $options = is_string($options) ?
array_map('trim',array_diff(explode(',',$options.','), array(''))) : $options;
37 if(is_array($options)){
38 foreach ($options as $k=>$option){
40 $association_id = $option;
41 $association_options = array();
44 $association_options = $option;
46 if($association_id = $this->setAssociationId($association_id)){
47 $this->addAssociated($association_id, $association_options);
53 function setAssociationId($association_id)
55 $association_id = strtolower(AkInflector
::underscore($association_id));
56 if(isset($this->Owner
->$association_id)){
57 trigger_error(Ak
::t('Could not load %association_id on %model_name because "%model_name->%association_id" attribute '.
58 'is already defided and can\' be used as an association placeholder',
59 array('%model_name'=>$this->Owner
->getModelName(),'%association_id'=>$association_id)),
63 return $association_id;
67 function _setAssociationAccesorAliasReferences()
69 $underscored_alias = AkInflector
::underscore($this->getType());
70 if(!isset($this->Owner
->$underscored_alias)){
71 $this->Owner
->$underscored_alias =& $this;
75 function setOptions($association_id, $options)
77 $this->options
[$association_id] = $options;
80 function getOptions($association_id)
82 return $this->options
[$association_id];
85 function getOption($association_id, $option_name)
87 return isset($this->options
[$association_id][$option_name]) ?
$this->options
[$association_id][$option_name] : false;
90 function &addModel($association_id, &$associated_model)
92 $this->models
[$association_id] =& $associated_model;
93 return $this->models
[$association_id];
97 function &getModel($association_id)
99 return $this->models
[$association_id];
102 function &getModels()
104 return $this->models
;
107 function getAssociatedIds()
109 return array_keys($this->options
);
113 function &_build($association_id, &$AssociatedObject, $reference_associated = true)
115 if($reference_associated){
116 $this->Owner
->$association_id =& $AssociatedObject;
118 $this->Owner
->$association_id = $AssociatedObject;
120 $this->Owner
->$association_id->_AssociationHandler
=& $this;
121 $this->Owner
->$association_id->_associatedAs
= $this->getType();
122 $this->Owner
->$association_id->_associationId
= $association_id;
123 $this->Owner
->_associations
[$association_id] =& $this->Owner
->$association_id;
124 return $this->Owner
->$association_id;
127 function setAssociatedId($association_id, $associated_id)
129 $this->Owner
->_associationIds
[$association_id] = $associated_id;
130 $this->asssociated_ids
[$association_id] = $associated_id;
133 function &loadAssociated($association_id)
135 if (!$this->Owner
->isNewRecord()){
136 if(empty($this->Owner
->$association_id->_loaded
)){
137 if($Associated =& $this->findAssociated($association_id)){
138 $Associated->_loaded
= true;
139 $this->_build($association_id, $Associated, false);
144 return $this->Owner
->$association_id;
148 * Class interfaces. All Association objects must implement the following methods
151 function addAssociated($association_id, $options = array())
153 trigger_error(__FUNCTION__
.' must be defined into your specific association handler');
158 trigger_error(__FUNCTION__
.' must be defined into your specific association handler');
161 function getAssociatedFinderSqlOptions()
163 trigger_error(__FUNCTION__
.' must be defined into your specific association handler');
166 function isOwnerAnActiveRecord()
168 return $this->__activeRecordObject
;
172 function _hasTablePrefix($association_id)
174 return isset($this->$association_id->_associationTablePrefixes
[$this->$association_id->_tableName
]);
177 function _saveLoadedHandler($association_id, $associated)
179 $this->Owner
->_association_handler_copies
[$association_id] = $associated;
182 function _getLoadedHandler($association_id)
184 return $this->Owner
->_association_handler_copies
[$association_id];
188 * Recurses through $owner and its superclasses until it finds the class which defines the association to the given $associatedModel
190 function _findOwnerTypeForAssociation(&$AssociatedModel, $Owner) {
191 if (!is_object($Owner)) {
194 $owner_type = AkInflector
::underscore($Owner->getType());
195 if (isset($AssociatedModel->$owner_type)) {
198 return $this->_findOwnerTypeForAssociation($AssociatedModel, get_parent_class($Owner));