diff --git a/apps/calendar/templates/settings.php b/apps/calendar/templates/settings.php index 12117750ca5..feb06655120 100644 --- a/apps/calendar/templates/settings.php +++ b/apps/calendar/templates/settings.php @@ -8,45 +8,50 @@ */ ?>
-
+
t('Calendar'); ?> - -
+ + $continent=$ex[0]; + echo ''; + endforeach;?> + - + - + -
- -
+ +
- -
+ +
+
- t('Calendar CalDAV syncing address:');?> -
+ t('Calendar CalDAV syncing addresses'); ?> (t('more info'); ?>) +
+
t('Primary address (Kontact et al)'); ?>
+
+
t('iOS/OS X'); ?>
+
principals//
+
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css index 1d02b3722dd..8de68fbf052 100644 --- a/apps/contacts/css/contacts.css +++ b/apps/contacts/css/contacts.css @@ -31,8 +31,9 @@ dl.form { width: 100%; float: left; clear: right; margin: 0; padding: 0; } .form dt { display: table-cell; clear: left; float: left; width: 7em; margin: 0; padding: 0.8em 0.5em 0 0; text-align:right; text-overflow:ellipsis; o-text-overflow: ellipsis; vertical-align: text-bottom; color: #bbb;/* white-space: pre-wrap; white-space: -moz-pre-wrap !important; white-space: -pre-wrap; white-space: -o-pre-wrap;*/ } .form dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0px; white-space: nowrap; vertical-align: text-bottom; } label:hover, dt:hover { color: #333; } -#address.form dt { min-width: 5em; } -#address.form dl { min-width: 10em; } +/*::-webkit-input-placeholder { color: #bbb; } +:-moz-placeholder { color: #bbb; } +:-ms-input-placeholder { color: #bbb; }*/ .droptarget { margin: 0.5em; padding: 0.5em; border: thin solid #ccc; -moz-border-radius:.3em; -webkit-border-radius:.3em; border-radius:.3em; } .droppable { margin: 0.5em; padding: 0.5em; border: thin dashed #333; -moz-border-radius:.3em; -webkit-border-radius:.3em; border-radius:.3em; } .loading { background: url('%webroot%/core/img/loading.gif') no-repeat center !important; /*cursor: progress; */ cursor: wait; } @@ -79,10 +80,17 @@ label:hover, dt:hover { color: #333; } #addressdisplay { padding: 0.5em; } dl.addresscard { background-color: #fff; float: left; width: auto; margin: 0 0.3em 0.3em 0.3em; padding: 0; border: 0; } dl.addresscard dd {} -dl.addresscard dt { padding: 0.3em; font-weight: bold; clear: both; color: #bbb;} +dl.addresscard dt { padding: 0.3em; font-weight: bold; clear: both; color: #aaa; } dl.addresscard dt:hover { color:#777; } dl.addresscard dd > ul { margin: 0.3em; padding: 0.3em; } dl.addresscard .action { float: right; } +#address dt { width: 30%; white-space:nowrap; } +#address dd { width: 66%; } +#address input { width: 12em; padding: 0.6em 0.5em 0.4em; } +#address input:-moz-placeholder { color: #aaa; } +#address input::-webkit-input-placeholder { color: #aaa; } +#address input:-ms-input-placeholder { color: #aaa; } +#address input:placeholder { color: #aaa; } #adr_type {} /* Select */ #adr_pobox {} #adr_extended {} diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js index e15dc0278f6..35d4a4a216d 100644 --- a/apps/contacts/js/contacts.js +++ b/apps/contacts/js/contacts.js @@ -1281,7 +1281,7 @@ Contacts={ }, Addressbooks:{ droptarget:undefined, - droptext:t('contacts', 'Drop a VCF file to import contacts.'), + droptext:t('contacts', 'Drop a VCF file
to import contacts.'), overview:function(){ if($('#chooseaddressbook_dialog').dialog('isOpen') == true){ $('#chooseaddressbook_dialog').dialog('moveToTop'); @@ -1290,7 +1290,7 @@ Contacts={ $.getJSON(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(jsondata){ if(jsondata.status == 'success'){ $('#addressbook_dialog').html(jsondata.data.page).find('#chooseaddressbook_dialog').dialog({ - width : 600, + minWidth : 600, close : function(event, ui) { $(this).dialog('destroy').remove(); $('#addressbook_dialog').remove(); diff --git a/apps/contacts/js/jquery.combobox.js b/apps/contacts/js/jquery.combobox.js index f12d1d7dd20..d9959eb6cde 100644 --- a/apps/contacts/js/jquery.combobox.js +++ b/apps/contacts/js/jquery.combobox.js @@ -23,16 +23,16 @@ minLength: 0, source: function( request, response ) { var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" ); - response( select.children( "option" ).map(function() { + response( select.children('option').map(function() { var text = $( this ).text(); if ( this.value && ( !request.term || matcher.test(text) ) ) return { label: text.replace( new RegExp( - "(?![^&;]+;)(?!<[^<>]*)(" + + '(?![^&;]+;)(?!<[^<>]*)(' + $.ui.autocomplete.escapeRegex(request.term) + - ")(?![^<>]*>)(?![^&;]+;)", "gi" - ), "$1" ), + ')(?![^<>]*>)(?![^&;]+;)', 'gi' + ), '$1'), value: text, option: this }; @@ -42,17 +42,17 @@ self.input.val($(ui.item.option).text()); self.input.trigger('change'); ui.item.option.selected = true; - self._trigger( "selected", event, { + self._trigger('selected', event, { item: ui.item.option }); }, change: function( event, ui ) { if ( !ui.item ) { - var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ), + var matcher = new RegExp( '^' + $.ui.autocomplete.escapeRegex( $(this).val() ) + '$', 'i' ), valid = false; self.input.val($(this).val()); //self.input.trigger('change'); - select.children( "option" ).each(function() { + select.children('option').each(function() { if ( $( this ).text().match( matcher ) ) { this.selected = valid = true; return false; @@ -62,36 +62,41 @@ // remove invalid value, as it didn't match anything $( this ).val( "" ); select.val( "" ); - input.data( "autocomplete" ).term = ""; + input.data('autocomplete').term = ''; return false; } } } }) - .addClass( "ui-widget ui-widget-content ui-corner-left" ); + .addClass('ui-widget ui-widget-content ui-corner-left'); - input.data( "autocomplete" )._renderItem = function( ul, item ) { - return $( "
  • " ) - .data( "item.autocomplete", item ) - .append( "" + item.label + "" ) + input.data('autocomplete')._renderItem = function( ul, item ) { + return $('
  • ') + .data('item.autocomplete', item ) + .append('' + item.label + '') .appendTo( ul ); }; $.each(this.options, function(key, value) { self._setOption(key, value); }); + input.dblclick(function() { + // pass empty string as value to search for, displaying all results + input.autocomplete('search', ''); + }); + if(this.options['showButton']) { - this.button = $( "" ) - .attr( "tabIndex", -1 ) - .attr( "title", "Show All Items" ) + this.button = $('') + .attr('tabIndex', -1 ) + .attr('title', 'Show All Items') .insertAfter( input ) .addClass('svg') .addClass('action') .addClass('combo-button') .click(function() { // close if already visible - if ( input.autocomplete( "widget" ).is( ":visible" ) ) { - input.autocomplete( "close" ); + if ( input.autocomplete('widget').is(':visible') ) { + input.autocomplete('close'); return; } @@ -99,7 +104,7 @@ $( this ).blur(); // pass empty string as value to search for, displaying all results - input.autocomplete( "search", "" ); + input.autocomplete('search', ''); input.focus(); }); } diff --git a/apps/contacts/templates/part.edit_address_dialog.php b/apps/contacts/templates/part.edit_address_dialog.php index 8b3425033cc..7684795f348 100644 --- a/apps/contacts/templates/part.edit_address_dialog.php +++ b/apps/contacts/templates/part.edit_address_dialog.php @@ -24,18 +24,17 @@ foreach(isset($adr['parameters']['TYPE'])?array($adr['parameters']['TYPE']):arra
    +
    + +
    + +
    - -
    -
    - -
    -
    - +
    @@ -47,13 +46,13 @@ foreach(isset($adr['parameters']['TYPE'])?array($adr['parameters']['TYPE']):arra
    - +
    - +
    diff --git a/apps/contacts/templates/part.importaddressbook.php b/apps/contacts/templates/part.importaddressbook.php index 6702262f231..0e2956ddaf4 100644 --- a/apps/contacts/templates/part.importaddressbook.php +++ b/apps/contacts/templates/part.importaddressbook.php @@ -22,7 +22,7 @@ if(OCP\App::isEnabled('files_encryption')) { echo OCP\html_select_options($contacts_options, $contacts_options[0]['id'], array('value'=>'id', 'label'=>'displayname')); ?> - t("Drop a VCF file to import contacts."); ?> (Max. ) + t("Drop a VCF file
    to import contacts."); ?> (Max. )
    @@ -36,5 +36,7 @@ if(OCP\App::isEnabled('files_encryption')) { \ No newline at end of file diff --git a/apps/gallery/ajax/thumbnail.php b/apps/gallery/ajax/thumbnail.php index ff0cb44022c..4fc9eba992d 100644 --- a/apps/gallery/ajax/thumbnail.php +++ b/apps/gallery/ajax/thumbnail.php @@ -20,14 +20,15 @@ * License along with this library. If not, see . * */ - OCP\JSON::checkLoggedIn(); OCP\JSON::checkAppEnabled('gallery'); +require_once('apps/gallery/lib/managers.php'); -$img = $_GET['img']; -$image = OC_Gallery_Photo::getThumbnail($img); +$img = $_GET['filepath']; + +$image = \OC\Pictures\ThumbnailsManager::getInstance()->getThumbnail($img); if ($image) { OCP\Response::enableCaching(3600 * 24); // 24 hour $image->show(); diff --git a/apps/gallery/appinfo/database.xml b/apps/gallery/appinfo/database.xml index f370e1521e4..d1ccd6b5a24 100644 --- a/apps/gallery/appinfo/database.xml +++ b/apps/gallery/appinfo/database.xml @@ -5,16 +5,8 @@ false latin1 - *dbprefix*gallery_albums + *dbprefix*pictures_images_cache - - album_id - integer - 0 - true - 1 - 4 - uid_owner text @@ -22,48 +14,22 @@ 64 - album_name - text - true - 100 - - - album_path + path text true 256 - parent_path - text - true - 256 - - -
    - - *dbprefix*gallery_photos - - - photo_id + width integer - 0 - true - 1 - 4 - - - album_id - integer - 0 true 4 - file_path - text + height + integer true - 256 + 4
    diff --git a/apps/gallery/appinfo/update.php b/apps/gallery/appinfo/update.php new file mode 100644 index 00000000000..dd248e21b3e --- /dev/null +++ b/apps/gallery/appinfo/update.php @@ -0,0 +1,9 @@ +execute(); +$stmt = OCP\DB::prepare('DROP TABLE IF EXISTS *PREFIX*gallery_albums'); +$stmt->execute(); + +\OC_DB::createDbFromStructure('./database.xml'); + diff --git a/apps/gallery/appinfo/version b/apps/gallery/appinfo/version index 17b2ccd9bf9..8f0916f768f 100644 --- a/apps/gallery/appinfo/version +++ b/apps/gallery/appinfo/version @@ -1 +1 @@ -0.4.3 +0.5.0 diff --git a/apps/gallery/index.php b/apps/gallery/index.php index a9fe200c4e4..9d4654a7cc5 100644 --- a/apps/gallery/index.php +++ b/apps/gallery/index.php @@ -27,26 +27,6 @@ OCP\User::checkLoggedIn(); OCP\App::checkAppEnabled('gallery'); OCP\App::setActiveNavigationEntry( 'gallery_index' ); -if (!isset($_GET['view'])) { - $result = OC_Gallery_Album::find(OCP\USER::getUser()); - - $r = array(); - while ($row = $result->fetchRow()) - $r[] = $row; - - $tmpl = new OCP\Template( 'gallery', 'index', 'user' ); - $tmpl->assign('r', $r); - $tmpl->printPage(); -} else { - $result = OC_Gallery_Photo::findForAlbum(OCP\USER::getUser(), $_GET['view']); - - $photos = array(); - while ($p = $result->fetchRow()) - $photos[] = $p['file_path']; - - $tmpl = new OCP\Template( 'gallery', 'view_album', 'user' ); - $tmpl->assign('photos', $photos); - $tmpl->assign('albumName', $_GET['view']); - $tmpl->printPage(); -} +$tmpl = new OCP\Template( 'gallery', 'index', 'user' ); +$tmpl->printPage(); ?> diff --git a/apps/gallery/lib/managers.php b/apps/gallery/lib/managers.php new file mode 100644 index 00000000000..2444659d0a4 --- /dev/null +++ b/apps/gallery/lib/managers.php @@ -0,0 +1,97 @@ +execute(array(\OCP\USER::getUser(), $path)); + if (($row = $result->fetchRow()) != false) { + return $row; + } + $image = new \OC_Image(); + if (!$image->loadFromFile($path)) { + return false; + } + \OCP\DB::beginTransaction(); + $stmt = \OCP\DB::prepare('INSERT INTO *PREFIX*pictures_images_cache (uid_owner, path, width, height) VALUES (?, ?, ?, ?)'); + $stmt->execute(array(\OCP\USER::getUser(), $path, $image->width(), $image->height())); + \OCP\DB::commit(); + $ret = array('filepath' => $path, 'width' => $image->width(), 'height' => $image->height()); + unset($image); + return $ret; + } + + private function __construct() {} +} + +class ThumbnailsManager { + + private static $instance = null; + const TAG = 'ThumbnailManager'; + + public static function getInstance() { + if (self::$instance === null) + self::$instance = new ThumbnailsManager(); + return self::$instance; + } + + public function getThumbnail($path) { + $gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery'; + if (file_exists($gallery_path.$path)) { + return new \OC_Image($gallery_path.$path); + } + if (!\OC_Filesystem::file_exists($path)) { + \OC_Log::write(self::TAG, 'File '.$path.' don\'t exists', \OC_Log::WARN); + return false; + } + $image = new \OC_Image(); + $image->loadFromFile(\OC_Filesystem::getLocalFile($path)); + if (!$image->valid()) return false; + + $image->fixOrientation(); + + $ret = $image->preciseResize(floor((150*$image->width())/$image->height()), 150); + + if (!$ret) { + \OC_Log::write(self::TAG, 'Couldn\'t resize image', \OC_Log::ERROR); + unset($image); + return false; + } + + $image->save($gallery_path.'/'.$path); + return $image; + } + + public function getThumbnailInfo($path) { + $arr = DatabaseManager::getInstance()->getFileData($path); + $ret = array('filepath' => $arr['path'], + 'width' => $arr['width'], + 'height' => $arr['height']); + return $ret; + } + + public function delete($path) { + unlink(\OC::$CONFIG_DATADIRECTORY_ROOT.'/'.\OC_User::getUser()."/gallery".$path); + } + + private function __construct() {} + +} +?> diff --git a/apps/gallery/lib/tiles.php b/apps/gallery/lib/tiles.php new file mode 100644 index 00000000000..ff9519142ac --- /dev/null +++ b/apps/gallery/lib/tiles.php @@ -0,0 +1,178 @@ +tiles_array = array(); + } + + public function setAvailableSpace($space) { + $available_space = $space; + } + + public function getTilesCount() { + return count($this->tiles_array); + } + + public function addTile($tile) { + array_push($this->tiles_array, $tile); + } + + public function getLeftSpace() { + $occupied_space = 0; + for ($i = 0; $i < count($this->tiles_array); $i++) { + $occupied_space += $this->tiles_array[$i]->getWidth(); + } + return $this->available_space - $occupied_space; + } + + public function tileWillFit($tile) { + return $this->getLeftSpace() > $tile->getWidth(); + } + + public function get() { + $r = ''; + return $r; + } + + private $tiles_array; + private $available_space; +} + +class TileSingle extends TileBase { + + public function __construct($path) { + \OC_Log::write(TAG, 'Loading file from path '.$path, \OC_Log::DEBUG); + $this->file_path = $path; +/* $this->image = new \OC_Image(); + if (!$this->image->loadFromFile($this->file_path)) { + \OC_Log::write(TAG, 'Loading file filed', \OC_Log::ERROR); + return; + } + $this->image->fixOrientation();*/ + } + + public function getWidth() { + $a = ThumbnailsManager::getInstance()->getThumbnailInfo($this->file_path); + return $a['width']; + } + + public function get($extra = '') { + // !HACK! file path needs to be encoded twice because files app decode twice url, so any special chars like + or & in filename + // !HACK! will result in failing of opening them + return ''; + } + + public function getMiniatureSrc() { + return \OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath()); + } + + public function getPath() { + return $this->file_path; + } + + public function getOnClickAction() { + return '';//'javascript:openFile(\''.$this->file_path.'\');'; + } + + private $file_path; + private $image; +} + +class TileStack extends TileBase { + + const STACK_REPRESENTATIVES = 3; + + public function __construct($path_array, $stack_name) { + $this->tiles_array = array(); + $this->stack_name = $stack_name; + for ($i = 0; $i < count($path_array) && $i < self::STACK_REPRESENTATIVES; $i++) { + $tile = new TileSingle($path_array[$i]); + array_push($this->tiles_array, $tile); + } + } + + public function forceSize($width_must_fit=false) { + for ($i = 0; $i < count($this->tiles_array); $i++) + $this->tiles_array[$i]->forceSize(true); + } + + public function getWidth() { + $max = 0; + for ($i = 0; $i < count($this->tiles_array); $i++) { + $max = max($max, $this->tiles_array[$i]->getWidth()); + } + return min(IMAGE_WIDTH, $max); + } + + public function get() { + $r = ''; + for ($i = 0; $i < count($this->tiles_array); $i++) { + $top = rand(-5, 5); + $left = rand(-5, 5); + $img_w = $this->tiles_array[$i]->getWidth(); + $extra = ''; + if ($img_w < IMAGE_WIDTH) { + $extra = 'width:'.$img_w.'px;'; + } + $r .= ''; + } + return $r; + } + + public function getOnHoverAction() { + return 'javascript:t(this);return false;'; + } + + public function getOnOutAction() { + return 'javascript:o(this);return false;'; + } + + public function getCount() { + return count($this->tiles_array); + } + + public function getOnClickAction() { + return 'javascript:openNewGal(\''.$this->stack_name.'\');'; + } + + private $tiles_array; + private $stack_name; +} + +?> diff --git a/apps/gallery/lib/tiles_test.php b/apps/gallery/lib/tiles_test.php new file mode 100644 index 00000000000..022a88f75cc --- /dev/null +++ b/apps/gallery/lib/tiles_test.php @@ -0,0 +1,87 @@ + + + + + +addTile(new \OC\Pictures\TileSingle($images[$i])); + continue; + } + if (strcmp($prev_dir_arr[0], $dir_arr[0])!=0) { + $tl->addTile(new \OC\Pictures\TileStack($arr, $prev_dir_arr[0])); + $arr = array(); + } + $arr[] = $root.$images[$i]; + $previous_element = $images[$i]; +} + +$dir_arr = explode('/', $previous_element); + +if (count($dir_arr)==0) { + $tl->addTile(new \OC\Pictures\TileSingle($previous_element)); +} else if (count($dir_arr) && $ts->getCount() == 0){ + $ts = new \OC\Pictures\TileStack(array($previous_element), $dir_arr[0]); +} else { + $arr[] = $previous_element; + $ts->addTile($arr); +} + +if ($ts->getCount() != 0) { + $tl->addTile($ts); +} + +echo $tl->get(); + +?> diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php index 99af3bda0a3..39e3bbf47b3 100644 --- a/apps/gallery/templates/index.php +++ b/apps/gallery/templates/index.php @@ -1,31 +1,105 @@ - -
    -
    -
    - - - - -
    -
    -
    - main -
    -
    - -
    - + + + +addTile(new \OC\Pictures\TileSingle($root.$images[$i])); + continue; + } + if (strcmp($prev_dir_arr[0], $dir_arr[0])!=0) { + $tl->addTile(new \OC\Pictures\TileStack($arr, $prev_dir_arr[0])); + $arr = array(); + } + $arr[] = $root.$images[$i]; + $previous_element = $images[$i]; +} + +$dir_arr = explode('/', $previous_element); + +if (count($images)>1) { + if (count($dir_arr)==0) { + $tl->addTile(new \OC\Pictures\TileSingle($previous_element)); + } else if (count($dir_arr) && $ts->getCount() == 0){ + $ts = new \OC\Pictures\TileStack(array($root.$previous_element), $dir_arr[0]); + } else { + $arr[] = $previous_element; + $ts->addTile($arr); + } +} + +if ($ts->getCount() != 0) { + $tl->addTile($ts); +} + +echo $tl->get(); + +?> diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php index baca1d32bad..62e7c8ca6bc 100644 --- a/apps/user_ldap/group_ldap.php +++ b/apps/user_ldap/group_ldap.php @@ -27,6 +27,11 @@ class OC_GROUP_LDAP extends OC_Group_Backend { protected $ldapGroupMemberAssocAttr; protected $configured = false; + protected $_group_user = array(); + protected $_user_groups = array(); + protected $_group_users = array(); + protected $_groups = array(); + public function __construct() { $this->ldapGroupFilter = OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)'); $this->ldapGroupMemberAssocAttr = OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'); @@ -48,6 +53,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(!$this->configured) { return false; } + if(isset($this->_group_user[$gid][$uid])) { + return $this->_group_user[$gid][$uid]; + } $dn_user = OC_LDAP::username2dn($uid); $dn_group = OC_LDAP::groupname2dn($gid); // just in case @@ -64,8 +72,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend { //TODO: this can be done with one LDAP query if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') { $dns = array(); - foreach($members as $uid) { - $filter = str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter')); + foreach($members as $mid) { + $filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter')); $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn'); if(count($ldap_users) < 1) { continue; @@ -75,7 +83,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend { $members = $dns; } - return in_array($dn_user, $members); + $this->_group_user[$gid][$uid] = in_array($dn_user, $members); + return $this->_group_user[$gid][$uid]; } /** @@ -90,8 +99,12 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(!$this->configured) { return array(); } + if(isset($this->_user_groups[$uid])) { + return $this->_user_groups[$uid]; + } $userDN = OC_LDAP::username2dn($uid); if(!$userDN) { + $this->_user_groups[$uid] = array(); return array(); } @@ -112,9 +125,9 @@ class OC_GROUP_LDAP extends OC_Group_Backend { $this->ldapGroupMemberAssocAttr.'='.$uid )); $groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn')); - $userGroups = OC_LDAP::ownCloudGroupNames($groups); + $this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING); - return array_unique($userGroups, SORT_LOCALE_STRING); + return $this->_user_groups[$uid]; } /** @@ -125,14 +138,19 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(!$this->configured) { return array(); } + if(isset($this->_group_users[$gid])) { + return $this->_group_users[$gid]; + } $groupDN = OC_LDAP::groupname2dn($gid); if(!$groupDN) { + $this->_group_users[$gid] = array(); return array(); } $members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr); if(!$members) { + $this->_group_users[$gid] = array(); return array(); } @@ -154,7 +172,8 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(!$isMemberUid) { $result = array_intersect($result, OCP\User::getUsers()); } - return array_unique($result, SORT_LOCALE_STRING); + $this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING); + return $this->_group_users[$gid]; } /** @@ -167,10 +186,11 @@ class OC_GROUP_LDAP extends OC_Group_Backend { if(!$this->configured) { return array(); } - - $ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn')); - $groups = OC_LDAP::ownCloudGroupNames($ldap_groups); - return $groups; + if(is_null($this->_groups)) { + $ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn')); + $this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups); + } + return $this->groups; } /** diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php index f6942ad326e..22d464b65a2 100644 --- a/apps/user_ldap/lib_ldap.php +++ b/apps/user_ldap/lib_ldap.php @@ -52,6 +52,8 @@ class OC_LDAP { static protected $ldapGroupDisplayName; static protected $ldapLoginFilter; + static protected $__d; + /** * @brief initializes the LDAP backend * @param $force read the config settings no matter what @@ -59,6 +61,9 @@ class OC_LDAP { * initializes the LDAP backend */ static public function init($force = false) { + if(is_null(self::$__d)) { + self::$__d = new OC_LDAP_DESTRUCTOR(); + } self::readConfiguration($force); self::establishConnection(); } @@ -258,7 +263,7 @@ class OC_LDAP { $key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']); //everything is fine when we know the group - if($key) { + if($key !== false) { $ownCloudNames[] = $knownObjects[$key]['owncloud_name']; continue; } @@ -329,30 +334,6 @@ class OC_LDAP { 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 @@ -380,12 +361,22 @@ class OC_LDAP { SELECT 1 FROM '.$table.' WHERE ldap_dn = ? - AND owncloud_name = ? ) + OR owncloud_name = ? ) '); $res = $insert->execute(array($dn, $ocname, $dn, $ocname)); - return !OCP\DB::isError($res); + if(OCP\DB::isError($res)) { + return false; + } + + $insRows = $res->numRows(); + + if($insRows == 0) { + return false; + } + + return true; } static public function fetchListOfUsers($filter, $attr) { diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index ba66c7a9ca8..9281aebe81d 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -34,6 +34,9 @@ class OC_USER_LDAP extends OC_User_Backend { // will be retrieved from LDAP server protected $ldap_dc = false; + // cache getUsers() + protected $_users = null; + public function __construct() { $this->ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)'); $this->ldapQuotaAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', ''); @@ -108,9 +111,11 @@ class OC_USER_LDAP extends OC_User_Backend { * Get a list of all users. */ public function getUsers(){ - $ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn')); - $users = OC_LDAP::ownCloudUserNames($ldap_users); - return $users; + if(is_null($this->_users)) { + $ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn')); + $this->_users = OC_LDAP::ownCloudUserNames($ldap_users); + } + return $this->_users; } /** @@ -119,7 +124,7 @@ class OC_USER_LDAP extends OC_User_Backend { * @return boolean */ public function userExists($uid){ - return in_array($uid, self::getUsers()); + return in_array($uid, $this->getUsers()); } } diff --git a/apps/user_migrate/js/export.js b/apps/user_migrate/js/export.js index 2d660b2de6b..aef45c45a7b 100644 --- a/apps/user_migrate/js/export.js +++ b/apps/user_migrate/js/export.js @@ -9,7 +9,7 @@ $(document).ready(function(){ function(result){ if(result.status == 'success'){ // Download the file - window.location = OC.filePath('user_migrate','ajax','export.php?operation=download') ; + window.location = OC.linkTo('user_migrate','ajax/export.php') + '?operation=download'; $('.loading').hide(); $('#exportbtn').val(t('user_migrate', 'Export')); } else { diff --git a/core/lostpassword/index.php b/core/lostpassword/index.php index f1d90eaeffe..6bed7bdd93f 100644 --- a/core/lostpassword/index.php +++ b/core/lostpassword/index.php @@ -23,7 +23,6 @@ if (isset($_POST['user'])) { $msg = $tmpl->fetchPage(); $l = OC_L10N::get('core'); $from = 'lostpassword-noreply@' . OCP\Util::getServerHost(); - $r=mail($email, $l->t('Owncloud password reset'), $msg, 'From:' . $from); OC_MAIL::send($email,$_POST['user'],$l->t('ownCloud password reset'),$msg,$from,'ownCloud'); echo('sent'); diff --git a/lib/cache.php b/lib/cache.php index 70f11f35518..55d5b064c41 100644 --- a/lib/cache.php +++ b/lib/cache.php @@ -10,7 +10,17 @@ class OC_Cache { static protected $cache; static protected function init() { + $fast_cache = null; + if (!$fast_cache && function_exists('xcache_set')) { + $fast_cache = new OC_Cache_XCache(); + } + if (!$fast_cache && function_exists('apc_store')) { + $fast_cache = new OC_Cache_APC(); + } self::$cache = new OC_Cache_File(); + if ($fast_cache) { + self::$cache = new OC_Cache_Broker($fast_cache, self::$cache); + } } static public function get($key) { diff --git a/lib/cache/broker.php b/lib/cache/broker.php new file mode 100644 index 00000000000..62a7cd96d15 --- /dev/null +++ b/lib/cache/broker.php @@ -0,0 +1,55 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class OC_Cache_Broker { + protected $fast_cache; + protected $slow_cache; + + public function __construct($fast_cache, $slow_cache) { + $this->fast_cache = $fast_cache; + $this->slow_cache = $slow_cache; + } + + public function get($key) { + if ($r = $this->fast_cache->get($key)) { + return $r; + } + return $this->slow_cache->get($key); + } + + public function set($key, $value, $ttl=0) { + $set_slow = strlen($value) > 8192; + if ($set_slow) { + if ($this->fast_cache->hasKey($key)) { + $this->fast_cache->remove($key); + } + $this->slow_cache->set($key, $value, $ttl); + } else { + $this->fast_cache->set($key, $value, $ttl); + } + } + + public function hasKey($key) { + if ($this->fast_cache->hasKey($key)) { + return true; + } + return $this->slow_cache->hasKey($key); + } + + public function remove($key) { + if ($this->fast_cache->remove($key)) { + return true; + } + return $this->slow_cache->remove($key); + } + + public function clear(){ + $this->fast_cache->clear(); + $this->slow_cache->clear(); + } +} diff --git a/lib/image.php b/lib/image.php index a6bb92cea27..af61f9424e9 100644 --- a/lib/image.php +++ b/lib/image.php @@ -136,6 +136,8 @@ class OC_Image { */ private function _output($filepath=null) { if($filepath) { + if (!file_exists(dirname($filepath))) + mkdir(dirname($filepath), 0777, true); if(!is_writable(dirname($filepath))) { OC_Log::write('core',__METHOD__.'(): Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR); return false; @@ -426,7 +428,7 @@ class OC_Image { if(is_resource($str)) { return false; } - $this->resource = imagecreatefromstring($str); + $this->resource = @imagecreatefromstring($str); if(!$this->resource) { OC_Log::write('core','OC_Image->loadFromData, couldn\'t load', OC_Log::DEBUG); return false; @@ -445,7 +447,7 @@ class OC_Image { } $data = base64_decode($str); if($data) { // try to load from string data - $this->resource = imagecreatefromstring($data); + $this->resource = @imagecreatefromstring($data); if(!$this->resource) { OC_Log::write('core','OC_Image->loadFromBase64, couldn\'t load', OC_Log::DEBUG); return false; @@ -496,6 +498,32 @@ class OC_Image { return true; } + public function preciseResize($width, $height) { + if (!$this->valid()) { + OC_Log::write('core',__METHOD__.'(): No image loaded', OC_Log::ERROR); + return false; + } + $width_orig=imageSX($this->resource); + $height_orig=imageSY($this->resource); + $process = imagecreatetruecolor($width, $height); + + if ($process == false) { + OC_Log::write('core',__METHOD__.'(): Error creating true color image',OC_Log::ERROR); + imagedestroy($process); + return false; + } + + imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); + if ($process == false) { + OC_Log::write('core',__METHOD__.'(): Error resampling process image '.$width.'x'.$height,OC_Log::ERROR); + imagedestroy($process); + return false; + } + imagedestroy($this->resource); + $this->resource = $process; + return true; + } + /** * @brief Crops the image to the middle square. If the image is already square it just returns. * @param int maximum size for the result (optional) diff --git a/lib/l10n.php b/lib/l10n.php index 70b32b92984..887652e2b85 100644 --- a/lib/l10n.php +++ b/lib/l10n.php @@ -77,6 +77,10 @@ class OC_L10N{ * language. */ public function __construct($app, $lang = null){ + $this->init($app, $lang); + } + + protected function init($app, $lang = null){ // Find the right language if(is_null($lang)){ $lang = self::findLanguage($app); diff --git a/settings/templates/help.php b/settings/templates/help.php index a53ec76d681..cf61207e601 100644 --- a/settings/templates/help.php +++ b/settings/templates/help.php @@ -26,9 +26,9 @@
    "") { echo(''); } ?> - '') echo('

    '.$kb["name"].'

    ');?> -

    - '') echo('

    '.$l->t('Answer').':

    '.$kb['answer'].'

    ');?> + '') echo('

    '.htmlentities($kb["name"]).'

    ');?> +

    + '') echo('

    '.$l->t('Answer').':

    '.htmlentities($kb['answer']).'

    ');?>