\version 2.00
\date 24.07.2003
This is the base class for all plugins. It can be used standalone or
can be included by the tabs class. All management should be done
within this class. Extend your plugins from this class.
*/
class plugin
{
/*!
\brief Reference to parent object
This variable is used when the plugin is included in tabs
and keeps reference to the tab class. Communication to other
tabs is possible by 'name'. So the 'fax' plugin can ask the
'userinfo' plugin for the fax number.
\sa tab
*/
var $parent= NULL;
/*!
\brief Configuration container
Access to global configuration
*/
var $config= NULL;
/*!
\brief Mark plugin as account
Defines whether this plugin is defined as an account or not.
This has consequences for the plugin to be saved from tab
mode. If it is set to 'FALSE' the tab will call the delete
function, else the save function. Should be set to 'TRUE' if
the construtor detects a valid LDAP object.
\sa plugin::plugin()
*/
var $is_account= FALSE;
var $initially_was_account= FALSE;
/*!
\brief Mark plugin as template
Defines whether we are creating a template or a normal object.
Has conseqences on the way execute() shows the formular and how
save() puts the data to LDAP.
\sa plugin::save() plugin::execute()
*/
var $is_template= FALSE;
var $ignore_account= FALSE;
var $is_modified= FALSE;
/*!
\brief Represent temporary LDAP data
This is only used internally.
*/
var $attrs= array();
/* Keep set of conflicting plugins */
var $conflicts= array();
/* Save unit tags */
var $gosaUnitTag= "";
var $skipTagging= FALSE;
/*!
\brief Used standard values
dn
*/
var $dn= "";
var $uid= "";
var $sn= "";
var $givenName= "";
var $acl= "*none*";
var $dialog= FALSE;
var $snapDialog = NULL;
/* attribute list for save action */
var $attributes= array();
var $objectclasses= array();
var $is_new= TRUE;
var $saved_attributes= array();
var $acl_base= "";
var $acl_category= "";
var $read_only = FALSE; // Used when the entry is opened as "readonly" due to locks.
/* This can be set to render the tabulators in another stylesheet */
var $pl_notify= FALSE;
/* Object entry CSN */
var $entryCSN = "";
var $CSN_check_active = FALSE;
/* This variable indicates that this class can handle multiple dns at once. */
var $multiple_support = FALSE;
var $multi_attrs = array();
var $multi_attrs_all = array();
/* This aviable indicates, that we are currently in multiple edit handle */
var $multiple_support_active = FALSE;
var $selected_edit_values = array();
var $multi_boxes = array();
/*! \brief plugin constructor
If 'dn' is set, the node loads the given 'dn' from LDAP
\param dn Distinguished name to initialize plugin from
\sa plugin()
*/
function plugin (&$config, $dn= NULL, $parent= NULL)
{
/* Configuration is fine, allways */
$this->config= &$config;
$this->dn= $dn;
/* Handle new accounts, don't read information from LDAP */
if ($dn == "new"){
return;
}
/* Check if this entry was opened in read only mode */
if(isset($_POST['open_readonly'])){
if(session::global_is_set("LOCK_CACHE")){
$cache = &session::get("LOCK_CACHE");
if(isset($cache['READ_ONLY'][$this->dn])){
$this->read_only = TRUE;
}
}
}
/* Save current dn as acl_base */
$this->acl_base= $dn;
/* Get LDAP descriptor */
if ($dn !== NULL){
/* Load data to 'attrs' and save 'dn' */
if ($parent !== NULL){
$this->attrs= $parent->attrs;
} else {
$ldap= $this->config->get_ldap_link();
$ldap->cat ($dn);
$this->attrs= $ldap->fetch();
}
/* Copy needed attributes */
foreach ($this->attributes as $val){
$found= array_key_ics($val, $this->attrs);
if ($found != ""){
$this->$val= $found[0];
}
}
/* gosaUnitTag loading... */
if (isset($this->attrs['gosaUnitTag'][0])){
$this->gosaUnitTag= $this->attrs['gosaUnitTag'][0];
}
/* Set the template flag according to the existence of objectClass
gosaUserTemplate */
if (isset($this->attrs['objectClass'])){
if (in_array_ics ("gosaUserTemplate", $this->attrs['objectClass'])){
$this->is_template= TRUE;
@DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
"found", "Template check");
}
}
/* Is Account? */
$found= TRUE;
foreach ($this->objectclasses as $obj){
if (preg_match('/top/i', $obj)){
continue;
}
if (!isset($this->attrs['objectClass']) || !in_array_ics ($obj, $this->attrs['objectClass'])){
$found= FALSE;
break;
}
}
if ($found){
$this->is_account= TRUE;
@DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,
"found", "Object check");
}
/* Prepare saved attributes */
$this->saved_attributes= $this->attrs;
foreach ($this->saved_attributes as $index => $value){
if (is_numeric($index)){
unset($this->saved_attributes[$index]);
continue;
}
if (!in_array_ics($index, $this->attributes) && strcasecmp('objectClass', $index)){
unset($this->saved_attributes[$index]);
continue;
}
if (isset($this->saved_attributes[$index][0])){
if(!isset($this->saved_attributes[$index]["count"])){
$this->saved_attributes[$index]["count"] = count($this->saved_attributes[$index]);
}
if($this->saved_attributes[$index]["count"] == 1){
$tmp= $this->saved_attributes[$index][0];
unset($this->saved_attributes[$index]);
$this->saved_attributes[$index]= $tmp;
continue;
}
}
unset($this->saved_attributes["$index"]["count"]);
}
if(isset($this->attrs['gosaUnitTag'])){
$this->saved_attributes['gosaUnitTag'] = $this->attrs['gosaUnitTag'][0];
}
}
/* Save initial account state */
$this->initially_was_account= $this->is_account;
}
/*! \brief execute plugin
Generates the html output for this node
*/
function execute()
{
/* This one is empty currently. Fabian - please fill in the docu code */
session::global_set('current_class_for_help',get_class($this));
/* Reset Lock message POST/GET check array, to prevent perg_match errors*/
session::set('LOCK_VARS_TO_USE',array());
session::set('LOCK_VARS_USED',array());
}
/*! \brief execute plugin
Removes object from parent
*/
function remove_from_parent()
{
/* include global link_info */
$ldap= $this->config->get_ldap_link();
/* Get current objectClasses in order to add the required ones */
$ldap->cat($this->dn);
$tmp= $ldap->fetch ();
$oc= array();
if (isset($tmp['objectClass'])){
$oc= $tmp['objectClass'];
unset($oc['count']);
}
/* Remove objectClasses from entry */
$ldap->cd($this->dn);
$this->attrs= array();
$this->attrs['objectClass']= array_remove_entries_ics($this->objectclasses,$oc);
/* Unset attributes from entry */
foreach ($this->attributes as $val){
$this->attrs["$val"]= array();
}
/* Unset account info */
$this->is_account= FALSE;
/* Do not write in plugin base class, this must be done by
children, since there are normally additional attribs,
lists, etc. */
/*
$ldap->modify($this->attrs);
*/
}
/*! \brief Save HTML posted data to object
*/
function save_object()
{
/* Update entry CSN if it is empty. */
if(empty($this->entryCSN) && $this->CSN_check_active){
$this->entryCSN = getEntryCSN($this->dn);
}
/* Save values to object */
foreach ($this->attributes as $val){
if ($this->acl_is_writeable($val) && isset ($_POST["$val"])){
/* Check for modifications */
if (get_magic_quotes_gpc()) {
$data= stripcslashes($_POST["$val"]);
} else {
$data= $this->$val = $_POST["$val"];
}
if ($this->$val != $data){
$this->is_modified= TRUE;
}
/* Okay, how can I explain this fix ...
* In firefox, disabled option fields aren't selectable ... but in IE you can select these fileds.
* So IE posts these 'unselectable' option, with value = chr(194)
* chr(194) seems to be the in between the ...option> $val= $data;
}
}
}
/* Save data to LDAP, depending on is_account we save or delete */
function save()
{
/* include global link_info */
$ldap= $this->config->get_ldap_link();
/* Save all plugins */
$this->entryCSN = "";
/* Start with empty array */
$this->attrs= array();
/* Get current objectClasses in order to add the required ones */
$ldap->cat($this->dn);
$tmp= $ldap->fetch ();
$oc= array();
if (isset($tmp['objectClass'])){
$oc= $tmp["objectClass"];
$this->is_new= FALSE;
unset($oc['count']);
} else {
$this->is_new= TRUE;
}
/* Load (minimum) attributes, add missing ones */
$this->attrs['objectClass']= gosa_array_merge($oc,$this->objectclasses);
/* Copy standard attributes */
foreach ($this->attributes as $val){
if ($this->$val != ""){
$this->attrs["$val"]= $this->$val;
} elseif (!$this->is_new) {
$this->attrs["$val"]= array();
}
}
/* Handle tagging */
$this->tag_attrs($this->attrs);
}
function cleanup()
{
foreach ($this->attrs as $index => $value){
/* Convert arrays with one element to non arrays, if the saved
attributes are no array, too */
if (is_array($this->attrs[$index]) &&
count ($this->attrs[$index]) == 1 &&
isset($this->saved_attributes[$index]) &&
!is_array($this->saved_attributes[$index])){
$tmp= $this->attrs[$index][0];
$this->attrs[$index]= $tmp;
}
/* Remove emtpy arrays if they do not differ */
if (is_array($this->attrs[$index]) &&
count($this->attrs[$index]) == 0 &&
!isset($this->saved_attributes[$index])){
unset ($this->attrs[$index]);
continue;
}
/* Remove single attributes that do not differ */
if (!is_array($this->attrs[$index]) &&
isset($this->saved_attributes[$index]) &&
!is_array($this->saved_attributes[$index]) &&
$this->attrs[$index] == $this->saved_attributes[$index]){
unset ($this->attrs[$index]);
continue;
}
/* Remove arrays that do not differ */
if (is_array($this->attrs[$index]) &&
isset($this->saved_attributes[$index]) &&
is_array($this->saved_attributes[$index])){
if (!array_differs($this->attrs[$index],$this->saved_attributes[$index])){
unset ($this->attrs[$index]);
continue;
}
}
}
/* Update saved attributes and ensure that next cleanups will be successful too */
foreach($this->attrs as $name => $value){
$this->saved_attributes[$name] = $value;
}
}
/* Check formular input */
function check()
{
$message= array();
/* Skip if we've no config object */
if (!isset($this->config) || !is_object($this->config)){
return $message;
}
/* Find hooks entries for this class */
$command= $this->config->search(get_class($this), "CHECK", array('menu', 'tabs'));
if ($command != ""){
if (!check_command($command)){
$message[]= msgPool::cmdnotfound("CHECK", get_class($this));
} else {
/* Generate "ldif" for check hook */
$ldif= "dn: $this->dn\n";
/* ... objectClasses */
foreach ($this->objectclasses as $oc){
$ldif.= "objectClass: $oc\n";
}
/* ... attributes */
foreach ($this->attributes as $attr){
if ($this->$attr == ""){
continue;
}
if (is_array($this->$attr)){
foreach ($this->$attr as $val){
$ldif.= "$attr: $val\n";
}
} else {
$ldif.= "$attr: ".$this->$attr."\n";
}
}
/* Append empty line */
$ldif.= "\n";
/* Feed "ldif" into hook and retrieve result*/
$descriptorspec = array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w"));
$fh= proc_open($command, $descriptorspec, $pipes);
if (is_resource($fh)) {
fwrite ($pipes[0], $ldif);
fclose($pipes[0]);
$result= stream_get_contents($pipes[1]);
if ($result != ""){
$message[]= $result;
}
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($fh);
}
}
}
/* Check entryCSN */
if($this->CSN_check_active){
$current_csn = getEntryCSN($this->dn);
if($current_csn != $this->entryCSN && !empty($this->entryCSN) && !empty($current_csn)){
$this->entryCSN = $current_csn;
$message[] = _("The object has changed since opened in GOsa. All changes that may be done by others get lost if you save this entry!");
}
}
return ($message);
}
/* Adapt from template, using 'dn' */
function adapt_from_template($dn, $skip= array())
{
/* Include global link_info */
$ldap= $this->config->get_ldap_link();
/* Load requested 'dn' to 'attrs' */
$ldap->cat ($dn);
$this->attrs= $ldap->fetch();
/* Walk through attributes */
foreach ($this->attributes as $val){
/* Skip the ones in skip list */
if (in_array($val, $skip)){
continue;
}
if (isset($this->attrs["$val"][0])){
/* If attribute is set, replace dynamic parts:
%sn, %givenName and %uid. Fill these in our local variables. */
$value= $this->attrs["$val"][0];
foreach (array("sn", "givenName", "uid") as $repl){
if (preg_match("/%$repl/i", $value)){
$value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
}
}
$this->$val= $value;
}
}
/* Is Account? */
$found= TRUE;
foreach ($this->objectclasses as $obj){
if (preg_match('/top/i', $obj)){
continue;
}
if (!in_array_ics ($obj, $this->attrs['objectClass'])){
$found= FALSE;
break;
}
}
if ($found){
$this->is_account= TRUE;
}
}
/* Indicate whether a password change is needed or not */
function password_change_needed()
{
return FALSE;
}
/* Show header message for tab dialogs */
function show_enable_header($button_text, $text, $disabled= FALSE)
{
if (($disabled == TRUE) || (!$this->acl_is_createable())){
$state= "disabled";
} else {
$state= "";
}
$display= "
\n
$text
\n";
$display.= "
";
return($display);
}
/* Show header message for tab dialogs */
function show_disable_header($button_text, $text, $disabled= FALSE)
{
if (($disabled == TRUE) || !$this->acl_is_removeable()){
$state= "disabled";
} else {
$state= "";
}
$display= "
\n
$text
\n";
$display.= "
";
return($display);
}
/* Show header message for tab dialogs */
function show_header($button_text, $text, $disabled= FALSE)
{
echo "FIXME: show_header should be replaced by show_disable_header and show_enable_header ";
if ($disabled == TRUE){
$state= "disabled";
} else {
$state= "";
}
$display= "