Created
July 21, 2011 21:18
-
-
Save pnomolos/1098232 to your computer and use it in GitHub Desktop.
LS DB ActiveRecord HABTM extension for conditional joins
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if (!class_exists('Db_ActiveRecord_habtm_ConditionalJoins')) { | |
class Db_ActiveRecord_habtm_ConditionalJoins extends Db_ActiveRecord { | |
public function get_relation_options($type, $name, &$has_primary_key, &$has_foreign_key) { | |
$backtrace = debug_backtrace(false); | |
$options = parent::get_relation_options($type, $name, $has_primary_key, $has_foreign_key); | |
// TODO: I am very aware that this is a massive hack. Still looking for a way around it. | |
if ( $backtrace[1]['function'] == 'formFieldGetOptions' ) { return $options; } | |
if ( $type == 'has_and_belongs_to_many' ) { | |
$settings = $this->has_and_belongs_to_many[$name]; | |
if ( isset( $settings['join_conditions'] ) || isset( $settings['join_fields'] ) ) { | |
$condition = ( isset( $settings['conditions'] ) ? ($settings['conditions']) . ' AND ' : null ); | |
$this->has_and_belongs_to_many[$name]['old_conditions'] = | |
( isset( $settings['conditions'] ) ? $settings['conditions'] : null ); | |
$join_conditions = isset( $settings['join_conditions'] ) ? $settings['join_conditions'] : ''; | |
if ( isset( $settings['join_fields'] ) ) { | |
if ( $join_conditions ) { | |
$join_conditions .= ' AND '; | |
} | |
$fields = array(); | |
foreach ( $settings['join_fields'] as $field_name => $value ) { | |
$fields[] = "{$field_name}='" . mysql_real_escape_string( $value ) . "'"; | |
} | |
$join_conditions .= '(' . join(' AND ', $fields) . ')'; | |
} | |
if ( $join_conditions ) { | |
$options['conditions'] = '(' . $condition . "({$join_conditions})" . ')'; | |
} | |
} | |
} | |
return $options; | |
} | |
protected function custom_relation_save() { | |
foreach ($this->changed_relations as $action => $relation) { | |
foreach ($relation as $name => $info) { | |
if ($info['type'] == 'has_and_belongs_to_many') { | |
// Most of the following code is taken from db_activerecord.php in apply_relations_changes() | |
$defaults = array( | |
'class_name' => Phpr_Inflector::classify($name) | |
); | |
if (is_array($info['relation'])) { | |
$options = array_merge($defaults, $info['relation']); | |
} else { | |
$options = array_merge($defaults, array('class_name' => Phpr_Inflector::classify($info['relation']))); | |
} | |
// We're only handling the polymorphic associations | |
if ( !isset( $options['join_fields'] ) ) { continue; } | |
// Create model | |
$object = new $options['class_name'](); | |
if (is_null($object)) { | |
throw new Phpr_SystemException('Class not found: '.$options['class_name']); | |
} | |
if (!isset($options['primary_key'])) { | |
$options['primary_key'] = Phpr_Inflector::foreign_key($this->table_name, $this->primary_key); | |
} | |
if (!isset($options['foreign_key'])) { | |
$options['foreign_key'] = Phpr_Inflector::foreign_key($object->table_name, $object->primary_key); | |
} | |
if (!isset($options['join_table'])) { | |
$options['join_table'] = $this->get_join_table_name($this->table_name, $object->table_name); | |
} | |
if ($action == 'bind') { | |
foreach ( $info['values'] as $value ) { | |
$fields_to_set = array( | |
$options['primary_key'] => $this->{$this->primary_key}, | |
$options['foreign_key'] => $value | |
); | |
// Merge the values if we're joining with additional fields | |
if ( isset( $options['join_fields'] ) ) { | |
$fields_to_set = array_merge( | |
$fields_to_set, | |
$options['join_fields'] | |
); | |
} | |
$this->sql_insert( | |
$options['join_table'], | |
$fields_to_set | |
); | |
} | |
} elseif ($action == 'unbind') { | |
$delete_statement = Db::where( | |
$options['primary_key'] . ' = ?', | |
$this->{$this->primary_key} | |
)->where( | |
$options['foreign_key'] . ' IN (?)', | |
array($info['values']) | |
); | |
// Make sure to add the additional fields | |
if ( isset( $options['join_fields'] ) ) { | |
foreach ( $options['join_fields'] as $field_name => $value ) { | |
$delete_statement->where( $field_name . '=?', array($value) ); | |
} | |
} | |
$this->sql_delete( | |
$options['join_table'], | |
$delete_statement | |
); | |
} | |
unset ( $this->changed_relations[$action] ); | |
} // 'has_and_belongs_to_many' | |
} | |
} // foreach | |
} // custom_relation_save | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
public $has_and_belongs_to_many = array( | |
'add_on_order_status'=>array( | |
'class_name'=>'Shop_StatusTransition', | |
'primary_key'=>'psinventory_param_id', | |
'foreign_key' => 'shop_status_transition_id', | |
'join_table' => 'psinventory_params_shop_status_transitions', | |
'join_fields' => array( | |
'transition_flag' => 'active' | |
) | |
), | |
'remove_on_order_status'=>array( | |
'class_name'=>'Shop_StatusTransition', | |
'primary_key'=>'psinventory_param_id', | |
'foreign_key' => 'shop_status_transition_id', | |
'join_table' => 'psinventory_params_shop_status_transitions', | |
'join_fields' => array( | |
'transition_flag' => 'reclaim' | |
) | |
), | |
'update_at_order_status'=>array( | |
'class_name'=>'Shop_OrderStatus', | |
'primary_key'=>'psinventory_param_id', | |
'foreign_key' => 'shop_status_transition_id', | |
'join_table' => 'psinventory_params_shop_status_transitions', | |
'join_fields' => array( | |
'transition_flag' => 'order_status' | |
) | |
) | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment