summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorGeorg Ehrke <dev@georgswebsite.de>2012-04-26 18:08:49 +0200
committerGeorg Ehrke <dev@georgswebsite.de>2012-04-26 18:08:49 +0200
commit2b10371bdeb2c8a3d5cc2617ada5cf8195c264c9 (patch)
treef25b463c90992764887416c3082098fed6ecac65 /apps
parent40f95ffdf3edf9ab45c15bd5b9018d7f4d92baa9 (diff)
parent127796218314c6b1f19ba86f74caa913375aac8d (diff)
downloadnextcloud-server-2b10371bdeb2c8a3d5cc2617ada5cf8195c264c9.tar.gz
nextcloud-server-2b10371bdeb2c8a3d5cc2617ada5cf8195c264c9.zip
fix merge conflicts
Diffstat (limited to 'apps')
-rw-r--r--apps/calendar/ajax/event/edit.form.php6
-rw-r--r--apps/calendar/ajax/event/move.php12
-rw-r--r--apps/calendar/ajax/event/resize.php4
-rwxr-xr-xapps/calendar/ajax/events.php1
-rw-r--r--apps/calendar/lib/object.php14
-rw-r--r--apps/calendar/lib/search.php2
-rw-r--r--apps/contacts/ajax/uploadimport.php39
-rw-r--r--apps/contacts/css/contacts.css2
-rw-r--r--apps/contacts/import.php5
-rw-r--r--apps/contacts/js/contacts.js58
-rw-r--r--apps/contacts/templates/part.contact.php2
-rw-r--r--apps/files/ajax/scan.php3
-rw-r--r--apps/files/css/files.css8
-rw-r--r--apps/files/index.php2
-rw-r--r--apps/files/js/fileactions.js15
-rw-r--r--apps/files/js/filelist.js1
-rw-r--r--apps/files/js/files.js286
-rw-r--r--apps/files/templates/index.php5
-rw-r--r--apps/files/templates/part.list.php4
-rw-r--r--apps/files_encryption/lib/cryptstream.php15
-rw-r--r--apps/files_encryption/lib/proxy.php17
-rw-r--r--apps/files_external/lib/swift.php17
-rw-r--r--apps/files_sharing/ajax/email.php15
-rw-r--r--apps/files_sharing/ajax/toggleresharing.php13
-rw-r--r--apps/files_sharing/appinfo/app.php9
-rw-r--r--apps/files_sharing/js/settings.js9
-rw-r--r--apps/files_sharing/js/share.js21
-rw-r--r--apps/files_sharing/lib_share.php28
-rw-r--r--apps/files_sharing/settings.php9
-rw-r--r--apps/files_sharing/templates/settings.php6
-rw-r--r--apps/files_versions/appinfo/app.php1
-rw-r--r--apps/files_versions/css/versions.css5
-rw-r--r--apps/files_versions/history.php39
-rw-r--r--apps/files_versions/js/versions.js65
-rw-r--r--apps/files_versions/templates/history.php4
-rw-r--r--apps/files_versions/versions.php2
-rw-r--r--apps/user_ldap/appinfo/database.xml95
-rw-r--r--apps/user_ldap/appinfo/version2
-rw-r--r--apps/user_ldap/group_ldap.php63
-rw-r--r--apps/user_ldap/js/settings.js3
-rw-r--r--apps/user_ldap/lib_ldap.php407
-rw-r--r--apps/user_ldap/settings.php9
-rw-r--r--apps/user_ldap/templates/settings.php31
43 files changed, 1141 insertions, 213 deletions
diff --git a/apps/calendar/ajax/event/edit.form.php b/apps/calendar/ajax/event/edit.form.php
index ec50b78be6f..e963da32958 100644
--- a/apps/calendar/ajax/event/edit.form.php
+++ b/apps/calendar/ajax/event/edit.form.php
@@ -27,15 +27,15 @@ $vevent = $object->VEVENT;
$dtstart = $vevent->DTSTART;
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
switch($dtstart->getDateType()) {
- case Sabre_VObject_Element_DateTime::LOCALTZ:
- case Sabre_VObject_Element_DateTime::LOCAL:
+ case Sabre_VObject_Property_DateTime::LOCALTZ:
+ case Sabre_VObject_Property_DateTime::LOCAL:
$startdate = $dtstart->getDateTime()->format('d-m-Y');
$starttime = $dtstart->getDateTime()->format('H:i');
$enddate = $dtend->getDateTime()->format('d-m-Y');
$endtime = $dtend->getDateTime()->format('H:i');
$allday = false;
break;
- case Sabre_VObject_Element_DateTime::DATE:
+ case Sabre_VObject_Property_DateTime::DATE:
$startdate = $dtstart->getDateTime()->format('d-m-Y');
$starttime = '';
$dtend->getDateTime()->modify('-1 day');
diff --git a/apps/calendar/ajax/event/move.php b/apps/calendar/ajax/event/move.php
index 0552c7bbc5b..75d174c13e1 100644
--- a/apps/calendar/ajax/event/move.php
+++ b/apps/calendar/ajax/event/move.php
@@ -27,19 +27,19 @@ $dtstart = $vevent->DTSTART;
$dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent);
$start_type = $dtstart->getDateType();
$end_type = $dtend->getDateType();
-if ($allday && $start_type != Sabre_VObject_Element_DateTime::DATE){
- $start_type = $end_type = Sabre_VObject_Element_DateTime::DATE;
+if ($allday && $start_type != Sabre_VObject_Property_DateTime::DATE){
+ $start_type = $end_type = Sabre_VObject_Property_DateTime::DATE;
$dtend->setDateTime($dtend->getDateTime()->modify('+1 day'), $end_type);
}
-if (!$allday && $start_type == Sabre_VObject_Element_DateTime::DATE){
- $start_type = $end_type = Sabre_VObject_Element_DateTime::LOCALTZ;
+if (!$allday && $start_type == Sabre_VObject_Property_DateTime::DATE){
+ $start_type = $end_type = Sabre_VObject_Property_DateTime::LOCALTZ;
}
$dtstart->setDateTime($dtstart->getDateTime()->add($delta), $start_type);
$dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
unset($vevent->DURATION);
-$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
$result = OC_Calendar_Object::edit($id, $vcalendar->serialize());
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
diff --git a/apps/calendar/ajax/event/resize.php b/apps/calendar/ajax/event/resize.php
index 593835d86c5..260b6914426 100644
--- a/apps/calendar/ajax/event/resize.php
+++ b/apps/calendar/ajax/event/resize.php
@@ -30,8 +30,8 @@ $end_type = $dtend->getDateType();
$dtend->setDateTime($dtend->getDateTime()->add($delta), $end_type);
unset($vevent->DURATION);
-$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
-$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+$vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+$vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
OC_Calendar_Object::edit($id, $vcalendar->serialize());
$lastmodified = $vevent->__get('LAST-MODIFIED')->getDateTime();
diff --git a/apps/calendar/ajax/events.php b/apps/calendar/ajax/events.php
index 3aa487fd231..8adaa4c98f3 100755
--- a/apps/calendar/ajax/events.php
+++ b/apps/calendar/ajax/events.php
@@ -20,7 +20,6 @@ $events = OC_Calendar_App::getrequestedEvents($_GET['calendar_id'], $start, $end
$output = array();
foreach($events as $event){
$output[] = OC_Calendar_App::generateEventOutput($event, $start, $end);
-
}
OC_JSON::encodedPrint($output);
?>
diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php
index 825977c17c5..ae6fce3c842 100644
--- a/apps/calendar/lib/object.php
+++ b/apps/calendar/lib/object.php
@@ -590,7 +590,7 @@ class OC_Calendar_Object{
$vevent = new OC_VObject('VEVENT');
$vcalendar->add($vevent);
- $vevent->setDateTime('CREATED', 'now', Sabre_VObject_Element_DateTime::UTC);
+ $vevent->setDateTime('CREATED', 'now', Sabre_VObject_Property_DateTime::UTC);
$vevent->setUID();
return self::updateVCalendarFromRequest($request, $vcalendar);
@@ -751,22 +751,22 @@ class OC_Calendar_Object{
}
- $vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC);
- $vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC);
+ $vevent->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC);
+ $vevent->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC);
$vevent->setString('SUMMARY', $title);
if($allday){
$start = new DateTime($from);
$end = new DateTime($to.' +1 day');
- $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Element_DateTime::DATE);
- $vevent->setDateTime('DTEND', $end, Sabre_VObject_Element_DateTime::DATE);
+ $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::DATE);
+ $vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::DATE);
}else{
$timezone = OC_Preferences::getValue(OC_USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
$timezone = new DateTimeZone($timezone);
$start = new DateTime($from.' '.$fromtime, $timezone);
$end = new DateTime($to.' '.$totime, $timezone);
- $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Element_DateTime::LOCALTZ);
- $vevent->setDateTime('DTEND', $end, Sabre_VObject_Element_DateTime::LOCALTZ);
+ $vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::LOCALTZ);
+ $vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::LOCALTZ);
}
unset($vevent->DURATION);
diff --git a/apps/calendar/lib/search.php b/apps/calendar/lib/search.php
index da5fa35bc21..0e1a9032666 100644
--- a/apps/calendar/lib/search.php
+++ b/apps/calendar/lib/search.php
@@ -26,7 +26,7 @@ class OC_Search_Provider_Calendar extends OC_Search_Provider{
$start_dt->setTimezone(new DateTimeZone($user_timezone));
$end_dt = $dtend->getDateTime();
$end_dt->setTimezone(new DateTimeZone($user_timezone));
- if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE){
+ if ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE){
$end_dt->modify('-1 sec');
if($start_dt->format('d.m.Y') != $end_dt->format('d.m.Y')){
$info = $l->t('Date') . ': ' . $start_dt->format('d.m.Y') . ' - ' . $end_dt->format('d.m.Y');
diff --git a/apps/contacts/ajax/uploadimport.php b/apps/contacts/ajax/uploadimport.php
index ab680c8823f..f44335a961e 100644
--- a/apps/contacts/ajax/uploadimport.php
+++ b/apps/contacts/ajax/uploadimport.php
@@ -34,17 +34,52 @@ function debug($msg) {
OC_Log::write('contacts','ajax/uploadimport.php: '.$msg, OC_Log::DEBUG);
}
+$view = OC_App::getStorage('contacts');
+$tmpfile = md5(rand());
+
// If it is a Drag'n'Drop transfer it's handled here.
$fn = (isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : false);
if($fn) {
- $view = OC_App::getStorage('contacts');
- $tmpfile = md5(rand());
if($view->file_put_contents('/'.$tmpfile, file_get_contents('php://input'))) {
debug($fn.' uploaded');
OC_JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+ exit();
} else {
bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
}
}
+// File input transfers are handled here
+if (!isset($_FILES['importfile'])) {
+ OC_Log::write('contacts','ajax/uploadphoto.php: No file was uploaded. Unknown error.', OC_Log::DEBUG);
+ OC_JSON::error(array('data' => array( 'message' => 'No file was uploaded. Unknown error' )));
+ exit();
+}
+$error = $_FILES['importfile']['error'];
+if($error !== UPLOAD_ERR_OK) {
+ $errors = array(
+ 0=>OC_Contacts_App::$l10n->t("There is no error, the file uploaded with success"),
+ 1=>OC_Contacts_App::$l10n->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
+ 2=>OC_Contacts_App::$l10n->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
+ 3=>OC_Contacts_App::$l10n->t("The uploaded file was only partially uploaded"),
+ 4=>OC_Contacts_App::$l10n->t("No file was uploaded"),
+ 6=>OC_Contacts_App::$l10n->t("Missing a temporary folder")
+ );
+ bailOut($errors[$error]);
+}
+$file=$_FILES['importfile'];
+
+$tmpfname = tempnam("/tmp", "occOrig");
+if(file_exists($file['tmp_name'])) {
+ if($view->file_put_contents('/'.$tmpfile, file_get_contents($file['tmp_name']))) {
+ debug($fn.' uploaded');
+ OC_JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+ } else {
+ bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
+ }
+} else {
+ bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?');
+}
+
+
?>
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index 0bb9f975fc5..e3d2cfbdd66 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -100,4 +100,4 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.propertylist li > input[type="checkbox"],input[type="radio"] { float: left; clear: left; width: 20px; height: 20px; vertical-align: middle; }
.propertylist li > select { float: left; max-width: 8em; }
.typelist { float: left; max-width: 10em; } /* for multiselect */
-.addresslist { clear: both; } \ No newline at end of file
+.addresslist { clear: both; }
diff --git a/apps/contacts/import.php b/apps/contacts/import.php
index ca2c1e1605d..8e0a427399b 100644
--- a/apps/contacts/import.php
+++ b/apps/contacts/import.php
@@ -24,6 +24,11 @@ if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
} else {
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
}
+if(!$file) {
+ OC_JSON::error(array('message' => 'Import file was empty.'));
+ exit();
+}
+error_log('File: '.$file);
if(isset($_POST['method']) && $_POST['method'] == 'new'){
$id = OC_Contacts_Addressbook::add(OC_User::getUser(), $_POST['addressbookname']);
OC_Contacts_Addressbook::setActive($id, 1);
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index 18edb40a3cb..7e0fe8b41cf 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -1287,6 +1287,7 @@ Contacts={
},
Addressbooks:{
droptarget:undefined,
+ droptext:t('contacts', 'Drop a VCF file to import contacts.'),
overview:function(){
if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
$('#chooseaddressbook_dialog').dialog('moveToTop');
@@ -1345,8 +1346,16 @@ Contacts={
}
},
loadImportHandlers:function() {
+ $('#import_upload_start').change(function(){
+ Contacts.UI.Addressbooks.uploadImport(this.files);
+ });
+ $('#importaddressbook_dialog').find('.upload').click(function() {
+ Contacts.UI.Addressbooks.droptarget.html(t('contacts', 'Uploading...'));
+ Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
+ $('#import_upload_start').trigger('click');
+ });
+ $('#importaddressbook_dialog').find('.upload').tipsy();
this.droptarget = $('#import_drop_target');
- console.log($('#import_drop_target').html());
$(this.droptarget).bind('dragover',function(event){
$(event.target).addClass('droppable');
event.stopPropagation();
@@ -1371,13 +1380,13 @@ Contacts={
console.log('size: '+file.size+', type: '+file.type);
if(file.size > $('#max_upload').val()){
OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts','Upload too large'));
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
return;
}
if(file.type.indexOf('text') != 0) {
OC.dialogs.alert(t('contacts','You have dropped a file type that cannot be imported: ') + file.type, t('contacts','Wrong file type'));
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
return;
}
@@ -1392,11 +1401,9 @@ Contacts={
response = $.parseJSON(xhr.responseText);
if(response.status == 'success') {
if(xhr.status == 200) {
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Importing...'));
- Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
} else {
- $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Drop a VCF file to import contacts.'));
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
}
@@ -1405,7 +1412,7 @@ Contacts={
}
}
};
- xhr.open("POST", 'ajax/uploadimport.php?file='+encodeURIComponent(file.name), true);
+ xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name), true);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
@@ -1414,12 +1421,39 @@ Contacts={
xhr.send(file);
}
},
+ uploadImport:function(filelist) {
+ if(!filelist) {
+ OC.dialogs.alert(t('contacts','No files selected for upload.'), t('contacts', 'Error'));
+ return;
+ }
+ //var file = filelist.item(0);
+ var file = filelist[0];
+ var target = $('#import_upload_target');
+ var form = $('#import_upload_form');
+ var totalSize=0;
+ if(file.size > $('#max_upload').val()){
+ OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts', 'Error'));
+ return;
+ } else {
+ target.load(function(){
+ var response=jQuery.parseJSON(target.contents().text());
+ if(response != undefined && response.status == 'success'){
+ Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
+ }else{
+ OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
+ }
+ });
+ form.submit();
+ }
+ },
importAddressbook:function(object){
var tr = $(document.createElement('tr'))
.load(OC.filePath('contacts', 'ajax', 'importaddressbook.php'));
$(object).closest('tr').after(tr).hide();
},
doImport:function(path, file){
+ $(Contacts.UI.Addressbooks.droptarget).html(t('contacts', 'Importing...'));
+ Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, true);
var id = $('#importaddressbook_dialog').find('#book').val();
console.log('Selected book: ' + id);
$.post(OC.filePath('contacts', '', 'import.php'), { id: id, path: path, file: file, fstype: 'OC_FilesystemView' },
@@ -1428,6 +1462,10 @@ Contacts={
Contacts.UI.Addressbooks.droptarget.html(t('contacts', 'Import done. Success/Failure: ')+jsondata.data.imported+'/'+jsondata.data.failed);
$('#chooseaddressbook_dialog').find('#close_button').val(t('contacts', 'OK'));
Contacts.UI.Contacts.update();
+ setTimeout(
+ function() {
+ $(Contacts.UI.Addressbooks.droptarget).html(Contacts.UI.Addressbooks.droptext);
+ }, 5000);
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
@@ -1590,7 +1628,7 @@ $(document).ready(function(){
* Profile picture upload handling
*/
// New profile picture selected
- $('#file_upload_start').live('change',function(){
+ $('#file_upload_start').change(function(){
Contacts.UI.Card.uploadPhoto(this.files);
});
$('#contacts_details_photo_wrapper').bind('dragover',function(event){
@@ -1662,7 +1700,7 @@ $(document).ready(function(){
};
// Start loading indicator.
//$('#contacts_details_photo_progress').show()();
- xhr.open("POST", OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&imagefile='+encodeURIComponent(file.name), true);
+ xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&imagefile='+encodeURIComponent(file.name), true);
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
@@ -1691,4 +1729,4 @@ $(document).ready(function(){
Contacts.UI.Card.addProperty(type);
$('#contacts_propertymenu').hide();
});
-}); \ No newline at end of file
+});
diff --git a/apps/contacts/templates/part.contact.php b/apps/contacts/templates/part.contact.php
index dec081a9b89..64a024c0926 100644
--- a/apps/contacts/templates/part.contact.php
+++ b/apps/contacts/templates/part.contact.php
@@ -24,7 +24,6 @@ $id = isset($_['id']) ? $_['id'] : '';
<div id="contact_photo" class="contactsection">
<form class="float" id="file_upload_form" action="ajax/uploadphoto.php" method="post" enctype="multipart/form-data" target="file_upload_target">
- <fieldset id="photo">
<div class="tip propertycontainer" id="contacts_details_photo_wrapper" title="<?php echo $l->t('Click or drop to upload picture'); ?> (max <?php echo $_['uploadMaxHumanFilesize']; ?>)" data-element="PHOTO">
<!-- img style="padding: 1em;" id="contacts_details_photo" alt="Profile picture" src="photo.php?id=<?php echo $_['id']; ?>" / -->
<progress id="contacts_details_photo_progress" style="display:none;" value="0" max="100">0 %</progress>
@@ -34,7 +33,6 @@ $id = isset($_['id']) ? $_['id'] : '';
<input type="hidden" class="max_human_file_size" value="(max <?php echo $_['uploadMaxHumanFilesize']; ?>)">
<input id="file_upload_start" type="file" accept="image/*" name="imagefile" />
<iframe name="file_upload_target" id='file_upload_target' src=""></iframe>
- </fieldset>
</form>
</div> <!-- contact_photo -->
diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php
index 488f68e6b3c..a227dcc3ffc 100644
--- a/apps/files/ajax/scan.php
+++ b/apps/files/ajax/scan.php
@@ -3,6 +3,7 @@
set_time_limit(0);//scanning can take ages
$force=isset($_GET['force']) and $_GET['force']=='true';
+$dir=isset($_GET['dir'])?$_GET['dir']:'';
$checkOnly=isset($_GET['checkonly']) and $_GET['checkonly']=='true';
if(!$checkOnly){
@@ -14,7 +15,7 @@ if(!$checkOnly){
if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OC_DB::beginTransaction();
- OC_FileCache::scan('',$eventSource);
+ OC_FileCache::scan($dir,$eventSource);
OC_FileCache::clean();
OC_DB::commit();
$eventSource->send('success',true);
diff --git a/apps/files/css/files.css b/apps/files/css/files.css
index 99623b6355e..a135f7ded5b 100644
--- a/apps/files/css/files.css
+++ b/apps/files/css/files.css
@@ -30,6 +30,8 @@
.file_upload_filename { position: relative; z-index:100; padding-left: 0.8em; padding-right: 0.8em; cursor:pointer; border-top-left-radius:0; border-bottom-left-radius:0; }
.file_upload_filename img { position: absolute; top: 0.4em; left: 0.4em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
+#upload { position:absolute; right:13.5em; top:0em; }
+#upload #uploadprogressbar { position:relative; display:inline-block; width:10em; height:1.5em; top:.4em; }
.file_upload_form, .file_upload_wrapper, .file_upload_start, .file_upload_filename, #file_upload_submit { cursor:pointer; }
@@ -41,7 +43,7 @@ tbody tr { background-color:#fff; height:2.5em; }
tbody tr:hover, tbody tr:active, tbody tr.selected { background-color:#f8f8f8; }
tbody tr.selected { background-color:#eee; }
tbody a { color:#000; }
-span.extension, td.date { color:#999; }
+span.extension, span.uploading, td.date { color:#999; }
span.extension { text-transform:lowercase; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; filter:alpha(opacity=70); opacity:.7; -webkit-transition:opacity 300ms; -moz-transition:opacity 300ms; -o-transition:opacity 300ms; transition:opacity 300ms; }
tr:hover span.extension { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; color:#777; }
div.crumb { float:left; display:block; background:no-repeat right 0; padding:.75em 1.5em 0 1em; height:2.9em; }
@@ -60,8 +62,10 @@ table td.filename a.name { display:block; height:1.5em; vertical-align:middle; m
table tr[data-type="dir"] td.filename a.name span.nametext {font-weight:bold; }
table td.filename a.name input, table td.filename a.name form { width:100%; cursor:text; }
table td.filename a, table td.login, table td.logout, table td.download, table td.upload, table td.create, table td.delete { padding:.2em .5em .5em 0; }
-table td.filename .nametext, .modified { float:left; padding:.3em 0; }
+table td.filename .nametext, .uploadtext, .modified { float:left; padding:.3em 0; }
+// TODO fix usability bug (accidental file/folder selection)
table td.filename .nametext { width:70%; overflow:hidden; }
+table td.filename .uploadtext { font-weight:normal; margin-left:.5em; }
table td.filename form { float:left; font-size:.85em; }
table thead.fixed tr{ position:fixed; top:6.5em; z-index:49; -moz-box-shadow:0 -3px 7px #ddd; -webkit-box-shadow:0 -3px 7px #ddd; box-shadow:0 -3px 7px #ddd; }
table thead.fixed { height:2em; }
diff --git a/apps/files/index.php b/apps/files/index.php
index 46b511d66eb..8464db30f01 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -26,6 +26,8 @@ OC_Util::checkLoggedIn();
// Load the files we need
OC_Util::addStyle( "files", "files" );
+OC_Util::addScript( "files", "jquery.iframe-transport" );
+OC_Util::addScript( "files", "jquery.fileupload" );
OC_Util::addScript( "files", "files" );
OC_Util::addScript( 'files', 'filelist' );
OC_Util::addScript( 'files', 'fileactions' );
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 481802e0d63..68268a7d3a9 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -140,7 +140,20 @@ $(document).ready(function(){
});
FileActions.register('all','Delete',function(){return OC.imagePath('core','actions/delete')},function(filename){
- FileList.do_delete(filename);
+ if(Files.cancelUpload(filename)) {
+ if(filename.substr){
+ filename=[filename];
+ }
+ $.each(filename,function(index,file){
+ var filename = $('tr').filterAttr('data-file',file);
+ filename.hide();
+ filename.find('input[type="checkbox"]').removeAttr('checked');
+ filename.removeClass('selected');
+ });
+ procesSelection();
+ }else{
+ FileList.do_delete(filename);
+ }
});
FileActions.register('all','Rename',function(){return OC.imagePath('core','actions/rename')},function(filename){
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 5bd85fc29ef..febdfc473b1 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -43,6 +43,7 @@ FileList={
td.append('<input type="checkbox" />');
var link_elem = $('<a></a>').attr({ "class": "name", "href": "index.php?dir="+ encodeURIComponent($('#dir').val()+'/'+name).replace(/%2F/g, '/') });
link_elem.append($('<span></span>').addClass('nametext').text(name));
+ link_elem.append($('<span></span>').attr({'class': 'uploadtext', 'currentUploads': 0}));
td.append(link_elem);
html.append(td);
if(size!='Pending'){
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 9d83e5e6d26..2dce00035e1 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -1,3 +1,32 @@
+var uploadingFiles = {};
+Files={
+ cancelUpload:function(filename) {
+ if(uploadingFiles[filename]) {
+ uploadingFiles[filename].abort();
+ delete uploadingFiles[filename];
+ return true;
+ }
+ return false;
+ },
+ cancelUploads:function() {
+ $.each(uploadingFiles,function(index,file) {
+ if(typeof file['abort'] === 'function') {
+ file.abort();
+ var filename = $('tr').filterAttr('data-file',index);
+ filename.hide();
+ filename.find('input[type="checkbox"]').removeAttr('checked');
+ filename.removeClass('selected');
+ } else {
+ $.each(file,function(i,f) {
+ f.abort();
+ delete file[i];
+ });
+ }
+ delete uploadingFiles[index];
+ });
+ procesSelection();
+ }
+}
$(document).ready(function() {
$('#fileList tr').each(function(){
//little hack to set unescape filenames in attribute
@@ -151,83 +180,205 @@ $(document).ready(function() {
return false;
});
- $('.file_upload_start').live('change',function(){
- var form=$(this).closest('form');
- var that=this;
- var uploadId=form.attr('data-upload-id');
- var files=this.files;
- var target=form.children('iframe');
- var totalSize=0;
- if(files){
- for(var i=0;i<files.length;i++){
- totalSize+=files[i].size;
- if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
- FileList.finishDelete(function(){
- $(that).change();
- });
- return;
- }
- }
- }
- if(totalSize>$('#max_upload').val()){
- $( "#uploadsize-message" ).dialog({
- modal: true,
- buttons: {
- Close: function() {
- $( this ).dialog( "close" );
+ // drag&drop support using jquery.fileupload
+ // TODO use OC.dialogs
+ $(document).bind('drop dragover', function (e) {
+ e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
+ });
+
+ $(function() {
+ $('.file_upload_start').fileupload({
+ dropZone: $('#content'), // restrict dropZone to content div
+ add: function(e, data) {
+ var files = data.files;
+ var totalSize=0;
+ if(files){
+ for(var i=0;i<files.length;i++){
+ totalSize+=files[i].size;
+ if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
+ FileList.finishDelete(function(){
+ $('.file_upload_start').change();
+ });
+ return;
+ }
}
}
- });
- }else{
- target.load(function(){
- var response=jQuery.parseJSON(target.contents().find('body').text());
- //set mimetype and if needed filesize
- if(response){
- if(response[0] != undefined && response[0].status == 'success'){
- for(var i=0;i<response.length;i++){
- var file=response[i];
+ if(totalSize>$('#max_upload').val()){
+ $( '#uploadsize-message' ).dialog({
+ modal: true,
+ buttons: {
+ Close: function() {
+ $( this ).dialog( 'close' );
+ }
+ }
+ });
+ }else{
+ if($.support.xhrFileUpload) {
+ for(var i=0;i<files.length;i++){
+ var fileName = files[i].name
+ var dropTarget = $(e.originalEvent.target).closest('tr');
+ if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
+ var dirName = dropTarget.attr('data-file')
+ var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i],
+ formData: function(form) {
+ var formArray = form.serializeArray();
+ formArray[1]['value'] = dirName;
+ return formArray;
+ }}).success(function(result, textStatus, jqXHR) {
+ var response;
+ response=jQuery.parseJSON(result);
+ if(response[0] == undefined || response[0].status != 'success') {
+ $('#notification').text(t('files', response.data.message));
+ $('#notification').fadeIn();
+ }
+ var file=response[0];
+ delete uploadingFiles[dirName][file.name];
+ var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+ currentUploads -= 1;
+ uploadtext.attr('currentUploads', currentUploads);
+ if(currentUploads === 0) {
+ var img = OC.imagePath('core', 'filetypes/folder.png');
+ var tr=$('tr').filterAttr('data-file',dirName);
+ tr.find('td.filename').attr('style','background-image:url('+img+')');
+ uploadtext.text('');
+ uploadtext.hide();
+ } else {
+ uploadtext.text(currentUploads + ' files uploading')
+ }
+ })
+ .error(function(jqXHR, textStatus, errorThrown) {
+ if(errorThrown === 'abort') {
+ var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+ currentUploads -= 1;
+ uploadtext.attr('currentUploads', currentUploads);
+ if(currentUploads === 0) {
+ var img = OC.imagePath('core', 'filetypes/folder.png');
+ var tr=$('tr').filterAttr('data-file',dirName);
+ tr.find('td.filename').attr('style','background-image:url('+img+')');
+ uploadtext.text('');
+ uploadtext.hide();
+ } else {
+ uploadtext.text(currentUploads + ' files uploading')
+ }
+ $('#notification').hide();
+ $('#notification').text(t('files', 'Upload cancelled.'));
+ $('#notification').fadeIn();
+ }
+ });
+ //TODO test with filenames containing slashes
+ if(uploadingFiles[dirName] === undefined) {
+ uploadingFiles[dirName] = {};
+ }
+ uploadingFiles[dirName][fileName] = jqXHR;
+ } else {
+ var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i]})
+ .success(function(result, textStatus, jqXHR) {
+ var response;
+ response=jQuery.parseJSON(result);
+ if(response[0] != undefined && response[0].status == 'success') {
+ var file=response[0];
+ delete uploadingFiles[file.name];
+ $('tr').filterAttr('data-file',file.name).data('mime',file.mime);
+ var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
+ if(size==t('files','Pending')){
+ $('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
+ }
+ FileList.loadingDone(file.name);
+ } else {
+ $('#notification').text(t('files', response.data.message));
+ $('#notification').fadeIn();
+ $('#fileList > tr').not('[data-mime]').fadeOut();
+ $('#fileList > tr').not('[data-mime]').remove();
+ }
+ })
+ .error(function(jqXHR, textStatus, errorThrown) {
+ if(errorThrown === 'abort') {
+ $('#notification').hide();
+ $('#notification').text(t('files', 'Upload cancelled.'));
+ $('#notification').fadeIn();
+ }
+ });
+ uploadingFiles[files[i].name] = jqXHR;
+ }
+ }
+ }else{
+ data.submit().success(function(data, status) {
+ response = jQuery.parseJSON(data[0].body.innerText);
+ if(response[0] != undefined && response[0].status == 'success') {
+ var file=response[0];
+ delete uploadingFiles[file.name];
$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
- if(size=='Pending'){
+ var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
+ if(size==t('files','Pending')){
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
}
FileList.loadingDone(file.name);
+ } else {
+ $('#notification').text(t('files', response.data.message));
+ $('#notification').fadeIn();
+ $('#fileList > tr').not('[data-mime]').fadeOut();
+ $('#fileList > tr').not('[data-mime]').remove();
}
- }
- else{
- $('#notification').text(t('files',response.data.message));
- $('#notification').fadeIn();
- $('#fileList > tr').not('[data-mime]').fadeOut();
- $('#fileList > tr').not('[data-mime]').remove();
- }
+ });
}
- });
- form.submit();
- var date=new Date();
- if(files){
- for(var i=0;i<files.length;i++){
- if(files[i].size>0){
- var size=files[i].size;
- }else{
- var size=t('files','Pending');
- }
+
+ var date=new Date();
if(files){
+ for(var i=0;i<files.length;i++){
+ if(files[i].size>0){
+ var size=files[i].size;
+ }else{
+ var size=t('files','Pending');
+ }
+ if(files && !dirName){
FileList.addFile(getUniqueName(files[i].name),size,date,true);
+ } else if(dirName) {
+ var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
+ var currentUploads = parseInt(uploadtext.attr('currentUploads'));
+ currentUploads += 1;
+ uploadtext.attr('currentUploads', currentUploads);
+ if(currentUploads === 1) {
+ var img = OC.imagePath('core', 'loading.gif');
+ var tr=$('tr').filterAttr('data-file',dirName);
+ tr.find('td.filename').attr('style','background-image:url('+img+')');
+ uploadtext.text('1 file uploading');
+ uploadtext.show();
+ } else {
+ uploadtext.text(currentUploads + ' files uploading')
+ }
+ }
+ }
+ }else{
+ var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
+ FileList.addFile(getUniqueName(filename),'Pending',date,true);
}
}
- }else{
- var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
- FileList.addFile(getUniqueName(filename),'Pending',date,true);
+ },
+ fail: function(e, data) {
+ // TODO: cancel upload & display error notification
+ },
+ progress: function(e, data) {
+ // TODO: show nice progress bar in file row
+ },
+ progressall: function(e, data) {
+ var progress = (data.loaded/data.total)*100;
+ $('#uploadprogressbar').progressbar('value',progress);
+ },
+ start: function(e, data) {
+ $('#uploadprogressbar').progressbar({value:0});
+ $('#uploadprogressbar').fadeIn();
+ if(data.dataType != 'iframe ') {
+ $('#upload input.stop').show();
+ }
+ },
+ stop: function(e, data) {
+ if(data.dataType != 'iframe ') {
+ $('#upload input.stop').hide();
+ }
+ $('#uploadprogressbar').progressbar('value',100);
+ $('#uploadprogressbar').fadeOut();
}
-
- //clone the upload form and hide the new one to allow users to start a new upload while the old one is still uploading
- var clone=form.clone();
- uploadId++;
- clone.attr('data-upload-id',uploadId);
- clone.attr('target','file_upload_target_'+uploadId);
- clone.children('iframe').attr('name','file_upload_target_'+uploadId)
- clone.insertBefore(form);
- form.hide();
- }
+ })
});
//add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
@@ -370,12 +521,15 @@ $(document).ready(function() {
}, "json");
});
-function scanFiles(force){
+function scanFiles(force,dir){
+ if(!dir){
+ dir='';
+ }
force=!!force; //cast to bool
scanFiles.scanning=true;
$('#scanning-message').show();
$('#fileList').remove();
- var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force});
+ var scannerEventSource=new OC.EventSource(OC.filePath('files','ajax','scan.php'),{force:force,dir:dir});
scanFiles.cancel=scannerEventSource.close.bind(scannerEventSource);
scannerEventSource.listen('scanning',function(data){
$('#scan-count').text(data.count+' files scanned');
diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php
index 3571950467e..fc385e1ed3a 100644
--- a/apps/files/templates/index.php
+++ b/apps/files/templates/index.php
@@ -22,6 +22,11 @@
<iframe name="file_upload_target_1" class='file_upload_target' src=""></iframe>
</form>
</div>
+ <div id="upload">
+ <div id="uploadprogressbar"></div>
+ <input type="button" class="stop" style="display:none" value="<?php echo $l->t('Cancel upload');?>" onclick="javascript:Files.cancelUploads();" />
+ </div>
+
</div>
<div id="file_action_panel"></div>
<?php else:?>
diff --git a/apps/files/templates/part.list.php b/apps/files/templates/part.list.php
index 5a5941fc7ae..b2db4cbb8df 100644
--- a/apps/files/templates/part.list.php
+++ b/apps/files/templates/part.list.php
@@ -21,6 +21,10 @@
<?php echo htmlspecialchars($file['basename']);?><span class='extension'><?php echo $file['extension'];?></span>
<?php endif;?>
</span>
+ <?php if($file['type'] == 'dir'):?>
+ <span class="uploadtext" currentUploads="0">
+ </span>
+ <?php endif;?>
</a>
</td>
<td class="filesize" title="<?php echo human_file_size($file['size']); ?>" style="color:rgb(<?php echo $simple_size_color.','.$simple_size_color.','.$simple_size_color ?>)"><?php echo $simple_file_size; ?></td>
diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php
index 21fa38e4b59..07a2e523a42 100644
--- a/apps/files_encryption/lib/cryptstream.php
+++ b/apps/files_encryption/lib/cryptstream.php
@@ -33,6 +33,7 @@ class OC_CryptStream{
private $path;
private $readBuffer;//for streams that dont support seeking
private $meta=array();//header/meta for source stream
+ private $count;
public function stream_open($path, $mode, $options, &$opened_path){
$path=str_replace('crypt://','',$path);
@@ -92,16 +93,6 @@ class OC_CryptStream{
$data=substr($block,0,$currentPos%8192).$data;
}
while(strlen($data)>0){
- if(strlen($data)<8192){
- //fetch the current data in that block and append it to the input so we always write entire blocks
- $oldPos=ftell($this->source);
- $encryptedBlock=fread($this->source,8192);
- fseek($this->source,$oldPos);
- if($encryptedBlock){
- $block=OC_Crypt::decrypt($encryptedBlock);
- $data.=substr($block,strlen($data));
- }
- }
$encrypted=OC_Crypt::encrypt(substr($data,0,8192));
fwrite($this->source,$encrypted);
$data=substr($data,8192);
@@ -139,7 +130,9 @@ class OC_CryptStream{
}
public function stream_close(){
- OC_FileCache::put($this->path,array('encrypted'=>true));
+ if($this->meta['mode']!='r' and $this->meta['mode']!='rb'){
+ OC_FileCache::put($this->path,array('encrypted'=>true));
+ }
return fclose($this->source);
}
} \ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index e3a106d0d04..d65bcba8bfa 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -27,7 +27,6 @@
class OC_FileProxy_Encryption extends OC_FileProxy{
private static $blackList=null; //mimetypes blacklisted from encryption
- private static $metaData=array(); //metadata cache
private static $enableEncryption=null;
/**
@@ -60,13 +59,8 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
* @return bool
*/
private static function isEncrypted($path){
- if(isset(self::$metaData[$path])){
- $metadata=self::$metaData[$path];
- }else{
- $metadata=OC_FileCache::getCached($path);
- self::$metaData[$path]=$metadata;
- }
- return (bool)$metadata['encrypted'];
+ $metadata=OC_FileCache::getCached($path);
+ return isset($metadata['encrypted']) and (bool)$metadata['encrypted'];
}
public function preFile_put_contents($path,&$data){
@@ -98,12 +92,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{
//first encrypt the target file so we don't end up with a half encrypted file
OC_Log::write('files_encryption','Decrypting '.$path.' before writing',OC_Log::DEBUG);
$tmp=fopen('php://temp');
- while(!feof($result)){
- $chunk=fread($result,8192);
- if($chunk){
- fwrite($tmp,$chunk);
- }
- }
+ OC_Helper::streamCopy($result,$tmp);
fclose($result);
OC_Filesystem::file_put_contents($path,$tmp);
fclose($tmp);
diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php
index e53eb1ff3b6..a987d17d799 100644
--- a/apps/files_external/lib/swift.php
+++ b/apps/files_external/lib/swift.php
@@ -28,6 +28,8 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
private $rootContainer;
private static $tempFiles=array();
+ private $objects=array();
+ private $containers=array();
const SUBCONTAINER_FILE='.subcontainers';
@@ -38,7 +40,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
*/
private function getContainerName($path){
$path=trim($this->root.$path,'/');
- return md5($path);
+ return str_replace('/','\\',$path);
}
/**
@@ -50,8 +52,12 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
if($path=='' or $path=='/'){
return $this->rootContainer;
}
+ if(isset($this->containers[$path])){
+ return $this->containers[$path];
+ }
try{
$container=$this->conn->get_container($this->getContainerName($path));
+ $this->containers[$path]=$container;
return $container;
}catch(NoSuchContainerException $e){
return null;
@@ -87,12 +93,16 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
* @return CF_Object
*/
private function getObject($path){
+ if(isset($this->objects[$path])){
+ return $this->objects[$path];
+ }
$container=$this->getContainer(dirname($path));
if(is_null($container)){
return null;
}else{
try{
$obj=$container->get_object(basename($path));
+ $this->objects[$path]=$obj;
return $obj;
}catch(NoSuchObjectException $e){
return null;
@@ -295,6 +305,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
}
$this->conn->delete_container($this->getContainerName($path));
+ unset($this->containers[$path]);
return true;
}
}
@@ -309,12 +320,14 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
if($sub){
$this->emptyContainer($path.'/'.$sub);
$this->conn->delete_container($this->getContainerName($path.'/'.$sub));
+ unset($this->containers[$path.'/'.$sub]);
}
}
$objects=$this->getObjects($container);
foreach($objects as $object){
$container->delete_object($object);
+ unset($this->objects[$path.'/'.$object]);
}
}
@@ -381,6 +394,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
if($this->objectExists($path)){
$container=$this->getContainer(dirname($path));
$container->delete_object(basename($path));
+ unset($this->objects[$path]);
}else{
return false;
}
@@ -447,6 +461,7 @@ class OC_FileStorage_SWIFT extends OC_Filestorage_Common{
$sourceContainer=$this->getContainer(dirname($path1));
$targetContainer=$this->getContainer(dirname($path2));
$result=$sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2));
+ unset($this->objects[$path1]);
if($result){
$targetObj=$this->getObject($path2);
$this->resetMTime($targetObj);
diff --git a/apps/files_sharing/ajax/email.php b/apps/files_sharing/ajax/email.php
new file mode 100644
index 00000000000..d6d53c49bff
--- /dev/null
+++ b/apps/files_sharing/ajax/email.php
@@ -0,0 +1,15 @@
+<?php
+
+require_once('../../../lib/base.php');
+
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('files_sharing');
+$user = OC_User::getUser();
+// TODO translations
+$subject = $user + ' ' + 'shared a file with you';
+$link = $_POST['link'] + '&f=' + $_POST['f'];
+$text = $user + ' ' + 'shared the file' + ' ' + $_POST['f'] + ' ' + 'with you.' + ' ' + 'It is available for download here:' + ' ' + $link;
+$fromaddress = OC_Preferences::getValue($user, 'settings', 'email', 'owncloud.org');
+OC_Mail::send($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user);
+
+?> \ No newline at end of file
diff --git a/apps/files_sharing/ajax/toggleresharing.php b/apps/files_sharing/ajax/toggleresharing.php
new file mode 100644
index 00000000000..72af1eedec1
--- /dev/null
+++ b/apps/files_sharing/ajax/toggleresharing.php
@@ -0,0 +1,13 @@
+<?php
+
+require_once('../../../lib/base.php');
+
+OC_JSON::checkAppEnabled('files_sharing');
+OC_JSON::checkAdminUser();
+if ($_POST['resharing'] == true) {
+ OC_Appconfig::setValue('files_sharing', 'resharing', 'yes');
+} else {
+ OC_Appconfig::setValue('files_sharing', 'resharing', 'no');
+}
+
+?>
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index 8049e9b0ae3..645f4f5e4f2 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -3,10 +3,17 @@
require_once('apps/files_sharing/sharedstorage.php');
OC::$CLASSPATH['OC_Share'] = "apps/files_sharing/lib_share.php";
+OC_APP::registerAdmin('files_sharing', 'settings');
OC_Hook::connect("OC_Filesystem", "post_delete", "OC_Share", "deleteItem");
OC_Hook::connect("OC_Filesystem", "post_rename", "OC_Share", "renameItem");
OC_Hook::connect("OC_Filesystem", "post_write", "OC_Share", "updateItem");
-OC_Util::addScript("files_sharing", "share");
+OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_Share', 'removeUser');
+OC_Hook::connect('OC_User', 'post_addToGroup', 'OC_Share', 'addToGroupShare');
+OC_Hook::connect('OC_User', 'post_removeFromGroup', 'OC_Share', 'removeFromGroupShare');
+$dir = isset($_GET['dir']) ? $_GET['dir'] : '/';
+if ($dir != '/Shared' || OC_Appconfig::getValue('files_sharing', 'resharing', 'yes') == 'yes') {
+ OC_Util::addScript("files_sharing", "share");
+}
OC_Util::addScript("3rdparty", "chosen/chosen.jquery.min");
OC_Util::addStyle( 'files_sharing', 'sharing' );
OC_Util::addStyle("3rdparty", "chosen/chosen");
diff --git a/apps/files_sharing/js/settings.js b/apps/files_sharing/js/settings.js
new file mode 100644
index 00000000000..bb7d79fecbb
--- /dev/null
+++ b/apps/files_sharing/js/settings.js
@@ -0,0 +1,9 @@
+$(document).ready(function() {
+ $('#allowResharing').bind('change', function() {
+ var checked = 1;
+ if (!this.checked) {
+ checked = 0;
+ }
+ $.post(OC.filePath('files_sharing','ajax','toggleresharing.php'), 'resharing='+checked);
+ });
+}); \ No newline at end of file
diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js
index 54d749d833e..4125fd14d25 100644
--- a/apps/files_sharing/js/share.js
+++ b/apps/files_sharing/js/share.js
@@ -163,6 +163,9 @@ $(document).ready(function() {
data: data,
success: function(){
$('#link').hide('blind');
+ $('#emailBreak').remove();
+ $('#email').hide('blind');
+ $('#emailButton').hide('blind');
}
});
}
@@ -172,6 +175,14 @@ $(document).ready(function() {
$(this).focus();
$(this).select();
});
+
+ $('#emailButton').live('click', function() {
+ $('#email').css('font-weight', 'bold');
+ $('#email').animate({ fontWeight: 'normal' }, 2000, function() {
+ $(this).val('');
+ }).val('Email sent');
+ $.post(OC.filePath('files_sharing','ajax','email.php'), 'toaddress='+$('#email').val()+'&link='+$('#link').val());
+ });
});
function createDropdown(filename, files) {
@@ -183,10 +194,12 @@ function createDropdown(filename, files) {
html += '<ul id="shared_list"></ul>';
html += '</div>';
html += '<div id="public">';
- html += '<input type="checkbox" name="makelink" id="makelink" value="1" /><label for="makelink">make public</label>';
+ html += '<input type="checkbox" name="makelink" id="makelink" value="1" /><label for="makelink">Share with private link</label>';
//html += '<input type="checkbox" name="public_link_write" id="public_link_write" value="1" /><label for="public_link_write">allow upload</label>';
html += '<br />';
html += '<input id="link" style="display:none; width:90%;" />';
+ html += '<input id="email" style="display:none; width:65%;" value="" placeholder="Email link to person" />';
+ html += '<input id="emailButton" style="display:none;" type="submit" value="Send" />';
html += '</div>';
if (filename) {
$('tr').filterAttr('data-file',filename).addClass('mouseOver');
@@ -241,5 +254,9 @@ function showPublicLink(token, file) {
$('#makelink').attr('checked', true);
$('#link').data('token', token);
$('#link').val(parent.location.protocol+'//'+location.host+OC.linkTo('files_sharing','get.php')+'?token='+token+'&f='+file);
- $('#link').show('blind');
+ $('#link').show('blind', function() {
+ $('#link').after('<br id="emailBreak" />');
+ $('#email').show('blind');
+ $('#emailButton').show('blind');
+ });
}
diff --git a/apps/files_sharing/lib_share.php b/apps/files_sharing/lib_share.php
index 673984f393b..62ac05a5952 100644
--- a/apps/files_sharing/lib_share.php
+++ b/apps/files_sharing/lib_share.php
@@ -436,6 +436,34 @@ class OC_Share {
}
}
+ public static function removeUser($arguments) {
+ $query = OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_owner = ? OR uid_shared_with '.self::getUsersAndGroups($arguments['uid']));
+ $query->execute(array($arguments['uid']));
+ }
+
+ public static function addToGroupShare($arguments) {
+ $length = -strlen($arguments['gid']) - 1;
+ $query = OC_DB::prepare('SELECT uid_owner, source, permissions FROM *PREFIX*sharing WHERE SUBSTR(uid_shared_with, '.$length.') = ?');
+ $gid = '@'.$arguments['gid'];
+ $result = $query->execute(array($gid))->fetchAll();
+ if (count($result) > 0) {
+ $query = OC_DB::prepare('INSERT INTO *PREFIX*sharing VALUES(?,?,?,?,?)');
+ $sharedFolder = '/'.$arguments['uid'].'/files/Shared/';
+ $lastSource = '';
+ for ($i = 0; $i < count($result) - 1; $i++) {
+ if ($result[$i]['source'] != $lastSource) {
+ $query->execute(array($result[$i]['uid_owner'], $arguments['uid'].'@'.$arguments['gid'], $result[$i]['source'], $sharedFolder.basename($result[$i]['source']), $result[$i]['permissions']));
+ $lastSource = $result[$i]['source'];
+ }
+ }
+ }
+ }
+
+ public static function removeFromGroupShare($arguments) {
+ $query = OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_shared_with = ?');
+ $query->execute(array($arguments['uid'].'@'.$arguments['gid']));
+ }
+
}
?>
diff --git a/apps/files_sharing/settings.php b/apps/files_sharing/settings.php
new file mode 100644
index 00000000000..b30c4f45cde
--- /dev/null
+++ b/apps/files_sharing/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+OC_Util::checkAdminUser();
+OC_Util::addScript('files_sharing', 'settings');
+$tmpl = new OC_Template('files_sharing', 'settings');
+$tmpl->assign('allowResharing', OC_Appconfig::getValue('files_sharing', 'resharing', 'yes'));
+return $tmpl->fetchPage();
+
+?> \ No newline at end of file
diff --git a/apps/files_sharing/templates/settings.php b/apps/files_sharing/templates/settings.php
new file mode 100644
index 00000000000..5b6ba5f33ee
--- /dev/null
+++ b/apps/files_sharing/templates/settings.php
@@ -0,0 +1,6 @@
+<form id="resharing">
+ <fieldset class="personalblock">
+ <input type="checkbox" name="allowResharing" id="allowResharing" value="1" <?php if ($_['allowResharing'] == 'yes') echo ' checked="checked"'; ?> /> <label for="allowResharing"><?php echo $l->t('Enable Resharing'); ?></label> <br/>
+ <em><?php echo $l->t('Allow users to reshare files they don\'t own');?></em>
+ </fieldset>
+</form> \ No newline at end of file
diff --git a/apps/files_versions/appinfo/app.php b/apps/files_versions/appinfo/app.php
index 6e7a803252e..32e4c0ce81b 100644
--- a/apps/files_versions/appinfo/app.php
+++ b/apps/files_versions/appinfo/app.php
@@ -9,6 +9,7 @@ OC_App::register( array(
'name' => 'Versioning' ));
OC_APP::registerAdmin('files_versions', 'settings');
+OC_UTIL::addScript('files_versions', 'versions');
// Listen to write signals
OC_Hook::connect(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OCA_Versions\Storage", "write_hook");
diff --git a/apps/files_versions/css/versions.css b/apps/files_versions/css/versions.css
index 139597f9cb0..b2279e9b05a 100644
--- a/apps/files_versions/css/versions.css
+++ b/apps/files_versions/css/versions.css
@@ -1,2 +1,3 @@
-
-
+#history {
+ margin: 2em 2em 0;
+} \ No newline at end of file
diff --git a/apps/files_versions/history.php b/apps/files_versions/history.php
index 6c7626ca4ed..b0aa8fdc982 100644
--- a/apps/files_versions/history.php
+++ b/apps/files_versions/history.php
@@ -20,40 +20,41 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
-require_once('../../lib/base.php');
+require_once( '../../lib/base.php' );
-OC_Util::checkLoggedIn();
+OC_Util::checkLoggedIn( );
+OC_Util::addStyle('files_versions','versions');
-if (isset($_GET['path'])) {
+if ( isset( $_GET['path'] ) ) {
$path = $_GET['path'];
- $path = strip_tags($path);
+ $path = strip_tags( $path);
// roll back to old version if button clicked
- if(isset($_GET['revert'])) {
- \OCA_Versions\Storage::rollback($path,$_GET['revert']);
+ if( isset( $_GET['revert'] ) ) {
+ \OCA_Versions\Storage::rollback( $path, $_GET['revert'] );
}
// show the history only if there is something to show
- if(OCA_Versions\Storage::isversioned($path)) {
+ if( OCA_Versions\Storage::isversioned( $path ) ) {
$count=5; //show the newest revisions
- $versions=OCA_Versions\Storage::getversions($path,$count);
+ $versions=OCA_Versions\Storage::getversions( $path, $count);
- $tmpl = new OC_Template('files_versions', 'history', 'user');
- $tmpl->assign('path', $path);
- $tmpl->assign('versions', array_reverse($versions));
- $tmpl->printPage();
+ $tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+ $tmpl->assign( 'path', $path);
+ $tmpl->assign( 'versions', array_reverse( $versions) );
+ $tmpl->printPage( );
}else{
- $tmpl = new OC_Template('files_versions', 'history', 'user');
- $tmpl->assign('path', $path);
- $tmpl->assign('message', 'No old versions available');
- $tmpl->printPage();
+ $tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+ $tmpl->assign( 'path', $path);
+ $tmpl->assign( 'message', 'No old versions available' );
+ $tmpl->printPage( );
}
}else{
- $tmpl = new OC_Template('files_versions', 'history', 'user');
- $tmpl->assign('message', 'No path specified');
- $tmpl->printPage();
+ $tmpl = new OC_Template( 'files_versions', 'history', 'user' );
+ $tmpl->assign( 'message', 'No path specified' );
+ $tmpl->printPage( );
}
diff --git a/apps/files_versions/js/versions.js b/apps/files_versions/js/versions.js
index 139597f9cb0..325ef823a9c 100644
--- a/apps/files_versions/js/versions.js
+++ b/apps/files_versions/js/versions.js
@@ -1,2 +1,67 @@
+$(document).ready(function(){
+
+ // Add history button to files/index.php
+ FileActions.register('file','History',function(){return OC.imagePath('core','actions/history')},function(filename){
+
+ if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback
+
+ var file = $('#dir').val()+'/'+filename;
+
+ createVersionsDropdown(filename, file)
+ //window.location='../apps/files_versions/history.php?path='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
+
+ });
+
+});
+
+function createVersionsDropdown(filename, files) {
+ var historyUrl = '../apps/files_versions/history.php?path='+encodeURIComponent($('#dir').val()).replace(/%2F/g, '/')+'/'+encodeURIComponent(filename);
+ //alert( historyUrl );
+ var html = '<div id="dropdown" class="drop" data-file="'+files+'">';
+ html += '<div id="private">';
+ html += '<select data-placeholder="File Version" id="share_with" class="chzen-select">';
+ html += '<option value=""></option>';
+ html += '</select>';
+ html += '<ul id="shared_list"></ul>';
+ html += '</div>';
+ html += '<div id="public">';
+ html += '<input type="button" name="makelink" id="makelink" value="Revert file" />';
+ html += '<input type="button" onclick="window.location=\''+historyUrl+'\'" name="makelink" id="makelink" value="More..." />';
+ html += '<br />';
+ html += '<input id="link" style="display:none; width:90%;" />';
+ html += '</div>';
+
+ if (filename) {
+ $('tr').filterAttr('data-file',filename).addClass('mouseOver');
+ $(html).appendTo($('tr').filterAttr('data-file',filename).find('td.filename'));
+ } else {
+ $(html).appendTo($('thead .share'));
+ }
+// $.getJSON(OC.linkTo('files_sharing', 'ajax/userautocomplete.php'), function(users) {
+// if (users) {
+// $.each(users, function(index, row) {
+// $(row).appendTo('#share_with');
+// });
+// $('#share_with').trigger('liszt:updated');
+// }
+// });
+// $.getJSON(OC.linkTo('files_sharing', 'ajax/getitem.php'), { source: files }, function(users) {
+// if (users) {
+// $.each(users, function(index, row) {
+// if (row.uid_shared_with == 'public') {
+// showPublicLink(row.token, '/'+filename);
+// } else if (isNaN(index)) {
+// addUser(row.uid_shared_with, row.permissions, index.substr(0, index.lastIndexOf('-')));
+// } else {
+// addUser(row.uid_shared_with, row.permissions, false);
+// }
+// });
+// }
+// });
+
+ $('#dropdown').show('blind');
+ $('#share_with').chosen();
+
+} \ No newline at end of file
diff --git a/apps/files_versions/templates/history.php b/apps/files_versions/templates/history.php
index 1b3de9ce77c..d33d2b0f68b 100644
--- a/apps/files_versions/templates/history.php
+++ b/apps/files_versions/templates/history.php
@@ -1,3 +1,4 @@
+<div id="history">
<?php
if(isset($_['message'])){
@@ -10,9 +11,10 @@
echo('<strong>Versions of '.$_['path']).'</strong><br>';
echo('<p><em>You can click on the revert button to revert to the specific verson.</em></p><br />');
foreach ($_['versions'] as $v){
- echo(' '.OC_Util::formatDate($v).' <a href="history.php?path='.urlencode($_['path']).'&revert='.$v.'" class="button">revert</a><br /><br />');
+ echo(' '.OC_Util::formatDate($v).' <a href="history.php?path='.urlencode($_['path']).'&revert='.$v.'" class="button">Revert</a><br /><br />');
}
}
?>
+</div>
diff --git a/apps/files_versions/versions.php b/apps/files_versions/versions.php
index 156a4f59c73..167c64a4345 100644
--- a/apps/files_versions/versions.php
+++ b/apps/files_versions/versions.php
@@ -36,7 +36,7 @@ class Storage {
const DEFAULTFOLDER='versions';
const DEFAULTBLACKLIST='avi mp3 mpg mp4';
const DEFAULTMAXFILESIZE=1048576; // 10MB
- const DEFAULTMININTERVAL=300; // 5 min
+ const DEFAULTMININTERVAL=1; // 5 min
const DEFAULTMAXVERSIONS=50;
/**
diff --git a/apps/user_ldap/appinfo/database.xml b/apps/user_ldap/appinfo/database.xml
new file mode 100644
index 00000000000..74c56fcf743
--- /dev/null
+++ b/apps/user_ldap/appinfo/database.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<database>
+
+ <name>*dbname*</name>
+ <create>true</create>
+ <overwrite>false</overwrite>
+ <charset>utf8</charset>
+
+ <table>
+
+ <name>*dbprefix*ldap_user_mapping</name>
+
+ <declaration>
+
+ <field>
+ <name>ldap_dn</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <field>
+ <name>owncloud_name</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <index>
+ <name>ldap_dn</name>
+ <unique>true</unique>
+ <field>
+ <name>ldap_dn</name>
+ </field>
+ </index>
+
+ <index>
+ <name>owncloud_name</name>
+ <unique>true</unique>
+ <field>
+ <name>owncloud_name</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+
+ </declaration>
+
+ </table>
+
+ <table>
+
+ <name>*dbprefix*ldap_group_mapping</name>
+
+ <declaration>
+
+ <field>
+ <name>ldap_dn</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <field>
+ <name>owncloud_name</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>255</length>
+ <default></default>
+ </field>
+
+ <index>
+ <name>ldap_dn</name>
+ <unique>true</unique>
+ <field>
+ <name>ldap_dn</name>
+ </field>
+ </index>
+
+ <index>
+ <name>owncloud_name</name>
+ <unique>true</unique>
+ <field>
+ <name>owncloud_name</name>
+ <sorting>ascending</sorting>
+ </field>
+ </index>
+
+ </declaration>
+
+ </table>
+
+</database> \ No newline at end of file
diff --git a/apps/user_ldap/appinfo/version b/apps/user_ldap/appinfo/version
index ceab6e11ece..a0d78bd347e 100644
--- a/apps/user_ldap/appinfo/version
+++ b/apps/user_ldap/appinfo/version
@@ -1 +1 @@
-0.1 \ No newline at end of file
+0.1.90 \ No newline at end of file
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index fe0789cdeb7..7773968e208 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -24,13 +24,9 @@
class OC_GROUP_LDAP extends OC_Group_Backend {
// //group specific settings
protected $ldapGroupFilter;
- protected $ldapGroupDisplayName;
- protected $ldapGroupMemberAttr;
public function __construct() {
$this->ldapGroupFilter = OC_Appconfig::getValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)');
- $this->ldapGroupDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_group_display_name', 'cn');
- $this->ldapGroupMemberAttr = OC_Appconfig::getValue('user_ldap', 'ldap_group_member_attr', 'memberUid');
}
/**
@@ -42,18 +38,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Checks whether the user is member of a group or not.
*/
public function inGroup($uid, $gid) {
- $filter = OC_LDAP::combineFilterWithAnd(array(
- $this->ldapGroupFilter,
- LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$uid,
- $this->ldapGroupDisplayName.'='.$gid
- ));
- $groups = $this->retrieveList($filter, $this->ldapGroupDisplayName);
-
- if(count($groups) > 0) {
- return true;
- } else {
+ $dn_user = OC_LDAP::username2dn($uid);
+ $dn_group = OC_LDAP::groupname2dn($gid);
+// if($dn_group == 'c') {echo('#sdfsdgfds');die($gid);}
+ // just in case
+ if(!$dn_group || !$dn_user) {
return false;
}
+// var_dump($dn_group);
+ $members = OC_LDAP::readAttribute($dn_group, LDAP_GROUP_MEMBER_ASSOC_ATTR);
+
+ return in_array($dn_user, $members);
}
/**
@@ -65,12 +60,19 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* if the user exists at all.
*/
public function getUserGroups($uid) {
+ $userDN = OC_LDAP::username2dn($uid);
+ if(!$userDN) {
+ return array();
+ }
+
$filter = OC_LDAP::combineFilterWithAnd(array(
$this->ldapGroupFilter,
- LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$uid
+ LDAP_GROUP_MEMBER_ASSOC_ATTR.'='.$userDN
));
+ $groups = $this->retrieveList($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
+ $userGroups = OC_LDAP::ownCloudGroupNames($groups);
- return $this->retrieveList($filter, $this->ldapGroupDisplayName);
+ return array_unique($userGroups, SORT_LOCALE_STRING);
}
/**
@@ -78,12 +80,16 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* @returns array with user ids
*/
public function usersInGroup($gid) {
- $filter = OC_LDAP::combineFilterWithAnd(array(
- $this->ldapGroupFilter,
- $this->ldapGroupDisplayName.'='.$gid
- ));
-
- return $this->retrieveList($filter, $this->ldapGroupMemberAttr, false);
+ $groupDN = OC_LDAP::groupname2dn($gid);
+ if(!$groupDN) {
+ return array();
+ }
+ $members = OC_LDAP::readAttribute($groupDN, LDAP_GROUP_MEMBER_ASSOC_ATTR);
+ $result = array();
+ foreach($members as $member) {
+ $result[] = OC_LDAP::dn2username($member);
+ }
+ return array_unique($result, SORT_LOCALE_STRING);
}
/**
@@ -93,7 +99,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Returns a list with all groups
*/
public function getGroups() {
- return $this->retrieveList($this->ldapGroupFilter, $this->ldapGroupDisplayName);
+ $ldap_groups = $this->retrieveList($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
+ $groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+ return $groups;
}
/**
@@ -112,13 +120,18 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
$list = OC_LDAP::searchUsers($filter, $attr);
}
-
if(is_array($list)) {
- return array_unique($list, SORT_LOCALE_STRING);
+ if(count($attr) > 1){
+ return $list;
+ } else {
+ return array_unique($list, SORT_LOCALE_STRING);
+ }
}
//error cause actually, maybe throw an exception in future.
return array();
}
+
+
} \ No newline at end of file
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
new file mode 100644
index 00000000000..cae9655e3df
--- /dev/null
+++ b/apps/user_ldap/js/settings.js
@@ -0,0 +1,3 @@
+$(document).ready(function() {
+ $('#ldapSettings').tabs();
+}); \ No newline at end of file
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
index 752ac4f2289..4efcf0c5a0d 100644
--- a/apps/user_ldap/lib_ldap.php
+++ b/apps/user_ldap/lib_ldap.php
@@ -21,7 +21,8 @@
*
*/
-define('LDAP_GROUP_MEMBER_ASSOC_ATTR','memberUid');
+define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniqueMember');
+define('LDAP_GROUP_DISPLAY_NAME_ATTR','cn');
//needed to unbind, because we use OC_LDAP only statically
class OC_LDAP_DESTRUCTOR {
@@ -45,7 +46,9 @@ class OC_LDAP {
static protected $ldapTLS;
static protected $ldapNoCase;
// user and group settings, that are needed in both backends
- static public $ldapUserDisplayName;
+ static protected $ldapUserDisplayName;
+ static protected $ldapUserFilter;
+ static protected $ldapGroupDisplayName;
static public function init() {
self::readConfiguration();
@@ -56,14 +59,345 @@ class OC_LDAP {
@ldap_unbind(self::$ldapConnectionRes);
}
+ /**
+ * @brief returns a read-only configuration value
+ * @param $key the name of the configuration value
+ * @returns the value on success, otherwise null
+ *
+ * returns a read-only configuration values
+ *
+ * we cannot work with getters, because it is a static class
+ */
static public function conf($key) {
+ if(!self::$configured) {
+ self::init();
+ }
+
$availableProperties = array(
'ldapUserDisplayName',
+ 'ldapGroupDisplayName',
);
if(in_array($key, $availableProperties)) {
return self::$$key;
}
+
+ return null;
+ }
+
+ /**
+ * gives back the database table for the query
+ */
+ static private function getMapTable($isUser) {
+ if($isUser) {
+ return '*PREFIX*ldap_user_mapping';
+ } else {
+ return '*PREFIX*ldap_group_mapping';
+ }
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name of the group
+ * @param $name the ownCloud name in question
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name of the group
+ */
+ static public function groupname2dn($name) {
+ return self::ocname2dn($name, false);
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name of the user
+ * @param $name the ownCloud name in question
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name of the user
+ */
+ static public function username2dn($name) {
+ $dn = self::ocname2dn($name, true);
+ if($dn) {
+ return $dn;
+ } else {
+ //fallback: user is not mapped
+ $filter = self::combineFilterWithAnd(array(
+ self::$ldapUserFilter,
+ self::$ldapUserDisplayName . '=' . $name,
+ ));
+ $result = self::searchUsers($filter, 'dn');
+ if(isset($result[0]['dn'])) {
+ self::mapUser($result[0], $name);
+ return $result[0];
+ }
+ }
+
+ return false;
+ }
+
+ static private function ocname2dn($name, $isUser) {
+ $table = self::getMapTable($isUser);
+
+ $query = OC_DB::prepare('
+ SELECT ldap_dn
+ FROM '.$table.'
+ WHERE owncloud_name = ?
+ ');
+
+ $record = $query->execute(array($name))->fetchOne();
+ return $record;
+ if($name=='Coyotes') {
+ echo("adsfasdf ");
+ var_dump($record);
+ die();
+ }
+ if(isset($record['ldap_dn'])) {
+ return $record['ldap_dn'];
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief returns the internal ownCloud name for the given LDAP DN of the group
+ * @param $dn the dn of the group object
+ * @param $ldapname optional, the display name of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the group
+ */
+ static public function dn2groupname($dn, $ldapname = null) {
+ return self::dn2ocname($dn, $ldapname, false);
+ }
+
+ /**
+ * @brief returns the internal ownCloud name for the given LDAP DN of the user
+ * @param $dn the dn of the user object
+ * @param $ldapname optional, the display name of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the user
+ */
+ static public function dn2username($dn, $ldapname = null) {
+ return self::dn2ocname($dn, $ldapname, true);
+ }
+
+ static public function dn2ocname($dn, $ldapname = null, $isUser = true) {
+ $table = self::getMapTable($isUser);
+ if($isUser) {
+ $nameAttribute = self::conf('ldapUserDisplayName');
+ } else {
+ $nameAttribute = self::conf('ldapGroupDisplayName');
+ }
+
+ $query = OC_DB::prepare('
+ SELECT owncloud_name
+ FROM '.$table.'
+ WHERE ldap_dn = ?
+ ');
+
+ $component = $query->execute(array($dn))->fetchOne();
+ if($component) {
+ return $component;
+ }
+
+ if(is_null($ldapname)) {
+ $ldapname = self::readAttribute($dn, $nameAttribute);
+ $ldapname = $ldapname[0];
+ }
+
+ //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
+ if(self::mapComponent($dn, $ldapname, $isUser)) {
+ return $ldapname;
+ }
+
+ //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
+ $oc_name = self::alternateOwnCloudName($ldapname, $dn);
+ if(self::mapComponent($dn, $oc_name, $isUser)) {
+ return $oc_name;
+ }
+
+ //and this of course should never been thrown :)
+ throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+ }
+
+ /**
+ * @brief gives back the user names as they are used ownClod internally
+ * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
+ * @returns an array with the user names to use in ownCloud
+ *
+ * gives back the user names as they are used ownClod internally
+ */
+ static public function ownCloudUserNames($ldapUsers) {
+ return self::ldap2ownCloudNames($ldapUsers, true);
+ }
+
+ /**
+ * @brief gives back the group names as they are used ownClod internally
+ * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
+ * @returns an array with the group names to use in ownCloud
+ *
+ * gives back the group names as they are used ownClod internally
+ */
+ static public function ownCloudGroupNames($ldapGroups) {
+ return self::ldap2ownCloudNames($ldapGroups, false);
+ }
+
+ static private function ldap2ownCloudNames($ldapObjects, $isUsers) {
+ if($isUsers) {
+ $knownObjects = self::mappedUsers();
+ $nameAttribute = self::conf('ldapUserDisplayName');
+ } else {
+ $knownObjects = self::mappedGroups();
+ $nameAttribute = self::conf('ldapGroupDisplayName');
+ }
+ $ownCloudNames = array();
+
+ foreach($ldapObjects as $ldapObject) {
+ $key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']);
+
+ //everything is fine when we know the group
+ if($key) {
+ $ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
+ continue;
+ }
+
+ //a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict
+ if(self::mapComponent($ldapObject['dn'], $ldapObject[$nameAttribute], $isUsers)) {
+ $ownCloudNames[] = $ldapObject[$nameAttribute];
+ continue;
+ }
+
+ //doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
+ $oc_name = self::alternateOwnCloudName($ldapObject[$nameAttribute], $ldapObject['dn']);
+ if(self::mapComponent($ldapObject['dn'], $oc_name, $isUsers)) {
+ $ownCloudNames[] = $oc_name;
+ continue;
+ }
+
+ //and this of course should never been thrown :)
+ throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+ }
+ return $ownCloudNames;
+ }
+
+ /**
+ * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+ * @param $name the display name of the object
+ * @param $dn the dn of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+ */
+ static private function alternateOwnCloudName($name, $dn) {
+ $ufn = ldap_dn2ufn($dn);
+ return $name . ' (' . trim(substr_replace($ufn, '', 0, strpos($ufn, ','))) . ')';
+ }
+
+ /**
+ * @brief retrieves all known groups from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known groups from the mappings table
+ */
+ static private function mappedGroups() {
+ return self::mappedComponents(false);
+ }
+
+ /**
+ * @brief retrieves all known users from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known users from the mappings table
+ */
+ static private function mappedUsers() {
+ return self::mappedComponents(true);
+ }
+
+ static private function mappedComponents($isUsers) {
+ $table = self::getMapTable($isUsers);
+
+ $query = OC_DB::prepare('
+ SELECT ldap_dn, owncloud_name
+ FROM '. $table
+ );
+
+ return $query->execute()->fetchAll();
+ }
+
+ /**
+ * @brief inserts a new group into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @returns true on success, false otherwise
+ *
+ * inserts a new group into the mappings table
+ */
+ static private function mapGroup($dn, $ocname) {
+ return self::mapComponent($dn, $ocname, false);
+ }
+
+ /**
+ * @brief inserts a new user into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @returns true on success, false otherwise
+ *
+ * inserts a new user into the mappings table
+ */
+ static private function mapUser($dn, $ocname) {
+ return self::mapComponent($dn, $ocname, true);
+ }
+
+ /**
+ * @brief inserts a new user or group into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @param $isUser is it a user or a group?
+ * @returns true on success, false otherwise
+ *
+ * inserts a new user or group into the mappings table
+ */
+ static private function mapComponent($dn, $ocname, $isUser = true) {
+ $table = self::getMapTable($isUser);
+
+ $insert = OC_DB::prepare('
+ INSERT IGNORE INTO '.$table.'
+ (ldap_dn, owncloud_name)
+ VALUES (?,?)
+ ');
+
+ $res = $insert->execute(array($dn, $ocname));
+
+ return !OC_DB::isError($res);
+ }
+
+ /**
+ * @brief reads a given attribute for an LDAP record identified by a DN
+ * @param $dn the record in question
+ * @param $attr the attribute that shall be retrieved
+ * @returns the values in an array on success, false otherwise
+ *
+ * Reads an attribute from an LDAP entry
+ */
+ static public function readAttribute($dn, $attr) {
+ $cr = self::getConnectionResource();
+// echo("<pre>");var_dump($dn);
+ $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
+ if(!$rr) {
+ echo('<pre>###RA ');var_dump($dn);var_dump(debug_backtrace());die();
+ }
+ $er = ldap_first_entry($cr, $rr);
+ $result = ldap_get_attributes($cr, $er);
+
+// if($dn == 'cn=Coyotes,cn=groups,dc=blizzz-oc,dc=bzoc') die((var_dump($result)));
+ if($result[$attr]['count'] > 0){
+ $values = array();
+ for($i=0;$i<$result[$attr]['count'];$i++) {
+ $values[] = $result[$attr][$i];
+ }
+ return $values;
+ }
+ return false;
}
/**
@@ -100,15 +434,38 @@ class OC_LDAP {
* Executes an LDAP search
*/
static private function search($filter, $base, $attr = null) {
- $sr = ldap_search(self::getConnectionResource(), $base, $filter, array($attr));
+ if(!is_null($attr) && !is_array($attr)) {
+ $attr = array(strtolower($attr));
+ }
+ $sr = ldap_search(self::getConnectionResource(), $base, $filter, $attr);
$findings = ldap_get_entries(self::getConnectionResource(), $sr );
if(!is_null($attr)) {
$selection = array();
+ $multiarray = false;
+ if(count($attr) > 1) {
+ $multiarray = true;
+ $i = 0;
+ }
foreach($findings as $item) {
- if(isset($item[strtolower($attr)])) {
- $selection[] = $item[strtolower($attr)][0];
+ if($multiarray) {
+ foreach($attr as $key) {
+ if(isset($item[$key])) {
+ if($key != 'dn'){
+ $selection[$i][$key] = $item[$key][0];
+ } else {
+ $selection[$i][$key] = $item[$key];
+ }
+ }
+
+ }
+ $i++;
+ } else {
+ if(isset($item[$attr[0]])) {
+ $selection[] = $item[$attr[0]];
+ }
}
+
}
return $selection;
}
@@ -173,16 +530,18 @@ class OC_LDAP {
*/
static private function readConfiguration() {
if(!self::$configured) {
- self::$ldapHost = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
- self::$ldapPort = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
- self::$ldapAgentName = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
- self::$ldapAgentPassword = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
- self::$ldapBase = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
- self::$ldapBaseUsers = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
- self::$ldapBaseGroups = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
- self::$ldapTLS = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
- self::$ldapNoCase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
- self::$ldapUserDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
+ self::$ldapHost = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
+ self::$ldapPort = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
+ self::$ldapAgentName = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
+ self::$ldapAgentPassword = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
+ self::$ldapBase = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
+ self::$ldapBaseUsers = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
+ self::$ldapBaseGroups = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
+ self::$ldapTLS = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
+ self::$ldapNoCase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
+ self::$ldapUserDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
+ self::$ldapUserFilter = OC_Appconfig::getValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
+ self::$ldapGroupDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR);
if(
!empty(self::$ldapHost)
@@ -226,5 +585,23 @@ class OC_LDAP {
}
}
+ /**
+ * taken from http://www.php.net/manual/en/function.array-search.php#97645
+ * TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe?
+ */
+ static public function recursiveArraySearch($haystack, $needle, $index = null) {
+ $aIt = new RecursiveArrayIterator($haystack);
+ $it = new RecursiveIteratorIterator($aIt);
+
+ while($it->valid()) {
+ if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
+ return $aIt->key();
+ }
+
+ $it->next();
+ }
+
+ return false;
+ }
} \ No newline at end of file
diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php
index ad44fe95f9e..2226c74609d 100644
--- a/apps/user_ldap/settings.php
+++ b/apps/user_ldap/settings.php
@@ -20,7 +20,10 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
-$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
+$params = array('ldap_host', 'ldap_port', 'ldap_dn', 'ldap_password', 'ldap_base', 'ldap_base_users', 'ldap_base_groups', 'ldap_userlist_filter', 'ldap_login_filter', 'ldap_display_name', 'ldap_tls', 'ldap_nocase'. 'ldap_quota_def', 'ldap_quota_attr', 'ldap_email_attr');
+
+OC_Util::addScript('user_ldap', 'settings');
+OC_Util::addStyle('user_ldap', 'settings');
if ($_POST) {
foreach($params as $param){
@@ -45,10 +48,8 @@ foreach($params as $param){
$tmpl->assign($param, $value);
}
-// ldap_port has a default value
+// settings with default values
$tmpl->assign( 'ldap_port', OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT));
-
-// ldap_display_name has a default value
$tmpl->assign( 'ldap_display_name', OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME));
return $tmpl->fetchPage();
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index 828c72cba97..7e327bb0701 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -1,21 +1,30 @@
<form id="ldap" action="#" method="post">
- <fieldset class="personalblock">
- <legend><strong>LDAP</strong></legend>
- <p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label>
- <label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p>
+ <div id="ldapSettings" class="personalblock">
+ <ul>
+ <li><a href="#ldapSettings-1">LDAP Basic</a></li>
+ <li><a href="#ldapSettings-2">Advanced</a></li>
+ </ul>
+ <fieldset id="ldapSettings-1">
+ <p><label for="ldap_host"><?php echo $l->t('Host');?><input type="text" id="ldap_host" name="ldap_host" value="<?php echo $_['ldap_host']; ?>"></label> <label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
<p><label for="ldap_dn"><?php echo $l->t('Name');?></label><input type="text" id="ldap_dn" name="ldap_dn" value="<?php echo $_['ldap_dn']; ?>" />
<label for="ldap_password"><?php echo $l->t('Password');?></label><input type="password" id="ldap_password" name="ldap_password" value="<?php echo $_['ldap_password']; ?>" />
<small><?php echo $l->t('Leave both empty for anonymous bind for search, then bind with users credentials.');?></small></p>
- <p><label for="ldap_base"><?php echo $l->t('Base');?></label><input type="text" id="ldap_base" name="ldap_base" value="<?php echo $_['ldap_base']; ?>" /></p>
<p><label for="ldap_login_filter"><?php echo $l->t('User Login Filter');?></label><input type="text" id="ldap_login_filter" name="ldap_login_filter" value="<?php echo $_['ldap_login_filter']; ?>" /><small><?php echo $l->t('use %%uid placeholder, e.g. uid=%%uid');?></small></p>
- <p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?> </p>
- <p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
- <small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
+ <p><label for="ldap_userlist_filter"><?php echo $l->t('User List Filter');?></label><input type="text" id="ldap_userlist_filter" name="ldap_userlist_filter" value="<?php echo $_['ldap_userlist_filter']; ?>" /><small><?php echo $l->t('without any placeholder, e.g. "objectClass=person".');?></small></p>
+ </fieldset>
+ <fieldset id="ldapSettings-2">
+ <p><label for="ldap_port"><?php echo $l->t('Port');?></label><input type="text" id="ldap_port" name="ldap_port" value="<?php echo $_['ldap_port']; ?>" /></p>
+ <p><label for="ldap_base_users"><?php echo $l->t('Base User Tree');?></label><input type="text" id="ldap_base_users" name="ldap_base_users" value="<?php echo $_['ldap_base_users']; ?>" /></p>
+ <p><label for="ldap_base_groups"><?php echo $l->t('Base Group Tree');?></label><input type="text" id="ldap_base_groups" name="ldap_base_groups" value="<?php echo $_['ldap_base_groups']; ?>" /></p>
<p><input type="checkbox" id="ldap_tls" name="ldap_tls" value="1"<?php if ($_['ldap_tls']) echo ' checked'; ?>><label for="ldap_tls"><?php echo $l->t('Use TLS');?></label></p>
<p><input type="checkbox" id="ldap_nocase" name="ldap_nocase" value="1"<?php if ($_['ldap_nocase']) echo ' checked'; ?>><label for="ldap_nocase"><?php echo $l->t('Case insensitve LDAP server (Windows)');?></label></p>
+ <p><label for="ldap_display_name"><?php echo $l->t('Display Name Field');?></label><input type="text" id="ldap_display_name" name="ldap_display_name" value="<?php echo $_['ldap_display_name']; ?>" />
+ <small><?php echo $l->t('Currently the display name field needs to be the same you matched %%uid against in the filter above, because ownCloud doesn\'t distinguish between user id and user name.');?></small></p>
<p><label for="ldap_quota_attr">Quota Attribute</label><input type="text" id="ldap_quota_attr" name="ldap_quota_attr" value="<?php echo $_['ldap_quota_attr']; ?>" />
- <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
- <p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
- <input type="submit" value="Save" />
+ <label for="ldap_quota_def">Quota Default</label><input type="text" id="ldap_quota_def" name="ldap_quota_def" value="<?php echo $_['ldap_quota_def']; ?>" />bytes</p>
+ <p><label for="ldap_email_attr">Email Attribute</label><input type="text" id="ldap_email_attr" name="ldap_email_attr" value="<?php echo $_['ldap_email_attr']; ?>" /></p>
</fieldset>
+ <input type="submit" value="Save" />
+ </div>
+
</form>