This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
lnldap/classes/Kohana/ORM/LDAP.php
2015-01-09 13:58:11 +11:00

261 lines
7.5 KiB
PHP

<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* Kohana ORM LDAP Extension
*
* @package Kohana/ORM
* @author Deon George
* @copyright (c) 2013 phpLDAPadmin Development Team
* @license http://dev.phpldapadmin.org/license.html
*/
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();
// protected $_db_group = 'default';
public function __construct($id = NULL) {
// We'll process our $id
parent::__construct(NULL);
if (empty($this->_cast_data) AND $id) {
if (is_array($id)) {
// Passing an array of column => values
foreach ($id as $column => $value)
$this->where($column, '=', $value);
$this->limit(1);
$this->scope('sub');
$this->find();
} else {
// Passing the primary key
$this->base($id)->find();
}
}
}
public function __get($column) {
$x = parent::__get($column);
return (! is_object($x) AND is_object(LDAP::factory('schema')->schema()->attribute($column)) AND LDAP::factory('schema')->schema()->attribute($column)->getIsSingleValue()) ? $x[0] : $x;
}
/**
* Initializes the Database Builder to given query type
*
* @param integer $type Type of Database query
* @return ORM
*/
protected function _build($type) {
// Construct new builder object based on query type
switch ($type) {
case Database::SELECT:
$this->_db_builder = new Database_LDAP_Search($this->_db,NULL);
break;
default:
throw HTTP_Exception::factory(501,'Unknown type :type',array(':type'=>$type));
}
// Process pending database method calls
foreach ($this->_db_pending as $method) {
$name = $method['name'];
$args = $method['args'];
$this->_db_applied[$name] = $name;
call_user_func_array(array($this->_db_builder, $name), $args);
}
return $this;
}
protected function _initialize() {
parent::_initialize();
// Check if this model has already been initialized
if ($init = Arr::get(ORM::$_init_cache, $this->_object_name, FALSE)) {
// We need to make sure that our _db is an LDAP DB source.
if ( ! is_object($this->_db) OR ! $this->_db instanceof LDAP) {
// Get database instance
$init['_db'] = LDAP::factory('user',NULL,$this->_db_group);
}
ORM::$_init_cache[$this->_object_name] = $init;
$this->_db = $init['_db'];
}
}
// During authentication, is this user activated
// @todo This should probably query a group membership, etc
public function activated() {
return TRUE;
}
public function base($value) {
// Add pending database call which is executed after query type is determined
$this->_db_pending[] = array(
'name' => 'base',
'args' => array(array($value)),
);
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
{
// The item doesnt exist.
return NULL;
}
}
public function result_load_values(array $values) {
$this->clear();
$this->_load_values($values);
return $this;
}
// @todo Taken into account the schema definition
public function resolve($key) {
eval("\$x = \$this->get_first('$key');");
return $x;
}
public function scope($scope) {
// Add pending database call which is executed after query type is determined
$this->_db_pending[] = array(
'name' => 'scope',
'args' => array($scope),
);
return $this;
}
}
?>