Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117881294
kolab_client_task.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
55 KB
Referenced Files
None
Subscribers
None
kolab_client_task.php
View Options
<?php
/*
+--------------------------------------------------------------------------+
| This file is part of the Kolab Web Admin Panel |
| |
| Copyright (C) 2011-2012, Kolab Systems AG |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU Affero General Public License as published |
| by the Free Software Foundation, either version 3 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 Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/> |
+--------------------------------------------------------------------------+
| Author: Aleksander Machniak <machniak@kolabsys.com> |
| Author: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> |
+--------------------------------------------------------------------------+
*/
class
kolab_client_task
{
/**
* @var kolab_client_output
*/
protected
$output
;
/**
* @var kolab_client_api
*/
protected
$api
;
/**
* @var Conf
*/
protected
$config
;
protected
$ajax_only
=
false
;
protected
$page_title
=
'Kolab Web Admin Panel'
;
protected
$menu
=
array
();
protected
$cache
=
array
();
protected
$devel_mode
=
false
;
protected
$object_types
=
array
(
'user'
,
'group'
,
'role'
,
'resource'
,
'sharedfolder'
,
'ou'
,
'domain'
);
protected
$page_size
=
20
;
protected
$list_attribs
=
array
();
protected
$list_module
;
protected
$search_attribs
=
array
(
'name'
=>
array
(
'cn'
,
'displayname'
),
'email'
=>
array
(
'mail'
,
'alias'
,
'mailalternateaddress'
),
'uid'
=>
array
(
'uid'
),
);
protected
static
$translation
=
array
();
/**
* Class constructor.
*
* @param kolab_client_output $output Optional output object
*/
public
function
__construct
(
$output
=
null
)
{
$this
->
config_init
();
$this
->
devel_mode
=
$this
->
config_get
(
'devel_mode'
,
false
,
Conf
::
BOOL
);
$this
->
output_init
(
$output
);
$this
->
api_init
();
ini_set
(
'session.use_cookies'
,
'On'
);
session_start
();
$this
->
auth
();
}
/**
* Localization initialization.
*/
protected
function
locale_init
()
{
if
(!
empty
(
self
::
$translation
))
{
return
;
}
$language
=
$this
->
get_language
();
$LANG
=
array
();
if
(!
$language
)
{
$language
=
'en_US'
;
}
@
include
INSTALL_PATH
.
'/locale/en_US.php'
;
if
(
$language
!=
'en_US'
)
{
@
include
INSTALL_PATH
.
"/locale/$language.php"
;
}
setlocale
(
LC_ALL
,
$language
.
'.utf8'
,
'en_US.utf8'
);
self
::
$translation
=
$LANG
;
}
/**
* Configuration initialization.
*/
private
function
config_init
()
{
$this
->
config
=
Conf
::
get_instance
();
}
/**
* Output initialization.
*/
private
function
output_init
(
$output
=
null
)
{
if
(
$output
)
{
$this
->
output
=
$output
;
return
;
}
$skin
=
$this
->
config_get
(
'skin'
,
'default'
);
$this
->
output
=
new
kolab_client_output
(
$skin
);
// Assign self to template variable
$this
->
output
->
assign
(
'engine'
,
$this
);
}
/**
* API initialization
*/
private
function
api_init
()
{
$url
=
$this
->
config_get
(
'api_url'
,
''
);
if
(!
$url
)
{
$port
=
$_SERVER
[
'SERVER_PORT'
];
$url
=
kolab_utils
::
https_check
()
?
'https://'
:
'http://'
;
$url
.=
$_SERVER
[
'SERVER_NAME'
]
.
(
$port
?
":$port"
:
''
);
$url
.=
preg_replace
(
'/
\/
?
\?
.*$/'
,
''
,
$_SERVER
[
'REQUEST_URI'
]);
$url
.=
'/api'
;
}
// TODO: Debug logging
//console($url);
$this
->
api
=
new
kolab_client_api
(
$url
);
}
/**
* Returns system language (locale) setting.
*
* @return string Language code
*/
private
function
get_language
()
{
$aliases
=
array
(
'de'
=>
'de_DE'
,
'en'
=>
'en_US'
,
'pl'
=>
'pl_PL'
,
);
// UI language
$langs
=
!
empty
(
$_SERVER
[
'HTTP_ACCEPT_LANGUAGE'
])
?
$_SERVER
[
'HTTP_ACCEPT_LANGUAGE'
]
:
''
;
$langs
=
explode
(
','
,
$langs
);
if
(!
empty
(
$_SESSION
[
'user'
])
&&
!
empty
(
$_SESSION
[
'user'
][
'language'
]))
{
array_unshift
(
$langs
,
$_SESSION
[
'user'
][
'language'
]);
}
while
(
$lang
=
array_shift
(
$langs
))
{
$lang
=
explode
(
';'
,
$lang
);
$lang
=
$lang
[
0
];
$lang
=
str_replace
(
'-'
,
'_'
,
$lang
);
if
(
file_exists
(
INSTALL_PATH
.
"/locale/$lang.php"
))
{
return
$lang
;
}
if
(
isset
(
$aliases
[
$lang
])
&&
(
$alias
=
$aliases
[
$lang
])
&&
file_exists
(
INSTALL_PATH
.
"/locale/$alias.php"
)
)
{
return
$alias
;
}
}
return
null
;
}
/**
* User authentication (and authorization).
*/
private
function
auth
()
{
if
(
isset
(
$_POST
[
'login'
]))
{
$login
=
$this
->
get_input
(
'login'
,
'POST'
);
if
(
$login
[
'username'
])
{
$result
=
$this
->
api
->
login
(
$login
[
'username'
],
$login
[
'password'
],
$login
[
'domain'
]);
if
(
$token
=
$result
->
get
(
'session_token'
))
{
$user
=
array
(
'token'
=>
$token
,
'id'
=>
$result
->
get
(
'userid'
),
'domain'
=>
$result
->
get
(
'domain'
)
);
$this
->
api
->
set_session_token
(
$user
[
'token'
]);
// Find user settings
// Don't call API user.info for non-existing users (#1025)
if
(
preg_match
(
'/^cn=([a-z ]+)/i'
,
$login
[
'username'
],
$m
))
{
$user
[
'fullname'
]
=
ucwords
(
$m
[
1
]);
}
else
{
$res
=
$this
->
api
->
get
(
'user.info'
,
array
(
'id'
=>
$user
[
'id'
]));
$res
=
$res
->
get
();
if
(
is_array
(
$res
)
&&
!
empty
(
$res
))
{
$user
[
'language'
]
=
$res
[
'preferredlanguage'
];
$user
[
'fullname'
]
=
$res
[
'cn'
];
// overwrite user id set in login request, which might be user base DN,
// with unique attribute, which suits better to our needs
$user
[
'id'
]
=
$res
[
'id'
];
}
}
// Save user data
$_SESSION
[
'user'
]
=
$user
;
if
((
$language
=
$this
->
get_language
())
&&
$language
!=
'en_US'
)
{
$_SESSION
[
'user'
][
'language'
]
=
$language
;
$session_config
[
'language'
]
=
$language
;
}
// Configure API session
if
(!
empty
(
$session_config
))
{
$this
->
api
->
post
(
'system.configure'
,
null
,
$session_config
);
}
header
(
'Location: ?'
);
die
;
}
else
{
$code
=
$result
->
get_error_code
();
$str
=
$result
->
get_error_str
();
$label
=
'loginerror'
;
if
(
$code
==
kolab_client_api
::
ERROR_INTERNAL
||
$code
==
kolab_client_api
::
ERROR_CONNECTION
)
{
$label
=
'internalerror'
;
$this
->
raise_error
(
500
,
'Login failed. '
.
$str
);
}
$this
->
output
->
command
(
'display_message'
,
$label
,
'error'
);
}
}
}
else
if
(!
empty
(
$_SESSION
[
'user'
])
&&
!
empty
(
$_SESSION
[
'user'
][
'token'
]))
{
// Validate session
$timeout
=
$this
->
config_get
(
'session_timeout'
,
3600
);
if
(
$timeout
&&
$_SESSION
[
'time'
]
&&
$_SESSION
[
'time'
]
<
time
()
-
$timeout
)
{
$this
->
action_logout
(
true
);
}
// update session time
$_SESSION
[
'time'
]
=
time
();
// Set API session key
$this
->
api
->
set_session_token
(
$_SESSION
[
'user'
][
'token'
]);
}
}
/**
* Main execution.
*/
public
function
run
()
{
// Initialize locales
$this
->
locale_init
();
// Session check
if
(
empty
(
$_SESSION
[
'user'
])
||
empty
(
$_SESSION
[
'user'
][
'token'
]))
{
$this
->
action_logout
();
}
// Run security checks
$this
->
input_checks
();
$this
->
action
=
$this
->
get_input
(
'action'
,
'GET'
);
if
(
$this
->
action
)
{
$method
=
'action_'
.
$this
->
action
;
if
(
method_exists
(
$this
,
$method
))
{
$this
->
$method
();
}
}
else
if
(
method_exists
(
$this
,
'action_default'
))
{
$this
->
action_default
();
}
}
/**
* Security checks and input validation.
*/
public
function
input_checks
()
{
$ajax
=
$this
->
output
->
is_ajax
();
// Check AJAX-only tasks
if
(
$this
->
ajax_only
&&
!
$ajax
)
{
$this
->
raise_error
(
500
,
'Invalid request type!'
,
null
,
true
);
}
// CSRF prevention
$token
=
$ajax
?
kolab_utils
::
get_request_header
(
'X-Session-Token'
)
:
$this
->
get_input
(
'token'
);
$task
=
$this
->
get_task
();
if
(
$task
!=
'main'
&&
$token
!=
$_SESSION
[
'user'
][
'token'
])
{
$this
->
raise_error
(
403
,
'Invalid request data!'
,
null
,
true
);
}
}
/**
* Logout action.
*/
private
function
action_logout
(
$sess_expired
=
false
,
$stop_sess
=
true
)
{
// Initialize locales
$this
->
locale_init
();
if
(!
empty
(
$_SESSION
[
'user'
])
&&
!
empty
(
$_SESSION
[
'user'
][
'token'
])
&&
$stop_sess
)
{
$this
->
api
->
logout
();
}
$_SESSION
=
array
();
if
(
$this
->
output
->
is_ajax
())
{
if
(
$sess_expired
)
{
$args
=
array
(
'error'
=>
'session.expired'
);
}
$this
->
output
->
command
(
'main_logout'
,
$args
);
if
(
$sess_expired
)
{
$this
->
output
->
send
();
exit
;
}
}
else
{
$this
->
output
->
add_translation
(
'loginerror'
,
'internalerror'
,
'session.expired'
);
}
if
(
$sess_expired
)
{
$error
=
'session.expired'
;
}
else
{
$error
=
$this
->
get_input
(
'error'
,
'GET'
);
}
if
(
$error
)
{
$this
->
output
->
command
(
'display_message'
,
$error
,
'error'
,
60000
);
}
$this
->
send
(
'login'
);
exit
;
}
/**
* Error action (with error logging).
*
* @param int $code Error code
* @param string $msg Error message
* @param array $args Optional arguments (type, file, line)
* @param bool $output Enable to send output and finish
*/
public
function
raise_error
(
$code
,
$msg
,
$args
=
array
(),
$output
=
false
)
{
$log_line
=
sprintf
(
"%s Error: %s (%s)"
,
isset
(
$args
[
'type'
])
?
$args
[
'type'
]
:
'PHP'
,
$msg
.
(
isset
(
$args
[
'file'
])
?
sprintf
(
' in %s on line %d'
,
$args
[
'file'
],
$args
[
'line'
])
:
''
),
$_SERVER
[
'REQUEST_METHOD'
]);
write_log
(
'errors'
,
$log_line
);
if
(!
$output
)
{
return
;
}
if
(
$this
->
output
->
is_ajax
())
{
header
(
"HTTP/1.0 $code $msg"
);
die
;
}
$this
->
output
->
assign
(
'error_code'
,
$code
);
$this
->
output
->
assign
(
'error_message'
,
$msg
);
$this
->
send
(
'error'
);
exit
;
}
/**
* Output sending.
*/
public
function
send
(
$template
=
null
)
{
if
(!
$template
)
{
$template
=
$this
->
get_task
();
}
if
(
$this
->
page_title
)
{
$this
->
output
->
assign
(
'pagetitle'
,
$this
->
page_title
);
}
$this
->
output
->
send
(
$template
);
exit
;
}
/**
* Returns name of the current task.
*
* @return string Task name
*/
public
function
get_task
()
{
$class_name
=
get_class
(
$this
);
if
(
preg_match
(
'/^kolab_client_task_([a-z]+)$/'
,
$class_name
,
$m
))
{
return
$m
[
1
];
}
}
/**
* Returns output environment variable value
*
* @param string $name Variable name
*
* @return mixed Variable value
*/
public
function
get_env
(
$name
)
{
return
$this
->
output
->
get_env
(
$name
);
}
/**
* Returns configuration option value.
*
* @param string $name Option name
* @param mixed $fallback Default value
* @param int $type Value type (one of Conf class constants)
*
* @return mixed Option value
*/
public
function
config_get
(
$name
,
$fallback
=
null
,
$type
=
null
)
{
$value
=
$this
->
config
->
get
(
'kolab_wap'
,
$name
,
$type
);
return
$value
!==
null
?
$value
:
$fallback
;
}
/**
* Returns translation of defined label/message.
*
* @return string Translated string.
*/
public
static
function
translate
()
{
$args
=
func_get_args
();
if
(
is_array
(
$args
[
0
]))
{
$args
=
$args
[
0
];
}
$label
=
$args
[
0
];
if
(
isset
(
self
::
$translation
[
$label
]))
{
$content
=
trim
(
self
::
$translation
[
$label
]);
}
else
{
$content
=
$label
;
}
for
(
$i
=
1
,
$len
=
count
(
$args
);
$i
<
$len
;
$i
++)
{
$content
=
str_replace
(
'$'
.
$i
,
$args
[
$i
],
$content
);
}
return
$content
;
}
/**
* Returns input parameter value.
*
* @param string $name Parameter name
* @param string $type Parameter type (GET|POST|NULL)
* @param bool $allow_html Disables stripping of insecure content (HTML tags)
*
* @see kolab_utils::get_input
* @return mixed Input value.
*/
public
static
function
get_input
(
$name
,
$type
=
null
,
$allow_html
=
false
)
{
if
(
$type
==
'GET'
)
{
$type
=
kolab_utils
::
REQUEST_GET
;
}
else
if
(
$type
==
'POST'
)
{
$type
=
kolab_utils
::
REQUEST_POST
;
}
else
{
$type
=
kolab_utils
::
REQUEST_ANY
;
}
$result
=
kolab_utils
::
get_input
(
$name
,
$type
,
$allow_html
);
return
$result
;
}
/**
* Returns task menu output.
*
* @return string HTML output
*/
protected
function
menu
()
{
if
(
empty
(
$this
->
menu
))
{
return
''
;
}
$menu
=
array
();
$task
=
$this
->
get_task
();
$caps
=
(
array
)
$this
->
get_capability
(
'actions'
);
foreach
(
$this
->
menu
as
$idx
=>
$label
)
{
if
(
in_array
(
$task
,
array
(
'domain'
,
'group'
,
'resource'
,
'role'
,
'user'
)))
{
if
(!
array_key_exists
(
$task
.
"."
.
$idx
,
$caps
))
{
continue
;
}
}
if
(
strpos
(
$idx
,
'.'
))
{
$action
=
$idx
;
$class
=
preg_replace
(
'/
\.
[a-z_-]+$/'
,
''
,
$idx
);
}
else
{
$action
=
$task
.
'.'
.
$idx
;
$class
=
$idx
;
}
$menu
[
$idx
]
=
sprintf
(
'<li class="%s">'
.
'<a href="#%s" onclick="return kadm.command(
\'
%s
\'
,
\'\'
, this)">%s</a></li>'
,
$class
,
$idx
,
$action
,
$this
->
translate
(
$label
));
}
return
'<ul>'
.
implode
(
"
\n
"
,
$menu
)
.
'</ul>'
;
}
/**
* Adds watermark page definition into main page.
*/
protected
function
watermark
(
$name
)
{
$this
->
output
->
command
(
'set_watermark'
,
$name
);
}
/**
* API GET request wrapper
*/
protected
function
api_get
(
$action
,
$get
=
array
())
{
return
$this
->
api_call
(
'get'
,
$action
,
$get
);
}
/**
* API POST request wrapper
*/
protected
function
api_post
(
$action
,
$get
=
array
(),
$post
=
array
())
{
return
$this
->
api_call
(
'post'
,
$action
,
$get
,
$post
);
}
/**
* API request wrapper with error handling
*/
protected
function
api_call
(
$type
,
$action
,
$get
=
array
(),
$post
=
array
())
{
if
(
$type
==
'post'
)
{
$result
=
$this
->
api
->
post
(
$action
,
$get
,
$post
);
}
else
{
$result
=
$this
->
api
->
get
(
$action
,
$get
);
}
// error handling
if
(
$code
=
$result
->
get_error_code
())
{
// Invalid session, do logout
if
(
$code
==
403
)
{
$this
->
action_logout
(
true
,
false
);
}
// Log communication errors, other should be logged on API side
if
(
$code
<
400
)
{
$this
->
raise_error
(
$code
,
'API Error: '
.
$result
->
get_error_str
());
}
}
return
$result
;
}
/**
* Returns list of object types.
*
* @para string $type Object type name
* @param string $used_for Used_for attribute of object type
*
* @return array List of user types
*/
protected
function
object_types
(
$type
,
$used_for
=
null
)
{
if
(
empty
(
$type
)
||
!
in_array
(
$type
,
$this
->
object_types
))
{
return
array
();
}
$cache_idx
=
$type
.
'_types'
.
(
$used_for
?
":$used_for"
:
''
);
if
(!
array_key_exists
(
$cache_idx
,
$this
->
cache
))
{
$result
=
$this
->
api_post
(
$type
.
'_types.list'
);
$list
=
$result
->
get
(
'list'
);
if
(!
empty
(
$used_for
)
&&
is_array
(
$list
))
{
foreach
(
$list
as
$type_id
=>
$type_attrs
)
{
if
(
$type_attrs
[
'used_for'
]
!=
$used_for
)
{
unset
(
$list
[
$type_id
]);
}
}
}
$this
->
cache
[
$cache_idx
]
=
!
empty
(
$list
)
?
$list
:
array
();
Log
::
trace
(
"kolab_client_task::${type}_types() returns: "
.
var_export
(
$list
,
true
));
}
return
$this
->
cache
[
$cache_idx
];
}
/**
* Returns user name.
*
* @param string $dn User DN attribute value
*
* @return string User name (displayname)
*/
protected
function
user_name
(
$dn
)
{
if
(!
$this
->
devel_mode
)
{
if
(!
empty
(
$this
->
cache
[
'user_names'
])
&&
isset
(
$this
->
cache
[
'user_names'
][
$dn
]))
{
return
$this
->
cache
[
'user_names'
][
$dn
];
}
}
$result
=
$this
->
api_get
(
'user.info'
,
array
(
'id'
=>
$dn
));
$username
=
$result
->
get
(
'displayname'
);
if
(
empty
(
$username
))
{
$username
=
$result
->
get
(
'cn'
);
}
if
(
empty
(
$username
))
{
if
(
preg_match
(
'/^cn=([a-zA=Z ]+)/'
,
$dn
,
$m
))
{
$username
=
ucwords
(
$m
[
1
]);
}
}
if
(!
$this
->
devel_mode
)
{
$this
->
cache
[
'user_names'
][
$dn
]
=
$username
;
}
return
$username
;
}
/**
* Returns list of system capabilities.
*
* @param bool $all If enabled capabilities for all domains will be returned
* @param bool $refresh Disable session cache
*
* @return array List of system capabilities
*/
protected
function
capabilities
(
$all
=
false
,
$refresh
=
false
)
{
if
(!
$refresh
&&
isset
(
$_SESSION
[
'capabilities'
])
&&
!
$this
->
devel_mode
)
{
$list
=
$_SESSION
[
'capabilities'
];
}
else
{
$result
=
$this
->
api_post
(
'system.capabilities'
);
$list
=
$result
->
get
(
'list'
);
if
(
is_array
(
$list
)
&&
!
$this
->
devel_mode
)
{
$_SESSION
[
'capabilities'
]
=
$list
;
}
}
$domain
=
$this
->
domain
?
$this
->
domain
:
$_SESSION
[
'user'
][
'domain'
];
return
!
$all
?
$list
[
$domain
]
:
$list
;
}
/**
* Returns system capability
*
* @param string $name Capability (key) name
*
* @return array Capability value if supported, NULL otherwise
*/
protected
function
get_capability
(
$name
)
{
$caps
=
$this
->
capabilities
();
return
$caps
[
$name
];
}
/**
* Returns domains list (based on capabilities response)
*
* @param bool $refresh Refresh session cache
*
* @return array List of domains
*/
protected
function
get_domains
(
$refresh
=
false
)
{
$caps
=
$this
->
capabilities
(
true
,
$refresh
);
return
is_array
(
$caps
)
?
array_keys
(
$caps
)
:
array
();
}
/**
* Returns effective rights for the specified object
*
* @param string $type Object type
* @param string $id Object identifier
*
* @return array Two element array with 'attribute' and 'entry' elements
*/
protected
function
effective_rights
(
$type
,
$id
=
null
)
{
$caps
=
$this
->
get_capability
(
'actions'
);
if
(
empty
(
$caps
[
$type
.
'.effective_rights'
]))
{
return
array
(
'attribute'
=>
array
(),
'entry'
=>
array
(),
);
}
// Get the rights on the entry and attribute level
$result
=
$this
->
api_get
(
$type
.
'.effective_rights'
,
array
(
'id'
=>
$id
));
$result
=
array
(
'attribute'
=>
$result
->
get
(
'attributeLevelRights'
),
'entry'
=>
$result
->
get
(
'entryLevelRights'
),
);
return
$result
;
}
/**
* Returns execution time in seconds
*
* @param string Execution time
*/
public
function
gentime
()
{
return
sprintf
(
'%.4f'
,
microtime
(
true
)
-
KADM_START
);
}
/**
* Returns HTML output of login form
*
* @param string HTML output
*/
public
function
login_form
()
{
$post
=
$this
->
get_input
(
'login'
,
'POST'
);
$username
=
kolab_html
::
label
(
array
(
'for'
=>
'login_name'
,
'content'
=>
$this
->
translate
(
'login.username'
)),
true
)
.
kolab_html
::
input
(
array
(
'type'
=>
'text'
,
'id'
=>
'login_name'
,
'name'
=>
'login[username]'
,
'value'
=>
$post
[
'username'
],
'autofocus'
=>
true
));
$password
=
kolab_html
::
label
(
array
(
'for'
=>
'login_pass'
,
'content'
=>
$this
->
translate
(
'login.password'
)),
true
)
.
kolab_html
::
input
(
array
(
'type'
=>
'password'
,
'id'
=>
'login_pass'
,
'name'
=>
'login[password]'
,
'value'
=>
''
));
$button
=
kolab_html
::
input
(
array
(
'type'
=>
'submit'
,
'id'
=>
'login_submit'
,
'value'
=>
$this
->
translate
(
'login.login'
)));
$form
=
kolab_html
::
form
(
array
(
'id'
=>
'login_form'
,
'name'
=>
'login'
,
'method'
=>
'post'
,
'action'
=>
'?'
),
kolab_html
::
span
(
array
(
'content'
=>
$username
))
.
kolab_html
::
span
(
array
(
'content'
=>
$password
))
.
$button
);
return
$form
;
}
/**
* Returns form element definition based on field attributes
*
* @param array $field Field attributes
* @param array $data Attribute values
*
* @return array Field definition
*/
protected
function
form_element_type
(
$field
,
$data
=
array
())
{
$result
=
array
();
switch
(
$field
[
'type'
])
{
case
'select'
:
case
'multiselect'
:
$opts
=
$this
->
form_element_select_data
(
$field
,
$data
);
$result
[
'type'
]
=
kolab_form
::
INPUT_SELECT
;
$result
[
'options'
]
=
$opts
[
'options'
];
$result
[
'value'
]
=
$opts
[
'default'
];
$result
[
'default'
]
=
$field
[
'default'
];
if
(
$field
[
'type'
]
==
'multiselect'
)
{
$result
[
'multiple'
]
=
true
;
}
break
;
case
'list'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_TEXTAREA
;
$result
[
'data-type'
]
=
'list'
;
if
(!
empty
(
$field
[
'maxlength'
]))
{
$result
[
'data-maxlength'
]
=
$field
[
'maxlength'
];
}
if
(!
empty
(
$field
[
'maxcount'
]))
{
$result
[
'data-maxcount'
]
=
$field
[
'maxcount'
];
}
if
(!
empty
(
$field
[
'autocomplete'
]))
{
$result
[
'data-autocomplete'
]
=
true
;
}
break
;
case
'checkbox'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_CHECKBOX
;
break
;
case
'password'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_PASSWORD
;
if
(
isset
(
$field
[
'maxlength'
]))
{
$result
[
'maxlength'
]
=
$field
[
'maxlength'
];
}
break
;
case
'text-quota'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_TEXTQUOTA
;
$result
[
'default'
]
=
$field
[
'default'
];
break
;
case
'aci'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_TEXTAREA
;
$result
[
'data-type'
]
=
'aci'
;
$this
->
output
->
add_translation
(
'aci.new'
,
'aci.edit'
,
'aci.remove'
,
'aci.users'
,
'aci.rights'
,
'aci.targets'
,
'aci.aciname'
,
'aci.read'
,
'aci.compare'
,
'aci.search'
,
'aci.write'
,
'aci.selfwrite'
,
'aci.delete'
,
'aci.add'
,
'aci.proxy'
,
'aci.all'
,
'aci.allow'
,
'aci.deny'
,
'aci.typeusers'
,
'aci.typegroups'
,
'aci.typeroles'
,
'aci.typeadmins'
,
'aci.typespecials'
,
'aci.ldap-all'
,
'aci.ldap-anyone'
,
'aci.ldap-self'
,
'aci.ldap-parent'
,
'aci.usersearch'
,
'aci.usersearchresult'
,
'aci.selected'
,
'aci.other'
,
'aci.userselected'
,
'aci.useradd'
,
'aci.userremove'
,
'aci.thisentry'
,
'aci.rights.target'
,
'aci.rights.filter'
,
'aci.rights.attrs'
,
'aci.checkall'
,
'aci.checknone'
,
'aci.error.noname'
,
'aci.error.exists'
,
'aci.error.nousers'
,
'button.cancel'
,
'button.ok'
);
break
;
case
'imap_acl'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_TEXTAREA
;
$result
[
'data-type'
]
=
'acl'
;
$result
[
'default'
]
=
$field
[
'default'
];
$this
->
output
->
add_translation
(
'aci.new'
,
'aci.edit'
,
'aci.remove'
,
'button.ok'
,
'button.cancel'
,
'acl.all'
,
'acl.custom'
,
'acl.read-only'
,
'acl.read-write'
,
'acl.full'
,
'acl.semi-full'
,
'acl.l'
,
'acl.r'
,
'acl.s'
,
'acl.w'
,
'acl.i'
,
'acl.p'
,
'acl.k'
,
'acl.a'
,
'acl.x'
,
'acl.t'
,
'acl.n'
,
'acl.e'
,
'acl.d'
,
'acl.anyone'
,
'acl.anonymous'
,
'acl.identifier'
,
'acl.rights'
,
'acl.expire'
,
'acl.user'
,
'acl.error.invaliddate'
,
'acl.error.nouser'
,
'acl.error.subjectexists'
,
'acl.error.norights'
);
break
;
case
'text-separated'
:
$result
[
'type'
]
=
kolab_form
::
INPUT_TEXTAREA
;
$result
[
'data-type'
]
=
'separated'
;
break
;
default
:
$result
[
'type'
]
=
kolab_form
::
INPUT_TEXT
;
if
(
isset
(
$field
[
'maxlength'
]))
{
$result
[
'maxlength'
]
=
$field
[
'maxlength'
];
}
if
(
$field
[
'type'
]
&&
$field
[
'type'
]
!=
'text'
)
{
$result
[
'data-type'
]
=
$field
[
'type'
];
if
(
$field
[
'type'
]
==
'ldap_url'
)
{
$this
->
output
->
add_translation
(
'ldap.one'
,
'ldap.sub'
,
'ldap.base'
,
'ldap.host'
,
'ldap.basedn'
,
'ldap.scope'
,
'ldap.conditions'
,
'ldap.filter_any'
,
'ldap.filter_both'
,
'ldap.filter_prefix'
,
'ldap.filter_suffix'
,
'ldap.filter_exact'
);
}
}
else
{
$result
[
'default'
]
=
$field
[
'default'
];
}
}
$result
[
'required'
]
=
empty
(
$field
[
'optional'
]);
return
$result
;
}
/**
* Prepares options/value of select element
*
* @param array $field Field attributes
* @param array $data Attribute values
* @param bool $lc Convert option values to lower-case
*
* @return array Options/Default definition
*/
protected
function
form_element_select_data
(
$field
,
$data
=
array
(),
$lc
=
false
)
{
$options
=
array
();
$default
=
null
;
if
(!
isset
(
$field
[
'values'
]))
{
$data
[
'attributes'
]
=
array
(
$field
[
'name'
]);
$resp
=
$this
->
api_post
(
'form_value.select_options'
,
null
,
$data
);
$resp
=
$resp
->
get
(
$field
[
'name'
]);
unset
(
$data
[
'attributes'
]);
$default
=
empty
(
$data
[
$field
[
'name'
]])
?
$resp
[
'default'
]
:
$data
[
$field
[
'name'
]];
$field
[
'values'
]
=
$resp
[
'list'
];
}
if
(!
empty
(
$field
[
'values'
]))
{
if
(
$lc
)
{
$options
=
array_combine
(
array_map
(
'strtolower'
,
$field
[
'values'
]),
$field
[
'values'
]);
}
else
{
$options
=
array_combine
(
$field
[
'values'
],
$field
[
'values'
]);
}
// Exceptions
if
(
$field
[
'name'
]
==
'ou'
)
{
foreach
(
$options
as
$idx
=>
$dn
)
{
$options
[
$idx
]
=
kolab_utils
::
dn2ufn
(
$dn
);
}
}
}
if
(!
empty
(
$default
))
{
foreach
(
$options
as
$key
=>
$value
)
{
if
(
strtolower
(
$default
)
==
$key
)
{
$default
=
strtolower
(
$default
);
}
}
}
return
array
(
'options'
=>
$options
,
'default'
=>
$default
,
);
}
/**
* HTML Form elements preparation.
*
* @param string $name Object name (user, group, etc.)
* @param array $data Object data
* @param array $extra_fields Extra field names
* @param string $used_for Object types filter
* @param string $id_section Name of section for type_id field
*
* @return array Fields list, Object types list, Current type ID
*/
protected
function
form_prepare
(
$name
,
&
$data
,
$extra_fields
=
array
(),
$used_for
=
null
,
$id_section
=
null
)
{
$types
=
(
array
)
$this
->
object_types
(
$name
,
$used_for
);
$add_mode
=
empty
(
$data
[
'id'
]);
$event_fields
=
array
();
$auto_fields
=
array
();
$form_fields
=
array
();
$fields
=
array
();
$auto_attribs
=
array
();
$extra_fields
=
array_flip
(
$extra_fields
);
// Object type
$data
[
'object_type'
]
=
$name
;
// Selected account type
if
(!
empty
(
$data
[
'type_id'
]))
{
$type
=
$data
[
'type_id'
];
}
else
{
// find default object type
foreach
(
$types
as
$type_id
=>
$type
)
{
if
(
$type
[
'is_default'
])
{
$default
=
$type_id
;
break
;
}
}
reset
(
$types
);
$data
[
'type_id'
]
=
$type
=
(
$default
!==
null
?
$default
:
key
(
$types
));
}
if
(
$type
)
{
$auto_fields
=
(
array
)
$types
[
$type
][
'attributes'
][
'auto_form_fields'
];
$form_fields
=
(
array
)
$types
[
$type
][
'attributes'
][
'form_fields'
];
}
// Mark automatically generated fields as read-only, etc.
foreach
(
$auto_fields
as
$idx
=>
$field
)
{
if
(!
is_array
(
$field
))
{
unset
(
$auto_fields
[
$idx
]);
continue
;
}
// merge with field definition from
if
(
isset
(
$form_fields
[
$idx
]))
{
$field
=
array_merge
(
$field
,
$form_fields
[
$idx
]);
}
// remove auto-generated value on type change, it will be re-generated
else
if
(
$add_mode
)
{
unset
(
$data
[
$idx
]);
}
$field
[
'name'
]
=
$idx
;
$fields
[
$idx
]
=
$this
->
form_element_type
(
$field
,
$data
);
$fields
[
$idx
][
'readonly'
]
=
true
;
$extra_fields
[
$idx
]
=
true
;
// build auto_attribs and event_fields lists
$is_data
=
0
;
if
(!
empty
(
$field
[
'data'
]))
{
foreach
(
$field
[
'data'
]
as
$fd
)
{
$event_fields
[
$fd
][]
=
$idx
;
if
(
isset
(
$data
[
$fd
]))
{
$is_data
++;
}
}
if
(
count
(
$field
[
'data'
])
==
$is_data
)
{
$auto_attribs
[]
=
$idx
;
}
}
else
{
//console("\$field['data'] is empty for \$auto_fields[\$idx] (idx: $idx)");
$auto_attribs
[]
=
$idx
;
// Unset the $auto_field array key to prevent the form field from
// becoming disabled/readonly
unset
(
$auto_fields
[
$idx
]);
}
}
// Other fields
foreach
(
$form_fields
as
$idx
=>
$field
)
{
if
(!
isset
(
$fields
[
$idx
]))
{
$field
[
'name'
]
=
$idx
;
$fields
[
$idx
]
=
$this
->
form_element_type
(
$field
,
$data
);
}
else
{
unset
(
$extra_fields
[
$idx
]);
}
$fields
[
$idx
][
'readonly'
]
=
false
;
// Attach on-change events to some fields, to update
// auto-generated field values
if
(!
empty
(
$event_fields
[
$idx
]))
{
$event
=
json_encode
(
array_unique
(
$event_fields
[
$idx
]));
$fields
[
$idx
][
'onchange'
]
=
"kadm.form_value_change($event)"
;
}
}
// Get the rights on the entry and attribute level
$data
[
'effective_rights'
]
=
$this
->
effective_rights
(
$name
,
$data
[
'id'
]);
$attribute_rights
=
(
array
)
$data
[
'effective_rights'
][
'attribute'
];
$entry_rights
=
(
array
)
$data
[
'effective_rights'
][
'entry'
];
// See if "administrators" (those who can delete and add back on the entry
// level) may override the automatically generated contents of auto_form_fields.
$admin_auto_fields_rw
=
$this
->
config_get
(
'admin_auto_fields_rw'
,
false
,
Conf
::
BOOL
);
foreach
(
$fields
as
$idx
=>
$field
)
{
$readonly
=
null
;
if
(!
array_key_exists
(
$idx
,
$attribute_rights
))
{
// If the entry level rights contain 'add' and 'delete', well, you're an admin
if
(
in_array
(
'add'
,
$entry_rights
)
&&
in_array
(
'delete'
,
$entry_rights
))
{
if
(
$admin_auto_fields_rw
)
{
$fields
[
$idx
][
'readonly'
]
=
false
;
}
}
else
{
$fields
[
$idx
][
'readonly'
]
=
$readonly
=
true
;
}
}
else
{
if
(
in_array
(
'add'
,
$entry_rights
)
&&
in_array
(
'delete'
,
$entry_rights
))
{
if
(
$admin_auto_fields_rw
)
{
$fields
[
$idx
][
'readonly'
]
=
false
;
}
}
// Explicit attribute level rights, check for 'write'
else
if
(!
in_array
(
'write'
,
$attribute_rights
[
$idx
]))
{
$fields
[
$idx
][
'readonly'
]
=
$readonly
=
true
;
}
}
// disable auto-fields updates, user has no rights to modify them anyway
if
(
is_bool
(
$readonly
)
&&
$readonly
)
{
if
((
$s_idx
=
array_search
(
$idx
,
$auto_attribs
))
!==
false
)
{
unset
(
$auto_attribs
[
$s_idx
]);
}
unset
(
$auto_fields
[
$idx
]);
}
}
// Register list of auto-generated fields
$this
->
output
->
set_env
(
'auto_fields'
,
$auto_fields
);
// Register list of disabled fields
$this
->
output
->
set_env
(
'extra_fields'
,
array_keys
(
$extra_fields
));
// (Re-|Pre-)populate auto_form_fields
if
(
$add_mode
)
{
if
(!
empty
(
$auto_attribs
))
{
$data
[
'attributes'
]
=
$auto_attribs
;
$resp
=
$this
->
api_post
(
'form_value.generate'
,
null
,
$data
);
$data
=
array_merge
((
array
)
$data
,
(
array
)
$resp
->
get
());
unset
(
$data
[
'attributes'
]);
}
}
else
{
// Add common information fields
$add_fields
=
array
(
'creatorsname'
=>
'createtimestamp'
,
'modifiersname'
=>
'modifytimestamp'
,
);
foreach
(
$add_fields
as
$idx
=>
$val
)
{
if
(!
empty
(
$data
[
$idx
]))
{
if
(
$value
=
$this
->
user_name
(
$data
[
$idx
]))
{
if
(
$data
[
$val
])
{
$value
.=
' ('
.
strftime
(
'%x %X'
,
strtotime
(
$data
[
$val
]))
.
')'
;
}
$fields
[
$idx
]
=
array
(
'label'
=>
$idx
,
'section'
=>
'system'
,
'value'
=>
$value
,
);
}
}
}
// Add debug information
if
(
$this
->
devel_mode
)
{
ksort
(
$data
);
$debug
=
kolab_html
::
escape
(
print_r
(
$data
,
true
));
$debug
=
preg_replace
(
'/(^Array
\n\(
|
\n
*
\)
$|
\t
)/'
,
''
,
$debug
);
$debug
=
str_replace
(
"
\n
"
,
"
\n
"
,
$debug
);
$debug
=
'<pre class="debug">'
.
$debug
.
'</pre>'
;
$fields
[
'debug'
]
=
array
(
'label'
=>
'debug'
,
'section'
=>
'system'
,
'value'
=>
$debug
,
);
}
}
// Add object type hidden field
$fields
[
'object_type'
]
=
array
(
'section'
=>
'system'
,
'type'
=>
kolab_form
::
INPUT_HIDDEN
,
'value'
=>
$name
,
);
// Get user-friendly names for lists
foreach
(
$fields
as
$fname
=>
$field
)
{
if
(!
empty
(
$field
[
'data-autocomplete'
])
&&
!
empty
(
$data
[
$fname
]))
{
if
(!
is_array
(
$data
[
$fname
]))
{
$data
[
$fname
]
=
(
array
)
$data
[
$fname
];
}
// request parameters
$post
=
array
(
'list'
=>
$data
[
$fname
],
'attribute'
=>
$fname
,
'object_type'
=>
$name
,
'type_id'
=>
$data
[
'type_id'
],
);
// get options list
$result
=
$this
->
api_post
(
'form_value.list_options'
,
null
,
$post
);
$result
=
$result
->
get
(
'list'
);
$data
[
$fname
]
=
$result
;
}
}
// Add entry identifier
if
(!
$add_mode
)
{
$fields
[
'id'
]
=
array
(
'section'
=>
'system'
,
'type'
=>
kolab_form
::
INPUT_HIDDEN
,
'value'
=>
$data
[
'id'
]
);
}
// Add object type id selector
if
(
$id_section
)
{
$object_types
=
array
();
foreach
(
$types
as
$idx
=>
$elem
)
{
$object_types
[
$idx
]
=
array
(
'value'
=>
$idx
,
'content'
=>
$elem
[
'name'
]);
}
// Add object type id selector
$fields
[
'type_id'
]
=
array
(
'section'
=>
$id_section
,
'type'
=>
kolab_form
::
INPUT_SELECT
,
'options'
=>
$object_types
,
'onchange'
=>
"kadm.{$name}_save(true, '$id_section')"
,
);
// Hide account type selector if there's only one type
if
(
count
(
$object_types
)
<
2
||
!
$add_mode
)
{
$fields
[
'type_id'
][
'type'
]
=
kolab_form
::
INPUT_HIDDEN
;
}
// Add object type name
if
(!
$add_mode
&&
count
(
$object_types
)
>
1
)
{
$fields
[
'type_id_name'
]
=
array
(
'label'
=>
"$name.type_id"
,
'section'
=>
$id_section
,
'value'
=>
$object_types
[
$type
][
'content'
],
);
}
}
$result
=
array
(
$fields
,
$types
,
$type
,
$add_mode
);
return
$result
;
}
/**
* HTML Form creation.
*
* @param string $name Object name (user, group, etc.)
* @param array $attribs HTML attributes of the form
* @param array $sections List of form sections
* @param array $fields Fields list (from self::form_prepare())
* @param array $fields_map Fields map (used for sorting and sections assignment)
* @param array $data Object data (with effective rights, see form_prepare())
* @param bool $add_mode Add mode enabled
* @param string $title Page title
*
* @return kolab_form HTML Form object
*/
protected
function
form_create
(
$name
,
$attribs
,
$sections
,
$fields
,
$fields_map
,
$data
,
$add_mode
,
$title
=
null
)
{
// Assign sections to fields
foreach
(
$fields
as
$idx
=>
$field
)
{
if
(!
$field
[
'section'
])
{
$fields
[
$idx
][
'section'
]
=
isset
(
$fields_map
[
$idx
])
?
$fields_map
[
$idx
]
:
'other'
;
}
}
// Sort
foreach
(
$fields_map
as
$idx
=>
$val
)
{
if
(
array_key_exists
(
$idx
,
$fields
))
{
$fields_map
[
$idx
]
=
$fields
[
$idx
];
unset
(
$fields
[
$idx
]);
}
else
{
unset
(
$fields_map
[
$idx
]);
}
}
if
(!
empty
(
$fields
))
{
$fields_map
=
array_merge
(
$fields_map
,
$fields
);
}
$form
=
new
kolab_form
(
$attribs
);
$default_values
=
array
();
$assoc_fields
=
array
();
$req_fields
=
array
();
$writeable
=
0
;
$auto_fields
=
$this
->
output
->
get_env
(
'auto_fields'
);
$conf_aliases
=
array
(
'mailquota'
=>
'quota'
);
$domain
=
$this
->
domain
?:
$_SESSION
[
'user'
][
'domain'
];
// Parse elements and add them to the form object
foreach
(
$sections
as
$section_idx
=>
$section
)
{
$form
->
add_section
(
$section_idx
,
kolab_html
::
escape
(
$this
->
translate
(
$section
)));
foreach
(
$fields_map
as
$idx
=>
$field
)
{
if
(
$field
[
'section'
]
!=
$section_idx
)
{
continue
;
}
if
(
empty
(
$field
[
'label'
]))
{
$field
[
'label'
]
=
"$name.$idx"
;
}
$field
[
'label'
]
=
kolab_html
::
escape
(
$this
->
translate
(
$field
[
'label'
]));
$field
[
'description'
]
=
"$name.$idx.desc"
;
$field
[
'section'
]
=
$section_idx
;
if
(
empty
(
$field
[
'value'
])
&&
!
empty
(
$data
[
$idx
]))
{
$value
=
$data
[
$idx
];
// Convert data for the list field with autocompletion
if
(
$field
[
'data-type'
]
==
'list'
)
{
if
(!
is_array
(
$value
))
{
if
(!
empty
(
$field
[
'data-autocomplete'
]))
{
$value
=
array
(
$value
=>
$value
);
}
else
{
$value
=
(
array
)
$value
;
}
}
$value
=
!
empty
(
$field
[
'data-autocomplete'
])
?
array_keys
(
$value
)
:
array_values
(
$value
);
}
if
(
is_array
(
$value
))
{
$value
=
implode
(
"
\n
"
,
$value
);
}
$field
[
'value'
]
=
$value
;
}
else
if
(
$add_mode
&&
!
isset
(
$field
[
'value'
]))
{
// read default from config, e.g. default_quota
if
(!
isset
(
$field
[
'default'
]))
{
$conf_name
=
'default_'
.
(
$conf_aliases
[
$idx
]
?:
$idx
);
$field
[
'default'
]
=
$this
->
config
->
get
(
$domain
,
$conf_name
);
}
if
(
isset
(
$field
[
'default'
]))
{
$field
[
'value'
]
=
$field
[
'default'
];
$default_values
[
$idx
]
=
$field
[
'default'
];
unset
(
$field
[
'default'
]);
}
}
// @TODO: We assume here that all autocompletion lists are associative
// It's likely that we'll need autocompletion on ordinary lists
if
(!
empty
(
$field
[
'data-autocomplete'
]))
{
$assoc_fields
[
$idx
]
=
!
empty
(
$data
[
$idx
])
?
$data
[
$idx
]
:
array
();
}
if
(
$field
[
'type'
]
==
kolab_form
::
INPUT_CHECKBOX
&&
!
isset
(
$field
[
'checked'
]))
{
$field
[
'checked'
]
=
$field
[
'value'
]
==
'TRUE'
;
}
/*
if (!empty($field['suffix'])) {
$field['suffix'] = kolab_html::escape($this->translate($field['suffix']));
}
*/
if
(!
empty
(
$field
[
'options'
])
&&
empty
(
$field
[
'escaped'
]))
{
foreach
(
$field
[
'options'
]
as
$opt_idx
=>
$option
)
{
if
(
is_array
(
$option
))
{
$field
[
'options'
][
$opt_idx
][
'content'
]
=
kolab_html
::
escape
(
$this
->
translate
(
$option
[
'content'
]));
}
else
{
$field
[
'options'
][
$opt_idx
]
=
kolab_html
::
escape
(
$this
->
translate
(
$option
));
}
}
$field
[
'escaped'
]
=
true
;
}
if
(!
empty
(
$field
[
'description'
]))
{
$description
=
$this
->
translate
(
$field
[
'description'
]);
if
(
$description
!=
$field
[
'description'
])
{
$field
[
'title'
]
=
$description
;
}
unset
(
$field
[
'description'
]);
}
if
(
empty
(
$field
[
'name'
]))
{
$field
[
'name'
]
=
$idx
;
}
if
(
empty
(
$field
[
'readonly'
])
&&
empty
(
$field
[
'disabled'
]))
{
// count writeable fields
if
(
$field
[
'type'
]
&&
$field
[
'type'
]
!=
kolab_form
::
INPUT_HIDDEN
)
{
$writeable
++;
}
if
(
$idx
!=
"userpassword2"
)
{
if
(!
empty
(
$field
[
'required'
]))
{
$req_fields
[]
=
$idx
;
}
}
}
$form
->
add_element
(
$field
);
}
}
if
(!
empty
(
$data
[
'section'
]))
{
$form
->
activate_section
(
$data
[
'section'
]);
}
if
(
$writeable
)
{
$form
->
add_button
(
array
(
'value'
=>
kolab_html
::
escape
(
$this
->
translate
(
'button.submit'
)),
'onclick'
=>
"kadm.command('{$name}.save')"
,
));
}
// add delete button
if
(
$this
->
is_deletable
(
$data
))
{
$id
=
$data
[
'id'
];
$form
->
add_button
(
array
(
'value'
=>
kolab_html
::
escape
(
$this
->
translate
(
'button.delete'
)),
'onclick'
=>
"kadm.command('{$name}.delete', '{$id}')"
,
));
}
$ac_min_len
=
$this
->
config_get
(
'autocomplete_min_length'
,
1
,
Conf
::
INT
);
$this
->
output
->
set_env
(
'form_id'
,
$attribs
[
'id'
]);
$this
->
output
->
set_env
(
'default_values'
,
$default_values
);
$this
->
output
->
set_env
(
'assoc_fields'
,
$assoc_fields
);
$this
->
output
->
set_env
(
'required_fields'
,
$req_fields
);
$this
->
output
->
set_env
(
'autocomplete_min_length'
,
$ac_min_len
);
$this
->
output
->
set_env
(
'entrydn'
,
$data
[
'entrydn'
]);
$this
->
output
->
add_translation
(
'form.required.empty'
,
'form.maxcount.exceeded'
,
$name
.
'.add.success'
,
$name
.
'.edit.success'
,
$name
.
'.delete.success'
,
$name
.
'.delete.confirm'
,
$name
.
'.delete.force'
,
'add'
,
'edit'
,
'delete'
);
if
(
empty
(
$title
))
{
$title
=
$add_mode
?
$this
->
translate
(
"$name.add"
)
:
$data
[
'cn'
];
}
$form
->
set_title
(
kolab_html
::
escape
(
$title
));
return
$form
;
}
/**
* Check wether specified object can be deleted
*/
protected
function
is_deletable
(
$data
)
{
return
!
empty
(
$data
[
'id'
])
&&
in_array
(
'delete'
,
(
array
)
$data
[
'effective_rights'
][
'entry'
]);
}
/**
* Search form.
*
* @return string HTML output of the form
*/
public
function
search_form
()
{
$attribs
=
$this
->
get_search_attribs
();
if
(
empty
(
$attribs
))
{
return
''
;
}
$options
=
array
();
foreach
(
array_keys
(
$attribs
)
as
$key
)
{
$options
[
$key
]
=
kolab_html
::
escape
(
$this
->
translate
(
'search.'
.
$key
));
}
$form
=
new
kolab_form
(
array
(
'id'
=>
'search-form'
));
$form
->
add_section
(
'criteria'
,
kolab_html
::
escape
(
$this
->
translate
(
'search.criteria'
)));
$form
->
add_element
(
array
(
'section'
=>
'criteria'
,
'label'
=>
$this
->
translate
(
'search.field'
),
'name'
=>
'field'
,
'type'
=>
kolab_form
::
INPUT_SELECT
,
'options'
=>
$options
,
));
$form
->
add_element
(
array
(
'section'
=>
'criteria'
,
'label'
=>
$this
->
translate
(
'search.method'
),
'name'
=>
'method'
,
'type'
=>
kolab_form
::
INPUT_SELECT
,
'options'
=>
array
(
'both'
=>
kolab_html
::
escape
(
$this
->
translate
(
'search.contains'
)),
'exact'
=>
kolab_html
::
escape
(
$this
->
translate
(
'search.is'
)),
'prefix'
=>
kolab_html
::
escape
(
$this
->
translate
(
'search.prefix'
)),
),
));
return
$form
->
output
();
}
/**
* Returns list of attributes assigned to search field(s)
*
* @param string $name Optional search field name
*
* @return array List of attributes
*/
protected
function
get_search_attribs
(
$name
=
null
)
{
$task
=
$this
->
get_task
();
$types
=
$this
->
object_types
(
$task
);
$attribs
=
array
();
foreach
(
$this
->
search_attribs
as
$key
=>
$value
)
{
foreach
((
array
)
$value
as
$idx
=>
$attr
)
{
$found
=
false
;
foreach
(
$types
as
$type
)
{
if
(
array_key_exists
(
$attr
,
(
array
)
$type
[
'attributes'
][
'auto_form_fields'
])
||
array_key_exists
(
$attr
,
(
array
)
$type
[
'attributes'
][
'form_fields'
])
||
array_key_exists
(
$attr
,
(
array
)
$type
[
'attributes'
][
'fields'
])
)
{
$found
=
true
;
break
;
}
}
if
(!
$found
)
{
unset
(
$value
[
$idx
]);
}
}
if
(!
empty
(
$value
))
{
$attribs
[
$key
]
=
$value
;
}
}
return
$name
?
$attribs
[
$name
]
:
$attribs
;
}
/**
* Object list (and search handler)
*/
public
function
action_list
()
{
if
(
empty
(
$this
->
list_attribs
))
{
return
;
}
$task
=
$this
->
get_task
();
$page
=
(
int
)
self
::
get_input
(
'page'
,
'POST'
);
if
(!
$page
||
$page
<
1
)
{
$page
=
1
;
}
// request parameters
$post
=
array
(
'attributes'
=>
$this
->
list_attribs
,
'sort_by'
=>
$this
->
list_attribs
,
// 'sort_order' => 'ASC',
'page_size'
=>
$this
->
page_size
,
'page'
=>
$page
,
);
// search parameters
if
(!
empty
(
$_POST
[
'search'
]))
{
$search
=
self
::
get_input
(
'search'
,
'POST'
,
true
);
$field
=
self
::
get_input
(
'field'
,
'POST'
);
$method
=
self
::
get_input
(
'method'
,
'POST'
);
$attrs
=
$this
->
get_search_attribs
(
$field
);
$search_request
=
array
();
foreach
(
$attrs
as
$attr
)
{
$search_request
[
$attr
]
=
array
(
'value'
=>
$search
,
'type'
=>
$method
,
);
}
}
else
if
(!
empty
(
$_POST
[
'search_request'
]))
{
$search_request
=
self
::
get_input
(
'search_request'
,
'POST'
);
$search_request
=
@
unserialize
(
base64_decode
(
$search_request
));
}
if
(!
empty
(
$search_request
))
{
$post
[
'search'
]
=
$search_request
;
$post
[
'search_operator'
]
=
'OR'
;
}
// get users list
$module
=
$this
->
list_module
?
$this
->
list_module
:
$task
.
's'
;
$result
=
$this
->
api_post
(
$module
.
'.list'
,
null
,
$post
);
$count
=
$result
->
get
(
'count'
);
$result
=
(
array
)
$result
->
get
(
'list'
);
// calculate records
if
(
$count
)
{
$start
=
1
+
max
(
0
,
$page
-
1
)
*
$this
->
page_size
;
$end
=
min
(
$start
+
$this
->
page_size
-
1
,
$count
);
}
$rows
=
$head
=
$foot
=
array
();
$cols
=
array
(
'name'
);
$i
=
0
;
$table_class
=
'list'
;
// table header
$head
[
0
][
'cells'
][]
=
array
(
'class'
=>
'name'
,
'body'
=>
$this
->
translate
(
$task
.
'.list'
));
// table footer (navigation)
if
(
$count
)
{
$pages
=
ceil
(
$count
/
$this
->
page_size
);
$prev
=
max
(
0
,
$page
-
1
);
$next
=
$page
<
$pages
?
$page
+
1
:
0
;
$count_str
=
kolab_html
::
span
(
array
(
'content'
=>
$this
->
translate
(
'list.records'
,
$start
,
$end
,
$count
)),
true
);
$prev
=
kolab_html
::
a
(
array
(
'class'
=>
'prev'
.
(
$prev
?
''
:
' disabled'
),
'href'
=>
'#'
,
'onclick'
=>
$prev
?
"kadm.command('$task.list', {page: $prev})"
:
"return false"
,
));
$next
=
kolab_html
::
a
(
array
(
'class'
=>
'next'
.
(
$next
?
''
:
' disabled'
),
'href'
=>
'#'
,
'onclick'
=>
$next
?
"kadm.command('$task.list', {page: $next})"
:
"return false"
,
));
$foot_body
=
kolab_html
::
span
(
array
(
'content'
=>
$prev
.
$count_str
.
$next
));
}
$foot
[
0
][
'cells'
][]
=
array
(
'class'
=>
'listnav'
,
'body'
=>
$foot_body
);
// table body
if
(!
empty
(
$result
))
{
if
(
method_exists
(
$this
,
'list_result_handler'
))
{
list
(
$rows
,
$head
,
$foot
,
$table_class
)
=
$this
->
list_result_handler
(
$result
,
$head
,
$foot
,
$table_class
);
}
else
{
foreach
(
$result
as
$idx
=>
$item
)
{
if
(!
is_array
(
$item
))
{
continue
;
}
$class
=
array
(
'selectable'
);
if
(
method_exists
(
$this
,
'list_item_handler'
))
{
$item
=
$this
->
list_item_handler
(
$item
,
$class
);
}
else
{
$item
=
array_shift
(
$item
);
}
if
(
empty
(
$item
))
{
continue
;
}
$i
++;
$cells
=
array
();
$cells
[]
=
array
(
'class'
=>
'name'
,
'body'
=>
kolab_html
::
escape
(
$item
),
'onclick'
=>
"kadm.command('$task.info', '"
.
kolab_utils
::
js_escape
(
$idx
)
.
"')"
);
$rows
[]
=
array
(
'id'
=>
$i
,
'class'
=>
implode
(
' '
,
$class
),
'cells'
=>
$cells
);
}
}
}
else
{
$rows
[]
=
array
(
'cells'
=>
array
(
0
=>
array
(
'class'
=>
'empty-body'
,
'body'
=>
$this
->
translate
(
$task
.
'.norecords'
)
)));
}
$table
=
kolab_html
::
table
(
array
(
'id'
=>
$task
.
'list'
,
'class'
=>
$table_class
,
'head'
=>
$head
,
'body'
=>
$rows
,
'foot'
=>
$foot
,
));
if
(
$this
->
action
==
'list'
)
{
$this
->
output
->
command
(
'set_watermark'
,
'taskcontent'
);
}
$this
->
output
->
set_env
(
'search_request'
,
$search_request
?
base64_encode
(
serialize
(
$search_request
))
:
null
);
$this
->
output
->
set_env
(
'list_page'
,
$page
);
$this
->
output
->
set_env
(
'list_count'
,
$count
);
$this
->
output
->
set_env
(
'list_size'
,
count
(
$result
));
$this
->
output
->
set_object
(
$task
.
'list'
,
$table
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sun, Apr 5, 11:48 PM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18831625
Default Alt Text
kolab_client_task.php (55 KB)
Attached To
Mode
rWAP webadmin
Attached
Detach File
Event Timeline