mirror of
https://github.com/owncloudarchive/contacts.git
synced 2024-11-28 10:24:11 +01:00
after a painful rebase
This commit is contained in:
parent
f890fb5357
commit
de4bb76c53
17
admin.php
Normal file
17
admin.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - Contact Admin settings
|
||||
*
|
||||
* @author Nicolas Mora
|
||||
* @copyright 2014 Nicolas Mora mail@babelouest.org
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
*/
|
||||
|
||||
namespace OCA\Contacts;
|
||||
|
||||
\OCP\User::checkAdminUser();
|
||||
$tmpl = new \OCP\Template('contacts', 'admin');
|
||||
return $tmpl->fetchPage();
|
@ -53,18 +53,20 @@ $api->connectHook('OC_Calendar', 'getEvents', 'OCA\Contacts\Hooks', 'getBirthday
|
||||
$api->connectHook('OC_Calendar', 'getSources', 'OCA\Contacts\Hooks', 'getCalenderSources');
|
||||
|
||||
\OCP\Util::addscript('contacts', 'loader');
|
||||
\OCP\Util::addscript('contacts', 'admin');
|
||||
|
||||
\OC_Search::registerProvider('OCA\Contacts\SearchProvider');
|
||||
//\OCP\Share::registerBackend('contact', 'OCA\Contacts\Share_Backend_Contact');
|
||||
\OCP\Share::registerBackend('addressbook', 'OCA\Contacts\Share\Addressbook', 'contact');
|
||||
//\OCP\App::registerPersonal('contacts','personalsettings');
|
||||
\OCP\App::registerAdmin('contacts', 'admin');
|
||||
|
||||
if (\OCP\User::isLoggedIn()) {
|
||||
$app = new App($api->getUserId());
|
||||
$addressBooks = $app->getAddressBooksForUser();
|
||||
foreach ($addressBooks as $addressBook) {
|
||||
if ($addressBook->isActive()) {
|
||||
\OCP\Contacts::registerAddressBook($addressBook->getSearchProvider());
|
||||
\OCP\Contacts::registerAddressBook(new AddressbookProvider($addressBook));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,11 @@ $principalBackend = new OC_Connector_Sabre_Principal();
|
||||
|
||||
$addressbookbackends = array();
|
||||
$addressbookbackends[] = new OCA\Contacts\Backend\Database(\OCP\User::getUser());
|
||||
$carddavBackend = new OCA\Contacts\CardDAV\Backend(array('local', 'shared', 'ldap'));
|
||||
$backends = array('local', 'shared');
|
||||
if (\OCP\Config::getAppValue('contacts', 'backend_ldap', "false") === "true") {
|
||||
$backends[] = 'ldap'
|
||||
}
|
||||
$carddavBackend = new OCA\Contacts\CardDAV\Backend($backends);
|
||||
$requestBackend = new OC_Connector_Sabre_Request();
|
||||
|
||||
// Root nodes
|
||||
|
@ -34,6 +34,39 @@ $this->create('contacts_address_books_for_user', 'addressbooks/')
|
||||
}
|
||||
);
|
||||
|
||||
$this->create('contacts_address_book_connectors', 'connectors/{backend}')
|
||||
->get()
|
||||
->action(
|
||||
function($params) {
|
||||
\OC::$session->close();
|
||||
$dispatcher = new Dispatcher($params);
|
||||
$dispatcher->dispatch('BackendController', 'getConnectors');
|
||||
}
|
||||
)
|
||||
->requirements(array('backend'));
|
||||
|
||||
$this->create('contacts_backend_enable', 'backend/{backend}/{enable}')
|
||||
->get()
|
||||
->action(
|
||||
function($params) {
|
||||
\OC::$session->close();
|
||||
$dispatcher = new Dispatcher($params);
|
||||
$dispatcher->dispatch('BackendController', 'enableBackend');
|
||||
}
|
||||
)
|
||||
->requirements(array('backend', 'enable'));
|
||||
|
||||
$this->create('contacts_backend_status', 'backend/{backend}')
|
||||
->get()
|
||||
->action(
|
||||
function($params) {
|
||||
\OC::$session->close();
|
||||
$dispatcher = new Dispatcher($params);
|
||||
$dispatcher->dispatch('BackendController', 'backendStatus');
|
||||
}
|
||||
)
|
||||
->requirements(array('backend'));
|
||||
|
||||
$this->create('contacts_address_book_add', 'addressbook/{backend}/add')
|
||||
->post()
|
||||
->action(
|
||||
@ -428,4 +461,3 @@ $this->create('contacts_index_properties', 'indexproperties/{user}/')
|
||||
)
|
||||
->requirements(array('user'))
|
||||
->defaults(array('user' => \OCP\User::getUser()));
|
||||
|
||||
|
73
backendcontroller.php
Normal file
73
backendcontroller.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Nicolas Mora
|
||||
* @copyright 2014 Nicolas Mora (mail@babelouest.org)
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OCA\Contacts\Controller;
|
||||
|
||||
use OCA\Contacts\App,
|
||||
OCA\Contacts\JSONResponse,
|
||||
OCA\Contacts\Utils\JSONSerializer,
|
||||
OCA\Contacts\Controller,
|
||||
OCP\AppFramework\Http;
|
||||
|
||||
/**
|
||||
* Controller class For Address Books
|
||||
*/
|
||||
class BackendController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getConnectors() {
|
||||
$response = new JSONResponse();
|
||||
$prefix = "backend_ldap_";
|
||||
$suffix = "_connector.xml";
|
||||
$path = __DIR__ . "/../../formats/";
|
||||
$files = scandir($path);
|
||||
$formats = array();
|
||||
foreach ($files as $file) {
|
||||
if (!strncmp($file, $prefix, strlen($prefix)) && substr($file, - strlen($suffix)) === $suffix) {
|
||||
if (file_exists($path.$file)) {
|
||||
$format = simplexml_load_file ( $path.$file );
|
||||
if ($format) {
|
||||
if (isset($format['name'])) {
|
||||
$formatId = substr($file, strlen($prefix), - strlen($suffix));
|
||||
$formats[] = array('id' => $formatId, 'name' => (string)$format['name'], 'xml' => $format->asXML());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $response->setData($formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function enableBackend() {
|
||||
$response = new JSONResponse();
|
||||
$params = $this->request->urlParams;
|
||||
$backend = $params['backend'];
|
||||
$enable = $params['enable'];
|
||||
return $response->setData(\OCP\Config::setAppValue('contacts', 'backend_'.$backend, $enable));
|
||||
}
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function backendStatus() {
|
||||
$response = new JSONResponse();
|
||||
$params = $this->request->urlParams;
|
||||
$backend = $params['backend'];
|
||||
$enabled = \OCP\Config::getAppValue('contacts', 'backend_'.$backend, "false");
|
||||
return $response->setData($enabled);
|
||||
}
|
||||
}
|
||||
|
138
js/admin.js
Normal file
138
js/admin.js
Normal file
@ -0,0 +1,138 @@
|
||||
console.log($('#contacts-ldap-enabled'));
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
$.when(
|
||||
backendStatus(
|
||||
'ldap'
|
||||
))
|
||||
.then(function(response) {
|
||||
if(!response.error) {
|
||||
console.log('response', response.data);
|
||||
if (response.data === "true") {
|
||||
$('#contacts-ldap-enabled').prop('checked', true);
|
||||
}
|
||||
} else {
|
||||
console.warn('Error', response.message);
|
||||
}
|
||||
}).fail(function(response) {
|
||||
console.log(response.message);
|
||||
});
|
||||
|
||||
$('#contacts-ldap-enabled').change(function() {
|
||||
var enabled=$(this).prop('checked')?"true":"false";
|
||||
$.when(
|
||||
enableBackend(
|
||||
'ldap',
|
||||
enabled
|
||||
))
|
||||
.then(function(response) {
|
||||
if(!response.error) {
|
||||
console.log('response', response.data);
|
||||
} else {
|
||||
console.warn('Error', response.message);
|
||||
}
|
||||
}).fail(function(response) {
|
||||
console.log(response.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function requestRoute(route, type, routeParams, params, additionalHeaders) {
|
||||
var isJSON = (typeof params === 'string');
|
||||
var contentType = isJSON
|
||||
? (type === 'PATCH' ? 'application/json-merge-patch' : 'application/json')
|
||||
: 'application/x-www-form-urlencoded';
|
||||
var processData = !isJSON;
|
||||
contentType += '; charset=UTF-8';
|
||||
var url = OC.generateUrl('apps/contacts/' + route, routeParams);
|
||||
var headers = {
|
||||
Accept : 'application/json; charset=utf-8'
|
||||
};
|
||||
if(typeof additionalHeaders === 'object') {
|
||||
headers = $.extend(headers, additionalHeaders);
|
||||
}
|
||||
var ajaxParams = {
|
||||
type: type,
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
headers: headers,
|
||||
contentType: contentType,
|
||||
processData: processData,
|
||||
data: params
|
||||
};
|
||||
|
||||
var defer = $.Deferred();
|
||||
|
||||
$.ajax(ajaxParams)
|
||||
.done(function(response, textStatus, jqXHR) {
|
||||
console.log(jqXHR);
|
||||
defer.resolve(new JSONResponse(jqXHR));
|
||||
})
|
||||
.fail(function(jqXHR/*, textStatus, error*/) {
|
||||
console.log(jqXHR);
|
||||
var response = jqXHR.responseText ? $.parseJSON(jqXHR.responseText) : null;
|
||||
console.log('response', response);
|
||||
defer.reject(new JSONResponse(jqXHR));
|
||||
});
|
||||
|
||||
return defer.promise();
|
||||
}
|
||||
|
||||
function enableBackend(backend, enable, params) {
|
||||
return this.requestRoute(
|
||||
'backend/{backend}/{enable}',
|
||||
'GET',
|
||||
{backend: backend, enable: enable},
|
||||
JSON.stringify(params)
|
||||
);
|
||||
}
|
||||
|
||||
function backendStatus(backend, params) {
|
||||
return this.requestRoute(
|
||||
'backend/{backend}',
|
||||
'GET',
|
||||
{backend: backend},
|
||||
JSON.stringify(params)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
var JSONResponse = function(jqXHR) {
|
||||
this.getAllResponseHeaders = jqXHR.getAllResponseHeaders;
|
||||
this.getResponseHeader = jqXHR.getResponseHeader;
|
||||
this.statusCode = jqXHR.status;
|
||||
var response = jqXHR.responseJSON;
|
||||
this.error = false;
|
||||
console.log('jqXHR', jqXHR);
|
||||
if (!response) {
|
||||
// 204 == No content
|
||||
// 304 == Not modified
|
||||
if ([204, 304].indexOf(this.statusCode) === -1) {
|
||||
this.error = true;
|
||||
}
|
||||
this.message = jqXHR.statusText;
|
||||
} else {
|
||||
// We need to allow for both the 'old' success/error status property
|
||||
// with the body in the data property, and the newer where we rely
|
||||
// on the status code, and the entire body is used.
|
||||
if (response.status === 'error'|| this.statusCode >= 400) {
|
||||
this.error = true;
|
||||
if (!response.data || !response.data.message) {
|
||||
this.message = t('contacts', 'Server error! Please inform system administator');
|
||||
} else {
|
||||
console.log('JSONResponse', response);
|
||||
this.message = (response.data && response.data.message)
|
||||
? response.data.message
|
||||
: response;
|
||||
}
|
||||
} else {
|
||||
this.data = response.data || response;
|
||||
// Kind of a hack
|
||||
if (response.metadata) {
|
||||
this.metadata = response.metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -13,6 +13,7 @@ namespace OCA\Contacts;
|
||||
use Sabre\VObject,
|
||||
OCP\AppFramework,
|
||||
OCA\Contacts\Controller\AddressBookController,
|
||||
OCA\Contacts\Controller\BackendController,
|
||||
OCA\Contacts\Controller\GroupController,
|
||||
OCA\Contacts\Controller\ContactController,
|
||||
OCA\Contacts\Controller\ContactPhotoController,
|
||||
@ -53,7 +54,6 @@ class App {
|
||||
* @var array
|
||||
*/
|
||||
public static $backendClasses = array(
|
||||
'ldap' => 'OCA\Contacts\Backend\Ldap',
|
||||
'local' => 'OCA\Contacts\Backend\Database',
|
||||
'shared' => 'OCA\Contacts\Backend\Shared',
|
||||
'localusers' => 'OCA\Contacts\Backend\LocalUsers',
|
||||
@ -71,6 +71,9 @@ class App {
|
||||
$this->dbBackend = $dbBackend
|
||||
? $dbBackend
|
||||
: new Backend\Database($user);
|
||||
if (\OCP\Config::getAppValue('contacts', 'backend_ldap', "false") === "true") {
|
||||
self::$backendClasses['ldap'] = 'OCA\Contacts\Backend\Ldap';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,10 +38,15 @@ class Ldap extends AbstractBackend {
|
||||
* @var string
|
||||
*/
|
||||
public $name='ldap';
|
||||
static private $preparedQueries = array();
|
||||
private $ldapConnection = null;
|
||||
private $connector = null;
|
||||
|
||||
/**
|
||||
* The cached address books.
|
||||
* @var array[]
|
||||
*/
|
||||
public $addressbooks;
|
||||
|
||||
/**
|
||||
* @brief validates and sets the ldap parameters
|
||||
* @param $ldapParams array containing the parameters
|
||||
@ -50,7 +55,7 @@ class Ldap extends AbstractBackend {
|
||||
public function setLdapParams($aid) {
|
||||
$tmp = $this->getPreferences($aid);
|
||||
if ($tmp != false) {
|
||||
$this->ldapParams = $tmp;
|
||||
$this->ldapParams = (array)$tmp;
|
||||
$this->connector = new LdapConnector($this->ldapParams['ldap_vcard_connector']);
|
||||
return true;
|
||||
} else {
|
||||
@ -213,12 +218,7 @@ class Ldap extends AbstractBackend {
|
||||
*/
|
||||
public function ldapUpdate($ldapDN, $ldapValues) {
|
||||
if (self::ldapIsConnected()) {
|
||||
$result = @ldap_modify($this->ldapConnection, $ldapDN, $ldapValues);
|
||||
if (!$result) {
|
||||
self::ldapDelete($ldapDN);
|
||||
return self::ldapAdd($ldapDN, $ldapValues);
|
||||
}
|
||||
return true;
|
||||
return @ldap_modify($this->ldapConnection, $ldapDN, $ldapValues);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -257,12 +257,10 @@ class Ldap extends AbstractBackend {
|
||||
*/
|
||||
public function getAddressBooksForUser(array $options = array()) {
|
||||
$addressbookidList = $this->getAddressbookList();
|
||||
$this->addressbooks = array();
|
||||
foreach($addressbookidList as $addressbookid) {
|
||||
$this->addressbooks[] = self::getAddressBook($addressbookid);
|
||||
}
|
||||
return $this->addressbooks;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,16 +284,19 @@ class Ldap extends AbstractBackend {
|
||||
}
|
||||
// Hmm, not found. Lets query the db.
|
||||
$preferences = self::getPreferences($addressbookid);
|
||||
if ($preferences != false) {
|
||||
$current = array();
|
||||
$current['id'] = (string)$addressbookid;
|
||||
$current['displayname'] = (string)$preferences['displayname'];
|
||||
$current['description'] = (string)$preferences['description'];
|
||||
$current['owner'] = $this->userid;
|
||||
$current['uri'] = (string)$preferences['uri'];
|
||||
$current['permissions'] = \OCP\PERMISSION_ALL;
|
||||
$current['lastmodified'] = self::lastModifiedAddressBook($addressbookid);
|
||||
return $current;
|
||||
if (count($preferences) > 0) {
|
||||
$preferences['id'] = (string)$addressbookid;
|
||||
$preferences['backend'] = $this->name;
|
||||
$preferences['owner'] = $this->userid;
|
||||
$preferences['permissions'] = \OCP\PERMISSION_ALL;
|
||||
$preferences['lastmodified'] = self::lastModifiedAddressBook($addressbookid);
|
||||
|
||||
// remove the ldappassword from the return value if exists
|
||||
if (isset($preferences['ldappass']) && (isset($options['getpwd']) && !$options['getpwd'])) {
|
||||
unset($preferences['ldappass']);
|
||||
}
|
||||
|
||||
return $preferences;
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
@ -322,14 +323,22 @@ class Ldap extends AbstractBackend {
|
||||
*
|
||||
* @param string $addressbookid
|
||||
* @param array $properties
|
||||
* @return bool
|
||||
* @return string|false The ID if the modified AddressBook or false on error.
|
||||
*/
|
||||
public function updateAddressBook($addressbookid, array $properties, array $options = array()) {
|
||||
// TODO: use backend settings
|
||||
|
||||
return true;
|
||||
if ($this->hasAddressBook($addressbookid)) {
|
||||
// Addressbook exists, modify it through the create function
|
||||
if (isset($properties['ldappassmodified']) && $properties['ldappassmodified'] != 'true') {
|
||||
// If password hasn't changed, get it from the preferences
|
||||
$addrbook = $this->getAddressBook($addressbookid, array('getpwd' => true));
|
||||
$properties['ldappass'] = base64_decode($addrbook['ldappass']);
|
||||
}
|
||||
return $this->setAddressBook($properties, $options);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new address book
|
||||
*
|
||||
@ -341,7 +350,80 @@ class Ldap extends AbstractBackend {
|
||||
* @return string|false The ID if the newly created AddressBook or false on error.
|
||||
*/
|
||||
public function createAddressBook(array $properties, array $options = array()) {
|
||||
// TODO: use backend settings
|
||||
if (!isset($properties['uri']) || $this->hasAddressBook($properties['uri'])) {
|
||||
return false;
|
||||
} else {
|
||||
return $this->setAddressBook($properties, $options);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the parameters for a new or existing addressbook
|
||||
*
|
||||
* @param array $properties
|
||||
* @return string|false The ID if the newly created AddressBook or false on error.
|
||||
*/
|
||||
public function setAddressBook(array $properties, array $options = array()) {
|
||||
if (count($properties) === 0) {
|
||||
return false;
|
||||
}
|
||||
if (isset($properties['displayname']) && $properties['displayname'] != '' &&
|
||||
isset($properties['uri']) && $properties['uri'] != '' &&
|
||||
isset($properties['ldapurl']) && $properties['ldapurl'] != '' &&
|
||||
isset($properties['ldappagesize']) && $properties['ldappagesize'] != '' &&
|
||||
isset($properties['ldapbasednsearch']) && $properties['ldapbasednsearch'] != '' &&
|
||||
isset($properties['ldapfilter']) && $properties['ldapfilter'] != '' &&
|
||||
isset($properties['ldapvcardconnector']) &&
|
||||
isset($properties['ldapanonymous']) &&
|
||||
($properties['ldapanonymous']=='true'
|
||||
|| ($properties['ldapanonymous']=='false'
|
||||
&& isset($properties['ldapuser']) && $properties['ldapuser'] != ''
|
||||
&& isset($properties['ldappass']) && $properties['ldappass'] != ''
|
||||
)
|
||||
) &&
|
||||
isset($properties['ldapreadonly']) &&
|
||||
($properties['ldapreadonly']=='true'
|
||||
|| ($properties['ldapreadonly']=='false'
|
||||
&& isset($properties['ldapbasednmodify']) && $properties['ldapbasednmodify'] != ''
|
||||
)
|
||||
)
|
||||
) {
|
||||
$addressbookSettings = array();
|
||||
$addressbookSettings['uri'] = $properties['uri'];
|
||||
$addressbookSettings['displayname'] = $properties['displayname'];
|
||||
$addressbookSettings['description'] = $properties['description'];
|
||||
$addressbookSettings['ldapurl'] = $properties['ldapurl'];
|
||||
$addressbookSettings['ldapanonymous'] = ($properties['ldapanonymous']=='true');
|
||||
$addressbookSettings['ldapreadonly'] = ($properties['ldapreadonly']=='true');
|
||||
$addressbookSettings['ldapuser'] = ($properties['ldapanonymous']=='false')?$properties['ldapuser']:"";
|
||||
$addressbookSettings['ldappass'] = ($properties['ldapanonymous']=='false')?base64_encode($properties['ldappass']):"";
|
||||
$addressbookSettings['ldappagesize'] = $properties['ldappagesize'];
|
||||
$addressbookSettings['ldapbasednsearch'] = $properties['ldapbasednsearch'];
|
||||
$addressbookSettings['ldapfilter'] = $properties['ldapfilter'];
|
||||
$addressbookSettings['ldapbasednmodify'] = ($properties['ldapanonymous']=='false')?$properties['ldapbasednmodify']:"";
|
||||
$addressbookSettings['ldapconnectorid'] = $properties['ldapvcardconnector'];
|
||||
|
||||
if ($properties['ldapvcardconnector'] != '') {
|
||||
$prefix = "backend_ldap_";
|
||||
$suffix = "_connector.xml";
|
||||
$path = __DIR__ . "/../../formats/";
|
||||
if (file_exists( $path.$prefix.$properties['ldapvcardconnector'].$suffix )) {
|
||||
$addressbookSettings['ldap_vcard_connector'] = file_get_contents ( $path.$prefix.$properties['ldapvcardconnector'].$suffix );
|
||||
}
|
||||
} else {
|
||||
$addressbookSettings['ldap_vcard_connector'] = $properties['ldapvcardconnectorvalue'];
|
||||
}
|
||||
|
||||
$addressbookList = $this->getAddressbookList();
|
||||
if (!in_array($properties['uri'], $addressbookList)) {
|
||||
$addressbookList[] = $properties['uri'];
|
||||
$this->setAddressbookList($addressbookList);
|
||||
}
|
||||
$this->setPreferences($properties['uri'], $addressbookSettings);
|
||||
$this->setActive(1, $properties['uri']);
|
||||
return $properties['uri'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,27 +433,21 @@ class Ldap extends AbstractBackend {
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteAddressBook($addressbookid, array $options = array()) {
|
||||
$addressbook = self::getAddressBook($addressbookid);
|
||||
//$addressbook = self::getAddressBook($addressbookid);
|
||||
$addressbookList = $this->getAddressbookList();
|
||||
$toRemove = array_search($addressbookid, $addressbookList);
|
||||
if (is_int($toRemove)) {
|
||||
unset($addressbookList[$toRemove]);
|
||||
$addressbookList = array_values($addressbookList);
|
||||
$this->setAddressbookList($addressbookList);
|
||||
}
|
||||
|
||||
self::removePreferences($addressbookid);
|
||||
|
||||
// TODO: use backend settings
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the last modification time for an address book.
|
||||
*
|
||||
* Must return a UNIX time stamp or null if the backend
|
||||
* doesn't support it.
|
||||
*
|
||||
* TODO: Implement default methods get/set for backends that
|
||||
* don't support.
|
||||
* @param string $addressbookid
|
||||
* @returns int | null
|
||||
*/
|
||||
public function lastModifiedAddressBook($addressbookid, array $options = array()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all contacts for a specific addressbook id.
|
||||
*
|
||||
@ -399,6 +475,16 @@ class Ldap extends AbstractBackend {
|
||||
* @return array
|
||||
*/
|
||||
public function getContacts($addressbookid, array $options = array()) {
|
||||
$backtrace = debug_backtrace();
|
||||
$trace=array();
|
||||
foreach ($backtrace as $elt) {
|
||||
foreach ($elt as $key => $line) {
|
||||
if ($key == "file" || $key == "line") {
|
||||
$trace[] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cards = array();
|
||||
$vcards = array();
|
||||
if(is_array($addressbookid) && count($addressbookid)) {
|
||||
@ -448,7 +534,6 @@ class Ldap extends AbstractBackend {
|
||||
|
||||
$cards = array();
|
||||
$toReturn = false;
|
||||
self::setLdapParams($addressbookid);
|
||||
if (self::setLdapParams($addressbookid)) {
|
||||
foreach ($a_ids as $id) {
|
||||
$cid = str_replace(".vcf", "", $id);
|
||||
@ -465,7 +550,7 @@ class Ldap extends AbstractBackend {
|
||||
$this->connector->getLdapEntries());
|
||||
} else {
|
||||
$card = self::ldapFindOne(base64_decode($cid),
|
||||
'objectClass=*',
|
||||
$this->ldapParams['ldapfilter'],
|
||||
$this->connector->getLdapEntries());
|
||||
}
|
||||
}
|
||||
@ -501,7 +586,7 @@ class Ldap extends AbstractBackend {
|
||||
$URI = (string)$vcard->{'X-LDAP-DN'};
|
||||
}
|
||||
return array('id' => $UID,
|
||||
'permissions' => \OCP\PERMISSION_READ,
|
||||
'permissions' => \OCP\PERMISSION_ALL,
|
||||
'displayname' => $FN,
|
||||
'carddata' => $vcard->serialize(),
|
||||
'uri' => $URI,
|
||||
@ -516,25 +601,16 @@ class Ldap extends AbstractBackend {
|
||||
* @return string|bool The identifier for the new contact or false on error.
|
||||
*/
|
||||
public function createContact($addressbookid, $contact, array $options = array()) {
|
||||
$backtrace = debug_backtrace();
|
||||
$trace=array();
|
||||
foreach ($backtrace as $elt) {
|
||||
foreach ($elt as $key => $line) {
|
||||
if ($key == "file" || $key == "line") {
|
||||
$trace[] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
//error_log("stay added ".print_r($trace,1));
|
||||
|
||||
$uri = isset($options['uri']) ? $options['uri'] : null;
|
||||
|
||||
$contact->REV = (new \DateTime)->format(\DateTime::W3C);
|
||||
|
||||
// 2014/02/13 Sometimes, a card is created without a name (I don't like that)...
|
||||
if (!isset($contact->N)) {
|
||||
$generated = "gruik".rand(0, 65535);
|
||||
$generated = "nocn-".rand(0, 65535);
|
||||
$contact->N = $generated;
|
||||
$contact->FN = $generated;
|
||||
error_log("Generated name: $generated");
|
||||
}
|
||||
|
||||
if(!$contact instanceof VCard) {
|
||||
@ -545,7 +621,6 @@ class Ldap extends AbstractBackend {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
error_log("adding ".$contact->serialize());
|
||||
|
||||
try {
|
||||
$contact->validate(VCard::REPAIR|VCard::UPGRADE);
|
||||
@ -588,16 +663,6 @@ class Ldap extends AbstractBackend {
|
||||
* @return bool
|
||||
*/
|
||||
public function updateContact($addressbookid, $id, $carddata, array $options = array()) {
|
||||
$backtrace = debug_backtrace();
|
||||
$trace=array();
|
||||
foreach ($backtrace as $elt) {
|
||||
foreach ($elt as $key => $line) {
|
||||
if ($key == "file" || $key == "line") {
|
||||
$trace[] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
//error_log("stay modified ".print_r($trace,1));
|
||||
if(!$carddata instanceof VCard) {
|
||||
try {
|
||||
$vcard = \Sabre\VObject\Reader::read($carddata);
|
||||
@ -609,7 +674,14 @@ class Ldap extends AbstractBackend {
|
||||
$vcard = $carddata;
|
||||
}
|
||||
|
||||
//error_log("updating ".$vcard->serialize());
|
||||
try {
|
||||
$vcard->validate(VCard::REPAIR|VCard::UPGRADE);
|
||||
} catch (\Exception $e) {
|
||||
OCP\Util::writeLog('contacts', __METHOD__ . ' ' .
|
||||
'Error validating vcard: ' . $e->getMessage(), \OCP\Util::ERROR);
|
||||
return false;
|
||||
}
|
||||
//$vcard->REV = (new \DateTime)->format(\DateTime::W3C);
|
||||
|
||||
if (!is_array($id)) {
|
||||
$a_ids = array($id);
|
||||
@ -631,6 +703,8 @@ class Ldap extends AbstractBackend {
|
||||
$dn = base64_decode($tmpVCard->{'X-LDAP-DN'});
|
||||
}
|
||||
// Updates the existing card
|
||||
$ldifSource = self::ldapFindOne($dn, $this->ldapParams['ldapfilter'], $this->connector->getLdapEntries());
|
||||
$this->connector->insertEmptyEntries($ldifSource, $ldifEntries);
|
||||
$result = self::ldapUpdate($dn, $ldifEntries);
|
||||
}
|
||||
self::ldapCloseConnection();
|
||||
@ -645,19 +719,8 @@ class Ldap extends AbstractBackend {
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteContact($addressbookid, $id, array $options = array()) {
|
||||
$backtrace = debug_backtrace();
|
||||
$trace=array();
|
||||
foreach ($backtrace as $elt) {
|
||||
foreach ($elt as $key => $line) {
|
||||
if ($key == "file" || $key == "line") {
|
||||
$trace[] = $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
//error_log("stay dead ".print_r($trace, 1));
|
||||
self::setLdapParams($addressbookid);
|
||||
self::ldapCreateAndBindConnection();
|
||||
$card=null;
|
||||
if (is_array($id)) {
|
||||
$card = self::getContact($addressbookid, $id);
|
||||
} else {
|
||||
@ -694,20 +757,33 @@ class Ldap extends AbstractBackend {
|
||||
}
|
||||
}
|
||||
|
||||
// Please remove this
|
||||
public function debug_string_backtrace() {
|
||||
ob_start();
|
||||
debug_print_backtrace();
|
||||
$trace = ob_get_contents();
|
||||
ob_end_clean();
|
||||
/**
|
||||
* @brief sets the list of ldap addressbooks in the preferences
|
||||
* with the list given in parameter
|
||||
* @param the new list
|
||||
* @returns result|false
|
||||
*/
|
||||
protected function setAddressbookList(array $addressbookList) {
|
||||
$key = $this->name . "_list";
|
||||
$data = json_encode($addressbookList);
|
||||
|
||||
return $data
|
||||
? \OCP\Config::setUserValue($this->userid, 'contacts', $key, $data)
|
||||
: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets the list of ldap addressbooks in the preferences
|
||||
* returns array()
|
||||
*/
|
||||
protected function getAddressbookList() {
|
||||
$key = $this->name . "_list";
|
||||
$data = \OCP\Config::getUserValue($this->userid, 'contacts', $key, false);
|
||||
|
||||
return $data ? json_decode($data) : array();
|
||||
}
|
||||
|
||||
// Remove first item from backtrace as it's this function which
|
||||
// is redundant.
|
||||
$trace = preg_replace ('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);
|
||||
|
||||
// Renumber backtrace items.
|
||||
$trace = preg_replace ('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);
|
||||
|
||||
return $trace;
|
||||
}
|
||||
public function getSearchProvider($addressbook) {
|
||||
return new \OCA\Contacts\AddressbookProvider($addressbook);
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,14 @@ class LdapConnector {
|
||||
\OCP\Util::writeLog('ldap_vcard_connector', __METHOD__.', error in setting xml config', \OCP\Util::DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
private function convertDate ($ldapDate) {
|
||||
|
||||
$tstamp = strtotime($ldapDate);
|
||||
$theDate = new \DateTime;
|
||||
$theDate->setTimestamp($tstamp);
|
||||
|
||||
return $theDate;
|
||||
}
|
||||
/**
|
||||
* @brief transform a ldap entry into an VCard object
|
||||
* for each ldap entry which is like "property: value"
|
||||
@ -43,26 +50,27 @@ class LdapConnector {
|
||||
*/
|
||||
public function ldapToVCard($ldapEntry) {
|
||||
$vcard = \Sabre\VObject\Component::create('VCARD');
|
||||
$vcard->REV = $ldapEntry['modifytimestamp'][0];
|
||||
$vcard->REV = $this->convertDate($ldapEntry['modifytimestamp'][0])->format(\DateTime::W3C);
|
||||
//error_log("modifytimestamp: ".$vcard->REV);
|
||||
$vcard->{'X-LDAP-DN'} = base64_encode($ldapEntry['dn']);
|
||||
// OCP\Util::writeLog('ldap_vcard_connector', __METHOD__.' vcard is '.$vcard->serialize(), \OCP\Util::DEBUG);
|
||||
|
||||
for ($i=0; $i<$ldapEntry["count"]; $i++) {
|
||||
// ldap property name : $ldap_entry[$i]
|
||||
$l_property = $ldapEntry[$i];
|
||||
for ($j=0;$j<$ldapEntry[$l_property]["count"];$j++){
|
||||
$lProperty = $ldapEntry[$i];
|
||||
for ($j=0;$j<$ldapEntry[$lProperty]["count"];$j++){
|
||||
|
||||
// What to do :
|
||||
// convert the ldap property into vcard property, type and position (if needed)
|
||||
// $v_params format: array('property' => property, 'type' => array(types), 'position' => position)
|
||||
$v_params = $this->getVCardProperty($l_property);
|
||||
$v_params = $this->getVCardProperty($lProperty);
|
||||
|
||||
foreach ($v_params as $v_param) {
|
||||
|
||||
if (isset($v_param['unassigned'])) {
|
||||
// if the value comes from the unassigned entry, it's a vcard property dumped
|
||||
try {
|
||||
$property = \Sabre\VObject\Reader::read($ldapEntry[$l_property][$j]);
|
||||
$property = \Sabre\VObject\Reader::read($ldapEntry[$lProperty][$j]);
|
||||
$vcard->add($property);
|
||||
} catch (exception $e) {
|
||||
}
|
||||
@ -74,9 +82,9 @@ class LdapConnector {
|
||||
|
||||
// modify the property with the new data
|
||||
if (strcasecmp($v_param['image'], 'true') == 0) {
|
||||
$this->updateVCardImageProperty($v_property, $ldapEntry[$l_property][$j], $vcard->VERSION);
|
||||
$this->updateVCardImageProperty($v_property, $ldapEntry[$lProperty][$j], $vcard->VERSION);
|
||||
} else {
|
||||
$this->updateVCardProperty($v_property, $ldapEntry[$l_property][$j], $v_param['position']);
|
||||
$this->updateVCardProperty($v_property, $ldapEntry[$lProperty][$j], $v_param['position']);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,7 +94,6 @@ class LdapConnector {
|
||||
if (!isset($vcard->UID)) {
|
||||
$vcard->UID = base64_encode($ldapEntry['dn']);
|
||||
}
|
||||
$vcard->validate(\Sabre\VObject\Component\VCard::REPAIR);
|
||||
return $vcard;
|
||||
}
|
||||
|
||||
@ -179,16 +186,16 @@ class LdapConnector {
|
||||
|
||||
/**
|
||||
* @brief gets the vcard property values from an ldif entry name
|
||||
* @param $l_property the ldif property name
|
||||
* @param $lProperty the ldif property name
|
||||
* @return array('property' => property, 'type' => type, 'position' => position)
|
||||
*/
|
||||
public function getVCardProperty($l_property) {
|
||||
public function getVCardProperty($lProperty) {
|
||||
$properties = array();
|
||||
if (strcmp($l_property, $this->getUnassignedVCardProperty()) == 0) {
|
||||
if (strcmp($lProperty, $this->getUnassignedVCardProperty()) == 0) {
|
||||
$properties[] = array('unassigned' => true);
|
||||
} else {
|
||||
foreach ($this->config_content->ldap_entries->ldif_entry as $ldif_entry) {
|
||||
if ($l_property == $ldif_entry['name']) {
|
||||
if ($lProperty == $ldif_entry['name']) {
|
||||
// $ldif_entry['name'] is the right config xml
|
||||
foreach ($ldif_entry->vcard_entry as $vcard_entry) {
|
||||
$type=isset($vcard_entry['type'])?$vcard_entry['type']:"";
|
||||
@ -421,6 +428,22 @@ class LdapConnector {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief adds empty entries in $dest if $dest doesn't have those entries and if $source has
|
||||
* otherwise, I couldn't find how to remove attributes
|
||||
* @param $source the source ldap entry as model
|
||||
* @param $dest the destination entry to add empty params if we have to
|
||||
*/
|
||||
public function insertEmptyEntries($source, &$dest) {
|
||||
for ($i=0; $i<$source["count"]; $i++) {
|
||||
|
||||
$lProperty = $source[$i];
|
||||
if (!isset($dest[$lProperty]) && $lProperty != 'modifytimestamp') {
|
||||
$dest[$lProperty] = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
73
lib/controller/backendcontroller.php
Normal file
73
lib/controller/backendcontroller.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Nicolas Mora
|
||||
* @copyright 2014 Nicolas Mora (mail@babelouest.org)
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
namespace OCA\Contacts\Controller;
|
||||
|
||||
use OCA\Contacts\App,
|
||||
OCA\Contacts\JSONResponse,
|
||||
OCA\Contacts\Utils\JSONSerializer,
|
||||
OCA\Contacts\Controller,
|
||||
OCP\AppFramework\Http;
|
||||
|
||||
/**
|
||||
* Controller class For Address Books
|
||||
*/
|
||||
class BackendController extends Controller {
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getConnectors() {
|
||||
$response = new JSONResponse();
|
||||
$prefix = "backend_ldap_";
|
||||
$suffix = "_connector.xml";
|
||||
$path = __DIR__ . "/../../formats/";
|
||||
$files = scandir($path);
|
||||
$formats = array();
|
||||
foreach ($files as $file) {
|
||||
if (!strncmp($file, $prefix, strlen($prefix)) && substr($file, - strlen($suffix)) === $suffix) {
|
||||
if (file_exists($path.$file)) {
|
||||
$format = simplexml_load_file ( $path.$file );
|
||||
if ($format) {
|
||||
if (isset($format['name'])) {
|
||||
$formatId = substr($file, strlen($prefix), - strlen($suffix));
|
||||
$formats[] = array('id' => $formatId, 'name' => (string)$format['name'], 'xml' => $format->asXML());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $response->setData($formats);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function enableBackend() {
|
||||
$response = new JSONResponse();
|
||||
$params = $this->request->urlParams;
|
||||
$backend = $params['backend'];
|
||||
$enable = $params['enable'];
|
||||
return $response->setData(\OCP\Config::setAppValue('contacts', 'backend_'.$backend, $enable));
|
||||
}
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function backendStatus() {
|
||||
$response = new JSONResponse();
|
||||
$params = $this->request->urlParams;
|
||||
$backend = $params['backend'];
|
||||
$enabled = \OCP\Config::getAppValue('contacts', 'backend_'.$backend, "false");
|
||||
return $response->setData($enabled);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,8 @@ use OCP\AppFramework\App as MainApp,
|
||||
OCA\Contacts\Controller\ContactPhotoController,
|
||||
OCA\Contacts\Controller\SettingsController,
|
||||
OCA\Contacts\Controller\ImportController,
|
||||
OCA\Contacts\Controller\ExportController;
|
||||
OCA\Contacts\Controller\ExportController,
|
||||
OCA\Contacts\Controller\BackendController;
|
||||
|
||||
/**
|
||||
* This class manages our app actions
|
||||
@ -105,6 +106,10 @@ class Dispatcher extends MainApp {
|
||||
$request = $container->query('Request');
|
||||
return new ExportController($appName, $request, $app);
|
||||
});
|
||||
$this->container->registerService('BackendController', function(IAppContainer $container) use($appName, $app) {
|
||||
$request = $container->query('Request');
|
||||
return new BackendController($appName, $request, $app);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
21
templates/admin.php
Normal file
21
templates/admin.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ownCloud - Contacts
|
||||
*
|
||||
* @author Nicolas Mora
|
||||
* @copyright 2014 Nicolas Mora mail@babelouest.org
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later.
|
||||
*/
|
||||
|
||||
?>
|
||||
|
||||
<div class="section">
|
||||
<h2>Contacts</h2>
|
||||
<input type="checkbox" name="contacts-ldap-enabled" id="contacts-ldap-enabled" value="checked"/>
|
||||
<label for="contacts-ldap-enabled"><?php p($l->t('Enable LDAP Backend')) ?></label><br>
|
||||
<em><?php p($l->t('Enable LDAP backend for the contacts application')) ?></em>
|
||||
<br/><em><?php p($l->t('Warning: LDAP Backend is in beta mode, use with precautions')) ?></em>
|
||||
</div>
|
@ -1,3 +1,6 @@
|
||||
<?php
|
||||
use OCA\Contacts\ImportManager;
|
||||
?>
|
||||
<div id="app">
|
||||
<div id="app-navigation" class="loading">
|
||||
<ul id="grouplist" class="hidden-on-load">
|
||||
@ -20,6 +23,15 @@
|
||||
<ul class="addressbooklist">
|
||||
</ul>
|
||||
<input type="text" tabindex="0" autofocus id="add-address-book" placeholder="<?php p($l->t('Display name')); ?>" title="<?php p($l->t('Add Address Book')); ?>" />
|
||||
<?php
|
||||
if (\OCP\Config::getAppValue('contacts', 'backend_ldap', "false") === "true") {
|
||||
?>
|
||||
<ul class="oc-addnew">
|
||||
<li id="add-ldap-address-book-element"><a class="oc-addnew-init"><?php p($l->t('Add LDAP Address Book')); ?></a></li>
|
||||
</ul>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div id="import">
|
||||
<h2 data-id="import" tabindex="0" role="button"><?php p($l->t('Import')); ?></h2>
|
||||
@ -31,7 +43,8 @@
|
||||
<select id="import_format">
|
||||
<option value="automatic"><?php p($l->t('Automatic format')); ?></option>
|
||||
<?php
|
||||
$types = $_['importManager']->getTypes();
|
||||
$importManager = new ImportManager();
|
||||
$types = $importManager->getTypes();
|
||||
foreach ($types as $id => $label) {
|
||||
echo "<option value=\"$id\">$label</option>";
|
||||
}
|
||||
@ -503,3 +516,117 @@
|
||||
</span>
|
||||
</li>
|
||||
</script>
|
||||
|
||||
<script id="addressBookConfigTemplate" class="hidden" type="text/template">
|
||||
<div id="addressbooks-ui-div" class="addressbooks-ui-class">
|
||||
<input type="hidden" id="addressbooks-ui-addressbookid" />
|
||||
<input type="hidden" id="addressbooks-ui-backend" value="{backend}" />
|
||||
<p id="addressbooks-ui-name-p">
|
||||
<label for="addressbooks-ui-name">
|
||||
<?php p($l->t('Name')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-name" value=""
|
||||
placeholder="<?php p($l->t('Name')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-uri-p">
|
||||
<label for="addressbooks-ui-uri">
|
||||
<?php p($l->t('Addressbook URI')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-uri" value=""
|
||||
placeholder="<?php p($l->t('URI')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-description-p">
|
||||
<label for="addressbooks-ui-description">
|
||||
<?php p($l->t('Description')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-description" value=""
|
||||
placeholder="<?php p($l->t('Description')); ?>" />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapurl-p">
|
||||
<label for="addressbooks-ui-ldapurl">
|
||||
<?php p($l->t('LDAP URL')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-ldapurl" value=""
|
||||
placeholder="<?php p($l->t('LDAP URL')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapanonymous-p">
|
||||
<label for="addressbooks-ui-ldapanonymous">
|
||||
<?php p($l->t('Anonymous')); ?>:
|
||||
</label>
|
||||
<input type="checkbox" id="addressbooks-ui-ldapanonymous" title="<?php p($l->t('Anonymous')); ?>" />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapreadonly-p">
|
||||
<label for="addressbooks-ui-ldapreadonly">
|
||||
<?php p($l->t('Read-only')); ?>:
|
||||
</label>
|
||||
<input type="checkbox" id="addressbooks-ui-ldapreadonly" title="<?php p($l->t('Read-Only')); ?>" />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapuser-p">
|
||||
<label for="addressbooks-ui-ldapuser">
|
||||
<?php p($l->t('User')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-ldapuser" value=""
|
||||
placeholder="<?php p($l->t('User')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldappass-p">
|
||||
<input type="hidden" id="addressbooks-ui-ldappass-modified" />
|
||||
<label for="addressbooks-ui-ldappass">
|
||||
<?php p($l->t('Password')); ?>:
|
||||
</label>
|
||||
<input type="password" class="nonempty value" id="addressbooks-ui-ldappass" value=""
|
||||
placeholder="<?php p($l->t('Password')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldappagesize-p">
|
||||
<label for="addressbooks-ui-ldappagesize">
|
||||
<?php p($l->t('Page size')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-ldappagesize" value="20"
|
||||
placeholder="<?php p($l->t('Page size')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapbasednsearch-p">
|
||||
<label for="addressbooks-ui-ldapbasednsearch">
|
||||
<?php p($l->t('Base DN for search')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-ldapbasednsearch" value=""
|
||||
placeholder="<?php p($l->t('Base DN')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapfilter-p">
|
||||
<label for="addressbooks-ui-ldapfilter">
|
||||
<?php p($l->t('Search filter')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-ldapfilter" value=""
|
||||
placeholder="<?php p($l->t('Filter')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapbasednmodify-p">
|
||||
<label for="addressbooks-ui-ldapbasednmodify">
|
||||
<?php p($l->t('Base DN for modification')); ?>:
|
||||
</label>
|
||||
<input type="text" class="nonempty value" id="addressbooks-ui-ldapbasednmodify" value=""
|
||||
placeholder="<?php p($l->t('Base DN modification')); ?>" required />
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapvcardconnector-p">
|
||||
<label for="addressbooks-ui-ldapvcardconnector">
|
||||
<?php p($l->t('Connector')); ?>:
|
||||
</label>
|
||||
<select id="addressbooks-ui-ldapvcardconnector">
|
||||
</select>
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapvcardconnector-value-p">
|
||||
<label for="addressbooks-ui-ldapvcardconnector-value">
|
||||
<?php p($l->t('Connector value (Better use external editor and copy/paste)')); ?>:
|
||||
</label>
|
||||
<textarea id="addressbooks-ui-ldapvcardconnector-value"></textarea>
|
||||
</p>
|
||||
<p id="addressbooks-ui-ldapvcardconnector-copyfrom-p">
|
||||
<label for="addressbooks-ui-ldapvcardconnector-copyfrom">
|
||||
<?php p($l->t('Copy from (Warning, replaces current custom value)')); ?>:
|
||||
</label>
|
||||
<select id="addressbooks-ui-ldapvcardconnector-copyfrom">
|
||||
</select>
|
||||
</p>
|
||||
<p id="addressbooks-ui-errortitle-p">
|
||||
</p>
|
||||
<p id="addressbooks-ui-errormessage-p">
|
||||
</p>
|
||||
</div>
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user