From 0ee23bf06e781a43d26d0a22e8c7f0690f17c5d1 Mon Sep 17 00:00:00 2001 From: Deon George Date: Fri, 7 Feb 2014 23:34:37 +1100 Subject: [PATCH] Fixes for ORM --- classes/Kohana/Database/LDAP.php | 2 +- classes/Kohana/Database/LDAP/Search.php | 6 +- classes/Kohana/ORM/LDAP.php | 129 ++++++++++++++++++++++++ classes/Model/LDAP.php | 11 ++ 4 files changed, 145 insertions(+), 3 deletions(-) diff --git a/classes/Kohana/Database/LDAP.php b/classes/Kohana/Database/LDAP.php index b399063..99b437d 100644 --- a/classes/Kohana/Database/LDAP.php +++ b/classes/Kohana/Database/LDAP.php @@ -183,7 +183,7 @@ abstract class Kohana_Database_LDAP extends Kohana_LDAP { foreach ($u as $dn => $leaf) if ($this->_bind($dn,$pass)) - return $this; + return ORM::factory('LDAP',$dn); // We didnt find an AUTH DN to bind with return FALSE; diff --git a/classes/Kohana/Database/LDAP/Search.php b/classes/Kohana/Database/LDAP/Search.php index 0ed99d0..f2a3ef8 100644 --- a/classes/Kohana/Database/LDAP/Search.php +++ b/classes/Kohana/Database/LDAP/Search.php @@ -212,6 +212,8 @@ abstract class Kohana_Database_LDAP_Search { $this->_filter = $this->_build(); // Validation that we are connected, no point contining if we are not. + $this->_db->connect(); + if (! $this->_db->connection()) throw HTTP_Exception::factory(501,'Cant run a search without a connection (:type,:filter)',array(':type'=>$this->_db,':filter'=>$this->_filter)); @@ -247,8 +249,8 @@ abstract class Kohana_Database_LDAP_Search { } } catch (Exception $e) { - throw HTTP_Exception::factory(501,'Error running a query (SCOPE::scope,TYPE::type,FILTER::filter,ATTRS::attrs) [:error]', - array(':scope'=>$this->_scope,':type'=>$this->_db,':filter'=>$this->_filter,':attrs'=>join('|',$this->_attrs),':error'=>$e->getMessage())); + throw HTTP_Exception::factory(501,'Error running a query (SCOPE::scope,BASE::base,TYPE::type,FILTER::filter,ATTRS::attrs) [:error]', + array(':base'=>$base,':scope'=>$this->_scope,':type'=>$this->_db,':filter'=>$this->_filter,':attrs'=>join('|',$this->_attrs),':error'=>$e->getMessage())); } $result[$base] = new Database_LDAP_Result(array('l'=>$this->_db->connection(),'r'=>$search),array('b'=>$base,'s'=>$this->_scope,'f'=>$this->_filter),$as_object,$object_params); diff --git a/classes/Kohana/ORM/LDAP.php b/classes/Kohana/ORM/LDAP.php index f732df3..25cd580 100644 --- a/classes/Kohana/ORM/LDAP.php +++ b/classes/Kohana/ORM/LDAP.php @@ -13,6 +13,7 @@ abstract class Kohana_ORM_LDAP extends ORM { protected $_disable_wild_select = TRUE; protected $_disable_join_table_name = TRUE; protected $_primary_key = 'dn'; + protected $_sub_items = array(); public function __construct($id = NULL) { // We'll process our $id @@ -89,5 +90,133 @@ abstract class Kohana_ORM_LDAP extends ORM { return $this; } + + /** + * Handles getting of column + * We override Kohana's get() to allow for LDAP symantics. + * + * @param string $column Column name + * @throws Kohana_Exception + * @return mixed + */ + public function get($column) + { + if (array_key_exists($column, $this->_object)) + { + return (in_array($column, $this->_serialize_columns)) + ? $this->_unserialize_value($this->_object[$column]) + : $this->_object[$column]; + } + elseif (isset($this->_related[$column])) + { + // Return related model that has already been fetched + return $this->_related[$column]; + } + elseif (isset($this->_belongs_to[$column])) + { + $model = $this->_related($column); + + // Use this model's column and foreign model's primary key + $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$model->_primary_key; + $val = $this->_object[$this->_belongs_to[$column]['foreign_key']]; + + // Make sure we don't run WHERE "AUTO_INCREMENT column" = NULL queries. This would + // return the last inserted record instead of an empty result. + // See: http://mysql.localhost.net.ar/doc/refman/5.1/en/server-session-variables.html#sysvar_sql_auto_is_null + if ($val !== NULL) + { + $model->where($col, '=', $val)->find(); + } + + return $this->_related[$column] = $model; + } + elseif (isset($this->_has_one[$column])) + { + $model = $this->_related($column); + + if (! is_array($this->_has_one[$column]['foreign_key'])) + { + // Use this model's primary key value and foreign model's column + $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$this->_has_one[$column]['foreign_key']; + $val = $this->_object[$this->_has_one[$column]['far_key']]; + $val = array_pop($val); + } + else + { + foreach ($this->_has_one[$column]['foreign_key'] as $fk) + { + // Simple has_many relationship, search where target model's foreign key is this model's primary key + $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$fk; + $val = $this->_object[$fk]; + + $model = $model->where($col, '=', $val); + } + } + + if ($col = 'dn' AND $val) + $model->base($val)->find(); + else + $model->where($col, '=', $val)->find(); + + return $this->_related[$column] = $model; + } + elseif (isset($this->_has_many[$column])) + { + $model = ORM::factory($this->_has_many[$column]['model']); + + if (! is_array($this->_has_many[$column]['foreign_key'])) + { + if (isset($this->_has_many[$column]['through'])) + { + // Grab has_many "through" relationship table + $through = $this->_has_many[$column]['through']; + + // Join on through model's target foreign key (far_key) and target model's primary key + $join_col1 = ($this->_disable_join_table_name ? '' : $through.'.').$this->_has_many[$column]['far_key']; + $join_col2 = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$model->_primary_key; + + $model->join($through)->on($join_col1, '=', $join_col2) + ->on(($this->_disable_join_table_name ? '' : $through.'.').'site_id', '=', ($this->_disable_join_table_name ? '' : $model->_object_name.'.').'site_id'); + + // Through table's source foreign key (foreign_key) should be this model's primary key + $col = ($this->_disable_join_table_name ? '' : $through.'.').$this->_has_many[$column]['foreign_key']; + $val = $this->pk(); + } + else + { + // Simple has_many relationship, search where target model's foreign key is this model's primary key + $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$this->_has_many[$column]['foreign_key']; + $val = $this->_object[$this->_has_many[$column]['far_key']]; + } + + return $model->where($col, '=', $val); + } + else + { + foreach ($this->_has_many[$column]['foreign_key'] as $mk => $fk) + { + if (isset($this->_has_many[$column]['through'])) + { + throw new Kohana_Exception('This code hasnt been written yet!'); + } + else + { + // Simple has_many relationship, search where target model's foreign key is this model's primary key + $col = ($this->_disable_join_table_name ? '' : $model->_object_name.'.').$fk; + $val = $this->_object[$mk]; + } + + $model = $model->where($col, '=', $val); + } + + return $model; + } + } + else + { + throw new Kohana_Exception('The :property property does not exist in the :class class', + array(':property' => $column, ':class' => get_class($this))); + } + } } ?> diff --git a/classes/Model/LDAP.php b/classes/Model/LDAP.php index 3e64ff4..c40638b 100644 --- a/classes/Model/LDAP.php +++ b/classes/Model/LDAP.php @@ -10,5 +10,16 @@ * @license http://dev.phpldapadmin.org/license.html */ class Model_LDAP extends ORM_LDAP { + public $_reload_on_wakeup = FALSE; + + protected $_has_one = array( + 'bp_manager'=>array('model'=>'LDAP','foreign_key'=>'dn','far_key'=>'manager'), + 'tl_manager'=>array('model'=>'LDAP','foreign_key'=>'dn','far_key'=>'glteamlead'), + ); + + // Unused - by required for page rendering for admin menu items + public function isAdmin() { + return FALSE; + } } ?>