Location: PHPKode > projects > LDAPted > ldapted/includes/Schema.php
<?
/***************************************************************************
 *
 *                                  Schema.php
 *                              -------------------
 *
 *   begin                : Friday, Jul 5, 2002
 *   copyright            : (C) 2002 The Kabramps Team
 *   email                : hide@address.com,
 *                          hide@address.com
 *
 *
 *
 ***************************************************************************/

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *   
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 *
 *   See the GNU General Public License for more details.
 *   (http://www.gnu.org/licenses/gpl.html)
 *
 ***************************************************************************/

/***************************************************************************
 *	
 *   Schema.php was create in conjunction with ldap.inc - version 1.1 
 *   written by Eric Kilfoil hide@address.com
 *
 *   Thanks to the author of the ldap.inc class who can be reached at hide@address.com
 *
 ***************************************************************************/

class Schema {

  var $error = ""; // Any error messages to be returned can be put here
  var $objectClasses = array(); // Information read from slapd.oc.conf
  var $attributeTypes = array();
  var $attributeNames = array();
  var $sup = array();
  var $connection;
  
  function Schema($connection) {
    $this->connection=$connection;
  }

  function readConfiguration() {
    $objectfilter="(objectClass=*)";
    $search = ldap_read($this->connection, "cn=subschema", $objectfilter,array("objectClasses","attributeTypes"));
    if ($search) {
      $objects = array();
      if (ldap_count_entries($this->connection, $search) > 0) {
	for ($object=ldap_first_entry($this->connection,$search);$object;$object=ldap_next_entry($this->connection,$object)) {
	  $attribut = ldap_get_attributes($this->connection,$object);
	  // READ and EVALUATE attributeTypes
	  $attributes = ldap_get_values($this->connection,$object,"attributeTypes");
	  for ($i=0;$i<count($attributes);$i++) {
	    $line = split(" ", $attributes[$i]);
	    $open=0;
	    $n=0;
	    for ($j=0;$j<count($line);$j++) {
	      switch ($line[$j]) {
	      case 'NAME':
		$type="name";
		$n=0;
		break;
	      case 'EQUALITY':
		$type="match";
		break;
	      case '(':
		if ($open > -1) $open++;
		else echo "Error parsing '('<br>";
		break;
	      case ')':
		if ($open > 0) {
		  $open--;
		  $type=null;
		} else echo "Error parsing ')'<br>";
		break;
	      default:
		switch ($type) {
		case 'name':
		  if ( $n == 0 ) {
		    $alias = substr(strtolower($line[$j]),1,-1);
		  } 
		  $this->attributeNames[substr(strtolower($line[$j]),1,-1)]=$alias;
		  //echo "Attributename: '".$line[$j]."' ".$n." '".$alias."'<br>";
		  if ( $open > 1 ) {
		    $n++;
		  }
		  break;
		case 'match':
		  $this->attributeTypes[$alias]=strtolower($line[$j]);
		  //echo "Attributetype ".$alias." ".$this->attributeTypes[$alias]."<br>";
		  break;
		}
		if ( $open == 1 ) $type = null;
	      }
	      //echo $attributes[$i]."<br>";
	    }
	  }

	  // READ and EVALUATE objectClasses
	  $value = ldap_get_values($this->connection,$object,"objectClasses");
	  for ( $i=0; $i<count($value);$i++) {
	    //echo $value[$i]."<br>";
	    $line = split(" ", $value[$i]);
	    $open=0;
	    $n=0;
	    $attribute=null;
	    $type=null;
	    for ($j=0;$j<count($line);$j++) {
	      switch ($line[$j]) {
	      case 'NAME':
		$type="name";
		break;
	      case 'MAY':
		$type="may";
		$n=0;
		break;
	      case 'MUST':
		$type="must";
		$n=0;
		break;
	      case 'SUP':
		$type="sup";
		break;
	      case '(':
		if ($open > -1) $open++;
		else echo "Error parsing '('<br>";
		break;
	      case ')':
		if ($open > 0) {
		  $open--;
		  $type = null;
		} else echo "Error parsing ')'<br>";
		break;
	      case '$':
		if ($open == 2) { 
		  $n++;
		  //$attribute = $last;
		} else echo "Error parsing '$'<br>";
		break;
	      default:
		switch ($type) {
		case 'name':
		  //echo "Name: :".substr($line[$j],1,-1).":<br>"; //$attributes[$attribute]=strtolower($line[$j]); 
		  $attribute = strtolower(substr($line[$j],1,-1));
		  $this->sup[$attribute] = array();
		  //echo $attribute."<br>";
		  break;
		case 'may':
		  //echo "may '".$attribute."' ".$n." '".$line[$j]."'<br>";
		  $this->objectClasses[$attribute]['allows'][$n]=strtolower($line[$j]);
		  break;
		case 'must':
		  //echo "must '".$attribute."' ".$n." '".$line[$j]."'<br>";
		  $this->objectClasses[$attribute]['requires'][$n]=strtolower($line[$j]);
		  break;
		case 'sup':
		  $this->sup[$attribute][] = strtolower($line[$j]);
		  //echo "OC: ".$attribute." sup: ".$this->sup[$attribute][count($this->sup[$attribute])-1]."<br>";
		  
		}
		if ( $open == 1 ) $type = null;
	      }
	    }
	  }
	}
      }
    }
  }
		
  function getObjectClasses() {
    if (count($this->objectClasses) == 0)
      $this->readConfiguration();
    $ocs = array();
    for ($ctr = 0, reset($this->objectClasses); $OCName = key($this->objectClasses); next($this->objectClasses), $ctr++) {
      $ocs[$ctr] = $OCName;
    }
    return($ocs);
  }
  
  function isObjectClass($ocname) {
    $ocname = strtolower($ocname);
    
    if (count($this->objectClasses) == 0)
      $this->readConfiguration();
    
    if (is_array($this->objectClasses[$ocname]))
      return(1);
    return(0);
  }


  function getAllows($ocname) {
    $ocname = strtolower($ocname);
    
    if (count($this->objectClasses) == 0)
      $this->readConfiguration();
    
    if (! $this->isObjectClass($ocname))
      return(array());
    
    $allows = array();
    $allows = $this->objectClasses[$ocname]["allows"];
    for ( $i=0; $i<count($this->sup[$ocname]); $i++ ) {
      $tmp=$this->getAllows($this->sup[$ocname][$i]);
      for ( $j=0; $j<count($tmp); $j++) {
	if ( $tmp[$j] != "" ) {
	  if ( ( count($allows) == 0 ) || ( ! in_array($tmp[$j],$allows) ) ) $allows[] = $tmp[$j];
	}
      }
    }
    return($allows);
  }

  function getRequires($ocname) {
    $ocname = strtolower($ocname);
    
    if (count($this->objectClasses) == 0)
      $this->readConfiguration();
    
    if (! $this->isObjectClass($ocname))
      return(array());
    
    $requires = array();
    $requires = $this->objectClasses[$ocname]["requires"];
    for ( $i=0; $i<count($this->sup[$ocname]); $i++ ) {
      if ($this->sup[$ocname][$i] != 'top') { // don't wanna have the objectclass attribute as a required field
	                                      // just make trouble
	$tmp=$this->getRequires($this->sup[$ocname][$i]);
	for ( $j=0; $j<count($tmp); $j++) {
	  if ( $tmp[$j] != "" ) {
	    if ( ( count($requires) == 0 ) || ( ! in_array($tmp[$j],$requires) ) ) $requires[] = $tmp[$j];
	  }
	}
      } 
    }
    // uncomment it to see how often the method is called
    /*
    echo "<br>".$ocname.":<br>";
    for ( $j = 0; $j < count($requires); $j++) {
      echo $requires[$j]."<br>";
    }
    */
    return($requires);
  }

  function isAllowed($ocname, $allowed) {
    $ocname = strtolower($ocname);
    $allowed = strtolower($allowed);
    
    if (count($this->objectClasses) == 0)
      $this->readConfiguration();
    
    if (! $this->isObjectClass($ocname))
      return(0);
    
    for ($ctr = 0; $ctr < count($this->objectClasses[$ocname]["allows"]); $ctr++)
      if (strcasecmp($this->objectClasses[$ocname]["allows"][$ctr], $allowed) == 0)
	return(1);
    
    return(0);
  }

  function isRequired($ocname, $required)	{
    $ocname = strtolower($ocname);
    $required = strtolower($required);
    
    if (count($this->objectClasses) == 0)
      $this->readConfiguration();
    
    if (! $this->isObjectClass($ocname))
      return(0);
    
    for ($ctr = 0; $ctr < count($this->objectClasses[$ocname]["requires"]); $ctr++)
      if (strcasecmp($this->objectClasses[$ocname]["requires"][$ctr], $required) == 0)
	return(1);

    return(0);
  }

  function getAttributeName($attribute) {
    if ( count($this->attributeNames) == 0 )
      $this->readConfiguration();
    return $this->attributeNames[strtolower($attribute)];
  }

  function getAttributeType($attribute) {
    if ( count($this->attributeTypes) == 0 )
      $this->readConfiguration();
    return $this->attributeTypes[$attribute];
  }
}
?>
Return current item: LDAPted