summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Needham <needham.thomas@gmail.com>2012-07-26 11:26:22 +0000
committerTom Needham <needham.thomas@gmail.com>2012-07-26 11:26:22 +0000
commitedb04b25dea733e0ac3a1f87c55cfd368dcdf731 (patch)
treee8b951b8162955d7f2282c83d06cf803e61396f3
parent7de97ed20003d1f5ab9e2bfde9386bba07d0eff8 (diff)
parentb3848581bf5f77008a71cf79ba6e3d61b33baed6 (diff)
downloadnextcloud-server-edb04b25dea733e0ac3a1f87c55cfd368dcdf731.tar.gz
nextcloud-server-edb04b25dea733e0ac3a1f87c55cfd368dcdf731.zip
Fix merge conflicts
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules3
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre.includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Backend/Abstract.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Backend/PDO.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Calendar.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/CalendarObject.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/CalendarQueryParser.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/CalendarQueryValidator.php28
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/CalendarRootNode.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/ICSExportPlugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/ICalendar.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/ICalendarObject.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Plugin.php36
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/Collection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/ProxyRead.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Principal/User.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Schedule/IMip.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Schedule/IOutbox.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Schedule/Outbox.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Server.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/UserCalendars.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/Version.php2
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CalDAV/includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/AddressBook.php4
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/AddressBookQueryParser.php18
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/AddressBookRoot.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Backend/Abstract.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Backend/PDO.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Card.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/IAddressBook.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/ICard.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/IDirectory.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Plugin.php79
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/UserAddressBooks.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/Version.php2
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/CardDAV/includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/Apache.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/File.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Backend/PDO.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/IBackend.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Auth/Plugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/GuessContentType.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/Plugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/favicon.icobin4286 -> 4286 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.pngbin7232 -> 7232 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/calendar.pngbin4388 -> 4388 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/card.pngbin5695 -> 5695 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/collection.pngbin3474 -> 3474 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/file.pngbin2837 -> 2837 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/parent.pngbin3474 -> 3474 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Browser/assets/icons/principal.pngbin5480 -> 5480 bytes
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Client.php49
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Collection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Directory.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/BadRequest.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/Conflict.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/ConflictingLock.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/FileNotFound.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/Forbidden.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/InsufficientStorage.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/InvalidResourceType.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/Locked.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/NotAuthenticated.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/NotFound.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/NotImplemented.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/PaymentRequired.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/PreconditionFailed.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FS/Directory.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FS/File.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FS/Node.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FSExt/Directory.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FSExt/File.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/FSExt/Node.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/File.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/ICollection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IExtendedCollection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IFile.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/INode.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IProperties.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/IQuota.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/Abstract.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/FS.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/File.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Backend/PDO.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/LockInfo.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Locks/Plugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Mount/Plugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Node.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/ObjectTree.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/GetLastModified.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/Href.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/HrefList.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/IHref.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/LockDiscovery.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/ResourceType.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/Response.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/ResponseList.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/SupportedLock.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Property/SupportedReportSet.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Server.php9
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/ServerPlugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/SimpleCollection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/SimpleDirectory.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/SimpleFile.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/StringUtil.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Tree.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Tree/Filesystem.php4
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/URLUtil.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/UUIDUtil.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/Version.php2
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/XMLUtil.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAV/includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/AceConflict.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NoAbstract.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/IACL.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/IPrincipal.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/IPrincipalBackend.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Plugin.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Principal.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/PrincipalCollection.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/Acl.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/AclRestrictions.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/Principal.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/Version.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/DAVACL/includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/AWSAuth.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/AbstractAuth.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/BasicAuth.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/DigestAuth.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Request.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Response.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Util.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/Version.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/HTTP/includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component/VAlarm.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component/VCalendar.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component/VEvent.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component/VJournal.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Component/VTodo.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/DateTimeParser.php4
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Element.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Element/DateTime.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Element/MultiDateTime.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/ElementList.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/FreeBusyGenerator.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Node.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Parameter.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/ParseException.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Property.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Property/DateTime.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Property/MultiDateTime.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Reader.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/RecurrenceIterator.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/Version.php2
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/WindowsTimezoneMap.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/VObject/includes.php0
-rwxr-xr-x[-rw-r--r--]3rdparty/Sabre/autoload.php0
m---------3rdparty/Symfony/Component/Routing0
-rw-r--r--3rdparty/miniColors/GPL-LICENSE.txt278
-rw-r--r--3rdparty/miniColors/MIT-LICENSE.txt20
-rwxr-xr-x3rdparty/miniColors/css/images/colors.pngbin0 -> 12485 bytes
-rwxr-xr-x3rdparty/miniColors/css/images/trigger.pngbin0 -> 1406 bytes
-rwxr-xr-x3rdparty/miniColors/css/jquery.miniColors.css81
-rwxr-xr-x3rdparty/miniColors/js/jquery.miniColors.js580
-rwxr-xr-x3rdparty/miniColors/js/jquery.miniColors.min.js9
-rw-r--r--3rdparty/openid/class.openid.v3.php (renamed from apps/user_openid/class.openid.v3.php)0
-rw-r--r--3rdparty/openid/phpmyid.php (renamed from apps/user_openid/phpmyid.php)1
-rw-r--r--apps/bookmarks/ajax/addBookmark.php2
-rw-r--r--apps/bookmarks/ajax/delBookmark.php2
-rw-r--r--apps/bookmarks/ajax/editBookmark.php2
-rw-r--r--apps/bookmarks/lib/bookmarks.php3
-rw-r--r--apps/calendar/ajax/calendar/activation.php2
-rw-r--r--apps/calendar/ajax/calendar/delete.php1
-rw-r--r--apps/calendar/ajax/calendar/new.php3
-rw-r--r--apps/calendar/ajax/calendar/update.php1
-rw-r--r--apps/calendar/ajax/categories/rescan.php1
-rw-r--r--apps/calendar/ajax/event/delete.php1
-rw-r--r--apps/calendar/ajax/event/edit.php1
-rw-r--r--apps/calendar/ajax/event/move.php1
-rw-r--r--apps/calendar/ajax/event/new.form.php2
-rw-r--r--apps/calendar/ajax/event/new.php1
-rw-r--r--apps/calendar/ajax/event/resize.php1
-rw-r--r--apps/calendar/ajax/import/calendarcheck.php18
-rw-r--r--apps/calendar/ajax/import/dialog.php2
-rw-r--r--apps/calendar/ajax/import/dropimport.php89
-rw-r--r--apps/calendar/ajax/import/import.php77
-rw-r--r--apps/calendar/ajax/settings/setfirstday.php1
-rw-r--r--apps/calendar/ajax/settings/settimeformat.php1
-rw-r--r--apps/calendar/ajax/settings/settimezone.php1
-rw-r--r--apps/calendar/ajax/share/changepermission.php4
-rw-r--r--apps/calendar/ajax/share/share.php2
-rw-r--r--apps/calendar/ajax/share/unshare.php4
-rw-r--r--apps/calendar/appinfo/app.php4
-rw-r--r--apps/calendar/appinfo/remote.php2
-rw-r--r--apps/calendar/appinfo/version2
-rw-r--r--apps/calendar/css/import.css14
-rw-r--r--apps/calendar/js/calendar.js19
-rw-r--r--apps/calendar/js/loader.js214
-rw-r--r--apps/calendar/js/settings.js4
-rw-r--r--apps/calendar/lib/app.php14
-rw-r--r--apps/calendar/lib/calendar.php36
-rw-r--r--apps/calendar/lib/hooks.php13
-rw-r--r--apps/calendar/lib/import.php334
-rw-r--r--apps/calendar/lib/object.php2
-rw-r--r--apps/calendar/lib/search.php2
-rw-r--r--apps/calendar/settings.php1
-rw-r--r--apps/calendar/templates/calendar.php8
-rw-r--r--apps/calendar/templates/part.import.php74
-rw-r--r--apps/calendar/templates/settings.php6
-rw-r--r--apps/contacts/ajax/activation.php8
-rw-r--r--apps/contacts/ajax/addaddressbook.php37
-rw-r--r--apps/contacts/ajax/addbook.php1
-rw-r--r--apps/contacts/ajax/addcontact.php10
-rw-r--r--apps/contacts/ajax/addproperty.php42
-rw-r--r--apps/contacts/ajax/categories/categoriesfor.php16
-rw-r--r--apps/contacts/ajax/categories/delete.php5
-rw-r--r--apps/contacts/ajax/categories/list.php2
-rw-r--r--apps/contacts/ajax/categories/rescan.php20
-rw-r--r--apps/contacts/ajax/contactdetails.php5
-rw-r--r--apps/contacts/ajax/createaddressbook.php2
-rw-r--r--apps/contacts/ajax/currentphoto.php4
-rw-r--r--apps/contacts/ajax/deletecard.php12
-rw-r--r--apps/contacts/ajax/deleteproperty.php11
-rw-r--r--apps/contacts/ajax/editaddress.php6
-rw-r--r--apps/contacts/ajax/editaddressbook.php1
-rw-r--r--apps/contacts/ajax/editname.php8
-rw-r--r--apps/contacts/ajax/importaddressbook.php23
-rw-r--r--apps/contacts/ajax/importdialog.php1
-rw-r--r--apps/contacts/ajax/loadcard.php14
-rw-r--r--apps/contacts/ajax/loadintro.php2
-rw-r--r--apps/contacts/ajax/loadphoto.php46
-rw-r--r--apps/contacts/ajax/loghandler.php10
-rw-r--r--apps/contacts/ajax/oc_photo.php8
-rw-r--r--apps/contacts/ajax/savecrop.php22
-rw-r--r--apps/contacts/ajax/saveproperty.php21
-rw-r--r--apps/contacts/ajax/selectaddressbook.php16
-rw-r--r--apps/contacts/ajax/updateaddressbook.php2
-rw-r--r--apps/contacts/ajax/uploadimport.php43
-rw-r--r--apps/contacts/ajax/uploadphoto.php47
-rw-r--r--apps/contacts/appinfo/app.php3
-rw-r--r--apps/contacts/appinfo/database.xml4
-rw-r--r--apps/contacts/appinfo/migrate.php15
-rw-r--r--apps/contacts/appinfo/remote.php5
-rw-r--r--apps/contacts/appinfo/update.php2
-rw-r--r--apps/contacts/appinfo/version2
-rw-r--r--apps/contacts/carddav.php6
-rw-r--r--apps/contacts/css/contacts.css22
-rw-r--r--apps/contacts/export.php19
-rw-r--r--apps/contacts/import.php69
-rw-r--r--apps/contacts/index.php73
-rw-r--r--apps/contacts/js/contacts.js1228
-rw-r--r--apps/contacts/js/jquery.inview.js4
-rw-r--r--apps/contacts/js/loader.js4
-rw-r--r--apps/contacts/lib/VCFExportPlugin.php100
-rw-r--r--apps/contacts/lib/addressbook.php84
-rw-r--r--apps/contacts/lib/app.php29
-rw-r--r--apps/contacts/lib/connector_sabre.php10
-rw-r--r--apps/contacts/lib/hooks.php24
-rw-r--r--apps/contacts/lib/search.php6
-rw-r--r--apps/contacts/lib/vcard.php130
-rw-r--r--apps/contacts/photo.php23
-rw-r--r--apps/contacts/settings.php2
-rw-r--r--apps/contacts/templates/index.php51
-rw-r--r--apps/contacts/templates/part.chooseaddressbook.php1
-rw-r--r--apps/contacts/templates/part.cropphoto.php1
-rw-r--r--apps/contacts/templates/part.edit_categories_dialog.php16
-rw-r--r--apps/contacts/templates/part.importaddressbook.php37
-rw-r--r--apps/contacts/templates/part.selectaddressbook.php27
-rw-r--r--apps/contacts/templates/settings.php6
-rw-r--r--apps/contacts/thumbnail.php27
-rw-r--r--apps/contacts/tmpphoto.php2
-rw-r--r--apps/external/ajax/setsites.php2
-rw-r--r--apps/external/index.php1
-rw-r--r--apps/external/lib/external.php2
-rw-r--r--apps/external/settings.php1
-rw-r--r--apps/files/ajax/autocomplete.php2
-rw-r--r--apps/files/ajax/delete.php3
-rw-r--r--apps/files/ajax/download.php1
-rw-r--r--apps/files/ajax/list.php2
-rw-r--r--apps/files/ajax/mimeicon.php2
-rw-r--r--apps/files/ajax/move.php3
-rw-r--r--apps/files/ajax/newfile.php57
-rw-r--r--apps/files/ajax/newfolder.php1
-rw-r--r--apps/files/ajax/rawlist.php2
-rw-r--r--apps/files/ajax/rename.php3
-rw-r--r--apps/files/ajax/scan.php5
-rw-r--r--apps/files/ajax/timezone.php2
-rw-r--r--apps/files/ajax/upload.php3
-rw-r--r--apps/files/appinfo/update.php11
-rw-r--r--apps/files/appinfo/version2
-rw-r--r--apps/files/download.php1
-rw-r--r--apps/files/index.php3
-rw-r--r--apps/files/js/filelist.js2
-rw-r--r--apps/files/js/files.js36
-rw-r--r--apps/files/settings.php2
-rw-r--r--apps/files_encryption/js/settings.js4
-rw-r--r--apps/files_encryption/lib/cryptstream.php3
-rw-r--r--apps/files_encryption/templates/settings.php2
-rw-r--r--apps/files_external/ajax/addMountPoint.php4
-rw-r--r--apps/files_external/ajax/addRootCertificate.php1
-rw-r--r--apps/files_external/ajax/removeMountPoint.php4
-rwxr-xr-xapps/files_external/lib/dropbox.php2
-rw-r--r--apps/files_external/lib/google.php9
-rw-r--r--apps/files_external/lib/smb.php2
-rw-r--r--apps/files_external/lib/webdav.php20
-rw-r--r--apps/files_external/templates/settings.php2
-rw-r--r--apps/files_external/tests/amazons3.php3
-rw-r--r--apps/files_external/tests/ftp.php1
-rw-r--r--apps/files_external/tests/google.php1
-rw-r--r--apps/files_external/tests/smb.php1
-rw-r--r--apps/files_external/tests/swift.php1
-rw-r--r--apps/files_external/tests/webdav.php1
-rw-r--r--apps/files_imageviewer/appinfo/app.php2
-rw-r--r--apps/files_pdfviewer/appinfo/app.php1
-rw-r--r--apps/files_pdfviewer/js/pdfjs/viewer.js11
-rw-r--r--apps/files_sharing/ajax/email.php6
-rw-r--r--apps/files_sharing/ajax/getitem.php2
-rw-r--r--apps/files_sharing/ajax/getstatuses.php2
-rw-r--r--apps/files_sharing/ajax/setpermissions.php3
-rw-r--r--apps/files_sharing/ajax/share.php3
-rw-r--r--apps/files_sharing/ajax/toggleresharing.php2
-rw-r--r--apps/files_sharing/ajax/unshare.php3
-rw-r--r--apps/files_sharing/ajax/userautocomplete.php2
-rw-r--r--apps/files_sharing/appinfo/version2
-rw-r--r--apps/files_sharing/get.php1
-rw-r--r--apps/files_sharing/lib_share.php2
-rw-r--r--apps/files_sharing/list.php2
-rw-r--r--apps/files_sharing/sharedstorage.php66
-rw-r--r--apps/files_sharing_log/appinfo/database.xml2
-rw-r--r--apps/files_texteditor/ajax/savefile.php1
-rw-r--r--apps/files_texteditor/appinfo/app.php1
-rw-r--r--apps/files_versions/ajax/expireAll.php3
-rw-r--r--apps/files_versions/ajax/rollbackVersion.php1
-rw-r--r--apps/files_versions/ajax/togglesettings.php3
-rw-r--r--apps/files_versions/appinfo/update.php16
-rw-r--r--apps/files_versions/appinfo/version2
-rw-r--r--apps/files_versions/history.php4
-rw-r--r--apps/files_versions/lib/hooks.php19
-rw-r--r--apps/files_versions/lib/versions.php227
-rw-r--r--apps/files_versions/settings.php1
-rw-r--r--apps/gallery/ajax/createAlbum.php2
-rw-r--r--apps/gallery/ajax/galleryOp.php1
-rw-r--r--apps/gallery/ajax/viewImage.php32
-rw-r--r--apps/gallery/appinfo/version2
-rw-r--r--apps/gallery/css/styles.css4
-rw-r--r--apps/gallery/css/supersized.css25
-rw-r--r--apps/gallery/css/supersized.shutter.css74
-rw-r--r--apps/gallery/img/supersized/back.pngbin0 -> 2629 bytes
-rw-r--r--apps/gallery/img/supersized/bg-black.pngbin0 -> 1074 bytes
-rw-r--r--apps/gallery/img/supersized/bg-hover.pngbin0 -> 960 bytes
-rw-r--r--apps/gallery/img/supersized/button-tray-down.pngbin0 -> 1506 bytes
-rw-r--r--apps/gallery/img/supersized/button-tray-up.pngbin0 -> 1466 bytes
-rw-r--r--apps/gallery/img/supersized/forward.pngbin0 -> 2614 bytes
-rw-r--r--apps/gallery/img/supersized/nav-bg.pngbin0 -> 995 bytes
-rw-r--r--apps/gallery/img/supersized/nav-dot.pngbin0 -> 1901 bytes
-rw-r--r--apps/gallery/img/supersized/pause.pngbin0 -> 1131 bytes
-rw-r--r--apps/gallery/img/supersized/play.pngbin0 -> 1562 bytes
-rw-r--r--apps/gallery/img/supersized/progress-back.pngbin0 -> 929 bytes
-rw-r--r--apps/gallery/img/supersized/progress-bar.pngbin0 -> 929 bytes
-rw-r--r--apps/gallery/img/supersized/progress.gifbin0 -> 2608 bytes
-rw-r--r--apps/gallery/img/supersized/supersized-logo.pngbin0 -> 3982 bytes
-rw-r--r--apps/gallery/img/supersized/thumb-back.pngbin0 -> 2122 bytes
-rw-r--r--apps/gallery/img/supersized/thumb-forward.pngbin0 -> 2118 bytes
-rw-r--r--apps/gallery/index.php9
-rw-r--r--apps/gallery/js/albums.js2
-rw-r--r--apps/gallery/js/jquery.easing.min.js71
-rw-r--r--apps/gallery/js/slideshow.js58
-rw-r--r--apps/gallery/js/supersized.3.2.7.js930
-rw-r--r--apps/gallery/js/supersized.3.2.7.min.js13
-rw-r--r--apps/gallery/js/supersized.shutter.js337
-rw-r--r--apps/gallery/js/supersized.shutter.min.js14
-rw-r--r--apps/gallery/lib/album.php2
-rw-r--r--apps/gallery/lib/hooks_handlers.php2
-rw-r--r--apps/gallery/lib/images_utils.php2
-rw-r--r--apps/gallery/lib/managers.php59
-rw-r--r--apps/gallery/lib/photo.php105
-rw-r--r--apps/gallery/lib/tiles.php6
-rw-r--r--apps/gallery/lib/tiles_test.php2
-rw-r--r--apps/gallery/templates/index.php52
-rw-r--r--apps/gallery/templates/view_album.php8
-rw-r--r--apps/media/ajax/api.php1
-rw-r--r--apps/media/ajax/autoupdate.php1
-rw-r--r--apps/media/appinfo/version2
-rw-r--r--apps/media/index.php2
-rw-r--r--apps/media/lib_ampache.php3
-rw-r--r--apps/media/lib_collection.php5
-rw-r--r--apps/media/lib_media.php6
-rw-r--r--apps/media/settings.php1
-rw-r--r--apps/remoteStorage/appinfo/info.xml3
-rw-r--r--apps/remoteStorage/appinfo/version2
-rw-r--r--apps/remoteStorage/appinfo/webfinger.php6
-rw-r--r--apps/remoteStorage/lib_remoteStorage.php13
-rw-r--r--apps/remoteStorage/oauth_ro_auth.php20
-rw-r--r--apps/remoteStorage/settings.php1
-rw-r--r--apps/remoteStorage/webdav.php (renamed from apps/remoteStorage/WebDAV.php)36
-rw-r--r--apps/tasks/ajax/addtask.php3
-rw-r--r--apps/tasks/ajax/addtaskform.php20
-rw-r--r--apps/tasks/ajax/delete.php1
-rw-r--r--apps/tasks/ajax/edittask.php31
-rw-r--r--apps/tasks/ajax/edittaskform.php24
-rw-r--r--apps/tasks/ajax/getdetails.php24
-rw-r--r--apps/tasks/ajax/gettasks.php2
-rw-r--r--apps/tasks/ajax/update_property.php5
-rw-r--r--apps/tasks/index.php4
-rw-r--r--apps/tasks/js/tasks.js62
-rw-r--r--apps/tasks/lib/app.php18
-rw-r--r--apps/tasks/templates/part.addtaskform.php15
-rw-r--r--apps/tasks/templates/part.details.php42
-rw-r--r--apps/tasks/templates/part.edittaskform.php5
-rw-r--r--apps/tasks/templates/part.property.php22
-rw-r--r--apps/tasks/templates/part.taskform.php36
-rw-r--r--apps/tasks/templates/part.tasks.php3
-rw-r--r--apps/user_external/appinfo/app.php4
-rw-r--r--apps/user_external/appinfo/info.xml13
-rw-r--r--apps/user_external/appinfo/version1
-rw-r--r--apps/user_external/lib/ftp.php45
-rw-r--r--apps/user_external/lib/imap.php40
-rw-r--r--apps/user_external/lib/smb.php43
-rw-r--r--apps/user_external/tests/config.php28
-rw-r--r--apps/user_external/tests/ftp.php34
-rw-r--r--apps/user_external/tests/imap.php34
-rw-r--r--apps/user_external/tests/smb.php34
-rw-r--r--apps/user_ldap/appinfo/app.php14
-rw-r--r--apps/user_ldap/group_ldap.php94
-rw-r--r--apps/user_ldap/lib/access.php593
-rw-r--r--apps/user_ldap/lib/connection.php245
-rw-r--r--apps/user_ldap/lib_ldap.php721
-rw-r--r--apps/user_ldap/tests/group_ldap.php4
-rw-r--r--apps/user_ldap/user_ldap.php72
-rw-r--r--apps/user_migrate/appinfo/app.php1
-rw-r--r--apps/user_migrate/templates/settings.php2
-rw-r--r--apps/user_openid/user.php5
-rw-r--r--apps/user_openid/user_openid.php2
-rw-r--r--apps/user_webfinger/.htaccess5
-rw-r--r--apps/user_webfinger/appinfo/app.php2
-rw-r--r--apps/user_webfinger/appinfo/info.xml4
-rw-r--r--apps/user_webfinger/appinfo/version2
-rw-r--r--apps/user_webfinger/host-meta.php19
-rw-r--r--apps/user_webfinger/webfinger.php1
-rwxr-xr-xautotest.sh110
-rw-r--r--core/ajax/grouplist.php2
-rw-r--r--core/ajax/translations.php1
-rw-r--r--core/ajax/userlist.php2
-rw-r--r--core/ajax/validateuser.php2
-rw-r--r--core/ajax/vcategories/add.php2
-rw-r--r--core/ajax/vcategories/delete.php2
-rw-r--r--core/ajax/vcategories/edit.php2
-rw-r--r--core/css/styles.css2
-rw-r--r--core/js/eventsource.js1
-rw-r--r--core/strings.php1
-rw-r--r--core/templates/exception.php30
-rw-r--r--core/templates/layout.user.php1
-rw-r--r--core/templates/login.php2
-rw-r--r--lib/MDB2/Driver/Function/sqlite3.php1
-rw-r--r--lib/MDB2/Driver/Manager/sqlite3.php1
-rw-r--r--lib/MDB2/Driver/sqlite3.php4
-rwxr-xr-xlib/app.php9
-rw-r--r--lib/archive/zip.php4
-rw-r--r--lib/base.php8
-rw-r--r--lib/cache.php108
-rw-r--r--lib/cache/apc.php5
-rw-r--r--lib/cache/broker.php6
-rw-r--r--lib/cache/file.php5
-rw-r--r--lib/cache/xcache.php5
-rw-r--r--lib/connector/sabre/auth.php17
-rw-r--r--lib/connector/sabre/client.php83
-rw-r--r--lib/connector/sabre/directory.php24
-rw-r--r--lib/connector/sabre/file.php27
-rw-r--r--lib/connector/sabre/locks.php2
-rw-r--r--lib/connector/sabre/node.php29
-rw-r--r--lib/db.php15
-rw-r--r--lib/eventsource.php5
-rw-r--r--lib/exception.php93
-rw-r--r--lib/filecache.php36
-rw-r--r--lib/filecache/update.php1
-rw-r--r--lib/filestorage.php2
-rw-r--r--lib/filestorage/common.php2
-rw-r--r--lib/filestorage/local.php14
-rw-r--r--lib/filesystem.php225
-rw-r--r--lib/filesystemview.php436
-rw-r--r--lib/group.php8
-rw-r--r--lib/group/backend.php2
-rw-r--r--lib/group/database.php5
-rw-r--r--lib/group/dummy.php3
-rw-r--r--lib/group/example.php18
-rw-r--r--lib/group/interface.php76
-rw-r--r--lib/helper.php63
-rw-r--r--lib/image.php98
-rw-r--r--lib/installer.php30
-rw-r--r--lib/json.php14
-rw-r--r--lib/l10n.php7
-rw-r--r--lib/mail.php56
-rw-r--r--lib/migrate.php2
-rw-r--r--lib/mimetypes.fixlist.php22
-rw-r--r--lib/mimetypes.list.php13
-rw-r--r--lib/minimizer.php10
-rw-r--r--lib/ocs.php368
-rw-r--r--lib/ocsclient.php2
-rw-r--r--lib/preferences.php8
-rw-r--r--lib/public/app.php25
-rw-r--r--lib/public/config.php2
-rw-r--r--lib/public/db.php2
-rw-r--r--lib/public/files.php2
-rw-r--r--lib/public/groupinterface.php31
-rw-r--r--lib/public/json.php107
-rw-r--r--lib/public/response.php2
-rw-r--r--lib/public/template.php3
-rw-r--r--lib/public/user.php3
-rw-r--r--lib/public/userinterface.php31
-rw-r--r--lib/public/util.php13
-rw-r--r--lib/route.php65
-rw-r--r--lib/router.php50
-rw-r--r--lib/search/provider.php10
-rw-r--r--lib/setup.php5
-rw-r--r--lib/streamwrappers.php5
-rw-r--r--lib/template.php1
-rw-r--r--lib/templatelayout.php2
-rw-r--r--lib/updater.php1
-rw-r--r--lib/user.php58
-rw-r--r--lib/user/backend.php2
-rw-r--r--lib/user/database.php8
-rw-r--r--lib/user/example.php12
-rw-r--r--lib/user/interface.php60
-rwxr-xr-xlib/util.php61
-rw-r--r--lib/vcategories.php7
-rw-r--r--ocs/providers.php7
-rw-r--r--ocs/v1.php2
-rw-r--r--public.php1
-rw-r--r--remote.php10
-rw-r--r--search/ajax/search.php2
-rw-r--r--search/index.php2
-rw-r--r--settings/ajax/changepassword.php4
-rw-r--r--settings/ajax/creategroup.php4
-rw-r--r--settings/ajax/createuser.php3
-rw-r--r--settings/ajax/disableapp.php1
-rw-r--r--settings/ajax/enableapp.php1
-rw-r--r--settings/ajax/lostpassword.php4
-rw-r--r--settings/ajax/openid.php3
-rw-r--r--settings/ajax/removegroup.php3
-rw-r--r--settings/ajax/removeuser.php3
-rw-r--r--settings/ajax/setlanguage.php3
-rw-r--r--settings/ajax/setloglevel.php1
-rw-r--r--settings/ajax/setquota.php2
-rw-r--r--settings/ajax/togglegroups.php3
-rw-r--r--settings/apps.php2
-rw-r--r--settings/help.php2
-rw-r--r--settings/js/users.js35
-rw-r--r--settings/personal.php4
-rw-r--r--settings/users.php3
-rw-r--r--status.php3
-rw-r--r--tests/index.php57
-rw-r--r--tests/lib/cache.php21
-rw-r--r--tests/lib/cache/file.php25
-rw-r--r--tests/lib/user/database.php1
-rw-r--r--webapps.php56
580 files changed, 8758 insertions, 3766 deletions
diff --git a/.gitignore b/.gitignore
index e2ff07d14d8..ae636931706 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,9 @@ RCS/*
# netbeans
nbproject
+# phpStorm
+.idea
+
# geany
*.geany
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000000..0f4ad588071
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "3rdparty/Symfony/Component/Routing"]
+ path = 3rdparty/Symfony/Component/Routing
+ url = git://github.com/symfony/Routing.git
diff --git a/3rdparty/Sabre.includes.php b/3rdparty/Sabre.includes.php
index c1334373663..c1334373663 100644..100755
--- a/3rdparty/Sabre.includes.php
+++ b/3rdparty/Sabre.includes.php
diff --git a/3rdparty/Sabre/CalDAV/Backend/Abstract.php b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
index 7aba1d69ffe..7aba1d69ffe 100644..100755
--- a/3rdparty/Sabre/CalDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CalDAV/Backend/Abstract.php
diff --git a/3rdparty/Sabre/CalDAV/Backend/PDO.php b/3rdparty/Sabre/CalDAV/Backend/PDO.php
index ddacf940c74..ddacf940c74 100644..100755
--- a/3rdparty/Sabre/CalDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CalDAV/Backend/PDO.php
diff --git a/3rdparty/Sabre/CalDAV/Calendar.php b/3rdparty/Sabre/CalDAV/Calendar.php
index 623df2dd1b8..623df2dd1b8 100644..100755
--- a/3rdparty/Sabre/CalDAV/Calendar.php
+++ b/3rdparty/Sabre/CalDAV/Calendar.php
diff --git a/3rdparty/Sabre/CalDAV/CalendarObject.php b/3rdparty/Sabre/CalDAV/CalendarObject.php
index 72f0a578d16..72f0a578d16 100644..100755
--- a/3rdparty/Sabre/CalDAV/CalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/CalendarObject.php
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryParser.php b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
index bd0d343382f..bd0d343382f 100644..100755
--- a/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryParser.php
diff --git a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
index 1bb6b5d53fa..4bcd32cdf88 100644..100755
--- a/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
+++ b/3rdparty/Sabre/CalDAV/CalendarQueryValidator.php
@@ -294,6 +294,7 @@ class Sabre_CalDAV_CalendarQueryValidator {
// in the VALARM component code, so this is a hack, and an
// expensive one too.
if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
+
// Fire up the iterator!
$it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
while($it->valid()) {
@@ -304,14 +305,35 @@ class Sabre_CalDAV_CalendarQueryValidator {
// determine if we can 'give up' expanding events.
$firstAlarm = null;
foreach($expandedEvent->VALARM as $expandedAlarm) {
+
$effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
- if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
- $firstAlarm = $effectiveTrigger;
- }
if ($expandedAlarm->isInTimeRange($start, $end)) {
return true;
}
+ if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') {
+ // This is an alarm with a non-relative trigger
+ // time, likely created by a buggy client. The
+ // implication is that every alarm in this
+ // recurring event trigger at the exact same
+ // time. It doesn't make sense to traverse
+ // further.
+ } else {
+ // We store the first alarm as a means to
+ // figure out when we can stop traversing.
+ if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
+ $firstAlarm = $effectiveTrigger;
+ }
+ }
+
+ }
+ if (is_null($firstAlarm)) {
+ // No alarm was found.
+ //
+ // Or technically: No alarm that will change for
+ // every instance of the recurrence was found,
+ // which means we can assume there was no match.
+ return false;
}
if ($firstAlarm > $end) {
return false;
diff --git a/3rdparty/Sabre/CalDAV/CalendarRootNode.php b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
index 3907913cc78..3907913cc78 100644..100755
--- a/3rdparty/Sabre/CalDAV/CalendarRootNode.php
+++ b/3rdparty/Sabre/CalDAV/CalendarRootNode.php
diff --git a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
index ec42b406b2f..ec42b406b2f 100644..100755
--- a/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
+++ b/3rdparty/Sabre/CalDAV/ICSExportPlugin.php
diff --git a/3rdparty/Sabre/CalDAV/ICalendar.php b/3rdparty/Sabre/CalDAV/ICalendar.php
index 15d51ebcf79..15d51ebcf79 100644..100755
--- a/3rdparty/Sabre/CalDAV/ICalendar.php
+++ b/3rdparty/Sabre/CalDAV/ICalendar.php
diff --git a/3rdparty/Sabre/CalDAV/ICalendarObject.php b/3rdparty/Sabre/CalDAV/ICalendarObject.php
index 280f982a310..280f982a310 100644..100755
--- a/3rdparty/Sabre/CalDAV/ICalendarObject.php
+++ b/3rdparty/Sabre/CalDAV/ICalendarObject.php
diff --git a/3rdparty/Sabre/CalDAV/Plugin.php b/3rdparty/Sabre/CalDAV/Plugin.php
index d7d1d970518..5903968c003 100644..100755
--- a/3rdparty/Sabre/CalDAV/Plugin.php
+++ b/3rdparty/Sabre/CalDAV/Plugin.php
@@ -672,6 +672,42 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
+ if ($vobj->name !== 'VCALENDAR') {
+ throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support iCalendar objects.');
+ }
+
+ $foundType = null;
+ $foundUID = null;
+ foreach($vobj->getComponents() as $component) {
+ switch($component->name) {
+ case 'VTIMEZONE' :
+ continue 2;
+ case 'VEVENT' :
+ case 'VTODO' :
+ case 'VJOURNAL' :
+ if (is_null($foundType)) {
+ $foundType = $component->name;
+ if (!isset($component->UID)) {
+ throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' component must have an UID');
+ }
+ $foundUID = (string)$component->UID;
+ } else {
+ if ($foundType !== $component->name) {
+ throw new Sabre_DAV_Exception_BadRequest('A calendar object must only contain 1 component. We found a ' . $component->name . ' as well as a ' . $foundType);
+ }
+ if ($foundUID !== (string)$component->UID) {
+ throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' in this object must have identical UIDs');
+ }
+ }
+ break;
+ default :
+ throw new Sabre_DAV_Exception_BadRequest('You are not allowed to create components of type: ' . $component->name . ' here');
+
+ }
+ }
+ if (!$foundType)
+ throw new Sabre_DAV_Exception_BadRequest('iCalendar object must contain at least 1 of VEVENT, VTODO or VJOURNAL');
+
}
/**
diff --git a/3rdparty/Sabre/CalDAV/Principal/Collection.php b/3rdparty/Sabre/CalDAV/Principal/Collection.php
index abbefa5567a..abbefa5567a 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/Collection.php
+++ b/3rdparty/Sabre/CalDAV/Principal/Collection.php
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
index 4b3f035634a..4b3f035634a 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
+++ b/3rdparty/Sabre/CalDAV/Principal/ProxyRead.php
diff --git a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
index dd0c2e86edd..dd0c2e86edd 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
+++ b/3rdparty/Sabre/CalDAV/Principal/ProxyWrite.php
diff --git a/3rdparty/Sabre/CalDAV/Principal/User.php b/3rdparty/Sabre/CalDAV/Principal/User.php
index 8453b877a73..8453b877a73 100644..100755
--- a/3rdparty/Sabre/CalDAV/Principal/User.php
+++ b/3rdparty/Sabre/CalDAV/Principal/User.php
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
index 2ea078d7dac..2ea078d7dac 100644..100755
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
index 1d848dd5cf6..1d848dd5cf6 100644..100755
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCalendarData.php
diff --git a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
index 24e84d4c17d..24e84d4c17d 100644..100755
--- a/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
+++ b/3rdparty/Sabre/CalDAV/Property/SupportedCollationSet.php
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IMip.php b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
index 37e75fcc4a7..37e75fcc4a7 100644..100755
--- a/3rdparty/Sabre/CalDAV/Schedule/IMip.php
+++ b/3rdparty/Sabre/CalDAV/Schedule/IMip.php
diff --git a/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
index 46d77514bc0..46d77514bc0 100644..100755
--- a/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
+++ b/3rdparty/Sabre/CalDAV/Schedule/IOutbox.php
diff --git a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
index 014c37230d1..014c37230d1 100644..100755
--- a/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
+++ b/3rdparty/Sabre/CalDAV/Schedule/Outbox.php
diff --git a/3rdparty/Sabre/CalDAV/Server.php b/3rdparty/Sabre/CalDAV/Server.php
index 325e3d80a7f..325e3d80a7f 100644..100755
--- a/3rdparty/Sabre/CalDAV/Server.php
+++ b/3rdparty/Sabre/CalDAV/Server.php
diff --git a/3rdparty/Sabre/CalDAV/UserCalendars.php b/3rdparty/Sabre/CalDAV/UserCalendars.php
index b8d3f0573fa..b8d3f0573fa 100644..100755
--- a/3rdparty/Sabre/CalDAV/UserCalendars.php
+++ b/3rdparty/Sabre/CalDAV/UserCalendars.php
diff --git a/3rdparty/Sabre/CalDAV/Version.php b/3rdparty/Sabre/CalDAV/Version.php
index 939e903c89f..289a0c83a34 100644..100755
--- a/3rdparty/Sabre/CalDAV/Version.php
+++ b/3rdparty/Sabre/CalDAV/Version.php
@@ -14,7 +14,7 @@ class Sabre_CalDAV_Version {
/**
* Full version number
*/
- const VERSION = '1.6.2';
+ const VERSION = '1.6.3';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CalDAV/includes.php b/3rdparty/Sabre/CalDAV/includes.php
index 1ecb870a0e1..1ecb870a0e1 100644..100755
--- a/3rdparty/Sabre/CalDAV/includes.php
+++ b/3rdparty/Sabre/CalDAV/includes.php
diff --git a/3rdparty/Sabre/CardDAV/AddressBook.php b/3rdparty/Sabre/CardDAV/AddressBook.php
index 3b381e1eea3..12297175a85 100644..100755
--- a/3rdparty/Sabre/CardDAV/AddressBook.php
+++ b/3rdparty/Sabre/CardDAV/AddressBook.php
@@ -108,7 +108,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
*/
public function createFile($name,$vcardData = null) {
- $vcardData = stream_get_contents($vcardData);
+ if (is_resource($vcardData)) {
+ $vcardData = stream_get_contents($vcardData);
+ }
// Converting to UTF-8, if needed
$vcardData = Sabre_DAV_StringUtil::ensureUTF8($vcardData);
diff --git a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
index 85a4963127b..46bb8ff18dd 100644..100755
--- a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
+++ b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
@@ -9,7 +9,7 @@
* @package Sabre
* @subpackage CardDAV
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CardDAV_AddressBookQueryParser {
@@ -88,12 +88,22 @@ class Sabre_CardDAV_AddressBookQueryParser {
if (is_nan($limit)) $limit = null;
$filter = $this->xpath->query('/card:addressbook-query/card:filter');
- if ($filter->length !== 1) {
+
+ // According to the CardDAV spec there needs to be exactly 1 filter
+ // element. However, KDE 4.8.2 contains a bug that will encode 0 filter
+ // elements, so this is a workaround for that.
+ //
+ // See: https://bugs.kde.org/show_bug.cgi?id=300047
+ if ($filter->length === 0) {
+ $test = null;
+ $filter = null;
+ } elseif ($filter->length === 1) {
+ $filter = $filter->item(0);
+ $test = $this->xpath->evaluate('string(@test)', $filter);
+ } else {
throw new Sabre_DAV_Exception_BadRequest('Only one filter element is allowed');
}
- $filter = $filter->item(0);
- $test = $this->xpath->evaluate('string(@test)', $filter);
if (!$test) $test = self::TEST_ANYOF;
if ($test !== self::TEST_ANYOF && $test !== self::TEST_ALLOF) {
throw new Sabre_DAV_Exception_BadRequest('The test attribute must either hold "anyof" or "allof"');
diff --git a/3rdparty/Sabre/CardDAV/AddressBookRoot.php b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
index 9d37b15f08e..9d37b15f08e 100644..100755
--- a/3rdparty/Sabre/CardDAV/AddressBookRoot.php
+++ b/3rdparty/Sabre/CardDAV/AddressBookRoot.php
diff --git a/3rdparty/Sabre/CardDAV/Backend/Abstract.php b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
index e4806b7161f..e4806b7161f 100644..100755
--- a/3rdparty/Sabre/CardDAV/Backend/Abstract.php
+++ b/3rdparty/Sabre/CardDAV/Backend/Abstract.php
diff --git a/3rdparty/Sabre/CardDAV/Backend/PDO.php b/3rdparty/Sabre/CardDAV/Backend/PDO.php
index 413a77f3bcc..413a77f3bcc 100644..100755
--- a/3rdparty/Sabre/CardDAV/Backend/PDO.php
+++ b/3rdparty/Sabre/CardDAV/Backend/PDO.php
diff --git a/3rdparty/Sabre/CardDAV/Card.php b/3rdparty/Sabre/CardDAV/Card.php
index d7c66333837..d7c66333837 100644..100755
--- a/3rdparty/Sabre/CardDAV/Card.php
+++ b/3rdparty/Sabre/CardDAV/Card.php
diff --git a/3rdparty/Sabre/CardDAV/IAddressBook.php b/3rdparty/Sabre/CardDAV/IAddressBook.php
index 2bc275bcf74..2bc275bcf74 100644..100755
--- a/3rdparty/Sabre/CardDAV/IAddressBook.php
+++ b/3rdparty/Sabre/CardDAV/IAddressBook.php
diff --git a/3rdparty/Sabre/CardDAV/ICard.php b/3rdparty/Sabre/CardDAV/ICard.php
index a17299316c1..a17299316c1 100644..100755
--- a/3rdparty/Sabre/CardDAV/ICard.php
+++ b/3rdparty/Sabre/CardDAV/ICard.php
diff --git a/3rdparty/Sabre/CardDAV/IDirectory.php b/3rdparty/Sabre/CardDAV/IDirectory.php
index 22d4afeb24a..22d4afeb24a 100644..100755
--- a/3rdparty/Sabre/CardDAV/IDirectory.php
+++ b/3rdparty/Sabre/CardDAV/IDirectory.php
diff --git a/3rdparty/Sabre/CardDAV/Plugin.php b/3rdparty/Sabre/CardDAV/Plugin.php
index 9ebec243eb0..ca20e468497 100644..100755
--- a/3rdparty/Sabre/CardDAV/Plugin.php
+++ b/3rdparty/Sabre/CardDAV/Plugin.php
@@ -52,6 +52,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
$server->subscribeEvent('report', array($this,'report'));
$server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
$server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
+ $server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent'));
+ $server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile'));
/* Namespaces */
$server->xmlNamespaces[self::NS_CARDDAV] = 'card';
@@ -284,6 +286,81 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
/**
+ * This method is triggered before a file gets updated with new content.
+ *
+ * This plugin uses this method to ensure that Card nodes receive valid
+ * vcard data.
+ *
+ * @param string $path
+ * @param Sabre_DAV_IFile $node
+ * @param resource $data
+ * @return void
+ */
+ public function beforeWriteContent($path, Sabre_DAV_IFile $node, &$data) {
+
+ if (!$node instanceof Sabre_CardDAV_ICard)
+ return;
+
+ $this->validateVCard($data);
+
+ }
+
+ /**
+ * This method is triggered before a new file is created.
+ *
+ * This plugin uses this method to ensure that Card nodes receive valid
+ * vcard data.
+ *
+ * @param string $path
+ * @param resource $data
+ * @param Sabre_DAV_ICollection $parentNode
+ * @return void
+ */
+ public function beforeCreateFile($path, &$data, Sabre_DAV_ICollection $parentNode) {
+
+ if (!$parentNode instanceof Sabre_CardDAV_IAddressBook)
+ return;
+
+ $this->validateVCard($data);
+
+ }
+
+ /**
+ * Checks if the submitted iCalendar data is in fact, valid.
+ *
+ * An exception is thrown if it's not.
+ *
+ * @param resource|string $data
+ * @return void
+ */
+ protected function validateVCard(&$data) {
+
+ // If it's a stream, we convert it to a string first.
+ if (is_resource($data)) {
+ $data = stream_get_contents($data);
+ }
+
+ // Converting the data to unicode, if needed.
+ $data = Sabre_DAV_StringUtil::ensureUTF8($data);
+
+ try {
+
+ $vobj = Sabre_VObject_Reader::read($data);
+
+ } catch (Sabre_VObject_ParseException $e) {
+
+ throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid vcard data. Parse error: ' . $e->getMessage());
+
+ }
+
+ if ($vobj->name !== 'VCARD') {
+ throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support vcard objects.');
+ }
+
+ }
+
+
+ /**
* This function handles the addressbook-query REPORT
*
* This report is used by the client to filter an addressbook based on a
@@ -362,6 +439,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
$vcard = Sabre_VObject_Reader::read($vcardData);
+ if (!$filters) return true;
+
foreach($filters as $filter) {
$isDefined = isset($vcard->{$filter['name']});
diff --git a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
index 36d9306e7aa..36d9306e7aa 100644..100755
--- a/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
+++ b/3rdparty/Sabre/CardDAV/Property/SupportedAddressData.php
diff --git a/3rdparty/Sabre/CardDAV/UserAddressBooks.php b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
index 3f11fb11238..3f11fb11238 100644..100755
--- a/3rdparty/Sabre/CardDAV/UserAddressBooks.php
+++ b/3rdparty/Sabre/CardDAV/UserAddressBooks.php
diff --git a/3rdparty/Sabre/CardDAV/Version.php b/3rdparty/Sabre/CardDAV/Version.php
index 811b929e397..d0623f0d3e8 100644..100755
--- a/3rdparty/Sabre/CardDAV/Version.php
+++ b/3rdparty/Sabre/CardDAV/Version.php
@@ -16,7 +16,7 @@ class Sabre_CardDAV_Version {
/**
* Full version number
*/
- const VERSION = '1.6.1';
+ const VERSION = '1.6.3';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/CardDAV/includes.php b/3rdparty/Sabre/CardDAV/includes.php
index c3b8c04b077..c3b8c04b077 100644..100755
--- a/3rdparty/Sabre/CardDAV/includes.php
+++ b/3rdparty/Sabre/CardDAV/includes.php
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
index 1e89b84f9a1..1e89b84f9a1 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
index 9833928b976..9833928b976 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/AbstractDigest.php
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
index d4294ea4d86..d4294ea4d86 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/Apache.php
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/File.php b/3rdparty/Sabre/DAV/Auth/Backend/File.php
index de308d64a67..de308d64a67 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/File.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/File.php
diff --git a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
index eac18a23fbb..eac18a23fbb 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
+++ b/3rdparty/Sabre/DAV/Auth/Backend/PDO.php
diff --git a/3rdparty/Sabre/DAV/Auth/IBackend.php b/3rdparty/Sabre/DAV/Auth/IBackend.php
index 5be5d1bc93d..5be5d1bc93d 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/IBackend.php
+++ b/3rdparty/Sabre/DAV/Auth/IBackend.php
diff --git a/3rdparty/Sabre/DAV/Auth/Plugin.php b/3rdparty/Sabre/DAV/Auth/Plugin.php
index 55a4e391674..55a4e391674 100644..100755
--- a/3rdparty/Sabre/DAV/Auth/Plugin.php
+++ b/3rdparty/Sabre/DAV/Auth/Plugin.php
diff --git a/3rdparty/Sabre/DAV/Browser/GuessContentType.php b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
index b6c00d461cb..b6c00d461cb 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/GuessContentType.php
+++ b/3rdparty/Sabre/DAV/Browser/GuessContentType.php
diff --git a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
index 15884887641..15884887641 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
+++ b/3rdparty/Sabre/DAV/Browser/MapGetToPropFind.php
diff --git a/3rdparty/Sabre/DAV/Browser/Plugin.php b/3rdparty/Sabre/DAV/Browser/Plugin.php
index 09bbdd2ae02..09bbdd2ae02 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/Plugin.php
+++ b/3rdparty/Sabre/DAV/Browser/Plugin.php
diff --git a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
index 2b2c10a22cc..2b2c10a22cc 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
+++ b/3rdparty/Sabre/DAV/Browser/assets/favicon.ico
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
index c9acc84172d..c9acc84172d 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/addressbook.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
index 3ecd6a800a0..3ecd6a800a0 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/calendar.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
index 2ce954866d8..2ce954866d8 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/card.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
index 156fa64fd50..156fa64fd50 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/collection.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
index 3b98551cec3..3b98551cec3 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/file.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
index 156fa64fd50..156fa64fd50 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/parent.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
index f8988f828e6..f8988f828e6 100644..100755
--- a/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
+++ b/3rdparty/Sabre/DAV/Browser/assets/icons/principal.png
Binary files differ
diff --git a/3rdparty/Sabre/DAV/Client.php b/3rdparty/Sabre/DAV/Client.php
index 075e84caa1d..9a428765e90 100644..100755
--- a/3rdparty/Sabre/DAV/Client.php
+++ b/3rdparty/Sabre/DAV/Client.php
@@ -11,7 +11,7 @@
* @package Sabre
* @subpackage DAVClient
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
- * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_DAV_Client {
@@ -24,6 +24,28 @@ class Sabre_DAV_Client {
protected $proxy;
/**
+ * Basic authentication
+ */
+ const AUTH_BASIC = 1;
+
+ /**
+ * Digest authentication
+ */
+ const AUTH_DIGEST = 2;
+
+ /**
+ * The authentication type we're using.
+ *
+ * This is a bitmask of AUTH_BASIC and AUTH_DIGEST.
+ *
+ * If DIGEST is used, the client makes 1 extra request per request, to get
+ * the authentication tokens.
+ *
+ * @var int
+ */
+ protected $authType;
+
+ /**
* Constructor
*
* Settings are provided through the 'settings' argument. The following
@@ -46,16 +68,21 @@ class Sabre_DAV_Client {
'baseUri',
'userName',
'password',
- 'proxy'
+ 'proxy',
);
-
foreach($validSettings as $validSetting) {
if (isset($settings[$validSetting])) {
$this->$validSetting = $settings[$validSetting];
}
}
+ if (isset($settings['authType'])) {
+ $this->authType = $settings['authType'];
+ } else {
+ $this->authType = self::AUTH_BASIC | self::AUTH_DIGEST;
+ }
+
$this->propertyMap['{DAV:}resourcetype'] = 'Sabre_DAV_Property_ResourceType';
}
@@ -250,14 +277,9 @@ class Sabre_DAV_Client {
// Automatically follow redirects
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
- CURLOPT_SSL_VERIFYPEER => true,
- //CURLOPT_SSL_VERIFYPEER => false,
);
switch ($method) {
- case 'PUT':
- $curlSettings[CURLOPT_PUT] = true;
- break;
case 'HEAD' :
// do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
@@ -288,8 +310,15 @@ class Sabre_DAV_Client {
$curlSettings[CURLOPT_PROXY] = $this->proxy;
}
- if ($this->userName) {
- $curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST;
+ if ($this->userName && $this->authType) {
+ $curlType = 0;
+ if ($this->authType & self::AUTH_BASIC) {
+ $curlType |= CURLAUTH_BASIC;
+ }
+ if ($this->authType & self::AUTH_DIGEST) {
+ $curlType |= CURLAUTH_DIGEST;
+ }
+ $curlSettings[CURLOPT_HTTPAUTH] = $curlType;
$curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
}
diff --git a/3rdparty/Sabre/DAV/Collection.php b/3rdparty/Sabre/DAV/Collection.php
index 776c22531b2..776c22531b2 100644..100755
--- a/3rdparty/Sabre/DAV/Collection.php
+++ b/3rdparty/Sabre/DAV/Collection.php
diff --git a/3rdparty/Sabre/DAV/Directory.php b/3rdparty/Sabre/DAV/Directory.php
index 6db8febc02e..6db8febc02e 100644..100755
--- a/3rdparty/Sabre/DAV/Directory.php
+++ b/3rdparty/Sabre/DAV/Directory.php
diff --git a/3rdparty/Sabre/DAV/Exception.php b/3rdparty/Sabre/DAV/Exception.php
index a2cd6cf5820..a2cd6cf5820 100644..100755
--- a/3rdparty/Sabre/DAV/Exception.php
+++ b/3rdparty/Sabre/DAV/Exception.php
diff --git a/3rdparty/Sabre/DAV/Exception/BadRequest.php b/3rdparty/Sabre/DAV/Exception/BadRequest.php
index b198648a754..b198648a754 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/BadRequest.php
+++ b/3rdparty/Sabre/DAV/Exception/BadRequest.php
diff --git a/3rdparty/Sabre/DAV/Exception/Conflict.php b/3rdparty/Sabre/DAV/Exception/Conflict.php
index 6b0bd1fad73..6b0bd1fad73 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/Conflict.php
+++ b/3rdparty/Sabre/DAV/Exception/Conflict.php
diff --git a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
index 6121868e69e..6121868e69e 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
+++ b/3rdparty/Sabre/DAV/Exception/ConflictingLock.php
diff --git a/3rdparty/Sabre/DAV/Exception/FileNotFound.php b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
index d76e400c93b..d76e400c93b 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/FileNotFound.php
+++ b/3rdparty/Sabre/DAV/Exception/FileNotFound.php
diff --git a/3rdparty/Sabre/DAV/Exception/Forbidden.php b/3rdparty/Sabre/DAV/Exception/Forbidden.php
index 20b1056e31b..20b1056e31b 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/Forbidden.php
+++ b/3rdparty/Sabre/DAV/Exception/Forbidden.php
diff --git a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
index 1a15089b0a3..1a15089b0a3 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
+++ b/3rdparty/Sabre/DAV/Exception/InsufficientStorage.php
diff --git a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
index 2230f1d0811..2230f1d0811 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
+++ b/3rdparty/Sabre/DAV/Exception/InvalidResourceType.php
diff --git a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
index 80ab7aff65a..80ab7aff65a 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
+++ b/3rdparty/Sabre/DAV/Exception/LockTokenMatchesRequestUri.php
diff --git a/3rdparty/Sabre/DAV/Exception/Locked.php b/3rdparty/Sabre/DAV/Exception/Locked.php
index 976365ac1f8..976365ac1f8 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/Locked.php
+++ b/3rdparty/Sabre/DAV/Exception/Locked.php
diff --git a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
index 31875751505..31875751505 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
+++ b/3rdparty/Sabre/DAV/Exception/MethodNotAllowed.php
diff --git a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
index 87ca624429f..87ca624429f 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
+++ b/3rdparty/Sabre/DAV/Exception/NotAuthenticated.php
diff --git a/3rdparty/Sabre/DAV/Exception/NotFound.php b/3rdparty/Sabre/DAV/Exception/NotFound.php
index 2b9da560d23..2b9da560d23 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/NotFound.php
+++ b/3rdparty/Sabre/DAV/Exception/NotFound.php
diff --git a/3rdparty/Sabre/DAV/Exception/NotImplemented.php b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
index d017a19f559..d017a19f559 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/NotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/NotImplemented.php
diff --git a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
index 4982f45a4b5..4982f45a4b5 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
+++ b/3rdparty/Sabre/DAV/Exception/PaymentRequired.php
diff --git a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
index 213e9c52317..213e9c52317 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
+++ b/3rdparty/Sabre/DAV/Exception/PreconditionFailed.php
diff --git a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
index e86800f3038..e86800f3038 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
+++ b/3rdparty/Sabre/DAV/Exception/ReportNotImplemented.php
diff --git a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
index 29ee3654a7e..29ee3654a7e 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
+++ b/3rdparty/Sabre/DAV/Exception/RequestedRangeNotSatisfiable.php
diff --git a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
index 9a4693b21a8..9a4693b21a8 100644..100755
--- a/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
+++ b/3rdparty/Sabre/DAV/Exception/UnsupportedMediaType.php
diff --git a/3rdparty/Sabre/DAV/FS/Directory.php b/3rdparty/Sabre/DAV/FS/Directory.php
index 3af2d755583..3af2d755583 100644..100755
--- a/3rdparty/Sabre/DAV/FS/Directory.php
+++ b/3rdparty/Sabre/DAV/FS/Directory.php
diff --git a/3rdparty/Sabre/DAV/FS/File.php b/3rdparty/Sabre/DAV/FS/File.php
index 6a8039fe303..6a8039fe303 100644..100755
--- a/3rdparty/Sabre/DAV/FS/File.php
+++ b/3rdparty/Sabre/DAV/FS/File.php
diff --git a/3rdparty/Sabre/DAV/FS/Node.php b/3rdparty/Sabre/DAV/FS/Node.php
index 1283e9d0fdc..1283e9d0fdc 100644..100755
--- a/3rdparty/Sabre/DAV/FS/Node.php
+++ b/3rdparty/Sabre/DAV/FS/Node.php
diff --git a/3rdparty/Sabre/DAV/FSExt/Directory.php b/3rdparty/Sabre/DAV/FSExt/Directory.php
index 540057183b3..540057183b3 100644..100755
--- a/3rdparty/Sabre/DAV/FSExt/Directory.php
+++ b/3rdparty/Sabre/DAV/FSExt/Directory.php
diff --git a/3rdparty/Sabre/DAV/FSExt/File.php b/3rdparty/Sabre/DAV/FSExt/File.php
index b93ce5aee21..b93ce5aee21 100644..100755
--- a/3rdparty/Sabre/DAV/FSExt/File.php
+++ b/3rdparty/Sabre/DAV/FSExt/File.php
diff --git a/3rdparty/Sabre/DAV/FSExt/Node.php b/3rdparty/Sabre/DAV/FSExt/Node.php
index 68ca06beb7e..68ca06beb7e 100644..100755
--- a/3rdparty/Sabre/DAV/FSExt/Node.php
+++ b/3rdparty/Sabre/DAV/FSExt/Node.php
diff --git a/3rdparty/Sabre/DAV/File.php b/3rdparty/Sabre/DAV/File.php
index 3126bd8d364..3126bd8d364 100644..100755
--- a/3rdparty/Sabre/DAV/File.php
+++ b/3rdparty/Sabre/DAV/File.php
diff --git a/3rdparty/Sabre/DAV/ICollection.php b/3rdparty/Sabre/DAV/ICollection.php
index 4626038a66e..4626038a66e 100644..100755
--- a/3rdparty/Sabre/DAV/ICollection.php
+++ b/3rdparty/Sabre/DAV/ICollection.php
diff --git a/3rdparty/Sabre/DAV/IExtendedCollection.php b/3rdparty/Sabre/DAV/IExtendedCollection.php
index 6ec345f9a62..6ec345f9a62 100644..100755
--- a/3rdparty/Sabre/DAV/IExtendedCollection.php
+++ b/3rdparty/Sabre/DAV/IExtendedCollection.php
diff --git a/3rdparty/Sabre/DAV/IFile.php b/3rdparty/Sabre/DAV/IFile.php
index 478f822ae71..478f822ae71 100644..100755
--- a/3rdparty/Sabre/DAV/IFile.php
+++ b/3rdparty/Sabre/DAV/IFile.php
diff --git a/3rdparty/Sabre/DAV/INode.php b/3rdparty/Sabre/DAV/INode.php
index c57d3923105..c57d3923105 100644..100755
--- a/3rdparty/Sabre/DAV/INode.php
+++ b/3rdparty/Sabre/DAV/INode.php
diff --git a/3rdparty/Sabre/DAV/IProperties.php b/3rdparty/Sabre/DAV/IProperties.php
index 38eaab16dad..38eaab16dad 100644..100755
--- a/3rdparty/Sabre/DAV/IProperties.php
+++ b/3rdparty/Sabre/DAV/IProperties.php
diff --git a/3rdparty/Sabre/DAV/IQuota.php b/3rdparty/Sabre/DAV/IQuota.php
index 3fe4c4eced4..3fe4c4eced4 100644..100755
--- a/3rdparty/Sabre/DAV/IQuota.php
+++ b/3rdparty/Sabre/DAV/IQuota.php
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
index 127e643a2b9..127e643a2b9 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/Abstract.php
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/FS.php b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
index 02cab87fc82..02cab87fc82 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/FS.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/FS.php
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/File.php b/3rdparty/Sabre/DAV/Locks/Backend/File.php
index c33f963514b..c33f963514b 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/File.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/File.php
diff --git a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
index acce80638ec..acce80638ec 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
+++ b/3rdparty/Sabre/DAV/Locks/Backend/PDO.php
diff --git a/3rdparty/Sabre/DAV/Locks/LockInfo.php b/3rdparty/Sabre/DAV/Locks/LockInfo.php
index 9df014a4281..9df014a4281 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/LockInfo.php
+++ b/3rdparty/Sabre/DAV/Locks/LockInfo.php
diff --git a/3rdparty/Sabre/DAV/Locks/Plugin.php b/3rdparty/Sabre/DAV/Locks/Plugin.php
index fd956950b8a..fd956950b8a 100644..100755
--- a/3rdparty/Sabre/DAV/Locks/Plugin.php
+++ b/3rdparty/Sabre/DAV/Locks/Plugin.php
diff --git a/3rdparty/Sabre/DAV/Mount/Plugin.php b/3rdparty/Sabre/DAV/Mount/Plugin.php
index b37a90ae993..b37a90ae993 100644..100755
--- a/3rdparty/Sabre/DAV/Mount/Plugin.php
+++ b/3rdparty/Sabre/DAV/Mount/Plugin.php
diff --git a/3rdparty/Sabre/DAV/Node.php b/3rdparty/Sabre/DAV/Node.php
index 070b7176afd..070b7176afd 100644..100755
--- a/3rdparty/Sabre/DAV/Node.php
+++ b/3rdparty/Sabre/DAV/Node.php
diff --git a/3rdparty/Sabre/DAV/ObjectTree.php b/3rdparty/Sabre/DAV/ObjectTree.php
index bce51463900..bce51463900 100644..100755
--- a/3rdparty/Sabre/DAV/ObjectTree.php
+++ b/3rdparty/Sabre/DAV/ObjectTree.php
diff --git a/3rdparty/Sabre/DAV/Property.php b/3rdparty/Sabre/DAV/Property.php
index 1cfada3236c..1cfada3236c 100644..100755
--- a/3rdparty/Sabre/DAV/Property.php
+++ b/3rdparty/Sabre/DAV/Property.php
diff --git a/3rdparty/Sabre/DAV/Property/GetLastModified.php b/3rdparty/Sabre/DAV/Property/GetLastModified.php
index bd63f573140..bd63f573140 100644..100755
--- a/3rdparty/Sabre/DAV/Property/GetLastModified.php
+++ b/3rdparty/Sabre/DAV/Property/GetLastModified.php
diff --git a/3rdparty/Sabre/DAV/Property/Href.php b/3rdparty/Sabre/DAV/Property/Href.php
index dac564f24d7..dac564f24d7 100644..100755
--- a/3rdparty/Sabre/DAV/Property/Href.php
+++ b/3rdparty/Sabre/DAV/Property/Href.php
diff --git a/3rdparty/Sabre/DAV/Property/HrefList.php b/3rdparty/Sabre/DAV/Property/HrefList.php
index 7a52272e885..7a52272e885 100644..100755
--- a/3rdparty/Sabre/DAV/Property/HrefList.php
+++ b/3rdparty/Sabre/DAV/Property/HrefList.php
diff --git a/3rdparty/Sabre/DAV/Property/IHref.php b/3rdparty/Sabre/DAV/Property/IHref.php
index 5c0409064cb..5c0409064cb 100644..100755
--- a/3rdparty/Sabre/DAV/Property/IHref.php
+++ b/3rdparty/Sabre/DAV/Property/IHref.php
diff --git a/3rdparty/Sabre/DAV/Property/LockDiscovery.php b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
index 2ded5649a44..2ded5649a44 100644..100755
--- a/3rdparty/Sabre/DAV/Property/LockDiscovery.php
+++ b/3rdparty/Sabre/DAV/Property/LockDiscovery.php
diff --git a/3rdparty/Sabre/DAV/Property/ResourceType.php b/3rdparty/Sabre/DAV/Property/ResourceType.php
index f6269611e54..f6269611e54 100644..100755
--- a/3rdparty/Sabre/DAV/Property/ResourceType.php
+++ b/3rdparty/Sabre/DAV/Property/ResourceType.php
diff --git a/3rdparty/Sabre/DAV/Property/Response.php b/3rdparty/Sabre/DAV/Property/Response.php
index 88afbcfb26d..88afbcfb26d 100644..100755
--- a/3rdparty/Sabre/DAV/Property/Response.php
+++ b/3rdparty/Sabre/DAV/Property/Response.php
diff --git a/3rdparty/Sabre/DAV/Property/ResponseList.php b/3rdparty/Sabre/DAV/Property/ResponseList.php
index cae923afbf9..cae923afbf9 100644..100755
--- a/3rdparty/Sabre/DAV/Property/ResponseList.php
+++ b/3rdparty/Sabre/DAV/Property/ResponseList.php
diff --git a/3rdparty/Sabre/DAV/Property/SupportedLock.php b/3rdparty/Sabre/DAV/Property/SupportedLock.php
index 4e3aaf23a1a..4e3aaf23a1a 100644..100755
--- a/3rdparty/Sabre/DAV/Property/SupportedLock.php
+++ b/3rdparty/Sabre/DAV/Property/SupportedLock.php
diff --git a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
index e62699f3b5a..e62699f3b5a 100644..100755
--- a/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
+++ b/3rdparty/Sabre/DAV/Property/SupportedReportSet.php
diff --git a/3rdparty/Sabre/DAV/Server.php b/3rdparty/Sabre/DAV/Server.php
index 50b190e8fab..0dfac8b0c71 100644..100755
--- a/3rdparty/Sabre/DAV/Server.php
+++ b/3rdparty/Sabre/DAV/Server.php
@@ -215,7 +215,7 @@ class Sabre_DAV_Server {
$DOM->appendChild($error);
$error->appendChild($DOM->createElement('s:exception',get_class($e)));
- $error->appendChild($DOM->createElement('s:message',htmlentities($e->getMessage())));
+ $error->appendChild($DOM->createElement('s:message',$e->getMessage()));
if ($this->debugExceptions) {
$error->appendChild($DOM->createElement('s:file',$e->getFile()));
$error->appendChild($DOM->createElement('s:line',$e->getLine()));
@@ -1784,7 +1784,14 @@ class Sabre_DAV_Server {
$etag = $node->getETag();
if ($etag===$ifMatchItem) {
$haveMatch = true;
+ } else {
+ // Evolution has a bug where it sometimes prepends the "
+ // with a \. This is our workaround.
+ if (str_replace('\\"','"', $ifMatchItem) === $etag) {
+ $haveMatch = true;
+ }
}
+
}
if (!$haveMatch) {
throw new Sabre_DAV_Exception_PreconditionFailed('An If-Match header was specified, but none of the specified the ETags matched.','If-Match');
diff --git a/3rdparty/Sabre/DAV/ServerPlugin.php b/3rdparty/Sabre/DAV/ServerPlugin.php
index 131863d13fb..131863d13fb 100644..100755
--- a/3rdparty/Sabre/DAV/ServerPlugin.php
+++ b/3rdparty/Sabre/DAV/ServerPlugin.php
diff --git a/3rdparty/Sabre/DAV/SimpleCollection.php b/3rdparty/Sabre/DAV/SimpleCollection.php
index 4acf971caa5..4acf971caa5 100644..100755
--- a/3rdparty/Sabre/DAV/SimpleCollection.php
+++ b/3rdparty/Sabre/DAV/SimpleCollection.php
diff --git a/3rdparty/Sabre/DAV/SimpleDirectory.php b/3rdparty/Sabre/DAV/SimpleDirectory.php
index 621222ebc53..621222ebc53 100644..100755
--- a/3rdparty/Sabre/DAV/SimpleDirectory.php
+++ b/3rdparty/Sabre/DAV/SimpleDirectory.php
diff --git a/3rdparty/Sabre/DAV/SimpleFile.php b/3rdparty/Sabre/DAV/SimpleFile.php
index 58330d6861d..58330d6861d 100644..100755
--- a/3rdparty/Sabre/DAV/SimpleFile.php
+++ b/3rdparty/Sabre/DAV/SimpleFile.php
diff --git a/3rdparty/Sabre/DAV/StringUtil.php b/3rdparty/Sabre/DAV/StringUtil.php
index b126a94c825..b126a94c825 100644..100755
--- a/3rdparty/Sabre/DAV/StringUtil.php
+++ b/3rdparty/Sabre/DAV/StringUtil.php
diff --git a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
index 36096e67775..36096e67775 100644..100755
--- a/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
+++ b/3rdparty/Sabre/DAV/TemporaryFileFilterPlugin.php
diff --git a/3rdparty/Sabre/DAV/Tree.php b/3rdparty/Sabre/DAV/Tree.php
index 50216394155..50216394155 100644..100755
--- a/3rdparty/Sabre/DAV/Tree.php
+++ b/3rdparty/Sabre/DAV/Tree.php
diff --git a/3rdparty/Sabre/DAV/Tree/Filesystem.php b/3rdparty/Sabre/DAV/Tree/Filesystem.php
index 85a9ee317be..40580ae366f 100644..100755
--- a/3rdparty/Sabre/DAV/Tree/Filesystem.php
+++ b/3rdparty/Sabre/DAV/Tree/Filesystem.php
@@ -42,9 +42,9 @@ class Sabre_DAV_Tree_Filesystem extends Sabre_DAV_Tree {
$realPath = $this->getRealPath($path);
if (!file_exists($realPath)) throw new Sabre_DAV_Exception_NotFound('File at location ' . $realPath . ' not found');
if (is_dir($realPath)) {
- return new Sabre_DAV_FS_Directory($path);
+ return new Sabre_DAV_FS_Directory($realPath);
} else {
- return new Sabre_DAV_FS_File($path);
+ return new Sabre_DAV_FS_File($realPath);
}
}
diff --git a/3rdparty/Sabre/DAV/URLUtil.php b/3rdparty/Sabre/DAV/URLUtil.php
index 794665a44f6..794665a44f6 100644..100755
--- a/3rdparty/Sabre/DAV/URLUtil.php
+++ b/3rdparty/Sabre/DAV/URLUtil.php
diff --git a/3rdparty/Sabre/DAV/UUIDUtil.php b/3rdparty/Sabre/DAV/UUIDUtil.php
index f0eebe598e5..f0eebe598e5 100644..100755
--- a/3rdparty/Sabre/DAV/UUIDUtil.php
+++ b/3rdparty/Sabre/DAV/UUIDUtil.php
diff --git a/3rdparty/Sabre/DAV/Version.php b/3rdparty/Sabre/DAV/Version.php
index 5e5d15e4039..40cfe81b34f 100644..100755
--- a/3rdparty/Sabre/DAV/Version.php
+++ b/3rdparty/Sabre/DAV/Version.php
@@ -14,7 +14,7 @@ class Sabre_DAV_Version {
/**
* Full version number
*/
- const VERSION = '1.6.2';
+ const VERSION = '1.6.3';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/DAV/XMLUtil.php b/3rdparty/Sabre/DAV/XMLUtil.php
index 60eff3b159a..60eff3b159a 100644..100755
--- a/3rdparty/Sabre/DAV/XMLUtil.php
+++ b/3rdparty/Sabre/DAV/XMLUtil.php
diff --git a/3rdparty/Sabre/DAV/includes.php b/3rdparty/Sabre/DAV/includes.php
index 6a4890677ea..6a4890677ea 100644..100755
--- a/3rdparty/Sabre/DAV/includes.php
+++ b/3rdparty/Sabre/DAV/includes.php
diff --git a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
index e05b7749805..e05b7749805 100644..100755
--- a/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/AbstractPrincipalCollection.php
diff --git a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
index 4b9f93b0036..4b9f93b0036 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
+++ b/3rdparty/Sabre/DAVACL/Exception/AceConflict.php
diff --git a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
index 9b055dd9709..9b055dd9709 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NeedPrivileges.php
diff --git a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
index f44e3e32281..f44e3e32281 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NoAbstract.php
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
index 8d1e38ca1b4..8d1e38ca1b4 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NotRecognizedPrincipal.php
diff --git a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
index 3b5d012d7fa..3b5d012d7fa 100644..100755
--- a/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
+++ b/3rdparty/Sabre/DAVACL/Exception/NotSupportedPrivilege.php
diff --git a/3rdparty/Sabre/DAVACL/IACL.php b/3rdparty/Sabre/DAVACL/IACL.php
index 003e6993483..003e6993483 100644..100755
--- a/3rdparty/Sabre/DAVACL/IACL.php
+++ b/3rdparty/Sabre/DAVACL/IACL.php
diff --git a/3rdparty/Sabre/DAVACL/IPrincipal.php b/3rdparty/Sabre/DAVACL/IPrincipal.php
index fc7605bf625..fc7605bf625 100644..100755
--- a/3rdparty/Sabre/DAVACL/IPrincipal.php
+++ b/3rdparty/Sabre/DAVACL/IPrincipal.php
diff --git a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
index e798bf890c0..e798bf890c0 100644..100755
--- a/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
+++ b/3rdparty/Sabre/DAVACL/IPrincipalBackend.php
diff --git a/3rdparty/Sabre/DAVACL/Plugin.php b/3rdparty/Sabre/DAVACL/Plugin.php
index 5c828c6d97b..5c828c6d97b 100644..100755
--- a/3rdparty/Sabre/DAVACL/Plugin.php
+++ b/3rdparty/Sabre/DAVACL/Plugin.php
diff --git a/3rdparty/Sabre/DAVACL/Principal.php b/3rdparty/Sabre/DAVACL/Principal.php
index 51c6658afd6..51c6658afd6 100644..100755
--- a/3rdparty/Sabre/DAVACL/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Principal.php
diff --git a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
index a76b4a9d727..a76b4a9d727 100644..100755
--- a/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
+++ b/3rdparty/Sabre/DAVACL/PrincipalBackend/PDO.php
diff --git a/3rdparty/Sabre/DAVACL/PrincipalCollection.php b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
index c3e4cb83f23..c3e4cb83f23 100644..100755
--- a/3rdparty/Sabre/DAVACL/PrincipalCollection.php
+++ b/3rdparty/Sabre/DAVACL/PrincipalCollection.php
diff --git a/3rdparty/Sabre/DAVACL/Property/Acl.php b/3rdparty/Sabre/DAVACL/Property/Acl.php
index 05e1a690b3c..05e1a690b3c 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/Acl.php
+++ b/3rdparty/Sabre/DAVACL/Property/Acl.php
diff --git a/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
index a8b054956dd..a8b054956dd 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
+++ b/3rdparty/Sabre/DAVACL/Property/AclRestrictions.php
diff --git a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
index 94a29640615..94a29640615 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
+++ b/3rdparty/Sabre/DAVACL/Property/CurrentUserPrivilegeSet.php
diff --git a/3rdparty/Sabre/DAVACL/Property/Principal.php b/3rdparty/Sabre/DAVACL/Property/Principal.php
index c36328a58e0..c36328a58e0 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/Principal.php
+++ b/3rdparty/Sabre/DAVACL/Property/Principal.php
diff --git a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
index 276d57ae093..276d57ae093 100644..100755
--- a/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
+++ b/3rdparty/Sabre/DAVACL/Property/SupportedPrivilegeSet.php
diff --git a/3rdparty/Sabre/DAVACL/Version.php b/3rdparty/Sabre/DAVACL/Version.php
index 9950f748741..9950f748741 100644..100755
--- a/3rdparty/Sabre/DAVACL/Version.php
+++ b/3rdparty/Sabre/DAVACL/Version.php
diff --git a/3rdparty/Sabre/DAVACL/includes.php b/3rdparty/Sabre/DAVACL/includes.php
index 28fa3eed225..28fa3eed225 100644..100755
--- a/3rdparty/Sabre/DAVACL/includes.php
+++ b/3rdparty/Sabre/DAVACL/includes.php
diff --git a/3rdparty/Sabre/HTTP/AWSAuth.php b/3rdparty/Sabre/HTTP/AWSAuth.php
index fb8245c8cbf..fb8245c8cbf 100644..100755
--- a/3rdparty/Sabre/HTTP/AWSAuth.php
+++ b/3rdparty/Sabre/HTTP/AWSAuth.php
diff --git a/3rdparty/Sabre/HTTP/AbstractAuth.php b/3rdparty/Sabre/HTTP/AbstractAuth.php
index 3bccabcd1c1..3bccabcd1c1 100644..100755
--- a/3rdparty/Sabre/HTTP/AbstractAuth.php
+++ b/3rdparty/Sabre/HTTP/AbstractAuth.php
diff --git a/3rdparty/Sabre/HTTP/BasicAuth.php b/3rdparty/Sabre/HTTP/BasicAuth.php
index a747cc6a31b..a747cc6a31b 100644..100755
--- a/3rdparty/Sabre/HTTP/BasicAuth.php
+++ b/3rdparty/Sabre/HTTP/BasicAuth.php
diff --git a/3rdparty/Sabre/HTTP/DigestAuth.php b/3rdparty/Sabre/HTTP/DigestAuth.php
index ee7f05c08ed..ee7f05c08ed 100644..100755
--- a/3rdparty/Sabre/HTTP/DigestAuth.php
+++ b/3rdparty/Sabre/HTTP/DigestAuth.php
diff --git a/3rdparty/Sabre/HTTP/Request.php b/3rdparty/Sabre/HTTP/Request.php
index 4746ef77704..4746ef77704 100644..100755
--- a/3rdparty/Sabre/HTTP/Request.php
+++ b/3rdparty/Sabre/HTTP/Request.php
diff --git a/3rdparty/Sabre/HTTP/Response.php b/3rdparty/Sabre/HTTP/Response.php
index ffe9bda2082..ffe9bda2082 100644..100755
--- a/3rdparty/Sabre/HTTP/Response.php
+++ b/3rdparty/Sabre/HTTP/Response.php
diff --git a/3rdparty/Sabre/HTTP/Util.php b/3rdparty/Sabre/HTTP/Util.php
index 67bdd489e1e..67bdd489e1e 100644..100755
--- a/3rdparty/Sabre/HTTP/Util.php
+++ b/3rdparty/Sabre/HTTP/Util.php
diff --git a/3rdparty/Sabre/HTTP/Version.php b/3rdparty/Sabre/HTTP/Version.php
index 23dc7f8a7a1..23dc7f8a7a1 100644..100755
--- a/3rdparty/Sabre/HTTP/Version.php
+++ b/3rdparty/Sabre/HTTP/Version.php
diff --git a/3rdparty/Sabre/HTTP/includes.php b/3rdparty/Sabre/HTTP/includes.php
index 9d34bf3a8be..9d34bf3a8be 100644..100755
--- a/3rdparty/Sabre/HTTP/includes.php
+++ b/3rdparty/Sabre/HTTP/includes.php
diff --git a/3rdparty/Sabre/VObject/Component.php b/3rdparty/Sabre/VObject/Component.php
index b78a26133fa..b78a26133fa 100644..100755
--- a/3rdparty/Sabre/VObject/Component.php
+++ b/3rdparty/Sabre/VObject/Component.php
diff --git a/3rdparty/Sabre/VObject/Component/VAlarm.php b/3rdparty/Sabre/VObject/Component/VAlarm.php
index ebb4a9b18f6..ebb4a9b18f6 100644..100755
--- a/3rdparty/Sabre/VObject/Component/VAlarm.php
+++ b/3rdparty/Sabre/VObject/Component/VAlarm.php
diff --git a/3rdparty/Sabre/VObject/Component/VCalendar.php b/3rdparty/Sabre/VObject/Component/VCalendar.php
index f3be29afdbb..f3be29afdbb 100644..100755
--- a/3rdparty/Sabre/VObject/Component/VCalendar.php
+++ b/3rdparty/Sabre/VObject/Component/VCalendar.php
diff --git a/3rdparty/Sabre/VObject/Component/VEvent.php b/3rdparty/Sabre/VObject/Component/VEvent.php
index 4cc1e36d7d6..4cc1e36d7d6 100644..100755
--- a/3rdparty/Sabre/VObject/Component/VEvent.php
+++ b/3rdparty/Sabre/VObject/Component/VEvent.php
diff --git a/3rdparty/Sabre/VObject/Component/VJournal.php b/3rdparty/Sabre/VObject/Component/VJournal.php
index 22b3ec921e5..22b3ec921e5 100644..100755
--- a/3rdparty/Sabre/VObject/Component/VJournal.php
+++ b/3rdparty/Sabre/VObject/Component/VJournal.php
diff --git a/3rdparty/Sabre/VObject/Component/VTodo.php b/3rdparty/Sabre/VObject/Component/VTodo.php
index 79d06298d7f..79d06298d7f 100644..100755
--- a/3rdparty/Sabre/VObject/Component/VTodo.php
+++ b/3rdparty/Sabre/VObject/Component/VTodo.php
diff --git a/3rdparty/Sabre/VObject/DateTimeParser.php b/3rdparty/Sabre/VObject/DateTimeParser.php
index 1e2d54ef3a9..23a4bb69916 100644..100755
--- a/3rdparty/Sabre/VObject/DateTimeParser.php
+++ b/3rdparty/Sabre/VObject/DateTimeParser.php
@@ -125,6 +125,9 @@ class Sabre_VObject_DateTimeParser {
}
+ if ($duration==='P') {
+ $duration = 'PT0S';
+ }
$iv = new DateInterval($duration);
if ($invert) $iv->invert = true;
@@ -150,6 +153,7 @@ class Sabre_VObject_DateTimeParser {
}
$newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
+ if ($newDur === '+') { $newDur = '+0 seconds'; };
return $newDur;
}
diff --git a/3rdparty/Sabre/VObject/Element.php b/3rdparty/Sabre/VObject/Element.php
index e20ff0b353c..e20ff0b353c 100644..100755
--- a/3rdparty/Sabre/VObject/Element.php
+++ b/3rdparty/Sabre/VObject/Element.php
diff --git a/3rdparty/Sabre/VObject/Element/DateTime.php b/3rdparty/Sabre/VObject/Element/DateTime.php
index 5e5eb7ab6f2..5e5eb7ab6f2 100644..100755
--- a/3rdparty/Sabre/VObject/Element/DateTime.php
+++ b/3rdparty/Sabre/VObject/Element/DateTime.php
diff --git a/3rdparty/Sabre/VObject/Element/MultiDateTime.php b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
index 8a12ced94a8..8a12ced94a8 100644..100755
--- a/3rdparty/Sabre/VObject/Element/MultiDateTime.php
+++ b/3rdparty/Sabre/VObject/Element/MultiDateTime.php
diff --git a/3rdparty/Sabre/VObject/ElementList.php b/3rdparty/Sabre/VObject/ElementList.php
index 7e508db20f0..7e508db20f0 100644..100755
--- a/3rdparty/Sabre/VObject/ElementList.php
+++ b/3rdparty/Sabre/VObject/ElementList.php
diff --git a/3rdparty/Sabre/VObject/FreeBusyGenerator.php b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
index 1c96a64a004..1c96a64a004 100644..100755
--- a/3rdparty/Sabre/VObject/FreeBusyGenerator.php
+++ b/3rdparty/Sabre/VObject/FreeBusyGenerator.php
diff --git a/3rdparty/Sabre/VObject/Node.php b/3rdparty/Sabre/VObject/Node.php
index d89e01b56c6..d89e01b56c6 100644..100755
--- a/3rdparty/Sabre/VObject/Node.php
+++ b/3rdparty/Sabre/VObject/Node.php
diff --git a/3rdparty/Sabre/VObject/Parameter.php b/3rdparty/Sabre/VObject/Parameter.php
index 2e39af5f78a..2e39af5f78a 100644..100755
--- a/3rdparty/Sabre/VObject/Parameter.php
+++ b/3rdparty/Sabre/VObject/Parameter.php
diff --git a/3rdparty/Sabre/VObject/ParseException.php b/3rdparty/Sabre/VObject/ParseException.php
index 1b5e95bf16e..1b5e95bf16e 100644..100755
--- a/3rdparty/Sabre/VObject/ParseException.php
+++ b/3rdparty/Sabre/VObject/ParseException.php
diff --git a/3rdparty/Sabre/VObject/Property.php b/3rdparty/Sabre/VObject/Property.php
index ce74fe3865b..ce74fe3865b 100644..100755
--- a/3rdparty/Sabre/VObject/Property.php
+++ b/3rdparty/Sabre/VObject/Property.php
diff --git a/3rdparty/Sabre/VObject/Property/DateTime.php b/3rdparty/Sabre/VObject/Property/DateTime.php
index fe2372caa81..fe2372caa81 100644..100755
--- a/3rdparty/Sabre/VObject/Property/DateTime.php
+++ b/3rdparty/Sabre/VObject/Property/DateTime.php
diff --git a/3rdparty/Sabre/VObject/Property/MultiDateTime.php b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
index ae53ab6a617..ae53ab6a617 100644..100755
--- a/3rdparty/Sabre/VObject/Property/MultiDateTime.php
+++ b/3rdparty/Sabre/VObject/Property/MultiDateTime.php
diff --git a/3rdparty/Sabre/VObject/Reader.php b/3rdparty/Sabre/VObject/Reader.php
index eea73fa3dce..eea73fa3dce 100644..100755
--- a/3rdparty/Sabre/VObject/Reader.php
+++ b/3rdparty/Sabre/VObject/Reader.php
diff --git a/3rdparty/Sabre/VObject/RecurrenceIterator.php b/3rdparty/Sabre/VObject/RecurrenceIterator.php
index 833aa091ab7..833aa091ab7 100644..100755
--- a/3rdparty/Sabre/VObject/RecurrenceIterator.php
+++ b/3rdparty/Sabre/VObject/RecurrenceIterator.php
diff --git a/3rdparty/Sabre/VObject/Version.php b/3rdparty/Sabre/VObject/Version.php
index 00110febc07..2617c7b129d 100644..100755
--- a/3rdparty/Sabre/VObject/Version.php
+++ b/3rdparty/Sabre/VObject/Version.php
@@ -14,7 +14,7 @@ class Sabre_VObject_Version {
/**
* Full version number
*/
- const VERSION = '1.3.2';
+ const VERSION = '1.3.3';
/**
* Stability : alpha, beta, stable
diff --git a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
index 5e1cc5d479b..5e1cc5d479b 100644..100755
--- a/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
+++ b/3rdparty/Sabre/VObject/WindowsTimezoneMap.php
diff --git a/3rdparty/Sabre/VObject/includes.php b/3rdparty/Sabre/VObject/includes.php
index 0177a8f1ba6..0177a8f1ba6 100644..100755
--- a/3rdparty/Sabre/VObject/includes.php
+++ b/3rdparty/Sabre/VObject/includes.php
diff --git a/3rdparty/Sabre/autoload.php b/3rdparty/Sabre/autoload.php
index c7b537d83d3..c7b537d83d3 100644..100755
--- a/3rdparty/Sabre/autoload.php
+++ b/3rdparty/Sabre/autoload.php
diff --git a/3rdparty/Symfony/Component/Routing b/3rdparty/Symfony/Component/Routing
new file mode 160000
+Subproject d72483890880a987afa679503af096d2aaf7d2e
diff --git a/3rdparty/miniColors/GPL-LICENSE.txt b/3rdparty/miniColors/GPL-LICENSE.txt
new file mode 100644
index 00000000000..11dddd00ef0
--- /dev/null
+++ b/3rdparty/miniColors/GPL-LICENSE.txt
@@ -0,0 +1,278 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/3rdparty/miniColors/MIT-LICENSE.txt b/3rdparty/miniColors/MIT-LICENSE.txt
new file mode 100644
index 00000000000..ec6f7581576
--- /dev/null
+++ b/3rdparty/miniColors/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) Cory LaViska
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/3rdparty/miniColors/css/images/colors.png b/3rdparty/miniColors/css/images/colors.png
new file mode 100755
index 00000000000..1b4f819d8d9
--- /dev/null
+++ b/3rdparty/miniColors/css/images/colors.png
Binary files differ
diff --git a/3rdparty/miniColors/css/images/trigger.png b/3rdparty/miniColors/css/images/trigger.png
new file mode 100755
index 00000000000..8c169fd6053
--- /dev/null
+++ b/3rdparty/miniColors/css/images/trigger.png
Binary files differ
diff --git a/3rdparty/miniColors/css/jquery.miniColors.css b/3rdparty/miniColors/css/jquery.miniColors.css
new file mode 100755
index 00000000000..381bc1dc065
--- /dev/null
+++ b/3rdparty/miniColors/css/jquery.miniColors.css
@@ -0,0 +1,81 @@
+.miniColors-trigger {
+ height: 22px;
+ width: 22px;
+ background: url(images/trigger.png) center no-repeat;
+ vertical-align: middle;
+ margin: 0 .25em;
+ display: inline-block;
+ outline: none;
+}
+
+.miniColors-selector {
+ position: absolute;
+ width: 175px;
+ height: 150px;
+ background: #FFF;
+ border: solid 1px #BBB;
+ -moz-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
+ -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
+ box-shadow: 0 0 6px rgba(0, 0, 0, .25);
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 5px;
+ z-index: 999999;
+}
+
+.miniColors-selector.black {
+ background: #000;
+ border-color: #000;
+}
+
+.miniColors-colors {
+ position: absolute;
+ top: 5px;
+ left: 5px;
+ width: 150px;
+ height: 150px;
+ background: url(images/colors.png) right no-repeat;
+ cursor: crosshair;
+}
+
+.miniColors-hues {
+ position: absolute;
+ top: 5px;
+ left: 160px;
+ width: 20px;
+ height: 150px;
+ background: url(images/colors.png) left no-repeat;
+ cursor: crosshair;
+}
+
+.miniColors-colorPicker {
+ position: absolute;
+ width: 9px;
+ height: 9px;
+ border: 1px solid #fff;
+ -moz-border-radius: 11px;
+ -webkit-border-radius: 11px;
+ border-radius: 11px;
+}
+.miniColors-colorPicker-inner {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 7px;
+ height: 7px;
+ border: 1px solid #000;
+ -moz-border-radius: 9px;
+ -webkit-border-radius: 9px;
+ border-radius: 9px;
+}
+
+.miniColors-huePicker {
+ position: absolute;
+ left: -3px;
+ width: 24px;
+ height: 1px;
+ border: 1px solid #fff;
+ border-radius: 2px;
+ background: #000;
+} \ No newline at end of file
diff --git a/3rdparty/miniColors/js/jquery.miniColors.js b/3rdparty/miniColors/js/jquery.miniColors.js
new file mode 100755
index 00000000000..187db3fa84e
--- /dev/null
+++ b/3rdparty/miniColors/js/jquery.miniColors.js
@@ -0,0 +1,580 @@
+/*
+ * jQuery miniColors: A small color selector
+ *
+ * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
+ *
+ * Dual licensed under the MIT or GPL Version 2 licenses
+ *
+*/
+if(jQuery) (function($) {
+
+ $.extend($.fn, {
+
+ miniColors: function(o, data) {
+
+ var create = function(input, o, data) {
+ //
+ // Creates a new instance of the miniColors selector
+ //
+
+ // Determine initial color (defaults to white)
+ var color = expandHex(input.val());
+ if( !color ) color = 'ffffff';
+ var hsb = hex2hsb(color);
+
+ // Create trigger
+ var trigger = $('<a class="miniColors-trigger" style="background-color: #' + color + '" href="#"></a>');
+ trigger.insertAfter(input);
+
+ // Set input data and update attributes
+ input
+ .addClass('miniColors')
+ .data('original-maxlength', input.attr('maxlength') || null)
+ .data('original-autocomplete', input.attr('autocomplete') || null)
+ .data('letterCase', 'uppercase')
+ .data('trigger', trigger)
+ .data('hsb', hsb)
+ .data('change', o.change ? o.change : null)
+ .data('close', o.close ? o.close : null)
+ .data('open', o.open ? o.open : null)
+ .attr('maxlength', 7)
+ .attr('autocomplete', 'off')
+ .val('#' + convertCase(color, o.letterCase));
+
+ // Handle options
+ if( o.readonly ) input.prop('readonly', true);
+ if( o.disabled ) disable(input);
+
+ // Show selector when trigger is clicked
+ trigger.bind('click.miniColors', function(event) {
+ event.preventDefault();
+ if( input.val() === '' ) input.val('#');
+ show(input);
+
+ });
+
+ // Show selector when input receives focus
+ input.bind('focus.miniColors', function(event) {
+ if( input.val() === '' ) input.val('#');
+ show(input);
+ });
+
+ // Hide on blur
+ input.bind('blur.miniColors', function(event) {
+ var hex = expandHex( hsb2hex(input.data('hsb')) );
+ input.val( hex ? '#' + convertCase(hex, input.data('letterCase')) : '' );
+ });
+
+ // Hide when tabbing out of the input
+ input.bind('keydown.miniColors', function(event) {
+ if( event.keyCode === 9 ) hide(input);
+ });
+
+ // Update when color is typed in
+ input.bind('keyup.miniColors', function(event) {
+ setColorFromInput(input);
+ });
+
+ // Handle pasting
+ input.bind('paste.miniColors', function(event) {
+ // Short pause to wait for paste to complete
+ setTimeout( function() {
+ setColorFromInput(input);
+ }, 5);
+ });
+
+ };
+
+ var destroy = function(input) {
+ //
+ // Destroys an active instance of the miniColors selector
+ //
+
+ hide();
+ input = $(input);
+
+ // Restore to original state
+ input.data('trigger').remove();
+ input
+ .attr('autocomplete', input.data('original-autocomplete'))
+ .attr('maxlength', input.data('original-maxlength'))
+ .removeData()
+ .removeClass('miniColors')
+ .unbind('.miniColors');
+ $(document).unbind('.miniColors');
+ };
+
+ var enable = function(input) {
+ //
+ // Enables the input control and the selector
+ //
+ input
+ .prop('disabled', false)
+ .data('trigger')
+ .css('opacity', 1);
+ };
+
+ var disable = function(input) {
+ //
+ // Disables the input control and the selector
+ //
+ hide(input);
+ input
+ .prop('disabled', true)
+ .data('trigger')
+ .css('opacity', 0.5);
+ };
+
+ var show = function(input) {
+ //
+ // Shows the miniColors selector
+ //
+ if( input.prop('disabled') ) return false;
+
+ // Hide all other instances
+ hide();
+
+ // Generate the selector
+ var selector = $('<div class="miniColors-selector"></div>');
+ selector
+ .append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>')
+ .append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>')
+ .css({
+ top: input.is(':visible') ? input.offset().top + input.outerHeight() : input.data('trigger').offset().top + input.data('trigger').outerHeight(),
+ left: input.is(':visible') ? input.offset().left : input.data('trigger').offset().left,
+ display: 'none'
+ })
+ .addClass( input.attr('class') );
+
+ // Set background for colors
+ var hsb = input.data('hsb');
+ selector
+ .find('.miniColors-colors')
+ .css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
+
+ // Set colorPicker position
+ var colorPosition = input.data('colorPosition');
+ if( !colorPosition ) colorPosition = getColorPositionFromHSB(hsb);
+ selector.find('.miniColors-colorPicker')
+ .css('top', colorPosition.y + 'px')
+ .css('left', colorPosition.x + 'px');
+
+ // Set huePicker position
+ var huePosition = input.data('huePosition');
+ if( !huePosition ) huePosition = getHuePositionFromHSB(hsb);
+ selector.find('.miniColors-huePicker').css('top', huePosition.y + 'px');
+
+ // Set input data
+ input
+ .data('selector', selector)
+ .data('huePicker', selector.find('.miniColors-huePicker'))
+ .data('colorPicker', selector.find('.miniColors-colorPicker'))
+ .data('mousebutton', 0);
+
+ $('BODY').append(selector);
+ selector.fadeIn(100);
+
+ // Prevent text selection in IE
+ selector.bind('selectstart', function() { return false; });
+
+ $(document).bind('mousedown.miniColors touchstart.miniColors', function(event) {
+
+ input.data('mousebutton', 1);
+ var testSubject = $(event.target).parents().andSelf();
+
+ if( testSubject.hasClass('miniColors-colors') ) {
+ event.preventDefault();
+ input.data('moving', 'colors');
+ moveColor(input, event);
+ }
+
+ if( testSubject.hasClass('miniColors-hues') ) {
+ event.preventDefault();
+ input.data('moving', 'hues');
+ moveHue(input, event);
+ }
+
+ if( testSubject.hasClass('miniColors-selector') ) {
+ event.preventDefault();
+ return;
+ }
+
+ if( testSubject.hasClass('miniColors') ) return;
+
+ hide(input);
+ });
+
+ $(document)
+ .bind('mouseup.miniColors touchend.miniColors', function(event) {
+ event.preventDefault();
+ input.data('mousebutton', 0).removeData('moving');
+ })
+ .bind('mousemove.miniColors touchmove.miniColors', function(event) {
+ event.preventDefault();
+ if( input.data('mousebutton') === 1 ) {
+ if( input.data('moving') === 'colors' ) moveColor(input, event);
+ if( input.data('moving') === 'hues' ) moveHue(input, event);
+ }
+ });
+
+ // Fire open callback
+ if( input.data('open') ) {
+ input.data('open').call(input.get(0), '#' + hsb2hex(hsb), hsb2rgb(hsb));
+ }
+
+ };
+
+ var hide = function(input) {
+
+ //
+ // Hides one or more miniColors selectors
+ //
+
+ // Hide all other instances if input isn't specified
+ if( !input ) input = '.miniColors';
+
+ $(input).each( function() {
+ var selector = $(this).data('selector');
+ $(this).removeData('selector');
+ $(selector).fadeOut(100, function() {
+ // Fire close callback
+ if( input.data('close') ) {
+ var hsb = input.data('hsb'), hex = hsb2hex(hsb);
+ input.data('close').call(input.get(0), '#' + hex, hsb2rgb(hsb));
+ }
+ $(this).remove();
+ });
+ });
+
+ $(document).unbind('.miniColors');
+
+ };
+
+ var moveColor = function(input, event) {
+
+ var colorPicker = input.data('colorPicker');
+
+ colorPicker.hide();
+
+ var position = {
+ x: event.pageX,
+ y: event.pageY
+ };
+
+ // Touch support
+ if( event.originalEvent.changedTouches ) {
+ position.x = event.originalEvent.changedTouches[0].pageX;
+ position.y = event.originalEvent.changedTouches[0].pageY;
+ }
+ position.x = position.x - input.data('selector').find('.miniColors-colors').offset().left - 5;
+ position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 5;
+ if( position.x <= -5 ) position.x = -5;
+ if( position.x >= 144 ) position.x = 144;
+ if( position.y <= -5 ) position.y = -5;
+ if( position.y >= 144 ) position.y = 144;
+
+ input.data('colorPosition', position);
+ colorPicker.css('left', position.x).css('top', position.y).show();
+
+ // Calculate saturation
+ var s = Math.round((position.x + 5) * 0.67);
+ if( s < 0 ) s = 0;
+ if( s > 100 ) s = 100;
+
+ // Calculate brightness
+ var b = 100 - Math.round((position.y + 5) * 0.67);
+ if( b < 0 ) b = 0;
+ if( b > 100 ) b = 100;
+
+ // Update HSB values
+ var hsb = input.data('hsb');
+ hsb.s = s;
+ hsb.b = b;
+
+ // Set color
+ setColor(input, hsb, true);
+ };
+
+ var moveHue = function(input, event) {
+
+ var huePicker = input.data('huePicker');
+
+ huePicker.hide();
+
+ var position = {
+ y: event.pageY
+ };
+
+ // Touch support
+ if( event.originalEvent.changedTouches ) {
+ position.y = event.originalEvent.changedTouches[0].pageY;
+ }
+
+ position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 1;
+ if( position.y <= -1 ) position.y = -1;
+ if( position.y >= 149 ) position.y = 149;
+ input.data('huePosition', position);
+ huePicker.css('top', position.y).show();
+
+ // Calculate hue
+ var h = Math.round((150 - position.y - 1) * 2.4);
+ if( h < 0 ) h = 0;
+ if( h > 360 ) h = 360;
+
+ // Update HSB values
+ var hsb = input.data('hsb');
+ hsb.h = h;
+
+ // Set color
+ setColor(input, hsb, true);
+
+ };
+
+ var setColor = function(input, hsb, updateInput) {
+ input.data('hsb', hsb);
+ var hex = hsb2hex(hsb);
+ if( updateInput ) input.val( '#' + convertCase(hex, input.data('letterCase')) );
+ input.data('trigger').css('backgroundColor', '#' + hex);
+ if( input.data('selector') ) input.data('selector').find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
+
+ // Fire change callback
+ if( input.data('change') ) {
+ if( hex === input.data('lastChange') ) return;
+ input.data('change').call(input.get(0), '#' + hex, hsb2rgb(hsb));
+ input.data('lastChange', hex);
+ }
+
+ };
+
+ var setColorFromInput = function(input) {
+
+ input.val('#' + cleanHex(input.val()));
+ var hex = expandHex(input.val());
+ if( !hex ) return false;
+
+ // Get HSB equivalent
+ var hsb = hex2hsb(hex);
+
+ // If color is the same, no change required
+ var currentHSB = input.data('hsb');
+ if( hsb.h === currentHSB.h && hsb.s === currentHSB.s && hsb.b === currentHSB.b ) return true;
+
+ // Set colorPicker position
+ var colorPosition = getColorPositionFromHSB(hsb);
+ var colorPicker = $(input.data('colorPicker'));
+ colorPicker.css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px');
+ input.data('colorPosition', colorPosition);
+
+ // Set huePosition position
+ var huePosition = getHuePositionFromHSB(hsb);
+ var huePicker = $(input.data('huePicker'));
+ huePicker.css('top', huePosition.y + 'px');
+ input.data('huePosition', huePosition);
+
+ setColor(input, hsb);
+
+ return true;
+
+ };
+
+ var convertCase = function(string, letterCase) {
+ if( letterCase === 'lowercase' ) return string.toLowerCase();
+ if( letterCase === 'uppercase' ) return string.toUpperCase();
+ return string;
+ };
+
+ var getColorPositionFromHSB = function(hsb) {
+ var x = Math.ceil(hsb.s / 0.67);
+ if( x < 0 ) x = 0;
+ if( x > 150 ) x = 150;
+ var y = 150 - Math.ceil(hsb.b / 0.67);
+ if( y < 0 ) y = 0;
+ if( y > 150 ) y = 150;
+ return { x: x - 5, y: y - 5 };
+ };
+
+ var getHuePositionFromHSB = function(hsb) {
+ var y = 150 - (hsb.h / 2.4);
+ if( y < 0 ) h = 0;
+ if( y > 150 ) h = 150;
+ return { y: y - 1 };
+ };
+
+ var cleanHex = function(hex) {
+ return hex.replace(/[^A-F0-9]/ig, '');
+ };
+
+ var expandHex = function(hex) {
+ hex = cleanHex(hex);
+ if( !hex ) return null;
+ if( hex.length === 3 ) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
+ return hex.length === 6 ? hex : null;
+ };
+
+ var hsb2rgb = function(hsb) {
+ var rgb = {};
+ var h = Math.round(hsb.h);
+ var s = Math.round(hsb.s*255/100);
+ var v = Math.round(hsb.b*255/100);
+ if(s === 0) {
+ rgb.r = rgb.g = rgb.b = v;
+ } else {
+ var t1 = v;
+ var t2 = (255 - s) * v / 255;
+ var t3 = (t1 - t2) * (h % 60) / 60;
+ if( h === 360 ) h = 0;
+ if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
+ else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
+ else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
+ else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
+ else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
+ else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
+ else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
+ }
+ return {
+ r: Math.round(rgb.r),
+ g: Math.round(rgb.g),
+ b: Math.round(rgb.b)
+ };
+ };
+
+ var rgb2hex = function(rgb) {
+ var hex = [
+ rgb.r.toString(16),
+ rgb.g.toString(16),
+ rgb.b.toString(16)
+ ];
+ $.each(hex, function(nr, val) {
+ if (val.length === 1) hex[nr] = '0' + val;
+ });
+ return hex.join('');
+ };
+
+ var hex2rgb = function(hex) {
+ hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
+
+ return {
+ r: hex >> 16,
+ g: (hex & 0x00FF00) >> 8,
+ b: (hex & 0x0000FF)
+ };
+ };
+
+ var rgb2hsb = function(rgb) {
+ var hsb = { h: 0, s: 0, b: 0 };
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
+ var delta = max - min;
+ hsb.b = max;
+ hsb.s = max !== 0 ? 255 * delta / max : 0;
+ if( hsb.s !== 0 ) {
+ if( rgb.r === max ) {
+ hsb.h = (rgb.g - rgb.b) / delta;
+ } else if( rgb.g === max ) {
+ hsb.h = 2 + (rgb.b - rgb.r) / delta;
+ } else {
+ hsb.h = 4 + (rgb.r - rgb.g) / delta;
+ }
+ } else {
+ hsb.h = -1;
+ }
+ hsb.h *= 60;
+ if( hsb.h < 0 ) {
+ hsb.h += 360;
+ }
+ hsb.s *= 100/255;
+ hsb.b *= 100/255;
+ return hsb;
+ };
+
+ var hex2hsb = function(hex) {
+ var hsb = rgb2hsb(hex2rgb(hex));
+ // Zero out hue marker for black, white, and grays (saturation === 0)
+ if( hsb.s === 0 ) hsb.h = 360;
+ return hsb;
+ };
+
+ var hsb2hex = function(hsb) {
+ return rgb2hex(hsb2rgb(hsb));
+ };
+
+
+ // Handle calls to $([selector]).miniColors()
+ switch(o) {
+
+ case 'readonly':
+
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ $(this).prop('readonly', data);
+ });
+
+ return $(this);
+
+ case 'disabled':
+
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ if( data ) {
+ disable($(this));
+ } else {
+ enable($(this));
+ }
+ });
+
+ return $(this);
+
+ case 'value':
+
+ // Getter
+ if( data === undefined ) {
+ if( !$(this).hasClass('miniColors') ) return;
+ var input = $(this),
+ hex = expandHex(input.val());
+ return hex ? '#' + convertCase(hex, input.data('letterCase')) : null;
+ }
+
+ // Setter
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ $(this).val(data);
+ setColorFromInput($(this));
+ });
+
+ return $(this);
+
+ case 'destroy':
+
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ destroy($(this));
+ });
+
+ return $(this);
+
+ default:
+
+ if( !o ) o = {};
+
+ $(this).each( function() {
+
+ // Must be called on an input element
+ if( $(this)[0].tagName.toLowerCase() !== 'input' ) return;
+
+ // If a trigger is present, the control was already created
+ if( $(this).data('trigger') ) return;
+
+ // Create the control
+ create($(this), o, data);
+
+ });
+
+ return $(this);
+
+ }
+
+ }
+
+ });
+
+})(jQuery); \ No newline at end of file
diff --git a/3rdparty/miniColors/js/jquery.miniColors.min.js b/3rdparty/miniColors/js/jquery.miniColors.min.js
new file mode 100755
index 00000000000..c00e0ace6b5
--- /dev/null
+++ b/3rdparty/miniColors/js/jquery.miniColors.min.js
@@ -0,0 +1,9 @@
+/*
+ * jQuery miniColors: A small color selector
+ *
+ * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
+ *
+ * Dual licensed under the MIT or GPL Version 2 licenses
+ *
+*/
+if(jQuery)(function($){$.extend($.fn,{miniColors:function(o,data){var create=function(input,o,data){var color=expandHex(input.val());if(!color)color='ffffff';var hsb=hex2hsb(color);var trigger=$('<a class="miniColors-trigger" style="background-color: #'+color+'" href="#"></a>');trigger.insertAfter(input);input.addClass('miniColors').data('original-maxlength',input.attr('maxlength')||null).data('original-autocomplete',input.attr('autocomplete')||null).data('letterCase','uppercase').data('trigger',trigger).data('hsb',hsb).data('change',o.change?o.change:null).data('close',o.close?o.close:null).data('open',o.open?o.open:null).attr('maxlength',7).attr('autocomplete','off').val('#'+convertCase(color,o.letterCase));if(o.readonly)input.prop('readonly',true);if(o.disabled)disable(input);trigger.bind('click.miniColors',function(event){event.preventDefault();if(input.val()==='')input.val('#');show(input)});input.bind('focus.miniColors',function(event){if(input.val()==='')input.val('#');show(input)});input.bind('blur.miniColors',function(event){var hex=expandHex(hsb2hex(input.data('hsb')));input.val(hex?'#'+convertCase(hex,input.data('letterCase')):'')});input.bind('keydown.miniColors',function(event){if(event.keyCode===9)hide(input)});input.bind('keyup.miniColors',function(event){setColorFromInput(input)});input.bind('paste.miniColors',function(event){setTimeout(function(){setColorFromInput(input)},5)})};var destroy=function(input){hide();input=$(input);input.data('trigger').remove();input.attr('autocomplete',input.data('original-autocomplete')).attr('maxlength',input.data('original-maxlength')).removeData().removeClass('miniColors').unbind('.miniColors');$(document).unbind('.miniColors')};var enable=function(input){input.prop('disabled',false).data('trigger').css('opacity',1)};var disable=function(input){hide(input);input.prop('disabled',true).data('trigger').css('opacity',0.5)};var show=function(input){if(input.prop('disabled'))return false;hide();var selector=$('<div class="miniColors-selector"></div>');selector.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>').append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>').css({top:input.is(':visible')?input.offset().top+input.outerHeight():input.data('trigger').offset().top+input.data('trigger').outerHeight(),left:input.is(':visible')?input.offset().left:input.data('trigger').offset().left,display:'none'}).addClass(input.attr('class'));var hsb=input.data('hsb');selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));var colorPosition=input.data('colorPosition');if(!colorPosition)colorPosition=getColorPositionFromHSB(hsb);selector.find('.miniColors-colorPicker').css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');var huePosition=input.data('huePosition');if(!huePosition)huePosition=getHuePositionFromHSB(hsb);selector.find('.miniColors-huePicker').css('top',huePosition.y+'px');input.data('selector',selector).data('huePicker',selector.find('.miniColors-huePicker')).data('colorPicker',selector.find('.miniColors-colorPicker')).data('mousebutton',0);$('BODY').append(selector);selector.fadeIn(100);selector.bind('selectstart',function(){return false});$(document).bind('mousedown.miniColors touchstart.miniColors',function(event){input.data('mousebutton',1);var testSubject=$(event.target).parents().andSelf();if(testSubject.hasClass('miniColors-colors')){event.preventDefault();input.data('moving','colors');moveColor(input,event)}if(testSubject.hasClass('miniColors-hues')){event.preventDefault();input.data('moving','hues');moveHue(input,event)}if(testSubject.hasClass('miniColors-selector')){event.preventDefault();return}if(testSubject.hasClass('miniColors'))return;hide(input)});$(document).bind('mouseup.miniColors touchend.miniColors',function(event){event.preventDefault();input.data('mousebutton',0).removeData('moving')}).bind('mousemove.miniColors touchmove.miniColors',function(event){event.preventDefault();if(input.data('mousebutton')===1){if(input.data('moving')==='colors')moveColor(input,event);if(input.data('moving')==='hues')moveHue(input,event)}});if(input.data('open')){input.data('open').call(input.get(0),'#'+hsb2hex(hsb),hsb2rgb(hsb))}};var hide=function(input){if(!input)input='.miniColors';$(input).each(function(){var selector=$(this).data('selector');$(this).removeData('selector');$(selector).fadeOut(100,function(){if(input.data('close')){var hsb=input.data('hsb'),hex=hsb2hex(hsb);input.data('close').call(input.get(0),'#'+hex,hsb2rgb(hsb))}$(this).remove()})});$(document).unbind('.miniColors')};var moveColor=function(input,event){var colorPicker=input.data('colorPicker');colorPicker.hide();var position={x:event.pageX,y:event.pageY};if(event.originalEvent.changedTouches){position.x=event.originalEvent.changedTouches[0].pageX;position.y=event.originalEvent.changedTouches[0].pageY}position.x=position.x-input.data('selector').find('.miniColors-colors').offset().left-5;position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-5;if(position.x<=-5)position.x=-5;if(position.x>=144)position.x=144;if(position.y<=-5)position.y=-5;if(position.y>=144)position.y=144;input.data('colorPosition',position);colorPicker.css('left',position.x).css('top',position.y).show();var s=Math.round((position.x+5)*0.67);if(s<0)s=0;if(s>100)s=100;var b=100-Math.round((position.y+5)*0.67);if(b<0)b=0;if(b>100)b=100;var hsb=input.data('hsb');hsb.s=s;hsb.b=b;setColor(input,hsb,true)};var moveHue=function(input,event){var huePicker=input.data('huePicker');huePicker.hide();var position={y:event.pageY};if(event.originalEvent.changedTouches){position.y=event.originalEvent.changedTouches[0].pageY}position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-1;if(position.y<=-1)position.y=-1;if(position.y>=149)position.y=149;input.data('huePosition',position);huePicker.css('top',position.y).show();var h=Math.round((150-position.y-1)*2.4);if(h<0)h=0;if(h>360)h=360;var hsb=input.data('hsb');hsb.h=h;setColor(input,hsb,true)};var setColor=function(input,hsb,updateInput){input.data('hsb',hsb);var hex=hsb2hex(hsb);if(updateInput)input.val('#'+convertCase(hex,input.data('letterCase')));input.data('trigger').css('backgroundColor','#'+hex);if(input.data('selector'))input.data('selector').find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));if(input.data('change')){if(hex===input.data('lastChange'))return;input.data('change').call(input.get(0),'#'+hex,hsb2rgb(hsb));input.data('lastChange',hex)}};var setColorFromInput=function(input){input.val('#'+cleanHex(input.val()));var hex=expandHex(input.val());if(!hex)return false;var hsb=hex2hsb(hex);var currentHSB=input.data('hsb');if(hsb.h===currentHSB.h&&hsb.s===currentHSB.s&&hsb.b===currentHSB.b)return true;var colorPosition=getColorPositionFromHSB(hsb);var colorPicker=$(input.data('colorPicker'));colorPicker.css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');input.data('colorPosition',colorPosition);var huePosition=getHuePositionFromHSB(hsb);var huePicker=$(input.data('huePicker'));huePicker.css('top',huePosition.y+'px');input.data('huePosition',huePosition);setColor(input,hsb);return true};var convertCase=function(string,letterCase){if(letterCase==='lowercase')return string.toLowerCase();if(letterCase==='uppercase')return string.toUpperCase();return string};var getColorPositionFromHSB=function(hsb){var x=Math.ceil(hsb.s/0.67);if(x<0)x=0;if(x>150)x=150;var y=150-Math.ceil(hsb.b/0.67);if(y<0)y=0;if(y>150)y=150;return{x:x-5,y:y-5}};var getHuePositionFromHSB=function(hsb){var y=150-(hsb.h/2.4);if(y<0)h=0;if(y>150)h=150;return{y:y-1}};var cleanHex=function(hex){return hex.replace(/[^A-F0-9]/ig,'')};var expandHex=function(hex){hex=cleanHex(hex);if(!hex)return null;if(hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];return hex.length===6?hex:null};var hsb2rgb=function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s===0){rgb.r=rgb.g=rgb.b=v}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h===360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3}else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3}else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3}else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3}else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3}else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3}else{rgb.r=0;rgb.g=0;rgb.b=0}}return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)}};var rgb2hex=function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length===1)hex[nr]='0'+val});return hex.join('')};var hex2rgb=function(hex){hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)}};var rgb2hsb=function(rgb){var hsb={h:0,s:0,b:0};var min=Math.min(rgb.r,rgb.g,rgb.b);var max=Math.max(rgb.r,rgb.g,rgb.b);var delta=max-min;hsb.b=max;hsb.s=max!==0?255*delta/max:0;if(hsb.s!==0){if(rgb.r===max){hsb.h=(rgb.g-rgb.b)/delta}else if(rgb.g===max){hsb.h=2+(rgb.b-rgb.r)/delta}else{hsb.h=4+(rgb.r-rgb.g)/delta}}else{hsb.h=-1}hsb.h*=60;if(hsb.h<0){hsb.h+=360}hsb.s*=100/255;hsb.b*=100/255;return hsb};var hex2hsb=function(hex){var hsb=rgb2hsb(hex2rgb(hex));if(hsb.s===0)hsb.h=360;return hsb};var hsb2hex=function(hsb){return rgb2hex(hsb2rgb(hsb))};switch(o){case'readonly':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).prop('readonly',data)});return $(this);case'disabled':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data){disable($(this))}else{enable($(this))}});return $(this);case'value':if(data===undefined){if(!$(this).hasClass('miniColors'))return;var input=$(this),hex=expandHex(input.val());return hex?'#'+convertCase(hex,input.data('letterCase')):null}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).val(data);setColorFromInput($(this))});return $(this);case'destroy':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;destroy($(this))});return $(this);default:if(!o)o={};$(this).each(function(){if($(this)[0].tagName.toLowerCase()!=='input')return;if($(this).data('trigger'))return;create($(this),o,data)});return $(this)}}})})(jQuery); \ No newline at end of file
diff --git a/apps/user_openid/class.openid.v3.php b/3rdparty/openid/class.openid.v3.php
index eeb31986659..eeb31986659 100644
--- a/apps/user_openid/class.openid.v3.php
+++ b/3rdparty/openid/class.openid.v3.php
diff --git a/apps/user_openid/phpmyid.php b/3rdparty/openid/phpmyid.php
index 5aaab642856..13fd31c47ca 100644
--- a/apps/user_openid/phpmyid.php
+++ b/3rdparty/openid/phpmyid.php
@@ -1705,4 +1705,3 @@ $run_mode = (isset($_REQUEST['openid_mode'])
debug("Run mode: $run_mode at: " . time());
debug($_REQUEST, 'Request params');
call_user_func($run_mode . '_mode');
-?>
diff --git a/apps/bookmarks/ajax/addBookmark.php b/apps/bookmarks/ajax/addBookmark.php
index 6b5a0f71d4e..483716405a1 100644
--- a/apps/bookmarks/ajax/addBookmark.php
+++ b/apps/bookmarks/ajax/addBookmark.php
@@ -28,6 +28,8 @@ $RUNTIME_NOSETUPFS=true;
// Check if we are a user
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
+
OCP\JSON::checkAppEnabled('bookmarks');
require_once(OC_App::getAppPath('bookmarks').'/bookmarksHelper.php');
diff --git a/apps/bookmarks/ajax/delBookmark.php b/apps/bookmarks/ajax/delBookmark.php
index 5a067701c9f..f40f02ebab7 100644
--- a/apps/bookmarks/ajax/delBookmark.php
+++ b/apps/bookmarks/ajax/delBookmark.php
@@ -28,6 +28,8 @@ $RUNTIME_NOSETUPFS=true;
// Check if we are a user
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
+
OCP\JSON::checkAppEnabled('bookmarks');
$id = $_POST['id'];
diff --git a/apps/bookmarks/ajax/editBookmark.php b/apps/bookmarks/ajax/editBookmark.php
index 439b680dc20..0b37d161af1 100644
--- a/apps/bookmarks/ajax/editBookmark.php
+++ b/apps/bookmarks/ajax/editBookmark.php
@@ -28,6 +28,8 @@ $RUNTIME_NOSETUPFS=true;
// Check if we are a user
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
+
OCP\JSON::checkAppEnabled('bookmarks');
$CONFIG_DBTYPE = OCP\Config::getSystemValue( "dbtype", "sqlite" );
diff --git a/apps/bookmarks/lib/bookmarks.php b/apps/bookmarks/lib/bookmarks.php
index e0005968f31..86fba45a50c 100644
--- a/apps/bookmarks/lib/bookmarks.php
+++ b/apps/bookmarks/lib/bookmarks.php
@@ -145,5 +145,4 @@ class OC_Bookmarks_Bookmarks{
$result = $query->execute();
return true;
}
-}
-?>
+} \ No newline at end of file
diff --git a/apps/calendar/ajax/calendar/activation.php b/apps/calendar/ajax/calendar/activation.php
index e31908beb14..f4aadc5b017 100644
--- a/apps/calendar/ajax/calendar/activation.php
+++ b/apps/calendar/ajax/calendar/activation.php
@@ -9,6 +9,8 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
+
$calendarid = $_POST['calendarid'];
$calendar = OC_Calendar_App::getCalendar($calendarid, true);
if(!$calendar){
diff --git a/apps/calendar/ajax/calendar/delete.php b/apps/calendar/ajax/calendar/delete.php
index 4d6706f6002..089255cae39 100644
--- a/apps/calendar/ajax/calendar/delete.php
+++ b/apps/calendar/ajax/calendar/delete.php
@@ -9,6 +9,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
$cal = $_POST["calendarid"];
$calendar = OC_Calendar_App::getCalendar($cal, true);
diff --git a/apps/calendar/ajax/calendar/new.php b/apps/calendar/ajax/calendar/new.php
index e77d4ebff03..67d12822378 100644
--- a/apps/calendar/ajax/calendar/new.php
+++ b/apps/calendar/ajax/calendar/new.php
@@ -6,11 +6,10 @@
* See the COPYING-README file.
*/
-
-
// Check if we are a user
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
if(trim($_POST['name']) == ''){
OCP\JSON::error(array('message'=>'empty'));
diff --git a/apps/calendar/ajax/calendar/update.php b/apps/calendar/ajax/calendar/update.php
index a2c898c8075..c09b1008c9c 100644
--- a/apps/calendar/ajax/calendar/update.php
+++ b/apps/calendar/ajax/calendar/update.php
@@ -11,6 +11,7 @@
// Check if we are a user
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
if(trim($_POST['name']) == ''){
OCP\JSON::error(array('message'=>'empty'));
diff --git a/apps/calendar/ajax/categories/rescan.php b/apps/calendar/ajax/categories/rescan.php
index f0060cb23b2..08c32865b6f 100644
--- a/apps/calendar/ajax/categories/rescan.php
+++ b/apps/calendar/ajax/categories/rescan.php
@@ -9,6 +9,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
foreach ($_POST as $key=>$element) {
debug('_POST: '.$key.'=>'.print_r($element, true));
diff --git a/apps/calendar/ajax/event/delete.php b/apps/calendar/ajax/event/delete.php
index f183d431afa..17e45c001e8 100644
--- a/apps/calendar/ajax/event/delete.php
+++ b/apps/calendar/ajax/event/delete.php
@@ -9,6 +9,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
$id = $_POST['id'];
$access = OC_Calendar_App::getaccess($id, OC_Calendar_App::EVENT);
diff --git a/apps/calendar/ajax/event/edit.php b/apps/calendar/ajax/event/edit.php
index 1c3babc3d90..db78bf6e5e0 100644
--- a/apps/calendar/ajax/event/edit.php
+++ b/apps/calendar/ajax/event/edit.php
@@ -9,6 +9,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
$id = $_POST['id'];
diff --git a/apps/calendar/ajax/event/move.php b/apps/calendar/ajax/event/move.php
index 04cf2fb0513..f4e2b36376d 100644
--- a/apps/calendar/ajax/event/move.php
+++ b/apps/calendar/ajax/event/move.php
@@ -7,6 +7,7 @@
*/
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
$id = $_POST['id'];
$access = OC_Calendar_App::getaccess($id, OC_Calendar_App::EVENT);
diff --git a/apps/calendar/ajax/event/new.form.php b/apps/calendar/ajax/event/new.form.php
index 0b19e7e92f9..db04cdf2d49 100644
--- a/apps/calendar/ajax/event/new.form.php
+++ b/apps/calendar/ajax/event/new.form.php
@@ -27,7 +27,7 @@ if (!$end){
}
$start = new DateTime('@'.$start);
$end = new DateTime('@'.$end);
-$timezone = OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+$timezone = OC_Calendar_App::getTimezone();
$start->setTimezone(new DateTimeZone($timezone));
$end->setTimezone(new DateTimeZone($timezone));
diff --git a/apps/calendar/ajax/event/new.php b/apps/calendar/ajax/event/new.php
index 30e2b0cae36..bc0439cc315 100644
--- a/apps/calendar/ajax/event/new.php
+++ b/apps/calendar/ajax/event/new.php
@@ -10,6 +10,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
$errarr = OC_Calendar_Object::validateRequest($_POST);
if($errarr){
diff --git a/apps/calendar/ajax/event/resize.php b/apps/calendar/ajax/event/resize.php
index 56b83205e85..15b687b55da 100644
--- a/apps/calendar/ajax/event/resize.php
+++ b/apps/calendar/ajax/event/resize.php
@@ -7,6 +7,7 @@
*/
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
$id = $_POST['id'];
diff --git a/apps/calendar/ajax/import/calendarcheck.php b/apps/calendar/ajax/import/calendarcheck.php
new file mode 100644
index 00000000000..a91bab70573
--- /dev/null
+++ b/apps/calendar/ajax/import/calendarcheck.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+OCP\JSON::checkLoggedIn();
+OCP\App::checkAppEnabled('calendar');
+$calname = strip_tags($_POST['calname']);
+$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser());
+foreach($calendars as $calendar){
+ if($calendar['displayname'] == $calname){
+ OCP\JSON::success(array('message'=>'exists'));
+ exit;
+ }
+}
+OCP\JSON::error(); \ No newline at end of file
diff --git a/apps/calendar/ajax/import/dialog.php b/apps/calendar/ajax/import/dialog.php
index b99c32278c4..18fe226172c 100644
--- a/apps/calendar/ajax/import/dialog.php
+++ b/apps/calendar/ajax/import/dialog.php
@@ -5,8 +5,6 @@
* later.
* See the COPYING-README file.
*/
-
-
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
$tmpl = new OCP\Template('calendar', 'part.import');
diff --git a/apps/calendar/ajax/import/dropimport.php b/apps/calendar/ajax/import/dropimport.php
index 87667d4de68..f46e7314098 100644
--- a/apps/calendar/ajax/import/dropimport.php
+++ b/apps/calendar/ajax/import/dropimport.php
@@ -1,73 +1,32 @@
<?php
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
$data = $_POST['data'];
$data = explode(',', $data);
$data = end($data);
$data = base64_decode($data);
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
-$nl="\r\n";
-$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
-$data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
-$lines = explode("\n", $data);
-unset($data);
-$comp=$uid=$cal=false;
-$cals=$uids=array();
-$i = 0;
-foreach($lines as $line) {
- if(strpos($line, ':')!==false) {
- list($attr, $val) = explode(':', strtoupper($line));
- if ($attr == 'BEGIN' && $val == 'VCALENDAR') {
- $cal = $i;
- $cals[$cal] = array('first'=>$i,'last'=>$i,'end'=>$i);
- } elseif ($attr =='BEGIN' && $cal!==false && isset($comps[$val])) {
- $comp = $val;
- $beginNo = $i;
- } elseif ($attr == 'END' && $cal!==false && $val == 'VCALENDAR') {
- if($comp!==false) {
- unset($cals[$cal]); // corrupt calendar, unset it
- } else {
- $cals[$cal]['end'] = $i;
- }
- $comp=$uid=$cal=false; // reset calendar
- } elseif ($attr == 'END' && $comp!==false && $val == $comp) {
- if(! $uid) {
- $uid = OC_Calendar_Object::createUID();
- }
- $uids[$uid][$beginNo] = array('end'=>$i, 'cal'=>$cal);
- if ($cals[$cal]['first'] == $cal) {
- $cals[$cal]['first'] = $beginNo;
- }
- $cals[$cal]['last'] = $i;
- $comp=$uid=false; // reset component
- } elseif ($attr =="UID" && $comp!==false) {
- list($attr, $uid) = explode(':', $line);
- }
- }
- $i++;
+$import = new OC_Calendar_Import($data);
+$import->setUserID(OCP\User::getUser());
+$import->setTimeZone(OC_Calendar_App::$tz);
+$import->disableProgressCache();
+if(!$import->isValid()){
+ OCP\JSON::error();
+ exit;
}
-$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), true);
-$id = $calendars[0]['id'];
-foreach($uids as $uid) {
- $prefix=$suffix=$content=array();
- foreach($uid as $begin=>$details) {
- $cal = $details['cal'];
- if(!isset($cals[$cal])) {
- continue; // from corrupt/incomplete calendar
- }
- $cdata = $cals[$cal];
- // if we have multiple components from different calendar objects,
- // we should really merge their elements (enhancement?) -- 1st one wins for now.
- if(! count($prefix)) {
- $prefix = array_slice($lines, $cal, $cdata['first'] - $cal);
- }
- if(! count($suffix)) {
- $suffix = array_slice($lines, $cdata['last']+1, $cdata['end'] - $cdata['last']);
- }
- $content = array_merge($content, array_slice($lines, $begin, $details['end'] - $begin + 1));
- }
- if(count($content)) {
- $import = join($nl, array_merge($prefix, $content, $suffix)) . $nl;
- OC_Calendar_Object::add($id, $import);
- }
-}
-OCP\JSON::success(); \ No newline at end of file
+$newcalendarname = strip_tags($import->createCalendarName());
+$newid = OC_Calendar_Calendar::addCalendar(OCP\User::getUser(),$newcalendarname,'VEVENT,VTODO,VJOURNAL',null,0,$import->createCalendarColor());
+$import->setCalendarID($newid);
+$import->import();
+$count = $import->getCount();
+if($count == 0){
+ OC_Calendar_Calendar::deleteCalendar($newid);
+ OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('The file contained either no events or all events are already saved in your calendar.')));
+}else{
+ OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in the new calendar') . ' ' . $newcalendarname, 'eventSource'=>OC_Calendar_Calendar::getEventSourceInfo(OC_Calendar_Calendar::find($newid))));
+} \ No newline at end of file
diff --git a/apps/calendar/ajax/import/import.php b/apps/calendar/ajax/import/import.php
index 1facedfe0da..b1dfc464d00 100644
--- a/apps/calendar/ajax/import/import.php
+++ b/apps/calendar/ajax/import/import.php
@@ -5,41 +5,71 @@
* later.
* See the COPYING-README file.
*/
-//check for calendar rights or create new one
-ob_start();
-
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
session_write_close();
-
-$nl="\r\n";
-$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
-
-global $progresskey;
-$progresskey = 'calendar.import-' . $_POST['progresskey'];
-
-if (isset($_POST['progress']) && $_POST['progress']) {
- echo OC_Cache::get($progresskey);
- die;
+if (isset($_POST['progresskey']) && isset($_POST['getprogress'])) {
+ echo OCP\JSON::success(array('percent'=>OC_Cache::get($_POST['progresskey'])));
+ exit;
}
-
-function writeProgress($pct) {
- global $progresskey;
- OC_Cache::set($progresskey, $pct, 300);
-}
-writeProgress('10');
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
+if(!$file){
+ OCP\JSON::error(array('error'=>'404'));
+}
+$import = new OC_Calendar_Import($file);
+$import->setUserID(OCP\User::getUser());
+$import->setTimeZone(OC_Calendar_App::$tz);
+$import->enableProgressCache();
+$import->setProgresskey($_POST['progresskey']);
+if(!$import->isValid()){
+ OCP\JSON::error(array('error'=>'notvalid'));
+ exit;
+}
+$newcal = false;
if($_POST['method'] == 'new'){
- $id = OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(), $_POST['calname']);
- OC_Calendar_Calendar::setCalendarActive($id, 1);
+ $calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser());
+ foreach($calendars as $calendar){
+ if($calendar['displayname'] == $_POST['calname']){
+ $id = $calendar['id'];
+ $newcal = false;
+ break;
+ }
+ $newcal = true;
+ }
+ if($newcal){
+ $id = OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(), strip_tags($_POST['calname']),'VEVENT,VTODO,VJOURNAL',null,0,strip_tags($_POST['calcolor']));
+ OC_Calendar_Calendar::setCalendarActive($id, 1);
+ }
}else{
$calendar = OC_Calendar_App::getCalendar($_POST['id']);
if($calendar['userid'] != OCP\USER::getUser()){
- OCP\JSON::error();
+ OCP\JSON::error(array('error'=>'missingcalendarrights'));
exit();
}
$id = $_POST['id'];
}
+$import->setCalendarID($id);
+try{
+ $import->import();
+}catch (Exception $e) {
+ OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('Import failed'), 'debug'=>$e->getMessage()));
+ //write some log
+}
+$count = $import->getCount();
+if($count == 0){
+ if($newcal){
+ OC_Calendar_Calendar::deleteCalendar($id);
+ }
+ OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('The file contained either no events or all events are already saved in your calendar.')));
+}else{
+ if($newcal){
+ OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in the new calendar') . ' ' . strip_tags($_POST['calname'])));
+ }else{
+ OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in your calendar')));
+ }
+}
+/* //////////////////////////// Attention: following code is quite painfull !!! ///////////////////////
writeProgress('20');
// normalize the newlines
$file = str_replace(array("\r","\n\n"), array("\n","\n"), $file);
@@ -91,7 +121,6 @@ foreach($lines as $line) {
// import the calendar
writeProgress('60');
foreach($uids as $uid) {
-
$prefix=$suffix=$content=array();
foreach($uid as $begin=>$details) {
@@ -119,4 +148,4 @@ foreach($uids as $uid) {
writeProgress('100');
sleep(3);
OC_Cache::remove($progresskey);
-OCP\JSON::success(); \ No newline at end of file
+OCP\JSON::success();*/
diff --git a/apps/calendar/ajax/settings/setfirstday.php b/apps/calendar/ajax/settings/setfirstday.php
index 056a6037524..73cf0c19b78 100644
--- a/apps/calendar/ajax/settings/setfirstday.php
+++ b/apps/calendar/ajax/settings/setfirstday.php
@@ -7,6 +7,7 @@
*/
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
if(isset($_POST["firstday"])){
OCP\Config::setUserValue(OCP\USER::getUser(), 'calendar', 'firstday', $_POST["firstday"]);
OCP\JSON::success();
diff --git a/apps/calendar/ajax/settings/settimeformat.php b/apps/calendar/ajax/settings/settimeformat.php
index 8e95f6f3bf5..6136857e2fe 100644
--- a/apps/calendar/ajax/settings/settimeformat.php
+++ b/apps/calendar/ajax/settings/settimeformat.php
@@ -7,6 +7,7 @@
*/
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
if(isset($_POST["timeformat"])){
OCP\Config::setUserValue(OCP\USER::getUser(), 'calendar', 'timeformat', $_POST["timeformat"]);
OCP\JSON::success();
diff --git a/apps/calendar/ajax/settings/settimezone.php b/apps/calendar/ajax/settings/settimezone.php
index 6d029a6643a..06db66d578e 100644
--- a/apps/calendar/ajax/settings/settimezone.php
+++ b/apps/calendar/ajax/settings/settimezone.php
@@ -14,6 +14,7 @@ $l=OC_L10N::get('calendar');
// Check if we are a user
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('calendar');
+OCP\JSON::callCheck();
// Get data
if( isset( $_POST['timezone'] ) ){
diff --git a/apps/calendar/ajax/share/changepermission.php b/apps/calendar/ajax/share/changepermission.php
index e807c164a23..5aff7666f79 100644
--- a/apps/calendar/ajax/share/changepermission.php
+++ b/apps/calendar/ajax/share/changepermission.php
@@ -5,7 +5,9 @@
* later.
* See the COPYING-README file.
*/
-
+
+OCP\JSON::callCheck();
+
$id = strip_tags($_POST['id']);
$idtype = strip_tags($_POST['idtype']);
$permission = (int) strip_tags($_POST['permission']);
diff --git a/apps/calendar/ajax/share/share.php b/apps/calendar/ajax/share/share.php
index 838db619f62..77e1ab9d657 100644
--- a/apps/calendar/ajax/share/share.php
+++ b/apps/calendar/ajax/share/share.php
@@ -6,6 +6,8 @@
* See the COPYING-README file.
*/
+OCP\JSON::callCheck();
+
$id = strip_tags($_POST['id']);
$idtype = strip_tags($_POST['idtype']);
switch($idtype){
diff --git a/apps/calendar/ajax/share/unshare.php b/apps/calendar/ajax/share/unshare.php
index 1ce04677fb1..c7c06113189 100644
--- a/apps/calendar/ajax/share/unshare.php
+++ b/apps/calendar/ajax/share/unshare.php
@@ -5,7 +5,9 @@
* later.
* See the COPYING-README file.
*/
-
+
+OCP\JSON::callCheck();
+
$id = strip_tags($_POST['id']);
$idtype = strip_tags($_POST['idtype']);
switch($idtype){
diff --git a/apps/calendar/appinfo/app.php b/apps/calendar/appinfo/app.php
index 3c8cc76133e..4fdba291262 100644
--- a/apps/calendar/appinfo/app.php
+++ b/apps/calendar/appinfo/app.php
@@ -9,7 +9,9 @@ OC::$CLASSPATH['OC_Calendar_Repeat'] = 'apps/calendar/lib/repeat.php';
OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php';
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
OC::$CLASSPATH['OC_Calendar_Export'] = 'apps/calendar/lib/export.php';
+OC::$CLASSPATH['OC_Calendar_Import'] = 'apps/calendar/lib/import.php';
//General Hooks
+OCP\Util::connectHook('OC_User', 'post_createUser', 'OC_Calendar_Hooks', 'createUser');
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
//Repeating Events Hooks
OCP\Util::connectHook('OC_Calendar', 'addEvent', 'OC_Calendar_Repeat', 'generate');
@@ -23,6 +25,8 @@ OCP\Util::connectHook('OC_Calendar', 'deleteCalendar', 'OC_Calendar_Share', 'pos
OCP\Util::addscript('calendar','loader');
OCP\Util::addscript("3rdparty", "chosen/chosen.jquery.min");
OCP\Util::addStyle("3rdparty", "chosen/chosen");
+OCP\Util::addStyle('3rdparty/miniColors', 'jquery.miniColors');
+OCP\Util::addscript('3rdparty/miniColors', 'jquery.miniColors.min');
OCP\App::addNavigationEntry( array(
'id' => 'calendar_index',
'order' => 10,
diff --git a/apps/calendar/appinfo/remote.php b/apps/calendar/appinfo/remote.php
index 7ab546245f6..e8f9e80c7a8 100644
--- a/apps/calendar/appinfo/remote.php
+++ b/apps/calendar/appinfo/remote.php
@@ -34,6 +34,6 @@ $server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'));
$server->addPlugin(new Sabre_CalDAV_Plugin());
$server->addPlugin(new Sabre_DAVACL_Plugin());
$server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload
-
+$server->addPlugin(new Sabre_CalDAV_ICSExportPlugin());
// And off we go!
$server->exec();
diff --git a/apps/calendar/appinfo/version b/apps/calendar/appinfo/version
index 2eb3c4fe4ee..cb0c939a936 100644
--- a/apps/calendar/appinfo/version
+++ b/apps/calendar/appinfo/version
@@ -1 +1 @@
-0.5
+0.5.2
diff --git a/apps/calendar/css/import.css b/apps/calendar/css/import.css
new file mode 100644
index 00000000000..8abdc3aecd1
--- /dev/null
+++ b/apps/calendar/css/import.css
@@ -0,0 +1,14 @@
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+#calendar_import_newcalform, #calendar_import_mergewarning, #calendar_import_process, #calendar_import_done{display:none;}
+#calendar_import_process_message, #calendar_import_status, #calendar_import_form_message, #calendar_import_mergewarning{text-align:center;}
+#calendar_import_form_message{font-weight: bold;}
+#calendar_import_newcalendar{width:415px;float:right;}
+#calendar_import_mergewarning{clear: both;}
+#calendar_import_defaultcolors{clear:both;margin: 0 auto;text-align: center;}
+.calendar_import_warning{border-color: #fc3333;}
+.calendar-colorpicker-color{display:inline-block;width:20px;height:5px;margin: 0 auto;cursor:pointer;border:2px solid transparent;} \ No newline at end of file
diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js
index 004b2386fb1..25311fa0df4 100644
--- a/apps/calendar/js/calendar.js
+++ b/apps/calendar/js/calendar.js
@@ -622,18 +622,11 @@ Calendar={
drop:function(e){
var files = e.dataTransfer.files;
for(var i = 0;i < files.length;i++){
- var file = files[i]
+ var file = files[i];
reader = new FileReader();
reader.onload = function(event){
- if(file.type != 'text/calendar'){
- $('#notification').html('At least one file don\'t seems to be a calendar file. File skipped.');
- $('#notification').slideDown();
- window.setTimeout(function(){$('#notification').slideUp();}, 5000);
- return false;
- }else{
- Calendar.UI.Drop.import(event.target.result);
- $('#calendar_holder').fullCalendar('refetchEvents');
- }
+ Calendar.UI.Drop.import(event.target.result);
+ $('#calendar_holder').fullCalendar('refetchEvents');
}
reader.readAsDataURL(file);
}
@@ -641,9 +634,13 @@ Calendar={
import:function(data){
$.post(OC.filePath('calendar', 'ajax/import', 'dropimport.php'), {'data':data},function(result) {
if(result.status == 'success'){
+ $('#calendar_holder').fullCalendar('addEventSource', result.eventSource);
+ $('#notification').html(result.message);
+ $('#notification').slideDown();
+ window.setTimeout(function(){$('#notification').slideUp();}, 5000);
return true;
}else{
- $('#notification').html('ownCloud wasn\'t able to import at least one file. File skipped.');
+ $('#notification').html(result.message);
$('#notification').slideDown();
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
}
diff --git a/apps/calendar/js/loader.js b/apps/calendar/js/loader.js
index cef95afc3aa..b28d19ab00e 100644
--- a/apps/calendar/js/loader.js
+++ b/apps/calendar/js/loader.js
@@ -5,77 +5,175 @@
* See the COPYING-README file.
*/
Calendar_Import={
- importdialog: function(filename){
- var path = $('#dir').val();
- $('body').append('<div id="calendar_import"></div>');
- $('#calendar_import').load(OC.filePath('calendar', 'ajax/import', 'dialog.php'), {filename:filename, path:path}, function(){Calendar_Import.initdialog(filename);});
+ Store:{
+ file: '',
+ path: '',
+ id: 0,
+ method: '',
+ calname: '',
+ calcolor: '',
+ progresskey: '',
+ percentage: 0
},
- initdialog: function(filename){
- $('#calendar_import_dialog').dialog({
- width : 500,
- close : function() {
- $(this).dialog('destroy').remove();
- $('#calendar_import').remove();
+ Dialog:{
+ open: function(filename){
+ OC.addStyle('calendar', 'import');
+ Calendar_Import.Store.file = filename;
+ Calendar_Import.Store.path = $('#dir').val();
+ $('body').append('<div id="calendar_import"></div>');
+ $('#calendar_import').load(OC.filePath('calendar', 'ajax/import', 'dialog.php'), {filename:Calendar_Import.Store.file, path:Calendar_Import.Store.path},function(){
+ Calendar_Import.Dialog.init();
+ });
+ },
+ close: function(){
+ Calendar_Import.reset();
+ $(this).dialog('destroy').remove();
+ $('#calendar_import_dialog').remove();
+ },
+ init: function(){
+ //init dialog
+ $('#calendar_import_dialog').dialog({
+ width : 500,
+ resizable: false,
+ close : function() {
+ Calendar_Import.Dialog.close();
+ }
+ });
+ //init buttons
+ $('#calendar_import_done').click(function(){
+ Calendar_Import.Dialog.close();
+ });
+ $('#calendar_import_submit').click(function(){
+ Calendar_Import.Core.process();
+ });
+ $('#calendar_import_mergewarning').click(function(){
+ $('#calendar_import_newcalendar').attr('value', $('#calendar_import_availablename').val());
+ Calendar_Import.Dialog.mergewarning($('#calendar_import_newcalendar').val());
+ });
+ $('#calendar_import_calendar').change(function(){
+ if($('#calendar_import_calendar option:selected').val() == 'newcal'){
+ $('#calendar_import_newcalform').slideDown('slow');
+ Calendar_Import.Dialog.mergewarning($('#calendar_import_newcalendar').val());
+ }else{
+ $('#calendar_import_newcalform').slideUp('slow');
+ $('#calendar_import_mergewarning').slideUp('slow');
+ }
+ });
+ $('#calendar_import_newcalendar').keyup(function(){
+ Calendar_Import.Dialog.mergewarning($.trim($('#calendar_import_newcalendar').val()));
+ });
+ $('#calendar_import_newcalendar_color').miniColors({
+ letterCase: 'uppercase'
+ });
+ $('.calendar-colorpicker-color').click(function(){
+ var str = $(this).attr('rel');
+ str = str.substr(1);
+ $('#calendar_import_newcalendar_color').attr('value', str);
+ $(".color-picker").miniColors('value', '#' + str);
+ });
+ //init progressbar
+ $('#calendar_import_progressbar').progressbar({value: Calendar_Import.Store.percentage});
+ Calendar_Import.Store.progresskey = $('#calendar_import_progresskey').val();
+ },
+ mergewarning: function(newcalname){
+ $.post(OC.filePath('calendar', 'ajax/import', 'calendarcheck.php'), {calname: newcalname}, function(data){
+ if(data.message == 'exists'){
+ $('#calendar_import_mergewarning').slideDown('slow');
+ }else{
+ $('#calendar_import_mergewarning').slideUp('slow');
+ }
+ });
+ },
+ update: function(){
+ if(Calendar_Import.Store.percentage == 100){
+ return false;
}
- });
- $('#import_done_button').click(function(){
- $('#calendar_import_dialog').dialog('destroy').remove();
- $('#calendar_import').remove();
- });
- $('#progressbar').progressbar({value: 0});
- $('#startimport').click(function(){
- var filename = $('#filename').val();
- var path = $('#path').val();
- var calid = $('#calendar option:selected').val();
- if($('#calendar option:selected').val() == 'newcal'){
- var method = 'new';
- var calname = $('#newcalendar').val();
- var calname = $.trim(calname);
- if(calname == ''){
- $('#newcalendar').css('background-color', '#FF2626');
- $('#newcalendar').focus(function(){
- $('#newcalendar').css('background-color', '#F8F8F8');
- });
- return false;
+ $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: Calendar_Import.Store.progresskey, getprogress: true}, function(data){
+ if(data.status == 'success'){
+ if(data.percent == null){
+ return false;
+ }
+ Calendar_Import.Store.percentage = parseInt(data.percent);
+ $('#calendar_import_progressbar').progressbar('option', 'value', parseInt(data.percent));
+ if(data.percent < 100 ){
+ window.setTimeout('Calendar_Import.Dialog.update()', 250);
+ }else{
+ $('#calendar_import_done').css('display', 'block');
+ }
+ }else{
+ $('#calendar_import_progressbar').progressbar('option', 'value', 100);
+ $('#calendar_import_progressbar > div').css('background-color', '#FF2626');
+ $('#calendar_import_status').html(data.message);
}
- }else{
- var method = 'old';
+ });
+ return 0;
+ },
+ warning: function(selector){
+ $(selector).addClass('calendar_import_warning');
+ $(selector).focus(function(){
+ $(selector).removeClass('calendar_import_warning');
+ });
+ }
+ },
+ Core:{
+ process: function(){
+ var validation = Calendar_Import.Core.prepare();
+ if(validation){
+ $('#calendar_import_form').css('display', 'none');
+ $('#calendar_import_process').css('display', 'block');
+ $('#calendar_import_newcalendar').attr('readonly', 'readonly');
+ $('#calendar_import_calendar').attr('disabled', 'disabled');
+ Calendar_Import.Core.send();
+ window.setTimeout('Calendar_Import.Dialog.update()', 250);
}
- $('#newcalendar').attr('readonly', 'readonly');
- $('#calendar').attr('disabled', 'disabled');
- var progresskey = $('#progresskey').val();
- $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: progresskey, method: String (method), calname: String (calname), path: String (path), file: String (filename), id: String (calid)}, function(data){
+ },
+ send: function(){
+ $.post(OC.filePath('calendar', 'ajax/import', 'import.php'),
+ {progresskey: Calendar_Import.Store.progresskey, method: String (Calendar_Import.Store.method), calname: String (Calendar_Import.Store.calname), path: String (Calendar_Import.Store.path), file: String (Calendar_Import.Store.file), id: String (Calendar_Import.Store.id), calcolor: String (Calendar_Import.Store.calcolor)}, function(data){
if(data.status == 'success'){
- $('#progressbar').progressbar('option', 'value', 100);
- $('#import_done').css('display', 'block');
+ $('#calendar_import_progressbar').progressbar('option', 'value', 100);
+ Calendar_Import.Store.percentage = 100;
+ $('#calendar_import_done').css('display', 'block');
+ $('#calendar_import_status').html(data.message);
+ }else{
+ $('#calendar_import_progressbar').progressbar('option', 'value', 100);
+ $('#calendar_import_progressbar > div').css('background-color', '#FF2626');
+ $('#calendar_import_status').html(data.message);
}
});
- $('#form_container').css('display', 'none');
- $('#progressbar_container').css('display', 'block');
- window.setTimeout('Calendar_Import.getimportstatus(\'' + progresskey + '\')', 500);
- });
- $('#calendar').change(function(){
- if($('#calendar option:selected').val() == 'newcal'){
- $('#newcalform').slideDown('slow');
+ },
+ prepare: function(){
+ Calendar_Import.Store.id = $('#calendar_import_calendar option:selected').val();
+ if($('#calendar_import_calendar option:selected').val() == 'newcal'){
+ Calendar_Import.Store.method = 'new';
+ Calendar_Import.Store.calname = $.trim($('#calendar_import_newcalendar').val());
+ if(Calendar_Import.Store.calname == ''){
+ Calendar_Import.Dialog.warning('#calendar_import_newcalendar');
+ return false;
+ }
+ Calendar_Import.Store.calcolor = $.trim($('#calendar_import_newcalendar_color').val());
+ if(Calendar_Import.Store.calcolor == ''){
+ Calendar_Import.Store.calcolor = $('.calendar-colorpicker-color:first').attr('rel');
+ }
}else{
- $('#newcalform').slideUp('slow');
+ Calendar_Import.Store.method = 'old';
}
- });
+ return true;
+ }
},
- getimportstatus: function(progresskey){
- $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progress:1,progresskey: progresskey}, function(percent){
- $('#progressbar').progressbar('option', 'value', parseInt(percent));
- if(percent < 100){
- window.setTimeout('Calendar_Import.getimportstatus(\'' + progresskey + '\')', 500);
- }else{
- $('#import_done').css('display', 'block');
- }
- });
+ reset: function(){
+ Calendar_Import.Store.file = '';
+ Calendar_Import.Store.path = '';
+ Calendar_Import.Store.id = 0;
+ Calendar_Import.Store.method = '';
+ Calendar_Import.Store.calname = '';
+ Calendar_Import.Store.progresskey = '';
+ Calendar_Import.Store.percentage = 0;
}
}
$(document).ready(function(){
if(typeof FileActions !== 'undefined'){
- FileActions.register('text/calendar','importcal', '', Calendar_Import.importdialog);
- FileActions.setDefault('text/calendar','importcal');
+ FileActions.register('text/calendar','importCalendar', '', Calendar_Import.Dialog.open);
+ FileActions.setDefault('text/calendar','importCalendar');
};
});
diff --git a/apps/calendar/js/settings.js b/apps/calendar/js/settings.js
index 03e4217573d..60741f2b6fc 100644
--- a/apps/calendar/js/settings.js
+++ b/apps/calendar/js/settings.js
@@ -34,6 +34,7 @@ $(document).ready(function(){
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'timeformat.php'), function(jsondata, status) {
$('#' + jsondata.timeformat).attr('selected',true);
$('#timeformat').chosen();
+ $('#timeformat_chzn').css('width', '100px');
});
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'gettimezonedetection.php'), function(jsondata, status){
if(jsondata.detection == 'true'){
@@ -43,6 +44,7 @@ $(document).ready(function(){
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'getfirstday.php'), function(jsondata, status) {
$('#' + jsondata.firstday).attr('selected',true);
$('#firstday').chosen();
+ $('#firstday_chzn').css('width', '100px');
});
$('#cleancalendarcache').click(function(){
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'rescan.php'), function(){
@@ -55,7 +57,7 @@ function calendarcachecheck(){
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'status.php'), function(jsondata, status) {
$('#cleancalendarcache').attr('title', jsondata.l10n.text);
if(jsondata.status == 'success'){
- $('#cleancalendarcache').css('background', '#90EE90');
+ $('#cleancalendarcache').css('background', '#F8F8F8');
$('#cleancalendarcache').css('color', '#333');
$('#cleancalendarcache').css('text-shadow', '#fff 0 1px 0');
}else{
diff --git a/apps/calendar/lib/app.php b/apps/calendar/lib/app.php
index 1a13f2958c0..29e5ab5b0c8 100644
--- a/apps/calendar/lib/app.php
+++ b/apps/calendar/lib/app.php
@@ -9,7 +9,7 @@
* This class manages our app actions
*/
OC_Calendar_App::$l10n = new OC_L10N('calendar');
-OC_Calendar_App::$tz = OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+OC_Calendar_App::$tz = OC_Calendar_App::getTimezone();
class OC_Calendar_App{
const CALENDAR = 'calendar';
const EVENT = 'event';
@@ -282,7 +282,17 @@ class OC_Calendar_App{
public static function getWeekofMonth(){
return OC_Calendar_Object::getWeekofMonth(self::$l10n);
}
-
+
+ /**
+ * @return (string) $timezone as set by user or the default timezone
+ */
+ public static function getTimezone() {
+ return OCP\Config::getUserValue(OCP\User::getUser(),
+ 'calendar',
+ 'timezone',
+ date_default_timezone_get());
+ }
+
/**
* @brief checks the access for a calendar / an event
* @param (int) $id - id of the calendar / event
diff --git a/apps/calendar/lib/calendar.php b/apps/calendar/lib/calendar.php
index 128b55c48e9..7778242464c 100644
--- a/apps/calendar/lib/calendar.php
+++ b/apps/calendar/lib/calendar.php
@@ -267,8 +267,42 @@ class OC_Calendar_Calendar{
'url' => OCP\Util::linkTo('calendar', 'ajax/events.php').'?calendar_id='.$calendar['id'],
'backgroundColor' => $calendar['calendarcolor'],
'borderColor' => '#888',
- 'textColor' => 'black',
+ 'textColor' => self::generateTextColor($calendar['calendarcolor']),
'cache' => true,
);
}
+
+ /*
+ * @brief checks if a calendar name is available for a user
+ * @param string $calendarname
+ * @param string $userid
+ * @return boolean
+ */
+ public static function isCalendarNameavailable($calendarname, $userid){
+ $calendars = self::allCalendars($userid);
+ foreach($calendars as $calendar){
+ if($calendar['displayname'] == $calendarname){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * @brief generates the text color for the calendar
+ * @param string $calendarcolor rgb calendar color code in hex format (with or without the leading #)
+ * (this function doesn't pay attention on the alpha value of rgba color codes)
+ * @return boolean
+ */
+ public static function generateTextColor($calendarcolor){
+ if(substr_count($calendarcolor, '#') == 1){
+ $calendarcolor = substr($calendarcolor,1);
+ }
+ $red = hexdec(substr($calendarcolor,0,2));
+ $green = hexdec(substr($calendarcolor,2,2));
+ $blue = hexdec(substr($calendarcolor,2,2));
+ //recommendation by W3C
+ $computation = ((($red * 299) + ($green * 587) + ($blue * 114)) / 1000);
+ return ($computation > 130)?'#000000':'#FAFAFA';
+ }
}
diff --git a/apps/calendar/lib/hooks.php b/apps/calendar/lib/hooks.php
index 328d2951d23..bc0b02c62b8 100644
--- a/apps/calendar/lib/hooks.php
+++ b/apps/calendar/lib/hooks.php
@@ -11,7 +11,18 @@
*/
class OC_Calendar_Hooks{
/**
- * @brief Deletes all Addressbooks of a certain user
+ * @brief Creates default calendar for a user
+ * @param paramters parameters from postCreateUser-Hook
+ * @return array
+ */
+ public static function createUser($parameters) {
+ OC_Calendar_Calendar::addCalendar($parameters['uid'],'Default calendar');
+
+ return true;
+ }
+
+ /**
+ * @brief Deletes all calendars of a certain user
* @param paramters parameters from postDeleteUser-Hook
* @return array
*/
diff --git a/apps/calendar/lib/import.php b/apps/calendar/lib/import.php
new file mode 100644
index 00000000000..d36891cb2b9
--- /dev/null
+++ b/apps/calendar/lib/import.php
@@ -0,0 +1,334 @@
+<?php
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+/*
+ * This class does import and converts all times to the users current timezone
+ */
+class OC_Calendar_Import{
+ /*
+ * @brief counts the absolute number of parsed elements
+ */
+ private $abscount;
+
+ /*
+ * @brief var saves if the percentage should be saved with OC_Cache
+ */
+ private $cacheprogress;
+
+ /*
+ * @brief Sabre_VObject_Component_VCalendar object - for documentation see http://code.google.com/p/sabredav/wiki/Sabre_VObject_Component_VCalendar
+ */
+ private $calobject;
+
+ /*
+ * @brief var counts the number of imported elements
+ */
+ private $count;
+
+ /*
+ * @brief var to check if errors happend while initialization
+ */
+ private $error;
+
+ /*
+ * @brief var saves the ical string that was submitted with the __construct function
+ */
+ private $ical;
+
+ /*
+ * @brief calendar id for import
+ */
+ private $id;
+
+ /*
+ * @brief var saves the percentage of the import's progress
+ */
+ private $progress;
+
+ /*
+ * @brief var saves the key for the percentage of the import's progress
+ */
+ private $progresskey;
+
+ /*
+ * @brief var saves the timezone the events shell converted to
+ */
+ private $tz;
+
+ /*
+ * @brief var saves the userid
+ */
+ private $userid;
+
+ /*
+ * public methods
+ */
+
+ /*
+ * @brief does general initialization for import object
+ * @param string $calendar content of ical file
+ * @param string $tz timezone of the user
+ * @return boolean
+ */
+ public function __construct($ical){
+ $this->error = null;
+ $this->ical = $ical;
+ $this->abscount = 0;
+ $this->count = 0;
+ try{
+ $this->calobject = OC_VObject::parse($this->ical);
+ }catch(Exception $e){
+ //MISSING: write some log
+ $this->error = true;
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * @brief imports a calendar
+ * @return boolean
+ */
+ public function import(){
+ if(!$this->isValid()){
+ return false;
+ }
+ $numofcomponents = count($this->calobject->getComponents());
+ foreach($this->calobject->getComponents() as $object){
+ if(!($object instanceof Sabre_VObject_Component_VEvent) && !($object instanceof Sabre_VObject_Component_VJournal) && !($object instanceof Sabre_VObject_Component_VTodo)){
+ continue;
+ }
+ $dtend = OC_Calendar_Object::getDTEndFromVEvent($object);
+ $object->DTSTART->getDateTime()->setTimezone(new DateTimeZone($this->tz));
+ $object->DTEND->setDateTime($dtend->getDateTime(), $object->DTSTART->getDateType());
+ $object->DTEND->getDateTime()->setTimezone(new DateTimeZone($this->tz));
+ $vcalendar = $this->createVCalendar($object->serialize());
+ $insertid = OC_Calendar_Object::add($this->id, $vcalendar);
+ $this->abscount++;
+ if($this->isDuplicate($insertid)){
+ OC_Calendar_Object::delete($insertid);
+ }else{
+ $this->count++;
+ }
+ $this->updateProgress(intval(($this->abscount / $numofcomponents)*100));
+ }
+ OC_Cache::remove($this->progresskey);
+ return true;
+ }
+
+ /*
+ * @brief sets the timezone
+ * @return boolean
+ */
+ public function setTimeZone($tz){
+ $this->tz = $tz;
+ return true;
+ }
+
+ /*
+ * @brief sets the progresskey
+ * @return boolean
+ */
+ public function setProgresskey($progresskey){
+ $this->progresskey = $progresskey;
+ return true;
+ }
+
+ /*
+ * @brief checks if something went wrong while initialization
+ * @return boolean
+ */
+ public function isValid(){
+ if(is_null($this->error)){
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @brief returns the percentage of progress
+ * @return integer
+ */
+ public function getProgress(){
+ return $this->progress;
+ }
+
+ /*
+ * @brief enables the cache for the percentage of progress
+ * @return boolean
+ */
+ public function enableProgressCache(){
+ $this->cacheprogress = true;
+ return true;
+ }
+
+ /*
+ * @brief disables the cache for the percentage of progress
+ * @return boolean
+ */
+ public function disableProgressCache(){
+ $this->cacheprogress = false;
+ return false;
+ }
+
+ /*
+ * @brief generates a new calendar name
+ * @return string
+ */
+ public function createCalendarName(){
+ $calendars = OC_Calendar_Calendar::allCalendars($this->userid);
+ $calendarname = $guessedcalendarname = !is_null($this->guessCalendarName())?($this->guessCalendarName()):(OC_Calendar_App::$l10n->t('New Calendar'));
+ $i = 1;
+ while(!OC_Calendar_Calendar::isCalendarNameavailable($calendarname, $this->userid)){
+ $calendarname = $guessedcalendarname . ' (' . $i . ')';
+ $i++;
+ }
+ return $calendarname;
+ }
+
+ /*
+ * @brief generates a new calendar color
+ * @return string
+ */
+ public function createCalendarColor(){
+ if(is_null($this->guessCalendarColor())){
+ return '#9fc6e7';
+ }
+ return $this->guessCalendarColor();
+ }
+
+ /*
+ * @brief sets the id for the calendar
+ * @param integer $id of the calendar
+ * @return boolean
+ */
+ public function setCalendarID($id){
+ $this->id = $id;
+ return true;
+ }
+
+ /*
+ * @brief sets the userid to import the calendar
+ * @param string $id of the user
+ * @return boolean
+ */
+ public function setUserID($userid){
+ $this->userid = $userid;
+ return true;
+ }
+
+ /*
+ * @brief returns the private
+ * @param string $id of the user
+ * @return boolean
+ */
+ public function getCount(){
+ return $this->count;
+ }
+
+ /*
+ * private methods
+ */
+
+ /*
+ * @brief generates an unique ID
+ * @return string
+ */
+ //private function createUID(){
+ // return substr(md5(rand().time()),0,10);
+ //}
+
+ /*
+ * @brief checks is the UID is already in use for another event
+ * @param string $uid uid to check
+ * @return boolean
+ */
+ //private function isUIDAvailable($uid){
+ //
+ //}
+
+ /*
+ * @brief generates a proper VCalendar string
+ * @param string $vobject
+ * @return string
+ */
+ private function createVCalendar($vobject){
+ if(is_object($vobject)){
+ $vobject = @$vobject->serialize();
+ }
+ $vcalendar = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Calendar " . OCP\App::getAppVersion('calendar') . "\n";
+ $vcalendar .= $vobject;
+ $vcalendar .= "END:VCALENDAR";
+ return $vcalendar;
+ }
+
+ /*
+ * @brief checks if an event already exists in the user's calendars
+ * @param integer $insertid id of the new object
+ * @return boolean
+ */
+ private function isDuplicate($insertid){
+ $newobject = OC_Calendar_Object::find($insertid);
+ $stmt = OCP\DB::prepare('SELECT COUNT(*) as count FROM *PREFIX*calendar_objects WHERE objecttype=? AND startdate=? AND enddate=? AND repeating=? AND summary=? AND calendardata=?');
+ $result = $stmt->execute(array($newobject['objecttype'],$newobject['startdate'],$newobject['enddate'],$newobject['repeating'],$newobject['summary'],$newobject['calendardata']));
+ $result = $result->fetchRow();
+ if($result['count'] >= 2){
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @brief updates the progress var
+ * @param integer $percentage
+ * @return boolean
+ */
+ private function updateProgress($percentage){
+ $this->progress = $percentage;
+ if($this->cacheprogress){
+ OC_Cache::set($this->progresskey, $this->progress, 300);
+ }
+ return true;
+ }
+
+ /*
+ * public methods for (pre)rendering of X-... Attributes
+ */
+
+ /*
+ * @brief guesses the calendar color
+ * @return mixed - string or boolean
+ */
+ public function guessCalendarColor(){
+ if(!is_null($this->calobject->__get('X-APPLE-CALENDAR-COLOR'))){
+ return $this->calobject->__get('X-APPLE-CALENDAR-COLOR');
+ }
+ return null;
+ }
+
+ /*
+ * @brief guesses the calendar description
+ * @return mixed - string or boolean
+ */
+ public function guessCalendarDescription(){
+ if(!is_null($this->calobject->__get('X-WR-CALDESC'))){
+ return $this->calobject->__get('X-WR-CALDESC');
+ }
+ return null;
+ }
+
+ /*
+ * @brief guesses the calendar name
+ * @return mixed - string or boolean
+ */
+ public function guessCalendarName(){
+ if(!is_null($this->calobject->__get('X-WR-CALNAME'))){
+ return $this->calobject->__get('X-WR-CALNAME');
+ }
+ return null;
+ }
+}
diff --git a/apps/calendar/lib/object.php b/apps/calendar/lib/object.php
index 140542bf4fb..34676830205 100644
--- a/apps/calendar/lib/object.php
+++ b/apps/calendar/lib/object.php
@@ -856,7 +856,7 @@ class OC_Calendar_Object{
$vevent->setDateTime('DTSTART', $start, Sabre_VObject_Property_DateTime::DATE);
$vevent->setDateTime('DTEND', $end, Sabre_VObject_Property_DateTime::DATE);
}else{
- $timezone = OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+ $timezone = OC_Calendar_App::getTimezone();
$timezone = new DateTimeZone($timezone);
$start = new DateTime($from.' '.$fromtime, $timezone);
$end = new DateTime($to.' '.$totime, $timezone);
diff --git a/apps/calendar/lib/search.php b/apps/calendar/lib/search.php
index 560330f65e9..551489672b9 100644
--- a/apps/calendar/lib/search.php
+++ b/apps/calendar/lib/search.php
@@ -12,7 +12,7 @@ class OC_Search_Provider_Calendar extends OC_Search_Provider{
}else{
$searchquery[] = $query;
}
- $user_timezone = OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+ $user_timezone = OC_Calendar_App::getTimezone();
$l = new OC_l10n('calendar');
foreach($calendars as $calendar){
$objects = OC_Calendar_Object::all($calendar['id']);
diff --git a/apps/calendar/settings.php b/apps/calendar/settings.php
index a18b1ca9f42..eaa20c6c9b4 100644
--- a/apps/calendar/settings.php
+++ b/apps/calendar/settings.php
@@ -10,6 +10,7 @@ $tmpl = new OCP\Template( 'calendar', 'settings');
$timezone=OCP\Config::getUserValue(OCP\USER::getUser(),'calendar','timezone','');
$tmpl->assign('timezone',$timezone);
$tmpl->assign('timezones',DateTimeZone::listIdentifiers());
+$tmpl->assign('calendars', OC_Calendar_Calendar::allCalendars(OCP\USER::getUser()), false);
OCP\Util::addscript('calendar','settings');
diff --git a/apps/calendar/templates/calendar.php b/apps/calendar/templates/calendar.php
index 2246a0178e3..29b9bf6bc54 100644
--- a/apps/calendar/templates/calendar.php
+++ b/apps/calendar/templates/calendar.php
@@ -2,10 +2,10 @@
var defaultView = '<?php echo OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'currentview', 'month') ?>';
var eventSources = <?php echo json_encode($_['eventSources']) ?>;
var categories = <?php echo json_encode($_['categories']); ?>;
- var dayNames = <?php echo json_encode($l->tA(array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'))) ?>;
- var dayNamesShort = <?php echo json_encode($l->tA(array('Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.'))) ?>;
- var monthNames = <?php echo json_encode($l->tA(array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'))) ?>;
- var monthNamesShort = <?php echo json_encode($l->tA(array('Jan.', 'Feb.', 'Mar.', 'Apr.', 'May.', 'Jun.', 'Jul.', 'Aug.', 'Sep.', 'Oct.', 'Nov.', 'Dec.'))) ?>;
+ var dayNames = new Array("<?php echo $l -> t("Sunday");?>", "<?php echo $l -> t("Monday");?>", "<?php echo $l -> t("Tuesday");?>", "<?php echo $l -> t("Wednesday");?>", "<?php echo $l -> t("Thursday");?>", "<?php echo $l -> t("Friday");?>", "<?php echo $l -> t("Saturday");?>");
+ var dayNamesShort = new Array("<?php echo $l -> t("Sun.");?>", "<?php echo $l -> t("Mon.");?>", "<?php echo $l -> t("Tue.");?>", "<?php echo $l -> t("Wed.");?>", "<?php echo $l -> t("Thu.");?>", "<?php echo $l -> t("Fri.");?>", "<?php echo $l -> t("Sat.");?>");
+ var monthNames = new Array("<?php echo $l -> t("January");?>", "<?php echo $l -> t("February");?>", "<?php echo $l -> t("March");?>", "<?php echo $l -> t("April");?>", "<?php echo $l -> t("May");?>", "<?php echo $l -> t("June");?>", "<?php echo $l -> t("July");?>", "<?php echo $l -> t("August");?>", "<?php echo $l -> t("September");?>", "<?php echo $l -> t("October");?>", "<?php echo $l -> t("November");?>", "<?php echo $l -> t("December");?>");
+ var monthNamesShort = new Array("<?php echo $l -> t("Jan.");?>", "<?php echo $l -> t("Feb.");?>", "<?php echo $l -> t("Mar.");?>", "<?php echo $l -> t("Apr.");?>", "<?php echo $l -> t("May.");?>", "<?php echo $l -> t("Jun.");?>", "<?php echo $l -> t("Jul.");?>", "<?php echo $l -> t("Aug.");?>", "<?php echo $l -> t("Sep.");?>", "<?php echo $l -> t("Oct.");?>", "<?php echo $l -> t("Nov.");?>", "<?php echo $l -> t("Dec.");?>");
var agendatime = '<?php echo ((int) OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timeformat', '24') == 24 ? 'HH:mm' : 'hh:mm tt'); ?>{ - <?php echo ((int) OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timeformat', '24') == 24 ? 'HH:mm' : 'hh:mm tt'); ?>}';
var defaulttime = '<?php echo ((int) OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timeformat', '24') == 24 ? 'HH:mm' : 'hh:mm tt'); ?>';
var allDayText = '<?php echo addslashes($l->t('All day')) ?>';
diff --git a/apps/calendar/templates/part.import.php b/apps/calendar/templates/part.import.php
index 70ff9612157..2ce3cc34239 100644
--- a/apps/calendar/templates/part.import.php
+++ b/apps/calendar/templates/part.import.php
@@ -1,30 +1,58 @@
-<div id="calendar_import_dialog" title="<?php echo $l->t("Import a calendar file"); ?>">
-<div id="form_container">
-<input type="hidden" id="filename" value="<?php echo $_['filename'];?>">
-<input type="hidden" id="path" value="<?php echo $_['path'];?>">
-<input type="hidden" id="progresskey" value="<?php echo rand() ?>">
-<p style="text-align:center;"><b><?php echo $l->t('Please choose the calendar'); ?></b></p>
-<select style="width:100%;" id="calendar" name="calendar">
<?php
+//Prerendering for iCalendar file
+$file = OC_Filesystem::file_get_contents($_['path'] . '/' . $_['filename']);
+if(!$file){
+ OCP\JSON::error(array('error'=>'404'));
+}
+$import = new OC_Calendar_Import($file);
+$import->setUserID(OCP\User::getUser());
+$newcalendarname = strip_tags($import->createCalendarName());
+$guessedcalendarname = strip_tags($import->guessCalendarName());
+$calendarcolor = strip_tags($import->createCalendarColor());
+//loading calendars for select box
$calendar_options = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
$calendar_options[] = array('id'=>'newcal', 'displayname'=>$l->t('create a new calendar'));
-for($i = 0;$i<count($calendar_options);$i++){
- $calendar_options[$i]['displayname'] = $calendar_options[$i]['displayname'];
-}
-echo OCP\html_select_options($calendar_options, $calendar_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
+$defaultcolors = OC_Calendar_Calendar::getCalendarColorOptions();
?>
-</select>
-<div id="newcalform" style="display: none;">
- <input type="text" style="width: 97%;" placeholder="<?php echo $l->t('Name of new calendar'); ?>" id="newcalendar" name="newcalendar">
-</div>
-<input type="button" value="<?php echo $l->t("Import");?>!" id="startimport">
-</div>
-<div id="progressbar_container" style="display: none">
-<p style="text-align:center;"><b><?php echo $l->t('Importing calendar'); ?></b></p>
-<div id="progressbar"></div>
-<div id="import_done" style="display: none;">
-<p style="text-align:center;"><b><?php echo $l->t('Calendar imported successfully'); ?></b></p>
-<input type="button" value="<?php echo $l->t('Close Dialog'); ?>" id="import_done_button">
+<div id="calendar_import_dialog" title="<?php echo $l->t("Import a calendar file");?>">
+<div id="calendar_import_form">
+ <form>
+ <input type="hidden" id="calendar_import_filename" value="<?php echo $_['filename'];?>">
+ <input type="hidden" id="calendar_import_path" value="<?php echo $_['path'];?>">
+ <input type="hidden" id="calendar_import_progresskey" value="<?php echo rand() ?>">
+ <input type="hidden" id="calendar_import_availablename" value="<?php echo $newcalendarname ?>">
+ <div id="calendar_import_form_message"><?php echo $l->t('Please choose a calendar'); ?></div>
+ <select style="width:100%;" id="calendar_import_calendar" name="calendar_import_calendar">
+ <?php
+ for($i = 0;$i<count($calendar_options);$i++){
+ $calendar_options[$i]['displayname'] = $calendar_options[$i]['displayname'];
+ }
+ echo OCP\html_select_options($calendar_options, $calendar_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
+ ?>
+ </select>
+ <br><br>
+ <div id="calendar_import_newcalform">
+ <input id="calendar_import_newcalendar_color" class="color-picker" type="hidden" size="6" value="<?php echo substr($calendarcolor,1); ?>">
+ <input id="calendar_import_newcalendar" class="" type="text" placeholder="<?php echo $l->t('Name of new calendar'); ?>" value="<?php echo $guessedcalendarname ?>"><br>
+ <div id="calendar_import_defaultcolors">
+ <?php
+ foreach($defaultcolors as $color){
+ echo '<span class="calendar-colorpicker-color" rel="' . $color . '" style="background-color: ' . $color . ';"></span>';
+ }
+ ?>
+ </div>
+ <!--<input id="calendar_import_generatename" type="button" class="button" value="<?php echo $l->t('Take an available name!'); ?>"><br>-->
+ <div id="calendar_import_mergewarning" class="hint"><?php echo $l->t('A Calendar with this name already exists. If you continue anyhow, these calendars will be merged.'); ?></div>
+ </div>
+ <input id="calendar_import_submit" type="button" class="button" value="&raquo; <?php echo $l->t('Import'); ?> &raquo;" id="startimport">
+ <form>
</div>
+<div id="calendar_import_process">
+ <div id="calendar_import_process_message"></div>
+ <div id="calendar_import_progressbar"></div>
+ <br>
+ <div id="calendar_import_status" class="hint"></div>
+ <br>
+ <input id="calendar_import_done" type="button" value="<?php echo $l->t('Close Dialog'); ?>">
</div>
</div> \ No newline at end of file
diff --git a/apps/calendar/templates/settings.php b/apps/calendar/templates/settings.php
index 6d018f15110..28c357621a8 100644
--- a/apps/calendar/templates/settings.php
+++ b/apps/calendar/templates/settings.php
@@ -56,6 +56,12 @@
<dd><code><?php echo OCP\Util::linkToRemote('caldav'); ?></code></dd>
<dt><?php echo $l->t('iOS/OS X'); ?></dt>
<dd><code><?php echo OCP\Util::linkToRemote('caldav'); ?>principals/<?php echo OCP\USER::getUser(); ?></code>/</dd>
+ <dt><?php echo $l->t('Read only iCalendar link(s)'); ?></dt>
+ <dd>
+ <?php foreach($_['calendars'] as $calendar) { ?>
+ <a href="<?php echo OCP\Util::linkToRemote('caldav').'calendars/'.OCP\USER::getUser().'/'.rawurlencode($calendar['uri']) ?>?export"><?php echo $calendar['displayname'] ?></a><br />
+ <?php } ?>
+ </dd>
</dl>
</fieldset>
</form>
diff --git a/apps/contacts/ajax/activation.php b/apps/contacts/ajax/activation.php
index 74cb738ab8f..69173c54c44 100644
--- a/apps/contacts/ajax/activation.php
+++ b/apps/contacts/ajax/activation.php
@@ -16,8 +16,12 @@ $bookid = $_POST['bookid'];
$book = OC_Contacts_App::getAddressbook($bookid);// is owner access check
if(!OC_Contacts_Addressbook::setActive($bookid, $_POST['active'])) {
- OCP\Util::writeLog('contacts','ajax/activation.php: Error activating addressbook: '.$bookid, OCP\Util::ERROR);
- OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error (de)activating addressbook.'))));
+ OCP\Util::writeLog('contacts',
+ 'ajax/activation.php: Error activating addressbook: '. $bookid,
+ OCP\Util::ERROR);
+ OCP\JSON::error(array(
+ 'data' => array(
+ 'message' => OC_Contacts_App::$l10n->t('Error (de)activating addressbook.'))));
exit();
}
diff --git a/apps/contacts/ajax/addaddressbook.php b/apps/contacts/ajax/addaddressbook.php
new file mode 100644
index 00000000000..40773704bb4
--- /dev/null
+++ b/apps/contacts/ajax/addaddressbook.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2011-2012 Thomas Tanghus <thomas@tanghus.net>
+ * Copyright (c) 2011 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+
+// Check if we are a user
+OCP\JSON::checkLoggedIn();
+OCP\JSON::checkAppEnabled('contacts');
+OCP\JSON::callCheck();
+require_once 'loghandler.php';
+
+debug('name: '.$_POST['name']);
+
+$userid = OCP\USER::getUser();
+$name = isset($_POST['name'])?trim(strip_tags($_POST['name'])):null;
+$description = isset($_POST['description'])
+ ? trim(strip_tags($_POST['description']))
+ : null;
+
+if(is_null($name)) {
+ bailOut('Cannot add addressbook with an empty name.');
+}
+$bookid = OC_Contacts_Addressbook::add($userid, $name, $description);
+if(!$bookid) {
+ bailOut('Error adding addressbook: '.$name);
+}
+
+if(!OC_Contacts_Addressbook::setActive($bookid, 1)) {
+ bailOut('Error activating addressbook.');
+}
+$addressbook = OC_Contacts_App::getAddressbook($bookid);
+OCP\JSON::success(array('data' => $addressbook));
diff --git a/apps/contacts/ajax/addbook.php b/apps/contacts/ajax/addbook.php
index 70f47cc8123..751185b44fd 100644
--- a/apps/contacts/ajax/addbook.php
+++ b/apps/contacts/ajax/addbook.php
@@ -17,4 +17,3 @@ $tmpl = new OCP\Template('contacts', 'part.editaddressbook');
$tmpl->assign('new', true);
$tmpl->assign('addressbook', $book);
$tmpl->printPage();
-?>
diff --git a/apps/contacts/ajax/addcontact.php b/apps/contacts/ajax/addcontact.php
index 12f7bb9db96..6aaf5a9df35 100644
--- a/apps/contacts/ajax/addcontact.php
+++ b/apps/contacts/ajax/addcontact.php
@@ -37,13 +37,15 @@ $n = trim($_POST['n']);
$vcard = new OC_VObject('VCARD');
$vcard->setUID();
-$vcard->setString('FN',$fn);
-$vcard->setString('N',$n);
+$vcard->setString('FN', $fn);
+$vcard->setString('N', $n);
$id = OC_Contacts_VCard::add($aid, $vcard, null, $isnew);
if(!$id) {
- OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('There was an error adding the contact.'))));
- OCP\Util::writeLog('contacts','ajax/addcontact.php: Recieved non-positive ID on adding card: '.$id, OCP\Util::ERROR);
+ OCP\JSON::error(array(
+ 'data' => array(
+ 'message' => OC_Contacts_App::$l10n->t('There was an error adding the contact.'))));
+ OCP\Util::writeLog('contacts', 'ajax/addcontact.php: Recieved non-positive ID on adding card: '.$id, OCP\Util::ERROR);
exit();
}
diff --git a/apps/contacts/ajax/addproperty.php b/apps/contacts/ajax/addproperty.php
index 1b6db0c8f81..58b857547fb 100644
--- a/apps/contacts/ajax/addproperty.php
+++ b/apps/contacts/ajax/addproperty.php
@@ -25,7 +25,7 @@ OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
OCP\JSON::callCheck();
-require_once('loghandler.php');
+require_once 'loghandler.php';
$id = isset($_POST['id'])?$_POST['id']:null;
$name = isset($_POST['name'])?$_POST['name']:null;
@@ -33,22 +33,27 @@ $value = isset($_POST['value'])?$_POST['value']:null;
$parameters = isset($_POST['parameters'])?$_POST['parameters']:array();
$vcard = OC_Contacts_App::getContactVCard($id);
+$l10n = OC_Contacts_App::$l10n;
if(!$name) {
- bailOut(OC_Contacts_App::$l10n->t('element name is not set.'));
+ bailOut($l10n->t('element name is not set.'));
}
if(!$id) {
- bailOut(OC_Contacts_App::$l10n->t('id is not set.'));
+ bailOut($l10n->t('id is not set.'));
}
if(!$vcard) {
- bailOut(OC_Contacts_App::$l10n->t('Could not parse contact: ').$id);
+ bailOut($l10n->t('Could not parse contact: ').$id);
}
-if(!is_array($value)){
+if(!is_array($value)) {
$value = trim($value);
- if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'URL', 'NICKNAME', 'NOTE'))) {
- bailOut(OC_Contacts_App::$l10n->t('Cannot add empty property.'));
+ if(!$value
+ && in_array(
+ $name,
+ array('TEL', 'EMAIL', 'ORG', 'BDAY', 'URL', 'NICKNAME', 'NOTE'))
+ ) {
+ bailOut($l10n->t('Cannot add empty property.'));
}
} elseif($name === 'ADR') { // only add if non-empty elements.
$empty = true;
@@ -59,7 +64,7 @@ if(!is_array($value)){
}
}
if($empty) {
- bailOut(OC_Contacts_App::$l10n->t('At least one of the address fields has to be filled out.'));
+ bailOut($l10n->t('At least one of the address fields has to be filled out.'));
}
}
@@ -68,12 +73,14 @@ $current = $vcard->select($name);
foreach($current as $item) {
$tmpvalue = (is_array($value)?implode(';', $value):$value);
if($tmpvalue == $item->value) {
- bailOut(OC_Contacts_App::$l10n->t('Trying to add duplicate property: '.$name.': '.$tmpvalue));
+ bailOut($l10n->t('Trying to add duplicate property: '.$name.': '.$tmpvalue));
}
}
if(is_array($value)) {
- ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
+ // NOTE: Important, otherwise the compound value will
+ // be set in the order the fields appear in the form!
+ ksort($value);
$value = array_map('strip_tags', $value);
} else {
$value = strip_tags($value);
@@ -116,24 +123,25 @@ switch($name) {
$line = count($vcard->children) - 1;
-// Apparently Sabre_VObject_Parameter doesn't do well with multiple values or I don't know how to do it. Tanghus.
+// Apparently Sabre_VObject_Parameter doesn't do well with
+// multiple values or I don't know how to do it. Tanghus.
foreach ($parameters as $key=>$element) {
if(is_array($element) && strtoupper($key) == 'TYPE') {
// NOTE: Maybe this doesn't only apply for TYPE?
// And it probably shouldn't be done here anyways :-/
- foreach($element as $e){
- if($e != '' && !is_null($e)){
- $vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($key,$e);
+ foreach($element as $e) {
+ if($e != '' && !is_null($e)) {
+ $vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($key, $e);
}
}
} else {
- $vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($key,$element);
+ $vcard->children[$line]->parameters[] = new Sabre_VObject_Parameter($key, $element);
}
}
$checksum = md5($vcard->children[$line]->serialize());
-if(!OC_Contacts_VCard::edit($id,$vcard)) {
- bailOut(OC_Contacts_App::$l10n->t('Error adding contact property: '.$name));
+if(!OC_Contacts_VCard::edit($id, $vcard)) {
+ bailOut($l10n->t('Error adding contact property: '.$name));
}
OCP\JSON::success(array('data' => array( 'checksum' => $checksum )));
diff --git a/apps/contacts/ajax/categories/categoriesfor.php b/apps/contacts/ajax/categories/categoriesfor.php
index 846af300de8..8391b14b545 100644
--- a/apps/contacts/ajax/categories/categoriesfor.php
+++ b/apps/contacts/ajax/categories/categoriesfor.php
@@ -12,17 +12,23 @@ OCP\JSON::checkAppEnabled('contacts');
$id = isset($_GET['id'])?$_GET['id']:null;
if(is_null($id)) {
- OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('No ID provided'))));
+ OCP\JSON::error(array(
+ 'data' => array(
+ 'message' => OC_Contacts_App::$l10n->t('No ID provided'))));
exit();
}
$vcard = OC_Contacts_App::getContactVCard( $id );
foreach($vcard->children as $property){
- //OCP\Util::writeLog('contacts','ajax/categories/checksumfor.php: '.$property->name, OCP\Util::DEBUG);
if($property->name == 'CATEGORIES') {
$checksum = md5($property->serialize());
- OCP\JSON::success(array('data' => array('value'=>$property->value, 'checksum'=>$checksum)));
+ OCP\JSON::success(array(
+ 'data' => array(
+ 'value' => $property->value,
+ 'checksum' => $checksum,
+ )));
exit();
}
}
-OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error setting checksum.'))));
-?>
+OCP\JSON::error(array(
+ 'data' => array(
+ 'message' => OC_Contacts_App::$l10n->t('Error setting checksum.'))));
diff --git a/apps/contacts/ajax/categories/delete.php b/apps/contacts/ajax/categories/delete.php
index 76c23d6487d..bc9f3e14e87 100644
--- a/apps/contacts/ajax/categories/delete.php
+++ b/apps/contacts/ajax/categories/delete.php
@@ -9,8 +9,9 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
+OCP\JSON::callCheck();
-require_once('../loghandler.php');
+require_once __DIR__.'/../loghandler.php';
$categories = isset($_POST['categories'])?$_POST['categories']:null;
@@ -45,5 +46,3 @@ $catman->delete($categories, $cards);
debug('After delete: '.print_r($catman->categories(), true));
OC_Contacts_VCard::updateDataByID($cards);
OCP\JSON::success(array('data' => array('categories'=>$catman->categories())));
-
-?>
diff --git a/apps/contacts/ajax/categories/list.php b/apps/contacts/ajax/categories/list.php
index 3ae7635390c..f234116ba8c 100644
--- a/apps/contacts/ajax/categories/list.php
+++ b/apps/contacts/ajax/categories/list.php
@@ -13,5 +13,3 @@ OCP\JSON::checkAppEnabled('contacts');
$categories = OC_Contacts_App::getCategories();
OCP\JSON::success(array('data' => array('categories'=>$categories)));
-
-?>
diff --git a/apps/contacts/ajax/categories/rescan.php b/apps/contacts/ajax/categories/rescan.php
index 679f57aa26a..a06e7803955 100644
--- a/apps/contacts/ajax/categories/rescan.php
+++ b/apps/contacts/ajax/categories/rescan.php
@@ -9,25 +9,9 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
+OCP\JSON::callCheck();
-require_once(__DIR__.'/../loghandler.php');
-
-$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser());
-if(count($addressbooks) == 0) {
- bailOut(OC_Contacts_App::$l10n->t('No address books found.'));
-}
-$addressbookids = array();
-foreach($addressbooks as $addressbook) {
- $addressbookids[] = $addressbook['id'];
-}
-$contacts = OC_Contacts_VCard::all($addressbookids);
-if(count($contacts) == 0) {
- bailOut(OC_Contacts_App::$l10n->t('No contacts found.'));
-}
-
-OC_Contacts_App::scanCategories($contacts);
+OC_Contacts_App::scanCategories();
$categories = OC_Contacts_App::getCategories();
OCP\JSON::success(array('data' => array('categories'=>$categories)));
-
-?>
diff --git a/apps/contacts/ajax/contactdetails.php b/apps/contacts/ajax/contactdetails.php
index b697b1a8e5b..27d7611ade9 100644
--- a/apps/contacts/ajax/contactdetails.php
+++ b/apps/contacts/ajax/contactdetails.php
@@ -20,7 +20,7 @@
*
*/
-require_once('loghandler.php');
+require_once 'loghandler.php';
// Check if we are a user
OCP\JSON::checkLoggedIn();
@@ -30,6 +30,7 @@ $id = isset($_GET['id'])?$_GET['id']:null;
if(is_null($id)) {
bailOut(OC_Contacts_App::$l10n->t('Missing ID'));
}
+$card = OC_Contacts_VCard::find($id);
$vcard = OC_Contacts_App::getContactVCard( $id );
if(is_null($vcard)) {
bailOut(OC_Contacts_App::$l10n->t('Error parsing VCard for ID: "'.$id.'"'));
@@ -50,5 +51,7 @@ if(isset($details['PHOTO'])) {
$details['PHOTO'] = false;
}
$details['id'] = $id;
+$details['displayname'] = $card['fullname'];
+$details['addressbookid'] = $card['addressbookid'];
OC_Contacts_App::setLastModifiedHeader($vcard);
OCP\JSON::success(array('data' => $details));
diff --git a/apps/contacts/ajax/createaddressbook.php b/apps/contacts/ajax/createaddressbook.php
index 2ec5f542bb3..8dbd63f6425 100644
--- a/apps/contacts/ajax/createaddressbook.php
+++ b/apps/contacts/ajax/createaddressbook.php
@@ -12,7 +12,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
OCP\JSON::callCheck();
-require_once('loghandler.php');
+require_once 'loghandler.php';
$userid = OCP\USER::getUser();
$name = trim(strip_tags($_POST['name']));
diff --git a/apps/contacts/ajax/currentphoto.php b/apps/contacts/ajax/currentphoto.php
index b10e752c453..96080e661ef 100644
--- a/apps/contacts/ajax/currentphoto.php
+++ b/apps/contacts/ajax/currentphoto.php
@@ -24,7 +24,7 @@
OCP\JSON::setContentTypeHeader('text/plain');
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
-require_once('loghandler.php');
+require_once 'loghandler.php';
if (!isset($_GET['id'])) {
bailOut(OC_Contacts_App::$l10n->t('No contact ID was submitted.'));
@@ -51,5 +51,3 @@ if( is_null($contact)) {
bailOut(OC_Contacts_App::$l10n->t('The loading photo is not valid.'));
}
}
-
-?>
diff --git a/apps/contacts/ajax/deletecard.php b/apps/contacts/ajax/deletecard.php
index 1161c18abda..9777046fc82 100644
--- a/apps/contacts/ajax/deletecard.php
+++ b/apps/contacts/ajax/deletecard.php
@@ -23,17 +23,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
OCP\JSON::callCheck();
-require_once('loghandler.php');
-
-// foreach($_SERVER as $key=>$value) {
-// OCP\Util::writeLog('contacts','ajax/saveproperty.php: _SERVER: '.$key.'=>'.$value, OCP\Util::DEBUG);
-// }
-// foreach($_POST as $key=>$value) {
-// debug($key.'=>'.print_r($value, true));
-// }
-// foreach($_GET as $key=>$value) {
-// debug($key.'=>'.print_r($value, true));
-// }
+require_once 'loghandler.php';
$id = isset($_POST['id'])?$_POST['id']:null;
if(!$id) {
diff --git a/apps/contacts/ajax/deleteproperty.php b/apps/contacts/ajax/deleteproperty.php
index 90e5e64903e..205df8bc184 100644
--- a/apps/contacts/ajax/deleteproperty.php
+++ b/apps/contacts/ajax/deleteproperty.php
@@ -24,22 +24,23 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
OCP\JSON::callCheck();
-require_once('loghandler.php');
+require_once 'loghandler.php';
$id = $_POST['id'];
$checksum = $_POST['checksum'];
+$l10n = OC_Contacts_App::$l10n;
$vcard = OC_Contacts_App::getContactVCard( $id );
$line = OC_Contacts_App::getPropertyLineByChecksum($vcard, $checksum);
-if(is_null($line)){
- bailOut(OC_Contacts_App::$l10n->t('Information about vCard is incorrect. Please reload the page.'));
+if(is_null($line)) {
+ bailOut($l10n->t('Information about vCard is incorrect. Please reload the page.'));
exit();
}
unset($vcard->children[$line]);
-if(!OC_Contacts_VCard::edit($id,$vcard)) {
- bailOut(OC_Contacts_App::$l10n->t('Error deleting contact property.'));
+if(!OC_Contacts_VCard::edit($id, $vcard)) {
+ bailOut($l10n->t('Error deleting contact property.'));
}
OCP\JSON::success(array('data' => array( 'id' => $id )));
diff --git a/apps/contacts/ajax/editaddress.php b/apps/contacts/ajax/editaddress.php
index 2d7aba11b0e..b5e4b72ed57 100644
--- a/apps/contacts/ajax/editaddress.php
+++ b/apps/contacts/ajax/editaddress.php
@@ -34,10 +34,8 @@ if($checksum) {
$tmpl->assign('adr', $adr, false);
}
-$tmpl->assign('id',$id);
-$tmpl->assign('adr_types',$adr_types);
+$tmpl->assign('id', $id);
+$tmpl->assign('adr_types', $adr_types);
$page = $tmpl->fetchPage();
OCP\JSON::success(array('data' => array('page'=>$page, 'checksum'=>$checksum)));
-
-?>
diff --git a/apps/contacts/ajax/editaddressbook.php b/apps/contacts/ajax/editaddressbook.php
index 7a9b757ae0d..4bc77302e5b 100644
--- a/apps/contacts/ajax/editaddressbook.php
+++ b/apps/contacts/ajax/editaddressbook.php
@@ -14,4 +14,3 @@ $tmpl = new OCP\Template("contacts", "part.editaddressbook");
$tmpl->assign('new', false);
$tmpl->assign('addressbook', $addressbook);
$tmpl->printPage();
-?>
diff --git a/apps/contacts/ajax/editname.php b/apps/contacts/ajax/editname.php
index 868ca222e0a..eb55634011d 100644
--- a/apps/contacts/ajax/editname.php
+++ b/apps/contacts/ajax/editname.php
@@ -9,7 +9,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
-require_once('loghandler.php');
+require_once 'loghandler.php';
$tmpl = new OCP\Template("contacts", "part.edit_name_dialog");
@@ -25,12 +25,10 @@ if($id) {
}
}
$name = array_map('htmlspecialchars', $name['value']);
- $tmpl->assign('name',$name, false);
- $tmpl->assign('id',$id, false);
+ $tmpl->assign('name', $name, false);
+ $tmpl->assign('id', $id, false);
} else {
bailOut(OC_Contacts_App::$l10n->t('Contact ID is missing.'));
}
$page = $tmpl->fetchPage();
OCP\JSON::success(array('data' => array('page'=>$page)));
-
-?>
diff --git a/apps/contacts/ajax/importaddressbook.php b/apps/contacts/ajax/importaddressbook.php
deleted file mode 100644
index f93bbfa4d9d..00000000000
--- a/apps/contacts/ajax/importaddressbook.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-
-OCP\JSON::checkLoggedIn();
-OCP\App::checkAppEnabled('contacts');
-$upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize'));
-$post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size'));
-$maxUploadFilesize = min($upload_max_filesize, $post_max_size);
-
-$freeSpace=OC_Filesystem::free_space('/');
-$freeSpace=max($freeSpace,0);
-$maxUploadFilesize = min($maxUploadFilesize ,$freeSpace);
-
-$tmpl = new OCP\Template('contacts', 'part.importaddressbook');
-$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
-$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
-$tmpl->printpage();
-?>
diff --git a/apps/contacts/ajax/importdialog.php b/apps/contacts/ajax/importdialog.php
index 5f8805a6106..691522538fb 100644
--- a/apps/contacts/ajax/importdialog.php
+++ b/apps/contacts/ajax/importdialog.php
@@ -13,4 +13,3 @@ $tmpl = new OCP\Template('contacts', 'part.import');
$tmpl->assign('path', $_POST['path']);
$tmpl->assign('filename', $_POST['filename']);
$tmpl->printpage();
-?>
diff --git a/apps/contacts/ajax/loadcard.php b/apps/contacts/ajax/loadcard.php
index 1309faaa7a2..75fe33ada6f 100644
--- a/apps/contacts/ajax/loadcard.php
+++ b/apps/contacts/ajax/loadcard.php
@@ -30,20 +30,20 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size);
$requesttoken = $_GET['requesttoken'];
$freeSpace=OC_Filesystem::free_space('/');
-$freeSpace=max($freeSpace,0);
-$maxUploadFilesize = min($maxUploadFilesize ,$freeSpace);
+$freeSpace=max($freeSpace, 0);
+$maxUploadFilesize = min($maxUploadFilesize, $freeSpace);
$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$email_types = OC_Contacts_App::getTypesOfProperty('EMAIL');
-$tmpl = new OCP\Template('contacts','part.contact');
+$tmpl = new OCP\Template('contacts', 'part.contact');
$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
-$tmpl->assign('adr_types',$adr_types);
-$tmpl->assign('phone_types',$phone_types);
-$tmpl->assign('email_types',$email_types);
+$tmpl->assign('adr_types', $adr_types);
+$tmpl->assign('phone_types', $phone_types);
+$tmpl->assign('email_types', $email_types);
$tmpl->assign('requesttoken', $requesttoken);
-$tmpl->assign('id','');
+$tmpl->assign('id', '');
$page = $tmpl->fetchPage();
OCP\JSON::success(array('data' => array( 'page' => $page )));
diff --git a/apps/contacts/ajax/loadintro.php b/apps/contacts/ajax/loadintro.php
index 6e8fcc4b049..1da08950ca0 100644
--- a/apps/contacts/ajax/loadintro.php
+++ b/apps/contacts/ajax/loadintro.php
@@ -25,7 +25,7 @@ OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
-$tmpl = new OCP\Template('contacts','part.no_contacts');
+$tmpl = new OCP\Template('contacts', 'part.no_contacts');
$page = $tmpl->fetchPage();
OCP\JSON::success(array('data' => array( 'page' => $page )));
diff --git a/apps/contacts/ajax/loadphoto.php b/apps/contacts/ajax/loadphoto.php
deleted file mode 100644
index a35631055eb..00000000000
--- a/apps/contacts/ajax/loadphoto.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * ownCloud - Addressbook
- *
- * @author Thomas Tanghus
- * @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Check if we are a user
-OCP\JSON::checkLoggedIn();
-OCP\JSON::checkAppEnabled('contacts');
-
-require_once('loghandler.php');
-
-$id = isset($_GET['id']) ? $_GET['id'] : '';
-$refresh = isset($_GET['refresh']) ? true : false;
-
-if($id == '') {
- bailOut(OC_Contacts_App::$l10n->t('Missing contact id.'));
-}
-
-$checksum = '';
-$vcard = OC_Contacts_App::getContactVCard( $id );
-foreach($vcard->children as $property){
- if($property->name == 'PHOTO') {
- $checksum = md5($property->serialize());
- break;
- }
-}
-
-OCP\JSON::success(array('data' => array('checksum'=>$checksum)));
-
diff --git a/apps/contacts/ajax/loghandler.php b/apps/contacts/ajax/loghandler.php
index 831b2e50c1e..be4b98c1112 100644
--- a/apps/contacts/ajax/loghandler.php
+++ b/apps/contacts/ajax/loghandler.php
@@ -20,13 +20,15 @@
*
*/
-function bailOut($msg, $tracelevel=1, $debuglevel=OCP\Util::ERROR) {
+function bailOut($msg, $tracelevel=1, $debuglevel=OCP\Util::ERROR)
+{
OCP\JSON::error(array('data' => array('message' => $msg)));
debug($msg, $tracelevel, $debuglevel);
exit();
}
-function debug($msg, $tracelevel=0, $debuglevel=OCP\Util::DEBUG) {
+function debug($msg, $tracelevel=0, $debuglevel=OCP\Util::DEBUG)
+{
if(PHP_VERSION >= "5.4") {
$call = debug_backtrace(false, $tracelevel+1);
} else {
@@ -35,6 +37,8 @@ function debug($msg, $tracelevel=0, $debuglevel=OCP\Util::DEBUG) {
error_log('trace: '.print_r($call, true));
$call = $call[$tracelevel];
if($debuglevel !== false) {
- OCP\Util::writeLog('contacts', $call['file'].'. Line: '.$call['line'].': '.$msg, $debuglevel);
+ OCP\Util::writeLog('contacts',
+ $call['file'].'. Line: '.$call['line'].': '.$msg,
+ $debuglevel);
}
}
diff --git a/apps/contacts/ajax/oc_photo.php b/apps/contacts/ajax/oc_photo.php
index 5c50ba92dbe..fe37b530f82 100644
--- a/apps/contacts/ajax/oc_photo.php
+++ b/apps/contacts/ajax/oc_photo.php
@@ -22,7 +22,7 @@
// Check if we are a user
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
-require_once('loghandler.php');
+require_once 'loghandler.php';
if(!isset($_GET['id'])) {
bailOut(OC_Contacts_App::$l10n->t('No contact ID was submitted.'));
@@ -50,7 +50,9 @@ if($image->width() > 400 || $image->height() > 400) {
$image->resize(400); // Prettier resizing than with browser and saves bandwidth.
}
if(!$image->fixOrientation()) { // No fatal error so we don't bail out.
- OCP\Util::writeLog('contacts','ajax/oc_photo.php: Couldn\'t save correct image orientation: '.$localpath, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts',
+ 'ajax/oc_photo.php: Couldn\'t save correct image orientation: '.$localpath,
+ OCP\Util::DEBUG);
}
if(OC_Cache::set($tmpkey, $image->data(), 600)) {
OCP\JSON::success(array('data' => array('id'=>$_GET['id'], 'tmp'=>$tmpkey)));
@@ -58,5 +60,3 @@ if(OC_Cache::set($tmpkey, $image->data(), 600)) {
} else {
bailOut('Couldn\'t save temporary image: '.$tmpkey);
}
-
-?>
diff --git a/apps/contacts/ajax/savecrop.php b/apps/contacts/ajax/savecrop.php
index adce6be3b39..8ee2e46bf0c 100644
--- a/apps/contacts/ajax/savecrop.php
+++ b/apps/contacts/ajax/savecrop.php
@@ -27,7 +27,7 @@ OCP\JSON::callCheck();
// Firefox and Konqueror tries to download application/json for me. --Arthur
OCP\JSON::setContentTypeHeader('text/plain');
-require_once('loghandler.php');
+require_once 'loghandler.php';
$image = null;
@@ -48,7 +48,7 @@ if($id == '') {
bailOut('Missing contact id.');
}
-OCP\Util::writeLog('contacts','savecrop.php: key: '.$tmpkey, OCP\Util::DEBUG);
+OCP\Util::writeLog('contacts', 'savecrop.php: key: '.$tmpkey, OCP\Util::DEBUG);
$data = OC_Cache::get($tmpkey);
if($data) {
@@ -56,7 +56,9 @@ if($data) {
if($image->loadFromdata($data)) {
$w = ($w != -1 ? $w : $image->width());
$h = ($h != -1 ? $h : $image->height());
- OCP\Util::writeLog('contacts','savecrop.php, x: '.$x1.' y: '.$y1.' w: '.$w.' h: '.$h, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts',
+ 'savecrop.php, x: '.$x1.' y: '.$y1.' w: '.$w.' h: '.$h,
+ OCP\Util::DEBUG);
if($image->crop($x1, $y1, $w, $h)) {
if(($image->width() <= 200 && $image->height() <= 200) || $image->resize(200)) {
$card = OC_Contacts_App::getContactVCard($id);
@@ -65,7 +67,9 @@ if($data) {
bailOut(OC_Contacts_App::$l10n->t('Error getting contact object.'));
}
if($card->__isset('PHOTO')) {
- OCP\Util::writeLog('contacts','savecrop.php: PHOTO property exists.', OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts',
+ 'savecrop.php: PHOTO property exists.',
+ OCP\Util::DEBUG);
$property = $card->__get('PHOTO');
if(!$property) {
OC_Cache::remove($tmpkey);
@@ -76,12 +80,16 @@ if($data) {
$property->parameters[] = new Sabre_VObject_Parameter('TYPE', $image->mimeType());
$card->__set('PHOTO', $property);
} else {
- OCP\Util::writeLog('contacts','savecrop.php: files: Adding PHOTO property.', OCP\Util::DEBUG);
- $card->addProperty('PHOTO', $image->__toString(), array('ENCODING' => 'b', 'TYPE' => $image->mimeType()));
+ OCP\Util::writeLog('contacts',
+ 'savecrop.php: files: Adding PHOTO property.',
+ OCP\Util::DEBUG);
+ $card->addProperty('PHOTO',
+ $image->__toString(), array('ENCODING' => 'b',
+ 'TYPE' => $image->mimeType()));
}
$now = new DateTime;
$card->setString('REV', $now->format(DateTime::W3C));
- if(!OC_Contacts_VCard::edit($id,$card)) {
+ if(!OC_Contacts_VCard::edit($id, $card)) {
bailOut(OC_Contacts_App::$l10n->t('Error saving contact.'));
}
$tmpl = new OCP\Template("contacts", "part.contactphoto");
diff --git a/apps/contacts/ajax/saveproperty.php b/apps/contacts/ajax/saveproperty.php
index 34fc3cc5351..5d743c99df4 100644
--- a/apps/contacts/ajax/saveproperty.php
+++ b/apps/contacts/ajax/saveproperty.php
@@ -19,7 +19,7 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
-require_once('loghandler.php');
+require_once 'loghandler.php';
// Check if we are a user
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
@@ -39,9 +39,11 @@ if(!$id) {
if(!$checksum) {
bailOut(OC_Contacts_App::$l10n->t('checksum is not set.'));
}
-if(is_array($value)){
+if(is_array($value)) {
$value = array_map('strip_tags', $value);
- ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
+ // NOTE: Important, otherwise the compound value will be
+ // set in the order the fields appear in the form!
+ ksort($value);
//if($name == 'CATEGORIES') {
// $value = OC_Contacts_VCard::escapeDelimiters($value, ',');
//} else {
@@ -66,8 +68,7 @@ if($element != $name) {
switch($element) {
case 'BDAY':
$date = New DateTime($value);
- //$vcard->setDateTime('BDAY', $date, Sabre_VObject_Element_DateTime::DATE);
- $value = $date->format(DateTime::ATOM);
+ $value = $date->format('Y-m-d');
break;
case 'FN':
if(!$value) {
@@ -89,6 +90,14 @@ if(!$value) {
} else {
/* setting value */
switch($element) {
+ case 'BDAY':
+ // I don't use setDateTime() because that formats it as YYYYMMDD instead of YYYY-MM-DD
+ // which is what the RFC recommends.
+ $vcard->children[$line]->setValue($value);
+ $vcard->children[$line]->parameters = array();
+ $vcard->children[$line]->add(new Sabre_VObject_Parameter('VALUE', 'DATE'));
+ debug('Setting value:'.$name.' '.$vcard->children[$line]);
+ break;
case 'CATEGORIES':
debug('Setting string:'.$name.' '.$value);
$vcard->children[$line]->setValue($value);
@@ -120,7 +129,7 @@ if(!$value) {
}
//debug('New checksum: '.$checksum);
-if(!OC_Contacts_VCard::edit($id,$vcard)) {
+if(!OC_Contacts_VCard::edit($id, $vcard)) {
bailOut(OC_Contacts_App::$l10n->t('Error updating contact property.'));
exit();
}
diff --git a/apps/contacts/ajax/selectaddressbook.php b/apps/contacts/ajax/selectaddressbook.php
new file mode 100644
index 00000000000..6c35d08c829
--- /dev/null
+++ b/apps/contacts/ajax/selectaddressbook.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright (c) 2011 Thomas Tanghus <thomas@tanghus.net>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+OCP\JSON::checkLoggedIn();
+OCP\JSON::checkAppEnabled('contacts');
+
+$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser());
+$tmpl = new OCP\Template("contacts", "part.selectaddressbook");
+$tmpl->assign('addressbooks', $addressbooks);
+$page = $tmpl->fetchPage();
+OCP\JSON::success(array('data' => array('page' => $page )));
diff --git a/apps/contacts/ajax/updateaddressbook.php b/apps/contacts/ajax/updateaddressbook.php
index d3a772c727f..a14b2158431 100644
--- a/apps/contacts/ajax/updateaddressbook.php
+++ b/apps/contacts/ajax/updateaddressbook.php
@@ -11,7 +11,7 @@
// Check if we are a user
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
-require_once('loghandler.php');
+require_once 'loghandler.php';
$bookid = $_POST['id'];
OC_Contacts_App::getAddressbook($bookid); // is owner access check
diff --git a/apps/contacts/ajax/uploadimport.php b/apps/contacts/ajax/uploadimport.php
index 9511520828f..87032b731a5 100644
--- a/apps/contacts/ajax/uploadimport.php
+++ b/apps/contacts/ajax/uploadimport.php
@@ -24,52 +24,57 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('contacts');
OCP\JSON::callCheck();
-require_once('loghandler.php');
+require_once 'loghandler.php';
+
+$l10n = OC_Contacts_App::$l10n;
$view = OCP\Files::getStorage('contacts');
+if(!$view->file_exists('imports')) {
+ $view->mkdir('imports');
+}
$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) {
- if($view->file_put_contents('/'.$tmpfile, file_get_contents('php://input'))) {
- OCP\JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+ if($view->file_put_contents('/imports/'.$fn, file_get_contents('php://input'))) {
+ OCP\JSON::success(array('data' => array('file'=>$tmpfile, 'name'=>$fn)));
exit();
} else {
- bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
+ bailOut($l10n->t('Error uploading contacts to storage.'));
}
}
// File input transfers are handled here
if (!isset($_FILES['importfile'])) {
- OCP\Util::writeLog('contacts','ajax/uploadphoto.php: No file was uploaded. Unknown error.', OCP\Util::DEBUG);
- OCP\JSON::error(array('data' => array( 'message' => 'No file was uploaded. Unknown error' )));
+ OCP\Util::writeLog('contacts',
+ 'ajax/uploadphoto.php: No file was uploaded. Unknown error.',
+ OCP\Util::DEBUG);
+ OCP\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")
+ 0=>$l10n->t("There is no error, the file uploaded with success"),
+ 1=>$l10n->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
+ 2=>$l10n->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
+ 3=>$l10n->t("The uploaded file was only partially uploaded"),
+ 4=>$l10n->t("No file was uploaded"),
+ 6=>$l10n->t("Missing a temporary folder")
);
bailOut($errors[$error]);
}
$file=$_FILES['importfile'];
-$tmpfname = tempnam(get_temp_dir(), "occOrig");
if(file_exists($file['tmp_name'])) {
- if($view->file_put_contents('/'.$tmpfile, file_get_contents($file['tmp_name']))) {
- OCP\JSON::success(array('data' => array('path'=>'', 'file'=>$tmpfile)));
+ if($view->file_put_contents('/imports/'.$file['name'], file_get_contents($file['tmp_name']))) {
+ OCP\JSON::success(array('data' => array('file'=>$file['name'], 'name'=>$file['name'])));
} else {
- bailOut(OC_Contacts_App::$l10n->t('Error uploading contacts to storage.'));
+ bailOut($l10n->t('Error uploading contacts to storage.'));
}
} else {
bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?');
}
-
-
-?>
diff --git a/apps/contacts/ajax/uploadphoto.php b/apps/contacts/ajax/uploadphoto.php
index 8545ca84eee..4cd38db8c72 100644
--- a/apps/contacts/ajax/uploadphoto.php
+++ b/apps/contacts/ajax/uploadphoto.php
@@ -27,13 +27,13 @@ OCP\JSON::callCheck();
// Firefox and Konqueror tries to download application/json for me. --Arthur
OCP\JSON::setContentTypeHeader('text/plain');
-require_once('loghandler.php');
-
+require_once 'loghandler.php';
+$l10n = OC_Contacts_App::$l10n;
// 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) {
if (!isset($_GET['id'])) {
- bailOut(OC_Contacts_App::$l10n->t('No contact ID was submitted.'));
+ bailOut($l10n->t('No contact ID was submitted.'));
}
$id = $_GET['id'];
$tmpkey = 'contact-photo-'.md5($fn);
@@ -48,33 +48,38 @@ if ($fn) {
debug('Couldn\'t save correct image orientation: '.$tmpkey);
}
if(OC_Cache::set($tmpkey, $image->data(), 600)) {
- OCP\JSON::success(array('data' => array('mime'=>$_SERVER['CONTENT_TYPE'], 'name'=>$fn, 'id'=>$id, 'tmp'=>$tmpkey)));
+ OCP\JSON::success(array(
+ 'data' => array(
+ 'mime'=>$_SERVER['CONTENT_TYPE'],
+ 'name'=>$fn,
+ 'id'=>$id,
+ 'tmp'=>$tmpkey)));
exit();
} else {
- bailOut(OC_Contacts_App::$l10n->t('Couldn\'t save temporary image: ').$tmpkey);
+ bailOut($l10n->t('Couldn\'t save temporary image: ').$tmpkey);
}
} else {
- bailOut(OC_Contacts_App::$l10n->t('Couldn\'t load temporary image: ').$tmpkey);
+ bailOut($l10n->t('Couldn\'t load temporary image: ').$tmpkey);
}
}
// Uploads from file dialog are handled here.
if (!isset($_POST['id'])) {
- bailOut(OC_Contacts_App::$l10n->t('No contact ID was submitted.'));
+ bailOut($l10n->t('No contact ID was submitted.'));
}
if (!isset($_FILES['imagefile'])) {
- bailOut(OC_Contacts_App::$l10n->t('No file was uploaded. Unknown error'));
+ bailOut($l10n->t('No file was uploaded. Unknown error'));
}
$error = $_FILES['imagefile']['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")
+ 0=>$l10n->t("There is no error, the file uploaded with success"),
+ 1=>$l10n->t("The uploaded file exceeds the upload_max_filesize directive in php.ini").ini_get('upload_max_filesize'),
+ 2=>$l10n->t("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"),
+ 3=>$l10n->t("The uploaded file was only partially uploaded"),
+ 4=>$l10n->t("No file was uploaded"),
+ 6=>$l10n->t("Missing a temporary folder")
);
bailOut($errors[$error]);
}
@@ -91,15 +96,21 @@ if(file_exists($file['tmp_name'])) {
debug('Couldn\'t save correct image orientation: '.$tmpkey);
}
if(OC_Cache::set($tmpkey, $image->data(), 600)) {
- OCP\JSON::success(array('data' => array('mime'=>$file['type'],'size'=>$file['size'],'name'=>$file['name'], 'id'=>$_POST['id'], 'tmp'=>$tmpkey)));
+ OCP\JSON::success(array(
+ 'data' => array(
+ 'mime'=>$file['type'],
+ 'size'=>$file['size'],
+ 'name'=>$file['name'],
+ 'id'=>$_POST['id'],
+ 'tmp'=>$tmpkey,
+ )));
exit();
} else {
- bailOut(OC_Contacts_App::$l10n->t('Couldn\'t save temporary image: ').$tmpkey);
+ bailOut($l10n->t('Couldn\'t save temporary image: ').$tmpkey);
}
} else {
- bailOut(OC_Contacts_App::$l10n->t('Couldn\'t load temporary image: ').$file['tmp_name']);
+ bailOut($l10n->t('Couldn\'t load temporary image: ').$file['tmp_name']);
}
} else {
bailOut('Temporary file: \''.$file['tmp_name'].'\' has gone AWOL?');
}
-?>
diff --git a/apps/contacts/appinfo/app.php b/apps/contacts/appinfo/app.php
index 64fe00eef10..cbbbbc79e58 100644
--- a/apps/contacts/appinfo/app.php
+++ b/apps/contacts/appinfo/app.php
@@ -4,6 +4,7 @@ OC::$CLASSPATH['OC_Contacts_Addressbook'] = 'apps/contacts/lib/addressbook.php';
OC::$CLASSPATH['OC_Contacts_VCard'] = 'apps/contacts/lib/vcard.php';
OC::$CLASSPATH['OC_Contacts_Hooks'] = 'apps/contacts/lib/hooks.php';
OC::$CLASSPATH['OC_Connector_Sabre_CardDAV'] = 'apps/contacts/lib/connector_sabre.php';
+OC::$CLASSPATH['Sabre_CardDAV_VCFExportPlugin'] = 'apps/contacts/lib/VCFExportPlugin.php';
OC::$CLASSPATH['OC_Search_Provider_Contacts'] = 'apps/contacts/lib/search.php';
OCP\Util::connectHook('OC_User', 'post_createUser', 'OC_Contacts_Hooks', 'createUser');
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Contacts_Hooks', 'deleteUser');
@@ -18,6 +19,6 @@ OCP\App::addNavigationEntry( array(
'name' => OC_L10N::get('contacts')->t('Contacts') ));
-OCP\App::registerPersonal('contacts','settings');
+OCP\App::registerPersonal('contacts', 'settings');
OCP\Util::addscript('contacts', 'loader');
OC_Search::registerProvider('OC_Search_Provider_Contacts');
diff --git a/apps/contacts/appinfo/database.xml b/apps/contacts/appinfo/database.xml
index 9b269d765dc..b814b0f1516 100644
--- a/apps/contacts/appinfo/database.xml
+++ b/apps/contacts/appinfo/database.xml
@@ -44,7 +44,7 @@
<type>text</type>
<default></default>
<notnull>false</notnull>
- <length>100</length>
+ <length>200</length>
</field>
<field>
@@ -118,7 +118,7 @@
<type>text</type>
<default></default>
<notnull>false</notnull>
- <length>100</length>
+ <length>200</length>
</field>
<field>
diff --git a/apps/contacts/appinfo/migrate.php b/apps/contacts/appinfo/migrate.php
index 02026c5979c..2559b4ea456 100644
--- a/apps/contacts/appinfo/migrate.php
+++ b/apps/contacts/appinfo/migrate.php
@@ -2,7 +2,7 @@
class OC_Migration_Provider_Contacts extends OC_Migration_Provider{
// Create the xml for the user supplied
- function export( ){
+ function export( ) {
$options = array(
'table'=>'contacts_addressbooks',
'matchcol'=>'userid',
@@ -21,9 +21,8 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{
$ids2 = $this->content->copyRows( $options );
// If both returned some ids then they worked
- if( is_array( $ids ) && is_array( $ids2 ) )
- {
- return true;
+ if(is_array($ids) && is_array($ids2)) {
+ return true;
} else {
return false;
}
@@ -31,14 +30,14 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{
}
// Import function for contacts
- function import( ){
- switch( $this->appinfo->version ){
+ function import( ) {
+ switch( $this->appinfo->version ) {
default:
// All versions of the app have had the same db structure, so all can use the same import function
$query = $this->content->prepare( "SELECT * FROM contacts_addressbooks WHERE userid LIKE ?" );
$results = $query->execute( array( $this->olduid ) );
$idmap = array();
- while( $row = $results->fetchRow() ){
+ while( $row = $results->fetchRow() ) {
// Import each addressbook
$addressbookquery = OCP\DB::prepare( "INSERT INTO *PREFIX*contacts_addressbooks (`userid`, `displayname`, `uri`, `description`, `ctag`) VALUES (?, ?, ?, ?, ?)" );
$addressbookquery->execute( array( $this->uid, $row['displayname'], $row['uri'], $row['description'], $row['ctag'] ) );
@@ -48,7 +47,7 @@ class OC_Migration_Provider_Contacts extends OC_Migration_Provider{
OC_Contacts_Addressbook::setActive($idmap[$row['id']], true);
}
// Now tags
- foreach($idmap as $oldid => $newid){
+ foreach($idmap as $oldid => $newid) {
$query = $this->content->prepare( "SELECT * FROM contacts_cards WHERE addressbookid LIKE ?" );
$results = $query->execute( array( $oldid ) );
diff --git a/apps/contacts/appinfo/remote.php b/apps/contacts/appinfo/remote.php
index 5add3bc6889..fd5604aec6f 100644
--- a/apps/contacts/appinfo/remote.php
+++ b/apps/contacts/appinfo/remote.php
@@ -22,7 +22,7 @@
OCP\App::checkAppEnabled('contacts');
-if(substr($_SERVER["REQUEST_URI"],0,strlen(OC_App::getAppWebPath('contacts').'/carddav.php')) == OC_App::getAppWebPath('contacts').'/carddav.php'){
+if(substr($_SERVER["REQUEST_URI"], 0, strlen(OC_App::getAppWebPath('contacts').'/carddav.php')) == OC_App::getAppWebPath('contacts').'/carddav.php') {
$baseuri = OC_App::getAppWebPath('contacts').'/carddav.php';
}
@@ -45,10 +45,11 @@ $nodes = array(
$server = new Sabre_DAV_Server($nodes);
$server->setBaseUri($baseuri);
// Add plugins
-$server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud'));
+$server->addPlugin(new Sabre_DAV_Auth_Plugin($authBackend, 'ownCloud'));
$server->addPlugin(new Sabre_CardDAV_Plugin());
$server->addPlugin(new Sabre_DAVACL_Plugin());
$server->addPlugin(new Sabre_DAV_Browser_Plugin(false)); // Show something in the Browser, but no upload
+$server->addPlugin(new Sabre_CardDAV_VCFExportPlugin());
// And off we go!
$server->exec();
diff --git a/apps/contacts/appinfo/update.php b/apps/contacts/appinfo/update.php
index 873899f578b..21e736bb446 100644
--- a/apps/contacts/appinfo/update.php
+++ b/apps/contacts/appinfo/update.php
@@ -1,7 +1,7 @@
<?php
$installedVersion=OCP\Config::getAppValue('contacts', 'installed_version');
-if (version_compare($installedVersion, '0.2.90', '<')) {
+if (version_compare($installedVersion, '0.2.3', '<')) {
// First set all address books in-active.
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET active=0' );
$result = $stmt->execute(array());
diff --git a/apps/contacts/appinfo/version b/apps/contacts/appinfo/version
index 7dff5b89211..72f9fa82020 100644
--- a/apps/contacts/appinfo/version
+++ b/apps/contacts/appinfo/version
@@ -1 +1 @@
-0.2.1 \ No newline at end of file
+0.2.4 \ No newline at end of file
diff --git a/apps/contacts/carddav.php b/apps/contacts/carddav.php
index e0579e625d7..264eb30836b 100644
--- a/apps/contacts/carddav.php
+++ b/apps/contacts/carddav.php
@@ -1,6 +1,6 @@
<?php
-if(!file_exists('../../lib/base.php')){
+if(!file_exists('../../lib/base.php')) {
die('Please update the path to /lib/base.php in carddav.php or make use of /remote.php/carddav/');
}
-require_once('../../lib/base.php');
-require_once('appinfo/remote.php'); \ No newline at end of file
+require_once '../../lib/base.php';
+require_once 'appinfo/remote.php'; \ No newline at end of file
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index 5b6ccb7638a..ddae27da211 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -5,17 +5,18 @@
#leftcontent a { padding: 0 0 0 25px; }
#rightcontent { top: 3.5em !important; padding-top: 5px; }
#leftcontent h3 { cursor: pointer; -moz-transition: background 300ms ease 0s; background: none no-repeat scroll 1em center #eee; border-bottom: 1px solid #ddd; border-top: 1px solid #fff; display: block; max-width: 100%; padding: 0.5em 0.8em; color: #666; text-shadow: 0 1px 0 #f8f8f8; font-size: 1.2em; }
-#leftcontent h3:hover,#leftcontent h3:active,#leftcontent h3.active { background-color: #DBDBDB; border-bottom: 1px solid #CCCCCC; border-top: 1px solid #D4D4D4; color: #333333; }
+#leftcontent h3:hover,#leftcontent h3:active,#leftcontent h3.active { background-color: #DBDBDB; border-bottom: 1px solid #CCCCCC; border-top: 1px solid #D4D4D4; color: #333333; font-weight: bold; }
#contacts { position: fixed; background: #fff; max-width: 100%; width: 20em; left: 12.5em; top: 3.7em; bottom: 3em; overflow: auto; padding: 0; margin: 0; }
.contacts a { height: 23px; display: block; left: 12.5em; margin: 0 0 0 0; padding: 0 0 0 25px; }
.contacts li.ui-draggable { height: 23px; }
-.ui-draggable-dragging { width: 16em; }
+.ui-draggable-dragging { width: 17em; cursor: move; }
.ui-state-hover { border: 1px solid dashed; }
#bottomcontrols { padding: 0; bottom:0px; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;}
#bottomcontrols img { margin-top: 0.35em; }
-#contacts_newcontact { float: left; margin: 0.2em 0 0 1em; }
+#uploadprogressbar { display: none; padding: 0; bottom: 3em; height:2em; width: 20em; margin:0; background:#eee; border:1px solid #ccc; position:fixed; }
+#contacts_newcontact, #contacts_import, #chooseaddressbook { float: left; margin: 0.2em 0 0 1em; border: 0 none; border-radius: 0; -moz-box-shadow: none; box-shadow: none; outline: 0 none; }
#chooseaddressbook { float: right; margin: 0.2em 1em 0 0; }
-#actionbar { position: relative; clear: both; height: 30px;}
+#actionbar { clear: both; height: 30px;}
#contacts_deletecard {position:relative; float:left; background:url('%webroot%/core/img/actions/delete.svg') no-repeat center; }
#contacts_downloadcard {position:relative; float:left; background:url('%webroot%/core/img/actions/download.svg') no-repeat center; }
#contacts_propertymenu { clear: left; float:left; max-width: 15em; margin: 2em; }
@@ -71,7 +72,7 @@ label:hover, dt:hover { color: #333; }
#identityprops { /*position: absolute; top: 2.5em; left: 0px;*/ }
/*#contact_photo { max-width: 250px; }*/
#contact_identity { min-width: 30em; }
-.contactsection { position: relative; float: left; /*max-width: 40em;*/ padding: 0.5em; height: auto: border: thin solid lightgray;/* -webkit-border-radius: 0.5em; -moz-border-radius: 0.5em; border-radius: 0.5em; background-color: #f8f8f8;*/ }
+.contactsection { position: relative; float: left; padding: 0.5em; height: auto; }
#cropbox { margin: auto; }
#contacts_details_photo_wrapper { width: 200px; }
@@ -110,7 +111,7 @@ dl.addresscard .action { float: right; }
#file_upload_form { width: 0; height: 0; }
#file_upload_target, #import_upload_target, #crop_target { display:none; }
#file_upload_start, #import_upload_start { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; z-index:1001; width:0; height:0;}
-#import_upload_start { width: 16px; height: 16px; margin: 0 0 0 0; }
+#import_upload_start { width: 20px; height: 20px; margin: 0 0 -24px 0; padding: 0;}
input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.big { font-weight:bold; font-size:1.2em; }
.huge { font-weight:bold; font-size:1.5em; }
@@ -124,3 +125,12 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.typelist[type="button"] { float: left; max-width: 10em; border: 0; background-color: #fff; color: #bbb} /* for multiselect */
.typelist[type="button"]:hover { color: #777; } /* for multiselect */
.addresslist { clear: both; font-weight: bold; }
+#ninjahelp { position: absolute; bottom: 0; left: 0; right: 0; padding: 1em; margin: 1em; border: thin solid #eee; border-radius: 5px; background-color: #DBDBDB; opacity: 0.9; }
+#ninjahelp .close { position: absolute; top: 5px; right: 5px; height: 20px; width: 20px; }
+#ninjahelp h2, .help-section h3 { width: 100%; font-weight: bold; text-align: center; }
+#ninjahelp h2 { font-size: 1.4em; }
+.help-section { width: 45%; min-width: 35em; float: left; }
+.help-section h3 { font-size: 1.2em; }
+.help-section dl { width: 100%; float: left; clear: right; margin: 0; padding: 0; cursor: normal; }
+.help-section dt { display: table-cell; clear: left; float: left; width: 35%; margin: 0; padding: 0.2em; text-align: right; text-overflow: ellipsis; vertical-align: text-bottom; font-weight: bold: }
+.help-section dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0.2em; white-space: nowrap; vertical-align: text-bottom; }
diff --git a/apps/contacts/export.php b/apps/contacts/export.php
index 58fdb040a5c..161ca8047ac 100644
--- a/apps/contacts/export.php
+++ b/apps/contacts/export.php
@@ -9,27 +9,30 @@
OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('contacts');
-$bookid = isset($_GET['bookid']) ? $_GET['bookid'] : NULL;
-$contactid = isset($_GET['contactid']) ? $_GET['contactid'] : NULL;
+$bookid = isset($_GET['bookid']) ? $_GET['bookid'] : null;
+$contactid = isset($_GET['contactid']) ? $_GET['contactid'] : null;
$nl = "\n";
-if(isset($bookid)){
+if(isset($bookid)) {
$addressbook = OC_Contacts_App::getAddressbook($bookid);
//$cardobjects = OC_Contacts_VCard::all($bookid);
header('Content-Type: text/directory');
- header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $addressbook['displayname']) . '.vcf');
+ header('Content-Disposition: inline; filename='
+ . str_replace(' ', '_', $addressbook['displayname']) . '.vcf');
$start = 0;
- $batchsize = OCP\Config::getUserValue(OCP\User::getUser(), 'contacts', 'export_batch_size', 20);
+ $batchsize = OCP\Config::getUserValue(OCP\User::getUser(),
+ 'contacts',
+ 'export_batch_size', 20);
while($cardobjects = OC_Contacts_VCard::all($bookid, $start, $batchsize)){
foreach($cardobjects as $card) {
echo $card['carddata'] . $nl;
}
$start += $batchsize;
}
-}elseif(isset($contactid)){
+}elseif(isset($contactid)) {
$data = OC_Contacts_App::getContactObject($contactid);
header('Content-Type: text/vcard');
- header('Content-Disposition: inline; filename=' . str_replace(' ', '_', $data['fullname']) . '.vcf');
+ header('Content-Disposition: inline; filename='
+ . str_replace(' ', '_', $data['fullname']) . '.vcf');
echo $data['carddata'];
}
-?>
diff --git a/apps/contacts/import.php b/apps/contacts/import.php
index c95fd970fe1..1986d79f6d6 100644
--- a/apps/contacts/import.php
+++ b/apps/contacts/import.php
@@ -30,37 +30,51 @@ writeProgress('10');
$view = $file = null;
if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
$view = OCP\Files::getStorage('contacts');
- $file = $view->file_get_contents('/' . $_POST['file']);
+ $file = $view->file_get_contents('/imports/' . $_POST['file']);
} else {
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
}
if(!$file) {
- OCP\JSON::error(array('message' => 'Import file was empty.'));
+ OCP\JSON::error(array('data' => array('message' => 'Import file was empty.')));
exit();
}
-if(isset($_POST['method']) && $_POST['method'] == 'new'){
- $id = OC_Contacts_Addressbook::add(OCP\USER::getUser(), $_POST['addressbookname']);
+if(isset($_POST['method']) && $_POST['method'] == 'new') {
+ $id = OC_Contacts_Addressbook::add(OCP\USER::getUser(),
+ $_POST['addressbookname']);
if(!$id) {
- OCP\JSON::error(array('message' => 'Error creating address book.'));
+ OCP\JSON::error(
+ array(
+ 'data' => array('message' => 'Error creating address book.')
+ )
+ );
exit();
}
OC_Contacts_Addressbook::setActive($id, 1);
}else{
$id = $_POST['id'];
if(!$id) {
- OCP\JSON::error(array('message' => 'Error getting the ID of the address book.'));
+ OCP\JSON::error(
+ array(
+ 'data' => array(
+ 'message' => 'Error getting the ID of the address book.',
+ 'file'=>$_POST['file']
+ )
+ )
+ );
exit();
}
OC_Contacts_App::getAddressbook($id); // is owner access check
}
//analyse the contacts file
writeProgress('40');
+$file = str_replace(array("\r","\n\n"), array("\n","\n"), $file);
$lines = explode($nl, $file);
+
$inelement = false;
$parts = array();
$card = array();
foreach($lines as $line){
- if(strtoupper(trim($line)) == 'BEGIN:VCARD'){
+ if(strtoupper(trim($line)) == 'BEGIN:VCARD') {
$inelement = true;
} elseif (strtoupper(trim($line)) == 'END:VCARD') {
$card[] = $line;
@@ -77,21 +91,40 @@ writeProgress('70');
$imported = 0;
$failed = 0;
if(!count($parts) > 0) {
- OCP\JSON::error(array('message' => 'No contacts to import in .'.$_POST['file'].' Please check if the file is corrupted.'));
+ OCP\JSON::error(
+ array(
+ 'data' => array(
+ 'message' => 'No contacts to import in '
+ . $_POST['file'].'. Please check if the file is corrupted.',
+ 'file'=>$_POST['file']
+ )
+ )
+ );
+ if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
+ if(!$view->unlink('/imports/' . $_POST['file'])) {
+ OCP\Util::writeLog('contacts',
+ 'Import: Error unlinking OC_FilesystemView ' . '/' . $_POST['file'],
+ OCP\Util::ERROR);
+ }
+ }
exit();
}
foreach($parts as $part){
$card = OC_VObject::parse($part);
if (!$card) {
$failed += 1;
- OCP\Util::writeLog('contacts','Import: skipping card. Error parsing VCard: '.$part, OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',
+ 'Import: skipping card. Error parsing VCard: ' . $part,
+ OCP\Util::ERROR);
continue; // Ditch cards that can't be parsed by Sabre.
}
try {
OC_Contacts_VCard::add($id, $card);
$imported += 1;
} catch (Exception $e) {
- OCP\Util::writeLog('contacts', 'Error importing vcard: '.$e->getMessage().$nl.$card, OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',
+ 'Error importing vcard: ' . $e->getMessage() . $nl . $card,
+ OCP\Util::ERROR);
$failed += 1;
}
}
@@ -100,8 +133,18 @@ writeProgress('100');
sleep(3);
OC_Cache::remove($progresskey);
if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
- if(!$view->unlink('/' . $_POST['file'])) {
- OCP\Util::writeLog('contacts','Import: Error unlinking OC_FilesystemView ' . '/' . $_POST['file'], OCP\Util::ERROR);
+ if(!$view->unlink('/imports/' . $_POST['file'])) {
+ OCP\Util::writeLog('contacts',
+ 'Import: Error unlinking OC_FilesystemView ' . '/' . $_POST['file'],
+ OCP\Util::ERROR);
}
}
-OCP\JSON::success(array('data' => array('imported'=>$imported, 'failed'=>$failed)));
+OCP\JSON::success(
+ array(
+ 'data' => array(
+ 'imported'=>$imported,
+ 'failed'=>$failed,
+ 'file'=>$_POST['file'],
+ )
+ )
+);
diff --git a/apps/contacts/index.php b/apps/contacts/index.php
index 0b4f89b30c0..c35e1b85d4e 100644
--- a/apps/contacts/index.php
+++ b/apps/contacts/index.php
@@ -14,28 +14,20 @@ OCP\App::checkAppEnabled('contacts');
// Get active address books. This creates a default one if none exists.
$ids = OC_Contacts_Addressbook::activeIds(OCP\USER::getUser());
-$contacts = OC_Contacts_VCard::all($ids);
-if($contacts === false) {
- OCP\Util::writeLog('contacts','index.html: No contacts found.',OCP\Util::DEBUG);
+$has_contacts = (count(OC_Contacts_VCard::all($ids, 0, 1)) > 0
+ ? true
+ : false); // just to check if there are any contacts.
+if($has_contacts === false) {
+ OCP\Util::writeLog('contacts',
+ 'index.html: No contacts found.',
+ OCP\Util::DEBUG);
}
-$addressbooks = OC_Contacts_Addressbook::active(OCP\USER::getUser());
-
// Load the files we need
-OCP\App::setActiveNavigationEntry( 'contacts_index' );
+OCP\App::setActiveNavigationEntry('contacts_index');
// Load a specific user?
$id = isset( $_GET['id'] ) ? $_GET['id'] : null;
-$details = array();
-
-if(is_null($id) && count($contacts) > 0) {
- $id = $contacts[0]['id'];
-}
-unset($contacts);
-if(!is_null($id)) {
- $vcard = OC_Contacts_App::getContactVCard($id);
- $details = OC_Contacts_VCard::structureContact($vcard);
-}
$property_types = OC_Contacts_App::getAddPropertyOptions();
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
$email_types = OC_Contacts_App::getTypesOfProperty('EMAIL');
@@ -46,32 +38,31 @@ $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size'));
$maxUploadFilesize = min($upload_max_filesize, $post_max_size);
$freeSpace=OC_Filesystem::free_space('/');
-$freeSpace=max($freeSpace,0);
-$maxUploadFilesize = min($maxUploadFilesize ,$freeSpace);
+$freeSpace=max($freeSpace, 0);
+$maxUploadFilesize = min($maxUploadFilesize, $freeSpace);
-OCP\Util::addscript('','jquery.multiselect');
-OCP\Util::addscript('','oc-vcategories');
-OCP\Util::addscript('contacts','contacts');
-OCP\Util::addscript('contacts','expanding');
-OCP\Util::addscript('contacts','jquery.combobox');
-OCP\Util::addscript('contacts','jquery.inview');
-OCP\Util::addscript('contacts','jquery.Jcrop');
-OCP\Util::addscript('contacts','jquery.multi-autocomplete');
-OCP\Util::addStyle('','jquery.multiselect');
-OCP\Util::addStyle('contacts','jquery.combobox');
-OCP\Util::addStyle('contacts','jquery.Jcrop');
-OCP\Util::addStyle('contacts','contacts');
+OCP\Util::addscript('', 'jquery.multiselect');
+OCP\Util::addscript('', 'oc-vcategories');
+OCP\Util::addscript('contacts', 'contacts');
+OCP\Util::addscript('contacts', 'expanding');
+OCP\Util::addscript('contacts', 'jquery.combobox');
+OCP\Util::addscript('files', 'jquery.fileupload');
+OCP\Util::addscript('contacts', 'jquery.inview');
+OCP\Util::addscript('contacts', 'jquery.Jcrop');
+OCP\Util::addscript('contacts', 'jquery.multi-autocomplete');
+OCP\Util::addStyle('', 'jquery.multiselect');
+OCP\Util::addStyle('contacts', 'jquery.combobox');
+OCP\Util::addStyle('contacts', 'jquery.Jcrop');
+OCP\Util::addStyle('contacts', 'contacts');
$tmpl = new OCP\Template( "contacts", "index", "user" );
-$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
-$tmpl->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
-$tmpl->assign('property_types', $property_types);
-$tmpl->assign('phone_types', $phone_types);
-$tmpl->assign('email_types', $email_types);
-$tmpl->assign('categories', $categories);
-$tmpl->assign('addressbooks', $addressbooks);
-$tmpl->assign('details', $details );
-$tmpl->assign('id',$id);
+$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize, false);
+$tmpl->assign('uploadMaxHumanFilesize',
+ OCP\Util::humanFileSize($maxUploadFilesize), false);
+$tmpl->assign('property_types', $property_types, false);
+$tmpl->assign('phone_types', $phone_types, false);
+$tmpl->assign('email_types', $email_types, false);
+$tmpl->assign('categories', $categories, false);
+$tmpl->assign('has_contacts', $has_contacts, false);
+$tmpl->assign('id', $id, false);
$tmpl->printPage();
-
-?>
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index 39ef14e5062..4c6c8bf3d93 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -12,13 +12,42 @@ String.prototype.strip_tags = function(){
Contacts={
UI:{
- notification:function(msg, ndata) {
- $('#notification').text(msg);
- if(data) {
- $('#notification').data(ndata[0],ndata[1]);
+ /**
+ * Arguments:
+ * message: The text message to show. The only mandatory parameter.
+ * timeout: The timeout in seconds before the notification disappears. Default 10.
+ * timeouthandler: A function to run on timeout.
+ * clickhandler: A function to run on click. If a timeouthandler is given it will be cancelled.
+ * data: An object that will be passed as argument to the timeouthandler and clickhandler functions.
+ */
+ notify:function(params) {
+ self = this;
+ if(!self.notifier) {
+ self.notifier = $('#notification');
+ }
+ self.notifier.text(params.message);
+ self.notifier.fadeIn();
+ self.notifier.on('click', function() { $(this).fadeOut();});
+ var timer = setTimeout(function() {
+ self.notifier.fadeOut();
+ if(params.timeouthandler && $.isFunction(params.timeouthandler)) {
+ params.timeouthandler(self.notifier.data(dataid));
+ self.notifier.off('click');
+ self.notifier.removeData(dataid);
+ }
+ }, params.timeout && $.isNumeric(params.timeout) ? parseInt(params.timeout)*1000 : 10000);
+ var dataid = timer.toString();
+ if(params.data) {
+ self.notifier.data(dataid, params.data);
+ }
+ if(params.clickhandler && $.isFunction(params.clickhandler)) {
+ self.notifier.on('click', function() {
+ clearTimeout(timer);
+ self.notifier.off('click');
+ params.clickhandler(self.notifier.data(dataid));
+ self.notifier.removeData(dataid);
+ });
}
- $('#notification').fadeIn();
- setTimeout($('#notification').fadeOut(), 10000);
},
notImplemented:function() {
OC.dialogs.alert(t('contacts', 'Sorry, this functionality has not been implemented yet'), t('contacts', 'Not implemented'));
@@ -99,7 +128,7 @@ Contacts={
$('.addresscard,.propertylist li,.propertycontainer').hover(
function () {
$(this).find('.globe,.mail,.delete,.edit').animate({ opacity: 1.0 }, 200, function() {});
- },
+ },
function () {
$(this).find('.globe,.mail,.delete,.edit').animate({ opacity: 0.1 }, 200, function() {});
}
@@ -110,7 +139,7 @@ Contacts={
obj.tipsy('hide');
Contacts.UI.Card.deleteProperty(obj, 'single');
}
-
+
var goToUrl = function(obj) {
var url = Contacts.UI.propertyContainerFor(obj).find('#url').val();
if(url != '') {
@@ -118,7 +147,7 @@ Contacts={
newWindow.focus();
}
}
-
+
$('#identityprops a.delete').click( function() { deleteItem($(this)) });
$('#identityprops a.delete').keydown( function() { deleteItem($(this)) });
$('#categories_value a.edit').click( function() { $(this).tipsy('hide');OCCategories.edit(); } );
@@ -143,7 +172,7 @@ Contacts={
});
$('#edit_name').click(function(){Contacts.UI.Card.editName()});
$('#edit_name').keydown(function(){Contacts.UI.Card.editName()});
-
+
$('#phototools li a').click(function() {
$(this).tipsy('hide');
});
@@ -170,13 +199,13 @@ Contacts={
OC.dialogs.filepicker(t('contacts', 'Select photo'), Contacts.UI.Card.cloudPhotoSelected, false, 'image', true);
});
/* Initialize the photo edit dialog */
- $('#edit_photo_dialog').dialog({
+ $('#edit_photo_dialog').dialog({
autoOpen: false, modal: true, height: 'auto', width: 'auto'
});
$('#edit_photo_dialog' ).dialog( 'option', 'buttons', [
{
text: "Ok",
- click: function() {
+ click: function() {
Contacts.UI.Card.savePhoto(this);
$(this).dialog('close');
}
@@ -186,47 +215,28 @@ Contacts={
click: function() { $(this).dialog('close'); }
}
] );
-
- /*$('#fn').blur(function(){
- if($('#fn').val() == '') {
- OC.dialogs.alert(t('contacts','The name field cannot be empty. Please enter a name for this contact.'), t('contacts','Name is empty'), function() { $('#fn').focus(); });
- $('#fn').focus();
- return false;
- }
- });*/
-
+
// Name has changed. Update it and reorder.
- // TODO: Take addressbook into account
$('#fn').change(function(){
var name = $('#fn').val().strip_tags();
- var item = $('.contacts li[data-id="'+Contacts.UI.Card.id+'"]');
+ var item = $('.contacts li[data-id="'+Contacts.UI.Card.id+'"]').detach();
$(item).find('a').html(name);
Contacts.UI.Card.fn = name;
- var added = false;
- $('.contacts li[data-bookid="'+Contacts.UI.Card.bookid+'"]').each(function(){
- if ($(this).text().toLowerCase() > name.toLowerCase()) {
- $(this).before(item).fadeIn('fast');
- added = true;
- return false;
- }
- });
- if(!added) {
- $('#contacts ul[data-id="'+Contacts.UI.Card.bookid+'"]').append(item);
- }
+ Contacts.UI.Contacts.insertContact({contact:item});
Contacts.UI.Contacts.scrollTo(Contacts.UI.Card.id);
});
- $('#contacts_deletecard').click( function() { Contacts.UI.Card.doDelete();return false;} );
- $('#contacts_deletecard').keydown( function(event) {
- if(event.which == 13) {
- Contacts.UI.Card.doDelete();
+ $('#contacts_deletecard').click( function() { Contacts.UI.Card.delayedDelete();return false;} );
+ $('#contacts_deletecard').keydown( function(event) {
+ if(event.which == 13 || event.which == 32) {
+ Contacts.UI.Card.delayedDelete();
}
return false;
});
$('#contacts_downloadcard').click( function() { Contacts.UI.Card.doExport();return false;} );
- $('#contacts_downloadcard').keydown( function(event) {
- if(event.which == 13) {
+ $('#contacts_downloadcard').keydown( function(event) {
+ if(event.which == 13 || event.which == 32) {
Contacts.UI.Card.doExport();
}
return false;
@@ -240,12 +250,12 @@ Contacts={
$('#contacts_details_photo_wrapper').bind('dragover',function(event){
$(event.target).addClass('droppable');
event.stopPropagation();
- event.preventDefault();
+ event.preventDefault();
});
$('#contacts_details_photo_wrapper').bind('dragleave',function(event){
$(event.target).removeClass('droppable');
//event.stopPropagation();
- //event.preventDefault();
+ //event.preventDefault();
});
$('#contacts_details_photo_wrapper').bind('drop',function(event){
event.stopPropagation();
@@ -258,7 +268,7 @@ Contacts={
$('#contacts_deletecard').tipsy({gravity: 'ne'});
$('#contacts_downloadcard').tipsy({gravity: 'ne'});
$('#contacts_propertymenu_button').tipsy();
- $('#contacts_newcontact, #chooseaddressbook').tipsy({gravity: 'sw'});
+ $('#contacts_newcontact, #contacts_import, #chooseaddressbook').tipsy({gravity: 'sw'});
$('body').click(function(e){
if(!$(e.target).is('#contacts_propertymenu_button')) {
@@ -285,48 +295,64 @@ Contacts={
$('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem);
},
Card:{
- id:'',
- fn:'',
- fullname:'',
- shortname:'',
- famname:'',
- givname:'',
- addname:'',
- honpre:'',
- honsuf:'',
- data:undefined,
- update:function(id, bookid) {
- var newid, firstitem;
- if(!id) {
+ update:function(params) { // params {cid:int, aid:int}
+ if(!params) { params = {}; }
+ $('#contacts li,#contacts h3').removeClass('active');
+ console.log('Card, cid: ' + params.cid + ' aid: ' + params.aid);
+ var newid, bookid, firstitem;
+ if(!parseInt(params.cid) && !parseInt(params.aid)) {
firstitem = $('#contacts ul').first().find('li:first-child');
if(firstitem.length > 0) {
- newid = firstitem.data('id');
- bookid = firstitem.data('bookid');
+ newid = parseInt(firstitem.data('id'));
+ bookid = parseInt(firstitem.data('bookid'));
+ }
+ } else if(!parseInt(params.cid) && parseInt(params.aid)) {
+ bookid = parseInt(params.aid);
+ newid = parseInt($('#contacts').find('li[data-bookid="'+bookid+'"]').first().data('id'));
+ } else if(parseInt(params.cid) && !parseInt(params.aid)) {
+ newid = parseInt(params.cid);
+ var listitem = Contacts.UI.Contacts.getContact(newid); //$('#contacts li[data-id="'+newid+'"]');
+ console.log('Is contact in list? ' + listitem.length);
+ if(listitem.length) {
+ //bookid = parseInt($('#contacts li[data-id="'+newid+'"]').data('bookid'));
+ bookid = parseInt(Contacts.UI.Contacts.getContact(newid).data('bookid'));
+ } else { // contact isn't in list yet.
+ bookid = 'unknown';
}
} else {
- newid = id;
- bookid = bookid?bookid:$('#contacts li[data-id="'+newid+'"]').data('bookid');
+ newid = parseInt(params.cid);
+ bookid = parseInt(params.aid);
}
- if(!bookid) {
- bookid = $('#contacts h3').first().data('id');
+ if(!bookid || !newid) {
+ bookid = parseInt($('#contacts h3').first().data('id'));
+ newid = parseInt($('#contacts').find('li[data-bookid="'+bookid+'"]').first().data('id'));
}
- console.log('bookid: ' +bookid);
+ console.log('newid: ' + newid + ' bookid: ' +bookid);
var localLoadContact = function(newid, bookid) {
if($('.contacts li').length > 0) {
- $('#contacts li[data-id="'+newid+'"]').addClass('active');
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':newid},function(jsondata){
if(jsondata.status == 'success'){
- $('#contacts h3[data-id="'+bookid+'"]').trigger('click');
+ if(bookid == 'unknown') {
+ bookid = jsondata.data.addressbookid;
+ var contact = Contacts.UI.Contacts.insertContact({
+ contactlist:$('#contacts ul[data-id="'+bookid+'"]'),
+ data:jsondata.data
+ });
+ }
+ $('#contacts li[data-id="'+newid+'"],#contacts h3[data-id="'+bookid+'"]').addClass('active');
+ $('#contacts ul[data-id="'+bookid+'"]').slideDown(300);
Contacts.UI.Card.loadContact(jsondata.data, bookid);
+ Contacts.UI.Contacts.scrollTo(newid);
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
}
-
+
// Make sure proper DOM is loaded.
- if(!$('#card')[0] && newid) {
+ if(!$('#card').length && newid) {
+ console.log('Loading card DOM');
$.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{requesttoken:requesttoken},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').html(jsondata.data.page).ready(function() {
@@ -339,6 +365,7 @@ Contacts={
});
}
else if(!newid) {
+ console.log('Loading intro');
// load intro page
$.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
if(jsondata.status == 'success'){
@@ -357,19 +384,14 @@ Contacts={
doExport:function() {
document.location.href = OC.linkTo('contacts', 'export.php') + '?contactid=' + this.id;
},
- doImport:function(){
- Contacts.UI.notImplemented();
- },
editNew:function(){ // add a new contact
this.id = ''; this.fn = ''; this.fullname = ''; this.givname = ''; this.famname = ''; this.addname = ''; this.honpre = ''; this.honsuf = '';
//Contacts.UI.Card.add(t('contacts', 'Contact')+';'+t('contacts', 'New')+';;;', t('contacts', 'New Contact'), '', true);
Contacts.UI.Card.add(';;;;;', '', '', true);
return false;
},
- createEntry:function(data) {
- return $('<li data-id="'+data.id+'" data-bookid="'+data.addressbookid+'" role="button"><a href="'+OC.linkTo('contacts', 'index.php')+'&id='+data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+data.id+') no-repeat scroll 0% 0% transparent;">'+data.displayname+'</a></li>');
- },
add:function(n, fn, aid, isnew){ // add a new contact
+ console.log('Adding ' + fn);
aid = aid?aid:$('#contacts h3.active').first().data('id');
var localAddcontact = function(n, fn, aid, isnew) {
$.post(OC.filePath('contacts', 'ajax', 'addcontact.php'), { n: n, fn: fn, aid: aid, isnew: isnew },
@@ -381,19 +403,7 @@ Contacts={
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data, aid);
- $('#contacts .active').removeClass('active');
- var item = $('<li data-id="'+jsondata.data.id+'" class="active"><a href="index.php?id='+jsondata.data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+jsondata.data.id+') no-repeat scroll 0% 0% transparent;">'+Contacts.UI.Card.fn+'</a></li>');
- var added = false;
- $('#contacts ul[data-id="'+aid+'"] li').each(function(){
- if ($(this).text().toLowerCase() > Contacts.UI.Card.fn.toLowerCase()) {
- $(this).before(item).fadeIn('fast');
- added = true;
- return false;
- }
- });
- if(!added) {
- $('#contacts ul[data-id="'+aid+'"]').append(item);
- }
+ var item = Contacts.UI.Contacts.insertContact({data:jsondata.data});
if(isnew) { // add some default properties
Contacts.UI.Card.addProperty('EMAIL');
Contacts.UI.Card.addProperty('TEL');
@@ -412,9 +422,9 @@ Contacts={
}
});
}
-
- var card = $('#card')[0];
- if(!card) {
+
+ if(!$('#card').length) {
+ console.log('Loading card DOM');
$.getJSON(OC.filePath('contacts', 'ajax', 'loadcard.php'),{'requesttoken': requesttoken},function(jsondata){
if(jsondata.status == 'success'){
$('#rightcontent').html(jsondata.data.page).ready(function() {
@@ -429,47 +439,63 @@ Contacts={
localAddcontact(n, fn, aid, isnew);
}
},
- doDelete:function() {
+ delayedDelete:function() {
+ /* TODO:
+ $(window).unload(function() {
+ deleteFilesInQueue();
+ });
+ */
$('#contacts_deletecard').tipsy('hide');
- OC.dialogs.confirm(t('contacts', 'Are you sure you want to delete this contact?'), t('contacts', 'Warning'), function(answer) {
- if(answer == true) {
- $.post(OC.filePath('contacts', 'ajax', 'deletecard.php'),{'id':Contacts.UI.Card.id},function(jsondata){
- if(jsondata.status == 'success'){
- var newid = '', bookid;
- var curlistitem = $('#contacts li[data-id="'+jsondata.data.id+'"]');
- var newlistitem = curlistitem.prev('li');
- if(newlistitem == undefined) {
- newlistitem = curlistitem.next('li');
- }
- curlistitem.remove();
- if(!$(newlistitem).is('li')) {
- newid = newlistitem.data('id');
- bookid = newlistitem.data('id');
- }
- $('#rightcontent').data('id',newid);
- this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
- this.data = undefined;
-
- if($('.contacts li').length > 0) { // Load first in list.
- Contacts.UI.Card.update(newid, bookid);
- } else {
- // load intro page
- $.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
- if(jsondata.status == 'success'){
- id = '';
- $('#rightcontent').data('id','');
- $('#rightcontent').html(jsondata.data.page);
- }
- else{
- OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
- }
- });
- }
- }
- else{
- OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
- }
- });
+ var newid = '', bookid;
+ var curlistitem = Contacts.UI.Contacts.getContact(this.id);
+ curlistitem.removeClass('active');
+ var newlistitem = curlistitem.prev('li');
+ if(!newlistitem) {
+ newlistitem = curlistitem.next('li');
+ }
+ curlistitem.detach();
+ if($(newlistitem).is('li')) {
+ newid = newlistitem.data('id');
+ bookid = newlistitem.data('bookid');
+ }
+ $('#rightcontent').data('id', newid);
+
+ with(this) {
+ delete id; delete fn; delete fullname; delete shortname; delete famname;
+ delete givname; delete addname; delete honpre; delete honsuf; delete data;
+ }
+
+ if($('.contacts li').length > 0) {
+ Contacts.UI.Card.update({cid:newid, aid:bookid});
+ } else {
+ // load intro page
+ $.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
+ if(jsondata.status == 'success'){
+ id = '';
+ $('#rightcontent').html(jsondata.data.page).removeData('id');
+ }
+ else{
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
+ }
+ });
+ }
+ Contacts.UI.notify({
+ data:curlistitem,
+ message:t('contacts','Click to undo deletion of "') + curlistitem.find('a').text() + '"',
+ timeouthandler:function(contact) {
+ Contacts.UI.Card.doDelete(contact.data('id'));
+ delete contact;
+ },
+ clickhandler:function(contact) {
+ Contacts.UI.Contacts.insertContact({contact:contact});
+ Contacts.UI.notify({message:t('contacts', 'Cancelled deletion of: "') + curlistitem.find('a').text() + '"'});
+ }
+ });
+ },
+ doDelete:function(id) {
+ $.post(OC.filePath('contacts', 'ajax', 'deletecard.php'),{'id':id},function(jsondata) {
+ if(jsondata.status == 'error'){
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
return false;
@@ -486,21 +512,22 @@ Contacts={
this.loadAddresses();
this.loadSingleProperties();
Contacts.UI.loadListHandlers();
+ var note = $('#note');
if(this.data.NOTE) {
- $('#note').data('checksum', this.data.NOTE[0]['checksum']);
- var note = $('#note').find('textarea');
+ note.data('checksum', this.data.NOTE[0]['checksum']);
+ var textarea = note.find('textarea');
var txt = this.data.NOTE[0]['value'];
var nheight = txt.split('\n').length > 4 ? txt.split('\n').length+2 : 5;
- note.css('min-height', nheight+'em');
- note.attr('rows', nheight);
- note.val(txt);
- $('#note').show();
- note.expandingTextarea();
+ textarea.css('min-height', nheight+'em');
+ textarea.attr('rows', nheight);
+ textarea.val(txt);
+ note.show();
+ textarea.expandingTextarea();
$('#contacts_propertymenu_dropdown a[data-type="NOTE"]').parent().hide();
} else {
- $('#note').data('checksum', '');
- $('#note').find('textarea').val('');
- $('#note').hide();
+ note.removeData('checksum');
+ note.find('textarea').val('');
+ note.hide();
$('#contacts_propertymenu_dropdown a[data-type="NOTE"]').parent().show();
}
},
@@ -521,15 +548,16 @@ Contacts={
$('#contacts_propertymenu_dropdown a[data-type="'+propname+'"]').parent().hide();
var property = this.data[propname][0];
var value = property['value'], checksum = property['checksum'];
-
+
if(propname == 'BDAY') {
var val = $.datepicker.parseDate('yy-mm-dd', value.substring(0, 10));
value = $.datepicker.formatDate('dd-mm-yy', val);
}
- $('#contact_identity').find('#'+propname.toLowerCase()).val(value);
- $('#contact_identity').find('#'+propname.toLowerCase()+'_value').data('checksum', checksum);
- $('#contact_identity').find('#'+propname.toLowerCase()+'_label').show();
- $('#contact_identity').find('#'+propname.toLowerCase()+'_value').show();
+ var identcontainer = $('#contact_identity');
+ identcontainer.find('#'+propname.toLowerCase()).val(value);
+ identcontainer.find('#'+propname.toLowerCase()+'_value').data('checksum', checksum);
+ identcontainer.find('#'+propname.toLowerCase()+'_label').show();
+ identcontainer.find('#'+propname.toLowerCase()+'_value').show();
} else {
$('#contacts_propertymenu_dropdown a[data-type="'+propname+'"]').parent().show();
}
@@ -544,8 +572,12 @@ Contacts={
$(this).find('input').val('');
}
});
- this.fn = ''; this.fullname = ''; this.givname = ''; this.famname = ''; this.addname = ''; this.honpre = ''; this.honsuf = '';
- var narray = undefined;
+
+ with(this) {
+ delete fn; delete fullname; delete givname; delete famname;
+ delete addname; delete honpre; delete honsuf;
+ }
+
if(this.data.FN) {
this.fn = this.data.FN[0]['value'];
}
@@ -586,7 +618,7 @@ Contacts={
$.each(names, function(key, value) {
$('#fn_select')
.append($('<option></option>')
- .text(value));
+ .text(value));
});
$('#fn_select').combobox('value', this.fn);
$('#contact_identity').find('*[data-element="N"]').data('checksum', this.data.N[0]['checksum']);
@@ -660,7 +692,7 @@ Contacts={
return false;
}
container = $(obj).parents('.propertycontainer').first(); // get the parent holding the metadata.
- Contacts.UI.loading(container, true);
+ Contacts.UI.loading(obj, true);
var checksum = container.data('checksum');
var name = container.data('element');
var fields = container.find('input.contacts_property,select.contacts_property').serializeArray();
@@ -683,7 +715,7 @@ Contacts={
var q = container.find('input.contacts_property,select.contacts_property,textarea.contacts_property').serialize();
if(q == '' || q == undefined) {
OC.dialogs.alert(t('contacts', 'Couldn\'t serialize elements.'), t('contacts', 'Error'));
- Contacts.UI.loading(container, false);
+ Contacts.UI.loading(obj, false);
return false;
}
q = q + '&id=' + this.id + '&name=' + name;
@@ -695,13 +727,13 @@ Contacts={
if(jsondata.status == 'success'){
container.data('checksum', jsondata.data.checksum);
Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum);
- Contacts.UI.loading(container, false);
+ Contacts.UI.loading(obj, false);
$(obj).removeAttr('disabled');
return true;
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
- Contacts.UI.loading(container, false);
+ Contacts.UI.loading(obj, false);
$(obj).removeAttr('disabled');
return false;
}
@@ -714,13 +746,13 @@ Contacts={
container.data('checksum', jsondata.data.checksum);
// TODO: savePropertyInternal doesn't know about new fields
//Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum);
- Contacts.UI.loading(container, false);
+ Contacts.UI.loading(obj, false);
$(obj).removeAttr('disabled');
return true;
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
- Contacts.UI.loading(container, false);
+ Contacts.UI.loading(obj, false);
$(obj).removeAttr('disabled');
return false;
}
@@ -729,17 +761,9 @@ Contacts={
},
addProperty:function(type){
switch (type) {
- case 'PHOTO':
- this.loadPhoto(true);
- $('#file_upload_form').show();
- $('#contacts_propertymenu_dropdown a[data-type="'+type+'"]').parent().hide();
- $('#file_upload_start').trigger('click');
- break;
case 'NOTE':
- $('#note').show();
$('#contacts_propertymenu_dropdown a[data-type="'+type+'"]').parent().hide();
- $('#note').find('textarea').expandingTextarea();
- $('#note').find('textarea').focus();
+ $('#note').find('textarea').expandingTextarea().show().focus();
break;
case 'EMAIL':
if($('#emaillist>li').length == 1) {
@@ -771,6 +795,7 @@ Contacts={
}
},
deleteProperty:function(obj, type){
+ console.log('deleteProperty');
Contacts.UI.loading(obj, true);
var checksum = Contacts.UI.checksumFor(obj);
if(checksum) {
@@ -793,8 +818,7 @@ Contacts={
}
} else {
$('dl dt[data-element="'+proptype+'"],dd[data-element="'+proptype+'"]').hide();
- $('dl dd[data-element="'+proptype+'"]').data('checksum', '');
- $('dl dd[data-element="'+proptype+'"]').find('input').val('');
+ $('dl dd[data-element="'+proptype+'"]').data('checksum', '').find('input').val('');
}
$('#contacts_propertymenu_dropdown a[data-type="'+proptype+'"]').parent().show();
Contacts.UI.loading(obj, false);
@@ -821,14 +845,14 @@ Contacts={
}
}
},
- editName:function(){
+ editName:function() {
var params = {id: this.id};
/* Initialize the name edit dialog */
- if($('#edit_name_dialog').dialog('isOpen') == true){
+ if($('#edit_name_dialog').dialog('isOpen') == true) {
$('#edit_name_dialog').dialog('moveToTop');
- }else{
- $.getJSON(OC.filePath('contacts', 'ajax', 'editname.php'),{id: this.id},function(jsondata){
- if(jsondata.status == 'success'){
+ } else {
+ $.getJSON(OC.filePath('contacts', 'ajax', 'editname.php'),{id: this.id},function(jsondata) {
+ if(jsondata.status == 'success') {
$('body').append('<div id="name_dialog"></div>');
$('#name_dialog').html(jsondata.data.page).find('#edit_name_dialog' ).dialog({
modal: true,
@@ -836,7 +860,7 @@ Contacts={
title: t('contacts', 'Edit name'),
height: 'auto', width: 'auto',
buttons: {
- 'Ok':function() {
+ 'Ok':function() {
Contacts.UI.Card.saveName(this);
$(this).dialog('close');
},
@@ -887,9 +911,9 @@ Contacts={
$.each(names, function(key, value) {
$('#fn_select')
.append($('<option></option>')
- .text(value));
+ .text(value));
});
-
+
if(this.id == '') {
var aid = $(dlg).find('#aid').val();
Contacts.UI.Card.add(n.join(';'), $('#short').text(), aid);
@@ -900,10 +924,11 @@ Contacts={
loadAddresses:function(){
$('#addresses').hide();
$('#addressdisplay dl.propertycontainer').remove();
+ var addresscontainer = $('#addressdisplay');
for(var adr in this.data.ADR) {
- $('#addressdisplay dl').first().clone().insertAfter($('#addressdisplay dl').last()).show();
- $('#addressdisplay dl').last().removeClass('template').addClass('propertycontainer');
- $('#addressdisplay dl').last().data('checksum', this.data.ADR[adr]['checksum']);
+ addresscontainer.find('dl').first().clone().insertAfter($('#addressdisplay dl').last()).show();
+ addresscontainer.find('dl').last().removeClass('template').addClass('propertycontainer');
+ addresscontainer.find('dl').last().data('checksum', this.data.ADR[adr]['checksum']);
var adrarray = this.data.ADR[adr]['value'];
var adrtxt = '';
if(adrarray[0] && adrarray[0].length > 0) {
@@ -915,7 +940,7 @@ Contacts={
if(adrarray[2] && adrarray[2].length > 0) {
adrtxt = adrtxt + '<li>' + adrarray[2].strip_tags() + '</li>';
}
- if((adrarray[3] && adrarray[5]) && adrarray[3].length > 0 || adrarray[5].length > 0) {
+ if((3 in adrarray && 5 in adrarray) && adrarray[3].length > 0 || adrarray[5].length > 0) {
adrtxt = adrtxt + '<li>' + adrarray[5].strip_tags() + ' ' + adrarray[3].strip_tags() + '</li>';
}
if(adrarray[4] && adrarray[4].length > 0) {
@@ -924,7 +949,7 @@ Contacts={
if(adrarray[6] && adrarray[6].length > 0) {
adrtxt = adrtxt + '<li>' + adrarray[6].strip_tags() + '</li>';
}
- $('#addressdisplay dl').last().find('.addresslist').html(adrtxt);
+ addresscontainer.find('dl').last().find('.addresslist').html(adrtxt);
var types = new Array();
var ttypes = new Array();
for(var param in this.data.ADR[adr]['parameters']) {
@@ -933,12 +958,12 @@ Contacts={
ttypes.push(this.data.ADR[adr]['parameters'][param]);
}
}
- $('#addressdisplay dl').last().find('.adr_type_label').text(types.join('/'));
- $('#addressdisplay dl').last().find('.adr_type').val(ttypes.join(','));
- $('#addressdisplay dl').last().find('.adr').val(adrarray.join(';'));
- $('#addressdisplay dl').last().data('checksum', this.data.ADR[adr]['checksum']);
+ addresscontainer.find('dl').last().find('.adr_type_label').text(types.join('/'));
+ addresscontainer.find('dl').last().find('.adr_type').val(ttypes.join(','));
+ addresscontainer.find('dl').last().find('.adr').val(adrarray.join(';'));
+ addresscontainer.find('dl').last().data('checksum', this.data.ADR[adr]['checksum']);
}
- if($('#addressdisplay dl').length > 1) {
+ if(addresscontainer.find('dl').length > 1) {
$('#addresses').show();
$('#contact_communication').show();
}
@@ -953,7 +978,7 @@ Contacts={
container = $('#addressdisplay dl').last();
container.removeClass('template').addClass('propertycontainer');
} else {
- params['checksum'] = Contacts.UI.checksumFor(obj);
+ params['checksum'] = Contacts.UI.checksumFor(obj);
}
/* Initialize the address edit dialog */
if($('#edit_address_dialog').dialog('isOpen') == true){
@@ -983,9 +1008,6 @@ Contacts={
close : function(event, ui) {
$(this).dialog('destroy').remove();
$('#address_dialog').remove();
- if(isnew) {
- container.remove();
- }
},
open : function(event, ui) {
$( "#adr_city" ).autocomplete({
@@ -1024,7 +1046,7 @@ Contacts={
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
- $( "#adr_country" ).autocomplete({
+ $('#adr_country').autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
@@ -1075,15 +1097,23 @@ Contacts={
saveAddress:function(dlg, obj, isnew){
if(isnew) {
container = $('#addressdisplay dl').last();
- obj = $('#addressdisplay dl:last-child').find('input').first();
+ obj = container.find('input').first();
} else {
checksum = Contacts.UI.checksumFor(obj);
container = Contacts.UI.propertyContainerFor(obj);
}
- var adr = new Array($(dlg).find('#adr_pobox').val().strip_tags(),$(dlg).find('#adr_extended').val().strip_tags(),$(dlg).find('#adr_street').val().strip_tags(),$(dlg).find('#adr_city').val().strip_tags(),$(dlg).find('#adr_region').val().strip_tags(),$(dlg).find('#adr_zipcode').val().strip_tags(),$(dlg).find('#adr_country').val().strip_tags());
- $(container).find('.adr').val(adr.join(';'));
- $(container).find('.adr_type').val($(dlg).find('#adr_type').val());
- $(container).find('.adr_type_label').html(t('contacts',ucwords($(dlg).find('#adr_type').val().toLowerCase())));
+ var adr = new Array(
+ $(dlg).find('#adr_pobox').val().strip_tags(),
+ $(dlg).find('#adr_extended').val().strip_tags(),
+ $(dlg).find('#adr_street').val().strip_tags(),
+ $(dlg).find('#adr_city').val().strip_tags(),
+ $(dlg).find('#adr_region').val().strip_tags(),
+ $(dlg).find('#adr_zipcode').val().strip_tags(),
+ $(dlg).find('#adr_country').val().strip_tags()
+ );
+ container.find('.adr').val(adr.join(';'));
+ container.find('.adr_type').val($(dlg).find('#adr_type').val());
+ container.find('.adr_type_label').html(t('contacts',ucwords($(dlg).find('#adr_type').val().toLowerCase())));
Contacts.UI.Card.saveProperty($(container).find('input').first());
var adrtxt = '';
if(adr[0].length > 0) {
@@ -1104,7 +1134,7 @@ Contacts={
if(adr[6].length > 0) {
adrtxt = adrtxt + '<li>' + adr[6] + '</li>';
}
- $(container).find('.addresslist').html(adrtxt);
+ container.find('.addresslist').html(adrtxt);
},
uploadPhoto:function(filelist) {
if(!filelist) {
@@ -1131,24 +1161,25 @@ Contacts={
form.submit();
}
},
- loadPhotoHandlers:function(){
- $('#phototools li a').tipsy('hide');
- $('#phototools li a').tipsy();
+ loadPhotoHandlers:function() {
+ var phototools = $('#phototools');
+ phototools.find('li a').tipsy('hide');
+ phototools.find('li a').tipsy();
if(this.data.PHOTO) {
- $('#phototools .delete').click(function() {
+ phototools.find('.delete').click(function() {
$(this).tipsy('hide');
Contacts.UI.Card.deleteProperty($('#contacts_details_photo'), 'single');
$(this).hide();
});
- $('#phototools .edit').click(function() {
+ phototools.find('.edit').click(function() {
$(this).tipsy('hide');
Contacts.UI.Card.editCurrentPhoto();
});
- $('#phototools .delete').show();
- $('#phototools .edit').show();
+ phototools.find('.delete').show();
+ phototools.find('.edit').show();
} else {
- $('#phototools .delete').hide();
- $('#phototools .edit').hide();
+ phototools.find('.delete').hide();
+ phototools.find('.edit').hide();
}
},
cloudPhotoSelected:function(path){
@@ -1169,28 +1200,18 @@ Contacts={
$('#phototools li a').tipsy('hide');
var wrapper = $('#contacts_details_photo_wrapper');
wrapper.addClass('loading').addClass('wait');
-
- var img = new Image();
- $(img).load(function () {
+ delete this.photo;
+ this.photo = new Image();
+ $(this.photo).load(function () {
$('img.contacts_details_photo').remove()
- $(this).addClass('contacts_details_photo').hide();
+ $(this).addClass('contacts_details_photo');
wrapper.removeClass('loading').removeClass('wait');
$(this).insertAfter($('#phototools')).fadeIn();
}).error(function () {
// notify the user that the image could not be loaded
- $(t('contacts','something went wrong.')).insertAfter($('#phototools'));
+ Contacts.UI.notify({message:t('contacts','Error loading profile picture.')});
}).attr('src', OC.linkTo('contacts', 'photo.php')+'?id='+self.id+refreshstr);
-
- $.getJSON(OC.filePath('contacts', 'ajax', 'loadphoto.php'),{'id':this.id, 'refresh': refresh},function(jsondata){
- if(jsondata.status == 'success'){
- $('#contacts_details_photo_wrapper').data('checksum', jsondata.data.checksum);
- Contacts.UI.Card.loadPhotoHandlers();
- }
- else{
- OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
- }
- });
- $('#file_upload_form').show();
+ this.loadPhotoHandlers()
},
editCurrentPhoto:function(){
$.getJSON(OC.filePath('contacts', 'ajax', 'currentphoto.php'),{'id':this.id},function(jsondata){
@@ -1244,10 +1265,11 @@ Contacts={
},
addMail:function() {
//alert('addMail');
- $('#emaillist li.template:first-child').clone(true).appendTo($('#emaillist')).show().find('a .tip').tipsy();
- $('#emaillist li.template:last-child').find('select').addClass('contacts_property');
- $('#emaillist li.template:last-child').removeClass('template').addClass('propertycontainer');
- $('#emaillist li:last-child').find('input[type="email"]').focus();
+ var emaillist = $('#emaillist');
+ emaillist.find('li.template:first-child').clone(true).appendTo(emaillist).show().find('a .tip').tipsy();
+ emaillist.find('li.template:last-child').find('select').addClass('contacts_property');
+ emaillist.find('li.template:last-child').removeClass('template').addClass('propertycontainer');
+ emaillist.find('li:last-child').find('input[type="email"]').focus();
return false;
},
loadMails:function() {
@@ -1283,35 +1305,37 @@ Contacts={
return false;
},
addPhone:function() {
- $('#phonelist li.template:first-child').clone(true).appendTo($('#phonelist')); //.show();
- $('#phonelist li.template:last-child').find('select').addClass('contacts_property');
- $('#phonelist li.template:last-child').removeClass('template').addClass('propertycontainer');
- $('#phonelist li:last-child').find('input[type="text"]').focus();
- $('#phonelist li:last-child').find('select').multiselect({
+ var phonelist = $('#phonelist');
+ phonelist.find('li.template:first-child').clone(true).appendTo(phonelist); //.show();
+ phonelist.find('li.template:last-child').find('select').addClass('contacts_property');
+ phonelist.find('li.template:last-child').removeClass('template').addClass('propertycontainer');
+ phonelist.find('li:last-child').find('input[type="text"]').focus();
+ phonelist.find('li:last-child').find('select').multiselect({
noneSelectedText: t('contacts', 'Select type'),
header: false,
selectedList: 4,
classes: 'typelist'
});
- $('#phonelist li:last-child').show();
+ phonelist.find('li:last-child').show();
return false;
},
loadPhones:function() {
$('#phones').hide();
$('#phonelist li.propertycontainer').remove();
+ var phonelist = $('#phonelist');
for(var phone in this.data.TEL) {
this.addPhone();
- $('#phonelist li:last-child').find('select').multiselect('destroy');
- $('#phonelist li:last-child').data('checksum', this.data.TEL[phone]['checksum'])
- $('#phonelist li:last-child').find('input[type="text"]').val(this.data.TEL[phone]['value']);
+ phonelist.find('li:last-child').find('select').multiselect('destroy');
+ phonelist.find('li:last-child').data('checksum', this.data.TEL[phone]['checksum'])
+ phonelist.find('li:last-child').find('input[type="text"]').val(this.data.TEL[phone]['value']);
for(var param in this.data.TEL[phone]['parameters']) {
if(param.toUpperCase() == 'PREF') {
- $('#phonelist li:last-child').find('input[type="checkbox"]').attr('checked', 'checked');
+ phonelist.find('li:last-child').find('input[type="checkbox"]').attr('checked', 'checked');
}
else if(param.toUpperCase() == 'TYPE') {
for(ptype in this.data.TEL[phone]['parameters'][param]) {
var pt = this.data.TEL[phone]['parameters'][param][ptype];
- $('#phonelist li:last-child').find('select option').each(function(){
+ phonelist.find('li:last-child').find('select option').each(function(){
//if ($(this).val().toUpperCase() == pt.toUpperCase()) {
if ($.inArray($(this).val().toUpperCase(), pt.toUpperCase().split(',')) > -1) {
$(this).attr('selected', 'selected');
@@ -1320,14 +1344,14 @@ Contacts={
}
}
}
- $('#phonelist li:last-child').find('select').multiselect({
- noneSelectedText: t('contacts', 'Select type'),
- header: false,
- selectedList: 4,
- classes: 'typelist'
- });
+ phonelist.find('li:last-child').find('select').multiselect({
+ noneSelectedText: t('contacts', 'Select type'),
+ header: false,
+ selectedList: 4,
+ classes: 'typelist'
+ });
}
- if($('#phonelist li').length > 1) {
+ if(phonelist.find('li').length > 1) {
$('#phones').show();
$('#contact_communication').show();
}
@@ -1335,8 +1359,6 @@ Contacts={
},
},
Addressbooks:{
- droptarget:undefined,
- droptext:t('contacts', 'Drop a VCF file<br />to import contacts.'),
overview:function(){
if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
$('#chooseaddressbook_dialog').dialog('moveToTop');
@@ -1374,6 +1396,20 @@ Contacts={
}
});
},
+ addAddressbook:function(name, description, cb) {
+ $.post(OC.filePath('contacts', 'ajax', 'addaddressbook.php'), { name: name, description: description, active: true },
+ function(jsondata){
+ if(jsondata.status == 'success'){
+ if(cb) {
+ cb(jsondata.data);
+ }
+ } else {
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
+ return false;
+ }
+ });
+
+ },
newAddressbook:function(object){
var tr = $(document.createElement('tr'))
.load(OC.filePath('contacts', 'ajax', 'addbook.php'));
@@ -1393,6 +1429,7 @@ Contacts={
function(jsondata) {
if (jsondata.status == 'success'){
$(obj).closest('tr').remove();
+ $('#contacts h3[data-id="'+bookid+'"],#contacts ul[data-id="'+bookid+'"]').remove();
Contacts.UI.Contacts.update();
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
@@ -1400,135 +1437,20 @@ 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');
- //return false;
- });
- $('#importaddressbook_dialog').find('.upload').tipsy();
- this.droptarget = $('#import_drop_target');
- $(this.droptarget).bind('dragover',function(event){
- $(event.target).addClass('droppable');
- event.stopPropagation();
- event.preventDefault();
- });
- $(this.droptarget).bind('dragleave',function(event){
- $(event.target).removeClass('droppable');
- });
- $(this.droptarget).bind('drop',function(event){
- event.stopPropagation();
- event.preventDefault();
- $(event.target).removeClass('droppable');
- $(event.target).html(t('contacts', 'Uploading...'));
- Contacts.UI.loading(event.target, true);
- $.importUpload(event.originalEvent.dataTransfer.files);
- });
-
- $.importUpload = function(files){
- var file = files[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','Upload too large'));
- $(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(Contacts.UI.Addressbooks.droptext);
- Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
- return;
- }
- var xhr = new XMLHttpRequest();
-
- if (!xhr.upload) {
- OC.dialogs.alert(t('contacts', 'Your browser doesn\'t support AJAX upload. Please upload the contacts file to ownCloud and import that way.'), t('contacts', 'Error'))
- }
- importUpload = xhr.upload,
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4){
- response = $.parseJSON(xhr.responseText);
- if(response.status == 'success') {
- if(xhr.status == 200) {
- Contacts.UI.Addressbooks.doImport(response.data.path, response.data.file);
- } else {
- $(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'));
- }
- } else {
- OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
- }
- }
- };
- xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadimport.php') + '?file='+encodeURIComponent(file.name)+'&requesttoken='+requesttoken, true);
- xhr.setRequestHeader('Cache-Control', 'no-cache');
- xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
- xhr.setRequestHeader('X_FILE_NAME', encodeURIComponent(file.name));
- xhr.setRequestHeader('X-File-Size', file.size);
- xhr.setRequestHeader('Content-Type', file.type);
- 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();
- $.post(OC.filePath('contacts', '', 'import.php'), { id: id, path: path, file: file, fstype: 'OC_FilesystemView' },
+ doImport:function(file, aid){
+ $.post(OC.filePath('contacts', '', 'import.php'), { id: aid, file: file, fstype: 'OC_FilesystemView' },
function(jsondata){
- if(jsondata.status == 'success'){
- 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'));
+ if(jsondata.status != 'success'){
+ Contacts.UI.notify({message:jsondata.data.message});
}
});
- Contacts.UI.loading(Contacts.UI.Addressbooks.droptarget, false);
+ return false;
},
submit:function(button, bookid){
var displayname = $("#displayname_"+bookid).val().trim();
var active = $("#edit_active_"+bookid+":checked").length;
var description = $("#description_"+bookid).val();
-
+
if(displayname.length == 0) {
OC.dialogs.alert(t('contacts', 'Displayname cannot be empty.'), t('contacts', 'Error'));
return false;
@@ -1554,60 +1476,151 @@ Contacts={
}
},
Contacts:{
+ contacts:{},
batchnum:50,
+ getContact:function(id) {
+ if(!this.contacts[id]) {
+ this.contacts[id] = $('#contacts li[data-id="'+id+'"]');
+ if(!this.contacts[id]) {
+ self = this;
+ $.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
+ if(jsondata.status == 'success'){
+ self.contacts[id] = self.insertContact({data:jsondata.data});
+ }
+ else{
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
+ }
+ });
+ }
+ }
+ return this.contacts[id];
+ },
drop:function(event, ui) {
var dragitem = ui.draggable, droptarget = $(this);
- //console.log('Drop ' + dragitem.data('id') +' on: ' + droptarget.data('id'));
+ if(dragitem.is('li')) {
+ Contacts.UI.Contacts.dropContact(event, dragitem, droptarget);
+ } else {
+ Contacts.UI.Contacts.dropAddressbook(event, dragitem, droptarget);
+ }
+ },
+ dropContact:function(event, dragitem, droptarget) {
if(dragitem.data('bookid') == droptarget.data('id')) {
return false;
}
var droplist = (droptarget.is('ul'))?droptarget:droptarget.next();
- $.post(OC.filePath('contacts', 'ajax', 'movetoaddressbook.php'), { ids: dragitem.data('id'), aid: $(this).data('id') },
+ $.post(OC.filePath('contacts', 'ajax', 'movetoaddressbook.php'), { ids: dragitem.data('id'), aid: droptarget.data('id') },
function(jsondata){
if(jsondata.status == 'success'){
- // Do some inserting/removing/sorting magic
- var name = $(dragitem).find('a').html();
- var added = false;
- $(droplist).children().each(function(){
- if ($(this).text().toLowerCase() > name.toLowerCase()) {
- $(this).before(dragitem.detach()); //.fadeIn('slow');
- added = true;
- return false;
- }
- });
- if(!added) {
- $(droplist).append(dragitem.detach());
- }
+ dragitem.attr('data-bookid', droptarget.data('id'))
dragitem.data('bookid', droptarget.data('id'));
+ Contacts.UI.Contacts.insertContact({
+ contactlist:droplist,
+ contact:dragitem.detach()
+ });
Contacts.UI.Contacts.scrollTo(dragitem.data('id'));
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
},
+ dropAddressbook:function(event, dragitem, droptarget) {
+ alert('Dropping address books not implemented yet');
+ },
+ /**
+ * @params params An object with the properties 'contactlist':a jquery object of the ul to insert into,
+ * 'contacts':a jquery object of all items in the list and either 'data': an object with the properties
+ * id, addressbookid and displayname or 'contact': a listitem to be inserted directly.
+ * If 'contactlist' or 'contacts' aren't defined they will be search for based in the properties in 'data'.
+ */
+ insertContact:function(params) {
+ var id, bookid;
+ if(!params.contactlist) {
+ // FIXME: Check if contact really exists.
+ bookid = params.data ? params.data.addressbookid : params.contact.data('bookid');
+ id = params.data ? params.data.id : params.contact.data('id');
+ params.contactlist = $('#contacts ul[data-id="'+bookid+'"]');
+ }
+ if(!params.contacts) {
+ bookid = params.data ? params.data.addressbookid : params.contact.data('bookid');
+ id = params.data ? params.data.id : params.contact.data('id');
+ params.contacts = $('#contacts ul[data-id="'+bookid+'"] li');
+ }
+ var contact = params.data
+ ? $('<li data-id="'+params.data.id+'" data-bookid="'+params.data.addressbookid+'" role="button"><a href="'+OC.linkTo('contacts', 'index.php')+'&id='+params.data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+params.data.id+') no-repeat scroll 0% 0% transparent;">'+params.data.displayname+'</a></li>')
+ : params.contact;
+ var added = false;
+ var name = params.data ? params.data.displayname.toLowerCase() : contact.find('a').text().toLowerCase();
+ if(params.contacts) {
+ params.contacts.each(function() {
+ if ($(this).text().toLowerCase() > name) {
+ $(this).before(contact);
+ added = true;
+ return false;
+ }
+ });
+ }
+ if(!added || !params.contacts) {
+ params.contactlist.append(contact);
+ }
+ //this.contacts[id] = contact;
+ return contact;
+ },
+ next:function(reverse) {
+ // TODO: Check if we're last-child/first-child and jump to next/prev address book.
+ var curlistitem = $('#contacts li[data-id="'+Contacts.UI.Card.id+'"]');
+ var newlistitem = reverse ? curlistitem.prev('li') : curlistitem.next('li');
+ if(newlistitem) {
+ curlistitem.removeClass('active');
+ Contacts.UI.Card.update({
+ cid:newlistitem.data('id'),
+ aid:newlistitem.data('bookid')
+ });
+ }
+ },
+ previous:function() {
+ this.next(true);
+ },
// Reload the contacts list.
- update:function(id, aid, start){
+ update:function(params){
+ if(!params) { params = {}; }
+ if(!params.start) {
+ if(params.aid) {
+ $('#contacts h3[data-id="'+params.aid+'"],#contacts ul[data-id="'+params.aid+'"]').remove();
+ } else {
+ $('#contacts').empty();
+ }
+ }
self = this;
- console.log('update: ' + aid + ' ' + start);
+ console.log('update: ' + params.cid + ' ' + params.aid + ' ' + params.start);
var firstrun = false;
var opts = {};
- opts['startat'] = (start?start:0);
- if(aid) {
- opts['aid'] = aid;
+ opts['startat'] = (params.start?params.start:0);
+ if(params.aid) {
+ opts['aid'] = params.aid;
}
$.getJSON(OC.filePath('contacts', 'ajax', 'contacts.php'),opts,function(jsondata){
if(jsondata.status == 'success'){
var books = jsondata.data.entries;
- $.each(jsondata.data.entries, function(b, book) {
+ $.each(books, function(b, book) {
if($('#contacts h3[data-id="'+b+'"]').length == 0) {
firstrun = true;
-
if($('#contacts h3').length == 0) {
- $('#contacts').html('<h3 class="addressbook" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts" data-id="'+b+'"></ul>');
+ $('#contacts').html('<h3 class="addressbook" contextmenu="addressbookmenu" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts hidden" data-id="'+b+'"></ul>');
} else {
if(!$('#contacts h3[data-id="'+b+'"]').length) {
- $('<h3 class="addressbook" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts" data-id="'+b+'"></ul>')
- .appendTo('#contacts');
+ var item = $('<h3 class="addressbook" contextmenu="addressbookmenu" data-id="'+b+'">'+book.displayname+'</h3><ul class="contacts hidden" data-id="'+b+'"></ul>')
+ var added = false;
+ $('#contacts h3').each(function(){
+ if ($(this).text().toLowerCase() > book.displayname.toLowerCase()) {
+ $(this).before(item).fadeIn('fast');
+ added = true;
+ return false;
+ }
+ });
+ if(!added) {
+ $('#contacts').append(item);
+ }
+
}
}
$('#contacts h3[data-id="'+b+'"]').on('click', function(event) {
@@ -1616,45 +1629,46 @@ Contacts={
$('#contacts ul[data-id="'+b+'"]').slideToggle(300);
return false;
});
- var accept = 'li:not([data-bookid="'+b+'"])';
- $('#contacts h3[data-id="'+b+'"]').droppable({
+ var accept = 'li:not([data-bookid="'+b+'"]),h3:not([data-id="'+b+'"])';
+ $('#contacts h3[data-id="'+b+'"],#contacts ul[data-id="'+b+'"]').droppable({
drop: Contacts.UI.Contacts.drop,
activeClass: 'ui-state-hover',
accept: accept
});
}
var contactlist = $('#contacts ul[data-id="'+b+'"]');
+ var contacts = $('#contacts ul[data-id="'+b+'"] li');
for(var c in book.contacts) {
if(book.contacts[c].id == undefined) { continue; }
- if($('#contacts li[data-id="'+book.contacts[c]['id']+'"][data-id="'+book.contacts[c]['bookid']+'"]').length == 0) {
- var contact = Contacts.UI.Card.createEntry(book.contacts[c]);
- if(c == self.batchnum-5) {
+ if(!$('#contacts li[data-id="'+book.contacts[c]['id']+'"]').length) {
+ var contact = Contacts.UI.Contacts.insertContact({contactlist:contactlist, contacts:contacts, data:book.contacts[c]});
+ if(c == self.batchnum-10) {
contact.bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
$(this).unbind(event);
var bookid = $(this).data('bookid');
var numsiblings = $('.contacts li[data-bookid="'+bookid+'"]').length;
if (isInView && numsiblings >= self.batchnum) {
console.log('This would be a good time to load more contacts.');
- Contacts.UI.Contacts.update(id, bookid, $('#contacts li[data-bookid="'+bookid+'"]').length);
+ Contacts.UI.Contacts.update({cid:params.cid, aid:bookid, start:$('#contacts li[data-bookid="'+bookid+'"]').length});
}
});
}
- contactlist.append(contact);
}
}
});
if($('#contacts h3').length > 1) {
- $('#contacts li').draggable({
+ $('#contacts li,#contacts h3').draggable({
+ distance: 10,
revert: 'invalid',
axis: 'y', containment: '#contacts',
- scroll: true, scrollSensitivity: 100,
+ scroll: true, scrollSensitivity: 40,
opacity: 0.7, helper: 'clone'
});
} else {
$('#contacts h3').first().addClass('active');
}
if(opts['startat'] == 0) { // only update card on first load.
- Contacts.UI.Card.update();
+ Contacts.UI.Card.update(params);
}
}
else{
@@ -1669,9 +1683,10 @@ Contacts={
},
scrollTo:function(id){
var item = $('#contacts li[data-id="'+id+'"]');
- if(item) {
- $('.contacts').animate({
- scrollTop: $('#contacts li[data-id="'+id+'"]').offset().top-20}, 'slow','swing');
+ if(item && $.isNumeric(item.offset().top)) {
+ console.log('scrollTo ' + parseInt(item.offset().top));
+ $('#contacts').animate({
+ scrollTop: parseInt(item.offset()).top-40}, 'slow','swing');
}
}
}
@@ -1682,23 +1697,90 @@ $(document).ready(function(){
OCCategories.changed = Contacts.UI.Card.categoriesChanged;
OCCategories.app = 'contacts';
- $('#notification').click(function(){
- $('#notification').fadeOut();
+ $('#chooseaddressbook').on('click keydown', Contacts.UI.Addressbooks.overview);
+ $('#contacts_newcontact').on('click keydown', Contacts.UI.Card.editNew);
+
+ var ninjahelp = $('#ninjahelp');
+
+ ninjahelp.find('.close').on('click keydown',function() {
+ ninjahelp.hide();
+ });
+
+ $(document).on('keyup', function(event) {
+ console.log(event.which + ' ' + event.target.nodeName);
+ if(event.target.nodeName.toUpperCase() != 'BODY'
+ || $('#contacts li').length == 0
+ || !Contacts.UI.Card.id) {
+ return;
+ }
+ /**
+ * To add:
+ * (Shift)n/p: next/prev addressbook
+ * u (85): hide/show leftcontent
+ * f (70): add field
+ */
+ switch(event.which) {
+ case 27: // Esc
+ ninjahelp.hide();
+ break;
+ case 46:
+ if(event.shiftKey) {
+ Contacts.UI.Card.delayedDelete();
+ }
+ break;
+ case 32: // space
+ if(event.shiftKey) {
+ Contacts.UI.Contacts.previous();
+ break;
+ }
+ case 40: // down
+ case 75: // k
+ Contacts.UI.Contacts.next();
+ break;
+ case 65: // a
+ if(event.shiftKey) {
+ // add addressbook
+ Contacts.UI.notImplemented();
+ break;
+ }
+ Contacts.UI.Card.editNew();
+ break;
+ case 38: // up
+ case 74: // j
+ Contacts.UI.Contacts.previous();
+ break;
+ case 78: // n
+ // next addressbook
+ Contacts.UI.notImplemented();
+ break;
+ case 13: // Enter
+ case 79: // o
+ var aid = $('#contacts h3.active').first().data('id');
+ if(aid) {
+ $('#contacts ul[data-id="'+aid+'"]').slideToggle(300);
+ }
+ break;
+ case 80: // p
+ // prev addressbook
+ Contacts.UI.notImplemented();
+ break;
+ case 82: // r
+ Contacts.UI.Contacts.update({cid:Contacts.UI.Card.id});
+ break;
+ case 191: // ?
+ ninjahelp.toggle('fast');
+ break;
+ }
+
});
-
- $('#chooseaddressbook').click(Contacts.UI.Addressbooks.overview);
- $('#chooseaddressbook').keydown(Contacts.UI.Addressbooks.overview);
- $('#contacts_newcontact').click(Contacts.UI.Card.editNew);
- $('#contacts_newcontact').keydown(Contacts.UI.Card.editNew);
-
- // Load a contact.
+ // Load a contact.
$('.contacts').keydown(function(event) {
- if(event.which == 13) {
+ if(event.which == 13 || event.which == 32) {
$('.contacts').click();
}
});
- $(document).on('click', '.contacts', function(event){
+ $(document).on('click', '#contacts', function(event){
var $tgt = $(event.target);
if ($tgt.is('li') || $tgt.is('a')) {
var item = $tgt.is('li')?$($tgt):($tgt).parent();
@@ -1707,7 +1789,13 @@ $(document).ready(function(){
item.addClass('active');
var oldid = $('#rightcontent').data('id');
if(oldid != 0){
- $('.contacts li[data-id="'+oldid+'"]').removeClass('active');
+ var olditem = $('.contacts li[data-id="'+oldid+'"]');
+ var oldbookid = olditem.data('bookid');
+ olditem.removeClass('active');
+ if(oldbookid != bookid) {
+ $('#contacts h3[data-id="'+oldbookid+'"]').removeClass('active');
+ $('#contacts h3[data-id="'+bookid+'"]').addClass('active');
+ }
}
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
if(jsondata.status == 'success'){
@@ -1721,81 +1809,267 @@ $(document).ready(function(){
return false;
});
- /*$('.contacts li').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
- if (isInView) { //NOTE: I've kept all conditions for future reference ;-)
- // element is now visible in the viewport
- if (visiblePartY == 'top') {
- // top part of element is visible
- } else if (visiblePartY == 'bottom') {
- // bottom part of element is visible
- } else {
- // whole part of element is visible
- if (!$(this).find('a').attr('style')) {
- //alert($(this).data('id') + ' has background: ' + $(this).attr('style'));
- $(this).find('a').css('background','url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+$(this).data('id')+') no-repeat');
- }// else {
- // alert($(this).data('id') + ' has style ' + $(this).attr('style').match('url'));
- //}
- }
- } else {
- // element has gone out of viewport
- }
- });*/
-
$('.contacts_property').live('change', function(){
Contacts.UI.Card.saveProperty(this);
});
- /**
- * Upload function for dropped files. Should go in the Contacts class/object.
- */
- $.fileUpload = function(files){
- var file = files[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','Upload too large'));
- return;
- }
- if (file.type.indexOf("image") != 0) {
- OC.dialogs.alert(t('contacts','Only image files can be used as profile picture.'), t('contacts','Wrong file type'));
- return;
- }
- var xhr = new XMLHttpRequest();
+ $(function() {
+ // Upload function for dropped contact photos files. Should go in the Contacts class/object.
+ $.fileUpload = function(files){
+ var file = files[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','Upload too large'));
+ return;
+ }
+ if (file.type.indexOf("image") != 0) {
+ OC.dialogs.alert(t('contacts','Only image files can be used as profile picture.'), t('contacts','Wrong file type'));
+ return;
+ }
+ var xhr = new XMLHttpRequest();
+
+ if (!xhr.upload) {
+ OC.dialogs.alert(t('contacts', 'Your browser doesn\'t support AJAX upload. Please click on the profile picture to select a photo to upload.'), t('contacts', 'Error'))
+ }
+ fileUpload = xhr.upload,
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4){
+ response = $.parseJSON(xhr.responseText);
+ if(response.status == 'success') {
+ if(xhr.status == 200) {
+ Contacts.UI.Card.editPhoto(response.data.id, response.data.tmp);
+ } else {
+ OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
+ }
+ } else {
+ OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
+ }
+ }
+ };
- if (!xhr.upload) {
- OC.dialogs.alert(t('contacts', 'Your browser doesn\'t support AJAX upload. Please click on the profile picture to select a photo to upload.'), t('contacts', 'Error'))
+ fileUpload.onprogress = function(e){
+ if (e.lengthComputable){
+ var _progress = Math.round((e.loaded * 100) / e.total);
+ //if (_progress != 100){
+ //}
+ }
+ };
+ xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&requesttoken='+requesttoken+'&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));
+ xhr.setRequestHeader('X-File-Size', file.size);
+ xhr.setRequestHeader('Content-Type', file.type);
+ xhr.send(file);
}
- fileUpload = xhr.upload,
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4){
- response = $.parseJSON(xhr.responseText);
- if(response.status == 'success') {
- if(xhr.status == 200) {
- Contacts.UI.Card.editPhoto(response.data.id, response.data.tmp);
+ });
+
+ $(document).bind('drop dragover', function (e) {
+ e.preventDefault(); // prevent browser from doing anything, if file isn't dropped in dropZone
+ });
+
+ //add multiply file upload attribute to all browsers except konqueror (which crashes when it's used)
+ if(navigator.userAgent.search(/konqueror/i)==-1){
+ $('#import_upload_start').attr('multiple','multiple')
+ }
+ // Import using jquery.fileupload
+ $(function() {
+ var uploadingFiles = {}, numfiles = 0, uploadedfiles = 0, retries = 0;
+ var aid;
+
+ $('#import_upload_start').fileupload({
+ dropZone: $('#contacts'), // restrict dropZone to contacts list.
+ acceptFileTypes: /^text\/(directory|vcard|x-vcard)$/i,
+ add: function(e, data) {
+ var files = data.files;
+ var totalSize=0;
+ if(files) {
+ numfiles += files.length; uploadedfiles = 0;
+ for(var i=0;i<files.length;i++) {
+ if(files[i].size ==0 && files[i].type== '') {
+ OC.dialogs.alert(t('files', 'Unable to upload your file as it is a directory or has 0 bytes'), t('files', 'Upload Error'));
+ return;
+ }
+ totalSize+=files[i].size;
+ }
+ }
+ if(totalSize>$('#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'));
+ numfiles = uploadedfiles = retries = aid = 0;
+ uploadingFiles = {};
+ return;
+ }else{
+ if($.support.xhrFileUpload) {
+ for(var i=0;i<files.length;i++){
+ var fileName = files[i].name;
+ var dropTarget;
+ if($(e.originalEvent.target).is('h3')) {
+ dropTarget = $(e.originalEvent.target).next('ul');
+ } else {
+ dropTarget = $(e.originalEvent.target).closest('ul');
+ }
+ if(dropTarget && dropTarget.hasClass('contacts')) { // TODO: More thorough check for where we are.
+ aid = dropTarget.attr('data-id');
+ } else {
+ aid = undefined;
+ }
+ var jqXHR = $('#import_upload_start').fileupload('send', {files: files[i],
+ formData: function(form) {
+ var formArray = form.serializeArray();
+ formArray['aid'] = aid;
+ return formArray;
+ }})
+ .success(function(result, textStatus, jqXHR) {
+ if(result.status == 'success') {
+ // import the file
+ uploadedfiles += 1;
+ } else {
+ Contacts.UI.notify({message:jsondata.data.message});
+ }
+ return false;
+ })
+ .error(function(jqXHR, textStatus, errorThrown) {
+ console.log(textStatus);
+ Contacts.UI.notify({message:errorThrown + ': ' + textStatus,});
+ });
+ uploadingFiles[fileName] = jqXHR;
+ }
} else {
- OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
+ 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);
+ 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 {
+ Contacts.UI.notify({message:response.data.message});
+ }
+ });
}
+ }
+ },
+ fail: function(e, data) {
+ console.log('fail');
+ Contacts.UI.notify({message:data.errorThrown + ': ' + data.textStatus});
+ // TODO: Remove file from upload queue.
+ },
+ progressall: function(e, data) {
+ var progress = (data.loaded/data.total)*50;
+ $('#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) {
+ // stop only gets fired once so we collect uploaded items here.
+ var importFiles = function(aid, fileList) {
+ // Create a closure that can be called from different places.
+ if(numfiles != uploadedfiles) {
+ Contacts.UI.notify({message:t('contacts', 'Not all files uploaded. Retrying...')});
+ retries += 1;
+ if(retries > 3) {
+ numfiles = uploadedfiles = retries = aid = 0;
+ uploadingFiles = {};
+ $('#uploadprogressbar').fadeOut();
+ OC.dialogs.alert(t('contacts', 'Something went wrong with the upload, please retry.'), t('contacts', 'Error'));
+ return;
+ }
+ setTimeout(function() { // Just to let any uploads finish
+ importFiles(aid, uploadingFiles);
+ }, 1000);
+ }
+ $('#uploadprogressbar').progressbar('value',50);
+ var todo = uploadedfiles;
+ $.each(fileList, function(fileName, data) {
+ Contacts.UI.Addressbooks.doImport(fileName, aid);
+ delete fileList[fileName];
+ numfiles -= 1; uploadedfiles -= 1;
+ $('#uploadprogressbar').progressbar('value',50+(50/(todo-uploadedfiles)));
+ })
+ $('#uploadprogressbar').progressbar('value',100);
+ $('#uploadprogressbar').fadeOut();
+ setTimeout(function() {
+ Contacts.UI.Contacts.update({aid:aid});
+ numfiles = uploadedfiles = retries = aid = 0;
+ }, 1000);
+ }
+ if(!aid) {
+ // Either selected with filepicker or dropped outside of an address book.
+ $.getJSON(OC.filePath('contacts', 'ajax', 'selectaddressbook.php'),{},function(jsondata) {
+ if(jsondata.status == 'success') {
+ if($('#selectaddressbook_dialog').dialog('isOpen') == true) {
+ $('#selectaddressbook_dialog').dialog('moveToTop');
+ } else {
+ $('#dialog_holder').html(jsondata.data.page).ready(function($) {
+ var select_dlg = $('#selectaddressbook_dialog');
+ select_dlg.dialog({
+ modal: true, height: 'auto', width: 'auto',
+ buttons: {
+ 'Ok':function() {
+ aid = select_dlg.find('input:checked').val();
+ if(aid == 'new') {
+ var displayname = select_dlg.find('input.name').val();
+ var description = select_dlg.find('input.desc').val();
+ if(!displayname.trim()) {
+ OC.dialogs.alert(t('contacts', 'The address book name cannot be empty.'), t('contacts', 'Error'));
+ return false;
+ }
+ $(this).dialog('close');
+ Contacts.UI.Addressbooks.addAddressbook(displayname, description, function(addressbook){
+ aid = addressbook.id;
+ setTimeout(function() {
+ importFiles(aid, uploadingFiles);
+ }, 500);
+ console.log('aid ' + aid);
+ });
+ } else {
+ setTimeout(function() {
+ importFiles(aid, uploadingFiles);
+ }, 500);
+ console.log('aid ' + aid);
+ $(this).dialog('close');
+ }
+ },
+ 'Cancel':function() {
+ $(this).dialog('close');
+ numfiles = uploadedfiles = retries = aid = 0;
+ uploadingFiles = {};
+ $('#uploadprogressbar').fadeOut();
+ }
+ },
+ close: function(event, ui) {
+ // TODO: If numfiles != 0 delete tmp files after a timeout.
+ $(this).dialog('destroy').remove();
+ }
+ });
+ });
+ }
+ } else {
+ $('#uploadprogressbar').fadeOut();
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
+ }
+ });
} else {
- OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
+ // Dropped on an address book or it's list.
+ setTimeout(function() { // Just to let any uploads finish
+ importFiles(aid, uploadingFiles);
+ }, 1000);
+ }
+ if(data.dataType != 'iframe ') {
+ $('#upload input.stop').hide();
}
}
- };
-
- fileUpload.onprogress = function(e){
- if (e.lengthComputable){
- var _progress = Math.round((e.loaded * 100) / e.total);
- //if (_progress != 100){
- //}
- }
- };
- xhr.open('POST', OC.filePath('contacts', 'ajax', 'uploadphoto.php')+'?id='+Contacts.UI.Card.id+'&requesttoken='+requesttoken+'&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));
- xhr.setRequestHeader('X-File-Size', file.size);
- xhr.setRequestHeader('Content-Type', file.type);
- xhr.send(file);
- }
+ })
+ });
Contacts.UI.loadHandlers();
- Contacts.UI.Contacts.update(id);
+ Contacts.UI.Contacts.update({cid:id});
});
diff --git a/apps/contacts/js/jquery.inview.js b/apps/contacts/js/jquery.inview.js
index 01900b0b4b4..9687cd83368 100644
--- a/apps/contacts/js/jquery.inview.js
+++ b/apps/contacts/js/jquery.inview.js
@@ -62,8 +62,8 @@
function getViewportOffset() {
return {
- top: w.pageYOffset || documentElement.scrollTop || d.body.scrollTop,
- left: w.pageXOffset || documentElement.scrollLeft || d.body.scrollLeft
+ top: w.pageYOffset || documentElement.scrollTop || (d.body?d.body.scrollTop:0),
+ left: w.pageXOffset || documentElement.scrollLeft || (d.body?d.body.scrollLeft:0)
};
}
diff --git a/apps/contacts/js/loader.js b/apps/contacts/js/loader.js
index 577ad103064..5bca0ab7237 100644
--- a/apps/contacts/js/loader.js
+++ b/apps/contacts/js/loader.js
@@ -78,9 +78,9 @@ Contacts_Import={
}
$(document).ready(function(){
if(typeof FileActions !== 'undefined'){
- FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
+ FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
FileActions.setDefault('text/vcard','importaddressbook');
- FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
+ FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
FileActions.setDefault('text/x-vcard','importaddressbook');
};
}); \ No newline at end of file
diff --git a/apps/contacts/lib/VCFExportPlugin.php b/apps/contacts/lib/VCFExportPlugin.php
new file mode 100644
index 00000000000..9a64c964b06
--- /dev/null
+++ b/apps/contacts/lib/VCFExportPlugin.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * VCF Exporter
+ *
+ * This plugin adds the ability to export entire address books as .vcf files.
+ * This is useful for clients that don't support CardDAV yet. They often do
+ * support vcf files.
+ *
+ * @package Sabre
+ * @subpackage CardDAV
+ * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CardDAV_VCFExportPlugin extends Sabre_DAV_ServerPlugin {
+
+ /**
+ * Reference to Server class
+ *
+ * @var Sabre_DAV_Server
+ */
+ private $server;
+
+ /**
+ * Initializes the plugin and registers event handlers
+ *
+ * @param Sabre_DAV_Server $server
+ * @return void
+ */
+ public function initialize(Sabre_DAV_Server $server) {
+
+ $this->server = $server;
+ $this->server->subscribeEvent('beforeMethod', array($this,'beforeMethod'), 90);
+
+ }
+
+ /**
+ * 'beforeMethod' event handles. This event handles intercepts GET requests ending
+ * with ?export
+ *
+ * @param string $method
+ * @param string $uri
+ * @return bool
+ */
+ public function beforeMethod($method, $uri) {
+
+ if ($method!='GET') return;
+ if ($this->server->httpRequest->getQueryString()!='export') return;
+
+ // splitting uri
+ list($uri) = explode('?', $uri, 2);
+
+ $node = $this->server->tree->getNodeForPath($uri);
+
+ if (!($node instanceof Sabre_CardDAV_IAddressBook)) return;
+
+ // Checking ACL, if available.
+ if ($aclPlugin = $this->server->getPlugin('acl')) {
+ $aclPlugin->checkPrivileges($uri, '{DAV:}read');
+ }
+
+ $this->server->httpResponse->setHeader('Content-Type', 'text/directory');
+ $this->server->httpResponse->sendStatus(200);
+
+ $nodes = $this->server->getPropertiesForPath($uri, array(
+ '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data',
+ ), 1);
+
+ $this->server->httpResponse->sendBody($this->generateVCF($nodes));
+
+ // Returning false to break the event chain
+ return false;
+
+ }
+
+ /**
+ * Merges all vcard objects, and builds one big vcf export
+ *
+ * @param array $nodes
+ * @return string
+ */
+ public function generateVCF(array $nodes) {
+ $objects = array();
+
+ foreach($nodes as $node) {
+
+ if (!isset($node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'])) {
+ continue;
+ }
+ $nodeData = $node[200]['{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}address-data'];
+ $objects[] = $nodeData;
+
+ }
+
+ return implode("\r\n", $objects);
+
+ }
+
+}
diff --git a/apps/contacts/lib/addressbook.php b/apps/contacts/lib/addressbook.php
index 7549464f464..eb61b6dbced 100644
--- a/apps/contacts/lib/addressbook.php
+++ b/apps/contacts/lib/addressbook.php
@@ -37,17 +37,17 @@
/**
* This class manages our addressbooks.
*/
-class OC_Contacts_Addressbook{
+class OC_Contacts_Addressbook {
/**
* @brief Returns the list of addressbooks for a specific user.
* @param string $uid
* @param boolean $active Only return addressbooks with this $active state, default(=false) is don't care
* @return array or false.
*/
- public static function all($uid, $active=false){
+ public static function all($uid, $active=false) {
$values = array($uid);
$active_where = '';
- if ($active){
+ if ($active) {
$active_where = ' AND active = ?';
$values[] = 1;
}
@@ -55,13 +55,13 @@ class OC_Contacts_Addressbook{
$stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' . $active_where . ' ORDER BY displayname' );
$result = $stmt->execute($values);
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.' uid: '.$uid, OCP\Util::DEBUG);
return false;
}
$addressbooks = array();
- while( $row = $result->fetchRow()){
+ while( $row = $result->fetchRow()) {
$addressbooks[] = $row;
}
if(!$active && !count($addressbooks)) {
@@ -76,14 +76,14 @@ class OC_Contacts_Addressbook{
* @param integer $uid User id. If null current user will be used.
* @return array
*/
- public static function activeIds($uid = null){
- if(is_null($uid)){
+ public static function activeIds($uid = null) {
+ if(is_null($uid)) {
$uid = OCP\USER::getUser();
}
$activeaddressbooks = self::all($uid, true);
$ids = array();
foreach($activeaddressbooks as $addressbook) {
- $ids[] = $addressbook['userid'];
+ $ids[] = $addressbook['id'];
}
return $ids;
}
@@ -93,7 +93,7 @@ class OC_Contacts_Addressbook{
* @param string $uid
* @return array
*/
- public static function active($uid){
+ public static function active($uid) {
return self::all($uid, true);
}
@@ -112,13 +112,13 @@ class OC_Contacts_Addressbook{
* @param integer $id
* @return associative array or false.
*/
- public static function find($id){
+ public static function find($id) {
try {
$stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
$result = $stmt->execute(array($id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '.$id, OCP\Util::DEBUG);
return false;
}
@@ -129,11 +129,11 @@ class OC_Contacts_Addressbook{
* @brief Adds default address book
* @return $id ID of the newly created addressbook or false on error.
*/
- public static function addDefault($uid = null){
+ public static function addDefault($uid = null) {
if(is_null($uid)) {
$uid = OCP\USER::getUser();
}
- $id = self::add($uid,'default','Default Address Book');
+ $id = self::add($uid, 'Contacts', 'Default Address Book');
if($id !== false) {
self::setActive($id, true);
}
@@ -147,13 +147,13 @@ class OC_Contacts_Addressbook{
* @param string $description
* @return insertid
*/
- public static function add($uid,$name,$description=''){
+ public static function add($uid,$name,$description='') {
try {
$stmt = OCP\DB::prepare( 'SELECT uri FROM *PREFIX*contacts_addressbooks WHERE userid = ? ' );
$result = $stmt->execute(array($uid));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' uid: '.$uid,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.' exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.' uid: '.$uid, OCP\Util::DEBUG);
return false;
}
$uris = array();
@@ -166,8 +166,8 @@ class OC_Contacts_Addressbook{
$stmt = OCP\DB::prepare( 'INSERT INTO *PREFIX*contacts_addressbooks (userid,displayname,uri,description,ctag) VALUES(?,?,?,?,?)' );
$result = $stmt->execute(array($uid,$name,$uri,$description,1));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', uid: '.$uid,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', uid: '.$uid, OCP\Util::DEBUG);
return false;
}
@@ -182,16 +182,16 @@ class OC_Contacts_Addressbook{
* @param string $description
* @return insertid or false
*/
- public static function addFromDAVData($principaluri,$uri,$name,$description){
+ public static function addFromDAVData($principaluri,$uri,$name,$description) {
$uid = self::extractUserID($principaluri);
try {
$stmt = OCP\DB::prepare('INSERT INTO *PREFIX*contacts_addressbooks (userid,displayname,uri,description,ctag) VALUES(?,?,?,?,?)');
$result = $stmt->execute(array($uid,$name,$uri,$description,1));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', uid: '.$uid,OCP\Util::DEBUG);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', uri: '.$uri,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', uid: '.$uid, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', uri: '.$uri, OCP\Util::DEBUG);
return false;
}
@@ -205,14 +205,14 @@ class OC_Contacts_Addressbook{
* @param string $description
* @return boolean
*/
- public static function edit($id,$name,$description){
+ public static function edit($id,$name,$description) {
// Need these ones for checking uri
$addressbook = self::find($id);
- if(is_null($name)){
+ if(is_null($name)) {
$name = $addressbook['name'];
}
- if(is_null($description)){
+ if(is_null($description)) {
$description = $addressbook['description'];
}
@@ -220,8 +220,8 @@ class OC_Contacts_Addressbook{
$stmt = OCP\DB::prepare('UPDATE *PREFIX*contacts_addressbooks SET displayname=?,description=?, ctag=ctag+1 WHERE id=?');
$result = $stmt->execute(array($name,$description,$id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '.$id, OCP\Util::DEBUG);
return false;
}
@@ -234,15 +234,15 @@ class OC_Contacts_Addressbook{
* @param boolean $active
* @return boolean
*/
- public static function setActive($id,$active){
+ public static function setActive($id,$active) {
$sql = 'UPDATE *PREFIX*contacts_addressbooks SET active = ? WHERE id = ?';
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id.', active: '.intval($active),OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '.$id.', active: '.intval($active), OCP\Util::ERROR);
try {
$stmt = OCP\DB::prepare($sql);
$stmt->execute(array(intval($active), $id));
return true;
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(),OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(), OCP\Util::ERROR);
return false;
}
}
@@ -252,7 +252,7 @@ class OC_Contacts_Addressbook{
* @param integer $id ID of the address book.
* @return boolean
*/
- public static function isActive($id){
+ public static function isActive($id) {
$sql = 'SELECT active FROM *PREFIX*contacts_addressbooks WHERE id = ?';
try {
$stmt = OCP\DB::prepare( $sql );
@@ -260,7 +260,7 @@ class OC_Contacts_Addressbook{
$row = $result->fetchRow();
return (bool)$row['active'];
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
}
}
@@ -269,13 +269,13 @@ class OC_Contacts_Addressbook{
* @param integer $id
* @return boolean
*/
- public static function delete($id){
+ public static function delete($id) {
self::setActive($id, false);
try {
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_addressbooks WHERE id = ?' );
$stmt->execute(array($id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(),OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception for '.$id.': '.$e->getMessage(), OCP\Util::ERROR);
return false;
}
@@ -292,7 +292,7 @@ class OC_Contacts_Addressbook{
* @param integer $id
* @return boolean
*/
- public static function touch($id){
+ public static function touch($id) {
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_addressbooks SET ctag = ctag + 1 WHERE id = ?' );
$stmt->execute(array($id));
@@ -305,11 +305,11 @@ class OC_Contacts_Addressbook{
* @param array $existing existing addressbook URIs
* @return string new name
*/
- public static function createURI($name,$existing){
- $name = strtolower($name);
+ public static function createURI($name,$existing) {
+ $name = str_replace(' ', '_', strtolower($name));
$newname = $name;
$i = 1;
- while(in_array($newname,$existing)){
+ while(in_array($newname, $existing)) {
$newname = $name.$i;
$i = $i + 1;
}
@@ -320,8 +320,8 @@ class OC_Contacts_Addressbook{
* @brief gets the userid from a principal path
* @return string
*/
- public static function extractUserID($principaluri){
- list($prefix,$userid) = Sabre_DAV_URLUtil::splitPath($principaluri);
+ public static function extractUserID($principaluri) {
+ list($prefix, $userid) = Sabre_DAV_URLUtil::splitPath($principaluri);
return $userid;
}
}
diff --git a/apps/contacts/lib/app.php b/apps/contacts/lib/app.php
index 25461877e62..689149367fa 100644
--- a/apps/contacts/lib/app.php
+++ b/apps/contacts/lib/app.php
@@ -41,7 +41,7 @@ class OC_Contacts_App {
$card = OC_Contacts_VCard::find( $id );
if( $card === false ) {
OCP\Util::writeLog('contacts', 'Contact could not be found: '.$id, OCP\Util::ERROR);
- OCP\JSON::error(array('data' => array( 'message' => self::$l10n->t('Contact could not be found.').' '.$id)));
+ OCP\JSON::error(array('data' => array( 'message' => self::$l10n->t('Contact could not be found.').' '.print_r($id, true))));
exit();
}
@@ -61,11 +61,11 @@ class OC_Contacts_App {
if(!is_null($vcard) && !$vcard->__isset('N')) {
$version = OCP\App::getAppVersion('contacts');
if($version >= 5) {
- OCP\Util::writeLog('contacts','OC_Contacts_App::getContactVCard. Deprecated check for missing N field', OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_App::getContactVCard. Deprecated check for missing N field', OCP\Util::DEBUG);
}
- OCP\Util::writeLog('contacts','getContactVCard, Missing N field', OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'getContactVCard, Missing N field', OCP\Util::DEBUG);
if($vcard->__isset('FN')) {
- OCP\Util::writeLog('contacts','getContactVCard, found FN field: '.$vcard->__get('FN'), OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'getContactVCard, found FN field: '.$vcard->__get('FN'), OCP\Util::DEBUG);
$n = implode(';', array_reverse(array_slice(explode(' ', $vcard->__get('FN')), 0, 2))).';;;';
$vcard->setString('N', $n);
OC_Contacts_VCard::edit( $id, $vcard);
@@ -196,16 +196,19 @@ class OC_Contacts_App {
foreach($vcaddressbooks as $vcaddressbook) {
$vcaddressbookids[] = $vcaddressbook['id'];
}
- $vccontacts = OC_Contacts_VCard::all($vcaddressbookids);
- }
- }
- if(is_array($vccontacts) && count($vccontacts) > 0) {
- $cards = array();
- foreach($vccontacts as $vccontact) {
- $cards[] = $vccontact['carddata'];
+ $start = 0;
+ $batchsize = 10;
+ while($vccontacts = OC_Contacts_VCard::all($vcaddressbookids, $start, $batchsize)){
+ $cards = array();
+ foreach($vccontacts as $vccontact) {
+ $cards[] = $vccontact['carddata'];
+ }
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', scanning: '.$batchsize.' starting from '.$start, OCP\Util::DEBUG);
+ // only reset on first batch.
+ self::getVCategories()->rescan($cards, true, ($start == 0 ? true : false));
+ $start += $batchsize;
+ }
}
-
- self::$categories->rescan($cards);
}
}
diff --git a/apps/contacts/lib/connector_sabre.php b/apps/contacts/lib/connector_sabre.php
index c967e906601..9fcfff08fa8 100644
--- a/apps/contacts/lib/connector_sabre.php
+++ b/apps/contacts/lib/connector_sabre.php
@@ -79,7 +79,7 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract {
}
}
- OC_Contacts_Addressbook::edit($addressbookid,$name,$description);
+ OC_Contacts_Addressbook::edit($addressbookid, $name, $description);
return true;
@@ -113,7 +113,7 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract {
}
- OC_Contacts_Addressbook::addFromDAVData($principaluri,$url,$name,$description);
+ OC_Contacts_Addressbook::addFromDAVData($principaluri, $url, $name, $description);
}
/**
@@ -138,7 +138,9 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract {
foreach($data as $i){
$cards[] = array(
'id' => $i['id'],
- 'carddata' => $i['carddata'],
+ //'carddata' => $i['carddata'],
+ 'size' => strlen($i['carddata']),
+ 'etag' => md5($i['carddata']),
'uri' => $i['uri'],
'lastmodified' => $i['lastmodified'] );
}
@@ -154,7 +156,7 @@ class OC_Connector_Sabre_CardDAV extends Sabre_CardDAV_Backend_Abstract {
* @return array
*/
public function getCard($addressbookid, $carduri) {
- return OC_Contacts_VCard::findWhereDAVDataIs($addressbookid,$carduri);
+ return OC_Contacts_VCard::findWhereDAVDataIs($addressbookid, $carduri);
}
diff --git a/apps/contacts/lib/hooks.php b/apps/contacts/lib/hooks.php
index d91d3c565b5..3344e3d6939 100644
--- a/apps/contacts/lib/hooks.php
+++ b/apps/contacts/lib/hooks.php
@@ -34,12 +34,12 @@
*/
class OC_Contacts_Hooks{
/**
- * @brief Add default Addressbooks of a certain user
- * @param paramters parameters from postDeleteUser-Hook
+ * @brief Add default Addressbook for a certain user
+ * @param paramters parameters from postCreateUser-Hook
* @return array
*/
static public function createUser($parameters) {
- OC_Contacts_Addressbook::addDefault($parameters['uid'],'default','Default Address Book');
+ OC_Contacts_Addressbook::addDefault($parameters['uid']);
return true;
}
@@ -61,8 +61,8 @@ class OC_Contacts_Hooks{
static public function getCalenderSources($parameters) {
$base_url = OCP\Util::linkTo('calendar', 'ajax/events.php').'?calendar_id=';
foreach(OC_Contacts_Addressbook::all(OCP\USER::getUser()) as $addressbook) {
- $parameters['sources'][] =
- array(
+ $parameters['sources'][]
+ = array(
'url' => $base_url.'birthday_'. $addressbook['id'],
'backgroundColor' => '#cccccc',
'borderColor' => '#888',
@@ -91,18 +91,24 @@ class OC_Contacts_Hooks{
$date = new DateTime($birthday);
$vevent = new OC_VObject('VEVENT');
//$vevent->setDateTime('LAST-MODIFIED', new DateTime($vcard->REV));
- $vevent->setDateTime('DTSTART', $date, Sabre_VObject_Element_DateTime::DATE);
+ $vevent->setDateTime('DTSTART', $date,
+ Sabre_VObject_Element_DateTime::DATE);
$vevent->setString('DURATION', 'P1D');
- $vevent->setString('UID', substr(md5(rand().time()),0,10));
+ $vevent->setString('UID', substr(md5(rand().time()), 0, 10));
// DESCRIPTION?
$vevent->setString('RRULE', 'FREQ=YEARLY');
- $title = str_replace('{name}', $vcard->getAsString('FN'), OC_Contacts_App::$l10n->t('{name}\'s Birthday'));
+ $title = str_replace('{name}',
+ $vcard->getAsString('FN'),
+ OC_Contacts_App::$l10n->t('{name}\'s Birthday'));
$parameters['events'][] = array(
'id' => 0,//$card['id'],
'vevent' => $vevent,
'repeating' => true,
'summary' => $title,
- 'calendardata' => "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Contacts " . OCP\App::getAppVersion('contacts') . "\n" . $vevent->serialize() . "END:VCALENDAR"
+ 'calendardata' => "BEGIN:VCALENDAR\nVERSION:2.0\n"
+ . "PRODID:ownCloud Contacts "
+ . OCP\App::getAppVersion('contacts') . "\n"
+ . $vevent->serialize() . "END:VCALENDAR"
);
}
}
diff --git a/apps/contacts/lib/search.php b/apps/contacts/lib/search.php
index 5d9ca97e761..53aa2b48496 100644
--- a/apps/contacts/lib/search.php
+++ b/apps/contacts/lib/search.php
@@ -2,7 +2,7 @@
class OC_Search_Provider_Contacts extends OC_Search_Provider{
function search($query){
$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser(), 1);
- if(count($addressbooks)==0 || !OCP\App::isEnabled('contacts')){
+ if(count($addressbooks)==0 || !OCP\App::isEnabled('contacts')) {
return array();
}
$results=array();
@@ -10,9 +10,9 @@ class OC_Search_Provider_Contacts extends OC_Search_Provider{
foreach($addressbooks as $addressbook){
$vcards = OC_Contacts_VCard::all($addressbook['id']);
foreach($vcards as $vcard){
- if(substr_count(strtolower($vcard['fullname']), strtolower($query)) > 0){
+ if(substr_count(strtolower($vcard['fullname']), strtolower($query)) > 0) {
$link = OCP\Util::linkTo('contacts', 'index.php').'&id='.urlencode($vcard['id']);
- $results[]=new OC_Search_Result($vcard['fullname'],'', $link,(string)$l->t('Contact'));//$name,$text,$link,$type
+ $results[]=new OC_Search_Result($vcard['fullname'], '', $link, (string)$l->t('Contact'));//$name,$text,$link,$type
}
}
}
diff --git a/apps/contacts/lib/vcard.php b/apps/contacts/lib/vcard.php
index e3b65605624..ca171e792fc 100644
--- a/apps/contacts/lib/vcard.php
+++ b/apps/contacts/lib/vcard.php
@@ -63,9 +63,9 @@ class OC_Contacts_VCard{
$stmt = OCP\DB::prepare( $prep );
$result = $stmt->execute($id);
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', ids: '.join(',', $id),OCP\Util::DEBUG);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.'SQL:'.$prep,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', ids: '.join(',', $id), OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.'SQL:'.$prep, OCP\Util::DEBUG);
return false;
}
} elseif(is_int($id) || is_string($id)) {
@@ -74,12 +74,12 @@ class OC_Contacts_VCard{
$stmt = OCP\DB::prepare( $sql );
$result = $stmt->execute(array($id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', ids: '. $id,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', ids: '. $id, OCP\Util::DEBUG);
return false;
}
} else {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.'. Addressbook id(s) argument is empty: '. $id,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.'. Addressbook id(s) argument is empty: '. $id, OCP\Util::DEBUG);
return false;
}
$cards = array();
@@ -102,8 +102,8 @@ class OC_Contacts_VCard{
$stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE id = ?' );
$result = $stmt->execute(array($id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '. $id,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '. $id, OCP\Util::DEBUG);
return false;
}
@@ -121,8 +121,8 @@ class OC_Contacts_VCard{
$stmt = OCP\DB::prepare( 'SELECT * FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri = ?' );
$result = $stmt->execute(array($aid,$uri));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', aid: '.$aid.' uri'.$uri, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', aid: '.$aid.' uri'.$uri, OCP\Util::DEBUG);
return false;
}
@@ -177,16 +177,16 @@ class OC_Contacts_VCard{
try {
$result = $stmt->execute(array($aid,$uri));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', aid: '.$aid.' uid'.$uid, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', aid: '.$aid.' uid'.$uid, OCP\Util::DEBUG);
return false;
}
- if($result->numRows() > 0){
+ if($result->numRows() > 0) {
while(true) {
- $tmpuid = substr(md5(rand().time()),0,10);
+ $tmpuid = substr(md5(rand().time()), 0, 10);
$uri = $tmpuid.'.vcf';
- $result = $stmt->execute(array($aid,$uri));
- if($result->numRows() > 0){
+ $result = $stmt->execute(array($aid, $uri));
+ if($result->numRows() > 0) {
continue;
} else {
$uid = $tmpuid;
@@ -212,7 +212,7 @@ class OC_Contacts_VCard{
// Add version if needed
if($version && $version < '3.0') {
$upgrade = true;
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. Updating from version: '.$version,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::updateValuesFromAdd. Updating from version: '.$version, OCP\Util::DEBUG);
}
foreach($vcard->children as &$property){
// Decode string properties and remove obsolete properties.
@@ -225,29 +225,29 @@ class OC_Contacts_VCard{
}
// Fix format of type parameters.
if($upgrade && in_array($property->name, $typeprops)) {
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. before: '.$property->serialize(),OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::updateValuesFromAdd. before: '.$property->serialize(), OCP\Util::DEBUG);
self::formatPropertyTypes($property);
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. after: '.$property->serialize(),OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::updateValuesFromAdd. after: '.$property->serialize(), OCP\Util::DEBUG);
}
- if($property->name == 'FN'){
+ if($property->name == 'FN') {
$fn = $property->value;
}
- if($property->name == 'N'){
+ if($property->name == 'N') {
$n = $property->value;
}
- if($property->name == 'UID'){
+ if($property->name == 'UID') {
$uid = $property->value;
}
- if($property->name == 'ORG'){
+ if($property->name == 'ORG') {
$org = $property->value;
}
- if($property->name == 'EMAIL' && is_null($email)){ // only use the first email as substitute for missing N or FN.
+ if($property->name == 'EMAIL' && is_null($email)) { // only use the first email as substitute for missing N or FN.
$email = $property->value;
}
}
// Check for missing 'N', 'FN' and 'UID' properties
if(!$fn) {
- if($n && $n != ';;;;'){
+ if($n && $n != ';;;;') {
$fn = join(' ', array_reverse(array_slice(explode(';', $n), 0, 2)));
} elseif($email) {
$fn = $email;
@@ -257,21 +257,21 @@ class OC_Contacts_VCard{
$fn = 'Unknown Name';
}
$vcard->setString('FN', $fn);
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. Added missing \'FN\' field: '.$fn,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::updateValuesFromAdd. Added missing \'FN\' field: '.$fn, OCP\Util::DEBUG);
}
- if(!$n || $n == ';;;;'){ // Fix missing 'N' field. Ugly hack ahead ;-)
+ if(!$n || $n == ';;;;') { // Fix missing 'N' field. Ugly hack ahead ;-)
$slice = array_reverse(array_slice(explode(' ', $fn), 0, 2)); // Take 2 first name parts of 'FN' and reverse.
if(count($slice) < 2) { // If not enought, add one more...
$slice[] = "";
}
$n = implode(';', $slice).';;;';
$vcard->setString('N', $n);
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. Added missing \'N\' field: '.$n,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::updateValuesFromAdd. Added missing \'N\' field: '.$n, OCP\Util::DEBUG);
}
if(!$uid) {
$vcard->setUID();
$uid = $vcard->getAsString('UID');
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. Added missing \'UID\' field: '.$uid,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::updateValuesFromAdd. Added missing \'UID\' field: '.$uid, OCP\Util::DEBUG);
}
if(self::trueUID($aid, $uid)) {
$vcard->setString('UID', $uid);
@@ -288,8 +288,8 @@ class OC_Contacts_VCard{
* @return insertid on success or false.
*/
public static function add($aid, OC_VObject $card, $uri=null, $isnew=false){
- if(is_null($card)){
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::add. No vCard supplied', OCP\Util::ERROR);
+ if(is_null($card)) {
+ OCP\Util::writeLog('contacts', 'OC_Contacts_VCard::add. No vCard supplied', OCP\Util::ERROR);
return null;
};
@@ -298,7 +298,7 @@ class OC_Contacts_VCard{
self::updateValuesFromAdd($aid, $card);
}
- $card->setString('VERSION','3.0');
+ $card->setString('VERSION', '3.0');
// Add product ID is missing.
$prodid = trim($card->getAsString('PRODID'));
if(!$prodid) {
@@ -323,8 +323,8 @@ class OC_Contacts_VCard{
try {
$result = $stmt->execute(array($aid,$fn,$data,$uri,time()));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', aid: '.$aid.' uri'.$uri, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', aid: '.$aid.' uri'.$uri, OCP\Util::DEBUG);
return false;
}
$newid = OCP\DB::insertid('*PREFIX*contacts_cards');
@@ -355,15 +355,15 @@ class OC_Contacts_VCard{
$now = new DateTime;
foreach($objects as $object) {
$vcard = OC_VObject::parse($object[1]);
- if(!is_null($vcard)){
+ if(!is_null($vcard)) {
$vcard->setString('REV', $now->format(DateTime::W3C));
$data = $vcard->serialize();
try {
$result = $stmt->execute(array($data,time(),$object[0]));
//OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateDataByID, id: '.$object[0].': '.$object[1],OCP\Util::DEBUG);
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$object[0],OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '.$object[0], OCP\Util::DEBUG);
}
}
}
@@ -397,8 +397,8 @@ class OC_Contacts_VCard{
try {
$result = $stmt->execute(array($fn,$data,time(),$id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id'.$id, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id'.$id, OCP\Util::DEBUG);
return false;
}
@@ -414,11 +414,11 @@ class OC_Contacts_VCard{
* @param string $data vCard file
* @return boolean
*/
- public static function editFromDAVData($aid,$uri,$data){
- $oldcard = self::findWhereDAVDataIs($aid,$uri);
+ public static function editFromDAVData($aid, $uri, $data){
+ $oldcard = self::findWhereDAVDataIs($aid, $uri);
$card = OC_VObject::parse($data);
if(!$card) {
- OCP\Util::writeLog('contacts','OC_Contacts_VCard::editFromDAVData. Unable to parse VCARD, uri: '.$uri,OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', Unable to parse VCARD, uri: '.$uri, OCP\Util::ERROR);
return false;
}
return self::edit($oldcard['id'], $card);
@@ -430,14 +430,13 @@ class OC_Contacts_VCard{
* @return boolean
*/
public static function delete($id){
- // FIXME: Add error checking.
OC_Hook::emit('OC_Contacts_VCard', 'pre_deleteVCard', array('aid' => null, 'id' => $id, 'uri' => null));
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE id = ?' );
try {
$stmt->execute(array($id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', id: '.$id, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', id: '.$id, OCP\Util::DEBUG);
return false;
}
@@ -451,14 +450,13 @@ class OC_Contacts_VCard{
* @return boolean
*/
public static function deleteFromDAVData($aid,$uri){
- // FIXME: Add error checking. Deleting a card gives an Kontact/Akonadi error.
OC_Hook::emit('OC_Contacts_VCard', 'pre_deleteVCard', array('aid' => $aid, 'id' => null, 'uri' => $uri));
$stmt = OCP\DB::prepare( 'DELETE FROM *PREFIX*contacts_cards WHERE addressbookid = ? AND uri=?' );
try {
$stmt->execute(array($aid,$uri));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', aid: '.$aid.' uri: '.$uri, OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', aid: '.$aid.' uri: '.$uri, OCP\Util::DEBUG);
return false;
}
OC_Contacts_Addressbook::touch($aid);
@@ -487,14 +485,14 @@ class OC_Contacts_VCard{
* @return array
*/
public static function unescapeDelimiters($value, $delimiter=';') {
- $array = explode($delimiter,$value);
+ $array = explode($delimiter, $value);
for($i=0;$i<count($array);$i++) {
- if(substr($array[$i],-1,1)=="\\") {
+ if(substr($array[$i], -1, 1)=="\\") {
if(isset($array[$i+1])) {
- $array[$i] = substr($array[$i],0,count($array[$i])-2).$delimiter.$array[$i+1];
+ $array[$i] = substr($array[$i], 0, count($array[$i])-2).$delimiter.$array[$i+1];
unset($array[$i+1]);
} else {
- $array[$i] = substr($array[$i],0,count($array[$i])-2).$delimiter;
+ $array[$i] = substr($array[$i], 0, count($array[$i])-2).$delimiter;
}
$i = $i - 1;
}
@@ -510,12 +508,12 @@ class OC_Contacts_VCard{
*
* look at code ...
*/
- public static function structureContact($object){
+ public static function structureContact($object) {
$details = array();
foreach($object->children as $property){
$temp = self::structureProperty($property);
if(!is_null($temp)) {
- if(array_key_exists($property->name,$details)){
+ if(array_key_exists($property->name, $details)) {
$details[$property->name][] = $temp;
}
else{
@@ -539,10 +537,10 @@ class OC_Contacts_VCard{
* NOTE: $value is not escaped anymore. It shouldn't make any difference
* but we should look out for any problems.
*/
- public static function structureProperty($property){
+ public static function structureProperty($property) {
$value = $property->value;
//$value = htmlspecialchars($value);
- if($property->name == 'ADR' || $property->name == 'N'){
+ if($property->name == 'ADR' || $property->name == 'N') {
$value = self::unescapeDelimiters($value);
} elseif($property->name == 'BDAY') {
if(strpos($value, '-') === false) {
@@ -562,17 +560,17 @@ class OC_Contacts_VCard{
// Faulty entries by kaddressbook
// Actually TYPE=PREF is correct according to RFC 2426
// but this way is more handy in the UI. Tanghus.
- if($parameter->name == 'TYPE' && $parameter->value == 'PREF'){
+ if($parameter->name == 'TYPE' && $parameter->value == 'PREF') {
$parameter->name = 'PREF';
$parameter->value = '1';
}
// NOTE: Apparently Sabre_VObject_Reader can't always deal with value list parameters
// like TYPE=HOME,CELL,VOICE. Tanghus.
- if (in_array($property->name, array('TEL', 'EMAIL')) && $parameter->name == 'TYPE'){
- if (isset($temp['parameters'][$parameter->name])){
+ if (in_array($property->name, array('TEL', 'EMAIL')) && $parameter->name == 'TYPE') {
+ if (isset($temp['parameters'][$parameter->name])) {
$temp['parameters'][$parameter->name][] = $parameter->value;
}
- else{
+ else {
$temp['parameters'][$parameter->name] = array($parameter->value);
}
}
@@ -590,7 +588,7 @@ class OC_Contacts_VCard{
* @return boolean
*
*/
- public static function moveToAddressBook($aid, $id){
+ public static function moveToAddressBook($aid, $id) {
OC_Contacts_App::getAddressbook($aid); // check for user ownership.
if(is_array($id)) {
$id_sql = join(',', array_fill(0, count($id), '?'));
@@ -601,9 +599,9 @@ class OC_Contacts_VCard{
$vals = array_merge((array)$aid, $id);
$result = $stmt->execute($vals);
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::ERROR);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', ids: '.join(',', $vals),OCP\Util::DEBUG);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', SQL:'.$prep,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', ids: '.join(',', $vals), OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', SQL:'.$prep, OCP\Util::DEBUG);
return false;
}
} else {
@@ -611,8 +609,8 @@ class OC_Contacts_VCard{
$stmt = OCP\DB::prepare( 'UPDATE *PREFIX*contacts_cards SET addressbookid = ? WHERE id = ?' );
$result = $stmt->execute(array($aid, $id));
} catch(Exception $e) {
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(),OCP\Util::DEBUG);
- OCP\Util::writeLog('contacts',__CLASS__.'::'.__METHOD__.' id: '.$id,OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.', exception: '.$e->getMessage(), OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts', __CLASS__.'::'.__METHOD__.' id: '.$id, OCP\Util::DEBUG);
return false;
}
}
diff --git a/apps/contacts/photo.php b/apps/contacts/photo.php
index 4660d61f618..efdf157cd95 100644
--- a/apps/contacts/photo.php
+++ b/apps/contacts/photo.php
@@ -13,7 +13,7 @@
OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('contacts');
-function getStandardImage(){
+function getStandardImage() {
//OCP\Response::setExpiresHeader('P10D');
OCP\Response::enableCaching();
OCP\Response::redirect(OCP\Util::imagePath('contacts', 'person_large.png'));
@@ -27,37 +27,39 @@ if(is_null($id)) {
}
if(!extension_loaded('gd') || !function_exists('gd_info')) {
- OCP\Util::writeLog('contacts','photo.php. GD module not installed',OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts',
+ 'photo.php. GD module not installed', OCP\Util::DEBUG);
getStandardImage();
}
$contact = OC_Contacts_App::getContactVCard($id);
$image = new OC_Image();
-if(!$image) {
+if (!$image) {
getStandardImage();
}
// invalid vcard
-if( is_null($contact)) {
- OCP\Util::writeLog('contacts','photo.php. The VCard for ID '.$id.' is not RFC compatible',OCP\Util::ERROR);
+if (is_null($contact)) {
+ OCP\Util::writeLog('contacts',
+ 'photo.php. The VCard for ID ' . $id . ' is not RFC compatible',
+ OCP\Util::ERROR);
} else {
OCP\Response::enableCaching($caching);
OC_Contacts_App::setLastModifiedHeader($contact);
// Photo :-)
- if($image->loadFromBase64($contact->getAsString('PHOTO'))) {
+ if ($image->loadFromBase64($contact->getAsString('PHOTO'))) {
// OK
OCP\Response::setETagHeader(md5($contact->getAsString('PHOTO')));
}
else
// Logo :-/
- if($image->loadFromBase64($contact->getAsString('LOGO'))) {
+ if ($image->loadFromBase64($contact->getAsString('LOGO'))) {
// OK
OCP\Response::setETagHeader(md5($contact->getAsString('LOGO')));
}
if ($image->valid()) {
$max_size = 200;
- if($image->width() > $max_size ||
- $image->height() > $max_size) {
+ if ($image->width() > $max_size || $image->height() > $max_size) {
$image->resize($max_size);
}
}
@@ -65,8 +67,7 @@ if( is_null($contact)) {
if (!$image->valid()) {
// Not found :-(
getStandardImage();
- //$image->loadFromFile('img/person_large.png');
}
header('Content-Type: '.$image->mimeType());
$image->show();
-//echo OC_Contacts_App::$l10n->t('This card does not contain a photo.');
+
diff --git a/apps/contacts/settings.php b/apps/contacts/settings.php
index c88fed0b4d6..a079499381b 100644
--- a/apps/contacts/settings.php
+++ b/apps/contacts/settings.php
@@ -1,6 +1,6 @@
<?php
$tmpl = new OCP\Template( 'contacts', 'settings');
+$tmpl->assign('addressbooks', OC_Contacts_Addressbook::all(OCP\USER::getUser()), false);
return $tmpl->fetchPage();
-?>
diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php
index a8fb6c57c2c..b2dde12684c 100644
--- a/apps/contacts/templates/index.php
+++ b/apps/contacts/templates/index.php
@@ -1,3 +1,4 @@
+<div id='notification'></div>
<script type='text/javascript'>
var totalurl = '<?php echo OCP\Util::linkToRemote('carddav'); ?>addressbooks';
var categories = <?php echo json_encode($_['categories']); ?>;
@@ -5,25 +6,69 @@
var lang = '<?php echo OCP\Config::getUserValue(OCP\USER::getUser(), 'core', 'lang', 'en'); ?>';
</script>
<div id="leftcontent">
+ <div class="hidden" id="statusbar"></div>
<div id="contacts">
</div>
+ <div id="uploadprogressbar"></div>
<div id="bottomcontrols">
- <form>
- <button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::imagePath('contacts', 'contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button>
+ <form id="import_upload_form" action="<?php echo OCP\Util::linkTo('contacts', 'ajax/uploadimport.php'); ?>" method="post" enctype="multipart/form-data" target="import_upload_target">
+ <button class="svg" id="contacts_newcontact" title="<?php echo $l->t('Add Contact'); ?>"><img class="svg" src="<?php echo OCP\Util::imagePath('contacts', 'contact-new.svg'); ?>" alt="<?php echo $l->t('Add Contact'); ?>" /></button>
+ <span class="svg" id="contacts_import" title="<?php echo $l->t('Import'); ?>">
+ <input class="float" id="import_upload_start" type="file" accept="text/directory,text/vcard,text/x-vcard" name="importfile" />
+ <img class="svg" src="core/img/actions/upload.svg" alt="<?php echo $l->t('Import'); ?>" />
+ </span>
<button class="svg" id="chooseaddressbook" title="<?php echo $l->t('Addressbooks'); ?>"><img class="svg" src="core/img/actions/settings.svg" alt="<?php echo $l->t('Addressbooks'); ?>" /></button>
+ <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $_['uploadMaxFilesize'] ?>" id="max_upload">
</form>
+ <iframe name="import_upload_target" id='import_upload_target' src=""></iframe>
</div>
</div>
<div id="rightcontent" class="rightcontent" data-id="<?php echo $_['id']; ?>">
<?php
- if ($_['id']){
+ if($_['has_contacts']) {
echo $this->inc('part.contact');
}
else{
echo $this->inc('part.no_contacts');
}
?>
+ <div class="hidden" id="ninjahelp">
+ <a class="close" tabindex="0" role="button">
+ <img class="svg" src="core/img/actions/delete.svg" alt="<?php echo $l->t('Close'); ?>" />
+ </a>
+ <h2><?php echo $l->t('Keyboard shortcuts'); ?></h2>
+ <div class="help-section">
+ <h3><?php echo $l->t('Navigation'); ?></h3>
+ <dl>
+ <dt>j/Down/Space</dt>
+ <dd><?php echo $l->t('Next contact in list'); ?></dd>
+ <dt>k/Up/Shift-Space</dt>
+ <dd><?php echo $l->t('Previous contact in list'); ?></dd>
+ <dt>o/Enter</dt>
+ <dd><?php echo $l->t('Expand/collapse current addressbook'); ?></dd>
+ <dt>n/p</dt>
+ <dd><?php echo $l->t('Next/previous addressbook'); ?></dd>
+ </dl>
+ </div>
+ <div class="help-section">
+ <h3><?php echo $l->t('Actions'); ?></h3>
+ <dl>
+ <dt>r</dt>
+ <dd><?php echo $l->t('Refresh contacts list'); ?></dd>
+ <dt>a</dt>
+ <dd><?php echo $l->t('Add new contact'); ?></dd>
+ <dt>Shift-a</dt>
+ <dd><?php echo $l->t('Add new addressbook'); ?></dd>
+ <dt>Shift-Delete</dt>
+ <dd><?php echo $l->t('Delete current contact'); ?></dd>
+ </dl>
+ </div>
+ </div>
</div>
<!-- Dialogs -->
<div id="dialog_holder"></div>
<!-- End of Dialogs -->
+<menu type="context" id="addressbookmenu">
+ <menuitem label="Delete" icon="core/img/actions/delete.svg" onclick="alert('Really? ' + $(this).attr('data-id'))"></menuitem>
+ <menuitem label="Rename" icon="core/img/actions/rename.svg" onclick="alert('Can\'t do that')"></menuitem>
+</menu>
diff --git a/apps/contacts/templates/part.chooseaddressbook.php b/apps/contacts/templates/part.chooseaddressbook.php
index a0ec053ab91..caed67736c5 100644
--- a/apps/contacts/templates/part.chooseaddressbook.php
+++ b/apps/contacts/templates/part.chooseaddressbook.php
@@ -14,7 +14,6 @@ for($i = 0; $i < count($option_addressbooks); $i++){
<tr>
<td colspan="5" style="padding: 0.5em;">
<a class="button" href="#" onclick="Contacts.UI.Addressbooks.newAddressbook(this);"><?php echo $l->t('New Address Book') ?></a>
- <a class="button" href="#" onclick="Contacts.UI.Addressbooks.importAddressbook(this);"><?php echo $l->t('Import from VCF') ?></a>
</td>
</tr>
<tr>
diff --git a/apps/contacts/templates/part.cropphoto.php b/apps/contacts/templates/part.cropphoto.php
index 6d7b1e44777..3f5817622b2 100644
--- a/apps/contacts/templates/part.cropphoto.php
+++ b/apps/contacts/templates/part.cropphoto.php
@@ -2,7 +2,6 @@
$id = $_['id'];
$tmpkey = $_['tmpkey'];
$requesttoken = $_['requesttoken'];
-OCP\Util::writeLog('contacts','templates/part.cropphoto.php: tmpkey: '.$tmpkey, OCP\Util::DEBUG);
?>
<script type="text/javascript">
jQuery(function($) {
diff --git a/apps/contacts/templates/part.edit_categories_dialog.php b/apps/contacts/templates/part.edit_categories_dialog.php
deleted file mode 100644
index 8997fa586bd..00000000000
--- a/apps/contacts/templates/part.edit_categories_dialog.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-$categories = isset($_['categories'])?$_['categories']:array();
-?>
-<div id="edit_categories_dialog" title="<?php echo $l->t('Edit categories'); ?>">
-<!-- ?php print_r($types); ? -->
- <form method="post" id="categoryform">
- <div class="scrollarea">
- <ul id="categorylist">
- <?php foreach($categories as $category) { ?>
- <li><input type="checkbox" name="categories[]" value="<?php echo $category; ?>" /><?php echo $category; ?></li>
- <?php } ?>
- </ul>
- </div>
- <div class="bottombuttons"><input type="text" id="category_addinput" name="category" /><button id="category_addbutton" disabled="disabled"><?php echo $l->t('Add'); ?></button></div>
- </form>
-</div>
diff --git a/apps/contacts/templates/part.importaddressbook.php b/apps/contacts/templates/part.importaddressbook.php
deleted file mode 100644
index 01f8dd77d0a..00000000000
--- a/apps/contacts/templates/part.importaddressbook.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- * Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net>
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-?>
-<td id="importaddressbook_dialog" colspan="6">
-<table>
-<tr>
- <th><?php echo $l->t('Select address book to import to:') ?></th>
- <td>
- <form id="import_upload_form" action="<?php echo OCP\Util::linkTo('contacts', 'ajax/uploadimport.php'); ?>" method="post" enctype="multipart/form-data" target="import_upload_target">
- <select id="book" name="book" class="float">
- <?php
- $contacts_options = OC_Contacts_Addressbook::all(OCP\USER::getUser());
- echo OCP\html_select_options($contacts_options, $contacts_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
- ?>
- </select>
- <span id="import_drop_target" class="droptarget float"><?php echo $l->t("Drop a VCF file<br />to import contacts."); ?> (Max. <?php echo $_['uploadMaxHumanFilesize']; ?>)</span>
- <a class="svg upload float" title="<?php echo $l->t('Select from HD'); ?>">
- <input class="float" id="import_upload_start" type="file" accept="text/*" name="importfile" /></a>
- <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $_['uploadMaxFilesize'] ?>" id="max_upload">
- </form>
- </td>
-</tr>
-</table>
-
-<input id="close_button" style="float: left;" type="button" onclick="Contacts.UI.Addressbooks.cancel(this);" value="<?php echo $l->t("Cancel"); ?>">
-<iframe name="import_upload_target" id='import_upload_target' src=""></iframe>
-</td>
-<script type="text/javascript">
-$(document).ready(function(){
- Contacts.UI.Addressbooks.loadImportHandlers();
-});
-</script> \ No newline at end of file
diff --git a/apps/contacts/templates/part.selectaddressbook.php b/apps/contacts/templates/part.selectaddressbook.php
new file mode 100644
index 00000000000..c54ddaf2e67
--- /dev/null
+++ b/apps/contacts/templates/part.selectaddressbook.php
@@ -0,0 +1,27 @@
+<div id="selectaddressbook_dialog" title="<?php echo $l->t("Select Address Books"); ?>">
+<form>
+<table style="width: 100%">
+ <?php foreach($_['addressbooks'] as $idx => $addressbook) { ?>
+ <tr>
+ <td>
+ <input id="book_<?php echo $addressbook['id']; ?>" name="book" type="radio" value="<?php echo $addressbook['id']; ?>" <?php echo ($idx==0?'checked="checked"':'')?>>
+ </td>
+ <td>
+ <label for="book_<?php echo $addressbook['id']; ?>"><?php echo $addressbook['displayname']; ?></label>
+ </td>
+ <td><?php echo $addressbook['description']; ?></td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <td>
+ <input id="book_new" name="book" type="radio" value="new">
+ </td>
+ <th>
+ <input type="text" class="name" name="displayname" placeholder="<?php echo $l->t("Enter name"); ?>" />
+ </th>
+ <td><input type="text" class="desc" name="description" placeholder="<?php echo $l->t("Enter description"); ?>" /></td>
+ </tr>
+</table>
+</form>
+</div>
+
diff --git a/apps/contacts/templates/settings.php b/apps/contacts/templates/settings.php
index 216003b6c69..f520559d143 100644
--- a/apps/contacts/templates/settings.php
+++ b/apps/contacts/templates/settings.php
@@ -7,6 +7,12 @@
<dd><code><?php echo OCP\Util::linkToRemote('carddav'); ?></code></dd>
<dt><?php echo $l->t('iOS/OS X'); ?></dt>
<dd><code><?php echo OCP\Util::linkToRemote('carddav'); ?>principals/<?php echo OCP\USER::getUser(); ?></code>/</dd>
+ <dt><?php echo $l->t('Read only vCard directory link(s)'); ?></dt>
+ <dd>
+ <?php foreach($_['addressbooks'] as $addressbook) { ?>
+ <a href="<?php echo OCP\Util::linkToRemote('carddav').'addressbooks/'.OCP\USER::getUser().'/'.rawurlencode($addressbook['uri']) ?>?export"><?php echo $addressbook['displayname'] ?></a><br />
+ <?php } ?>
+ </dd>
</dl>
Powered by <a href="http://geonames.org/" target="_blank">geonames.org webservice</a>
</fieldset>
diff --git a/apps/contacts/thumbnail.php b/apps/contacts/thumbnail.php
index a69e9c74f72..6deb5ca379e 100644
--- a/apps/contacts/thumbnail.php
+++ b/apps/contacts/thumbnail.php
@@ -25,14 +25,15 @@ OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('contacts');
session_write_close();
-function getStandardImage(){
+function getStandardImage() {
//OCP\Response::setExpiresHeader('P10D');
OCP\Response::enableCaching();
OCP\Response::redirect(OCP\Util::imagePath('contacts', 'person.png'));
}
if(!extension_loaded('gd') || !function_exists('gd_info')) {
- OCP\Util::writeLog('contacts','thumbnail.php. GD module not installed',OCP\Util::DEBUG);
+ OCP\Util::writeLog('contacts',
+ 'thumbnail.php. GD module not installed', OCP\Util::DEBUG);
getStandardImage();
exit();
}
@@ -43,8 +44,10 @@ $caching = isset($_GET['refresh']) ? 0 : null;
$contact = OC_Contacts_App::getContactVCard($id);
// invalid vcard
-if(is_null($contact)){
- OCP\Util::writeLog('contacts','thumbnail.php. The VCard for ID '.$id.' is not RFC compatible',OCP\Util::ERROR);
+if(is_null($contact)) {
+ OCP\Util::writeLog('contacts',
+ 'thumbnail.php. The VCard for ID ' . $id . ' is not RFC compatible',
+ OCP\Util::ERROR);
getStandardImage();
exit();
}
@@ -64,16 +67,24 @@ if($photo) {
if($image->show()) {
exit();
} else {
- OCP\Util::writeLog('contacts','thumbnail.php. Couldn\'t display thumbnail for ID '.$id,OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',
+ 'thumbnail.php. Couldn\'t display thumbnail for ID ' . $id,
+ OCP\Util::ERROR);
}
} else {
- OCP\Util::writeLog('contacts','thumbnail.php. Couldn\'t resize thumbnail for ID '.$id,OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',
+ 'thumbnail.php. Couldn\'t resize thumbnail for ID ' . $id,
+ OCP\Util::ERROR);
}
}else{
- OCP\Util::writeLog('contacts','thumbnail.php. Couldn\'t crop thumbnail for ID '.$id,OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',
+ 'thumbnail.php. Couldn\'t crop thumbnail for ID ' . $id,
+ OCP\Util::ERROR);
}
} else {
- OCP\Util::writeLog('contacts','thumbnail.php. Couldn\'t load image string for ID '.$id,OCP\Util::ERROR);
+ OCP\Util::writeLog('contacts',
+ 'thumbnail.php. Couldn\'t load image string for ID ' . $id,
+ OCP\Util::ERROR);
}
}
getStandardImage();
diff --git a/apps/contacts/tmpphoto.php b/apps/contacts/tmpphoto.php
index 5fde8de9977..156d5c80308 100644
--- a/apps/contacts/tmpphoto.php
+++ b/apps/contacts/tmpphoto.php
@@ -24,7 +24,7 @@ $tmpkey = $_GET['tmpkey'];
$maxsize = isset($_GET['maxsize']) ? $_GET['maxsize'] : -1;
header("Cache-Control: no-cache, no-store, must-revalidate");
-OCP\Util::writeLog('contacts','tmpphoto.php: tmpkey: '.$tmpkey, OCP\Util::DEBUG);
+OCP\Util::writeLog('contacts', 'tmpphoto.php: tmpkey: '.$tmpkey, OCP\Util::DEBUG);
$image = new OC_Image();
$image->loadFromData(OC_Cache::get($tmpkey));
diff --git a/apps/external/ajax/setsites.php b/apps/external/ajax/setsites.php
index 772863974ae..0f9e061d0e0 100644
--- a/apps/external/ajax/setsites.php
+++ b/apps/external/ajax/setsites.php
@@ -8,6 +8,7 @@
OCP\User::checkAdminUser();
+OCP\JSON::callCheck();
$sites = array();
for ($i = 0; $i < sizeof($_POST['site_name']); $i++) {
@@ -22,4 +23,3 @@ else
OCP\Config::setAppValue('external', 'sites', json_encode($sites));
echo 'true';
-?>
diff --git a/apps/external/index.php b/apps/external/index.php
index 81819e76e2f..3b6f06e1bff 100644
--- a/apps/external/index.php
+++ b/apps/external/index.php
@@ -40,4 +40,3 @@ if (isset($_GET['id'])) {
$tmpl->printPage();
}
}
-?>
diff --git a/apps/external/lib/external.php b/apps/external/lib/external.php
index 9fff5d5569a..d13a7cf6dd7 100644
--- a/apps/external/lib/external.php
+++ b/apps/external/lib/external.php
@@ -32,5 +32,3 @@ class OC_External {
}
}
-
-?>
diff --git a/apps/external/settings.php b/apps/external/settings.php
index c109733e548..488444c119a 100644
--- a/apps/external/settings.php
+++ b/apps/external/settings.php
@@ -7,4 +7,3 @@ OCP\Util::addscript( "external", "admin" );
$tmpl = new OCP\Template( 'external', 'settings');
return $tmpl->fetchPage();
-?>
diff --git a/apps/files/ajax/autocomplete.php b/apps/files/ajax/autocomplete.php
index 7ff34da96b3..e504bb24bf8 100644
--- a/apps/files/ajax/autocomplete.php
+++ b/apps/files/ajax/autocomplete.php
@@ -52,5 +52,3 @@ if(OC_Filesystem::file_exists($base) and OC_Filesystem::is_dir($base)){
}
}
OCP\JSON::encodedPrint($files);
-
-?>
diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php
index ed155de0dc7..695f803884e 100644
--- a/apps/files/ajax/delete.php
+++ b/apps/files/ajax/delete.php
@@ -4,6 +4,7 @@
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
// Get data
$dir = stripslashes($_GET["dir"]);
@@ -25,5 +26,3 @@ if($success) {
} else {
OCP\JSON::error(array("data" => array( "message" => "Could not delete:\n" . $filesWithError )));
}
-
-?>
diff --git a/apps/files/ajax/download.php b/apps/files/ajax/download.php
index e9373f5f6ac..b9a4ddaf5e7 100644
--- a/apps/files/ajax/download.php
+++ b/apps/files/ajax/download.php
@@ -34,4 +34,3 @@ $files = $_GET["files"];
$dir = $_GET["dir"];
OC_Files::get($dir, $files, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
-?>
diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php
index f0600a179d0..dae0c1a828d 100644
--- a/apps/files/ajax/list.php
+++ b/apps/files/ajax/list.php
@@ -42,5 +42,3 @@ $list->assign( "files", $files, false );
$data = array('files' => $list->fetchPage());
OCP\JSON::success(array('data' => $data));
-
-?>
diff --git a/apps/files/ajax/mimeicon.php b/apps/files/ajax/mimeicon.php
index 57898cd82d9..80d50f84528 100644
--- a/apps/files/ajax/mimeicon.php
+++ b/apps/files/ajax/mimeicon.php
@@ -7,5 +7,3 @@ $RUNTIME_NOAPPS=false;
print OC_Helper::mimetypeIcon($_GET['mime']);
-
-?>
diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php
index 945fe4e7b82..3d4003a8edc 100644
--- a/apps/files/ajax/move.php
+++ b/apps/files/ajax/move.php
@@ -4,6 +4,7 @@
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
// Get data
$dir = stripslashes($_GET["dir"]);
@@ -16,5 +17,3 @@ if(OC_Files::move($dir,$file,$target,$file)){
}else{
OCP\JSON::error(array("data" => array( "message" => "Could not move $file" )));
}
-
-?>
diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php
index edb78414872..cc9208ad08f 100644
--- a/apps/files/ajax/newfile.php
+++ b/apps/files/ajax/newfile.php
@@ -1,15 +1,25 @@
<?php
// Init owncloud
+global $eventSource;
+if(!OC_User::isLoggedIn()){
+ exit;
+}
-OCP\JSON::checkLoggedIn();
+session_write_close();
// Get the params
-$dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : '';
-$filename = isset( $_POST['filename'] ) ? stripslashes($_POST['filename']) : '';
-$content = isset( $_POST['content'] ) ? $_POST['content'] : '';
-$source = isset( $_POST['source'] ) ? stripslashes($_POST['source']) : '';
+$dir = isset( $_REQUEST['dir'] ) ? stripslashes($_REQUEST['dir']) : '';
+$filename = isset( $_REQUEST['filename'] ) ? stripslashes($_REQUEST['filename']) : '';
+$content = isset( $_REQUEST['content'] ) ? $_REQUEST['content'] : '';
+$source = isset( $_REQUEST['source'] ) ? stripslashes($_REQUEST['source']) : '';
+
+if($source){
+ $eventSource=new OC_EventSource();
+}else{
+ OC_JSON::callCheck();
+}
if($filename == '') {
OCP\JSON::error(array("data" => array( "message" => "Empty Filename" )));
@@ -20,22 +30,49 @@ if(strpos($filename,'/')!==false){
exit();
}
+function progress($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max){
+ static $filesize = 0;
+ static $lastsize = 0;
+ global $eventSource;
+
+ switch($notification_code) {
+ case STREAM_NOTIFY_FILE_SIZE_IS:
+ $filesize = $bytes_max;
+ break;
+
+ case STREAM_NOTIFY_PROGRESS:
+ if ($bytes_transferred > 0) {
+ if (!isset($filesize)) {
+ } else {
+ $progress = (int)(($bytes_transferred/$filesize)*100);
+ if($progress>$lastsize){//limit the number or messages send
+ $eventSource->send('progress',$progress);
+ }
+ $lastsize=$progress;
+ }
+ }
+ break;
+ }
+}
+
if($source){
if(substr($source,0,8)!='https://' and substr($source,0,7)!='http://'){
OCP\JSON::error(array("data" => array( "message" => "Not a valid source" )));
exit();
}
- $sourceStream=fopen($source,'rb');
+
+ $ctx = stream_context_create(null, array('notification' =>'progress'));
+ $sourceStream=fopen($source,'rb', false, $ctx);
$target=$dir.'/'.$filename;
$result=OC_Filesystem::file_put_contents($target,$sourceStream);
if($result){
$mime=OC_Filesystem::getMimetype($target);
- OCP\JSON::success(array("data" => array('mime'=>$mime)));
- exit();
+ $eventSource->send('success',$mime);
}else{
- OCP\JSON::error(array("data" => array( "message" => "Error while downloading ".$source. ' to '.$target )));
- exit();
+ $eventSource->send('error',"Error while downloading ".$source. ' to '.$target);
}
+ $eventSource->close();
+ exit();
}else{
if($content){
if(OC_Filesystem::file_put_contents($dir.'/'.$filename,$content)){
diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php
index c5c37914c6a..ae92bcf09bb 100644
--- a/apps/files/ajax/newfolder.php
+++ b/apps/files/ajax/newfolder.php
@@ -4,6 +4,7 @@
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
// Get the params
$dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : '';
diff --git a/apps/files/ajax/rawlist.php b/apps/files/ajax/rawlist.php
index 7cb02f79673..d159f6e152f 100644
--- a/apps/files/ajax/rawlist.php
+++ b/apps/files/ajax/rawlist.php
@@ -22,5 +22,3 @@ foreach( OC_Files::getdirectorycontent( $dir, $mimetype ) as $i ){
}
OCP\JSON::success(array('data' => $files));
-
-?>
diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php
index e2fa3d54a61..45448279fa1 100644
--- a/apps/files/ajax/rename.php
+++ b/apps/files/ajax/rename.php
@@ -4,6 +4,7 @@
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
// Get data
$dir = stripslashes($_GET["dir"]);
@@ -17,5 +18,3 @@ if( OC_Files::move( $dir, $file, $dir, $newname )) {
else{
OCP\JSON::error(array("data" => array( "message" => "Unable to rename file" )));
}
-
-?>
diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php
index 6fcf97688c2..eef38858516 100644
--- a/apps/files/ajax/scan.php
+++ b/apps/files/ajax/scan.php
@@ -16,6 +16,11 @@ session_write_close();
if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OCP\DB::beginTransaction();
+
+ if(OC_Cache::isFast()){
+ OC_Cache::clear('fileid/'); //make sure the old fileid's don't mess things up
+ }
+
OC_FileCache::scan($dir,$eventSource);
OC_FileCache::clean();
OCP\DB::commit();
diff --git a/apps/files/ajax/timezone.php b/apps/files/ajax/timezone.php
index cafb5074ece..0be441a36a2 100644
--- a/apps/files/ajax/timezone.php
+++ b/apps/files/ajax/timezone.php
@@ -3,4 +3,4 @@
// see lib/base.php for an example
//session_start();
$_SESSION['timezone'] = $_GET['time'];
-?>
+ \ No newline at end of file
diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php
index b779924cfb4..74e6eb560d8 100644
--- a/apps/files/ajax/upload.php
+++ b/apps/files/ajax/upload.php
@@ -7,6 +7,7 @@
OCP\JSON::setContentTypeHeader('text/plain');
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
if (!isset($_FILES['files'])) {
OCP\JSON::error(array("data" => array( "message" => "No file was uploaded. Unknown error" )));
@@ -59,5 +60,3 @@ if(strpos($dir,'..') === false){
}
OCP\JSON::error(array('data' => array('error' => $error, "file" => $fileName)));
-
-?>
diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php
index f9953ba4de5..5514aed197f 100644
--- a/apps/files/appinfo/update.php
+++ b/apps/files/appinfo/update.php
@@ -1,5 +1,16 @@
<?php
+// fix webdav properties, remove namespace information between curly bracket (update from OC4 to OC5)
+$installedVersion=OCP\Config::getAppValue('files', 'installed_version');
+if (version_compare($installedVersion, '1.1.4', '<')) {
+ $query = OC_DB::prepare( "SELECT propertyname, propertypath, userid FROM `*PREFIX*properties`" );
+ $result = $query->execute();
+ while( $row = $result->fetchRow()){
+ $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyname = ? WHERE userid = ? AND propertypath = ?' );
+ $query->execute( array( preg_replace("/^{.*}/", "", $row["propertyname"]),$row["userid"], $row["propertypath"] ));
+ }
+}
+
//update from OC 3
//try to remove remaining files.
diff --git a/apps/files/appinfo/version b/apps/files/appinfo/version
index 8cfbc905b39..1b87bcd0b09 100644
--- a/apps/files/appinfo/version
+++ b/apps/files/appinfo/version
@@ -1 +1 @@
-1.1.1 \ No newline at end of file
+1.1.4 \ No newline at end of file
diff --git a/apps/files/download.php b/apps/files/download.php
index 2b5d4e2d876..4e2478d1ad7 100644
--- a/apps/files/download.php
+++ b/apps/files/download.php
@@ -46,4 +46,3 @@ header('Content-Length: '.OC_Filesystem::filesize($filename));
@ob_end_clean();
OC_Filesystem::readfile( $filename );
-?>
diff --git a/apps/files/index.php b/apps/files/index.php
index ed36c5edab0..79bed8e357e 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -40,6 +40,7 @@ $dir = isset( $_GET['dir'] ) ? stripslashes($_GET['dir']) : '';
// Redirect if directory does not exist
if(!OC_Filesystem::is_dir($dir.'/')) {
header('Location: '.$_SERVER['PHP_SELF'].'');
+ exit();
}
$files = array();
@@ -98,5 +99,3 @@ $tmpl->assign( 'uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign( 'uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize));
$tmpl->assign( 'allowZipDownload', intval(OCP\Config::getSystemValue('allowZipDownload', true)));
$tmpl->printPage();
-
-?>
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index e6a9a6883af..3645258f98f 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -14,7 +14,7 @@ FileList={
var extension=false;
}
html+='<td class="filename" style="background-image:url('+img+')"><input type="checkbox" />';
- html+='<a class="name" href="download.php?file='+$('#dir').val()+'/'+name+'"><span class="nametext">'+basename
+ html+='<a class="name" href="download.php?file='+$('#dir').val().replace(/</, '&lt;').replace(/>/, '&gt;')+'/'+name+'"><span class="nametext">'+basename
if(extension){
html+='<span class="extension">'+extension+'</span>';
}
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 86c5185bf72..a4e2361feeb 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -497,23 +497,27 @@ $(document).ready(function() {
localName=(localName.match(/:\/\/(.[^/]+)/)[1]).replace('www.','');
}
localName = getUniqueName(localName);
- $.post(
- OC.filePath('files','ajax','newfile.php'),
- {dir:$('#dir').val(),source:name,filename:localName},
- function(result){
- if(result.status == 'success'){
- var date=new Date();
- FileList.addFile(localName,0,date);
- var tr=$('tr').filterAttr('data-file',localName);
- tr.data('mime',result.data.mime);
- getMimeIcon(result.data.mime,function(path){
- tr.find('td.filename').attr('style','background-image:url('+path+')');
- });
- }else{
+ $('#uploadprogressbar').progressbar({value:0});
+ $('#uploadprogressbar').fadeIn();
- }
- }
- );
+ var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName});
+ eventSource.listen('progress',function(progress){
+ $('#uploadprogressbar').progressbar('value',progress);
+ });
+ eventSource.listen('success',function(mime){
+ $('#uploadprogressbar').fadeOut();
+ var date=new Date();
+ FileList.addFile(localName,0,date);
+ var tr=$('tr').filterAttr('data-file',localName);
+ tr.data('mime',mime);
+ getMimeIcon(mime,function(path){
+ tr.find('td.filename').attr('style','background-image:url('+path+')');
+ });
+ });
+ eventSource.listen('error',function(error){
+ $('#uploadprogressbar').fadeOut();
+ alert(error);
+ });
break;
}
var li=$(this).parent();
diff --git a/apps/files/settings.php b/apps/files/settings.php
index e5a66239ebd..cd6dd8c1616 100644
--- a/apps/files/settings.php
+++ b/apps/files/settings.php
@@ -56,5 +56,3 @@ $tmpl = new OCP\Template( "files", "index", "user" );
$tmpl->assign( 'files', $files );
$tmpl->assign( "breadcrumb", $breadcrumb );
$tmpl->printPage();
-
-?>
diff --git a/apps/files_encryption/js/settings.js b/apps/files_encryption/js/settings.js
index 37d62265c94..8cc433246cb 100644
--- a/apps/files_encryption/js/settings.js
+++ b/apps/files_encryption/js/settings.js
@@ -17,8 +17,8 @@ $(document).ready(function(){
OC.AppConfig.setValue('files_encryption','type_blacklist',blackList);
}
- $('#enbale_encryption').change(function(){
- var checked=$('#enbale_encryption').is(':checked');
+ $('#enable_encryption').change(function(){
+ var checked=$('#enable_encryption').is(':checked');
OC.AppConfig.setValue('files_encryption','enable_encryption',(checked)?'true':'false');
})
}) \ No newline at end of file
diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php
index e0020537563..46471911d94 100644
--- a/apps/files_encryption/lib/cryptstream.php
+++ b/apps/files_encryption/lib/cryptstream.php
@@ -31,9 +31,7 @@ class OC_CryptStream{
public static $sourceStreams=array();
private $source;
private $path;
- private $readBuffer;//for streams that dont support seeking
private $meta=array();//header/meta for source stream
- private $count;
private $writeCache;
private $size;
private static $rootView;
@@ -100,7 +98,6 @@ class OC_CryptStream{
public function stream_write($data){
$length=strlen($data);
- $written=0;
$currentPos=ftell($this->source);
if($this->writeCache){
$data=$this->writeCache.$data;
diff --git a/apps/files_encryption/templates/settings.php b/apps/files_encryption/templates/settings.php
index 25b5a06f56c..79780d694cf 100644
--- a/apps/files_encryption/templates/settings.php
+++ b/apps/files_encryption/templates/settings.php
@@ -7,6 +7,6 @@
<option selected="selected" value="<?php echo $type;?>"><?php echo $type;?></option>
<?php endforeach;?>
</select>
- <input type='checkbox' id='enbale_encryption' <?php if($_['encryption_enabled']){echo 'checked="checked"';} ?>></input><label for='enbale_encryption'><?php echo $l->t('Enable Encryption')?></label>
+ <input type='checkbox' id='enable_encryption' <?php if($_['encryption_enabled']){echo 'checked="checked"';} ?>></input><label for='enable_encryption'><?php echo $l->t('Enable Encryption')?></label>
</fieldset>
</form>
diff --git a/apps/files_external/ajax/addMountPoint.php b/apps/files_external/ajax/addMountPoint.php
index 549cb6a3427..e08f805942f 100644
--- a/apps/files_external/ajax/addMountPoint.php
+++ b/apps/files_external/ajax/addMountPoint.php
@@ -1,6 +1,8 @@
<?php
OCP\JSON::checkAppEnabled('files_external');
+OCP\JSON::callCheck();
+
if ($_POST['isPersonal'] == 'true') {
OCP\JSON::checkLoggedIn();
$isPersonal = true;
@@ -9,5 +11,3 @@ if ($_POST['isPersonal'] == 'true') {
$isPersonal = false;
}
OC_Mount_Config::addMountPoint($_POST['mountPoint'], $_POST['class'], $_POST['classOptions'], $_POST['mountType'], $_POST['applicable'], $isPersonal);
-
-?>
diff --git a/apps/files_external/ajax/addRootCertificate.php b/apps/files_external/ajax/addRootCertificate.php
index c5f49a82d36..d28a7d24b2d 100644
--- a/apps/files_external/ajax/addRootCertificate.php
+++ b/apps/files_external/ajax/addRootCertificate.php
@@ -5,6 +5,7 @@ OCP\JSON::checkAppEnabled('files_external');
$view = \OCP\Files::getStorage("files_external");
$from = $_FILES['rootcert_import']['tmp_name'];
$path = \OCP\Config::getSystemValue('datadirectory').$view->getAbsolutePath("").'uploads/';
+if(!file_exists($path)) mkdir($path,0700,true);
$to = $path.$_FILES['rootcert_import']['name'];
move_uploaded_file($from, $to);
diff --git a/apps/files_external/ajax/removeMountPoint.php b/apps/files_external/ajax/removeMountPoint.php
index b77b306bcb5..aa446426202 100644
--- a/apps/files_external/ajax/removeMountPoint.php
+++ b/apps/files_external/ajax/removeMountPoint.php
@@ -1,6 +1,8 @@
<?php
OCP\JSON::checkAppEnabled('files_external');
+OCP\JSON::callCheck();
+
if ($_POST['isPersonal'] == 'true') {
OCP\JSON::checkLoggedIn();
$isPersonal = true;
@@ -9,5 +11,3 @@ if ($_POST['isPersonal'] == 'true') {
$isPersonal = false;
}
OC_Mount_Config::removeMountPoint($_POST['mountPoint'], $_POST['mountType'], $_POST['applicable'], $isPersonal);
-
-?>
diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/dropbox.php
index 35663d431f8..c849db38433 100755
--- a/apps/files_external/lib/dropbox.php
+++ b/apps/files_external/lib/dropbox.php
@@ -208,7 +208,7 @@ class OC_Filestorage_Dropbox extends OC_Filestorage_Common {
if (isset(self::$tempFiles[$tmpFile])) {
$handle = fopen($tmpFile, 'r');
try {
- $response = $this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle);
+ $this->dropbox->putFile(self::$tempFiles[$tmpFile], $handle);
unlink($tmpFile);
} catch (Exception $exception) {
diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php
index 41b560ae84e..2ad85d09d5f 100644
--- a/apps/files_external/lib/google.php
+++ b/apps/files_external/lib/google.php
@@ -178,7 +178,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
if ($collection == '/' || $collection == '\.' || $collection == '.') {
$uri = 'https://docs.google.com/feeds/default/private/full';
// Get parent content link
- } else if ($dom = $this->getResource(basename($dir))) {
+ } else if ($dom = $this->getResource(basename($collection))) {
$uri = $dom->getElementsByTagName('content')->item(0)->getAttribute('src');
}
if (isset($uri)) {
@@ -341,7 +341,7 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
break;
}
}
- $title = basename($path);
+ $title = basename($path2);
// Construct post data
$postData = '<?xml version="1.0" encoding="UTF-8"?>';
$postData .= '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:docs="http://schemas.google.com/docs/2007" xmlns:gd="http://schemas.google.com/g/2005" gd:etag='.$etag.'>';
@@ -352,13 +352,13 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
} else {
// Move to different collection
if ($collectionEntry = $this->getResource($collection)) {
- $feedUri = $colelctionEntry->getElementsByTagName('content')->item(0)->getAttribute('src');
+ $feedUri = $collectionEntry->getElementsByTagName('content')->item(0)->getAttribute('src');
// Construct post data
$postData = '<?xml version="1.0" encoding="UTF-8"?>';
$postData .= '<entry xmlns="http://www.w3.org/2005/Atom">';
$postData .= '<id>'.$entry->getElementsByTagName('id')->item(0).'</id>';
$postData .= '</entry>';
- $this->sendRequest($uri, 'POST', $postData);
+ $this->sendRequest($feedUri, 'POST', $postData);
return true;
}
}
@@ -424,7 +424,6 @@ class OC_Filestorage_Google extends OC_Filestorage_Common {
}
}
if (!isset($uploadUri) && $entry) {
- $etag = $entry->getAttribute('gd:etag');
$links = $entry->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->getAttribute('rel') == 'http://schemas.google.com/g/2005#resumable-create-media') {
diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php
index 5e34deb2337..8a5e993b1d0 100644
--- a/apps/files_external/lib/smb.php
+++ b/apps/files_external/lib/smb.php
@@ -15,8 +15,6 @@ class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
private $root;
private $share;
- private static $tempFiles=array();
-
public function __construct($params){
$this->host=$params['host'];
$this->user=$params['user'];
diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php
index ea6ca65b976..84d64b65193 100644
--- a/apps/files_external/lib/webdav.php
+++ b/apps/files_external/lib/webdav.php
@@ -45,7 +45,10 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
$this->client = new OC_Connector_Sabre_Client($settings);
if($caview = \OCP\Files::getStorage('files_external')) {
- $this->client->setCurlSettings(array(CURLOPT_CAINFO => \OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt'));
+ $certPath=\OCP\Config::getSystemValue('datadirectory').$caview->getAbsolutePath("").'rootcerts.crt';
+ if (file_exists($certPath)) {
+ $this->client->addTrustedCertificates($certPath);
+ }
}
//create the root folder if necesary
$this->mkdir('');
@@ -74,16 +77,11 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
$path=$this->cleanPath($path);
try{
$response=$this->client->propfind($path, array(),1);
- $stripLength=strlen($this->root)+strlen($path);
$id=md5('webdav'.$this->root.$path);
OC_FakeDirStream::$dirs[$id]=array();
- $skip = true;
- foreach($response as $file=>$data){
- // Skip the first file, because it is the current directory
- if ($skip) {
- $skip = false;
- continue;
- }
+ $files=array_keys($response);
+ array_shift($files);//the first entry is the current directory
+ foreach($files as $file){
$file = urldecode(basename($file));
OC_FakeDirStream::$dirs[$id][]=$file;
}
@@ -117,7 +115,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
public function file_exists($path){
$path=$this->cleanPath($path);
try{
- $response=$this->client->propfind($path, array('{DAV:}resourcetype'));
+ $this->client->propfind($path, array('{DAV:}resourcetype'));
return true;//no 404 exception
}catch(Exception $e){
return false;
@@ -198,7 +196,7 @@ class OC_FileStorage_DAV extends OC_Filestorage_Common{
$mtime=time();
}
$path=$this->cleanPath($path);
- $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime,));
+ $this->client->proppatch($path, array('{DAV:}lastmodified' => $mtime));
}
public function getFile($path,$target){
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 3d65e9b7473..e8bc94790dc 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -1,4 +1,4 @@
-<form id="files_external" method="post" enctype="multipart/form-data" action="/owncloud/?app=files_external&getfile=ajax%2FaddRootCertificate.php">
+<form id="files_external" method="post" enctype="multipart/form-data" action="<?php echo OCP\Util::linkTo('files_external', 'ajax/addRootCertificate.php'); ?>">
<fieldset class="personalblock">
<legend><strong><?php echo $l->t('External Storage'); ?></strong></legend>
<table id="externalStorage" data-admin='<?php echo json_encode($_['isAdminPage']); ?>'>
diff --git a/apps/files_external/tests/amazons3.php b/apps/files_external/tests/amazons3.php
index d0084c94afd..b9b4cf65bd6 100644
--- a/apps/files_external/tests/amazons3.php
+++ b/apps/files_external/tests/amazons3.php
@@ -45,6 +45,3 @@ if (!is_array($config) or !isset($config['amazons3']) or !$config['amazons3']['r
}
}
}
-
-?>
-
diff --git a/apps/files_external/tests/ftp.php b/apps/files_external/tests/ftp.php
index 68481b4e66b..97796bca128 100644
--- a/apps/files_external/tests/ftp.php
+++ b/apps/files_external/tests/ftp.php
@@ -13,7 +13,6 @@ if(!is_array($config) or !isset($config['ftp']) or !$config['ftp']['run']){
}else{
class Test_Filestorage_FTP extends Test_FileStorage {
private $config;
- private $id;
public function setUp(){
$id=uniqid();
diff --git a/apps/files_external/tests/google.php b/apps/files_external/tests/google.php
index 08116f0e748..806db5a6aaa 100644
--- a/apps/files_external/tests/google.php
+++ b/apps/files_external/tests/google.php
@@ -28,7 +28,6 @@ if(!is_array($config) or !isset($config['google']) or !$config['google']['run'])
class Test_Filestorage_Google extends Test_FileStorage {
private $config;
- private $id;
public function setUp(){
$id=uniqid();
diff --git a/apps/files_external/tests/smb.php b/apps/files_external/tests/smb.php
index e1495b7480d..001ef842276 100644
--- a/apps/files_external/tests/smb.php
+++ b/apps/files_external/tests/smb.php
@@ -14,7 +14,6 @@ if(!is_array($config) or !isset($config['smb']) or !$config['smb']['run']){
}else{
class Test_Filestorage_SMB extends Test_FileStorage {
private $config;
- private $id;
public function setUp(){
$id=uniqid();
diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php
index f0bde6ed605..1520c9473d3 100644
--- a/apps/files_external/tests/swift.php
+++ b/apps/files_external/tests/swift.php
@@ -13,7 +13,6 @@ if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']){
}else{
class Test_Filestorage_SWIFT extends Test_FileStorage {
private $config;
- private $id;
public function setUp(){
$id=uniqid();
diff --git a/apps/files_external/tests/webdav.php b/apps/files_external/tests/webdav.php
index 144659819b6..14abbef2cbf 100644
--- a/apps/files_external/tests/webdav.php
+++ b/apps/files_external/tests/webdav.php
@@ -13,7 +13,6 @@ if(!is_array($config) or !isset($config['webdav']) or !$config['webdav']['run'])
}else{
class Test_Filestorage_DAV extends Test_FileStorage {
private $config;
- private $id;
public function setUp(){
$id=uniqid();
diff --git a/apps/files_imageviewer/appinfo/app.php b/apps/files_imageviewer/appinfo/app.php
index 6c8d8c30cad..6184585cff3 100644
--- a/apps/files_imageviewer/appinfo/app.php
+++ b/apps/files_imageviewer/appinfo/app.php
@@ -4,5 +4,3 @@ OCP\Util::addscript( 'files_imageviewer', 'lightbox' );
OCP\Util::addscript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack');
OCP\Util::addscript('files_imageviewer', 'jquery.fancybox-1.3.4.pack');
OCP\Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' );
-
-?>
diff --git a/apps/files_pdfviewer/appinfo/app.php b/apps/files_pdfviewer/appinfo/app.php
index c8ca2dc8d94..e4771ee517f 100644
--- a/apps/files_pdfviewer/appinfo/app.php
+++ b/apps/files_pdfviewer/appinfo/app.php
@@ -6,4 +6,3 @@ OCP\Util::addscript( 'files_pdfviewer', 'pdfjs/compatibility');
OCP\Util::addscript( 'files_pdfviewer', 'viewer');
OCP\Util::addscript( 'files_pdfviewer', 'pdfjs/build/pdf');
OCP\Util::addscript( 'files_pdfviewer', 'pdfjs/viewer');
-?>
diff --git a/apps/files_pdfviewer/js/pdfjs/viewer.js b/apps/files_pdfviewer/js/pdfjs/viewer.js
index f49257d7929..90dd1eef020 100644
--- a/apps/files_pdfviewer/js/pdfjs/viewer.js
+++ b/apps/files_pdfviewer/js/pdfjs/viewer.js
@@ -1432,7 +1432,7 @@ var DocumentOutlineView = function documentOutlineView(outline) {
queue.push({parent: itemsDiv, items: item.items});
}
- levelData.parent.appendChild(div);
+// levelData.parent.appendChild(div);
}
}
};
@@ -1751,10 +1751,9 @@ function updateThumbViewArea() {
}
window.addEventListener('resize', function webViewerResize(evt) {
- if (PDFView.initialized &&
+ if (PDFView.initialized && PDFView.active &&
(document.getElementById('pageWidthOption').selected ||
- document.getElementById('pageFitOption').selected ||
- document.getElementById('pageAutoOption').selected))
+ document.getElementById('pageFitOption').selected ))
PDFView.parseScale(document.getElementById('scaleSelect').value);
updateViewarea();
});
@@ -1788,8 +1787,8 @@ window.addEventListener('change', function webViewerChange(evt) {
document.title = file.name;
// URL does not reflect proper document location - hiding some icons.
- document.getElementById('viewBookmark').setAttribute('hidden', 'true');
- document.getElementById('download').setAttribute('hidden', 'true');
+// document.getElementById('viewBookmark').setAttribute('hidden', 'true');
+// document.getElementById('download').setAttribute('hidden', 'true');
}, true);
function selectScaleOption(value) {
diff --git a/apps/files_sharing/ajax/email.php b/apps/files_sharing/ajax/email.php
index 523c3d2078b..3026eb74675 100644
--- a/apps/files_sharing/ajax/email.php
+++ b/apps/files_sharing/ajax/email.php
@@ -1,6 +1,8 @@
<?php
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('files_sharing');
+OCP\JSON::callCheck();
+
$user = OCP\USER::getUser();
// TODO translations
$type = (strpos($_POST['file'], '.') === false) ? 'folder' : 'file';
@@ -8,6 +10,4 @@ $subject = $user.' shared a '.$type.' with you';
$link = $_POST['link'];
$text = $user.' shared the '.$type.' '.$_POST['file'].' with you. It is available for download here: '.$link;
$fromaddress = OCP\Config::getUserValue($user, 'settings', 'email', 'sharing-noreply@'.OCP\Util::getServerHost());
-OC_Mail::send($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user);
-
-?>
+OCP\Util::sendMail($_POST['toaddress'], $_POST['toaddress'], $subject, $text, $fromaddress, $user);
diff --git a/apps/files_sharing/ajax/getitem.php b/apps/files_sharing/ajax/getitem.php
index 94f0890d706..ff6c29b6a0a 100644
--- a/apps/files_sharing/ajax/getitem.php
+++ b/apps/files_sharing/ajax/getitem.php
@@ -64,5 +64,3 @@ while ($path != $userDirectory) {
}
OCP\JSON::success(array('data' => $item));
-
-?>
diff --git a/apps/files_sharing/ajax/getstatuses.php b/apps/files_sharing/ajax/getstatuses.php
index 488cab13bc9..1be4d9a0d9c 100644
--- a/apps/files_sharing/ajax/getstatuses.php
+++ b/apps/files_sharing/ajax/getstatuses.php
@@ -20,5 +20,3 @@ if ($rows = OC_Share::getMySharedItems()) {
}
OCP\JSON::success(array('data' => $items));
-
-?>
diff --git a/apps/files_sharing/ajax/setpermissions.php b/apps/files_sharing/ajax/setpermissions.php
index 4d19cd40f2d..0a2cf78f765 100644
--- a/apps/files_sharing/ajax/setpermissions.php
+++ b/apps/files_sharing/ajax/setpermissions.php
@@ -2,6 +2,7 @@
OCP\JSON::checkAppEnabled('files_sharing');
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
$source = '/'.OCP\USER::getUser().'/files'.$_POST['source'];
$uid_shared_with = $_POST['uid_shared_with'];
@@ -9,5 +10,3 @@ $permissions = $_POST['permissions'];
OC_Share::setPermissions($source, $uid_shared_with, $permissions);
OCP\JSON::success();
-
-?>
diff --git a/apps/files_sharing/ajax/share.php b/apps/files_sharing/ajax/share.php
index 1ee8c3f791a..3f224d1b67b 100644
--- a/apps/files_sharing/ajax/share.php
+++ b/apps/files_sharing/ajax/share.php
@@ -2,6 +2,7 @@
OCP\JSON::checkAppEnabled('files_sharing');
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
$userDirectory = '/'.OCP\USER::getUser().'/files';
$sources = explode(';', $_POST['sources']);
@@ -34,5 +35,3 @@ foreach ($sources as $source) {
}
}
}
-
-?>
diff --git a/apps/files_sharing/ajax/toggleresharing.php b/apps/files_sharing/ajax/toggleresharing.php
index 673f00c5d18..7da4fdfeea8 100644
--- a/apps/files_sharing/ajax/toggleresharing.php
+++ b/apps/files_sharing/ajax/toggleresharing.php
@@ -7,5 +7,3 @@ if ($_POST['resharing'] == true) {
} else {
OCP\Config::setAppValue('files_sharing', 'resharing', 'no');
}
-
-?>
diff --git a/apps/files_sharing/ajax/unshare.php b/apps/files_sharing/ajax/unshare.php
index d50e7963a05..02a59c4016b 100644
--- a/apps/files_sharing/ajax/unshare.php
+++ b/apps/files_sharing/ajax/unshare.php
@@ -2,11 +2,10 @@
OCP\JSON::checkAppEnabled('files_sharing');
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
$source = '/'.OCP\USER::getUser().'/files'.$_POST['source'];
$uid_shared_with = $_POST['uid_shared_with'];
OC_Share::unshare($source, $uid_shared_with);
OCP\JSON::success();
-
-?>
diff --git a/apps/files_sharing/ajax/userautocomplete.php b/apps/files_sharing/ajax/userautocomplete.php
index 0e1bf6d588e..388a4844b95 100644
--- a/apps/files_sharing/ajax/userautocomplete.php
+++ b/apps/files_sharing/ajax/userautocomplete.php
@@ -28,5 +28,3 @@ $users[] = "</optgroup>";
$groups[] = "</optgroup>";
$users = array_merge($users, $groups);
OCP\JSON::encodedPrint($users);
-
-?>
diff --git a/apps/files_sharing/appinfo/version b/apps/files_sharing/appinfo/version
index 7dff5b89211..f4778493c50 100644
--- a/apps/files_sharing/appinfo/version
+++ b/apps/files_sharing/appinfo/version
@@ -1 +1 @@
-0.2.1 \ No newline at end of file
+0.2.2 \ No newline at end of file
diff --git a/apps/files_sharing/get.php b/apps/files_sharing/get.php
index 40a90a1530c..70a5162d382 100644
--- a/apps/files_sharing/get.php
+++ b/apps/files_sharing/get.php
@@ -86,4 +86,3 @@ if (isset($_GET['token']) && $source = OC_Share::getSource($_GET['token'])) {
$tmpl->printPage();
die();
}
-?>
diff --git a/apps/files_sharing/lib_share.php b/apps/files_sharing/lib_share.php
index 6e092269250..0237acfc1ac 100644
--- a/apps/files_sharing/lib_share.php
+++ b/apps/files_sharing/lib_share.php
@@ -513,5 +513,3 @@ class OC_Share {
}
}
-
-?>
diff --git a/apps/files_sharing/list.php b/apps/files_sharing/list.php
index 2fd24840d36..54704c942fd 100644
--- a/apps/files_sharing/list.php
+++ b/apps/files_sharing/list.php
@@ -33,5 +33,3 @@ OCP\Util::addscript("files_sharing", "list");
$tmpl = new OCP\Template("files_sharing", "list", "user");
$tmpl->assign("shared_items", OC_Share::getMySharedItems());
$tmpl->printPage();
-
-?>
diff --git a/apps/files_sharing/sharedstorage.php b/apps/files_sharing/sharedstorage.php
index 4138fc2b399..32fd2124429 100644
--- a/apps/files_sharing/sharedstorage.php
+++ b/apps/files_sharing/sharedstorage.php
@@ -67,7 +67,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
public function rmdir($path) {
// The folder will be removed from the database, but won't be deleted from the owner's filesystem
OC_Share::unshareFromMySelf($this->datadir.$path);
- $this->clearFolderSizeCache($path);
}
public function opendir($path) {
@@ -190,7 +189,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
public function filesize($path) {
if ($path == "" || $path == "/" || $this->is_dir($path)) {
- return $this->getFolderSize($path);
+ return 0;
} else {
$source = $this->getSource($path);
if ($source) {
@@ -200,55 +199,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
}
}
- public function getFolderSize($path) {
- return 0; //depricated
- }
-
- private function calculateFolderSize($path) {
- if ($this->is_file($path)) {
- $path = dirname($path);
- }
- $size = 0;
- if ($dh = $this->opendir($path)) {
- while (($filename = readdir($dh)) !== false) {
- if ($filename != "." && $filename != "..") {
- $subFile = $path."/".$filename;
- if ($this->is_file($subFile)) {
- $size += $this->filesize($subFile);
- } else {
- $size += $this->getFolderSize($subFile);
- }
- }
- }
- if ($size > 0) {
- $dbpath = rtrim($this->datadir.$path, "/");
-// $query = OCP\DB::prepare("INSERT INTO *PREFIX*foldersize VALUES(?,?)");
-// $result = $query->execute(array($dbpath, $size));
- }
- }
- return $size;
- }
-
- private function clearFolderSizeCache($path) {
- $path = rtrim($path, "/");
- $path = preg_replace('{(/)\1+}', "/", $path);
- if ($this->is_file($path)) {
- $path = dirname($path);
- }
- $dbpath = rtrim($this->datadir.$path, "/");
-// $query = OCP\DB::prepare("DELETE FROM *PREFIX*/*foldersize*/ WHERE path = ?");
-// $result = $query->execute(array($dbpath));
- if ($path != "/" && $path != "") {
- $parts = explode("/", $path);
- $part = array_pop($parts);
- if (empty($part)) {
- array_pop($parts);
- }
- $parent = implode("/", $parts);
- $this->clearFolderSizeCache($parent);
- }
- }
-
public function is_readable($path) {
return true;
}
@@ -341,9 +291,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
OCP\Util::emitHook('OC_Filestorage_Shared', 'file_put_contents', $info);
$storage = OC_Filesystem::getStorage($source);
$result = $storage->file_put_contents($this->getInternalPath($source), $data);
- if ($result) {
- $this->clearFolderSizeCache($path);
- }
return $result;
}
}
@@ -365,7 +312,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
} else {
OC_Share::unshareFromMySelf($target);
}
- $this->clearFolderSizeCache($this->getInternalPath($target));
return true;
}
@@ -401,8 +347,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
} else {
OC_Share::setTarget($oldTarget, $newTarget);
}
- $this->clearFolderSizeCache($this->getInternalPath($oldTarget));
- $this->clearFolderSizeCache($this->getInternalPath($newTarget));
return true;
}
@@ -413,9 +357,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
if ($this->is_writable($path2)) {
$tmpFile = $this->toTmpFile($path1);
$result = $this->fromTmpFile($tmpFile, $path2);
- if ($result) {
- $this->clearFolderSizeCache($path2);
- }
return $result;
} else {
return false;
@@ -451,9 +392,6 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
if ($source) {
$storage = OC_Filesystem::getStorage($source);
$result = $storage->fromTmpFile($tmpFile, $this->getInternalPath($source));
- if ($result) {
- $this->clearFolderSizeCache($path);
- }
return $result;
}
} else {
@@ -520,7 +458,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
$source = $this->getSource($path);
if ($source) {
$storage = OC_Filesystem::getStorage($source);
- return $storage->touch($this->getInternalPath($source),$time);
+ return $storage->touch($this->getInternalPath($source),$mtime);
}
}
diff --git a/apps/files_sharing_log/appinfo/database.xml b/apps/files_sharing_log/appinfo/database.xml
index 92e5f0125bd..dae811f87fa 100644
--- a/apps/files_sharing_log/appinfo/database.xml
+++ b/apps/files_sharing_log/appinfo/database.xml
@@ -3,7 +3,7 @@
<name>*dbname*</name>
<create>true</create>
<overwrite>false</overwrite>
- <charset>latin1</charset>
+ <charset>utf8</charset>
<table>
<name>*dbprefix*sharing_log</name>
<declaration>
diff --git a/apps/files_texteditor/ajax/savefile.php b/apps/files_texteditor/ajax/savefile.php
index 961db7105e3..f3ac323e32f 100644
--- a/apps/files_texteditor/ajax/savefile.php
+++ b/apps/files_texteditor/ajax/savefile.php
@@ -26,6 +26,7 @@
// Check if we are a user
OCP\JSON::checkLoggedIn();
+OCP\JSON::callCheck();
// Get paramteres
$filecontents = isset($_POST['filecontents']) ? $_POST['filecontents'] : false;
diff --git a/apps/files_texteditor/appinfo/app.php b/apps/files_texteditor/appinfo/app.php
index c745170018e..1f9773bca3a 100644
--- a/apps/files_texteditor/appinfo/app.php
+++ b/apps/files_texteditor/appinfo/app.php
@@ -4,4 +4,3 @@ OCP\Util::addStyle( 'files_texteditor', 'DroidSansMono/stylesheet' );
OCP\Util::addStyle( 'files_texteditor', 'style' );
OCP\Util::addscript( 'files_texteditor', 'editor');
OCP\Util::addscript( 'files_texteditor', 'aceeditor/ace');
-?>
diff --git a/apps/files_versions/ajax/expireAll.php b/apps/files_versions/ajax/expireAll.php
index 238e3bdad4d..2a678c7f0a5 100644
--- a/apps/files_versions/ajax/expireAll.php
+++ b/apps/files_versions/ajax/expireAll.php
@@ -27,8 +27,9 @@
// Check user and app status
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('files_versions');
+OCP\JSON::callCheck();
-$versions = new OCA_Versions\Storage( new OC_FilesystemView('') );
+$versions = new OCA_Versions\Storage();
if( $versions->expireAll() ){
diff --git a/apps/files_versions/ajax/rollbackVersion.php b/apps/files_versions/ajax/rollbackVersion.php
index 8d1092f8b8e..24d71a914a4 100644
--- a/apps/files_versions/ajax/rollbackVersion.php
+++ b/apps/files_versions/ajax/rollbackVersion.php
@@ -1,6 +1,7 @@
<?php
OCP\JSON::checkAppEnabled('files_versions');
+OCP\JSON::callCheck();
$userDirectory = "/".OCP\USER::getUser()."/files";
diff --git a/apps/files_versions/ajax/togglesettings.php b/apps/files_versions/ajax/togglesettings.php
index d513d12dd6c..546b37ae1aa 100644
--- a/apps/files_versions/ajax/togglesettings.php
+++ b/apps/files_versions/ajax/togglesettings.php
@@ -2,10 +2,9 @@
OCP\JSON::checkAppEnabled('files_versions');
OCP\JSON::checkAdminUser();
+OCP\JSON::callCheck();
if (OCP\Config::getSystemValue('versions', 'true')=='true') {
OCP\Config::setSystemValue('versions', 'false');
} else {
OCP\Config::setSystemValue('versions', 'true');
}
-
-?>
diff --git a/apps/files_versions/appinfo/update.php b/apps/files_versions/appinfo/update.php
new file mode 100644
index 00000000000..9569ca10485
--- /dev/null
+++ b/apps/files_versions/appinfo/update.php
@@ -0,0 +1,16 @@
+<?php
+
+$installedVersion=OCP\Config::getAppValue('files_versions', 'installed_version');
+// move versions to new directory
+if (version_compare($installedVersion, '1.0.2', '<')) {
+ $users = \OCP\User::getUsers();
+ $datadir = \OCP\Config::getSystemValue('datadirectory').'/';
+ foreach ($users as $user) {
+ $oldPath = $datadir.$user.'/versions';
+ $newPath = $datadir.$user.'/files_versions';
+ if(is_dir($oldPath)) {
+ rename($oldPath, $newPath);
+ }
+ }
+
+}
diff --git a/apps/files_versions/appinfo/version b/apps/files_versions/appinfo/version
index 7f207341d5d..e6d5cb833c6 100644
--- a/apps/files_versions/appinfo/version
+++ b/apps/files_versions/appinfo/version
@@ -1 +1 @@
-1.0.1 \ No newline at end of file
+1.0.2 \ No newline at end of file
diff --git a/apps/files_versions/history.php b/apps/files_versions/history.php
index e3332d7cdb6..a34c92ee422 100644
--- a/apps/files_versions/history.php
+++ b/apps/files_versions/history.php
@@ -30,7 +30,7 @@ if ( isset( $_GET['path'] ) ) {
$path = $_GET['path'];
$path = strip_tags( $path );
$tmpl->assign( 'path', $path );
- $versions = new OCA_Versions\Storage( new OC_FilesystemView('') );
+ $versions = new OCA_Versions\Storage();
// roll back to old version if button clicked
if( isset( $_GET['revert'] ) ) {
@@ -71,5 +71,3 @@ if ( isset( $_GET['path'] ) ) {
}
$tmpl->printPage( );
-
-?>
diff --git a/apps/files_versions/lib/hooks.php b/apps/files_versions/lib/hooks.php
index b43fdb9fd33..bfc8fd3a378 100644
--- a/apps/files_versions/lib/hooks.php
+++ b/apps/files_versions/lib/hooks.php
@@ -30,6 +30,7 @@ class Hooks {
}
}
+
/**
* @brief Erase versions of deleted file
* @param array
@@ -37,9 +38,10 @@ class Hooks {
* This function is connected to the delete signal of OC_Filesystem
* cleanup the versions directory if the actual file gets deleted
*/
- public static function remove_hook($params) {
+ public static function remove_hook($params) {
+ $versions_fileview = \OCP\Files::getStorage('files_versions');
$rel_path = $params['path'];
- $abs_path = \OCP\Config::getSystemValue('datadirectory').'/'.\OCP\User::getUser()."/versions".$rel_path.'.v';
+ $abs_path = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_path.'.v';
if(Storage::isversioned($rel_path)) {
$versions = Storage::getVersions($rel_path);
foreach ($versions as $v){
@@ -55,11 +57,14 @@ class Hooks {
* This function is connected to the rename signal of OC_Filesystem and adjust the name and location
* of the stored versions along the actual file
*/
- public static function rename_hook($params) {
+ public static function rename_hook($params) {
+ $versions_fileview = \OCP\Files::getStorage('files_versions');
$rel_oldpath = $params['oldpath'];
- $abs_oldpath = \OCP\Config::getSystemValue('datadirectory').'/'.\OCP\User::getUser()."/versions".$rel_oldpath.'.v';
- $abs_newpath = \OCP\Config::getSystemValue('datadirectory').'/'.\OCP\User::getUser()."/versions".$params['newpath'].'.v';
- if(Storage::isversioned($rel_oldpath)) {
+ $abs_oldpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$rel_oldpath.'.v';
+ $abs_newpath = \OCP\Config::getSystemValue('datadirectory').$versions_fileview->getAbsolutePath('').$params['newpath'].'.v';
+ if(Storage::isversioned($rel_oldpath)) {
+ $info=pathinfo($abs_newpath);
+ if(!file_exists($info['dirname'])) mkdir($info['dirname'],0700,true);
$versions = Storage::getVersions($rel_oldpath);
foreach ($versions as $v){
rename($abs_oldpath.$v['version'], $abs_newpath.$v['version']);
@@ -68,5 +73,3 @@ class Hooks {
}
}
-
-?>
diff --git a/apps/files_versions/lib/versions.php b/apps/files_versions/lib/versions.php
index 4f0ee2c6d52..f146676757d 100644
--- a/apps/files_versions/lib/versions.php
+++ b/apps/files_versions/lib/versions.php
@@ -22,41 +22,26 @@ class Storage {
// - files_versionsfolder
// - files_versionsblacklist
// - files_versionsmaxfilesize
- // - files_versionsinterval
- // - files_versionmaxversions
+ // - files_versionsinterval
+ // - files_versionmaxversions
//
// todo:
// - finish porting to OC_FilesystemView to enable network transparency
// - add transparent compression. first test if it´s worth it.
- const DEFAULTENABLED=true;
- const DEFAULTFOLDER='versions';
- const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp';
- const DEFAULTMAXFILESIZE=1048576; // 10MB
+ const DEFAULTENABLED=true;
+ const DEFAULTBLACKLIST='avi mp3 mpg mp4 ctmp';
+ const DEFAULTMAXFILESIZE=1048576; // 10MB
const DEFAULTMININTERVAL=60; // 1 min
const DEFAULTMAXVERSIONS=50;
-
+
private $view;
-
- function __construct( $view ) {
-
- $this->view = $view;
-
- }
- /**
- * init the versioning and create the versions folder.
- */
- public static function init() {
- if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
- // create versions folder
- $foldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
- if(!is_dir($foldername)){
- mkdir($foldername);
- }
- }
- }
+ function __construct() {
+
+ $this->view = \OCP\Files::getStorage('files_versions');
+ }
/**
* listen to write event.
@@ -75,11 +60,11 @@ class Storage {
*/
public function store($filename) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
-
+
$files_view = \OCP\Files::getStorage("files");
$users_view = \OCP\Files::getStorage("files_versions");
$users_view->chroot(\OCP\User::getUser().'/');
-
+
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
@@ -87,15 +72,14 @@ class Storage {
} else {
$uid = \OCP\User::getUser();
}
- $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
- $filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/files';
- Storage::init();
-
+
+ $versionsFolderName=\OCP\Config::getSystemValue('datadirectory') . $this->view->getAbsolutePath('');
+
//check if source file already exist as version to avoid recursions.
if ($users_view->file_exists($filename)) {
return false;
}
-
+
// check if filename is a directory
if($files_view->is_dir($filename)){
return false;
@@ -110,7 +94,7 @@ class Storage {
return false;
}
}
-
+
// check filesize
if($files_view->filesize($filename)>\OCP\Config::getSystemValue('files_versionsmaxfilesize', Storage::DEFAULTMAXFILESIZE)){
return false;
@@ -129,12 +113,12 @@ class Storage {
// create all parent folders
- $info=pathinfo($filename);
- if(!file_exists($versionsFolderName.'/'.$info['dirname'])) mkdir($versionsFolderName.'/'.$info['dirname'],0700,true);
+ $info=pathinfo($filename);
+ if(!file_exists($versionsFolderName.'/'.$info['dirname'])) mkdir($versionsFolderName.'/'.$info['dirname'],0700,true);
// store a new version of a file
- @$users_view->copy('files'.$filename, 'versions'.$filename.'.v'.time());
-
+ @$users_view->copy('files'.$filename, 'files_versions'.$filename.'.v'.time());
+
// expire old revisions if necessary
Storage::expire($filename);
}
@@ -145,11 +129,11 @@ class Storage {
* rollback to an old version of a file.
*/
public static function rollback($filename,$revision) {
-
+
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
$users_view = \OCP\Files::getStorage("files_versions");
$users_view->chroot(\OCP\User::getUser().'/');
-
+
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
@@ -157,23 +141,20 @@ class Storage {
} else {
$uid = \OCP\User::getUser();
}
- $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'.$uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
-
- $filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/files';
-
+
// rollback
- if( @$users_view->copy('versions'.$filename.'.v'.$revision, 'files'.$filename) ) {
-
+ if( @$users_view->copy('files_versions'.$filename.'.v'.$revision, 'files'.$filename) ) {
+
return true;
-
+
}else{
-
+
return false;
-
+
}
-
+
}
-
+
}
/**
@@ -181,18 +162,17 @@ class Storage {
*/
public static function isversioned($filename) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+ $versions_fileview = \OCP\Files::getStorage("files_versions");
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
- $uid = substr($source, 1, $pos - 1);
$filename = substr($source, $pos + 6);
- } else {
- $uid = \OCP\User::getUser();
}
- $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
+ $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
+
// check for old versions
- $matches=glob($versionsFolderName.'/'.$filename.'.v*');
- if(count($matches)>1){
+ $matches=glob($versionsFolderName.$filename.'.v*');
+ if(count($matches)>0){
return true;
}else{
return false;
@@ -203,17 +183,17 @@ class Storage {
}
-
- /**
- * @brief get a list of all available versions of a file in descending chronological order
- * @param $filename file to find versions of, relative to the user files dir
- * @param $count number of versions to return
- * @returns array
- */
- public static function getVersions( $filename, $count = 0 ) {
-
- if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
-
+
+ /**
+ * @brief get a list of all available versions of a file in descending chronological order
+ * @param $filename file to find versions of, relative to the user files dir
+ * @param $count number of versions to return
+ * @returns array
+ */
+ public static function getVersions( $filename, $count = 0 ) {
+
+ if( \OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true' ) {
+
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
@@ -221,71 +201,71 @@ class Storage {
} else {
$uid = \OCP\User::getUser();
}
- $versionsFolderName = \OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
- $versions = array();
-
+ $versions_fileview = \OCP\Files::getStorage('files_versions');
+ $versionsFolderName = \OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
+ $versions = array();
+
// fetch for old versions
$matches = glob( $versionsFolderName.'/'.$filename.'.v*' );
-
+
sort( $matches );
-
+
$i = 0;
-
- foreach( $matches as $ma ) {
+ $files_view = \OCP\Files::getStorage('files');
+ $local_file = $files_view->getLocalFile($filename);
+ foreach( $matches as $ma ) {
+
$i++;
$versions[$i]['cur'] = 0;
$parts = explode( '.v', $ma );
$versions[$i]['version'] = ( end( $parts ) );
-
+
// if file with modified date exists, flag it in array as currently enabled version
- $curFile['fileName'] = basename( $parts[0] );
- $curFile['filePath'] = \OCP\Config::getSystemValue('datadirectory').\OC_Filesystem::getRoot().'/'.$curFile['fileName'];
-
- ( \md5_file( $ma ) == \md5_file( $curFile['filePath'] ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 );
-
+ ( \md5_file( $ma ) == \md5_file( $local_file ) ? $versions[$i]['fileMatch'] = 1 : $versions[$i]['fileMatch'] = 0 );
+
}
-
+
$versions = array_reverse( $versions );
foreach( $versions as $key => $value ) {
-
+
// flag the first matched file in array (which will have latest modification date) as current version
- if ( $versions[$key]['fileMatch'] ) {
-
- $versions[$key]['cur'] = 1;
+ if ( $value['fileMatch'] ) {
+
+ $value['cur'] = 1;
break;
-
+
}
-
+
}
-
+
$versions = array_reverse( $versions );
-
+
// only show the newest commits
if( $count != 0 and ( count( $versions )>$count ) ) {
-
+
$versions = array_slice( $versions, count( $versions ) - $count );
-
+
}
-
+
return( $versions );
- } else {
-
+ } else {
+
// if versioning isn't enabled then return an empty array
- return( array() );
-
- }
-
- }
-
- /**
- * @brief Erase a file's versions which exceed the set quota
- */
- public static function expire($filename) {
- if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
+ return( array() );
+
+ }
+
+ }
+
+ /**
+ * @brief Erase a file's versions which exceed the set quota
+ */
+ public static function expire($filename) {
+ if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
@@ -294,36 +274,33 @@ class Storage {
} else {
$uid = \OCP\User::getUser();
}
- $versionsFolderName=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
+ $versions_fileview = \OCP\Files::getStorage("files_versions");
+ $versionsFolderName=\OCP\Config::getSystemValue('datadirectory'). $versions_fileview->getAbsolutePath('');
// check for old versions
$matches = glob( $versionsFolderName.'/'.$filename.'.v*' );
-
+
if( count( $matches ) > \OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) ) {
-
+
$numberToDelete = count( $matches-\OCP\Config::getSystemValue( 'files_versionmaxversions', Storage::DEFAULTMAXVERSIONS ) );
// delete old versions of a file
$deleteItems = array_slice( $matches, 0, $numberToDelete );
-
+
foreach( $deleteItems as $de ) {
-
+
unlink( $versionsFolderName.'/'.$filename.'.v'.$de );
-
+
}
}
- }
- }
-
- /**
- * @brief Erase all old versions of all user files
- * @return true/false
- */
- public function expireAll() {
-
- $dir = \OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
-
- return $this->view->deleteAll( $dir, true );
-
- }
+ }
+ }
+
+ /**
+ * @brief Erase all old versions of all user files
+ * @return true/false
+ */
+ public function expireAll() {
+ return $this->view->deleteAll('', true);
+ }
}
diff --git a/apps/files_versions/settings.php b/apps/files_versions/settings.php
index 5f9e60fc589..f2873b8f7c2 100644
--- a/apps/files_versions/settings.php
+++ b/apps/files_versions/settings.php
@@ -7,4 +7,3 @@ OCP\Util::addscript( 'files_versions', 'versions' );
$tmpl = new OCP\Template( 'files_versions', 'settings');
return $tmpl->fetchPage();
-?>
diff --git a/apps/gallery/ajax/createAlbum.php b/apps/gallery/ajax/createAlbum.php
index 61e2e9ae2e9..5bfa5aa9a93 100644
--- a/apps/gallery/ajax/createAlbum.php
+++ b/apps/gallery/ajax/createAlbum.php
@@ -28,5 +28,3 @@ OCP\JSON::checkAppEnabled('gallery');
OC_Gallery_Album::create(OCP\USER::getUser(), $_GET['album_name']);
OCP\JSON::success(array('name' => $_GET['album_name']));
-
-?>
diff --git a/apps/gallery/ajax/galleryOp.php b/apps/gallery/ajax/galleryOp.php
index 7cbe3e46e21..ab8c64e28ad 100644
--- a/apps/gallery/ajax/galleryOp.php
+++ b/apps/gallery/ajax/galleryOp.php
@@ -186,4 +186,3 @@ if ($_GET['operation']) {
OCP\JSON::error(array('cause' => 'Unknown operation'));
}
}
-?>
diff --git a/apps/gallery/ajax/viewImage.php b/apps/gallery/ajax/viewImage.php
new file mode 100644
index 00000000000..daf0ab741f0
--- /dev/null
+++ b/apps/gallery/ajax/viewImage.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * ownCloud - gallery application
+ *
+ * @author Ike Devolder
+ * @copyright 2012 Ike Devolder
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+OCP\JSON::checkLoggedIn();
+OCP\JSON::checkAppEnabled('gallery');
+
+$img = $_GET['img'];
+
+$image = OC_Gallery_Photo::getViewImage($img);
+if ($image) {
+ OCP\Response::enableCaching(3600 * 24); // 24 hour
+ $image->show();
+}
diff --git a/apps/gallery/appinfo/version b/apps/gallery/appinfo/version
index 8f0916f768f..4b9fcbec101 100644
--- a/apps/gallery/appinfo/version
+++ b/apps/gallery/appinfo/version
@@ -1 +1 @@
-0.5.0
+0.5.1
diff --git a/apps/gallery/css/styles.css b/apps/gallery/css/styles.css
index dcef1f08c6d..63f645662dd 100644
--- a/apps/gallery/css/styles.css
+++ b/apps/gallery/css/styles.css
@@ -1,11 +1,11 @@
#gallerycontent { margin-top: 2.8em; overflow: visible; }
-#g-settings {position: absolute; left 13.5em; top: 0;}
+#g-settings {position: absolute; left: 13.5em; top: 0;}
div#controls input[type=button] { -webkit-transition: opacity 0.5s ease-in-out; -moz-transition: opacity 0.5s ease-in-out; -o-transition: opacity 0.5s ease-in-out; opacity: 1; position:absolute; right:13.5em; top:0em; }
input[type=button]:disabled { opacity: 0.5 }
.ui-dialog tr {background-color: #eee;}
.ui-dialog input {width: 90%;}
-div.gallery_div {position:relative; display: inline-block; height: 152px; width: 150px; margin: 5px;}
+div.gallery_div {position:relative; display: inline-block; height: 150px; width: 150px; margin: 5px;}
div.miniature_border {position:absolute; height: 150px; -moz-transition-duration: 0.2s; -o-transition-duration:0.2s; -webkit-transition-duration: .2s; background-position: 50%;}
div.line {display:inline-block; border: 0; width: auto; height: 160px}
div.gallery_div img{position:absolute; top: 1; left: 0; -moz-transition-duration: 0.3s; -o-transition-duration:0.3s; -webkit-transition-duration: 0.3s; height:150px; width: auto;}
diff --git a/apps/gallery/css/supersized.css b/apps/gallery/css/supersized.css
new file mode 100644
index 00000000000..57ee7e23a50
--- /dev/null
+++ b/apps/gallery/css/supersized.css
@@ -0,0 +1,25 @@
+/*
+
+ Supersized - Fullscreen Slideshow jQuery Plugin
+ Version : 3.2.7
+ Site : www.buildinternet.com/project/supersized
+
+ Author : Sam Dunn
+ Company : One Mighty Roar (www.onemightyroar.com)
+ License : MIT License / GPL License
+
+*/
+#supersized-holder #supersized-loader { display:none; position:absolute; top:50%; left:50%; z-index:0; width:60px; height:60px; margin:-30px 0 0 -30px; text-indent:-999em; background:url('%appswebroot%/gallery/img/supersized/progress.gif') no-repeat center center;}
+
+#supersized-holder #supersized { visibility:hidden; display:block; position:fixed; left:0; top:0; overflow:hidden; z-index:200; height:100%; width:100%; }
+#supersized-holder #supersized img { width:auto; height:auto; position:relative; display:none; outline:none; border:none; }
+#supersized-holder #supersized.speed img { -ms-interpolation-mode:nearest-neighbor; image-rendering: -moz-crisp-edges; } /*Speed*/
+#supersized-holder #supersized.quality img { -ms-interpolation-mode:bicubic; image-rendering: optimizeQuality; } /*Quality*/
+
+#supersized-holder #supersized li { display:block; list-style:none; z-index:150; position:fixed; overflow:hidden; top:0; left:0; width:100%; height:100%; background:#111; }
+#supersized-holder #supersized a { width:100%; height:100%; display:block; }
+#supersized-holder #supersized li.prevslide { z-index:160; }
+#supersized-holder #supersized li.activeslide { z-index:170; }
+#supersized-holder #supersized li.image-loading { background:#111 url('%appswebroot%/gallery/img/supersized/progress.gif') no-repeat center center; width:100%; height:100%; }
+#supersized-holder #supersized li.image-loading img{ visibility:hidden; }
+#supersized-holder #supersized li.prevslide img, #supersized-holder #supersized li.activeslide img{ display:inline; }
diff --git a/apps/gallery/css/supersized.shutter.css b/apps/gallery/css/supersized.shutter.css
new file mode 100644
index 00000000000..428c254c3b2
--- /dev/null
+++ b/apps/gallery/css/supersized.shutter.css
@@ -0,0 +1,74 @@
+/*
+
+ Supersized - Fullscreen Slideshow jQuery Plugin
+ Version : 3.2.7
+ Site : www.buildinternet.com/project/supersized
+
+ Theme : Shutter 1.2
+ Author : Sam Dunn
+ Company : One Mighty Roar (www.onemightyroar.com)
+ License : MIT License / GPL License
+
+*/
+
+/* Controls Bar
+----------------------------*/
+#slideshow-content #slideshow-controls-wrapper { margin:0 auto; height:42px; width:100%; bottom:0px; left:0; z-index:204; background:url('%appswebroot%/gallery/img/supersized/nav-bg.png') repeat-x; position:fixed; }
+#slideshow-content #slideshow-controls { overflow:hidden; height:100%; position:relative; text-align:left; z-index:205; }
+#slideshow-content #slidecounter { float:left; color:#999; font:14px "Helvetica Neue", Helvetica, Arial, sans-serif; text-shadow:#000 0 -1px 0; margin:0px 10px 0 15px; line-height:42px; }
+#slideshow-content #slidecaption { overflow:hidden; float:left; color:#FFF; font:400 14px "Helvetica Neue", Helvetica, Arial, sans-serif; text-shadow:#000 1px 1px 2px; margin:0 20px 0 0; line-height:42px; }
+
+/*#navigation { float:right; margin:0px 20px 0 0; }*/
+#slideshow-content #play-button{ float:left; margin-top:1px;border-right:1px solid #333; background:url('%appswebroot%/gallery/img/supersized/bg-hover.png') repeat-x 0 44px; }
+#slideshow-content #play-button:hover{ background-position:0 1px; cursor:pointer; }
+
+#slideshow-content #prevslide, #nextslide{ position:fixed; height:43px; width:43px; top:50%; margin-top:-21px; opacity:0.6; z-index:204; }
+#slideshow-content #prevslide{ left:10px; background:url('%appswebroot%/gallery/img/supersized/back.png'); }
+#slideshow-content #nextslide{ right:10px; background:url('%appswebroot%/gallery/img/supersized/forward.png'); }
+#slideshow-content #prevslide:active, #nextslide:active{ margin-top:-19px; }
+#slideshow-content #prevslide:hover, #nextslide:hover{ cursor:pointer; }
+
+#slideshow-content ul#slide-list{ padding:15px 0; float:left; position:absolute; left:50%; }
+#slideshow-content ul#slide-list li{ list-style:none; width:12px; height:12px; float:left; margin:0 5px 0 0; }
+#slideshow-content ul#slide-list li.current-slide a, ul#slide-list li.current-slide a:hover{ background-position:0 0px; }
+#slideshow-content ul#slide-list li a{ display:block; width:12px; height:12px; background:url('%appswebroot%/gallery/img/supersized/nav-dot.png') no-repeat 0 -24px; }
+#slideshow-content ul#slide-list li a:hover{ background-position:0 -12px; cursor:pointer; }
+
+#slideshow-content #tray-button{ float:right; margin-top:1px; border-left:1px solid #333; background:url('%appswebroot%/gallery/img/supersized/bg-hover.png') repeat-x 0 44px; }
+#slideshow-content #tray-button:hover{ background-position:0 1px; cursor:pointer; }
+
+
+/* Progress Bar
+----------------------------*/
+#slideshow-content #progress-back{ z-index:205; position:fixed; bottom:42px; left:0; height:8px; width:100%; background:url('%appswebroot%/gallery/img/supersized/progress-back.png') repeat-x; }
+#slideshow-content #progress-bar{ position:relative; height:8px; width:100%; background:url('%appswebroot%/gallery/img/supersized/progress-bar.png') repeat-x; }
+
+
+/* Thumbnail Navigation
+----------------------------*/
+#slideshow-content #nextthumb, #slideshow-content #prevthumb { z-index:202; display:none; position:fixed; bottom:61px; height:75px; width:100px; overflow:hidden; background:#ddd; border:1px solid #fff; -webkit-box-shadow:0 0 5px #000; }
+#slideshow-content #nextthumb { right:12px; }
+#slideshow-content #prevthumb { left:12px; }
+#slideshow-content #nextthumb img, #slideshow-content #prevthumb img { width:150px; height:auto; }
+#slideshow-content #nextthumb:active, #slideshow-content #prevthumb:active { bottom:59px; }
+#slideshow-content #nextthumb:hover, #slideshow-content #prevthumb:hover { cursor:pointer; }
+
+
+/* Thumbnail Tray
+----------------------------*/
+#slideshow-content #thumb-tray{ position:fixed; z-index:203; bottom:0; left:0; background:url('%appswebroot%/gallery/img/supersized/bg-black.png'); height:150px; width:100%; overflow:hidden; text-align:center; -moz-box-shadow: 0px 0px 4px #000; -webkit-box-shadow: 0px 0px 4px #000; box-shadow: 0px 0px 4px #000; }
+
+#slideshow-content #thumb-back, #slideshow-content #thumb-forward{ position:absolute; z-index:5; bottom:42px; height:108px; width:40px; }
+#slideshow-content #thumb-back{ left:0; background: url('%appswebroot%/gallery/img/supersized/thumb-back.png') no-repeat center center;}
+#slideshow-content #thumb-forward{ right:0; background:url('%appswebroot%/gallery/img/supersized/thumb-forward.png') no-repeat center center;}
+#slideshow-content #thumb-back:hover, #slideshow-content #thumb-forward:hover{ cursor:pointer; background-color:rgba(256,256,256, 0.1); }
+#slideshow-content #thumb-back:hover{ border-right:1px solid rgba(256,256,256, 0.2); }
+#slideshow-content #thumb-forward:hover{ border-left:1px solid rgba(256,256,256, 0.2); }
+
+
+#slideshow-content ul#thumb-list{ display:inline-block; list-style:none; position:relative; left:0px; padding:0 0px; }
+#slideshow-content ul#thumb-list li{ background:#111; list-style:none; display:inline; width:150px; height:108px; overflow:hidden; float:left; margin:0; }
+#slideshow-content ul#thumb-list li img { width:200px; height:auto; opacity:0.5; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; filter:alpha(opacity=60); -webkit-transition: all 100ms ease-in-out; -moz-transition: all 100ms ease-in-out; -o-transition: all 100ms ease-in-out; -ms-transition: all 100ms ease-in-out; transition: all 100ms ease-in-out; }
+#slideshow-content ul#thumb-list li.current-thumb img, #slideshow-content ul#thumb-list li:hover img{ opacity:1; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); }
+#slideshow-content ul#thumb-list li:hover{ cursor:pointer; }
+
diff --git a/apps/gallery/img/supersized/back.png b/apps/gallery/img/supersized/back.png
new file mode 100644
index 00000000000..44cd0ae703c
--- /dev/null
+++ b/apps/gallery/img/supersized/back.png
Binary files differ
diff --git a/apps/gallery/img/supersized/bg-black.png b/apps/gallery/img/supersized/bg-black.png
new file mode 100644
index 00000000000..8c2f00140d6
--- /dev/null
+++ b/apps/gallery/img/supersized/bg-black.png
Binary files differ
diff --git a/apps/gallery/img/supersized/bg-hover.png b/apps/gallery/img/supersized/bg-hover.png
new file mode 100644
index 00000000000..1ca2022e106
--- /dev/null
+++ b/apps/gallery/img/supersized/bg-hover.png
Binary files differ
diff --git a/apps/gallery/img/supersized/button-tray-down.png b/apps/gallery/img/supersized/button-tray-down.png
new file mode 100644
index 00000000000..99b92aef122
--- /dev/null
+++ b/apps/gallery/img/supersized/button-tray-down.png
Binary files differ
diff --git a/apps/gallery/img/supersized/button-tray-up.png b/apps/gallery/img/supersized/button-tray-up.png
new file mode 100644
index 00000000000..7cc57785f0a
--- /dev/null
+++ b/apps/gallery/img/supersized/button-tray-up.png
Binary files differ
diff --git a/apps/gallery/img/supersized/forward.png b/apps/gallery/img/supersized/forward.png
new file mode 100644
index 00000000000..e2084ab3faf
--- /dev/null
+++ b/apps/gallery/img/supersized/forward.png
Binary files differ
diff --git a/apps/gallery/img/supersized/nav-bg.png b/apps/gallery/img/supersized/nav-bg.png
new file mode 100644
index 00000000000..800f904ddc7
--- /dev/null
+++ b/apps/gallery/img/supersized/nav-bg.png
Binary files differ
diff --git a/apps/gallery/img/supersized/nav-dot.png b/apps/gallery/img/supersized/nav-dot.png
new file mode 100644
index 00000000000..a28a50789f3
--- /dev/null
+++ b/apps/gallery/img/supersized/nav-dot.png
Binary files differ
diff --git a/apps/gallery/img/supersized/pause.png b/apps/gallery/img/supersized/pause.png
new file mode 100644
index 00000000000..a2c21a51cee
--- /dev/null
+++ b/apps/gallery/img/supersized/pause.png
Binary files differ
diff --git a/apps/gallery/img/supersized/play.png b/apps/gallery/img/supersized/play.png
new file mode 100644
index 00000000000..16e53f86745
--- /dev/null
+++ b/apps/gallery/img/supersized/play.png
Binary files differ
diff --git a/apps/gallery/img/supersized/progress-back.png b/apps/gallery/img/supersized/progress-back.png
new file mode 100644
index 00000000000..68cd45b6706
--- /dev/null
+++ b/apps/gallery/img/supersized/progress-back.png
Binary files differ
diff --git a/apps/gallery/img/supersized/progress-bar.png b/apps/gallery/img/supersized/progress-bar.png
new file mode 100644
index 00000000000..49ebb0513b7
--- /dev/null
+++ b/apps/gallery/img/supersized/progress-bar.png
Binary files differ
diff --git a/apps/gallery/img/supersized/progress.gif b/apps/gallery/img/supersized/progress.gif
new file mode 100644
index 00000000000..f3e45e0569c
--- /dev/null
+++ b/apps/gallery/img/supersized/progress.gif
Binary files differ
diff --git a/apps/gallery/img/supersized/supersized-logo.png b/apps/gallery/img/supersized/supersized-logo.png
new file mode 100644
index 00000000000..b1243a29784
--- /dev/null
+++ b/apps/gallery/img/supersized/supersized-logo.png
Binary files differ
diff --git a/apps/gallery/img/supersized/thumb-back.png b/apps/gallery/img/supersized/thumb-back.png
new file mode 100644
index 00000000000..3c969ebd527
--- /dev/null
+++ b/apps/gallery/img/supersized/thumb-back.png
Binary files differ
diff --git a/apps/gallery/img/supersized/thumb-forward.png b/apps/gallery/img/supersized/thumb-forward.png
new file mode 100644
index 00000000000..afe451c75d0
--- /dev/null
+++ b/apps/gallery/img/supersized/thumb-forward.png
Binary files differ
diff --git a/apps/gallery/index.php b/apps/gallery/index.php
index b8aadacb47f..ce79f8f8782 100644
--- a/apps/gallery/index.php
+++ b/apps/gallery/index.php
@@ -30,8 +30,14 @@ OCP\App::setActiveNavigationEntry( 'gallery_index' );
OCP\Util::addStyle('files', 'files');
OCP\Util::addStyle('gallery', 'styles');
OCP\Util::addScript('gallery', 'pictures');
+OCP\Util::addStyle( 'gallery', 'supersized' );
+OCP\Util::addStyle( 'gallery', 'supersized.shutter' );
+OCP\Util::addScript('gallery', 'slideshow');
+OCP\Util::addScript('gallery', 'jquery.easing.min');
+OCP\Util::addScript('gallery', 'supersized.3.2.7.min');
+OCP\Util::addScript('gallery', 'supersized.shutter.min');
-include('gallery/lib/tiles.php');
+include 'gallery/lib/tiles.php';
$root = !empty($_GET['root']) ? $_GET['root'] : '/';
$images = \OC_FileCache::searchByMime('image', null, '/'.\OCP\USER::getUser().'/files'.$root);
@@ -97,4 +103,3 @@ $tmpl = new OCP\Template( 'gallery', 'index', 'user' );
$tmpl->assign('root', $root, false);
$tmpl->assign('tl', $tl, false);
$tmpl->printPage();
-?>
diff --git a/apps/gallery/js/albums.js b/apps/gallery/js/albums.js
index 413c71471a3..62d3f783ece 100644
--- a/apps/gallery/js/albums.js
+++ b/apps/gallery/js/albums.js
@@ -79,7 +79,7 @@ Albums={
});
element.append(local);
}
- var photoDisplayTemplate = '<div class="gallery_box"><div class="dummy"></div><div><a rel="images" href="'+OC.linkTo('files','download.php')+'?file=URLPATH"><img src="'+OC.filePath('gallery','ajax','thumbnail.php')+'?img=IMGPATH"></a></div></div>';
+ var photoDisplayTemplate = '<div class="gallery_box"><div class="dummy"></div><div><a rel="images" href="'+OC.linkTo('gallery/ajax','viewImage.php')+'?img=URLPATH"><img src="'+OC.filePath('gallery','ajax','thumbnail.php')+'?img=IMGPATH"></a></div></div>';
for (var i in Albums.photos) {
element.append(photoDisplayTemplate.replace("IMGPATH", escape(Albums.photos[i])).replace("URLPATH", escape(Albums.photos[i])));
}
diff --git a/apps/gallery/js/jquery.easing.min.js b/apps/gallery/js/jquery.easing.min.js
new file mode 100644
index 00000000000..bbf8410391a
--- /dev/null
+++ b/apps/gallery/js/jquery.easing.min.js
@@ -0,0 +1,71 @@
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright å© 2008 George McGinley Smith
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+jQuery.easing.jswing=jQuery.easing.swing;jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,f,a,h,g){return jQuery.easing[jQuery.easing.def](e,f,a,h,g)},easeInQuad:function(e,f,a,h,g){return h*(f/=g)*f+a},easeOutQuad:function(e,f,a,h,g){return -h*(f/=g)*(f-2)+a},easeInOutQuad:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f+a}return -h/2*((--f)*(f-2)-1)+a},easeInCubic:function(e,f,a,h,g){return h*(f/=g)*f*f+a},easeOutCubic:function(e,f,a,h,g){return h*((f=f/g-1)*f*f+1)+a},easeInOutCubic:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f+a}return h/2*((f-=2)*f*f+2)+a},easeInQuart:function(e,f,a,h,g){return h*(f/=g)*f*f*f+a},easeOutQuart:function(e,f,a,h,g){return -h*((f=f/g-1)*f*f*f-1)+a},easeInOutQuart:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f+a}return -h/2*((f-=2)*f*f*f-2)+a},easeInQuint:function(e,f,a,h,g){return h*(f/=g)*f*f*f*f+a},easeOutQuint:function(e,f,a,h,g){return h*((f=f/g-1)*f*f*f*f+1)+a},easeInOutQuint:function(e,f,a,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+a}return h/2*((f-=2)*f*f*f*f+2)+a},easeInSine:function(e,f,a,h,g){return -h*Math.cos(f/g*(Math.PI/2))+h+a},easeOutSine:function(e,f,a,h,g){return h*Math.sin(f/g*(Math.PI/2))+a},easeInOutSine:function(e,f,a,h,g){return -h/2*(Math.cos(Math.PI*f/g)-1)+a},easeInExpo:function(e,f,a,h,g){return(f==0)?a:h*Math.pow(2,10*(f/g-1))+a},easeOutExpo:function(e,f,a,h,g){return(f==g)?a+h:h*(-Math.pow(2,-10*f/g)+1)+a},easeInOutExpo:function(e,f,a,h,g){if(f==0){return a}if(f==g){return a+h}if((f/=g/2)<1){return h/2*Math.pow(2,10*(f-1))+a}return h/2*(-Math.pow(2,-10*--f)+2)+a},easeInCirc:function(e,f,a,h,g){return -h*(Math.sqrt(1-(f/=g)*f)-1)+a},easeOutCirc:function(e,f,a,h,g){return h*Math.sqrt(1-(f=f/g-1)*f)+a},easeInOutCirc:function(e,f,a,h,g){if((f/=g/2)<1){return -h/2*(Math.sqrt(1-f*f)-1)+a}return h/2*(Math.sqrt(1-(f-=2)*f)+1)+a},easeInElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return -(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e},easeOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k)==1){return e+l}if(!j){j=k*0.3}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}return g*Math.pow(2,-10*h)*Math.sin((h*k-i)*(2*Math.PI)/j)+l+e},easeInOutElastic:function(f,h,e,l,k){var i=1.70158;var j=0;var g=l;if(h==0){return e}if((h/=k/2)==2){return e+l}if(!j){j=k*(0.3*1.5)}if(g<Math.abs(l)){g=l;var i=j/4}else{var i=j/(2*Math.PI)*Math.asin(l/g)}if(h<1){return -0.5*(g*Math.pow(2,10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j))+e}return g*Math.pow(2,-10*(h-=1))*Math.sin((h*k-i)*(2*Math.PI)/j)*0.5+l+e},easeInBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*(f/=h)*f*((g+1)*f-g)+a},easeOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}return i*((f=f/h-1)*f*((g+1)*f+g)+1)+a},easeInOutBack:function(e,f,a,i,h,g){if(g==undefined){g=1.70158}if((f/=h/2)<1){return i/2*(f*f*(((g*=(1.525))+1)*f-g))+a}return i/2*((f-=2)*f*(((g*=(1.525))+1)*f+g)+2)+a},easeInBounce:function(e,f,a,h,g){return h-jQuery.easing.easeOutBounce(e,g-f,0,h,g)+a},easeOutBounce:function(e,f,a,h,g){if((f/=g)<(1/2.75)){return h*(7.5625*f*f)+a}else{if(f<(2/2.75)){return h*(7.5625*(f-=(1.5/2.75))*f+0.75)+a}else{if(f<(2.5/2.75)){return h*(7.5625*(f-=(2.25/2.75))*f+0.9375)+a}else{return h*(7.5625*(f-=(2.625/2.75))*f+0.984375)+a}}}},easeInOutBounce:function(e,f,a,h,g){if(f<g/2){return jQuery.easing.easeInBounce(e,f*2,0,h,g)*0.5+a}return jQuery.easing.easeOutBounce(e,f*2-g,0,h,g)*0.5+h*0.5+a}});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright å© 2001 Robert Penner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * Neither the name of the author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */ \ No newline at end of file
diff --git a/apps/gallery/js/slideshow.js b/apps/gallery/js/slideshow.js
new file mode 100644
index 00000000000..cc5dfc44a26
--- /dev/null
+++ b/apps/gallery/js/slideshow.js
@@ -0,0 +1,58 @@
+$(document).ready(function(){
+
+ $.endSlideshow = function () {
+ if($.supersized.vars.slideshow_interval){
+ clearInterval($.supersized.vars.slideshow_interval);
+ };
+
+ $('#supersized-holder').remove();
+ $('#slideshow-content').hide();
+ $('#thumb-list').remove();
+ }
+
+ // add slideshow in holder div
+ $('#slideshow input.start').click(function(){
+
+ var images=[];
+ $('#gallerycontent div a').each(function(i,a){
+ images.push({image : a.href, title : a.title.replace(/</, '&lt;').replace(/>/, '&gt;'), thumb : a.children[0].src, url : 'javascript:$.endSlideshow()'});
+ });
+
+ if (images.length <= 0) {
+ return;
+ }
+
+ $('body').append("<div id='supersized-holder'></div>");
+ $('#supersized-loader').remove();
+ $('#supersized').remove();
+ $('#supersized-holder').append("<div id='supersized-loader'></div><ul id='supersized'></ul>");
+ $('#supersized').show();
+ $('#slideshow-content').show();
+
+
+ jQuery(function($){
+
+ $.supersized({
+
+ // Functionality
+ slide_interval : 3000, // Length between transitions
+ transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left
+ transition_speed : 700, // Speed of transition
+
+ // Components
+ slide_links : 'blank', // Individual links for each slide (Options: false, 'num', 'name', 'blank')
+ slides : images // Slideshow Images
+
+ });
+ });
+
+ });
+
+ //close slideshow on esc and remove holder
+ $(document).keyup(function(e) {
+ if (e.keyCode == 27) { // esc
+ $.endSlideshow();
+ }
+ });
+
+});
diff --git a/apps/gallery/js/supersized.3.2.7.js b/apps/gallery/js/supersized.3.2.7.js
new file mode 100644
index 00000000000..f5a1c0bbc2d
--- /dev/null
+++ b/apps/gallery/js/supersized.3.2.7.js
@@ -0,0 +1,930 @@
+/*
+
+ Supersized - Fullscreen Slideshow jQuery Plugin
+ Version : 3.2.7
+ Site : www.buildinternet.com/project/supersized
+
+ Author : Sam Dunn
+ Company : One Mighty Roar (www.onemightyroar.com)
+ License : MIT License / GPL License
+
+*/
+
+(function($){
+
+ /* Place Supersized Elements
+ ----------------------------*/
+ $(document).ready(function() {
+ $('body').append('<div id="supersized-loader"></div><ul id="supersized"></ul>');
+ });
+
+
+ $.supersized = function(options){
+
+ /* Variables
+ ----------------------------*/
+ var el = '#supersized',
+ base = this;
+ // Access to jQuery and DOM versions of element
+ base.$el = $(el);
+ base.el = el;
+ vars = $.supersized.vars;
+ // Add a reverse reference to the DOM object
+ base.$el.data("supersized", base);
+ api = base.$el.data('supersized');
+
+ base.init = function(){
+ // Combine options and vars
+ $.supersized.vars = $.extend($.supersized.vars, $.supersized.themeVars);
+ $.supersized.vars.options = $.extend({},$.supersized.defaultOptions, $.supersized.themeOptions, options);
+ base.options = $.supersized.vars.options;
+
+ base._build();
+ };
+
+
+ /* Build Elements
+ ----------------------------*/
+ base._build = function(){
+ // Add in slide markers
+ var thisSlide = 0,
+ slideSet = '',
+ markers = '',
+ markerContent,
+ thumbMarkers = '',
+ thumbImage;
+
+ while(thisSlide <= base.options.slides.length-1){
+ //Determine slide link content
+ switch(base.options.slide_links){
+ case 'num':
+ markerContent = thisSlide;
+ break;
+ case 'name':
+ markerContent = base.options.slides[thisSlide].title;
+ break;
+ case 'blank':
+ markerContent = '';
+ break;
+ }
+
+ slideSet = slideSet+'<li class="slide-'+thisSlide+'"></li>';
+
+ if(thisSlide == base.options.start_slide-1){
+ // Slide links
+ if (base.options.slide_links)markers = markers+'<li class="slide-link-'+thisSlide+' current-slide"><a>'+markerContent+'</a></li>';
+ // Slide Thumbnail Links
+ if (base.options.thumb_links){
+ base.options.slides[thisSlide].thumb ? thumbImage = base.options.slides[thisSlide].thumb : thumbImage = base.options.slides[thisSlide].image;
+ thumbMarkers = thumbMarkers+'<li class="thumb'+thisSlide+' current-thumb"><img src="'+thumbImage+'"/></li>';
+ };
+ }else{
+ // Slide links
+ if (base.options.slide_links) markers = markers+'<li class="slide-link-'+thisSlide+'" ><a>'+markerContent+'</a></li>';
+ // Slide Thumbnail Links
+ if (base.options.thumb_links){
+ base.options.slides[thisSlide].thumb ? thumbImage = base.options.slides[thisSlide].thumb : thumbImage = base.options.slides[thisSlide].image;
+ thumbMarkers = thumbMarkers+'<li class="thumb'+thisSlide+'"><img src="'+thumbImage+'"/></li>';
+ };
+ }
+ thisSlide++;
+ }
+
+ if (base.options.slide_links) $(vars.slide_list).html(markers);
+ if (base.options.thumb_links && vars.thumb_tray.length){
+ $(vars.thumb_tray).append('<ul id="'+vars.thumb_list.replace('#','')+'">'+thumbMarkers+'</ul>');
+ }
+
+ $(base.el).append(slideSet);
+
+ // Add in thumbnails
+ if (base.options.thumbnail_navigation){
+ // Load previous thumbnail
+ vars.current_slide - 1 < 0 ? prevThumb = base.options.slides.length - 1 : prevThumb = vars.current_slide - 1;
+ $(vars.prev_thumb).show().html($("<img/>").attr("src", base.options.slides[prevThumb].image));
+
+ // Load next thumbnail
+ vars.current_slide == base.options.slides.length - 1 ? nextThumb = 0 : nextThumb = vars.current_slide + 1;
+ $(vars.next_thumb).show().html($("<img/>").attr("src", base.options.slides[nextThumb].image));
+ }
+
+ base._start(); // Get things started
+ };
+
+
+ /* Initialize
+ ----------------------------*/
+ base._start = function(){
+
+ // Determine if starting slide random
+ if (base.options.start_slide){
+ vars.current_slide = base.options.start_slide - 1;
+ }else{
+ vars.current_slide = Math.floor(Math.random()*base.options.slides.length); // Generate random slide number
+ }
+
+ // If links should open in new window
+ var linkTarget = base.options.new_window ? ' target="_blank"' : '';
+
+ // Set slideshow quality (Supported only in FF and IE, no Webkit)
+ if (base.options.performance == 3){
+ base.$el.addClass('speed'); // Faster transitions
+ } else if ((base.options.performance == 1) || (base.options.performance == 2)){
+ base.$el.addClass('quality'); // Higher image quality
+ }
+
+ // Shuffle slide order if needed
+ if (base.options.random){
+ arr = base.options.slides;
+ for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x); // Fisher-Yates shuffle algorithm (jsfromhell.com/array/shuffle)
+ base.options.slides = arr;
+ }
+
+ /*-----Load initial set of images-----*/
+
+ if (base.options.slides.length > 1){
+ if(base.options.slides.length > 2){
+ // Set previous image
+ vars.current_slide - 1 < 0 ? loadPrev = base.options.slides.length - 1 : loadPrev = vars.current_slide - 1; // If slide is 1, load last slide as previous
+ var imageLink = (base.options.slides[loadPrev].url) ? "href='" + base.options.slides[loadPrev].url + "'" : "";
+
+ var imgPrev = $('<img src="'+base.options.slides[loadPrev].image+'"/>');
+ var slidePrev = base.el+' li:eq('+loadPrev+')';
+ imgPrev.appendTo(slidePrev).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading prevslide');
+
+ imgPrev.load(function(){
+ $(this).data('origWidth', $(this).width()).data('origHeight', $(this).height());
+ base.resizeNow(); // Resize background image
+ }); // End Load
+ }
+ } else {
+ // Slideshow turned off if there is only one slide
+ base.options.slideshow = 0;
+ }
+
+ // Set current image
+ imageLink = (api.getField('url')) ? "href='" + api.getField('url') + "'" : "";
+ var img = $('<img src="'+api.getField('image')+'"/>');
+
+ var slideCurrent= base.el+' li:eq('+vars.current_slide+')';
+ img.appendTo(slideCurrent).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading activeslide');
+
+ img.load(function(){
+ base._origDim($(this));
+ base.resizeNow(); // Resize background image
+ base.launch();
+ if( typeof theme != 'undefined' && typeof theme._init == "function" ) theme._init(); // Load Theme
+ });
+
+ if (base.options.slides.length > 1){
+ // Set next image
+ vars.current_slide == base.options.slides.length - 1 ? loadNext = 0 : loadNext = vars.current_slide + 1; // If slide is last, load first slide as next
+ imageLink = (base.options.slides[loadNext].url) ? "href='" + base.options.slides[loadNext].url + "'" : "";
+
+ var imgNext = $('<img src="'+base.options.slides[loadNext].image+'"/>');
+ var slideNext = base.el+' li:eq('+loadNext+')';
+ imgNext.appendTo(slideNext).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading');
+
+ imgNext.load(function(){
+ $(this).data('origWidth', $(this).width()).data('origHeight', $(this).height());
+ base.resizeNow(); // Resize background image
+ }); // End Load
+ }
+ /*-----End load initial images-----*/
+
+ // Hide elements to be faded in
+ base.$el.css('visibility','hidden');
+ $('.load-item').hide();
+
+ };
+
+
+ /* Launch Supersized
+ ----------------------------*/
+ base.launch = function(){
+
+ base.$el.css('visibility','visible');
+ $('#supersized-loader').remove(); //Hide loading animation
+
+ // Call theme function for before slide transition
+ if( typeof theme != 'undefined' && typeof theme.beforeAnimation == "function" ) theme.beforeAnimation('next');
+ $('.load-item').show();
+
+ // Keyboard Navigation
+ if (base.options.keyboard_nav){
+ $(document.documentElement).keyup(function (event) {
+
+ if(vars.in_animation) return false; // Abort if currently animating
+
+ // Left Arrow or Down Arrow
+ if ((event.keyCode == 37) || (event.keyCode == 40)) {
+ clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup
+ base.prevSlide();
+
+ // Right Arrow or Up Arrow
+ } else if ((event.keyCode == 39) || (event.keyCode == 38)) {
+ clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup
+ base.nextSlide();
+
+ // Spacebar
+ } else if (event.keyCode == 32 && !vars.hover_pause) {
+ clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup
+ base.playToggle();
+ }
+
+ });
+ }
+
+ // Pause when hover on image
+ if (base.options.slideshow && base.options.pause_hover){
+ $(base.el).hover(function() {
+ if(vars.in_animation) return false; // Abort if currently animating
+ vars.hover_pause = true; // Mark slideshow paused from hover
+ if(!vars.is_paused){
+ vars.hover_pause = 'resume'; // It needs to resume afterwards
+ base.playToggle();
+ }
+ }, function() {
+ if(vars.hover_pause == 'resume'){
+ base.playToggle();
+ vars.hover_pause = false;
+ }
+ });
+ }
+
+ if (base.options.slide_links){
+ // Slide marker clicked
+ $(vars.slide_list+'> li').click(function(){
+
+ index = $(vars.slide_list+'> li').index(this);
+ targetSlide = index + 1;
+
+ base.goTo(targetSlide);
+ return false;
+
+ });
+ }
+
+ // Thumb marker clicked
+ if (base.options.thumb_links){
+ $(vars.thumb_list+'> li').click(function(){
+
+ index = $(vars.thumb_list+'> li').index(this);
+ targetSlide = index + 1;
+
+ api.goTo(targetSlide);
+ return false;
+
+ });
+ }
+
+ // Start slideshow if enabled
+ if (base.options.slideshow && base.options.slides.length > 1){
+
+ // Start slideshow if autoplay enabled
+ if (base.options.autoplay && base.options.slides.length > 1){
+ vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval); // Initiate slide interval
+ }else{
+ vars.is_paused = true; // Mark as paused
+ }
+
+ //Prevent navigation items from being dragged
+ $('.load-item img').bind("contextmenu mousedown",function(){
+ return false;
+ });
+
+ }
+
+ // Adjust image when browser is resized
+ $(window).resize(function(){
+ base.resizeNow();
+ });
+
+ };
+
+
+ /* Resize Images
+ ----------------------------*/
+ base.resizeNow = function(){
+
+ return base.$el.each(function() {
+ // Resize each image seperately
+ $('img', base.el).each(function(){
+
+ thisSlide = $(this);
+ var ratio = (thisSlide.data('origHeight')/thisSlide.data('origWidth')).toFixed(2); // Define image ratio
+
+ // Gather browser size
+ var browserwidth = base.$el.width(),
+ browserheight = base.$el.height(),
+ offset;
+
+ /*-----Resize Image-----*/
+ if (base.options.fit_always){ // Fit always is enabled
+ if ((browserheight/browserwidth) > ratio){
+ resizeWidth();
+ } else {
+ resizeHeight();
+ }
+ }else{ // Normal Resize
+ if ((browserheight <= base.options.min_height) && (browserwidth <= base.options.min_width)){ // If window smaller than minimum width and height
+
+ if ((browserheight/browserwidth) > ratio){
+ base.options.fit_landscape && ratio < 1 ? resizeWidth(true) : resizeHeight(true); // If landscapes are set to fit
+ } else {
+ base.options.fit_portrait && ratio >= 1 ? resizeHeight(true) : resizeWidth(true); // If portraits are set to fit
+ }
+
+ } else if (browserwidth <= base.options.min_width){ // If window only smaller than minimum width
+
+ if ((browserheight/browserwidth) > ratio){
+ base.options.fit_landscape && ratio < 1 ? resizeWidth(true) : resizeHeight(); // If landscapes are set to fit
+ } else {
+ base.options.fit_portrait && ratio >= 1 ? resizeHeight() : resizeWidth(true); // If portraits are set to fit
+ }
+
+ } else if (browserheight <= base.options.min_height){ // If window only smaller than minimum height
+
+ if ((browserheight/browserwidth) > ratio){
+ base.options.fit_landscape && ratio < 1 ? resizeWidth() : resizeHeight(true); // If landscapes are set to fit
+ } else {
+ base.options.fit_portrait && ratio >= 1 ? resizeHeight(true) : resizeWidth(); // If portraits are set to fit
+ }
+
+ } else { // If larger than minimums
+
+ if ((browserheight/browserwidth) > ratio){
+ base.options.fit_landscape && ratio < 1 ? resizeWidth() : resizeHeight(); // If landscapes are set to fit
+ } else {
+ base.options.fit_portrait && ratio >= 1 ? resizeHeight() : resizeWidth(); // If portraits are set to fit
+ }
+
+ }
+ }
+ /*-----End Image Resize-----*/
+
+
+ /*-----Resize Functions-----*/
+
+ function resizeWidth(minimum){
+ if (minimum){ // If minimum height needs to be considered
+ if(thisSlide.width() < browserwidth || thisSlide.width() < base.options.min_width ){
+ if (thisSlide.width() * ratio >= base.options.min_height){
+ thisSlide.width(base.options.min_width);
+ thisSlide.height(thisSlide.width() * ratio);
+ }else{
+ resizeHeight();
+ }
+ }
+ }else{
+ if (base.options.min_height >= browserheight && !base.options.fit_landscape){ // If minimum height needs to be considered
+ if (browserwidth * ratio >= base.options.min_height || (browserwidth * ratio >= base.options.min_height && ratio <= 1)){ // If resizing would push below minimum height or image is a landscape
+ thisSlide.width(browserwidth);
+ thisSlide.height(browserwidth * ratio);
+ } else if (ratio > 1){ // Else the image is portrait
+ thisSlide.height(base.options.min_height);
+ thisSlide.width(thisSlide.height() / ratio);
+ } else if (thisSlide.width() < browserwidth) {
+ thisSlide.width(browserwidth);
+ thisSlide.height(thisSlide.width() * ratio);
+ }
+ }else{ // Otherwise, resize as normal
+ thisSlide.width(browserwidth);
+ thisSlide.height(browserwidth * ratio);
+ }
+ }
+ };
+
+ function resizeHeight(minimum){
+ if (minimum){ // If minimum height needs to be considered
+ if(thisSlide.height() < browserheight){
+ if (thisSlide.height() / ratio >= base.options.min_width){
+ thisSlide.height(base.options.min_height);
+ thisSlide.width(thisSlide.height() / ratio);
+ }else{
+ resizeWidth(true);
+ }
+ }
+ }else{ // Otherwise, resized as normal
+ if (base.options.min_width >= browserwidth){ // If minimum width needs to be considered
+ if (browserheight / ratio >= base.options.min_width || ratio > 1){ // If resizing would push below minimum width or image is a portrait
+ thisSlide.height(browserheight);
+ thisSlide.width(browserheight / ratio);
+ } else if (ratio <= 1){ // Else the image is landscape
+ thisSlide.width(base.options.min_width);
+ thisSlide.height(thisSlide.width() * ratio);
+ }
+ }else{ // Otherwise, resize as normal
+ thisSlide.height(browserheight);
+ thisSlide.width(browserheight / ratio);
+ }
+ }
+ };
+
+ /*-----End Resize Functions-----*/
+
+ if (thisSlide.parents('li').hasClass('image-loading')){
+ $('.image-loading').removeClass('image-loading');
+ }
+
+ // Horizontally Center
+ if (base.options.horizontal_center){
+ $(this).css('left', (browserwidth - $(this).width())/2);
+ }
+
+ // Vertically Center
+ if (base.options.vertical_center){
+ $(this).css('top', (browserheight - $(this).height())/2);
+ }
+
+ });
+
+ // Basic image drag and right click protection
+ if (base.options.image_protect){
+
+ $('img', base.el).bind("contextmenu mousedown",function(){
+ return false;
+ });
+
+ }
+
+ return false;
+
+ });
+
+ };
+
+
+ /* Next Slide
+ ----------------------------*/
+ base.nextSlide = function(){
+
+ if(vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating
+ else vars.in_animation = true; // Otherwise set animation marker
+
+ clearInterval(vars.slideshow_interval); // Stop slideshow
+
+ var slides = base.options.slides, // Pull in slides array
+ liveslide = base.$el.find('.activeslide'); // Find active slide
+ $('.prevslide').removeClass('prevslide');
+ liveslide.removeClass('activeslide').addClass('prevslide'); // Remove active class & update previous slide
+
+ // Get the slide number of new slide
+ vars.current_slide + 1 == base.options.slides.length ? vars.current_slide = 0 : vars.current_slide++;
+
+ var nextslide = $(base.el+' li:eq('+vars.current_slide+')'),
+ prevslide = base.$el.find('.prevslide');
+
+ // If hybrid mode is on drop quality for transition
+ if (base.options.performance == 1) base.$el.removeClass('quality').addClass('speed');
+
+
+ /*-----Load Image-----*/
+
+ loadSlide = false;
+
+ vars.current_slide == base.options.slides.length - 1 ? loadSlide = 0 : loadSlide = vars.current_slide + 1; // Determine next slide
+
+ var targetList = base.el+' li:eq('+loadSlide+')';
+ if (!$(targetList).html()){
+
+ // If links should open in new window
+ var linkTarget = base.options.new_window ? ' target="_blank"' : '';
+
+ imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it
+ var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>');
+
+ img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden');
+
+ img.load(function(){
+ base._origDim($(this));
+ base.resizeNow();
+ }); // End Load
+ };
+
+ // Update thumbnails (if enabled)
+ if (base.options.thumbnail_navigation == 1){
+
+ // Load previous thumbnail
+ vars.current_slide - 1 < 0 ? prevThumb = base.options.slides.length - 1 : prevThumb = vars.current_slide - 1;
+ $(vars.prev_thumb).html($("<img/>").attr("src", base.options.slides[prevThumb].image));
+
+ // Load next thumbnail
+ nextThumb = loadSlide;
+ $(vars.next_thumb).html($("<img/>").attr("src", base.options.slides[nextThumb].image));
+
+ }
+
+
+
+ /*-----End Load Image-----*/
+
+
+ // Call theme function for before slide transition
+ if( typeof theme != 'undefined' && typeof theme.beforeAnimation == "function" ) theme.beforeAnimation('next');
+
+ //Update slide markers
+ if (base.options.slide_links){
+ $('.current-slide').removeClass('current-slide');
+ $(vars.slide_list +'> li' ).eq(vars.current_slide).addClass('current-slide');
+ }
+
+ nextslide.css('visibility','hidden').addClass('activeslide'); // Update active slide
+
+ switch(base.options.transition){
+ case 0: case 'none': // No transition
+ nextslide.css('visibility','visible'); vars.in_animation = false; base.afterAnimation();
+ break;
+ case 1: case 'fade': // Fade
+ nextslide.animate({opacity : 0},0).css('visibility','visible').animate({opacity : 1, avoidTransforms : false}, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 2: case 'slideTop': // Slide Top
+ nextslide.animate({top : -base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 3: case 'slideRight': // Slide Right
+ nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 4: case 'slideBottom': // Slide Bottom
+ nextslide.animate({top : base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 5: case 'slideLeft': // Slide Left
+ nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 6: case 'carouselRight': // Carousel Right
+ nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ liveslide.animate({ left: -base.$el.width(), avoidTransforms : false }, base.options.transition_speed );
+ break;
+ case 7: case 'carouselLeft': // Carousel Left
+ nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ liveslide.animate({ left: base.$el.width(), avoidTransforms : false }, base.options.transition_speed );
+ break;
+ }
+ return false;
+ };
+
+
+ /* Previous Slide
+ ----------------------------*/
+ base.prevSlide = function(){
+
+ if(vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating
+ else vars.in_animation = true; // Otherwise set animation marker
+
+ clearInterval(vars.slideshow_interval); // Stop slideshow
+
+ var slides = base.options.slides, // Pull in slides array
+ liveslide = base.$el.find('.activeslide'); // Find active slide
+ $('.prevslide').removeClass('prevslide');
+ liveslide.removeClass('activeslide').addClass('prevslide'); // Remove active class & update previous slide
+
+ // Get current slide number
+ vars.current_slide == 0 ? vars.current_slide = base.options.slides.length - 1 : vars.current_slide-- ;
+
+ var nextslide = $(base.el+' li:eq('+vars.current_slide+')'),
+ prevslide = base.$el.find('.prevslide');
+
+ // If hybrid mode is on drop quality for transition
+ if (base.options.performance == 1) base.$el.removeClass('quality').addClass('speed');
+
+
+ /*-----Load Image-----*/
+
+ loadSlide = vars.current_slide;
+
+ var targetList = base.el+' li:eq('+loadSlide+')';
+ if (!$(targetList).html()){
+ // If links should open in new window
+ var linkTarget = base.options.new_window ? ' target="_blank"' : '';
+ imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it
+ var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>');
+
+ img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden');
+
+ img.load(function(){
+ base._origDim($(this));
+ base.resizeNow();
+ }); // End Load
+ };
+
+ // Update thumbnails (if enabled)
+ if (base.options.thumbnail_navigation == 1){
+
+ // Load previous thumbnail
+ //prevThumb = loadSlide;
+ loadSlide == 0 ? prevThumb = base.options.slides.length - 1 : prevThumb = loadSlide - 1;
+ $(vars.prev_thumb).html($("<img/>").attr("src", base.options.slides[prevThumb].image));
+
+ // Load next thumbnail
+ vars.current_slide == base.options.slides.length - 1 ? nextThumb = 0 : nextThumb = vars.current_slide + 1;
+ $(vars.next_thumb).html($("<img/>").attr("src", base.options.slides[nextThumb].image));
+ }
+
+ /*-----End Load Image-----*/
+
+
+ // Call theme function for before slide transition
+ if( typeof theme != 'undefined' && typeof theme.beforeAnimation == "function" ) theme.beforeAnimation('prev');
+
+ //Update slide markers
+ if (base.options.slide_links){
+ $('.current-slide').removeClass('current-slide');
+ $(vars.slide_list +'> li' ).eq(vars.current_slide).addClass('current-slide');
+ }
+
+ nextslide.css('visibility','hidden').addClass('activeslide'); // Update active slide
+
+ switch(base.options.transition){
+ case 0: case 'none': // No transition
+ nextslide.css('visibility','visible'); vars.in_animation = false; base.afterAnimation();
+ break;
+ case 1: case 'fade': // Fade
+ nextslide.animate({opacity : 0},0).css('visibility','visible').animate({opacity : 1, avoidTransforms : false}, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 2: case 'slideTop': // Slide Top (reverse)
+ nextslide.animate({top : base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 3: case 'slideRight': // Slide Right (reverse)
+ nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 4: case 'slideBottom': // Slide Bottom (reverse)
+ nextslide.animate({top : -base.$el.height()}, 0 ).css('visibility','visible').animate({ top:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 5: case 'slideLeft': // Slide Left (reverse)
+ nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ break;
+ case 6: case 'carouselRight': // Carousel Right (reverse)
+ nextslide.animate({left : -base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ liveslide.animate({left : 0}, 0 ).animate({ left: base.$el.width(), avoidTransforms : false}, base.options.transition_speed );
+ break;
+ case 7: case 'carouselLeft': // Carousel Left (reverse)
+ nextslide.animate({left : base.$el.width()}, 0 ).css('visibility','visible').animate({ left:0, avoidTransforms : false }, base.options.transition_speed, function(){ base.afterAnimation(); });
+ liveslide.animate({left : 0}, 0 ).animate({ left: -base.$el.width(), avoidTransforms : false }, base.options.transition_speed );
+ break;
+ }
+ return false;
+ };
+
+
+ /* Play/Pause Toggle
+ ----------------------------*/
+ base.playToggle = function(){
+
+ if (vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating
+
+ if (vars.is_paused){
+
+ vars.is_paused = false;
+
+ // Call theme function for play
+ if( typeof theme != 'undefined' && typeof theme.playToggle == "function" ) theme.playToggle('play');
+
+ // Resume slideshow
+ vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval);
+
+ }else{
+
+ vars.is_paused = true;
+
+ // Call theme function for pause
+ if( typeof theme != 'undefined' && typeof theme.playToggle == "function" ) theme.playToggle('pause');
+
+ // Stop slideshow
+ clearInterval(vars.slideshow_interval);
+
+ }
+
+ return false;
+
+ };
+
+
+ /* Go to specific slide
+ ----------------------------*/
+ base.goTo = function(targetSlide){
+ if (vars.in_animation || !api.options.slideshow) return false; // Abort if currently animating
+
+ var totalSlides = base.options.slides.length;
+
+ // If target outside range
+ if(targetSlide < 0){
+ targetSlide = totalSlides;
+ }else if(targetSlide > totalSlides){
+ targetSlide = 1;
+ }
+ targetSlide = totalSlides - targetSlide + 1;
+
+ clearInterval(vars.slideshow_interval); // Stop slideshow, prevent buildup
+
+ // Call theme function for goTo trigger
+ if (typeof theme != 'undefined' && typeof theme.goTo == "function" ) theme.goTo();
+
+ if (vars.current_slide == totalSlides - targetSlide){
+ if(!(vars.is_paused)){
+ vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval);
+ }
+ return false;
+ }
+
+ // If ahead of current position
+ if(totalSlides - targetSlide > vars.current_slide ){
+
+ // Adjust for new next slide
+ vars.current_slide = totalSlides-targetSlide-1;
+ vars.update_images = 'next';
+ base._placeSlide(vars.update_images);
+
+ //Otherwise it's before current position
+ }else if(totalSlides - targetSlide < vars.current_slide){
+
+ // Adjust for new prev slide
+ vars.current_slide = totalSlides-targetSlide+1;
+ vars.update_images = 'prev';
+ base._placeSlide(vars.update_images);
+
+ }
+
+ // set active markers
+ if (base.options.slide_links){
+ $(vars.slide_list +'> .current-slide').removeClass('current-slide');
+ $(vars.slide_list +'> li').eq((totalSlides-targetSlide)).addClass('current-slide');
+ }
+
+ if (base.options.thumb_links){
+ $(vars.thumb_list +'> .current-thumb').removeClass('current-thumb');
+ $(vars.thumb_list +'> li').eq((totalSlides-targetSlide)).addClass('current-thumb');
+ }
+
+ };
+
+
+ /* Place Slide
+ ----------------------------*/
+ base._placeSlide = function(place){
+
+ // If links should open in new window
+ var linkTarget = base.options.new_window ? ' target="_blank"' : '';
+
+ loadSlide = false;
+
+ if (place == 'next'){
+
+ vars.current_slide == base.options.slides.length - 1 ? loadSlide = 0 : loadSlide = vars.current_slide + 1; // Determine next slide
+
+ var targetList = base.el+' li:eq('+loadSlide+')';
+
+ if (!$(targetList).html()){
+ // If links should open in new window
+ var linkTarget = base.options.new_window ? ' target="_blank"' : '';
+
+ imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it
+ var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>');
+
+ img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden');
+
+ img.load(function(){
+ base._origDim($(this));
+ base.resizeNow();
+ }); // End Load
+ };
+
+ base.nextSlide();
+
+ }else if (place == 'prev'){
+
+ vars.current_slide - 1 < 0 ? loadSlide = base.options.slides.length - 1 : loadSlide = vars.current_slide - 1; // Determine next slide
+
+ var targetList = base.el+' li:eq('+loadSlide+')';
+
+ if (!$(targetList).html()){
+ // If links should open in new window
+ var linkTarget = base.options.new_window ? ' target="_blank"' : '';
+
+ imageLink = (base.options.slides[loadSlide].url) ? "href='" + base.options.slides[loadSlide].url + "'" : ""; // If link exists, build it
+ var img = $('<img src="'+base.options.slides[loadSlide].image+'"/>');
+
+ img.appendTo(targetList).wrap('<a ' + imageLink + linkTarget + '></a>').parent().parent().addClass('image-loading').css('visibility','hidden');
+
+ img.load(function(){
+ base._origDim($(this));
+ base.resizeNow();
+ }); // End Load
+ };
+ base.prevSlide();
+ }
+
+ };
+
+
+ /* Get Original Dimensions
+ ----------------------------*/
+ base._origDim = function(targetSlide){
+ targetSlide.data('origWidth', targetSlide.width()).data('origHeight', targetSlide.height());
+ };
+
+
+ /* After Slide Animation
+ ----------------------------*/
+ base.afterAnimation = function(){
+
+ // If hybrid mode is on swap back to higher image quality
+ if (base.options.performance == 1){
+ base.$el.removeClass('speed').addClass('quality');
+ }
+
+ // Update previous slide
+ if (vars.update_images){
+ vars.current_slide - 1 < 0 ? setPrev = base.options.slides.length - 1 : setPrev = vars.current_slide-1;
+ vars.update_images = false;
+ $('.prevslide').removeClass('prevslide');
+ $(base.el+' li:eq('+setPrev+')').addClass('prevslide');
+ }
+
+ vars.in_animation = false;
+
+ // Resume slideshow
+ if (!vars.is_paused && base.options.slideshow){
+ vars.slideshow_interval = setInterval(base.nextSlide, base.options.slide_interval);
+ if (base.options.stop_loop && vars.current_slide == base.options.slides.length - 1 ) base.playToggle();
+ }
+
+ // Call theme function for after slide transition
+ if (typeof theme != 'undefined' && typeof theme.afterAnimation == "function" ) theme.afterAnimation();
+
+ return false;
+
+ };
+
+ base.getField = function(field){
+ return base.options.slides[vars.current_slide][field];
+ };
+
+ // Make it go!
+ base.init();
+ };
+
+
+ /* Global Variables
+ ----------------------------*/
+ $.supersized.vars = {
+
+ // Elements
+ thumb_tray : '#thumb-tray', // Thumbnail tray
+ thumb_list : '#thumb-list', // Thumbnail list
+ slide_list : '#slide-list', // Slide link list
+
+ // Internal variables
+ current_slide : 0, // Current slide number
+ in_animation : false, // Prevents animations from stacking
+ is_paused : false, // Tracks paused on/off
+ hover_pause : false, // If slideshow is paused from hover
+ slideshow_interval : false, // Stores slideshow timer
+ update_images : false, // Trigger to update images after slide jump
+ options : {} // Stores assembled options list
+
+ };
+
+
+ /* Default Options
+ ----------------------------*/
+ $.supersized.defaultOptions = {
+
+ // Functionality
+ slideshow : 1, // Slideshow on/off
+ autoplay : 1, // Slideshow starts playing automatically
+ start_slide : 1, // Start slide (0 is random)
+ stop_loop : 0, // Stops slideshow on last slide
+ random : 0, // Randomize slide order (Ignores start slide)
+ slide_interval : 5000, // Length between transitions
+ transition : 1, // 0-None, 1-Fade, 2-Slide Top, 3-Slide Right, 4-Slide Bottom, 5-Slide Left, 6-Carousel Right, 7-Carousel Left
+ transition_speed : 750, // Speed of transition
+ new_window : 1, // Image links open in new window/tab
+ pause_hover : 0, // Pause slideshow on hover
+ keyboard_nav : 1, // Keyboard navigation on/off
+ performance : 1, // 0-Normal, 1-Hybrid speed/quality, 2-Optimizes image quality, 3-Optimizes transition speed // (Only works for Firefox/IE, not Webkit)
+ image_protect : 1, // Disables image dragging and right click with Javascript
+
+ // Size & Position
+ fit_always : 0, // Image will never exceed browser width or height (Ignores min. dimensions)
+ fit_landscape : 0, // Landscape images will not exceed browser width
+ fit_portrait : 1, // Portrait images will not exceed browser height
+ min_width : 0, // Min width allowed (in pixels)
+ min_height : 0, // Min height allowed (in pixels)
+ horizontal_center : 1, // Horizontally center background
+ vertical_center : 1, // Vertically center background
+
+
+ // Components
+ slide_links : 1, // Individual links for each slide (Options: false, 'num', 'name', 'blank')
+ thumb_links : 1, // Individual thumb links for each slide
+ thumbnail_navigation : 0 // Thumbnail navigation
+
+ };
+
+ $.fn.supersized = function(options){
+ return this.each(function(){
+ (new $.supersized(options));
+ });
+ };
+
+})(jQuery);
+
diff --git a/apps/gallery/js/supersized.3.2.7.min.js b/apps/gallery/js/supersized.3.2.7.min.js
new file mode 100644
index 00000000000..b9cea9cee1c
--- /dev/null
+++ b/apps/gallery/js/supersized.3.2.7.min.js
@@ -0,0 +1,13 @@
+/*
+
+ Supersized - Fullscreen Slideshow jQuery Plugin
+ Version : 3.2.7
+ Site : www.buildinternet.com/project/supersized
+
+ Author : Sam Dunn
+ Company : One Mighty Roar (www.onemightyroar.com)
+ License : MIT License / GPL License
+
+*/
+
+(function(a){a(document).ready(function(){a("body").append('<div id="supersized-loader"></div><ul id="supersized"></ul>')});a.supersized=function(b){var c="#supersized",d=this;d.$el=a(c);d.el=c;vars=a.supersized.vars;d.$el.data("supersized",d);api=d.$el.data("supersized");d.init=function(){a.supersized.vars=a.extend(a.supersized.vars,a.supersized.themeVars);a.supersized.vars.options=a.extend({},a.supersized.defaultOptions,a.supersized.themeOptions,b);d.options=a.supersized.vars.options;d._build()};d._build=function(){var g=0,e="",j="",h,f="",i;while(g<=d.options.slides.length-1){switch(d.options.slide_links){case"num":h=g;break;case"name":h=d.options.slides[g].title;break;case"blank":h="";break}e=e+'<li class="slide-'+g+'"></li>';if(g==d.options.start_slide-1){if(d.options.slide_links){j=j+'<li class="slide-link-'+g+' current-slide"><a>'+h+"</a></li>"}if(d.options.thumb_links){d.options.slides[g].thumb?i=d.options.slides[g].thumb:i=d.options.slides[g].image;f=f+'<li class="thumb'+g+' current-thumb"><img src="'+i+'"/></li>'}}else{if(d.options.slide_links){j=j+'<li class="slide-link-'+g+'" ><a>'+h+"</a></li>"}if(d.options.thumb_links){d.options.slides[g].thumb?i=d.options.slides[g].thumb:i=d.options.slides[g].image;f=f+'<li class="thumb'+g+'"><img src="'+i+'"/></li>'}}g++}if(d.options.slide_links){a(vars.slide_list).html(j)}if(d.options.thumb_links&&vars.thumb_tray.length){a(vars.thumb_tray).append('<ul id="'+vars.thumb_list.replace("#","")+'">'+f+"</ul>")}a(d.el).append(e);if(d.options.thumbnail_navigation){vars.current_slide-1<0?prevThumb=d.options.slides.length-1:prevThumb=vars.current_slide-1;a(vars.prev_thumb).show().html(a("<img/>").attr("src",d.options.slides[prevThumb].image));vars.current_slide==d.options.slides.length-1?nextThumb=0:nextThumb=vars.current_slide+1;a(vars.next_thumb).show().html(a("<img/>").attr("src",d.options.slides[nextThumb].image))}d._start()};d._start=function(){if(d.options.start_slide){vars.current_slide=d.options.start_slide-1}else{vars.current_slide=Math.floor(Math.random()*d.options.slides.length)}var o=d.options.new_window?' target="_blank"':"";if(d.options.performance==3){d.$el.addClass("speed")}else{if((d.options.performance==1)||(d.options.performance==2)){d.$el.addClass("quality")}}if(d.options.random){arr=d.options.slides;for(var h,m,k=arr.length;k;h=parseInt(Math.random()*k),m=arr[--k],arr[k]=arr[h],arr[h]=m){}d.options.slides=arr}if(d.options.slides.length>1){if(d.options.slides.length>2){vars.current_slide-1<0?loadPrev=d.options.slides.length-1:loadPrev=vars.current_slide-1;var g=(d.options.slides[loadPrev].url)?"href='"+d.options.slides[loadPrev].url+"'":"";var q=a('<img src="'+d.options.slides[loadPrev].image+'"/>');var n=d.el+" li:eq("+loadPrev+")";q.appendTo(n).wrap("<a "+g+o+"></a>").parent().parent().addClass("image-loading prevslide");q.load(function(){a(this).data("origWidth",a(this).width()).data("origHeight",a(this).height());d.resizeNow()})}}else{d.options.slideshow=0}g=(api.getField("url"))?"href='"+api.getField("url")+"'":"";var l=a('<img src="'+api.getField("image")+'"/>');var f=d.el+" li:eq("+vars.current_slide+")";l.appendTo(f).wrap("<a "+g+o+"></a>").parent().parent().addClass("image-loading activeslide");l.load(function(){d._origDim(a(this));d.resizeNow();d.launch();if(typeof theme!="undefined"&&typeof theme._init=="function"){theme._init()}});if(d.options.slides.length>1){vars.current_slide==d.options.slides.length-1?loadNext=0:loadNext=vars.current_slide+1;g=(d.options.slides[loadNext].url)?"href='"+d.options.slides[loadNext].url+"'":"";var e=a('<img src="'+d.options.slides[loadNext].image+'"/>');var p=d.el+" li:eq("+loadNext+")";e.appendTo(p).wrap("<a "+g+o+"></a>").parent().parent().addClass("image-loading");e.load(function(){a(this).data("origWidth",a(this).width()).data("origHeight",a(this).height());d.resizeNow()})}d.$el.css("visibility","hidden");a(".load-item").hide()};d.launch=function(){d.$el.css("visibility","visible");a("#supersized-loader").remove();if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("next")}a(".load-item").show();if(d.options.keyboard_nav){a(document.documentElement).keyup(function(e){if(vars.in_animation){return false}if((e.keyCode==37)||(e.keyCode==40)){clearInterval(vars.slideshow_interval);d.prevSlide()}else{if((e.keyCode==39)||(e.keyCode==38)){clearInterval(vars.slideshow_interval);d.nextSlide()}else{if(e.keyCode==32&&!vars.hover_pause){clearInterval(vars.slideshow_interval);d.playToggle()}}}})}if(d.options.slideshow&&d.options.pause_hover){a(d.el).hover(function(){if(vars.in_animation){return false}vars.hover_pause=true;if(!vars.is_paused){vars.hover_pause="resume";d.playToggle()}},function(){if(vars.hover_pause=="resume"){d.playToggle();vars.hover_pause=false}})}if(d.options.slide_links){a(vars.slide_list+"> li").click(function(){index=a(vars.slide_list+"> li").index(this);targetSlide=index+1;d.goTo(targetSlide);return false})}if(d.options.thumb_links){a(vars.thumb_list+"> li").click(function(){index=a(vars.thumb_list+"> li").index(this);targetSlide=index+1;api.goTo(targetSlide);return false})}if(d.options.slideshow&&d.options.slides.length>1){if(d.options.autoplay&&d.options.slides.length>1){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}else{vars.is_paused=true}a(".load-item img").bind("contextmenu mousedown",function(){return false})}a(window).resize(function(){d.resizeNow()})};d.resizeNow=function(){return d.$el.each(function(){a("img",d.el).each(function(){thisSlide=a(this);var f=(thisSlide.data("origHeight")/thisSlide.data("origWidth")).toFixed(2);var e=d.$el.width(),h=d.$el.height(),i;if(d.options.fit_always){if((h/e)>f){g()}else{j()}}else{if((h<=d.options.min_height)&&(e<=d.options.min_width)){if((h/e)>f){d.options.fit_landscape&&f<1?g(true):j(true)}else{d.options.fit_portrait&&f>=1?j(true):g(true)}}else{if(e<=d.options.min_width){if((h/e)>f){d.options.fit_landscape&&f<1?g(true):j()}else{d.options.fit_portrait&&f>=1?j():g(true)}}else{if(h<=d.options.min_height){if((h/e)>f){d.options.fit_landscape&&f<1?g():j(true)}else{d.options.fit_portrait&&f>=1?j(true):g()}}else{if((h/e)>f){d.options.fit_landscape&&f<1?g():j()}else{d.options.fit_portrait&&f>=1?j():g()}}}}}function g(k){if(k){if(thisSlide.width()<e||thisSlide.width()<d.options.min_width){if(thisSlide.width()*f>=d.options.min_height){thisSlide.width(d.options.min_width);thisSlide.height(thisSlide.width()*f)}else{j()}}}else{if(d.options.min_height>=h&&!d.options.fit_landscape){if(e*f>=d.options.min_height||(e*f>=d.options.min_height&&f<=1)){thisSlide.width(e);thisSlide.height(e*f)}else{if(f>1){thisSlide.height(d.options.min_height);thisSlide.width(thisSlide.height()/f)}else{if(thisSlide.width()<e){thisSlide.width(e);thisSlide.height(thisSlide.width()*f)}}}}else{thisSlide.width(e);thisSlide.height(e*f)}}}function j(k){if(k){if(thisSlide.height()<h){if(thisSlide.height()/f>=d.options.min_width){thisSlide.height(d.options.min_height);thisSlide.width(thisSlide.height()/f)}else{g(true)}}}else{if(d.options.min_width>=e){if(h/f>=d.options.min_width||f>1){thisSlide.height(h);thisSlide.width(h/f)}else{if(f<=1){thisSlide.width(d.options.min_width);thisSlide.height(thisSlide.width()*f)}}}else{thisSlide.height(h);thisSlide.width(h/f)}}}if(thisSlide.parents("li").hasClass("image-loading")){a(".image-loading").removeClass("image-loading")}if(d.options.horizontal_center){a(this).css("left",(e-a(this).width())/2)}if(d.options.vertical_center){a(this).css("top",(h-a(this).height())/2)}});if(d.options.image_protect){a("img",d.el).bind("contextmenu mousedown",function(){return false})}return false})};d.nextSlide=function(){if(vars.in_animation||!api.options.slideshow){return false}else{vars.in_animation=true}clearInterval(vars.slideshow_interval);var h=d.options.slides,e=d.$el.find(".activeslide");a(".prevslide").removeClass("prevslide");e.removeClass("activeslide").addClass("prevslide");vars.current_slide+1==d.options.slides.length?vars.current_slide=0:vars.current_slide++;var g=a(d.el+" li:eq("+vars.current_slide+")"),i=d.$el.find(".prevslide");if(d.options.performance==1){d.$el.removeClass("quality").addClass("speed")}loadSlide=false;vars.current_slide==d.options.slides.length-1?loadSlide=0:loadSlide=vars.current_slide+1;var k=d.el+" li:eq("+loadSlide+")";if(!a(k).html()){var j=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(k).wrap("<a "+imageLink+j+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}if(d.options.thumbnail_navigation==1){vars.current_slide-1<0?prevThumb=d.options.slides.length-1:prevThumb=vars.current_slide-1;a(vars.prev_thumb).html(a("<img/>").attr("src",d.options.slides[prevThumb].image));nextThumb=loadSlide;a(vars.next_thumb).html(a("<img/>").attr("src",d.options.slides[nextThumb].image))}if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("next")}if(d.options.slide_links){a(".current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq(vars.current_slide).addClass("current-slide")}g.css("visibility","hidden").addClass("activeslide");switch(d.options.transition){case 0:case"none":g.css("visibility","visible");vars.in_animation=false;d.afterAnimation();break;case 1:case"fade":g.animate({opacity:0},0).css("visibility","visible").animate({opacity:1,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 2:case"slideTop":g.animate({top:-d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 3:case"slideRight":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 4:case"slideBottom":g.animate({top:d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 5:case"slideLeft":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 6:case"carouselRight":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:-d.$el.width(),avoidTransforms:false},d.options.transition_speed);break;case 7:case"carouselLeft":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:d.$el.width(),avoidTransforms:false},d.options.transition_speed);break}return false};d.prevSlide=function(){if(vars.in_animation||!api.options.slideshow){return false}else{vars.in_animation=true}clearInterval(vars.slideshow_interval);var h=d.options.slides,e=d.$el.find(".activeslide");a(".prevslide").removeClass("prevslide");e.removeClass("activeslide").addClass("prevslide");vars.current_slide==0?vars.current_slide=d.options.slides.length-1:vars.current_slide--;var g=a(d.el+" li:eq("+vars.current_slide+")"),i=d.$el.find(".prevslide");if(d.options.performance==1){d.$el.removeClass("quality").addClass("speed")}loadSlide=vars.current_slide;var k=d.el+" li:eq("+loadSlide+")";if(!a(k).html()){var j=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(k).wrap("<a "+imageLink+j+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}if(d.options.thumbnail_navigation==1){loadSlide==0?prevThumb=d.options.slides.length-1:prevThumb=loadSlide-1;a(vars.prev_thumb).html(a("<img/>").attr("src",d.options.slides[prevThumb].image));vars.current_slide==d.options.slides.length-1?nextThumb=0:nextThumb=vars.current_slide+1;a(vars.next_thumb).html(a("<img/>").attr("src",d.options.slides[nextThumb].image))}if(typeof theme!="undefined"&&typeof theme.beforeAnimation=="function"){theme.beforeAnimation("prev")}if(d.options.slide_links){a(".current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq(vars.current_slide).addClass("current-slide")}g.css("visibility","hidden").addClass("activeslide");switch(d.options.transition){case 0:case"none":g.css("visibility","visible");vars.in_animation=false;d.afterAnimation();break;case 1:case"fade":g.animate({opacity:0},0).css("visibility","visible").animate({opacity:1,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 2:case"slideTop":g.animate({top:d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 3:case"slideRight":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 4:case"slideBottom":g.animate({top:-d.$el.height()},0).css("visibility","visible").animate({top:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 5:case"slideLeft":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});break;case 6:case"carouselRight":g.animate({left:-d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:0},0).animate({left:d.$el.width(),avoidTransforms:false},d.options.transition_speed);break;case 7:case"carouselLeft":g.animate({left:d.$el.width()},0).css("visibility","visible").animate({left:0,avoidTransforms:false},d.options.transition_speed,function(){d.afterAnimation()});e.animate({left:0},0).animate({left:-d.$el.width(),avoidTransforms:false},d.options.transition_speed);break}return false};d.playToggle=function(){if(vars.in_animation||!api.options.slideshow){return false}if(vars.is_paused){vars.is_paused=false;if(typeof theme!="undefined"&&typeof theme.playToggle=="function"){theme.playToggle("play")}vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}else{vars.is_paused=true;if(typeof theme!="undefined"&&typeof theme.playToggle=="function"){theme.playToggle("pause")}clearInterval(vars.slideshow_interval)}return false};d.goTo=function(f){if(vars.in_animation||!api.options.slideshow){return false}var e=d.options.slides.length;if(f<0){f=e}else{if(f>e){f=1}}f=e-f+1;clearInterval(vars.slideshow_interval);if(typeof theme!="undefined"&&typeof theme.goTo=="function"){theme.goTo()}if(vars.current_slide==e-f){if(!(vars.is_paused)){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval)}return false}if(e-f>vars.current_slide){vars.current_slide=e-f-1;vars.update_images="next";d._placeSlide(vars.update_images)}else{if(e-f<vars.current_slide){vars.current_slide=e-f+1;vars.update_images="prev";d._placeSlide(vars.update_images)}}if(d.options.slide_links){a(vars.slide_list+"> .current-slide").removeClass("current-slide");a(vars.slide_list+"> li").eq((e-f)).addClass("current-slide")}if(d.options.thumb_links){a(vars.thumb_list+"> .current-thumb").removeClass("current-thumb");a(vars.thumb_list+"> li").eq((e-f)).addClass("current-thumb")}};d._placeSlide=function(e){var h=d.options.new_window?' target="_blank"':"";loadSlide=false;if(e=="next"){vars.current_slide==d.options.slides.length-1?loadSlide=0:loadSlide=vars.current_slide+1;var g=d.el+" li:eq("+loadSlide+")";if(!a(g).html()){var h=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(g).wrap("<a "+imageLink+h+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}d.nextSlide()}else{if(e=="prev"){vars.current_slide-1<0?loadSlide=d.options.slides.length-1:loadSlide=vars.current_slide-1;var g=d.el+" li:eq("+loadSlide+")";if(!a(g).html()){var h=d.options.new_window?' target="_blank"':"";imageLink=(d.options.slides[loadSlide].url)?"href='"+d.options.slides[loadSlide].url+"'":"";var f=a('<img src="'+d.options.slides[loadSlide].image+'"/>');f.appendTo(g).wrap("<a "+imageLink+h+"></a>").parent().parent().addClass("image-loading").css("visibility","hidden");f.load(function(){d._origDim(a(this));d.resizeNow()})}d.prevSlide()}}};d._origDim=function(e){e.data("origWidth",e.width()).data("origHeight",e.height())};d.afterAnimation=function(){if(d.options.performance==1){d.$el.removeClass("speed").addClass("quality")}if(vars.update_images){vars.current_slide-1<0?setPrev=d.options.slides.length-1:setPrev=vars.current_slide-1;vars.update_images=false;a(".prevslide").removeClass("prevslide");a(d.el+" li:eq("+setPrev+")").addClass("prevslide")}vars.in_animation=false;if(!vars.is_paused&&d.options.slideshow){vars.slideshow_interval=setInterval(d.nextSlide,d.options.slide_interval);if(d.options.stop_loop&&vars.current_slide==d.options.slides.length-1){d.playToggle()}}if(typeof theme!="undefined"&&typeof theme.afterAnimation=="function"){theme.afterAnimation()}return false};d.getField=function(e){return d.options.slides[vars.current_slide][e]};d.init()};a.supersized.vars={thumb_tray:"#thumb-tray",thumb_list:"#thumb-list",slide_list:"#slide-list",current_slide:0,in_animation:false,is_paused:false,hover_pause:false,slideshow_interval:false,update_images:false,options:{}};a.supersized.defaultOptions={slideshow:1,autoplay:1,start_slide:1,stop_loop:0,random:0,slide_interval:5000,transition:1,transition_speed:750,new_window:1,pause_hover:0,keyboard_nav:1,performance:1,image_protect:1,fit_always:0,fit_landscape:0,fit_portrait:1,min_width:0,min_height:0,horizontal_center:1,vertical_center:1,slide_links:1,thumb_links:1,thumbnail_navigation:0};a.fn.supersized=function(b){return this.each(function(){(new a.supersized(b))})}})(jQuery); \ No newline at end of file
diff --git a/apps/gallery/js/supersized.shutter.js b/apps/gallery/js/supersized.shutter.js
new file mode 100644
index 00000000000..cc3025a94a3
--- /dev/null
+++ b/apps/gallery/js/supersized.shutter.js
@@ -0,0 +1,337 @@
+/*
+
+ Supersized - Fullscreen Slideshow jQuery Plugin
+ Version : 3.2.7
+ Theme : Shutter 1.1
+
+ Site : www.buildinternet.com/project/supersized
+ Author : Sam Dunn
+ Company : One Mighty Roar (www.onemightyroar.com)
+ License : MIT License / GPL License
+
+*/
+
+(function($){
+
+ theme = {
+
+
+ /* Initial Placement
+ ----------------------------*/
+ _init : function(){
+
+ // Center Slide Links
+ if (api.options.slide_links) $(vars.slide_list).css('margin-left', -$(vars.slide_list).width()/2);
+
+ // Start progressbar if autoplay enabled
+ if (api.options.autoplay){
+ if (api.options.progress_bar) theme.progressBar();
+ }else{
+ if ($(vars.play_button).attr('src')) $(vars.play_button).attr("src", vars.image_path + "play.png"); // If pause play button is image, swap src
+ if (api.options.progress_bar) $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ); // Place progress bar
+ }
+
+
+ /* Thumbnail Tray
+ ----------------------------*/
+ // Hide tray off screen
+ $(vars.thumb_tray).animate({bottom : -$(vars.thumb_tray).height()}, 0 );
+
+ // Thumbnail Tray Toggle
+ $(vars.tray_button).toggle(function(){
+ $(vars.thumb_tray).stop().animate({bottom : 0, avoidTransforms : true}, 300 );
+ if ($(vars.tray_arrow).attr('src')) $(vars.tray_arrow).attr("src", vars.image_path + "button-tray-down.png");
+ return false;
+ }, function() {
+ $(vars.thumb_tray).stop().animate({bottom : -$(vars.thumb_tray).height(), avoidTransforms : true}, 300 );
+ if ($(vars.tray_arrow).attr('src')) $(vars.tray_arrow).attr("src", vars.image_path + "button-tray-up.png");
+ return false;
+ });
+
+ // Make thumb tray proper size
+ $(vars.thumb_list).width($('> li', vars.thumb_list).length * $('> li', vars.thumb_list).outerWidth(true)); //Adjust to true width of thumb markers
+
+ // Display total slides
+ if ($(vars.slide_total).length){
+ $(vars.slide_total).html(api.options.slides.length);
+ }
+
+
+ /* Thumbnail Tray Navigation
+ ----------------------------*/
+ if (api.options.thumb_links){
+ //Hide thumb arrows if not needed
+ if ($(vars.thumb_list).width() <= $(vars.thumb_tray).width()){
+ $(vars.thumb_back +','+vars.thumb_forward).fadeOut(0);
+ }
+
+ // Thumb Intervals
+ vars.thumb_interval = Math.floor($(vars.thumb_tray).width() / $('> li', vars.thumb_list).outerWidth(true)) * $('> li', vars.thumb_list).outerWidth(true);
+ vars.thumb_page = 0;
+
+ // Cycle thumbs forward
+ $(vars.thumb_forward).click(function(){
+ if (vars.thumb_page - vars.thumb_interval <= -$(vars.thumb_list).width()){
+ vars.thumb_page = 0;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ }else{
+ vars.thumb_page = vars.thumb_page - vars.thumb_interval;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ }
+ });
+
+ // Cycle thumbs backwards
+ $(vars.thumb_back).click(function(){
+ if (vars.thumb_page + vars.thumb_interval > 0){
+ vars.thumb_page = Math.floor($(vars.thumb_list).width() / vars.thumb_interval) * -vars.thumb_interval;
+ if ($(vars.thumb_list).width() <= -vars.thumb_page) vars.thumb_page = vars.thumb_page + vars.thumb_interval;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ }else{
+ vars.thumb_page = vars.thumb_page + vars.thumb_interval;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ }
+ });
+
+ }
+
+
+ /* Navigation Items
+ ----------------------------*/
+ $(vars.next_slide).click(function() {
+ api.nextSlide();
+ });
+
+ $(vars.prev_slide).click(function() {
+ api.prevSlide();
+ });
+
+ // Full Opacity on Hover
+ if(jQuery.support.opacity){
+ $(vars.prev_slide +','+vars.next_slide).mouseover(function() {
+ $(this).stop().animate({opacity:1},100);
+ }).mouseout(function(){
+ $(this).stop().animate({opacity:0.6},100);
+ });
+ }
+
+ if (api.options.thumbnail_navigation){
+ // Next thumbnail clicked
+ $(vars.next_thumb).click(function() {
+ api.nextSlide();
+ });
+ // Previous thumbnail clicked
+ $(vars.prev_thumb).click(function() {
+ api.prevSlide();
+ });
+ }
+
+ $(vars.play_button).click(function() {
+ api.playToggle();
+ });
+
+
+ /* Thumbnail Mouse Scrub
+ ----------------------------*/
+ if (api.options.mouse_scrub){
+ $(vars.thumb_tray).mousemove(function(e) {
+ var containerWidth = $(vars.thumb_tray).width(),
+ listWidth = $(vars.thumb_list).width();
+ if (listWidth > containerWidth){
+ var mousePos = 1,
+ diff = e.pageX - mousePos;
+ if (diff > 10 || diff < -10) {
+ mousePos = e.pageX;
+ newX = (containerWidth - listWidth) * (e.pageX/containerWidth);
+ diff = parseInt(Math.abs(parseInt($(vars.thumb_list).css('left'))-newX )).toFixed(0);
+ $(vars.thumb_list).stop().animate({'left':newX}, {duration:diff*3, easing:'easeOutExpo'});
+ }
+ }
+ });
+ }
+
+
+ /* Window Resize
+ ----------------------------*/
+ $(window).resize(function(){
+
+ // Delay progress bar on resize
+ if (api.options.progress_bar && !vars.in_animation){
+ if (vars.slideshow_interval) clearInterval(vars.slideshow_interval);
+ if (api.options.slides.length - 1 > 0) clearInterval(vars.slideshow_interval);
+
+ $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 );
+
+ if (!vars.progressDelay && api.options.slideshow){
+ // Delay slideshow from resuming so Chrome can refocus images
+ vars.progressDelay = setTimeout(function() {
+ if (!vars.is_paused){
+ theme.progressBar();
+ vars.slideshow_interval = setInterval(api.nextSlide, api.options.slide_interval);
+ }
+ vars.progressDelay = false;
+ }, 1000);
+ }
+ }
+
+ // Thumb Links
+ if (api.options.thumb_links && vars.thumb_tray.length){
+ // Update Thumb Interval & Page
+ vars.thumb_page = 0;
+ vars.thumb_interval = Math.floor($(vars.thumb_tray).width() / $('> li', vars.thumb_list).outerWidth(true)) * $('> li', vars.thumb_list).outerWidth(true);
+
+ // Adjust thumbnail markers
+ if ($(vars.thumb_list).width() > $(vars.thumb_tray).width()){
+ $(vars.thumb_back +','+vars.thumb_forward).fadeIn('fast');
+ $(vars.thumb_list).stop().animate({'left':0}, 200);
+ }else{
+ $(vars.thumb_back +','+vars.thumb_forward).fadeOut('fast');
+ }
+
+ }
+ });
+
+
+ },
+
+
+ /* Go To Slide
+ ----------------------------*/
+ goTo : function(){
+ if (api.options.progress_bar && !vars.is_paused){
+ $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 );
+ theme.progressBar();
+ }
+ },
+
+ /* Play & Pause Toggle
+ ----------------------------*/
+ playToggle : function(state){
+
+ if (state =='play'){
+ // If image, swap to pause
+ if ($(vars.play_button).attr('src')) $(vars.play_button).attr("src", vars.image_path + "pause.png");
+ if (api.options.progress_bar && !vars.is_paused) theme.progressBar();
+ }else if (state == 'pause'){
+ // If image, swap to play
+ if ($(vars.play_button).attr('src')) $(vars.play_button).attr("src", vars.image_path + "play.png");
+ if (api.options.progress_bar && vars.is_paused)$(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 );
+ }
+
+ },
+
+
+ /* Before Slide Transition
+ ----------------------------*/
+ beforeAnimation : function(direction){
+ if (api.options.progress_bar && !vars.is_paused) $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 );
+
+ /* Update Fields
+ ----------------------------*/
+ // Update slide caption
+ if ($(vars.slide_caption).length){
+ (api.getField('title')) ? $(vars.slide_caption).html(api.getField('title')) : $(vars.slide_caption).html('');
+ }
+ // Update slide number
+ if (vars.slide_current.length){
+ $(vars.slide_current).html(vars.current_slide + 1);
+ }
+
+
+ // Highlight current thumbnail and adjust row position
+ if (api.options.thumb_links){
+
+ $('.current-thumb').removeClass('current-thumb');
+ $('li', vars.thumb_list).eq(vars.current_slide).addClass('current-thumb');
+
+ // If thumb out of view
+ if ($(vars.thumb_list).width() > $(vars.thumb_tray).width()){
+ // If next slide direction
+ if (direction == 'next'){
+ if (vars.current_slide == 0){
+ vars.thumb_page = 0;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ } else if ($('.current-thumb').offset().left - $(vars.thumb_tray).offset().left >= vars.thumb_interval){
+ vars.thumb_page = vars.thumb_page - vars.thumb_interval;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ }
+ // If previous slide direction
+ }else if(direction == 'prev'){
+ if (vars.current_slide == api.options.slides.length - 1){
+ vars.thumb_page = Math.floor($(vars.thumb_list).width() / vars.thumb_interval) * -vars.thumb_interval;
+ if ($(vars.thumb_list).width() <= -vars.thumb_page) vars.thumb_page = vars.thumb_page + vars.thumb_interval;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ } else if ($('.current-thumb').offset().left - $(vars.thumb_tray).offset().left < 0){
+ if (vars.thumb_page + vars.thumb_interval > 0) return false;
+ vars.thumb_page = vars.thumb_page + vars.thumb_interval;
+ $(vars.thumb_list).stop().animate({'left': vars.thumb_page}, {duration:500, easing:'easeOutExpo'});
+ }
+ }
+ }
+
+
+ }
+
+ },
+
+
+ /* After Slide Transition
+ ----------------------------*/
+ afterAnimation : function(){
+ if (api.options.progress_bar && !vars.is_paused) theme.progressBar(); // Start progress bar
+ },
+
+
+ /* Progress Bar
+ ----------------------------*/
+ progressBar : function(){
+ $(vars.progress_bar).stop().animate({left : -$(window).width()}, 0 ).animate({left:0}, api.options.slide_interval);
+ }
+
+
+ };
+
+
+ /* Theme Specific Variables
+ ----------------------------*/
+ $.supersized.themeVars = {
+
+ // Internal Variables
+ progress_delay : false, // Delay after resize before resuming slideshow
+ thumb_page : false, // Thumbnail page
+ thumb_interval : false, // Thumbnail interval
+ image_path : OC.webroot+"/apps/gallery/img/supersized/", // Default image path
+
+ // General Elements
+ play_button : '#pauseplay', // Play/Pause button
+ next_slide : '#nextslide', // Next slide button
+ prev_slide : '#prevslide', // Prev slide button
+ next_thumb : '#nextthumb', // Next slide thumb button
+ prev_thumb : '#prevthumb', // Prev slide thumb button
+
+ slide_caption : '#slidecaption', // Slide caption
+ slide_current : '.slidenumber', // Current slide number
+ slide_total : '.totalslides', // Total Slides
+ slide_list : '#slide-list', // Slide jump list
+
+ thumb_tray : '#thumb-tray', // Thumbnail tray
+ thumb_list : '#thumb-list', // Thumbnail list
+ thumb_forward : '#thumb-forward', // Cycles forward through thumbnail list
+ thumb_back : '#thumb-back', // Cycles backwards through thumbnail list
+ tray_arrow : '#tray-arrow', // Thumbnail tray button arrow
+ tray_button : '#tray-button', // Thumbnail tray button
+
+ progress_bar : '#progress-bar' // Progress bar
+
+ };
+
+ /* Theme Specific Options
+ ----------------------------*/
+ $.supersized.themeOptions = {
+
+ progress_bar : 1, // Timer for each slide
+ mouse_scrub : 0 // Thumbnails move with mouse
+
+ };
+
+
+})(jQuery);
diff --git a/apps/gallery/js/supersized.shutter.min.js b/apps/gallery/js/supersized.shutter.min.js
new file mode 100644
index 00000000000..52ea4a3384a
--- /dev/null
+++ b/apps/gallery/js/supersized.shutter.min.js
@@ -0,0 +1,14 @@
+/*
+
+ Supersized - Fullscreen Slideshow jQuery Plugin
+ Version : 3.2.7
+ Theme : Shutter 1.1
+
+ Site : www.buildinternet.com/project/supersized
+ Author : Sam Dunn
+ Company : One Mighty Roar (www.onemightyroar.com)
+ License : MIT License / GPL License
+
+*/
+
+(function(a){theme={_init:function(){if(api.options.slide_links){a(vars.slide_list).css("margin-left",-a(vars.slide_list).width()/2)}if(api.options.autoplay){if(api.options.progress_bar){theme.progressBar()}}else{if(a(vars.play_button).attr("src")){a(vars.play_button).attr("src",vars.image_path+"play.png")}if(api.options.progress_bar){a(vars.progress_bar).stop().animate({left:-a(window).width()},0)}}a(vars.thumb_tray).animate({bottom:-a(vars.thumb_tray).height()},0);a(vars.tray_button).toggle(function(){a(vars.thumb_tray).stop().animate({bottom:0,avoidTransforms:true},300);if(a(vars.tray_arrow).attr("src")){a(vars.tray_arrow).attr("src",vars.image_path+"button-tray-down.png")}return false},function(){a(vars.thumb_tray).stop().animate({bottom:-a(vars.thumb_tray).height(),avoidTransforms:true},300);if(a(vars.tray_arrow).attr("src")){a(vars.tray_arrow).attr("src",vars.image_path+"button-tray-up.png")}return false});a(vars.thumb_list).width(a("> li",vars.thumb_list).length*a("> li",vars.thumb_list).outerWidth(true));if(a(vars.slide_total).length){a(vars.slide_total).html(api.options.slides.length)}if(api.options.thumb_links){if(a(vars.thumb_list).width()<=a(vars.thumb_tray).width()){a(vars.thumb_back+","+vars.thumb_forward).fadeOut(0)}vars.thumb_interval=Math.floor(a(vars.thumb_tray).width()/a("> li",vars.thumb_list).outerWidth(true))*a("> li",vars.thumb_list).outerWidth(true);vars.thumb_page=0;a(vars.thumb_forward).click(function(){if(vars.thumb_page-vars.thumb_interval<=-a(vars.thumb_list).width()){vars.thumb_page=0;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{vars.thumb_page=vars.thumb_page-vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}});a(vars.thumb_back).click(function(){if(vars.thumb_page+vars.thumb_interval>0){vars.thumb_page=Math.floor(a(vars.thumb_list).width()/vars.thumb_interval)*-vars.thumb_interval;if(a(vars.thumb_list).width()<=-vars.thumb_page){vars.thumb_page=vars.thumb_page+vars.thumb_interval}a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{vars.thumb_page=vars.thumb_page+vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}})}a(vars.next_slide).click(function(){api.nextSlide()});a(vars.prev_slide).click(function(){api.prevSlide()});if(jQuery.support.opacity){a(vars.prev_slide+","+vars.next_slide).mouseover(function(){a(this).stop().animate({opacity:1},100)}).mouseout(function(){a(this).stop().animate({opacity:0.6},100)})}if(api.options.thumbnail_navigation){a(vars.next_thumb).click(function(){api.nextSlide()});a(vars.prev_thumb).click(function(){api.prevSlide()})}a(vars.play_button).click(function(){api.playToggle()});if(api.options.mouse_scrub){a(vars.thumb_tray).mousemove(function(f){var c=a(vars.thumb_tray).width(),g=a(vars.thumb_list).width();if(g>c){var b=1,d=f.pageX-b;if(d>10||d<-10){b=f.pageX;newX=(c-g)*(f.pageX/c);d=parseInt(Math.abs(parseInt(a(vars.thumb_list).css("left"))-newX)).toFixed(0);a(vars.thumb_list).stop().animate({left:newX},{duration:d*3,easing:"easeOutExpo"})}}})}a(window).resize(function(){if(api.options.progress_bar&&!vars.in_animation){if(vars.slideshow_interval){clearInterval(vars.slideshow_interval)}if(api.options.slides.length-1>0){clearInterval(vars.slideshow_interval)}a(vars.progress_bar).stop().animate({left:-a(window).width()},0);if(!vars.progressDelay&&api.options.slideshow){vars.progressDelay=setTimeout(function(){if(!vars.is_paused){theme.progressBar();vars.slideshow_interval=setInterval(api.nextSlide,api.options.slide_interval)}vars.progressDelay=false},1000)}}if(api.options.thumb_links&&vars.thumb_tray.length){vars.thumb_page=0;vars.thumb_interval=Math.floor(a(vars.thumb_tray).width()/a("> li",vars.thumb_list).outerWidth(true))*a("> li",vars.thumb_list).outerWidth(true);if(a(vars.thumb_list).width()>a(vars.thumb_tray).width()){a(vars.thumb_back+","+vars.thumb_forward).fadeIn("fast");a(vars.thumb_list).stop().animate({left:0},200)}else{a(vars.thumb_back+","+vars.thumb_forward).fadeOut("fast")}}})},goTo:function(b){if(api.options.progress_bar&&!vars.is_paused){a(vars.progress_bar).stop().animate({left:-a(window).width()},0);theme.progressBar()}},playToggle:function(b){if(b=="play"){if(a(vars.play_button).attr("src")){a(vars.play_button).attr("src",vars.image_path+"pause.png")}if(api.options.progress_bar&&!vars.is_paused){theme.progressBar()}}else{if(b=="pause"){if(a(vars.play_button).attr("src")){a(vars.play_button).attr("src",vars.image_path+"play.png")}if(api.options.progress_bar&&vars.is_paused){a(vars.progress_bar).stop().animate({left:-a(window).width()},0)}}}},beforeAnimation:function(b){if(api.options.progress_bar&&!vars.is_paused){a(vars.progress_bar).stop().animate({left:-a(window).width()},0)}if(a(vars.slide_caption).length){(api.getField("title"))?a(vars.slide_caption).html(api.getField("title")):a(vars.slide_caption).html("")}if(vars.slide_current.length){a(vars.slide_current).html(vars.current_slide+1)}if(api.options.thumb_links){a(".current-thumb").removeClass("current-thumb");a("li",vars.thumb_list).eq(vars.current_slide).addClass("current-thumb");if(a(vars.thumb_list).width()>a(vars.thumb_tray).width()){if(b=="next"){if(vars.current_slide==0){vars.thumb_page=0;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{if(a(".current-thumb").offset().left-a(vars.thumb_tray).offset().left>=vars.thumb_interval){vars.thumb_page=vars.thumb_page-vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}}}else{if(b=="prev"){if(vars.current_slide==api.options.slides.length-1){vars.thumb_page=Math.floor(a(vars.thumb_list).width()/vars.thumb_interval)*-vars.thumb_interval;if(a(vars.thumb_list).width()<=-vars.thumb_page){vars.thumb_page=vars.thumb_page+vars.thumb_interval}a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}else{if(a(".current-thumb").offset().left-a(vars.thumb_tray).offset().left<0){if(vars.thumb_page+vars.thumb_interval>0){return false}vars.thumb_page=vars.thumb_page+vars.thumb_interval;a(vars.thumb_list).stop().animate({left:vars.thumb_page},{duration:500,easing:"easeOutExpo"})}}}}}}},afterAnimation:function(){if(api.options.progress_bar&&!vars.is_paused){theme.progressBar()}},progressBar:function(){a(vars.progress_bar).stop().animate({left:-a(window).width()},0).animate({left:0},api.options.slide_interval)}};a.supersized.themeVars={progress_delay:false,thumb_page:false,thumb_interval:false,image_path:OC.webroot+"/apps/gallery/img/supersized/",play_button:"#pauseplay",next_slide:"#nextslide",prev_slide:"#prevslide",next_thumb:"#nextthumb",prev_thumb:"#prevthumb",slide_caption:"#slidecaption",slide_current:".slidenumber",slide_total:".totalslides",slide_list:"#slide-list",thumb_tray:"#thumb-tray",thumb_list:"#thumb-list",thumb_forward:"#thumb-forward",thumb_back:"#thumb-back",tray_arrow:"#tray-arrow",tray_button:"#tray-button",progress_bar:"#progress-bar"};a.supersized.themeOptions={progress_bar:1,mouse_scrub:0}})(jQuery);
diff --git a/apps/gallery/lib/album.php b/apps/gallery/lib/album.php
index 39d6d3aded1..701949d4d80 100644
--- a/apps/gallery/lib/album.php
+++ b/apps/gallery/lib/album.php
@@ -58,7 +58,7 @@ class OC_Gallery_Album {
return $stmt->execute($args);
}
- public static function removeByName($owner, $name) { self::remove($ownmer, $name); }
+ public static function removeByName($owner, $name) { self::remove($owner, $name); }
public static function removeByPath($owner, $path) { self::remove($owner, null, $path); }
public static function removeByParentPath($owner, $parent) { self::remove($owner, null, null, $parent); }
diff --git a/apps/gallery/lib/hooks_handlers.php b/apps/gallery/lib/hooks_handlers.php
index 093979834da..3bafdb5cf4d 100644
--- a/apps/gallery/lib/hooks_handlers.php
+++ b/apps/gallery/lib/hooks_handlers.php
@@ -38,5 +38,3 @@ class OC_Gallery_Hooks_Handlers {
//TODO: implement this
}
}
-
-?>
diff --git a/apps/gallery/lib/images_utils.php b/apps/gallery/lib/images_utils.php
index ac3a383c977..f5e37cf1dee 100644
--- a/apps/gallery/lib/images_utils.php
+++ b/apps/gallery/lib/images_utils.php
@@ -60,5 +60,3 @@ function CroppedThumbnail($imgSrc,$thumbnail_width,$thumbnail_height, $tgtImg, $
imagedestroy($process);
imagedestroy($myImage);
}
-
-?>
diff --git a/apps/gallery/lib/managers.php b/apps/gallery/lib/managers.php
index 17eb741a660..575d962dbe3 100644
--- a/apps/gallery/lib/managers.php
+++ b/apps/gallery/lib/managers.php
@@ -2,7 +2,7 @@
namespace OC\Pictures;
-class DatabaseManager {
+class DatabaseManager {
private static $instance = null;
protected $cache = array();
const TAG = 'DatabaseManager';
@@ -25,6 +25,15 @@ class DatabaseManager {
}
}
+ public function setFileData($path, $width, $height) {
+ $stmt = \OCP\DB::prepare('INSERT INTO *PREFIX*pictures_images_cache (uid_owner, path, width, height) VALUES (?, ?, ?, ?)');
+ $stmt->execute(array(\OCP\USER::getUser(), $path, $width, $height));
+ $ret = array('path' => $path, 'width' => $width, 'height' => $height);
+ $dir = dirname($path);
+ $this->cache[$dir][$path] = $ret;
+ return $ret;
+ }
+
public function getFileData($path) {
$gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery';
$path = $gallery_path.$path;
@@ -39,9 +48,7 @@ class DatabaseManager {
if (!$image->loadFromFile($path)) {
return false;
}
- $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()));
- $ret = array('path' => $path, 'width' => $image->width(), 'height' => $image->height());
+ $ret = $this->setFileData($path, $image->width(), $image->height());
unset($image);
$this->cache[$dir][$path] = $ret;
return $ret;
@@ -54,6 +61,7 @@ class ThumbnailsManager {
private static $instance = null;
const TAG = 'ThumbnailManager';
+ const THUMBNAIL_HEIGHT = 150;
public static function getInstance() {
if (self::$instance === null)
@@ -62,9 +70,9 @@ class ThumbnailsManager {
}
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);
+ $gallery_storage = \OCP\Files::getStorage('gallery');
+ if ($gallery_storage->file_exists($path)) {
+ return new \OC_Image($gallery_storage->getLocalFile($path));
}
if (!\OC_Filesystem::file_exists($path)) {
\OC_Log::write(self::TAG, 'File '.$path.' don\'t exists', \OC_Log::WARN);
@@ -73,27 +81,39 @@ class ThumbnailsManager {
$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);
+
+ $ret = $image->preciseResize( floor((self::THUMBNAIL_HEIGHT*$image->width())/$image->height()), self::THUMBNAIL_HEIGHT );
if (!$ret) {
\OC_Log::write(self::TAG, 'Couldn\'t resize image', \OC_Log::ERROR);
unset($image);
return false;
}
-
- $image->save($gallery_path.'/'.$path);
+ $l = $gallery_storage->getLocalFile($path);
+
+ $image->save($l);
return $image;
}
-
+
+ public function getThumbnailWidth($image) {
+ return floor((self::THUMBNAIL_HEIGHT*$image->widthTopLeft())/$image->heightTopLeft());
+ }
+
public function getThumbnailInfo($path) {
$arr = DatabaseManager::getInstance()->getFileData($path);
if (!$arr) {
- $thubnail = $this->getThumbnail($path);
- unset($thubnail);
- $arr = DatabaseManager::getInstance()->getFileData($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;
+ }
+ $arr = DatabaseManager::getInstance()->setFileData($path, $this->getThumbnailWidth($image), self::THUMBNAIL_HEIGHT);
}
$ret = array('filepath' => $arr['path'],
'width' => $arr['width'],
@@ -102,13 +122,12 @@ class ThumbnailsManager {
}
public function delete($path) {
- $thumbnail = \OCP\Config::getSystemValue('datadirectory').'/'.\OC_User::getUser()."/gallery".$path;
- if (file_exists($thumbnail)) {
- unlink($thumbnail);
+ $thumbnail_storage = \OCP\Files::getStorage('gallery');
+ if ($thumbnail_storage->file_exists($path)) {
+ $thumbnail_storage->unlink($path);
}
}
private function __construct() {}
}
-?>
diff --git a/apps/gallery/lib/photo.php b/apps/gallery/lib/photo.php
index f9527cb5fdb..3b4e74641b3 100644
--- a/apps/gallery/lib/photo.php
+++ b/apps/gallery/lib/photo.php
@@ -1,53 +1,55 @@
<?php
/**
-* ownCloud - gallery application
-*
-* @author Bartek Przybylski
-* @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
+ * ownCloud - gallery application
+ *
+ * @author Bartek Przybylski
+ * @copyright 2012 Bartek Przybylski bart.p.pl@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
class OC_Gallery_Photo {
- public static function create($albumId, $img){
+
+ public static function create($albumId, $img) {
$stmt = OCP\DB::prepare('INSERT INTO *PREFIX*gallery_photos (album_id, file_path) VALUES (?, ?)');
$stmt->execute(array($albumId, $img));
}
- public static function find($albumId, $img=null){
+
+ public static function find($albumId, $img = null) {
$sql = 'SELECT * FROM *PREFIX*gallery_photos WHERE album_id = ?';
$args = array($albumId);
- if (!is_null($img)){
+ if (!is_null($img)) {
$sql .= ' AND file_path = ?';
$args[] = $img;
}
$stmt = OCP\DB::prepare($sql);
return $stmt->execute($args);
}
- public static function findForAlbum($owner, $album_name){
+
+ public static function findForAlbum($owner, $album_name) {
$stmt = OCP\DB::prepare('SELECT *'
- .' FROM *PREFIX*gallery_photos photos,'
- .' *PREFIX*gallery_albums albums'
- .' WHERE albums.uid_owner = ?'
- .' AND albums.album_name = ?'
- .' AND photos.album_id = albums.album_id');
+ .' FROM *PREFIX*gallery_photos photos,'
+ .' *PREFIX*gallery_albums albums'
+ .' WHERE albums.uid_owner = ?'
+ .' AND albums.album_name = ?'
+ .' AND photos.album_id = albums.album_id');
return $stmt->execute(array($owner, $album_name));
}
- public static function removeByPath($path, $album_id) {
- $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path LIKE ? and album_id = ?');
+ public static function removeByPath($path, $album_id) {
+ $stmt = OCP\DB::prepare('DELETE FROM *PREFIX*gallery_photos WHERE file_path LIKE ? and album_id = ?');
$stmt->execute(array($path, $album_id));
}
@@ -67,19 +69,20 @@ class OC_Gallery_Photo {
}
public static function getThumbnail($image_name, $owner = null) {
- if (!$owner) $owner = OCP\USER::getUser();
+ if (!$owner)
+ $owner = OCP\USER::getUser();
$view = OCP\Files::getStorage('gallery');
$save_dir = dirname($image_name);
if (!$view->is_dir($save_dir)) {
$view->mkdir($save_dir);
}
- $view->chroot($view->getRoot().'/'.$save_dir);
+ $view->chroot($view->getRoot() . '/' . $save_dir);
$thumb_file = basename($image_name);
if ($view->file_exists($thumb_file)) {
$image = new OC_Image($view->fopen($thumb_file, 'r'));
} else {
$image_path = OC_Filesystem::getLocalFile($image_name);
- if(!file_exists($image_path)) {
+ if (!file_exists($image_path)) {
return null;
}
$image = new OC_Image($image_path);
@@ -91,7 +94,38 @@ class OC_Gallery_Photo {
}
if ($image->valid()) {
return $image;
- }else{
+ } else {
+ $image->destroy();
+ }
+ return null;
+ }
+
+ public static function getViewImage($image_name, $owner = null) {
+ if (!$owner) $owner = OCP\USER::getUser();
+ $save_dir = OCP\Config::getSystemValue("datadirectory") . '/' . $owner . '/gallery';
+ $save_dir .= dirname($image_name) . '/view/';
+ $image_path = $image_name;
+ $view_file = $save_dir . basename($image_name);
+ if (!is_dir($save_dir)) {
+ mkdir($save_dir, 0777, true);
+ }
+ if (file_exists($view_file)) {
+ $image = new OC_Image($view_file);
+ } else {
+ $image_path = OC_Filesystem::getLocalFile($image_path);
+ if (!file_exists($image_path)) {
+ return null;
+ }
+ $image = new OC_Image($image_path);
+ if ($image->valid()) {
+ $image->resize(1200);
+ $image->fixOrientation();
+ $image->save($view_file);
+ }
+ }
+ if ($image->valid()) {
+ return $image;
+ } else {
$image->destroy();
}
return null;
@@ -100,4 +134,5 @@ class OC_Gallery_Photo {
public static function getGalleryRoot() {
return OCP\Config::getUserValue(OCP\USER::getUser(), 'gallery', 'root', '');
}
+
}
diff --git a/apps/gallery/lib/tiles.php b/apps/gallery/lib/tiles.php
index 5efe0d7a299..e36d26d3191 100644
--- a/apps/gallery/lib/tiles.php
+++ b/apps/gallery/lib/tiles.php
@@ -33,7 +33,7 @@ class TilesLine {
}
public function setAvailableSpace($space) {
- $available_space = $space;
+ $this->available_space = $space;
}
public function getTilesCount() {
@@ -95,7 +95,7 @@ class TileSingle extends TileBase {
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 '<a rel="images" title="'.htmlentities(basename($this->getPath())).'" href="'.\OCP\Util::linkTo('files', 'download.php').'?file='.urlencode(urlencode($this->getPath())).'"><img rel="images" src="'.\OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath()).'" '.$extra.'></a>';
+ return '<a rel="images" title="'.htmlentities(basename($this->getPath())).'" href="'.\OCP\Util::linkTo('gallery','ajax/viewImage.php').'?img='.urlencode(urlencode($this->getPath())).'"><img rel="images" src="'.\OCP\Util::linkTo('gallery', 'ajax/thumbnail.php').'&filepath='.urlencode($this->getPath()).'" '.$extra.'></a>';
}
public function getMiniatureSrc() {
@@ -174,5 +174,3 @@ class TileStack extends TileBase {
private $tiles_array;
private $stack_name;
}
-
-?>
diff --git a/apps/gallery/lib/tiles_test.php b/apps/gallery/lib/tiles_test.php
index 022a88f75cc..02d567c628d 100644
--- a/apps/gallery/lib/tiles_test.php
+++ b/apps/gallery/lib/tiles_test.php
@@ -83,5 +83,3 @@ if ($ts->getCount() != 0) {
}
echo $tl->get();
-
-?>
diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php
index c90932cefd0..b2efd5342ff 100644
--- a/apps/gallery/templates/index.php
+++ b/apps/gallery/templates/index.php
@@ -22,7 +22,10 @@ $(document).ready(function() {
}
}
-?><br/>
+?>
+ <div id="slideshow">
+ <input type="button" class="start" value="<?php echo $l->t('Slideshow')?>" />
+ </div>
</div>
<div id="gallerycontent">
<?php
@@ -32,3 +35,50 @@ echo $_['tl']->get();
?>
</div>
+
+<!-- start supersized block -->
+<div id="slideshow-content" style="display:none;">
+
+ <!--Thumbnail Navigation-->
+ <div id="prevthumb"></div>
+ <div id="nextthumb"></div>
+
+ <!--Arrow Navigation-->
+ <a id="prevslide" class="load-item"></a>
+ <a id="nextslide" class="load-item"></a>
+
+ <div id="thumb-tray" class="load-item">
+ <div id="thumb-back"></div>
+ <div id="thumb-forward"></div>
+ </div>
+
+ <!--Time Bar-->
+ <div id="progress-back" class="load-item">
+ <div id="progress-bar"></div>
+ </div>
+
+ <!--Control Bar-->
+ <div id="slideshow-controls-wrapper" class="load-item">
+ <div id="slideshow-controls">
+
+ <a id="play-button"><img id="pauseplay" src="<?php echo OCP\image_path('gallery', 'supersized/pause.png'); ?>"/></a>
+
+ <!--Slide counter-->
+ <div id="slidecounter">
+ <span class="slidenumber"></span> / <span class="totalslides"></span>
+ </div>
+
+ <!--Slide captions displayed here-->
+ <div id="slidecaption"></div>
+
+ <!--Thumb Tray button-->
+ <a id="tray-button"><img id="tray-arrow" src="<?php echo OCP\image_path('gallery', 'supersized/button-tray-up.png'); ?>"/></a>
+
+ <!--Navigation-->
+ <!--
+ <ul id="slide-list"></ul>
+ -->
+ </div>
+ </div>
+
+</div><!-- end supersized block -->
diff --git a/apps/gallery/templates/view_album.php b/apps/gallery/templates/view_album.php
index c16ed69c065..00e891103f1 100644
--- a/apps/gallery/templates/view_album.php
+++ b/apps/gallery/templates/view_album.php
@@ -1,9 +1,9 @@
<?php
OCP\Util::addStyle('gallery', 'styles');
-OCP\Util::addscript('gallery', 'albums');
-OCP\Util::addscript('gallery', 'album_cover');
-OCP\Util::addscript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack');
-OCP\Util::addscript('files_imageviewer', 'jquery.fancybox-1.3.4.pack');
+OCP\Util::addScript('gallery', 'albums');
+OCP\Util::addScript('gallery', 'album_cover');
+OCP\Util::addScript('files_imageviewer', 'jquery.mousewheel-3.0.4.pack');
+OCP\Util::addScript('files_imageviewer', 'jquery.fancybox-1.3.4.pack');
OCP\Util::addStyle( 'files_imageviewer', 'jquery.fancybox-1.3.4' );
$l = OC_L10N::get('gallery');
?>
diff --git a/apps/media/ajax/api.php b/apps/media/ajax/api.php
index 23abc579272..7f5cdb22c12 100644
--- a/apps/media/ajax/api.php
+++ b/apps/media/ajax/api.php
@@ -131,4 +131,3 @@ if($arguments['action']){
exit;
}
}
-?>
diff --git a/apps/media/ajax/autoupdate.php b/apps/media/ajax/autoupdate.php
index 3122c7e6754..c2dbf27a004 100644
--- a/apps/media/ajax/autoupdate.php
+++ b/apps/media/ajax/autoupdate.php
@@ -35,4 +35,3 @@ $autoUpdate=(isset($_GET['autoupdate']) and $_GET['autoupdate']=='true');
OCP\Config::setUserValue(OCP\USER::getUser(),'media','autoupdate',(integer)$autoUpdate);
OCP\JSON::success(array('data' => $autoUpdate));
-?>
diff --git a/apps/media/appinfo/version b/apps/media/appinfo/version
index e6adf3fc7bb..44bb5d1f743 100644
--- a/apps/media/appinfo/version
+++ b/apps/media/appinfo/version
@@ -1 +1 @@
-0.4 \ No newline at end of file
+0.4.1 \ No newline at end of file
diff --git a/apps/media/index.php b/apps/media/index.php
index fb51aa0b17a..ae85abc8aab 100644
--- a/apps/media/index.php
+++ b/apps/media/index.php
@@ -40,5 +40,3 @@ OCP\App::setActiveNavigationEntry( 'media_index' );
$tmpl = new OCP\Template( 'media', 'music', 'user' );
$tmpl->printPage();
-?>
-
diff --git a/apps/media/lib_ampache.php b/apps/media/lib_ampache.php
index 255e6f468f8..d5a093338cc 100644
--- a/apps/media/lib_ampache.php
+++ b/apps/media/lib_ampache.php
@@ -271,7 +271,6 @@ class OC_MEDIA_AMPACHE{
</root>");
return;
}
- global $SITEROOT;
$filter=$params['filter'];
$albums=OC_MEDIA_COLLECTION::getAlbums($filter);
$artist=OC_MEDIA_COLLECTION::getArtistName($filter);
@@ -419,5 +418,3 @@ class OC_MEDIA_AMPACHE{
echo('</root>');
}
}
-
-?>
diff --git a/apps/media/lib_collection.php b/apps/media/lib_collection.php
index 598c08d32e2..cacab8e959f 100644
--- a/apps/media/lib_collection.php
+++ b/apps/media/lib_collection.php
@@ -27,7 +27,6 @@ class OC_MEDIA_COLLECTION{
public static $uid;
private static $artistIdCache=array();
private static $albumIdCache=array();
- private static $songIdCache=array();
private static $queries=array();
/**
@@ -152,7 +151,7 @@ class OC_MEDIA_COLLECTION{
return $artistId;
}else{
$query=OCP\DB::prepare("INSERT INTO `*PREFIX*media_artists` (`artist_name`) VALUES (?)");
- $result=$query->execute(array($name));
+ $query->execute(array($name));
return self::getArtistId($name);;
}
}
@@ -387,5 +386,3 @@ class OC_MEDIA_COLLECTION{
$query->execute(array($newPath,$oldPath));
}
}
-
-?>
diff --git a/apps/media/lib_media.php b/apps/media/lib_media.php
index 9e687a4af2c..54502f42575 100644
--- a/apps/media/lib_media.php
+++ b/apps/media/lib_media.php
@@ -27,12 +27,12 @@ class OC_MEDIA{
* @param array $params, parameters passed from OC_Hook
*/
public static function loginListener($params){
- if(isset($_POST['user']) and $_POST['password']){
- $name=$_POST['user'];
+ if(isset($params['uid']) and $params['password']){
+ $name=$params['uid'];
$query=OCP\DB::prepare("SELECT user_id from *PREFIX*media_users WHERE user_id LIKE ?");
$uid=$query->execute(array($name))->fetchAll();
if(count($uid)==0){
- $password=hash('sha256',$_POST['password']);
+ $password=hash('sha256',$params['password']);
$query=OCP\DB::prepare("INSERT INTO *PREFIX*media_users (user_id, user_password_sha256) VALUES (?, ?);");
$query->execute(array($name,$password));
}
diff --git a/apps/media/settings.php b/apps/media/settings.php
index 227298fafec..53738f02f9f 100644
--- a/apps/media/settings.php
+++ b/apps/media/settings.php
@@ -3,4 +3,3 @@
$tmpl = new OCP\Template( 'media', 'settings');
return $tmpl->fetchPage();
-?>
diff --git a/apps/remoteStorage/appinfo/info.xml b/apps/remoteStorage/appinfo/info.xml
index fa878762a05..1388ad9c316 100644
--- a/apps/remoteStorage/appinfo/info.xml
+++ b/apps/remoteStorage/appinfo/info.xml
@@ -7,4 +7,7 @@
<author>Michiel de Jong</author>
<require>4</require>
<shipped>true</shipped>
+ <remote>
+ <remoteStorage>webdav.php</remoteStorage>
+ </remote>
</info>
diff --git a/apps/remoteStorage/appinfo/version b/apps/remoteStorage/appinfo/version
index 490f510fc27..0e2c93950bb 100644
--- a/apps/remoteStorage/appinfo/version
+++ b/apps/remoteStorage/appinfo/version
@@ -1 +1 @@
-0.6 \ No newline at end of file
+0.7 \ No newline at end of file
diff --git a/apps/remoteStorage/appinfo/webfinger.php b/apps/remoteStorage/appinfo/webfinger.php
index 5d481f315f8..e8b237628c4 100644
--- a/apps/remoteStorage/appinfo/webfinger.php
+++ b/apps/remoteStorage/appinfo/webfinger.php
@@ -1,8 +1,8 @@
-<?php if(OC_User::userExists(WF_USER)) { ?>
+<?php if(OC_User::userExists(WF_USER)): ?>
{
"rel":"remoteStorage",
- "template":"<?php echo WF_BASEURL; ?>/apps/remoteStorage/WebDAV.php/<?php echo WF_USER; ?>/remoteStorage/{category}/",
+ "template":"<?php echo WF_BASEURL; ?>/remote.php/remoteStorage/<?php echo WF_USER; ?>/remoteStorage/{category}/",
"api":"WebDAV",
"auth":"<?php echo WF_BASEURL; ?>/?app=remoteStorage&getfile=auth.php&userid=<?php echo WF_USER; ?>"
}
-<?php } ?>
+<?php endif ?>
diff --git a/apps/remoteStorage/lib_remoteStorage.php b/apps/remoteStorage/lib_remoteStorage.php
index 42cd9c90f64..c1765640c5d 100644
--- a/apps/remoteStorage/lib_remoteStorage.php
+++ b/apps/remoteStorage/lib_remoteStorage.php
@@ -17,12 +17,11 @@ class OC_remoteStorage {
$user=OCP\USER::getUser();
$query=OCP\DB::prepare("SELECT token FROM *PREFIX*authtoken WHERE user=? AND appUrl=? AND category=? LIMIT 1");
$result=$query->execute(array($user, $appUrl, $categories));
- $ret = array();
if($row=$result->fetchRow()) {
- return base64_encode('remoteStorage:'.$row['token']);
- } else {
- return false;
- }
+ return base64_encode('remoteStorage:'.$row['token']);
+ } else {
+ return false;
+ }
}
public static function getAllTokens() {
@@ -42,13 +41,13 @@ class OC_remoteStorage {
public static function deleteToken($token) {
$user=OCP\USER::getUser();
$query=OCP\DB::prepare("DELETE FROM *PREFIX*authtoken WHERE token=? AND user=?");
- $result=$query->execute(array($token,$user));
+ $query->execute(array($token,$user));
return 'unknown';//how can we see if any rows were affected?
}
private static function addToken($token, $appUrl, $categories){
$user=OCP\USER::getUser();
$query=OCP\DB::prepare("INSERT INTO *PREFIX*authtoken (`token`,`appUrl`,`user`,`category`) VALUES(?,?,?,?)");
- $result=$query->execute(array($token,$appUrl,$user,$categories));
+ $query->execute(array($token,$appUrl,$user,$categories));
}
public static function createCategories($appUrl, $categories) {
$token=uniqid();
diff --git a/apps/remoteStorage/oauth_ro_auth.php b/apps/remoteStorage/oauth_ro_auth.php
index 12d02d1cf5d..bed3093c3b3 100644
--- a/apps/remoteStorage/oauth_ro_auth.php
+++ b/apps/remoteStorage/oauth_ro_auth.php
@@ -9,10 +9,10 @@
class OC_Connector_Sabre_Auth_ro_oauth extends Sabre_DAV_Auth_Backend_AbstractBasic {
private $validTokens;
- private $category;
+ private $category;
public function __construct($validTokensArg, $categoryArg) {
$this->validTokens = $validTokensArg;
- $this->category = $categoryArg;
+ $this->category = $categoryArg;
}
/**
@@ -25,16 +25,16 @@ class OC_Connector_Sabre_Auth_ro_oauth extends Sabre_DAV_Auth_Backend_AbstractBa
*/
protected function validateUserPass($username, $password){
//always give read-only:
- if(($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
+ if(($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
|| (isset($this->validTokens[$password]))
- || (($_SERVER['REQUEST_METHOD'] == 'GET') && ($this->category == 'public'))
- ) {
+ || (($_SERVER['REQUEST_METHOD'] == 'GET') && ($this->category == 'public'))
+ ) {
OC_Util::setUpFS();
return true;
} else {
- //var_export($_SERVER);
- //var_export($this->validTokens);
- //die('not getting in with "'.$username.'"/"'.$password.'"!');
+ //var_export($_SERVER);
+ //var_export($this->validTokens);
+ //die('not getting in with "'.$username.'"/"'.$password.'"!');
return false;
}
}
@@ -48,8 +48,8 @@ class OC_Connector_Sabre_Auth_ro_oauth extends Sabre_DAV_Auth_Backend_AbstractBa
$userpass = $auth->getUserPass();
if (!$userpass) {
if(($_SERVER['REQUEST_METHOD'] == 'OPTIONS')
- ||(($_SERVER['REQUEST_METHOD'] == 'GET') && ($this->category == 'public'))
- ) {
+ ||(($_SERVER['REQUEST_METHOD'] == 'GET') && ($this->category == 'public'))
+ ) {
$userpass = array('', '');
} else {
$auth->requireLogin();
diff --git a/apps/remoteStorage/settings.php b/apps/remoteStorage/settings.php
index 9c48549fe6d..3be8b0984d8 100644
--- a/apps/remoteStorage/settings.php
+++ b/apps/remoteStorage/settings.php
@@ -4,4 +4,3 @@ require_once('lib_remoteStorage.php');
$tmpl = new OCP\Template( 'remoteStorage', 'settings');
return $tmpl->fetchPage();
-?>
diff --git a/apps/remoteStorage/WebDAV.php b/apps/remoteStorage/webdav.php
index 7a81c18e0af..8d8ec6a45a1 100644
--- a/apps/remoteStorage/WebDAV.php
+++ b/apps/remoteStorage/webdav.php
@@ -25,22 +25,7 @@
*
*/
-
-// Do not load FS ...
-$RUNTIME_NOSETUPFS = true;
-
-
-require_once('../../lib/base.php');
-
-require_once('../../lib/user.php');
-require_once('../../lib/public/user.php');
-
-require_once('../../lib/app.php');
-require_once('../../lib/public/app.php');
-
-require_once('../../3rdparty/Sabre/DAV/Auth/IBackend.php');
-require_once('../../3rdparty/Sabre/DAV/Auth/Backend/AbstractBasic.php');
-require_once('../../lib/connector/sabre/auth.php');
+OC_App::loadApps(array('filesystem','authentication'));
OCP\App::checkAppEnabled('remoteStorage');
require_once('lib_remoteStorage.php');
@@ -61,14 +46,15 @@ if(isset($_SERVER['HTTP_ORIGIN'])) {
header('Access-Control-Allow-Origin: *');
}
-$path = substr($_SERVER["REQUEST_URI"], strlen($_SERVER["SCRIPT_NAME"]));
+$path = substr($_SERVER["REQUEST_URI"], strlen($baseuri));
+
$pathParts = explode('/', $path);
// for webdav:
-// 0/ 1 / 2 / 3...
-// /$ownCloudUser/remoteStorage/$category/
+// 0 / 1 / 2...
+// $ownCloudUser/remoteStorage/$category/
-if(count($pathParts) >= 3 && $pathParts[0] == '') {
- list($dummy, $ownCloudUser, $dummy2, $category) = $pathParts;
+if(count($pathParts) >= 2) {
+ list($ownCloudUser, $dummy2, $category) = $pathParts;
OC_Util::setupFS($ownCloudUser);
@@ -77,13 +63,13 @@ if(count($pathParts) >= 3 && $pathParts[0] == '') {
$server = new Sabre_DAV_Server($publicDir);
// Path to our script
- $server->setBaseUri(OC::$WEBROOT."/apps/remoteStorage/WebDAV.php/$ownCloudUser");
+ $server->setBaseUri($baseuri.$ownCloudUser);
// Auth backend
$authBackend = new OC_Connector_Sabre_Auth_ro_oauth(
- OC_remoteStorage::getValidTokens($ownCloudUser, $category),
- $category
- );
+ OC_remoteStorage::getValidTokens($ownCloudUser, $category),
+ $category
+ );
$authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'ownCloud');//should use $validTokens here
$server->addPlugin($authPlugin);
diff --git a/apps/tasks/ajax/addtask.php b/apps/tasks/ajax/addtask.php
index 9f35e7f21ec..d98fdbf3888 100644
--- a/apps/tasks/ajax/addtask.php
+++ b/apps/tasks/ajax/addtask.php
@@ -3,6 +3,7 @@
// Init owncloud
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('tasks');
+OCP\JSON::callCheck();
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true);
$first_calendar = reset($calendars);
@@ -21,7 +22,7 @@ $request['description'] = null;
$vcalendar = OC_Task_App::createVCalendarFromRequest($request);
$id = OC_Calendar_Object::add($cid, $vcalendar->serialize());
-$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+$user_timezone = OC_Calendar_App::getTimezone();
$task = OC_Task_App::arrayForJSON($id, $vcalendar->VTODO, $user_timezone);
OCP\JSON::success(array('task' => $task));
diff --git a/apps/tasks/ajax/addtaskform.php b/apps/tasks/ajax/addtaskform.php
deleted file mode 100644
index d86232e2da5..00000000000
--- a/apps/tasks/ajax/addtaskform.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-
-// Init owncloud
-OCP\JSON::checkLoggedIn();
-OCP\JSON::checkAppEnabled('tasks');
-
-$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true);
-$category_options = OC_Calendar_App::getCategoryOptions();
-$percent_options = range(0, 100, 10);
-$priority_options = OC_Task_App::getPriorityOptions();
-$tmpl = new OCP\Template('tasks','part.addtaskform');
-$tmpl->assign('calendars',$calendars);
-$tmpl->assign('category_options', $category_options);
-$tmpl->assign('percent_options', $percent_options);
-$tmpl->assign('priority_options', $priority_options);
-$tmpl->assign('details', new OC_VObject('VTODO'));
-$tmpl->assign('categories', '');
-$page = $tmpl->fetchPage();
-
-OCP\JSON::success(array('data' => array( 'page' => $page )));
diff --git a/apps/tasks/ajax/delete.php b/apps/tasks/ajax/delete.php
index e29add9b556..cc22c3e3873 100644
--- a/apps/tasks/ajax/delete.php
+++ b/apps/tasks/ajax/delete.php
@@ -23,6 +23,7 @@
// Init owncloud
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('tasks');
+OCP\JSON::callCheck();
$id = $_POST['id'];
$task = OC_Calendar_App::getEventObject( $id );
diff --git a/apps/tasks/ajax/edittask.php b/apps/tasks/ajax/edittask.php
deleted file mode 100644
index edcc8a7cdcd..00000000000
--- a/apps/tasks/ajax/edittask.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-// Init owncloud
-OCP\JSON::checkLoggedIn();
-OCP\JSON::checkAppEnabled('tasks');
-
-$l10n = new OC_L10N('tasks');
-
-$id = $_POST['id'];
-$vcalendar = OC_Calendar_App::getVCalendar($id);
-
-$errors = OC_Task_App::validateRequest($_POST);
-if (!empty($errors)) {
- OCP\JSON::error(array('data' => array( 'errors' => $errors )));
- exit();
-}
-
-OC_Task_App::updateVCalendarFromRequest($_POST, $vcalendar);
-OC_Calendar_Object::edit($id, $vcalendar->serialize());
-
-$priority_options = OC_Task_App::getPriorityOptions();
-$tmpl = new OCP\Template('tasks','part.details');
-$tmpl->assign('priority_options', $priority_options);
-$tmpl->assign('details', $vcalendar->VTODO);
-$tmpl->assign('id', $id);
-$page = $tmpl->fetchPage();
-
-$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
-$task = OC_Task_App::arrayForJSON($id, $vcalendar->VTODO, $user_timezone);
-
-OCP\JSON::success(array('data' => array( 'id' => $id, 'page' => $page, 'task' => $task )));
diff --git a/apps/tasks/ajax/edittaskform.php b/apps/tasks/ajax/edittaskform.php
deleted file mode 100644
index e5a0a7297c5..00000000000
--- a/apps/tasks/ajax/edittaskform.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-// Init owncloud
-OCP\JSON::checkLoggedIn();
-OCP\JSON::checkAppEnabled('tasks');
-
-$id = $_GET['id'];
-$details = OC_Calendar_App::getVCalendar($id)->VTODO;
-$categories = $details->getAsString('CATEGORIES');
-
-$category_options = OC_Calendar_App::getCategoryOptions();
-$percent_options = range(0, 100, 10);
-$priority_options = OC_Task_App::getPriorityOptions();
-
-$tmpl = new OCP\Template('tasks','part.edittaskform');
-$tmpl->assign('category_options', $category_options);
-$tmpl->assign('percent_options', $percent_options);
-$tmpl->assign('priority_options', $priority_options);
-$tmpl->assign('id',$id);
-$tmpl->assign('details',$details);
-$tmpl->assign('categories', $categories);
-$page = $tmpl->fetchPage();
-
-OCP\JSON::success(array('data' => array( 'page' => $page )));
diff --git a/apps/tasks/ajax/getdetails.php b/apps/tasks/ajax/getdetails.php
deleted file mode 100644
index 4ce469e0c9c..00000000000
--- a/apps/tasks/ajax/getdetails.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-
-// Init owncloud
-OCP\JSON::checkLoggedIn();
-OCP\JSON::checkAppEnabled('tasks');
-
-$l10n = new OC_L10N('tasks');
-
-$id = $_GET['id'];
-$task = OC_Calendar_Object::find($id);
-$details = OC_VObject::parse($task['calendardata']);
-if (!$details){
- OCP\JSON::error();
- exit;
-}
-
-$priority_options = OC_Task_App::getPriorityOptions();
-$tmpl = new OCP\Template('tasks','part.details');
-$tmpl->assign('priority_options', $priority_options);
-$tmpl->assign('details',$details->VTODO);
-$tmpl->assign('id',$id);
-$page = $tmpl->fetchPage();
-
-OCP\JSON::success(array('data' => array( 'id' => $id, 'page' => $page )));
diff --git a/apps/tasks/ajax/gettasks.php b/apps/tasks/ajax/gettasks.php
index 011730d0a13..b6183d9cb65 100644
--- a/apps/tasks/ajax/gettasks.php
+++ b/apps/tasks/ajax/gettasks.php
@@ -11,7 +11,7 @@ OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('tasks');
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true);
-$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+$user_timezone = OC_Calendar_App::getTimezone();
$tasks = array();
foreach( $calendars as $calendar ){
diff --git a/apps/tasks/ajax/update_property.php b/apps/tasks/ajax/update_property.php
index 46521cf6c58..679cfdefe48 100644
--- a/apps/tasks/ajax/update_property.php
+++ b/apps/tasks/ajax/update_property.php
@@ -9,6 +9,7 @@
// Init owncloud
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('tasks');
+OCP\JSON::callCheck();
$id = $_POST['id'];
$property = $_POST['type'];
@@ -38,7 +39,7 @@ switch($property) {
$type = null;
if ($due != 'false') {
try {
- $timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+ $timezone = OC_Calendar_App::getTimezone();
$timezone = new DateTimeZone($timezone);
$due = new DateTime('@'.$due);
$due->setTimezone($timezone);
@@ -63,6 +64,6 @@ switch($property) {
}
OC_Calendar_Object::edit($id, $vcalendar->serialize());
-$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+$user_timezone = OC_Calendar_App::getTimezone();
$task_info = OC_Task_App::arrayForJSON($id, $vtodo, $user_timezone);
OCP\JSON::success(array('data' => $task_info));
diff --git a/apps/tasks/index.php b/apps/tasks/index.php
index 4ff304a5607..f1c4d1e765c 100644
--- a/apps/tasks/index.php
+++ b/apps/tasks/index.php
@@ -21,8 +21,8 @@ OCP\Util::addScript('3rdparty/timepicker', 'jquery.ui.timepicker');
OCP\Util::addStyle('3rdparty/timepicker', 'jquery.ui.timepicker');
OCP\Util::addScript('tasks', 'tasks');
OCP\Util::addStyle('tasks', 'style');
-OCP\Util::addScript('contacts','jquery.multi-autocomplete');
-OCP\Util::addScript('','oc-vcategories');
+OCP\Util::addScript('contacts', 'jquery.multi-autocomplete');
+OCP\Util::addScript('', 'oc-vcategories');
OCP\App::setActiveNavigationEntry('tasks_index');
$categories = OC_Calendar_App::getCategoryOptions();
diff --git a/apps/tasks/js/tasks.js b/apps/tasks/js/tasks.js
index bc92965bb0b..de627927507 100644
--- a/apps/tasks/js/tasks.js
+++ b/apps/tasks/js/tasks.js
@@ -469,67 +469,5 @@ $(document).ready(function(){
return false;
});
- $('#tasks_addtaskform input[type="submit"]').live('click',function(){
- $.post('ajax/addtask.php',$('#tasks_addtaskform').serialize(),function(jsondata){
- if(jsondata.status == 'success'){
- $('#task_details').data('id',jsondata.data.id);
- $('#task_details').html(jsondata.data.page);
- $('#tasks_list').append(OC.Tasks.create_task_div(jsondata.data.task));
- }
- else{
- alert(jsondata.data.message);
- }
- }, 'json');
- return false;
- });
-
- $('#tasks_edit').live('click',function(){
- var id = $('#task_details').data('id');
- $.getJSON('ajax/edittaskform.php',{'id':id},function(jsondata){
- if(jsondata.status == 'success'){
- $('#task_details').html(jsondata.data.page);
- $('#task_details #categories').multiple_autocomplete({source: categories});
- }
- else{
- alert(jsondata.data.message);
- }
- });
- return false;
- });
-
- $('#tasks_edittaskform #percent_complete').live('change',function(event){
- if ($(event.target).val() == 100){
- $('#tasks_edittaskform #complete').show();
- }else{
- $('#tasks_edittaskform #complete').hide();
- }
- });
-
- $('#tasks_edittaskform input[type="submit"]').live('click',function(){
- $.post('ajax/edittask.php',$('#tasks_edittaskform').serialize(),function(jsondata){
- $('.error_msg').remove();
- $('.error').removeClass('error');
- if(jsondata.status == 'success'){
- var id = jsondata.data.id;
- $('#task_details').data('id',id);
- $('#task_details').html(jsondata.data.page);
- var task = jsondata.data.task;
- $('#tasks .task[data-id='+id+']')
- .data('task', task)
- .html(OC.Tasks.create_task_div(task).html());
- }
- else{
- var errors = jsondata.data.errors;
- for (k in errors){
- $('#'+k).addClass('error')
- .after('<span class="error_msg">'+errors[k]+'</span>');
- }
- $('.error_msg').effect('highlight', {}, 3000);
- $('.error').effect('highlight', {}, 3000);
- }
- }, 'json');
- return false;
- });
-
OCCategories.app = 'calendar';
});
diff --git a/apps/tasks/lib/app.php b/apps/tasks/lib/app.php
index 1b42968f0be..a97c6b95d1d 100644
--- a/apps/tasks/lib/app.php
+++ b/apps/tasks/lib/app.php
@@ -77,24 +77,24 @@ class OC_Task_App {
public static function validateRequest($request)
{
$errors = array();
- if($request['summary'] == ''){
+ if($request['summary'] == '') {
$errors['summary'] = self::$l10n->t('Empty Summary');
}
try {
- $timezone = OCP\Config::getUserValue(OCP\User::getUser(), "calendar", "timezone", "Europe/London");
+ $timezone = OC_Calendar_App::getTimezone();
$timezone = new DateTimeZone($timezone);
new DateTime($request['due'], $timezone);
} catch (Exception $e) {
$errors['due'] = self::$l10n->t('Invalid date/time');
}
- if ($request['percent_complete'] < 0 || $request['percent_complete'] > 100){
+ if ($request['percent_complete'] < 0 || $request['percent_complete'] > 100) {
$errors['percent_complete'] = self::$l10n->t('Invalid percent complete');
}
- if ($request['percent_complete'] == 100 && !empty($request['completed'])){
+ if ($request['percent_complete'] == 100 && !empty($request['completed'])) {
try {
- $timezone = OCP\Config::getUserValue(OCP\User::getUser(), "calendar", "timezone", "Europe/London");
+ $timezone = OC_Calendar_App::getTimezone();
$timezone = new DateTimeZone($timezone);
new DateTime($request['completed'], $timezone);
} catch (Exception $e) {
@@ -147,7 +147,7 @@ class OC_Task_App {
$vtodo->setString('PRIORITY', $priority);
if ($due) {
- $timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+ $timezone = OC_Calendar_App::getTimezone();
$timezone = new DateTimeZone($timezone);
$due = new DateTime($due, $timezone);
$vtodo->setDateTime('DUE', $due);
@@ -168,15 +168,15 @@ class OC_Task_App {
$vtodo->__unset('PERCENT-COMPLETE');
}
- if ($percent_complete == 100){
- if (!$completed){
+ if ($percent_complete == 100) {
+ if (!$completed) {
$completed = 'now';
}
} else {
$completed = null;
}
if ($completed) {
- $timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get());
+ $timezone = OC_Calendar_App::getTimezone();
$timezone = new DateTimeZone($timezone);
$completed = new DateTime($completed, $timezone);
$vtodo->setDateTime('COMPLETED', $completed);
diff --git a/apps/tasks/templates/part.addtaskform.php b/apps/tasks/templates/part.addtaskform.php
deleted file mode 100644
index 0fad5592aa7..00000000000
--- a/apps/tasks/templates/part.addtaskform.php
+++ /dev/null
@@ -1,15 +0,0 @@
-<form id="tasks_addtaskform">
- <?php if(count($_['calendars'])==1): ?>
- <input type="hidden" name="id" value="<?php echo $_['calendars'][0]['id']; ?>">
- <?php else: ?>
- <label for="id"><?php echo $l->t('Calendar'); ?></label>
- <select name="id" size="1">
- <?php foreach($_['calendars'] as $calendar): ?>
- <option value="<?php echo $calendar['id']; ?>"><?php echo $calendar['displayname']; ?></option>
- <?php endforeach; ?>
- </select>
- <br>
- <?php endif; ?>
- <?php echo $this->inc('part.taskform'); ?>
- <input type="submit" name="submit" value="<?php echo $l->t('Create Task'); ?>">
-</form>
diff --git a/apps/tasks/templates/part.details.php b/apps/tasks/templates/part.details.php
deleted file mode 100644
index 89636b6e762..00000000000
--- a/apps/tasks/templates/part.details.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php if(isset($_['details']->SUMMARY)): ?>
-<table>
-<?php
-echo $this->inc('part.property', array('label' => $l->t('Summary'), 'property' => $_['details']->SUMMARY));
-if(isset($_['details']->LOCATION)):
- echo $this->inc('part.property', array('label' => $l->t('Location'), 'property' => $_['details']->LOCATION));
-endif;
-if(isset($_['details']->CATEGORIES)):
- echo $this->inc('part.property', array('label' => $l->t('Categories'), 'property' => $_['details']->CATEGORIES));
-endif;
-if(isset($_['details']->DUE)):
- echo $this->inc('part.property', array('label' => $l->t('Due'), 'property' => $_['details']->DUE[0]));
-endif;
-if(isset($_['details']->PRIORITY)):
- echo $this->inc('part.property', array('label' => $l->t('Priority'), 'property' => $_['details']->PRIORITY[0], 'options' => $_['priority_options']));
-endif;
-if($_['details']->__isset('PERCENT-COMPLETE') || isset($_['details']->COMPLETED)):
-?>
-<tr>
- <th>
- <?php echo $l->t('Complete') ?>
- </th>
- <td>
-<?php if($_['details']->__isset('PERCENT-COMPLETE')):
- echo $_['details']->__get('PERCENT-COMPLETE')->value.' % ';
- endif;
- if(isset($_['details']->COMPLETED)):
- echo $l->t('on '). $l->l('datetime', $_['details']->COMPLETED[0]->getDateTime());
- endif;
- echo '</tr>';
-endif;
-if(isset($_['details']->DESCRIPTION)):
- echo $this->inc('part.property', array('label' => $l->t('Description'), 'property' => $_['details']->DESCRIPTION));
-endif; ?>
-</table>
-<form>
- <input type="button" id="tasks_delete" value="<?php echo $l->t('Delete');?>">
- <input type="button" id="tasks_edit" value="<?php echo $l->t('Edit');?>">
-</form>
-<?php else: ?>
-<?php //var_dump($_['details']); ?>
-<?php endif ?>
diff --git a/apps/tasks/templates/part.edittaskform.php b/apps/tasks/templates/part.edittaskform.php
deleted file mode 100644
index fe123f07ac6..00000000000
--- a/apps/tasks/templates/part.edittaskform.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<form id="tasks_edittaskform">
- <input type="hidden" name="id" value="<?php echo $_['id']; ?>">
- <?php echo $this->inc('part.taskform'); ?>
- <input type="submit" name="submit" value="<?php echo $l->t('Update Task'); ?>">
-</form>
diff --git a/apps/tasks/templates/part.property.php b/apps/tasks/templates/part.property.php
deleted file mode 100644
index 591fd363e6f..00000000000
--- a/apps/tasks/templates/part.property.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<tr>
- <th>
- <?php echo $_['label'] ?>
- </th>
- <td>
- <?php
- switch (get_class($_['property']))
- {
- case 'Sabre_VObject_Element_DateTime':
- echo $l->l('datetime', $_['property']->getDateTime());
- break;
- default:
- $value = $_['property']->value;
- if (isset($_['options']))
- {
- $value = $_['options'][$value];
- }
- echo nl2br($value);
- }
- ?>
- </td>
-</tr>
diff --git a/apps/tasks/templates/part.taskform.php b/apps/tasks/templates/part.taskform.php
deleted file mode 100644
index 0a25ed33c91..00000000000
--- a/apps/tasks/templates/part.taskform.php
+++ /dev/null
@@ -1,36 +0,0 @@
- <label for="summary"><?php echo $l->t('Summary'); ?></label>
- <input type="text" id="summary" name="summary" placeholder="<?php echo $l->t('Summary of the task');?>" value="<?php echo isset($_['details']->SUMMARY) ? $_['details']->SUMMARY[0]->value : '' ?>">
- <br>
- <label for="location"><?php echo $l->t('Location'); ?></label>
- <input type="text" id="location" name="location" placeholder="<?php echo $l->t('Location of the task');?>" value="<?php echo isset($_['details']->LOCATION) ? $_['details']->LOCATION[0]->value : '' ?>">
- <br>
- <label for="categories"><?php echo $l->t('Categories'); ?></label>
- <input id="categories" name="categories" type="text" placeholder="<?php echo $l->t('Separate categories with commas'); ?>" value="<?php echo isset($_['categories']) ? $_['categories'] : '' ?>">
- <a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"><img alt="<?php echo $l->t('Edit categories'); ?>" src="<?php echo OCP\image_path('core','actions/rename.svg')?>" class="svg action" style="width: 16px; height: 16px;"></a>
- <br>
- <label for="due"><?php echo $l->t('Due'); ?></label>
- <input type="text" id="due" name="due" placeholder="<?php echo $l->t('Due date') ?>" value="<?php echo isset($_['details']->DUE) ? $l->l('datetime', $_['details']->DUE[0]->getDateTime()) : '' ?>">
- <br>
- <select name="percent_complete" id="percent_complete">
- <?php
- foreach($_['percent_options'] as $percent){
- echo '<option value="' . $percent . '"' . (($_['details']->__get('PERCENT-COMPLETE') && $percent == $_['details']->__get('PERCENT-COMPLETE')->value) ? ' selected="selected"' : '') . '>' . $percent . ' %</option>';
- }
- ?>
- </select>
- <label for="percent_complete"><?php echo $l->t('Complete'); ?></label>
- <span id="complete"<?php echo ($_['details']->__get('PERCENT-COMPLETE') && $_['details']->__get('PERCENT-COMPLETE')->value == 100) ? '' : ' style="display:none;"' ?>><label for="completed"><?php echo $l->t('completed on'); ?></label>
- <input type="text" id="completed" name="completed" value="<?php echo isset($_['details']->COMPLETED) ? $l->l('datetime', $_['details']->COMPLETED[0]->getDateTime()) : '' ?>"></span>
- <br>
- <label for="priority"><?php echo $l->t('Priority'); ?></label>
- <select name="priority">
- <?php
- foreach($_['priority_options'] as $priority => $label){
- echo '<option value="' . $priority . '"' . ((isset($_['details']->PRIORITY) && $priority == $_['details']->PRIORITY->value) ? ' selected="selected"' : '') . '>' . $label . '</option>';
- }
- ?>
- </select>
- <br>
- <label for="description"><?php echo $l->t('Description'); ?></label><br>
- <textarea placeholder="<?php echo $l->t('Description of the task');?>" name="description"><?php echo isset($_['details']->DESCRIPTION) ? $_['details']->DESCRIPTION[0]->value : '' ?></textarea>
- <br>
diff --git a/apps/tasks/templates/part.tasks.php b/apps/tasks/templates/part.tasks.php
deleted file mode 100644
index 50be1cd6bed..00000000000
--- a/apps/tasks/templates/part.tasks.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php foreach( $_['tasks'] as $task ): ?>
- <li data-id="<?php echo $task['id']; ?>"><a href="index.php?id=<?php echo $task['id']; ?>"><?php echo $task['name']; ?></a> </li>
-<?php endforeach; ?>
diff --git a/apps/user_external/appinfo/app.php b/apps/user_external/appinfo/app.php
new file mode 100644
index 00000000000..c7408ec30d9
--- /dev/null
+++ b/apps/user_external/appinfo/app.php
@@ -0,0 +1,4 @@
+<?php
+OC::$CLASSPATH['OC_User_IMAP']='apps/user_external/lib/imap.php';
+OC::$CLASSPATH['OC_User_SMB']='apps/user_external/lib/smb.php';
+OC::$CLASSPATH['OC_User_FTP']='apps/user_external/lib/ftp.php';
diff --git a/apps/user_external/appinfo/info.xml b/apps/user_external/appinfo/info.xml
new file mode 100644
index 00000000000..1d1dcee5401
--- /dev/null
+++ b/apps/user_external/appinfo/info.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<info>
+ <id>user_external</id>
+ <name>External user support</name>
+ <description>Use external user authentication methods</description>
+ <licence>AGPL</licence>
+ <author>Robin Appelman</author>
+ <require>4</require>
+ <shipped>true</shipped>
+ <types>
+ <authentication/>
+ </types>
+</info>
diff --git a/apps/user_external/appinfo/version b/apps/user_external/appinfo/version
new file mode 100644
index 00000000000..ceab6e11ece
--- /dev/null
+++ b/apps/user_external/appinfo/version
@@ -0,0 +1 @@
+0.1 \ No newline at end of file
diff --git a/apps/user_external/lib/ftp.php b/apps/user_external/lib/ftp.php
new file mode 100644
index 00000000000..e03e17d2b6a
--- /dev/null
+++ b/apps/user_external/lib/ftp.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_User_FTP extends OC_User_Backend{
+ private $host;
+ private $secure;
+ private $protocol;
+
+ public function __construct($host,$secure=false){
+ $this->host=$host;
+ $this->secure=$secure;
+ $this->protocol='ftp';
+ if($this->secure){
+ $this->protocol.='s';
+ }
+ $this->protocol.='://';
+ }
+
+ /**
+ * @brief Check if the password is correct
+ * @param $uid The username
+ * @param $password The password
+ * @returns true/false
+ *
+ * Check if the password is correct without logging in the user
+ */
+ public function checkPassword($uid, $password){
+ $url=$this->protocol.$uid.':'.$password.'@'.$this->host.'/';
+ $result=@opendir($url);
+ if(is_resource($result)){
+ return $uid;
+ }else{
+ return false;
+ }
+ }
+
+ public function userExists($uid){
+ return true;
+ }
+}
diff --git a/apps/user_external/lib/imap.php b/apps/user_external/lib/imap.php
new file mode 100644
index 00000000000..584e9804b18
--- /dev/null
+++ b/apps/user_external/lib/imap.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_User_IMAP extends OC_User_Backend{
+ private $mailbox;
+
+ public function __construct($mailbox){
+ $this->mailbox=$mailbox;
+ }
+
+ /**
+ * @brief Check if the password is correct
+ * @param $uid The username
+ * @param $password The password
+ * @returns true/false
+ *
+ * Check if the password is correct without logging in the user
+ */
+ public function checkPassword($uid, $password){
+ $mbox = @imap_open($this->mailbox, $uid, $password);
+ imap_errors();
+ imap_alerts();
+ if($mbox){
+ imap_close($mbox);
+ return $uid;
+ }else{
+ return false;
+ }
+ }
+
+ public function userExists($uid){
+ return true;
+ }
+}
+
diff --git a/apps/user_external/lib/smb.php b/apps/user_external/lib/smb.php
new file mode 100644
index 00000000000..44d2b7903d8
--- /dev/null
+++ b/apps/user_external/lib/smb.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_User_SMB extends OC_User_Backend{
+ private $host;
+
+ const smbclient='smbclient';
+ const loginError='NT_STATUS_LOGON_FAILURE';
+
+ public function __construct($host){
+ $this->host=$host;
+ }
+
+ /**
+ * @brief Check if the password is correct
+ * @param $uid The username
+ * @param $password The password
+ * @returns true/false
+ *
+ * Check if the password is correct without logging in the user
+ */
+ public function checkPassword($uid, $password){
+ $uidEscaped=escapeshellarg($uid);
+ $password=escapeshellarg($password);
+ $result=array();
+ $command=self::smbclient.' //'.$this->host.'/dummy -U'.$uidEscaped.'%'.$password;
+ $result=exec($command,$result);
+ if(substr($result,-strlen(self::loginError))==self::loginError){
+ return false;
+ }else{
+ return $uid;
+ }
+ }
+
+ public function userExists($uid){
+ return true;
+ }
+} \ No newline at end of file
diff --git a/apps/user_external/tests/config.php b/apps/user_external/tests/config.php
new file mode 100644
index 00000000000..64ee141d32d
--- /dev/null
+++ b/apps/user_external/tests/config.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+return array(
+ 'imap'=>array(
+ 'run'=>false,
+ 'mailbox'=>'{imap.gmail.com:993/imap/ssl}INBOX', //see http://php.net/manual/en/function.imap-open.php
+ 'user'=>'foo',//valid username/password combination
+ 'password'=>'bar',
+ ),
+ 'smb'=>array(
+ 'run'=>false,
+ 'host'=>'localhost',
+ 'user'=>'test',//valid username/password combination
+ 'password'=>'test',
+ ),
+ 'ftp'=>array(
+ 'run'=>false,
+ 'host'=>'localhost',
+ 'user'=>'test',//valid username/password combination
+ 'password'=>'test',
+ ),
+);
diff --git a/apps/user_external/tests/ftp.php b/apps/user_external/tests/ftp.php
new file mode 100644
index 00000000000..0cf7565f9c6
--- /dev/null
+++ b/apps/user_external/tests/ftp.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_User_FTP extends UnitTestCase{
+ /**
+ * @var OC_User_IMAP $instance
+ */
+ private $instance;
+
+ private function getConfig(){
+ return include(__DIR__.'/config.php');
+ }
+
+ function skip(){
+ $config=$this->getConfig();
+ $this->skipUnless($config['ftp']['run']);
+ }
+
+ function setUp(){
+ $config=$this->getConfig();
+ $this->instance=new OC_User_FTP($config['ftp']['host']);
+ }
+
+ function testLogin(){
+ $config=$this->getConfig();
+ $this->assertEqual($config['ftp']['user'],$this->instance->checkPassword($config['ftp']['user'],$config['ftp']['password']));
+ $this->assertFalse($this->instance->checkPassword($config['ftp']['user'],$config['ftp']['password'].'foo'));
+ }
+}
diff --git a/apps/user_external/tests/imap.php b/apps/user_external/tests/imap.php
new file mode 100644
index 00000000000..c703b32107f
--- /dev/null
+++ b/apps/user_external/tests/imap.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_User_Imap extends UnitTestCase{
+ /**
+ * @var OC_User_IMAP $instance
+ */
+ private $instance;
+
+ private function getConfig(){
+ return include(__DIR__.'/config.php');
+ }
+
+ function skip(){
+ $config=$this->getConfig();
+ $this->skipUnless($config['imap']['run']);
+ }
+
+ function setUp(){
+ $config=$this->getConfig();
+ $this->instance=new OC_User_IMAP($config['imap']['mailbox']);
+ }
+
+ function testLogin(){
+ $config=$this->getConfig();
+ $this->assertEqual($config['imap']['user'],$this->instance->checkPassword($config['imap']['user'],$config['imap']['password']));
+ $this->assertFalse($this->instance->checkPassword($config['imap']['user'],$config['imap']['password'].'foo'));
+ }
+}
diff --git a/apps/user_external/tests/smb.php b/apps/user_external/tests/smb.php
new file mode 100644
index 00000000000..1ed7eb934be
--- /dev/null
+++ b/apps/user_external/tests/smb.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class Test_User_SMB extends UnitTestCase{
+ /**
+ * @var OC_User_IMAP $instance
+ */
+ private $instance;
+
+ private function getConfig(){
+ return include(__DIR__.'/config.php');
+ }
+
+ function skip(){
+ $config=$this->getConfig();
+ $this->skipUnless($config['smb']['run']);
+ }
+
+ function setUp(){
+ $config=$this->getConfig();
+ $this->instance=new OC_User_SMB($config['smb']['host']);
+ }
+
+ function testLogin(){
+ $config=$this->getConfig();
+ $this->assertEqual($config['smb']['user'],$this->instance->checkPassword($config['smb']['user'],$config['smb']['password']));
+ $this->assertFalse($this->instance->checkPassword($config['smb']['user'],$config['smb']['password'].'foo'));
+ }
+}
diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 330574c1d42..3c6da47d71a 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -21,15 +21,17 @@
*
*/
-require_once('apps/user_ldap/lib_ldap.php');
-require_once('apps/user_ldap/user_ldap.php');
-require_once('apps/user_ldap/group_ldap.php');
+OCP\App::registerAdmin('user_ldap', 'settings');
-OCP\App::registerAdmin('user_ldap','settings');
+$connector = new OCA\user_ldap\lib\Connection('user_ldap');
+$userBackend = new OCA\user_ldap\USER_LDAP();
+$userBackend->setConnector($connector);
+$groupBackend = new OCA\user_ldap\GROUP_LDAP();
+$groupBackend->setConnector($connector);
// register user backend
-OC_User::useBackend( 'LDAP' );
-OC_Group::useBackend( new OC_GROUP_LDAP() );
+OC_User::useBackend($userBackend);
+OC_Group::useBackend($groupBackend);
// add settings page to navigation
$entry = array(
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index d438c7d84df..b9f4bdf1990 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -21,24 +21,22 @@
*
*/
-class OC_GROUP_LDAP extends OC_Group_Backend {
-// //group specific settings
- protected $ldapGroupFilter;
- protected $ldapGroupMemberAssocAttr;
- protected $configured = false;
+namespace OCA\user_ldap;
+
+class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
+ protected $enabled = 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');
-
- if(!empty($this->ldapGroupFilter) && !empty($this->ldapGroupMemberAssocAttr)) {
- $this->configured = true;
+ public function setConnector(lib\Connection &$connection) {
+ parent::setConnector($connection);
+ if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) {
+ $this->enabled = false;
}
+ $this->enabled = true;
}
/**
@@ -50,31 +48,31 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Checks whether the user is member of a group or not.
*/
public function inGroup($uid, $gid) {
- if(!$this->configured) {
+ if(!$this->enabled) {
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);
+ $dn_user = $this->username2dn($uid);
+ $dn_group = $this->groupname2dn($gid);
// just in case
if(!$dn_group || !$dn_user) {
return false;
}
//usually, LDAP attributes are said to be case insensitive. But there are exceptions of course.
- $members = OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr);
+ $members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr);
if(!$members) {
return false;
}
//extra work if we don't get back user DNs
//TODO: this can be done with one LDAP query
- if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
+ if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
$dns = array();
foreach($members as $mid) {
- $filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter'));
- $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+ $filter = str_replace('%uid', $mid, $this->connection->ldapLoginFilter);
+ $ldap_users = $this->fetchListOfUsers($filter, 'dn');
if(count($ldap_users) < 1) {
continue;
}
@@ -96,36 +94,37 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* if the user exists at all.
*/
public function getUserGroups($uid) {
- if(!$this->configured) {
+ if(!$this->enabled) {
return array();
}
if(isset($this->_user_groups[$uid])) {
return $this->_user_groups[$uid];
}
- $userDN = OC_LDAP::username2dn($uid);
+ $userDN = $this->username2dn($uid);
if(!$userDN) {
$this->_user_groups[$uid] = array();
return array();
}
//uniqueMember takes DN, memberuid the uid, so we need to distinguish
- if((strtolower($this->ldapGroupMemberAssocAttr) == 'uniquemember')
- || (strtolower($this->ldapGroupMemberAssocAttr) == 'member')) {
+ if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember')
+ || (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')
+ ) {
$uid = $userDN;
- } else if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
- $result = OC_LDAP::readAttribute($userDN, 'uid');
+ } else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
+ $result = $this->readAttribute($userDN, 'uid');
$uid = $result[0];
} else {
// just in case
$uid = $userDN;
}
- $filter = OC_LDAP::combineFilterWithAnd(array(
- $this->ldapGroupFilter,
- $this->ldapGroupMemberAssocAttr.'='.$uid
+ $filter = $this->combineFilterWithAnd(array(
+ $this->connection->ldapGroupFilter,
+ $this->connection->ldapGroupMemberAssocAttr.'='.$uid
));
- $groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
- $this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING);
+ $groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn'));
+ $this->_user_groups[$uid] = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
return $this->_user_groups[$uid];
}
@@ -135,44 +134,44 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* @returns array with user ids
*/
public function usersInGroup($gid) {
- if(!$this->configured) {
+ if(!$this->enabled) {
return array();
}
if(isset($this->_group_users[$gid])) {
return $this->_group_users[$gid];
}
- $groupDN = OC_LDAP::groupname2dn($gid);
+ $groupDN = $this->groupname2dn($gid);
if(!$groupDN) {
$this->_group_users[$gid] = array();
return array();
}
- $members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr);
+ $members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr);
if(!$members) {
$this->_group_users[$gid] = array();
return array();
}
$result = array();
- $isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid');
+ $isMemberUid = (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid');
foreach($members as $member) {
if($isMemberUid) {
- $filter = OCP\Util::mb_str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
- $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+ $filter = \OCP\Util::mb_str_replace('%uid', $member, $this->connection->ldapLoginFilter, 'UTF-8');
+ $ldap_users = $this->fetchListOfUsers($filter, 'dn');
if(count($ldap_users) < 1) {
continue;
}
- $result[] = OC_LDAP::dn2username($ldap_users[0]);
+ $result[] = $this->dn2username($ldap_users[0]);
continue;
} else {
- if($ocname = OC_LDAP::dn2username($member)){
+ if($ocname = $this->dn2username($member)) {
$result[] = $ocname;
}
}
}
if(!$isMemberUid) {
- $result = array_intersect($result, OCP\User::getUsers());
+ $result = array_intersect($result, \OCP\User::getUsers());
}
$this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING);
return $this->_group_users[$gid];
@@ -185,12 +184,12 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Returns a list with all groups
*/
public function getGroups() {
- if(!$this->configured) {
+ if(!$this->enabled) {
return array();
}
if(empty($this->_groups)) {
- $ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
- $this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+ $ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn'));
+ $this->_groups = $this->ownCloudGroupNames($ldap_groups);
}
return $this->_groups;
}
@@ -203,4 +202,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
public function groupExists($gid){
return in_array($gid, $this->getGroups());
}
+
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function implementsActions($actions) {
+ //always returns false, because possible actions are modifying actions. We do not write to LDAP, at least for now.
+ return false;
+ }
} \ No newline at end of file
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
new file mode 100644
index 00000000000..870f6330edd
--- /dev/null
+++ b/apps/user_ldap/lib/access.php
@@ -0,0 +1,593 @@
+<?php
+
+/**
+ * ownCloud – LDAP Access
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+abstract class Access {
+ protected $connection;
+
+ public function setConnector(Connection &$connection) {
+ $this->connection = $connection;
+ }
+
+ private function checkConnection() {
+ return ($this->connection instanceof Connection);
+ }
+
+ /**
+ * @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
+ */
+ public function readAttribute($dn, $attr) {
+ if(!$this->checkConnection()) {
+ \OCP\Util::writeLog('user_ldap', 'No LDAP Connector assigned, access impossible for readAttribute.', \OCP\Util::WARN);
+ return false;
+ }
+ $cr = $this->connection->getConnectionResource();
+ $rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr));
+ if(!is_resource($rr)) {
+ \OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
+ //in case an error occurs , e.g. object does not exist
+ return false;
+ }
+ $er = ldap_first_entry($cr, $rr);
+ //LDAP attributes are not case sensitive
+ $result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
+ $attr = mb_strtolower($attr, 'UTF-8');
+
+ if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
+ $values = array();
+ for($i=0;$i<$result[$attr]['count'];$i++) {
+ $values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
+ }
+ return $values;
+ }
+ return false;
+ }
+
+ /**
+ * @brief checks wether the given attribute`s valua is probably a DN
+ * @param $attr the attribute in question
+ * @return if so true, otherwise false
+ */
+ private function resemblesDN($attr) {
+ $resemblingAttributes = array(
+ 'dn',
+ 'uniquemember',
+ 'member'
+ );
+ return in_array($attr, $resemblingAttributes);
+ }
+
+ /**
+ * @brief sanitizes a DN received from the LDAP server
+ * @param $dn the DN in question
+ * @return the sanitized DN
+ */
+ private function sanitizeDN($dn) {
+ //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this!
+ $dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
+
+ //make comparisons and everything work
+ $dn = mb_strtolower($dn, 'UTF-8');
+
+ return $dn;
+ }
+
+ /**
+ * gives back the database table for the query
+ */
+ 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
+ */
+ public function groupname2dn($name) {
+ return $this->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
+ */
+ public function username2dn($name) {
+ $dn = $this->ocname2dn($name, true);
+ if($dn) {
+ return $dn;
+ } else {
+ //fallback: user is not mapped
+ $filter = $this->combineFilterWithAnd(array(
+ $this->connection->ldapUserFilter,
+ $this->connection->ldapUserDisplayName . '=' . $name,
+ ));
+ $result = $this->searchUsers($filter, 'dn');
+ if(isset($result[0]['dn'])) {
+ $this->mapComponent($result[0], $name, true);
+ return $result[0];
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name
+ * @param $name the ownCloud name in question
+ * @param $isUser is it a user? otherwise group
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name
+ */
+ private function ocname2dn($name, $isUser) {
+ $table = $this->getMapTable($isUser);
+
+ $query = \OCP\DB::prepare('
+ SELECT ldap_dn
+ FROM '.$table.'
+ WHERE owncloud_name = ?
+ ');
+
+ $record = $query->execute(array($name))->fetchOne();
+ return $record;
+ }
+
+ /**
+ * @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, false on DN outside of search DN
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the group
+ */
+ public function dn2groupname($dn, $ldapname = null) {
+ if(mb_strripos($dn, $this->connection->ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseGroups, 'UTF-8'))) {
+ return false;
+ }
+ return $this->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, false on DN outside of search DN
+ */
+ public function dn2username($dn, $ldapname = null) {
+ if(mb_strripos($dn, $this->connection->ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseUsers, 'UTF-8'))) {
+ return false;
+ }
+ return $this->dn2ocname($dn, $ldapname, true);
+ }
+
+ /**
+ * @brief returns an internal ownCloud name for the given LDAP DN
+ * @param $dn the dn of the user object
+ * @param $ldapname optional, the display name of the object
+ * @param $isUser optional, wether it is a user object (otherwise group assumed)
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
+ */
+ public function dn2ocname($dn, $ldapname = null, $isUser = true) {
+ $dn = $this->sanitizeDN($dn);
+ $table = $this->getMapTable($isUser);
+ if($isUser) {
+ $nameAttribute = $this->connection->ldapUserDisplayName;
+ } else {
+ $nameAttribute = $this->connection->ldapGroupDisplayName;
+ }
+
+ $query = \OCP\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 = $this->readAttribute($dn, $nameAttribute);
+ $ldapname = $ldapname[0];
+ }
+ $ldapname = $this->sanitizeUsername($ldapname);
+
+ //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($this->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 = $this->alternateOwnCloudName($ldapname, $dn);
+ if($this->mapComponent($dn, $oc_name, $isUser)) {
+ return $oc_name;
+ }
+
+ //TODO: do not simple die away!
+ //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
+ */
+ public function ownCloudUserNames($ldapUsers) {
+ return $this->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
+ */
+ public function ownCloudGroupNames($ldapGroups) {
+ return $this->ldap2ownCloudNames($ldapGroups, false);
+ }
+
+ private function ldap2ownCloudNames($ldapObjects, $isUsers) {
+ if($isUsers) {
+ $knownObjects = $this->mappedUsers();
+ $nameAttribute = $this->connection->ldapUserDisplayName;
+ } else {
+ $knownObjects = $this->mappedGroups();
+ $nameAttribute = $this->connection->ldapGroupDisplayName;
+ }
+ $ownCloudNames = array();
+
+ foreach($ldapObjects as $ldapObject) {
+ $key = \OCP\Util::recursiveArraySearch($knownObjects, $ldapObject['dn']);
+
+ //everything is fine when we know the group
+ if($key !== false) {
+ $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. But first make sure, that the display name contains only allowed characters.
+ $ocname = $this->sanitizeUsername($ldapObject[$nameAttribute]);
+ if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+ $ownCloudNames[] = $ocname;
+ 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.
+ $ocname = $this->alternateOwnCloudName($ocname, $ldapObject['dn']);
+ if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+ $ownCloudNames[] = $ocname;
+ continue;
+ }
+
+ //TODO: do not simple die away
+ //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
+ */
+ private function alternateOwnCloudName($name, $dn) {
+ $ufn = ldap_dn2ufn($dn);
+ $name = $name . '@' . trim(\OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
+ $name = $this->sanitizeUsername($name);
+ return $name;
+ }
+
+ /**
+ * @brief retrieves all known groups from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known groups from the mappings table
+ */
+ private function mappedGroups() {
+ return $this->mappedComponents(false);
+ }
+
+ /**
+ * @brief retrieves all known users from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known users from the mappings table
+ */
+ private function mappedUsers() {
+ return $this->mappedComponents(true);
+ }
+
+ private function mappedComponents($isUsers) {
+ $table = $this->getMapTable($isUsers);
+
+ $query = \OCP\DB::prepare('
+ SELECT ldap_dn, owncloud_name
+ FROM '. $table
+ );
+
+ return $query->execute()->fetchAll();
+ }
+
+ /**
+ * @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
+ */
+ private function mapComponent($dn, $ocname, $isUser = true) {
+ $table = $this->getMapTable($isUser);
+ $dn = $this->sanitizeDN($dn);
+
+ $sqlAdjustment = '';
+ $dbtype = \OCP\Config::getSystemValue('dbtype');
+ if($dbtype == 'mysql') {
+ $sqlAdjustment = 'FROM dual';
+ }
+
+ $insert = \OCP\DB::prepare('
+ INSERT INTO '.$table.' (ldap_dn, owncloud_name)
+ SELECT ?,?
+ '.$sqlAdjustment.'
+ WHERE NOT EXISTS (
+ SELECT 1
+ FROM '.$table.'
+ WHERE ldap_dn = ?
+ OR owncloud_name = ? )
+ ');
+
+ $res = $insert->execute(array($dn, $ocname, $dn, $ocname));
+
+ if(\OCP\DB::isError($res)) {
+ return false;
+ }
+
+ $insRows = $res->numRows();
+
+ if($insRows == 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function fetchListOfUsers($filter, $attr) {
+ return $this->fetchList($this->searchUsers($filter, $attr), (count($attr) > 1));
+ }
+
+ public function fetchListOfGroups($filter, $attr) {
+ return $this->fetchList($this->searchGroups($filter, $attr), (count($attr) > 1));
+ }
+
+ private function fetchList($list, $manyAttributes) {
+ if(is_array($list)) {
+ if($manyAttributes) {
+ return $list;
+ } else {
+ return array_unique($list, SORT_LOCALE_STRING);
+ }
+ }
+
+ //error cause actually, maybe throw an exception in future.
+ return array();
+ }
+
+ /**
+ * @brief executes an LDAP search, optimized for Users
+ * @param $filter the LDAP filter for the search
+ * @param $attr optional, when a certain attribute shall be filtered out
+ * @returns array with the search result
+ *
+ * Executes an LDAP search
+ */
+ public function searchUsers($filter, $attr = null) {
+ return $this->search($filter, $this->connection->ldapBaseUsers, $attr);
+ }
+
+ /**
+ * @brief executes an LDAP search, optimized for Groups
+ * @param $filter the LDAP filter for the search
+ * @param $attr optional, when a certain attribute shall be filtered out
+ * @returns array with the search result
+ *
+ * Executes an LDAP search
+ */
+ public function searchGroups($filter, $attr = null) {
+ return $this->search($filter, $this->connection->ldapBaseGroups, $attr);
+ }
+
+ /**
+ * @brief executes an LDAP search
+ * @param $filter the LDAP filter for the search
+ * @param $base the LDAP subtree that shall be searched
+ * @param $attr optional, when a certain attribute shall be filtered out
+ * @returns array with the search result
+ *
+ * Executes an LDAP search
+ */
+ private function search($filter, $base, $attr = null) {
+ if(!is_null($attr) && !is_array($attr)) {
+ $attr = array(mb_strtolower($attr, 'UTF-8'));
+ }
+
+ // See if we have a resource
+ $link_resource = $this->connection->getConnectionResource();
+ if(is_resource($link_resource)) {
+ $sr = ldap_search($link_resource, $base, $filter, $attr);
+ $findings = ldap_get_entries($link_resource, $sr );
+
+ // if we're here, probably no connection resource is returned.
+ // to make ownCloud behave nicely, we simply give back an empty array.
+ if(is_null($findings)) {
+ return array();
+ }
+ } else {
+ // Seems like we didn't find any resource.
+ // Return an empty array just like before.
+ \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG);
+ return array();
+ }
+
+ if(!is_null($attr)) {
+ $selection = array();
+ $multiarray = false;
+ if(count($attr) > 1) {
+ $multiarray = true;
+ $i = 0;
+ }
+ foreach($findings as $item) {
+ if(!is_array($item)) {
+ continue;
+ }
+ $item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
+
+ if($multiarray) {
+ foreach($attr as $key) {
+ $key = mb_strtolower($key, 'UTF-8');
+ if(isset($item[$key])) {
+ if($key != 'dn') {
+ $selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0];
+ } else {
+ $selection[$i][$key] = $this->sanitizeDN($item[$key]);
+ }
+ }
+
+ }
+ $i++;
+ } else {
+ //tribute to case insensitivity
+ $key = mb_strtolower($attr[0], 'UTF-8');
+
+ if(isset($item[$key])) {
+ if($this->resemblesDN($key)) {
+ $selection[] = $this->sanitizeDN($item[$key]);
+ } else {
+ $selection[] = $item[$key];
+ }
+ }
+ }
+ }
+ return $selection;
+ }
+ return $findings;
+ }
+
+ public function sanitizeUsername($name) {
+ if($this->connection->ldapIgnoreNamingRules) {
+ return $name;
+ }
+
+ //REPLACEMENTS
+ $name = \OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
+
+ //every remaining unallowed characters will be removed
+ $name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
+
+ return $name;
+ }
+
+ /**
+ * @brief combines the input filters with AND
+ * @param $filters array, the filters to connect
+ * @returns the combined filter
+ *
+ * Combines Filter arguments with AND
+ */
+ public function combineFilterWithAnd($filters) {
+ return $this->combineFilter($filters, '&');
+ }
+
+ /**
+ * @brief combines the input filters with AND
+ * @param $filters array, the filters to connect
+ * @returns the combined filter
+ *
+ * Combines Filter arguments with AND
+ */
+ public function combineFilterWithOr($filters) {
+ return $this->combineFilter($filters, '|');
+ }
+
+ /**
+ * @brief combines the input filters with given operator
+ * @param $filters array, the filters to connect
+ * @param $operator either & or |
+ * @returns the combined filter
+ *
+ * Combines Filter arguments with AND
+ */
+ private function combineFilter($filters, $operator) {
+ $combinedFilter = '('.$operator;
+ foreach($filters as $filter) {
+ if($filter[0] != '(') {
+ $filter = '('.$filter.')';
+ }
+ $combinedFilter.=$filter;
+ }
+ $combinedFilter.=')';
+ return $combinedFilter;
+ }
+
+ public function areCredentialsValid($name, $password) {
+ $testConnection = clone $this->connection;
+ $credentials = array(
+ 'ldapAgentName' => $name,
+ 'ldapAgentPassword' => $password
+ );
+ if(!$testConnection->setConfiguration($credentials)) {
+ return false;
+ }
+ return $testConnection->bind();
+ }
+} \ No newline at end of file
diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php
new file mode 100644
index 00000000000..c8ba9dad70e
--- /dev/null
+++ b/apps/user_ldap/lib/connection.php
@@ -0,0 +1,245 @@
+<?php
+
+/**
+ * ownCloud – LDAP Access
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+class Connection {
+ private $ldapConnectionRes = null;
+ private $configID;
+ private $configured = false;
+
+ //cached settings
+ protected $config = array(
+ 'ldapHost' => null,
+ 'ldapPort' => null,
+ 'ldapBase' => null,
+ 'ldapBaseUsers' => null,
+ 'ldapBaseGroups' => null,
+ 'ldapAgentName' => null,
+ 'ldapAgentPassword' => null,
+ 'ldapTLS' => null,
+ 'ldapNoCase' => null,
+ 'ldapIgnoreNamingRules' => null,
+ 'ldapUserDisplayName' => null,
+ 'ldapUserFilter' => null,
+ 'ldapGroupFilter' => null,
+ 'ldapGroupDisplayName' => null,
+ 'ldapLoginFilter' => null,
+ 'ldapQuotaAttribute' => null,
+ 'ldapQuotaDefault' => null,
+ 'ldapEmailAttribute' => null,
+ );
+
+ public function __construct($configID = 'user_ldap') {
+ $this->configID = $configID;
+ }
+
+ public function __destruct() {
+ @ldap_unbind($this->ldapConnectionRes);
+ }
+
+ public function __get($name) {
+ if(!$this->configured) {
+ $this->readConfiguration();
+ }
+
+ if(isset($this->config[$name])) {
+ return $this->config[$name];
+ }
+ }
+
+ /**
+ * @brief initializes the LDAP backend
+ * @param $force read the config settings no matter what
+ *
+ * initializes the LDAP backend
+ */
+ public function init($force = false) {
+ $this->readConfiguration($force);
+ $this->establishConnection();
+ }
+
+ /**
+ * Returns the LDAP handler
+ */
+ public function getConnectionResource() {
+ if(!$this->ldapConnectionRes) {
+ $this->init();
+ }
+ if(is_null($this->ldapConnectionRes)) {
+ \OCP\Util::writeLog('user_ldap', 'Connection could not be established', \OCP\Util::ERROR);
+ }
+ return $this->ldapConnectionRes;
+ }
+
+ /**
+ * Caches the general LDAP configuration.
+ */
+ private function readConfiguration($force = false) {
+ \OCP\Util::writeLog('user_ldap','Checking conf state: isConfigured? '.print_r($this->configured, true).' isForce? '.print_r($force, true).' configID? '.print_r($this->configID, true), \OCP\Util::DEBUG);
+ if((!$this->configured || $force) && !is_null($this->configID)) {
+ \OCP\Util::writeLog('user_ldap','Reading the configuration', \OCP\Util::DEBUG);
+ $this->config['ldapHost'] = \OCP\Config::getAppValue($this->configID, 'ldap_host', '');
+ $this->config['ldapPort'] = \OCP\Config::getAppValue($this->configID, 'ldap_port', 389);
+ $this->config['ldapAgentName'] = \OCP\Config::getAppValue($this->configID, 'ldap_dn','');
+ $this->config['ldapAgentPassword'] = base64_decode(\OCP\Config::getAppValue($this->configID, 'ldap_agent_password',''));
+ $this->config['ldapBase'] = \OCP\Config::getAppValue($this->configID, 'ldap_base', '');
+ $this->config['ldapBaseUsers'] = \OCP\Config::getAppValue($this->configID, 'ldap_base_users',$this->config['ldapBase']);
+ $this->config['ldapBaseGroups'] = \OCP\Config::getAppValue($this->configID, 'ldap_base_groups', $this->config['ldapBase']);
+ $this->config['ldapTLS'] = \OCP\Config::getAppValue($this->configID, 'ldap_tls',0);
+ $this->config['ldapNoCase'] = \OCP\Config::getAppValue($this->configID, 'ldap_nocase', 0);
+ $this->config['ldapUserDisplayName'] = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_display_name', 'uid'), 'UTF-8');
+ $this->config['ldapUserFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_userlist_filter','objectClass=person');
+ $this->config['ldapGroupFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_filter','(objectClass=posixGroup)');
+ $this->config['ldapLoginFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_login_filter', '(uid=%uid)');
+ $this->config['ldapGroupDisplayName'] = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', 'uid'), 'UTF-8');
+ $this->config['ldapQuotaAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_quota_attr', '');
+ $this->config['ldapQuotaDefault'] = \OCP\Config::getAppValue($this->configID, 'ldap_quota_def', '');
+ $this->config['ldapEmailAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', '');
+ $this->config['ldapGroupMemberAssocAttr'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember');
+ $this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
+
+ $this->configured = $this->validateConfiguration();
+ }
+ }
+
+ /**
+ * @brief set LDAP configuration with values delivered by an array, not read from configuration
+ * @param $config array that holds the config parameters in an associated array
+ * @param &$setParameters optional; array where the set fields will be given to
+ * @return true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
+ */
+ public function setConfiguration($config, &$setParameters = null) {
+ if(!is_array($config)) {
+ return false;
+ }
+
+ foreach($config as $parameter => $value) {
+ if(isset($this->config[$parameter])) {
+ $this->config[$parameter] = $value;
+ if(is_array($setParameters)) {
+ $setParameters[] = $parameter;
+ }
+ }
+ }
+
+ $this->configured = $this->validateConfiguration();
+
+ return $this->configured;
+ }
+
+ /**
+ * @brief Validates the user specified configuration
+ * @returns true if configuration seems OK, false otherwise
+ */
+ private function validateConfiguration() {
+ //first step: "soft" checks: settings that are not really necessary, but advisable. If left empty, give an info message
+ if(empty($this->config['ldapBaseUsers'])) {
+ \OCP\Util::writeLog('user_ldap', 'Base tree for Users is empty, using Base DN', \OCP\Util::INFO);
+ $this->config['ldapBaseUsers'] = $this->config['ldapBase'];
+ }
+ if(empty($this->config['ldapBaseGroups'])) {
+ \OCP\Util::writeLog('user_ldap', 'Base tree for Groups is empty, using Base DN', \OCP\Util::INFO);
+ $this->config['ldapBaseGroups'] = $this->config['ldapBase'];
+ }
+ if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) {
+ \OCP\Util::writeLog('user_ldap', 'No group filter is specified, LDAP group feature will not be used.', \OCP\Util::INFO);
+ }
+
+ //second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning.
+ $configurationOK = true;
+ if(empty($this->config['ldapHost'])) {
+ \OCP\Util::writeLog('user_ldap', 'No LDAP host given, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapPort'])) {
+ \OCP\Util::writeLog('user_ldap', 'No LDAP Port given, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if((empty($this->config['ldapAgentName']) && !empty($this->config['ldapAgentPassword']))
+ || (!empty($this->config['ldapAgentName']) && empty($this->config['ldapAgentPassword']))) {
+ \OCP\Util::writeLog('user_ldap', 'Either no password given for the user agent or a password is given, but no LDAP agent; won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ //TODO: check if ldapAgentName is in DN form
+ if(empty($this->config['ldapBase']) && (empty($this->config['ldapBaseUsers']) && empty($this->config['ldapBaseGroups']))) {
+ \OCP\Util::writeLog('user_ldap', 'No Base DN given, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapUserDisplayName'])) {
+ \OCP\Util::writeLog('user_ldap', 'No user display name attribute specified, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapGroupDisplayName'])) {
+ \OCP\Util::writeLog('user_ldap', 'No group display name attribute specified, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapLoginFilter'])) {
+ \OCP\Util::writeLog('user_ldap', 'No login filter specified, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(mb_strpos($this->config['ldapLoginFilter'], '%uid', 0, 'UTF-8') === false) {
+ \OCP\Util::writeLog('user_ldap', 'Login filter does not contain %uid place holder, won`t connect.', \OCP\Util::WARN);
+ \OCP\Util::writeLog('user_ldap', 'Login filter was ' . $this->config['ldapLoginFilter'], \OCP\Util::DEBUG);
+ $configurationOK = false;
+ }
+
+ return $configurationOK;
+ }
+
+ /**
+ * Connects and Binds to LDAP
+ */
+ private function establishConnection() {
+ if(!$this->configured) {
+ \OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN);
+ return false;
+ }
+ if(!$this->ldapConnectionRes) {
+ $this->ldapConnectionRes = ldap_connect($this->config['ldapHost'], $this->config['ldapPort']);
+ if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
+ if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
+ if($this->config['ldapTLS']) {
+ ldap_start_tls($this->ldapConnectionRes);
+ }
+ }
+ }
+
+ return $this->bind();
+ }
+ }
+
+ /**
+ * Binds to LDAP
+ */
+ public function bind() {
+ $ldapLogin = @ldap_bind($this->getConnectionResource(), $this->config['ldapAgentName'], $this->config['ldapAgentPassword']);
+ if(!$ldapLogin) {
+ \OCP\Util::writeLog('user_ldap', 'Bind failed: ' . ldap_errno($this->ldapConnectionRes) . ': ' . ldap_error($this->ldapConnectionRes), \OCP\Util::ERROR);
+ $this->ldapConnectionRes = null;
+ return false;
+ }
+ return true;
+ }
+
+} \ No newline at end of file
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
deleted file mode 100644
index 08b09304d78..00000000000
--- a/apps/user_ldap/lib_ldap.php
+++ /dev/null
@@ -1,721 +0,0 @@
-<?php
-
-/**
- * ownCloud – LDAP lib
- *
- * @author Arthur Schiwon
- * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-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 {
- public function __destruct() {
- OC_LDAP::destruct();
- }
-}
-
-class OC_LDAP {
- static protected $ldapConnectionRes = false;
- static protected $configured = false;
-
- //cached settings
- static protected $ldapHost;
- static protected $ldapPort;
- static protected $ldapBase;
- static protected $ldapBaseUsers;
- static protected $ldapBaseGroups;
- static protected $ldapAgentName;
- static protected $ldapAgentPassword;
- static protected $ldapTLS;
- static protected $ldapNoCase;
- static protected $ldapIgnoreNamingRules;
- // user and group settings, that are needed in both backends
- static protected $ldapUserDisplayName;
- static protected $ldapUserFilter;
- static protected $ldapGroupDisplayName;
- static protected $ldapLoginFilter;
-
- static protected $__d;
-
- /**
- * @brief initializes the LDAP backend
- * @param $force read the config settings no matter what
- *
- * 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();
- }
-
- static public function destruct() {
- @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',
- 'ldapLoginFilter'
- );
-
- 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
- self::init();
- $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 = OCP\DB::prepare('
- SELECT ldap_dn
- FROM '.$table.'
- WHERE owncloud_name = ?
- ');
-
- $record = $query->execute(array($name))->fetchOne();
- return $record;
- }
-
- /**
- * @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, false on DN outside of search DN
- *
- * returns the internal ownCloud name for the given LDAP DN of the group
- */
- static public function dn2groupname($dn, $ldapname = null) {
- if(mb_strripos($dn, self::$ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseGroups, 'UTF-8'))) {
- return false;
- }
- 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, false on DN outside of search DN
- */
- static public function dn2username($dn, $ldapname = null) {
- if(mb_strripos($dn, self::$ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseUsers, 'UTF-8'))) {
- return false;
- }
- return self::dn2ocname($dn, $ldapname, true);
- }
-
- static public function dn2ocname($dn, $ldapname = null, $isUser = true) {
- $dn = self::sanitizeDN($dn);
- $table = self::getMapTable($isUser);
- if($isUser) {
- $nameAttribute = self::conf('ldapUserDisplayName');
- } else {
- $nameAttribute = self::conf('ldapGroupDisplayName');
- }
-
- $query = OCP\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];
- }
- $ldapname = self::sanitizeUsername($ldapname);
-
- //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 !== false) {
- $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. But first make sure, that the display name contains only allowed characters.
- $ocname = self::sanitizeUsername($ldapObject[$nameAttribute]);
- if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
- $ownCloudNames[] = $ocname;
- 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.
- $ocname = self::alternateOwnCloudName($ocname, $ldapObject['dn']);
- if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
- $ownCloudNames[] = $ocname;
- 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);
- $name = $name . '@' . trim(OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
- $name = self::sanitizeUsername($name);
- return $name;
- }
-
- /**
- * @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 = OCP\DB::prepare('
- SELECT ldap_dn, owncloud_name
- FROM '. $table
- );
-
- return $query->execute()->fetchAll();
- }
-
- /**
- * @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);
- $dn = self::sanitizeDN($dn);
-
- $sqlAdjustment = '';
- $dbtype = OCP\Config::getSystemValue('dbtype');
- if($dbtype == 'mysql') {
- $sqlAdjustment = 'FROM dual';
- }
-
- $insert = OCP\DB::prepare('
- INSERT INTO '.$table.' (ldap_dn, owncloud_name)
- SELECT ?,?
- '.$sqlAdjustment.'
- WHERE NOT EXISTS (
- SELECT 1
- FROM '.$table.'
- WHERE ldap_dn = ?
- OR owncloud_name = ? )
- ');
-
- $res = $insert->execute(array($dn, $ocname, $dn, $ocname));
-
- if(OCP\DB::isError($res)) {
- return false;
- }
-
- $insRows = $res->numRows();
-
- if($insRows == 0) {
- return false;
- }
-
- return true;
- }
-
- static public function fetchListOfUsers($filter, $attr) {
- return self::fetchList(OC_LDAP::searchUsers($filter, $attr), (count($attr) > 1));
- }
-
- static public function fetchListOfGroups($filter, $attr) {
- return self::fetchList(OC_LDAP::searchGroups($filter, $attr), (count($attr) > 1));
- }
-
- static private function fetchList($list, $manyAttributes) {
- if(is_array($list)) {
- if($manyAttributes) {
- return $list;
- } else {
- return array_unique($list, SORT_LOCALE_STRING);
- }
- }
-
- //error cause actually, maybe throw an exception in future.
- return array();
- }
-
- /**
- * @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();
- $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
- $er = ldap_first_entry($cr, $rr);
- //LDAP attributes are not case sensitive
- $result = OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
- $attr = mb_strtolower($attr, 'UTF-8');
-
- if(isset($result[$attr]) && $result[$attr]['count'] > 0){
- $values = array();
- for($i=0;$i<$result[$attr]['count'];$i++) {
- $values[] = self::resemblesDN($attr) ? self::sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
- }
- return $values;
- }
- return false;
- }
-
- /**
- * @brief executes an LDAP search, optimized for Users
- * @param $filter the LDAP filter for the search
- * @param $attr optional, when a certain attribute shall be filtered out
- * @returns array with the search result
- *
- * Executes an LDAP search
- */
- static public function searchUsers($filter, $attr = null) {
- self::init();
- return self::search($filter, self::$ldapBaseUsers, $attr);
- }
-
- /**
- * @brief executes an LDAP search, optimized for Groups
- * @param $filter the LDAP filter for the search
- * @param $attr optional, when a certain attribute shall be filtered out
- * @returns array with the search result
- *
- * Executes an LDAP search
- */
- static public function searchGroups($filter, $attr = null) {
- self::init();
- return self::search($filter, self::$ldapBaseGroups, $attr);
- }
-
- /**
- * @brief executes an LDAP search
- * @param $filter the LDAP filter for the search
- * @param $base the LDAP subtree that shall be searched
- * @param $attr optional, when a certain attribute shall be filtered out
- * @returns array with the search result
- *
- * Executes an LDAP search
- */
- static private function search($filter, $base, $attr = null) {
- if(!is_null($attr) && !is_array($attr)) {
- $attr = array(mb_strtolower($attr, 'UTF-8'));
- }
-
- // See if we have a resource
- $link_resource = self::getConnectionResource();
- if(is_resource($link_resource)) {
- $sr = ldap_search($link_resource, $base, $filter, $attr);
- $findings = ldap_get_entries($link_resource, $sr );
-
- // if we're here, probably no connection resource is returned.
- // to make ownCloud behave nicely, we simply give back an empty array.
- if(is_null($findings)) {
- return array();
- }
- } else {
- // Seems like we didn't find any resource.
- // Return an empty array just like before.
- return array();
- }
-
- if(!is_null($attr)) {
- $selection = array();
- $multiarray = false;
- if(count($attr) > 1) {
- $multiarray = true;
- $i = 0;
- }
- foreach($findings as $item) {
- if(!is_array($item)) {
- continue;
- }
- $item = OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
-
- if($multiarray) {
- foreach($attr as $key) {
- $key = mb_strtolower($key, 'UTF-8');
- if(isset($item[$key])) {
- if($key != 'dn'){
- $selection[$i][$key] = self::resemblesDN($key) ? self::sanitizeDN($item[$key][0]) : $item[$key][0];
- } else {
- $selection[$i][$key] = self::sanitizeDN($item[$key]);
- }
- }
-
- }
- $i++;
- } else {
- //tribute to case insensitivity
- $key = mb_strtolower($attr[0], 'UTF-8');
-
- if(isset($item[$key])) {
- if(self::resemblesDN($key)) {
- $selection[] = self::sanitizeDN($item[$key]);
- } else {
- $selection[] = $item[$key];
- }
- }
- }
-
- }
- return $selection;
- }
-
- return $findings;
- }
-
- static private function resemblesDN($attr) {
- $resemblingAttributes = array(
- 'dn',
- 'uniquemember',
- 'member'
- );
- return in_array($attr, $resemblingAttributes);
- }
-
- static private function sanitizeDN($dn) {
- //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this!
- $dn = preg_replace('/([^\\\]),(\s+)/u','\1,',$dn);
-
- //make comparisons and everything work
- $dn = mb_strtolower($dn, 'UTF-8');
-
- return $dn;
- }
-
- static private function sanitizeUsername($name) {
- if(self::$ldapIgnoreNamingRules) {
- return $name;
- }
-
- //REPLACEMENTS
- $name = OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
-
- //every remaining unallowed characters will be removed
- $name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
-
- return $name;
- }
-
- /**
- * @brief combines the input filters with AND
- * @param $filters array, the filters to connect
- * @returns the combined filter
- *
- * Combines Filter arguments with AND
- */
- static public function combineFilterWithAnd($filters) {
- return self::combineFilter($filters,'&');
- }
-
- /**
- * @brief combines the input filters with AND
- * @param $filters array, the filters to connect
- * @returns the combined filter
- *
- * Combines Filter arguments with AND
- */
- static public function combineFilterWithOr($filters) {
- return self::combineFilter($filters,'|');
- }
-
- /**
- * @brief combines the input filters with given operator
- * @param $filters array, the filters to connect
- * @param $operator either & or |
- * @returns the combined filter
- *
- * Combines Filter arguments with AND
- */
- static private function combineFilter($filters, $operator) {
- $combinedFilter = '('.$operator;
- foreach($filters as $filter) {
- if($filter[0] != '(') {
- $filter = '('.$filter.')';
- }
- $combinedFilter.=$filter;
- }
- $combinedFilter.=')';
- return $combinedFilter;
- }
-
- /**
- * Returns the LDAP handler
- */
- static private function getConnectionResource() {
- if(!self::$ldapConnectionRes) {
- self::init();
- }
- if(is_null(self::$ldapConnectionRes)) {
- OCP\Util::writeLog('ldap', 'Connection could not be established', OCP\Util::INFO);
- }
- return self::$ldapConnectionRes;
- }
-
- /**
- * Caches the general LDAP configuration.
- */
- static private function readConfiguration($force = false) {
- if(!self::$configured || $force) {
- self::$ldapHost = OCP\Config::getAppValue('user_ldap', 'ldap_host', '');
- self::$ldapPort = OCP\Config::getAppValue('user_ldap', 'ldap_port', 389);
- self::$ldapAgentName = OCP\Config::getAppValue('user_ldap', 'ldap_dn','');
- self::$ldapAgentPassword = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password',''));
- self::$ldapBase = OCP\Config::getAppValue('user_ldap', 'ldap_base', '');
- self::$ldapBaseUsers = OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase);
- self::$ldapBaseGroups = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
- self::$ldapTLS = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0);
- self::$ldapNoCase = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0);
- self::$ldapUserDisplayName = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'), 'UTF-8');
- self::$ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
- self::$ldapLoginFilter = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)');
- self::$ldapGroupDisplayName = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8');
- self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
-
- if(empty(self::$ldapBaseUsers)) {
- OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO);
- self::$ldapBaseUsers = self::$ldapBase;
- }
- if(empty(self::$ldapBaseGroups)) {
- OCP\Util::writeLog('ldap', 'Base for Groups is empty, using Base DN', OCP\Util::INFO);
- self::$ldapBaseGroups = self::$ldapBase;
- }
-
- if(
- !empty(self::$ldapHost)
- && !empty(self::$ldapPort)
- && (
- (!empty(self::$ldapAgentName) && !empty(self::$ldapAgentPassword))
- || ( empty(self::$ldapAgentName) && empty(self::$ldapAgentPassword))
- )
- && !empty(self::$ldapBase)
- && !empty(self::$ldapUserDisplayName)
- )
- {
- self::$configured = true;
- }
- }
- }
-
- /**
- * Connects and Binds to LDAP
- */
- static private function establishConnection() {
- if(!self::$configured) {
- OCP\Util::writeLog('ldap', 'Configuration is invalid, cannot connect', OCP\Util::INFO);
- return false;
- }
- if(!self::$ldapConnectionRes) {
- self::$ldapConnectionRes = ldap_connect(self::$ldapHost, self::$ldapPort);
- if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
- if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
- if(self::$ldapTLS) {
- ldap_start_tls(self::$ldapConnectionRes);
- }
- }
- }
-
- $ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword );
- if(!$ldapLogin) {
- OCP\Util::writeLog('ldap', 'Bind failed: ' . ldap_errno(self::$ldapConnectionRes) . ': ' . ldap_error(self::$ldapConnectionRes), OCP\Util::ERROR);
- self::$ldapConnectionRes = null;
- return false;
- }
- }
- }
-
- static public function areCredentialsValid($name, $password) {
- return @ldap_bind(self::getConnectionResource(), $name, $password);
- }
-
- /**
- * 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;
- }
-
- }
diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php
index 2be6b46fb23..106459580fa 100644
--- a/apps/user_ldap/tests/group_ldap.php
+++ b/apps/user_ldap/tests/group_ldap.php
@@ -26,8 +26,8 @@ class Test_Group_Ldap extends UnitTestCase {
}
function testSingleBackend(){
- OC_Group::useBackend(new OC_GROUP_LDAP());
- $group_ldap = new OC_GROUP_LDAP();
+ OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP());
+ $group_ldap = new OCA\user_ldap\GROUP_LDAP();
$this->assertIsA(OC_Group::getGroups(),gettype(array()));
$this->assertIsA($group_ldap->getGroups(),gettype(array()));
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index b51d9a55cc7..a4a8921d08d 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -23,13 +23,9 @@
*
*/
-class OC_USER_LDAP extends OC_User_Backend {
+namespace OCA\user_ldap;
- // cached settings
- protected $ldapUserFilter;
- protected $ldapQuotaAttribute;
- protected $ldapQuotaDefault;
- protected $ldapEmailAttribute;
+class USER_LDAP extends lib\Access implements \OCP\UserInterface {
// will be retrieved from LDAP server
protected $ldap_dc = false;
@@ -37,39 +33,32 @@ class OC_USER_LDAP extends OC_User_Backend {
// 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', '');
- $this->ldapQuotaDefault = OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', '');
- $this->ldapEmailAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', '');
- }
-
private function updateQuota($dn) {
$quota = null;
- if(!empty($this->ldapQuotaDefault)) {
- $quota = $this->ldapQuotaDefault;
+ if(!empty($this->connection->ldapQuotaDefault)) {
+ $quota = $this->connection->ldapQuotaDefault;
}
- if(!empty($this->ldapQuotaAttribute)) {
- $aQuota = OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute);
+ if(!empty($this->connection->ldapQuotaAttribute)) {
+ $aQuota = $this->readAttribute($dn, $this->connection->ldapQuotaAttribute);
if($aQuota && (count($aQuota) > 0)) {
$quota = $aQuota[0];
}
}
if(!is_null($quota)) {
- OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'files', 'quota', OCP\Util::computerFileSize($quota));
+ \OCP\Config::setUserValue($this->dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota));
}
}
private function updateEmail($dn) {
$email = null;
- if(!empty($this->ldapEmailAttribute)) {
- $aEmail = OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute);
+ if(!empty($this->connection->ldapEmailAttribute)) {
+ $aEmail = $this->readAttribute($dn, $this->connection->ldapEmailAttribute);
if($aEmail && (count($aEmail) > 0)) {
$email = $aEmail[0];
}
- if(!is_null($email)){
- OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'settings', 'email', $email);
+ if(!is_null($email)) {
+ \OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email);
}
}
}
@@ -84,15 +73,15 @@ class OC_USER_LDAP extends OC_User_Backend {
*/
public function checkPassword($uid, $password){
//find out dn of the user name
- $filter = OCP\Util::mb_str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
- $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+ $filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8');
+ $ldap_users = $this->fetchListOfUsers($filter, 'dn');
if(count($ldap_users) < 1) {
return false;
}
$dn = $ldap_users[0];
//are the credentials OK?
- if(!OC_LDAP::areCredentialsValid($dn, $password)) {
+ if(!$this->areCredentialsValid($dn, $password)) {
return false;
}
@@ -101,7 +90,7 @@ class OC_USER_LDAP extends OC_User_Backend {
$this->updateEmail($dn);
//give back the display name
- return OC_LDAP::dn2username($dn);
+ return $this->dn2username($dn);
}
/**
@@ -112,8 +101,8 @@ class OC_USER_LDAP extends OC_User_Backend {
*/
public function getUsers(){
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);
+ $ldap_users = $this->fetchListOfUsers($this->connection->ldapUserFilter, array($this->connection->ldapUserDisplayName, 'dn'));
+ $this->_users = $this->ownCloudUserNames($ldap_users);
}
return $this->_users;
}
@@ -125,13 +114,13 @@ class OC_USER_LDAP extends OC_User_Backend {
*/
public function userExists($uid){
//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
- $dn = OC_LDAP::username2dn($uid);
+ $dn = $this->username2dn($uid);
if(!$dn) {
return false;
}
//if user really still exists, we will be able to read his cn
- $cn = OC_LDAP::readAttribute($dn, 'cn');
+ $cn = $this->readAttribute($dn, 'cn');
if(!$cn || empty($cn)) {
return false;
}
@@ -139,4 +128,27 @@ class OC_USER_LDAP extends OC_User_Backend {
return true;
}
+ /**
+ * @brief delete a user
+ * @param $uid The username of the user to delete
+ * @returns true/false
+ *
+ * Deletes a user
+ */
+ public function deleteUser($uid) {
+ return false;
+ }
+
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function implementsActions($actions) {
+ return (bool)(OC_USER_BACKEND_CHECK_PASSWORD & $actions);
+ }
+
} \ No newline at end of file
diff --git a/apps/user_migrate/appinfo/app.php b/apps/user_migrate/appinfo/app.php
index 9d314b59ce7..366c4004932 100644
--- a/apps/user_migrate/appinfo/app.php
+++ b/apps/user_migrate/appinfo/app.php
@@ -31,4 +31,3 @@ $entry = array(
'href' => OCP\Util::linkTo( "user_migrate", "admin.php" ),
'name' => 'Import'
);
-?>
diff --git a/apps/user_migrate/templates/settings.php b/apps/user_migrate/templates/settings.php
index 1718abe9e0f..bce5fb2d7ca 100644
--- a/apps/user_migrate/templates/settings.php
+++ b/apps/user_migrate/templates/settings.php
@@ -12,7 +12,7 @@
<?php } ?>
<legend><strong><?php echo $l->t('Import user account');?></strong></legend>
</p>
- <p><input type="file" id="owncloud_import" name="owncloud_import" style="width:180px;"><label for="owncloud_import"> <?php echo $l->t('ownCloud User Zip');?></label>
+ <p><input type="file" id="owncloud_import" name="owncloud_import" style="width:280px;"><label for="owncloud_import"> <?php echo $l->t('ownCloud User Zip');?></label>
</p>
<input type="submit" name="user_import" value="<?php echo $l->t('Import'); ?>" />
</fieldset>
diff --git a/apps/user_openid/user.php b/apps/user_openid/user.php
index 392424795f8..88571ba618e 100644
--- a/apps/user_openid/user.php
+++ b/apps/user_openid/user.php
@@ -44,7 +44,4 @@ if(!OCP\User::userExists($USERNAME)){
}
$IDENTITY=OCP\Util::linkToAbsolute( "user_openid", "user.php" ).'/'.$USERNAME;
-require_once 'phpmyid.php';
-
-
-?>
+require_once 'openid/phpmyid.php';
diff --git a/apps/user_openid/user_openid.php b/apps/user_openid/user_openid.php
index 70b193a30b1..19f2f719b06 100644
--- a/apps/user_openid/user_openid.php
+++ b/apps/user_openid/user_openid.php
@@ -21,7 +21,7 @@
*
*/
-require_once('class.openid.v3.php');
+require_once('openid/class.openid.v3.php');
/**
* Class for user OpenId backend
diff --git a/apps/user_webfinger/.htaccess b/apps/user_webfinger/.htaccess
new file mode 100644
index 00000000000..1b13cf788ff
--- /dev/null
+++ b/apps/user_webfinger/.htaccess
@@ -0,0 +1,5 @@
+<IfModule mod_rewrite.c>
+RewriteEngine on
+RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+RewriteRule ^host-meta host-meta.php [QSA,L]
+</IfModule>
diff --git a/apps/user_webfinger/appinfo/app.php b/apps/user_webfinger/appinfo/app.php
index 3336af66820..b3d9bbc7f37 100644
--- a/apps/user_webfinger/appinfo/app.php
+++ b/apps/user_webfinger/appinfo/app.php
@@ -1,3 +1 @@
<?php
-OCP\CONFIG::setAppValue('core', 'public_host-meta', '/apps/user_webfinger/host-meta.php');
-OCP\CONFIG::setAppValue('core', 'public_webfinger', '/apps/user_webfinger/webfinger.php');
diff --git a/apps/user_webfinger/appinfo/info.xml b/apps/user_webfinger/appinfo/info.xml
index 4e28814a26c..f74e5d3f93a 100644
--- a/apps/user_webfinger/appinfo/info.xml
+++ b/apps/user_webfinger/appinfo/info.xml
@@ -7,4 +7,8 @@
<author>Michiel de Jong, Florian Hülsmann</author>
<require>4</require>
<shipped>true</shipped>
+ <public>
+ <host-meta>host-meta.php</host-meta>
+ <webfinger>webfinger.php</webfinger>
+ </public>
</info>
diff --git a/apps/user_webfinger/appinfo/version b/apps/user_webfinger/appinfo/version
index 1d71ef97443..a2268e2de44 100644
--- a/apps/user_webfinger/appinfo/version
+++ b/apps/user_webfinger/appinfo/version
@@ -1 +1 @@
-0.3 \ No newline at end of file
+0.3.1 \ No newline at end of file
diff --git a/apps/user_webfinger/host-meta.php b/apps/user_webfinger/host-meta.php
index 32ffb512057..4ac37b1ea09 100644
--- a/apps/user_webfinger/host-meta.php
+++ b/apps/user_webfinger/host-meta.php
@@ -1,10 +1,27 @@
<?php
+
+if(class_exists('OC')){
+ $WEBROOT=OC::$WEBROOT;
+}else{//not called trough remote.php try to guess the webroot the best we can from here
+ // calculate the root directories
+ $SERVERROOT=str_replace("\\",'/',substr(__FILE__,0,-strlen('apps/user_webfinger/host-meta.php')));
+ $WEBROOT=substr($SERVERROOT,strlen(realpath($_SERVER['DOCUMENT_ROOT'])));
+
+ if($WEBROOT!='' and $WEBROOT[0]!=='/'){
+ $WEBROOT='/'.$WEBROOT;
+ }
+}
+
+if(substr($WEBROOT,-1)==='/'){
+ $WEBROOT=substr($WEBROOT,0,-1);
+}
+
$hostMetaHeader = array(
'Access-Control-Allow-Origin' => '*',
'Content-Type' => 'application/xrd+json'
);
$serverName = $_SERVER['SERVER_NAME'];
-$hostMetaContents = '{"links":[{"rel":"lrdd","template":"http'.(isset($_SERVER['HTTPS'])?'s':'').'://'.$serverName.'/public.php?service=webfinger&q={uri}"}]}';
+$hostMetaContents = '{"links":[{"rel":"lrdd","template":"http'.(isset($_SERVER['HTTPS'])?'s':'').'://'.$serverName.$WEBROOT.'/public.php?service=webfinger&q={uri}"}]}';
foreach($hostMetaHeader as $header => $value) {
header($header . ": " . $value);
}
diff --git a/apps/user_webfinger/webfinger.php b/apps/user_webfinger/webfinger.php
index 6b64a7e2860..e5b7f042d5a 100644
--- a/apps/user_webfinger/webfinger.php
+++ b/apps/user_webfinger/webfinger.php
@@ -58,4 +58,3 @@ foreach($apps as $app) {
}
}
echo "]}";
-?>
diff --git a/autotest.sh b/autotest.sh
new file mode 100755
index 00000000000..a42c6ab059e
--- /dev/null
+++ b/autotest.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+#
+# ownCloud
+#
+# @author Thomas Müller
+# @copyright 2012 Thomas Müller thomas.mueller@tmit.eu
+#
+
+DATADIR=data-autotest
+BASEDIR=$PWD
+
+# create autoconfig for sqlite, mysql and (soon) postgresql
+cat > ./tests/autoconfig-sqlite.php <<DELIM
+<?php
+\$AUTOCONFIG = array (
+ 'installed' => false,
+ 'dbtype' => 'sqlite',
+ 'dbtableprefix' => 'oc_',
+ 'adminlogin' => 'admin',
+ 'adminpass' => 'admin',
+ 'directory' => '$BASEDIR/$DATADIR',
+);
+DELIM
+
+cat > ./tests/autoconfig-mysql.php <<DELIM
+<?php
+\$AUTOCONFIG = array (
+ 'installed' => false,
+ 'dbtype' => 'mysql',
+ 'dbtableprefix' => 'oc_',
+ 'adminlogin' => 'admin',
+ 'adminpass' => 'admin',
+ 'directory' => '$BASEDIR/$DATADIR',
+ 'dbuser' => 'oc_autotest',
+ 'dbname' => 'oc_autotest',
+ 'dbhost' => 'localhost',
+ 'dbpass' => 'owncloud',
+);
+DELIM
+
+cat > ./tests/autoconfig-pgsql.php <<DELIM
+<?php
+\$AUTOCONFIG = array (
+ 'installed' => false,
+ 'dbtype' => 'pgsql',
+ 'dbtableprefix' => 'oc_',
+ 'adminlogin' => 'admin',
+ 'adminpass' => 'admin',
+ 'directory' => '$BASEDIR/$DATADIR',
+ 'dbuser' => 'oc_autotest',
+ 'dbname' => 'oc_autotest',
+ 'dbhost' => 'localhost',
+ 'dbpass' => 'owncloud',
+);
+DELIM
+
+function execute_tests {
+ echo "Setup environment for $1 testing ..."
+ # back to root folder
+ cd $BASEDIR
+
+ # revert changes to tests/data
+ git checkout tests/data/*
+
+ # reset data directory
+ rm -rf $DATADIR
+ mkdir $DATADIR
+
+ # remove the old config file
+ rm -rf config/config.php
+
+ # drop database
+ if [ "$1" == "mysql" ] ; then
+ mysql -u oc_autotest -powncloud -e "DROP DATABASE oc_autotest"
+ fi
+ if [ "$1" == "pgsql" ] ; then
+ dropdb -U oc_autotest oc_autotest
+ fi
+
+ # copy autoconfig
+ cp $BASEDIR/tests/autoconfig-$1.php $BASEDIR/config/autoconfig.php
+
+ # trigger installation
+ php -f index.php
+
+ #test execution
+ echo "Testing with $1 ..."
+ cd tests
+ php -f index.php -- xml $1 > autotest-results-$1.xml
+}
+
+#
+# start test execution
+#
+execute_tests "sqlite"
+execute_tests 'mysql'
+execute_tests 'pgsql'
+
+#
+# NOTES on mysql:
+# - CREATE USER 'oc_autotest'@'localhost' IDENTIFIED BY 'owncloud';
+# - grant access permissions: grant all on oc_autotest.* to 'oc_autotest'@'localhost';
+#
+# NOTES on pgsql:
+# - su - postgres
+# - createuser -P (enter username and password and enable superuser)
+# - to enable dropdb I decided to add following line to pg_hba.conf (this is not the safest way but I don't care for the testing machine):
+# local all all trust
+#
+
diff --git a/core/ajax/grouplist.php b/core/ajax/grouplist.php
index cc15102bbc3..e3e92fcfa16 100644
--- a/core/ajax/grouplist.php
+++ b/core/ajax/grouplist.php
@@ -45,5 +45,3 @@ foreach( OC_Group::getGroups() as $i ){
}
OC_JSON::encodedPrint($groups);
-
-?>
diff --git a/core/ajax/translations.php b/core/ajax/translations.php
index a6433b1964a..2bd6b7ed634 100644
--- a/core/ajax/translations.php
+++ b/core/ajax/translations.php
@@ -29,4 +29,3 @@ $app = $_POST["app"];
$l = OC_L10N::get( $app );
OC_JSON::success(array('data' => $l->getTranslations()));
-?>
diff --git a/core/ajax/userlist.php b/core/ajax/userlist.php
index c8168eaf460..85ca004ae66 100644
--- a/core/ajax/userlist.php
+++ b/core/ajax/userlist.php
@@ -44,5 +44,3 @@ foreach( OC_User::getUsers() as $i ){
}
OC_JSON::encodedPrint($users);
-
-?>
diff --git a/core/ajax/validateuser.php b/core/ajax/validateuser.php
index 258bd50fcad..78ec451fac2 100644
--- a/core/ajax/validateuser.php
+++ b/core/ajax/validateuser.php
@@ -36,5 +36,3 @@ if(!isset($_SERVER['PHP_AUTH_USER'])){
OC_JSON::encodedPrint(array("username" => $_SERVER["PHP_AUTH_USER"], "user_valid" => "false"));
}
}
-
-?>
diff --git a/core/ajax/vcategories/add.php b/core/ajax/vcategories/add.php
index a58489228d8..e69f8bb726b 100644
--- a/core/ajax/vcategories/add.php
+++ b/core/ajax/vcategories/add.php
@@ -39,5 +39,3 @@ if($categories->hasCategory($category)) {
}
OC_JSON::success(array('data' => array('categories'=>$categories->categories())));
-
-?>
diff --git a/core/ajax/vcategories/delete.php b/core/ajax/vcategories/delete.php
index 75def433d30..a41fa083c38 100644
--- a/core/ajax/vcategories/delete.php
+++ b/core/ajax/vcategories/delete.php
@@ -34,5 +34,3 @@ if(is_null($categories)) {
$vcategories = new OC_VCategories($app);
$vcategories->delete($categories);
OC_JSON::success(array('data' => array('categories'=>$vcategories->categories())));
-
-?>
diff --git a/core/ajax/vcategories/edit.php b/core/ajax/vcategories/edit.php
index 252b3d3454c..3e5540cbc22 100644
--- a/core/ajax/vcategories/edit.php
+++ b/core/ajax/vcategories/edit.php
@@ -31,5 +31,3 @@ $categories = $vcategories->categories();
debug(print_r($categories, true));
$tmpl->assign('categories',$categories);
$tmpl->printpage();
-
-?>
diff --git a/core/css/styles.css b/core/css/styles.css
index 338518e5b2f..b818caa279f 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -139,6 +139,8 @@ li.error { width:640px; margin:4em auto; padding:1em 1em 1em 4em; background:#ff
a.bookmarklet { background-color: #ddd; border:1px solid #ccc; padding: 5px;padding-top: 0px;padding-bottom: 2px; text-decoration: none; margin-top: 5px }
+.exception{color: #000000;}
+.exception textarea{width:95%;height: 200px;background:#ffe;border:0;}
/* ---- DIALOGS ---- */
#dirtree {width: 100%;}
diff --git a/core/js/eventsource.js b/core/js/eventsource.js
index 08259e02cae..e3ad7e3a671 100644
--- a/core/js/eventsource.js
+++ b/core/js/eventsource.js
@@ -40,6 +40,7 @@ OC.EventSource=function(src,data){
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
}
}
+ dataStr+='requesttoken='+OC.EventSource.requesttoken;
if(!this.useFallBack && typeof EventSource !='undefined'){
this.source=new EventSource(src+'?'+dataStr);
this.source.onmessage=function(e){
diff --git a/core/strings.php b/core/strings.php
index 8c3f64ef14f..01ab3866089 100644
--- a/core/strings.php
+++ b/core/strings.php
@@ -7,4 +7,3 @@ $l->t("Users");
$l->t("Apps");
$l->t("Admin");
$l->t("Help");
-?>
diff --git a/core/templates/exception.php b/core/templates/exception.php
new file mode 100644
index 00000000000..7f58ce252cf
--- /dev/null
+++ b/core/templates/exception.php
@@ -0,0 +1,30 @@
+<ul>
+ <li class='error'>
+ <details>
+ <summary class="error">We're sorry, but something went terribly wrong.<br></summary>
+ <p class="exception">
+ <?php
+ if($_['showsysinfo'] == true){
+ echo 'If you would like to support ownCloud\'s developers and report this error in our <a href="http://bugs.owncloud.org">Bugtracker</a>, please copy the following informations into the description. <br><br><textarea readonly>';
+ echo 'Message: ' . $_['message'] . "\n";
+ echo 'Error Code: ' . $_['code'] . "\n";
+ echo 'File: ' . $_['file'] . "\n";
+ echo 'Line: ' . $_['line'] . "\n\n";
+ echo 'PHP: ' . $_['sysinfo']['phpversion'] . "\n";
+ echo 'OS: ' . $_['sysinfo']['os'] . "\n";
+ echo 'OS Release: ' . $_['sysinfo']['osrelease'] . "\n";
+ echo 'OS Arch.: ' . $_['sysinfo']['osarchitecture'] . "\n";
+ echo 'PHP-Server-Interface: ' . $_['sysinfo']['phpserverinterface'] . "\n";
+ echo 'Protocol: ' . $_['sysinfo']['serverprotocol'] . "\n";
+ echo 'HTTPS: ' . $_['sysinfo']['https'] . "\n";
+ echo 'Request Method: ' . $_['sysinfo']['requestmethod'] . "\n";
+ echo 'Database: ' . $_['sysinfo']['database'] . "\n";
+ echo '</textarea>';
+ }else{
+ echo 'Your administrator has disabled systeminformations.';
+ }
+ ?>
+ </p>
+ </details>
+ </li>
+</ul> \ No newline at end of file
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 7e98fdedc2d..dc303ffc1a7 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -33,6 +33,7 @@
<script type="text/javascript">
$(function() {
requesttoken = '<?php echo $_['requesttoken']; ?>';
+ OC.EventSource.requesttoken=requesttoken;
$(document).bind('ajaxSend', function(elm, xhr, s){
if(requesttoken) {
xhr.setRequestHeader('requesttoken', requesttoken);
diff --git a/core/templates/login.php b/core/templates/login.php
index 985cf90c2a2..b35c4a33be8 100644
--- a/core/templates/login.php
+++ b/core/templates/login.php
@@ -7,7 +7,7 @@
<?php endif; ?>
<p class="infield">
<label for="user" class="infield"><?php echo $l->t( 'Username' ); ?></label>
- <input type="text" name="user" id="user" value="<?php echo !empty($_POST['user'])?OC_Util::sanitizeHTML($_POST['user'],ENT_COMPAT,'utf-8').'"':'" autofocus'; ?> autocomplete="off" required />
+ <input type="text" name="user" id="user" value="<?php echo !empty($_POST['user'])?OC_Util::sanitizeHTML($_POST['user'],ENT_COMPAT,'utf-8').'"':'" autofocus'; ?> autocomplete="on" required />
</p>
<p class="infield">
<label for="password" class="infield"><?php echo $l->t( 'Password' ); ?></label>
diff --git a/lib/MDB2/Driver/Function/sqlite3.php b/lib/MDB2/Driver/Function/sqlite3.php
index a013aea165a..1af262fd7a7 100644
--- a/lib/MDB2/Driver/Function/sqlite3.php
+++ b/lib/MDB2/Driver/Function/sqlite3.php
@@ -134,4 +134,3 @@ class MDB2_Driver_Function_sqlite3 extends MDB2_Driver_Function_Common
// }}}
}
-?>
diff --git a/lib/MDB2/Driver/Manager/sqlite3.php b/lib/MDB2/Driver/Manager/sqlite3.php
index 8f4e1312eb8..10255a3619a 100644
--- a/lib/MDB2/Driver/Manager/sqlite3.php
+++ b/lib/MDB2/Driver/Manager/sqlite3.php
@@ -1360,4 +1360,3 @@ class MDB2_Driver_Manager_sqlite3 extends MDB2_Driver_Manager_Common
// }}}
}
-?>
diff --git a/lib/MDB2/Driver/sqlite3.php b/lib/MDB2/Driver/sqlite3.php
index 39d3fb6727d..6bfccadad9a 100644
--- a/lib/MDB2/Driver/sqlite3.php
+++ b/lib/MDB2/Driver/sqlite3.php
@@ -1221,7 +1221,7 @@ class MDB2_Statement_sqlite3 extends MDB2_Statement_Common
return $affected_rows;
}
- $result =& $this->db->_wrapResult($result, $this->result_types,
+ $result = $this->db->_wrapResult($result, $this->result_types,
$result_class, $result_wrap_class, $this->limit, $this->offset);
$this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'post', 'result' => $result));
return $result;
@@ -1332,5 +1332,3 @@ class MDB2_Statement_sqlite3 extends MDB2_Statement_Common
$this->free();
}
}
-
-?>
diff --git a/lib/app.php b/lib/app.php
index 4c2c43ec26b..56132c08671 100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -27,7 +27,6 @@
* upgrading and removing apps.
*/
class OC_App{
- static private $init = false;
static private $activeapp = '';
static private $navigation = array();
static private $settingsForms = array();
@@ -196,7 +195,7 @@ class OC_App{
// check if the app is compatible with this version of ownCloud
$info=OC_App::getAppInfo($app);
$version=OC_Util::getVersion();
- if(!isset($info['require']) or ($version[0]>$info['require'])){
+ if(!isset($info['require']) or ($version[0]>$info['require'])){
OC_Log::write('core','App "'.$info['name'].'" can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR);
return false;
}else{
@@ -332,8 +331,8 @@ class OC_App{
}
/**
- * Get the path where to install apps
- */
+ * Get the path where to install apps
+ */
public static function getInstallPath() {
if(OC_Config::getValue('appstoreenabled', true)==false) {
return false;
@@ -608,7 +607,7 @@ class OC_App{
//set remote/public handelers
$appData=self::getAppInfo($appid);
foreach($appData['remote'] as $name=>$path){
- OCP\CONFIG::setAppValue('core', 'remote_'.$name, $path);
+ OCP\CONFIG::setAppValue('core', 'remote_'.$name, $appid.'/'.$path);
}
foreach($appData['public'] as $name=>$path){
OCP\CONFIG::setAppValue('core', 'public_'.$name, $appid.'/'.$path);
diff --git a/lib/archive/zip.php b/lib/archive/zip.php
index 6631a649b16..b2d6674d639 100644
--- a/lib/archive/zip.php
+++ b/lib/archive/zip.php
@@ -11,7 +11,6 @@ class OC_Archive_ZIP extends OC_Archive{
* @var ZipArchive zip
*/
private $zip=null;
- private $success=false;
private $path;
function __construct($source){
@@ -74,8 +73,7 @@ class OC_Archive_ZIP extends OC_Archive{
* @return int
*/
function mtime($path){
- $stat=$this->zip->statName($path);
- return $stat['mtime'];
+ return filemtime($this->path);
}
/**
* get the files in a folder
diff --git a/lib/base.php b/lib/base.php
index fe69ad70c0f..5041f43648e 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -83,9 +83,15 @@ class OC{
elseif(strpos($className,'OCP\\')===0){
require_once 'public/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php');
}
+ elseif(strpos($className,'OCA\\')===0){
+ require_once 'apps/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php');
+ }
elseif(strpos($className,'Sabre_')===0) {
require_once str_replace('_','/',$className) . '.php';
}
+ elseif(strpos($className,'Symfony\\')===0){
+ require_once str_replace('\\','/',$className) . '.php';
+ }
elseif(strpos($className,'Test_')===0){
require_once 'tests/lib/'.strtolower(str_replace('_','/',substr($className,5)) . '.php');
}
@@ -345,7 +351,7 @@ class OC{
$_SESSION['user_id'] = '';
}
- OC_User::useBackend( OC_Config::getValue( "userbackend", "database" ));
+ OC_User::useBackend(new OC_User_Database());
OC_Group::useBackend(new OC_Group_Database());
// Load Apps
diff --git a/lib/cache.php b/lib/cache.php
index 1f269174fad..55f189a5da8 100644
--- a/lib/cache.php
+++ b/lib/cache.php
@@ -7,48 +7,96 @@
*/
class OC_Cache {
+ /**
+ * @var OC_Cache $user_cache
+ */
static protected $user_cache;
+ /**
+ * @var OC_Cache $global_cache
+ */
static protected $global_cache;
+ /**
+ * @var OC_Cache $global_cache_fast
+ */
+ static protected $global_cache_fast;
+ /**
+ * @var OC_Cache $user_cache_fast
+ */
+ static protected $user_cache_fast;
+ static protected $isFast=null;
- static public function getGlobalCache() {
+ /**
+ * get the global cache
+ * @return OC_Cache
+ */
+ static public function getGlobalCache($fast=false) {
if (!self::$global_cache) {
- $fast_cache = null;
- if (!$fast_cache && function_exists('xcache_set')) {
- $fast_cache = new OC_Cache_XCache(true);
+ self::$global_cache_fast = null;
+ if (!self::$global_cache_fast && function_exists('xcache_set')) {
+ self::$global_cache_fast = new OC_Cache_XCache(true);
}
- if (!$fast_cache && function_exists('apc_store')) {
- $fast_cache = new OC_Cache_APC(true);
+ if (!self::$global_cache_fast && function_exists('apc_store')) {
+ self::$global_cache_fast = new OC_Cache_APC(true);
}
+
self::$global_cache = new OC_Cache_FileGlobal();
- if ($fast_cache) {
- self::$global_cache = new OC_Cache_Broker($fast_cache, self::$global_cache);
+ if (self::$global_cache_fast) {
+ self::$global_cache = new OC_Cache_Broker(self::$global_cache_fast, self::$global_cache);
+ }
+ }
+ if($fast){
+ if(self::$global_cache_fast){
+ return self::$global_cache_fast;
+ }else{
+ return false;
}
}
return self::$global_cache;
}
- static public function getUserCache() {
+ /**
+ * get the user cache
+ * @return OC_Cache
+ */
+ static public function getUserCache($fast=false) {
if (!self::$user_cache) {
- $fast_cache = null;
- if (!$fast_cache && function_exists('xcache_set')) {
- $fast_cache = new OC_Cache_XCache();
+ self::$user_cache_fast = null;
+ if (!self::$user_cache_fast && function_exists('xcache_set')) {
+ self::$user_cache_fast = new OC_Cache_XCache();
}
- if (!$fast_cache && function_exists('apc_store')) {
- $fast_cache = new OC_Cache_APC();
+ if (!self::$user_cache_fast && function_exists('apc_store')) {
+ self::$user_cache_fast = new OC_Cache_APC();
}
+
self::$user_cache = new OC_Cache_File();
- if ($fast_cache) {
- self::$user_cache = new OC_Cache_Broker($fast_cache, self::$user_cache);
+ if (self::$user_cache_fast) {
+ self::$user_cache = new OC_Cache_Broker(self::$user_cache_fast, self::$user_cache);
+ }
+ }
+
+ if($fast){
+ if(self::$user_cache_fast){
+ return self::$user_cache_fast;
+ }else{
+ return false;
}
}
return self::$user_cache;
}
+ /**
+ * get a value from the user cache
+ * @return mixed
+ */
static public function get($key) {
$user_cache = self::getUserCache();
return $user_cache->get($key);
}
+ /**
+ * set a value in the user cache
+ * @return bool
+ */
static public function set($key, $value, $ttl=0) {
if (empty($key)) {
return false;
@@ -57,19 +105,43 @@ class OC_Cache {
return $user_cache->set($key, $value, $ttl);
}
+ /**
+ * check if a value is set in the user cache
+ * @return bool
+ */
static public function hasKey($key) {
$user_cache = self::getUserCache();
return $user_cache->hasKey($key);
}
+ /**
+ * remove an item from the user cache
+ * @return bool
+ */
static public function remove($key) {
$user_cache = self::getUserCache();
return $user_cache->remove($key);
}
- static public function clear() {
+ /**
+ * clear the user cache of all entries starting with a prefix
+ * @param string prefix (optional)
+ * @return bool
+ */
+ static public function clear($prefix='') {
$user_cache = self::getUserCache();
- return $user_cache->clear();
+ return $user_cache->clear($prefix);
+ }
+
+ /**
+ * check if a fast memory based cache is available
+ * @return true
+ */
+ static public function isFast() {
+ if(is_null(self::$isFast)){
+ self::$isFast=function_exists('xcache_set') || function_exists('apc_store');
+ }
+ return self::$isFast;
}
}
diff --git a/lib/cache/apc.php b/lib/cache/apc.php
index 6cf47d0c158..c192fe2f196 100644
--- a/lib/cache/apc.php
+++ b/lib/cache/apc.php
@@ -43,14 +43,15 @@ class OC_Cache_APC {
return apc_delete($this->getNamespace().$key);
}
- public function clear(){
- $ns = $this->getNamespace();
+ public function clear($prefix=''){
+ $ns = $this->getNamespace().$prefix;
$cache = apc_cache_info('user');
foreach($cache['cache_list'] as $entry) {
if (strpos($entry['info'], $ns) === 0) {
apc_delete($entry['info']);
}
}
+ return true;
}
}
if(!function_exists('apc_exists')) {
diff --git a/lib/cache/broker.php b/lib/cache/broker.php
index 931d0dd407e..c2aceabaf53 100644
--- a/lib/cache/broker.php
+++ b/lib/cache/broker.php
@@ -46,8 +46,8 @@ class OC_Cache_Broker {
return $this->slow_cache->remove($key);
}
- public function clear(){
- $this->fast_cache->clear();
- $this->slow_cache->clear();
+ public function clear($prefix=''){
+ $this->fast_cache->clear($prefix);
+ $this->slow_cache->clear($prefix);
}
}
diff --git a/lib/cache/file.php b/lib/cache/file.php
index 0b7d3e30508..562c3d17167 100644
--- a/lib/cache/file.php
+++ b/lib/cache/file.php
@@ -62,15 +62,16 @@ class OC_Cache_File{
return $storage->unlink($key);
}
- public function clear(){
+ public function clear($prefix=''){
$storage = $this->getStorage();
if($storage and $storage->is_dir('/')){
$dh=$storage->opendir('/');
while($file=readdir($dh)){
- if($file!='.' and $file!='..'){
+ if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)){
$storage->unlink('/'.$file);
}
}
}
+ return true;
}
}
diff --git a/lib/cache/xcache.php b/lib/cache/xcache.php
index bd55cee8f6b..951f9b47545 100644
--- a/lib/cache/xcache.php
+++ b/lib/cache/xcache.php
@@ -43,7 +43,8 @@ class OC_Cache_XCache {
return xcache_unset($this->getNamespace().$key);
}
- public function clear(){
- return xcache_unset_by_prefix($this->getNamespace());
+ public function clear($prefix=''){
+ xcache_unset_by_prefix($this->getNamespace().$prefix);
+ return true;
}
}
diff --git a/lib/connector/sabre/auth.php b/lib/connector/sabre/auth.php
index ee680391626..99f696e3a07 100644
--- a/lib/connector/sabre/auth.php
+++ b/lib/connector/sabre/auth.php
@@ -31,13 +31,18 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic {
* @return bool
*/
protected function validateUserPass($username, $password){
- OC_Util::setUpFS();//login hooks may need early access to the filesystem
- if(OC_User::login($username,$password)){
- OC_Util::setUpFS($username);
+ if (OC_User::isLoggedIn()) {
+ OC_Util::setupFS($username);
return true;
- }
- else{
- return false;
+ } else {
+ OC_Util::setUpFS();//login hooks may need early access to the filesystem
+ if(OC_User::login($username,$password)){
+ OC_Util::setUpFS($username);
+ return true;
+ }
+ else{
+ return false;
+ }
}
}
}
diff --git a/lib/connector/sabre/client.php b/lib/connector/sabre/client.php
index b799b541a05..7e8f21264f9 100644
--- a/lib/connector/sabre/client.php
+++ b/lib/connector/sabre/client.php
@@ -23,29 +23,18 @@
class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
- protected $curlSettings;
-
- public function __construct(array $settings) {
- //set default curl settings
- $this->curlSettings = array(
- CURLOPT_RETURNTRANSFER => true,
- // Return headers as part of the response
- CURLOPT_HEADER => true,
- // Automatically follow redirects
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_MAXREDIRS => 5,
- CURLOPT_SSL_VERIFYPEER => true,
- //CURLOPT_SSL_VERIFYPEER => false,
- );
- parent::__construct($settings);
- }
-
- public function setCurlSettings($settings) {
- if (is_array($settings)) {
- foreach ($settings as $k => $v) {
- $this->curlSettings[$k] = $v;
- }
- }
+ protected $trustedCertificates;
+
+ /**
+ * Add trusted root certificates to the webdav client.
+ *
+ * The parameter certificates should be a absulute path to a file which contains
+ * all trusted certificates
+ *
+ * @param string $certificates
+ */
+ public function addTrustedCertificates($certificates) {
+ $this->trustedCertificates = $certificates;
}
/**
@@ -68,14 +57,24 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
* @return array
*/
public function request($method, $url = '', $body = null, $headers = array()) {
-
- $this->curlSettings[CURLOPT_POSTFIELDS] = $body;
+
$url = $this->getAbsoluteUrl($url);
+ $curlSettings = array(
+ CURLOPT_RETURNTRANSFER => true,
+ // Return headers as part of the response
+ CURLOPT_HEADER => true,
+ CURLOPT_POSTFIELDS => $body,
+ // Automatically follow redirects
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_MAXREDIRS => 5,
+ );
+
+ if($this->trustedCertificates) {
+ $curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates;
+ }
+
switch ($method) {
- case 'PUT':
- $this->curlSettings[CURLOPT_PUT] = true;
- break;
case 'HEAD' :
// do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
@@ -83,12 +82,12 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
// specs...) cURL does unfortunately return an error in this case ("transfer closed transfer closed with
// ... bytes remaining to read") this can be circumvented by explicitly telling cURL to ignore the
// response body
- $this->curlSettings[CURLOPT_NOBODY] = true;
- $this->curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
+ $curlSettings[CURLOPT_NOBODY] = true;
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = 'HEAD';
break;
default:
- $this->curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
+ $curlSettings[CURLOPT_CUSTOMREQUEST] = $method;
break;
}
@@ -100,15 +99,22 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
$nHeaders[] = $key . ': ' . $value;
}
- $this->curlSettings[CURLOPT_HTTPHEADER] = $nHeaders;
+ $curlSettings[CURLOPT_HTTPHEADER] = $nHeaders;
if ($this->proxy) {
- $this->curlSettings[CURLOPT_PROXY] = $this->proxy;
+ $curlSettings[CURLOPT_PROXY] = $this->proxy;
}
- if ($this->userName) {
- $this->curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST;
- $this->curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
+ if ($this->userName && $this->authType) {
+ $curlType = 0;
+ if ($this->authType & self::AUTH_BASIC) {
+ $curlType |= CURLAUTH_BASIC;
+ }
+ if ($this->authType & self::AUTH_DIGEST) {
+ $curlType |= CURLAUTH_DIGEST;
+ }
+ $curlSettings[CURLOPT_HTTPAUTH] = $curlType;
+ $curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
}
list(
@@ -116,7 +122,7 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
$curlInfo,
$curlErrNo,
$curlError
- ) = $this->curlRequest($url, $this->curlSettings);
+ ) = $this->curlRequest($url, $curlSettings);
$headerBlob = substr($response, 0, $curlInfo['header_size']);
$response = substr($response, $curlInfo['header_size']);
@@ -163,6 +169,5 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client {
return $response;
- }
-
+ }
} \ No newline at end of file
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php
index b75bb5c50f5..0842fc4fc65 100644
--- a/lib/connector/sabre/directory.php
+++ b/lib/connector/sabre/directory.php
@@ -26,17 +26,33 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
/**
* Creates a new file in the directory
*
- * data is a readable stream resource
+ * Data will either be supplied as a stream resource, or in certain cases
+ * as a string. Keep in mind that you may have to support either.
+ *
+ * After succesful creation of the file, you may choose to return the ETag
+ * of the new file here.
+ *
+ * The returned ETag must be surrounded by double-quotes (The quotes should
+ * be part of the actual string).
+ *
+ * If you cannot accurately determine the ETag, you should not return it.
+ * If you don't store the file exactly as-is (you're transforming it
+ * somehow) you should also not return an ETag.
+ *
+ * This means that if a subsequent GET to this new file does not exactly
+ * return the same contents of what was submitted here, you are strongly
+ * recommended to omit the ETag.
*
* @param string $name Name of the file
- * @param resource $data Initial payload
- * @return void
+ * @param resource|string $data Initial payload
+ * @return null|string
*/
public function createFile($name, $data = null) {
$newPath = $this->path . '/' . $name;
OC_Filesystem::file_put_contents($newPath,$data);
+ return OC_Connector_Sabre_Node::getETagPropertyForFile($newPath);
}
/**
@@ -146,7 +162,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
* @return array
*/
public function getQuotaInfo() {
- $rootInfo=OC_FileCache::get('');
+ $rootInfo=OC_FileCache_Cached::get('');
return array(
$rootInfo['size'],
OC_Filesystem::free_space()
diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php
index dd25df78c29..80f0a0ab4d8 100644
--- a/lib/connector/sabre/file.php
+++ b/lib/connector/sabre/file.php
@@ -26,13 +26,28 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
/**
* Updates the data
*
+ * The data argument is a readable stream resource.
+ *
+ * After a succesful put operation, you may choose to return an ETag. The
+ * etag must always be surrounded by double-quotes. These quotes must
+ * appear in the actual string you're returning.
+ *
+ * Clients may use the ETag from a PUT request to later on make sure that
+ * when they update the file, the contents haven't changed in the mean
+ * time.
+ *
+ * If you don't plan to store the file byte-by-byte, and you return a
+ * different object on a subsequent GET you are strongly recommended to not
+ * return an ETag, and just return null.
+ *
* @param resource $data
- * @return void
+ * @return string|null
*/
public function put($data) {
OC_Filesystem::file_put_contents($this->path,$data);
+ return OC_Connector_Sabre_Node::getETagPropertyForFile($this->path);
}
/**
@@ -42,7 +57,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
*/
public function get() {
- return OC_Filesystem::fopen($this->path,'r');
+ return OC_Filesystem::fopen($this->path,'rb');
}
@@ -79,9 +94,11 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
* @return mixed
*/
public function getETag() {
-
- return null;
-
+ $properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME));
+ if (isset($properties[self::GETETAG_PROPERTYNAME])) {
+ return $properties[self::GETETAG_PROPERTYNAME];
+ }
+ return $this->getETagPropertyForFile($this->path);
}
/**
diff --git a/lib/connector/sabre/locks.php b/lib/connector/sabre/locks.php
index 94382e68a1a..e95dcf02d27 100644
--- a/lib/connector/sabre/locks.php
+++ b/lib/connector/sabre/locks.php
@@ -108,7 +108,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract {
$locks = $this->getLocks($uri,false);
$exists = false;
- foreach($locks as $k=>$lock) {
+ foreach($locks as $lock) {
if ($lock->token == $lockInfo->token) $exists = true;
}
diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php
index be315a0ffd9..663970487fb 100644
--- a/lib/connector/sabre/node.php
+++ b/lib/connector/sabre/node.php
@@ -22,6 +22,7 @@
*/
abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
+ const GETETAG_PROPERTYNAME = '{DAV:}getetag';
/**
* The path to the current node
@@ -141,6 +142,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
public function updateProperties($properties) {
$existing = $this->getProperties(array());
foreach($properties as $propertyName => $propertyValue) {
+ $propertyName = preg_replace("/^{.*}/", "", $propertyName); // remove leading namespace from property name
// If it was null, we need to delete the property
if (is_null($propertyValue)) {
if(array_key_exists( $propertyName, $existing )){
@@ -178,7 +180,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* @param array $properties
* @return void
*/
- function getProperties($properties) {
+ public function getProperties($properties) {
if (is_null($this->property_cache)) {
$query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' );
$result = $query->execute( array( OC_User::getUser(), $this->path ));
@@ -200,4 +202,29 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
}
return $props;
}
+
+ /**
+ * Returns the ETag surrounded by double-quotes for this path.
+ * @param string $path Path of the file
+ * @return string|null Returns null if the ETag can not effectively be determined
+ */
+ static public function getETagPropertyForFile($path) {
+ $tag = OC_Filesystem::hash('md5', $path);
+ if (empty($tag)) {
+ return null;
+ }
+ $etag = '"'.$tag.'"';
+ $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' );
+ $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag ));
+ return $etag;
+ }
+
+ /**
+ * Remove the ETag from the cache.
+ * @param string $path Path of the file
+ */
+ static public function removeETagPropertyForFile($path) {
+ $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' );
+ $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME ));
+ }
}
diff --git a/lib/db.php b/lib/db.php
index 2a06d72ea32..6971fe4a583 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -33,8 +33,6 @@ class OC_DB {
static private $MDB2=false;
static private $PDO=false;
static private $schema=false;
- static private $affected=0;
- static private $result=false;
static private $inTransaction=false;
static private $prefix=null;
static private $type=null;
@@ -222,7 +220,7 @@ class OC_DB {
echo( '<b>can not connect to database, using '.$type.'. ('.self::$MDB2->getUserInfo().')</center>');
OC_Log::write('core',self::$MDB2->getUserInfo(),OC_Log::FATAL);
OC_Log::write('core',self::$MDB2->getMessage(),OC_Log::FATAL);
- die( $error );
+ die();
}
// We always, really always want associative arrays
@@ -370,9 +368,6 @@ class OC_DB {
if( $definition instanceof MDB2_Schema_Error ){
die( $definition->getMessage().': '.$definition->getUserInfo());
}
-// if(OC_Config::getValue('dbtype','sqlite')=='sqlite'){
-// $definition['overwrite']=true;//always overwrite for sqlite
-// }
$ret=self::$schema->createDatabase( $definition );
// Die in case something went wrong
@@ -519,8 +514,9 @@ class OC_DB {
// Delete our temporary file
unlink( $file2 );
- foreach($definition['tables'] as $name=>$table){
- self::dropTable($name);
+ $tables=array_keys($definition['tables']);
+ foreach($tables as $table){
+ self::dropTable($table);
}
}
@@ -528,8 +524,7 @@ class OC_DB {
* @brief replaces the owncloud tables with a new set
* @param $file string path to the MDB2 xml db export file
*/
- public static function replaceDB( $file ){
-
+ public static function replaceDB( $file ){
$apps = OC_App::getAllApps();
self::beginTransaction();
// Delete the old tables
diff --git a/lib/eventsource.php b/lib/eventsource.php
index cf10660b94c..95af2e471bc 100644
--- a/lib/eventsource.php
+++ b/lib/eventsource.php
@@ -36,12 +36,15 @@ class OC_EventSource{
header('Cache-Control: no-cache');
$this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true';
if($this->fallback){
- $fallBackId=$_GET['fallback_id'];
+ $this->fallBackId=$_GET['fallback_id'];
header("Content-Type: text/html");
echo str_repeat('<span></span>'.PHP_EOL,10); //dummy data to keep IE happy
}else{
header("Content-Type: text/event-stream");
}
+ if( !OC_Util::isCallRegistered()){
+ exit();
+ }
flush();
}
diff --git a/lib/exception.php b/lib/exception.php
new file mode 100644
index 00000000000..db516fc12d2
--- /dev/null
+++ b/lib/exception.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Georg Ehrke
+ * @copyright 2012 georg@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+class OC_Exception extends Exception{
+
+ function __construct($message = null, $code = 0, $file = null, $line = null){
+ parent::__construct($message, $code);
+ if(!is_null($file)){
+ $this->file = $file;
+ }
+ if(!is_null($line)){
+ $this->line = $line;
+ }
+ $this->writelog();
+ }
+
+ private function writelog(){
+ @OC_Log::write(OC_App::getCurrentApp(), $this->getMessage() . '-' . $this->getFile() . '-' . $this->getLine(), OC_Log::FATAL);
+ }
+
+ private function generatesysinfo(){
+ return array('phpversion' => PHP_VERSION,
+ 'os' => php_uname('s'),
+ 'osrelease' => php_uname('r'),
+ 'osarchitecture' => php_uname('m'),
+ 'phpserverinterface' => php_sapi_name(),
+ 'serverprotocol' => $_SERVER['SERVER_PROTOCOL'],
+ 'requestmethod' => $_SERVER['REQUEST_METHOD'],
+ 'https' => ($_SERVER['HTTPS']==''?'false':'true'),
+ 'database'=>(@OC_Config::getValue('dbtype')!=''?@OC_Config::getValue('dbtype'):'')
+ );
+ }
+
+ function __toString(){
+ $tmpl = new OC_Template('core', 'exception', 'guest');
+ $tmpl->assign('showsysinfo', true);
+ $tmpl->assign('message', $this->getMessage());
+ $tmpl->assign('code', $this->getCode());
+ $tmpl->assign('file', $this->getFile());
+ $tmpl->assign('line', $this->getLine());
+ $tmpl->assign('sysinfo', $this->generatesysinfo());
+ $tmpl->printPage();
+ }
+}
+
+function oc_exceptionhandler($exception){
+ switch($exception->getCode()){
+ case E_NOTICE:
+ case E_DEPRECATED:
+ case E_USER_NOTICE:
+ case E_USER_DEPRECATED:
+ break;
+ default:
+ throw new OC_Exception($exception->getMessage(), $exception->getCode(), $exception->getFile(), $exception->getLine());
+ break;
+ }
+ return true;
+}
+
+function oc_errorhandler($errno , $errstr , $errfile , $errline){
+ switch($errno){
+ case E_NOTICE:
+ case E_DEPRECATED:
+ case E_USER_NOTICE:
+ case E_USER_DEPRECATED:
+ break;
+ default:
+ throw new OC_Exception($errstr, $errno, $errfile, $errline);
+ break;
+ }
+ return true;
+}
+set_exception_handler('oc_exceptionhandler');
+set_error_handler('oc_errorhandler');
+error_reporting(E_ERROR | E_WARNING | E_PARSE); \ No newline at end of file
diff --git a/lib/filecache.php b/lib/filecache.php
index d956f34dc48..22f7427ae42 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -98,6 +98,10 @@ class OC_FileCache{
if(OC_DB::isError($result)){
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
}
+
+ if($cache=OC_Cache::getUserCache(true)){
+ $cache->remove('fileid/'.$path);//ensure we don't have -1 cached
+ }
}
/**
@@ -126,7 +130,7 @@ class OC_FileCache{
$query=OC_DB::prepare($sql);
$result=$query->execute($arguments);
if(OC_DB::isError($result)){
- OC_Log::write('files','error while updating file('.$path.') in cache',OC_Log::ERROR);
+ OC_Log::write('files','error while updating file('.$id.') in cache',OC_Log::ERROR);
}
}
@@ -146,6 +150,11 @@ class OC_FileCache{
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=?, path_hash=? WHERE path_hash=?');
$query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath)));
+ if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$oldPath)){
+ $cache->set('fileid/'.$newPath,$cache->get('fileid/'.$oldPath));
+ $cache->remove('fileid/'.$oldPath);
+ }
+
$query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE path LIKE ?');
$oldLength=strlen($oldPath);
$updateQuery=OC_DB::prepare('UPDATE *PREFIX*fscache SET path=?, path_hash=? WHERE path_hash=?');
@@ -153,6 +162,11 @@ class OC_FileCache{
$old=$row['path'];
$new=$newPath.substr($old,$oldLength);
$updateQuery->execute(array($new,md5($new),md5($old)));
+
+ if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$old)){
+ $cache->set('fileid/'.$new,$cache->get('fileid/'.$old));
+ $cache->remove('fileid/'.$old);
+ }
}
}
@@ -171,6 +185,8 @@ class OC_FileCache{
//delete everything inside the folder
$query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE path LIKE ?');
$query->execute(array($root.$path.'/%'));
+
+ OC_Cache::remove('fileid/'.$root.$path);
}
/**
@@ -245,9 +261,14 @@ class OC_FileCache{
if($root===false){
$root=OC_Filesystem::getRoot();
}
+
+ $fullPath=$root.$path;
+ if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$fullPath)){
+ return $cache->get('fileid/'.$fullPath);
+ }
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?');
- $result=$query->execute(array(md5($root.$path)));
+ $result=$query->execute(array(md5($fullPath)));
if(OC_DB::isError($result)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
@@ -255,10 +276,15 @@ class OC_FileCache{
$result=$result->fetchRow();
if(is_array($result)){
- return $result['id'];
+ $id=$result['id'];
}else{
- return -1;
+ $id=-1;
}
+ if($cache=OC_Cache::getUserCache(true)){
+ $cache->set('fileid/'.$fullPath,$id);
+ }
+
+ return $id;
}
/**
@@ -303,7 +329,7 @@ class OC_FileCache{
*/
public static function increaseSize($path,$sizeDiff, $root=false){
if($sizeDiff==0) return;
- $id=self::getId($path,'');
+ $id=self::getId($path,$root);
while($id!=-1){//walk up the filetree increasing the size of all parent folders
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET size=size+? WHERE id=?');
$query->execute(array($sizeDiff,$id));
diff --git a/lib/filecache/update.php b/lib/filecache/update.php
index dd77f491ca0..93b632acb4e 100644
--- a/lib/filecache/update.php
+++ b/lib/filecache/update.php
@@ -207,7 +207,6 @@ class OC_FileCache_Update{
$cached=OC_FileCache_Cached::get($oldPath,$root);
$oldSize=$cached['size'];
- $size=$view->filesize($newPath);
OC_FileCache::increaseSize(dirname($oldPath),-$oldSize,$root);
OC_FileCache::increaseSize(dirname($newPath),$oldSize,$root);
OC_FileCache::move($oldPath,$newPath);
diff --git a/lib/filestorage.php b/lib/filestorage.php
index 71ef4aed00b..e786127d525 100644
--- a/lib/filestorage.php
+++ b/lib/filestorage.php
@@ -24,7 +24,7 @@
* Provde a common interface to all different storage options
*/
abstract class OC_Filestorage{
- public function __construct($parameters){}
+ abstract public function __construct($parameters);
abstract public function mkdir($path);
abstract public function rmdir($path);
abstract public function opendir($path);
diff --git a/lib/filestorage/common.php b/lib/filestorage/common.php
index ba78fca80e5..fd389d3e2d7 100644
--- a/lib/filestorage/common.php
+++ b/lib/filestorage/common.php
@@ -220,7 +220,7 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
}
$tmpFile=OC_Helper::tmpFile($extension);
$target=fopen($tmpFile,'w');
- $count=OC_Helper::streamCopy($source,$target);
+ OC_Helper::streamCopy($source,$target);
return $tmpFile;
}
// abstract public function touch($path, $mtime=null);
diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php
index b2eba051515..d60f32b15be 100644
--- a/lib/filestorage/local.php
+++ b/lib/filestorage/local.php
@@ -4,7 +4,6 @@
*/
class OC_Filestorage_Local extends OC_Filestorage_Common{
protected $datadir;
- private static $mimetypes=null;
public function __construct($arguments){
$this->datadir=$arguments['datadir'];
if(substr($this->datadir,-1)!=='/'){
@@ -41,7 +40,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
}
public function filesize($path){
if($this->is_dir($path)){
- return $this->getFolderSize($path);
+ return 0;
}else{
return filesize($this->datadir.$path);
}
@@ -157,7 +156,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
return $return;
}
- public function hash($type,$path,$raw){
+ public function hash($path,$type,$raw=false){
return hash_file($type,$this->datadir.$path,$raw);
}
@@ -187,15 +186,6 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{
}
/**
- * @brief get the size of folder and it's content
- * @param string $path file path
- * @return int size of folder and it's content
- */
- public function getFolderSize($path){
- return 0;//depricated, use OC_FileCach instead
- }
-
- /**
* check if a file or folder has been updated since $time
* @param int $time
* @return bool
diff --git a/lib/filesystem.php b/lib/filesystem.php
index 65318fa3ab6..a5edcf5bab3 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -46,105 +46,106 @@
class OC_Filesystem{
static private $storages=array();
static private $mounts=array();
- static private $storageTypes=array();
public static $loaded=false;
- private $fakeRoot='';
+ /**
+ * @var OC_Filestorage $defaultInstance
+ */
static private $defaultInstance;
- /**
- * classname which used for hooks handling
- * used as signalclass in OC_Hooks::emit()
- */
- const CLASSNAME = 'OC_Filesystem';
-
- /**
- * signalname emited before file renaming
- * @param oldpath
- * @param newpath
- */
- const signal_rename = 'rename';
-
- /**
- * signal emited after file renaming
- * @param oldpath
- * @param newpath
- */
- const signal_post_rename = 'post_rename';
-
- /**
- * signal emited before file/dir creation
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_create = 'create';
-
- /**
- * signal emited after file/dir creation
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_post_create = 'post_create';
-
- /**
- * signal emits before file/dir copy
- * @param oldpath
- * @param newpath
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_copy = 'copy';
-
- /**
- * signal emits after file/dir copy
- * @param oldpath
- * @param newpath
- */
- const signal_post_copy = 'post_copy';
-
- /**
- * signal emits before file/dir save
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_write = 'write';
-
- /**
- * signal emits after file/dir save
- * @param path
- */
- const signal_post_write = 'post_write';
-
- /**
- * signal emits when reading file/dir
- * @param path
- */
- const signal_read = 'read';
-
- /**
- * signal emits when removing file/dir
- * @param path
- */
- const signal_delete = 'delete';
-
- /**
- * parameters definitions for signals
- */
- const signal_param_path = 'path';
- const signal_param_oldpath = 'oldpath';
- const signal_param_newpath = 'newpath';
-
- /**
- * run - changing this flag to false in hook handler will cancel event
- */
- const signal_param_run = 'run';
-
- /**
- * get the mountpoint of the storage object for a path
- ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
- *
- * @param string path
- * @return string
- */
+ /**
+ * classname which used for hooks handling
+ * used as signalclass in OC_Hooks::emit()
+ */
+ const CLASSNAME = 'OC_Filesystem';
+
+ /**
+ * signalname emited before file renaming
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_rename = 'rename';
+
+ /**
+ * signal emited after file renaming
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_rename = 'post_rename';
+
+ /**
+ * signal emited before file/dir creation
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_create = 'create';
+
+ /**
+ * signal emited after file/dir creation
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_post_create = 'post_create';
+
+ /**
+ * signal emits before file/dir copy
+ * @param oldpath
+ * @param newpath
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_copy = 'copy';
+
+ /**
+ * signal emits after file/dir copy
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_copy = 'post_copy';
+
+ /**
+ * signal emits before file/dir save
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_write = 'write';
+
+ /**
+ * signal emits after file/dir save
+ * @param path
+ */
+ const signal_post_write = 'post_write';
+
+ /**
+ * signal emits when reading file/dir
+ * @param path
+ */
+ const signal_read = 'read';
+
+ /**
+ * signal emits when removing file/dir
+ * @param path
+ */
+ const signal_delete = 'delete';
+
+ /**
+ * parameters definitions for signals
+ */
+ const signal_param_path = 'path';
+ const signal_param_oldpath = 'oldpath';
+ const signal_param_newpath = 'newpath';
+
+ /**
+ * run - changing this flag to false in hook handler will cancel event
+ */
+ const signal_param_run = 'run';
+
+ /**
+ * get the mountpoint of the storage object for a path
+ ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
+ *
+ * @param string path
+ * @return string
+ */
static public function getMountPoint($path){
OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path));
if(!$path){
@@ -155,7 +156,8 @@ class OC_Filesystem{
}
$path=str_replace('//', '/',$path);
$foundMountPoint='';
- foreach(OC_Filesystem::$mounts as $mountpoint=>$storage){
+ $mountPoints=array_keys(OC_Filesystem::$mounts);
+ foreach($mountPoints as $mountpoint){
if($mountpoint==$path){
return $mountpoint;
}
@@ -260,10 +262,7 @@ class OC_Filesystem{
* tear down the filesystem, removing all storage providers
*/
static public function tearDown(){
- foreach(self::$storages as $mountpoint=>$storage){
- unset(self::$storages[$mountpoint]);
- }
- $fakeRoot='';
+ self::$storages=array();
}
/**
@@ -287,7 +286,7 @@ class OC_Filesystem{
* @return bool
*/
static public function chroot($fakeRoot){
- return self::$defaultInstance->chroot($path);
+ return self::$defaultInstance->chroot($fakeRoot);
}
/**
@@ -320,22 +319,8 @@ class OC_Filesystem{
if(substr($mountpoint,-1)!=='/'){
$mountpoint=$mountpoint.'/';
}
- if (self::getView() != null && $mountpoint != '/' && !self::is_dir(basename($mountpoint))) {
- self::mkdir(basename($mountpoint));
- }
self::$mounts[$mountpoint]=array('class'=>$class,'arguments'=>$arguments);
}
-
- /**
- * create all storage backends mounted in the filesystem
- */
- static private function mountAll(){
- foreach(self::$mounts as $mountPoint=>$mount){
- if(!isset(self::$storages[$mountPoint])){
- self::$storages[$mountPoint]=self::createStorage($mount['type'],$mount['arguments']);
- }
- }
- }
/**
* return the path to a local version of the file
@@ -485,9 +470,17 @@ class OC_Filesystem{
* @return bool
*/
static public function hasUpdated($path,$time){
- return self::$defaultInstance->hasUpdated($path);
+ return self::$defaultInstance->hasUpdated($path,$time);
+ }
+
+ static public function removeETagHook($params) {
+ $path=$params['path'];
+ OC_Connector_Sabre_Node::removeETagPropertyForFile($path);
}
}
+OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook');
+OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook');
+OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook');
OC_Util::setupFS();
require_once('filecache.php');
diff --git a/lib/filesystemview.php b/lib/filesystemview.php
index 448663bb081..9beda01e5a1 100644
--- a/lib/filesystemview.php
+++ b/lib/filesystemview.php
@@ -22,19 +22,19 @@
/**
- * Class to provide access to ownCloud filesystem via a "view", and methods for
- * working with files within that view (e.g. read, write, delete, etc.). Each
- * view is restricted to a set of directories via a virtual root. The default view
- * uses the currently logged in user's data directory as root (parts of
+ * Class to provide access to ownCloud filesystem via a "view", and methods for
+ * working with files within that view (e.g. read, write, delete, etc.). Each
+ * view is restricted to a set of directories via a virtual root. The default view
+ * uses the currently logged in user's data directory as root (parts of
* OC_Filesystem are merely a wrapper for OC_FilesystemView).
- *
+ *
* Apps that need to access files outside of the user data folders (to modify files
* belonging to a user other than the one currently logged in, for example) should
* use this class directly rather than using OC_Filesystem, or making use of PHP's
- * built-in file manipulation functions. This will ensure all hooks and proxies
+ * built-in file manipulation functions. This will ensure all hooks and proxies
* are triggered correctly.
*
- * Filesystem functions are not called directly; they are passed to the correct
+ * Filesystem functions are not called directly; they are passed to the correct
* OC_Filestorage object
*/
@@ -43,11 +43,11 @@ class OC_FilesystemView {
private $internal_path_cache=array();
private $storage_cache=array();
- public function __construct($root){
+ public function __construct($root) {
$this->fakeRoot=$root;
}
- public function getAbsolutePath($path){
+ public function getAbsolutePath($path) {
if(!$path){
$path='/';
}
@@ -63,9 +63,9 @@ class OC_FilesystemView {
* @param string fakeRoot
* @return bool
*/
- public function chroot($fakeRoot){
+ public function chroot($fakeRoot) {
if(!$fakeRoot==''){
- if($fakeRoot[0]!=='/'){
+ if($fakeRoot[0]!=='/') {
$fakeRoot='/'.$fakeRoot;
}
}
@@ -76,7 +76,7 @@ class OC_FilesystemView {
* get the fake root
* @return string
*/
- public function getRoot(){
+ public function getRoot() {
return $this->fakeRoot;
}
@@ -85,7 +85,7 @@ class OC_FilesystemView {
* @param string path
* @return bool
*/
- public function getInternalPath($path){
+ public function getInternalPath($path) {
if (!isset($this->internal_path_cache[$path])) {
$this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path));
}
@@ -97,23 +97,23 @@ class OC_FilesystemView {
* @param string path
* @return string
*/
- public function getRelativePath($path){
- if($this->fakeRoot==''){
+ public function getRelativePath($path) {
+ if($this->fakeRoot=='') {
return $path;
}
- if(strpos($path,$this->fakeRoot)!==0){
+ if(strpos($path, $this->fakeRoot)!==0) {
return null;
}else{
- return substr($path,strlen($this->fakeRoot));
+ return substr($path, strlen($this->fakeRoot));
}
}
-
+
/**
* get the storage object for a path
* @param string path
* @return OC_Filestorage
*/
- public function getStorage($path){
+ public function getStorage($path) {
if (!isset($this->storage_cache[$path])) {
$this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path));
}
@@ -127,7 +127,7 @@ class OC_FilesystemView {
* @param string path
* @return string
*/
- public function getMountPoint($path){
+ public function getMountPoint($path) {
return OC_Filesystem::getMountPoint($this->getAbsolutePath($path));
}
@@ -137,55 +137,55 @@ class OC_FilesystemView {
* @param string path
* @return string
*/
- public function getLocalFile($path){
- $parent=substr($path,0,strrpos($path,'/'));
- if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)){
+ public function getLocalFile($path) {
+ $parent=substr($path, 0, strrpos($path,'/'));
+ if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) {
return $storage->getLocalFile($this->getInternalPath($path));
}
}
/**
- * the following functions operate with arguments and return values identical
- * to those of their PHP built-in equivalents. Mostly they are merely wrappers
+ * the following functions operate with arguments and return values identical
+ * to those of their PHP built-in equivalents. Mostly they are merely wrappers
* for OC_Filestorage via basicOperation().
*/
- public function mkdir($path){
- return $this->basicOperation('mkdir',$path,array('create','write'));
+ public function mkdir($path) {
+ return $this->basicOperation('mkdir', $path, array('create', 'write'));
}
- public function rmdir($path){
- return $this->basicOperation('rmdir',$path,array('delete'));
+ public function rmdir($path) {
+ return $this->basicOperation('rmdir', $path, array('delete'));
}
- public function opendir($path){
- return $this->basicOperation('opendir',$path,array('read'));
+ public function opendir($path) {
+ return $this->basicOperation('opendir', $path, array('read'));
}
- public function readdir($handle){
+ public function readdir($handle) {
$fsLocal= new OC_Filestorage_Local( array( 'datadir' => '/' ) );
return $fsLocal->readdir( $handle );
}
- public function is_dir($path){
+ public function is_dir($path) {
if($path=='/'){
return true;
}
- return $this->basicOperation('is_dir',$path);
+ return $this->basicOperation('is_dir', $path);
}
- public function is_file($path){
+ public function is_file($path) {
if($path=='/'){
return false;
}
- return $this->basicOperation('is_file',$path);
+ return $this->basicOperation('is_file', $path);
}
- public function stat($path){
- return $this->basicOperation('stat',$path);
+ public function stat($path) {
+ return $this->basicOperation('stat', $path);
}
- public function filetype($path){
- return $this->basicOperation('filetype',$path);
+ public function filetype($path) {
+ return $this->basicOperation('filetype', $path);
}
- public function filesize($path){
- return $this->basicOperation('filesize',$path);
+ public function filesize($path) {
+ return $this->basicOperation('filesize', $path);
}
- public function readfile($path){
+ public function readfile($path) {
@ob_end_clean();
- $handle=$this->fopen($path,'rb');
+ $handle=$this->fopen($path, 'rb');
if ($handle) {
$chunkSize = 8192;// 8 MB chunks
while (!feof($handle)) {
@@ -197,137 +197,210 @@ class OC_FilesystemView {
}
return false;
}
- public function is_readable($path){
- return $this->basicOperation('is_readable',$path);
+ public function is_readable($path) {
+ return $this->basicOperation('is_readable', $path);
}
- public function is_writable($path){
- return $this->basicOperation('is_writable',$path);
+ public function is_writable($path) {
+ return $this->basicOperation('is_writable', $path);
}
- public function file_exists($path){
+ public function file_exists($path) {
if($path=='/'){
return true;
}
- return $this->basicOperation('file_exists',$path);
+ return $this->basicOperation('file_exists', $path);
}
- public function filectime($path){
- return $this->basicOperation('filectime',$path);
+ public function filectime($path) {
+ return $this->basicOperation('filectime', $path);
}
- public function filemtime($path){
- return $this->basicOperation('filemtime',$path);
+ public function filemtime($path) {
+ return $this->basicOperation('filemtime', $path);
}
- public function touch($path, $mtime=null){
+ public function touch($path, $mtime=null) {
return $this->basicOperation('touch', $path, array('write'), $mtime);
}
- public function file_get_contents($path){
- return $this->basicOperation('file_get_contents',$path,array('read'));
- }
- public function file_put_contents($path,$data){
- if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier
- $exists=$this->file_exists($path);
- $run=true;
- if(!$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
+ public function file_get_contents($path) {
+ return $this->basicOperation('file_get_contents', $path, array('read'));
+ }
+ public function file_put_contents($path, $data) {
+ if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier
+ $exists = $this->file_exists($path);
+ $run = true;
+ if(!$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_create,
+ array(
+ OC_Filesystem::signal_param_path => $path,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
- if(!$run){
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_write,
+ array(
+ OC_Filesystem::signal_param_path => $path,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
+ if(!$run) {
return false;
}
- $target=$this->fopen($path,'w');
- if($target){
- $count=OC_Helper::streamCopy($data,$target);
+ $target=$this->fopen($path, 'w');
+ if($target) {
+ $count=OC_Helper::streamCopy($data, $target);
fclose($target);
fclose($data);
- if(!$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path));
+ if(!$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_create,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path));
- return $count>0;
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_write,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
+ return $count > 0;
}else{
return false;
}
}else{
- return $this->basicOperation('file_put_contents',$path,array('create','write'),$data);
+ return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data);
}
}
- public function unlink($path){
- return $this->basicOperation('unlink',$path,array('delete'));
+ public function unlink($path) {
+ return $this->basicOperation('unlink', $path, array('delete'));
}
public function deleteAll( $directory, $empty = false ) {
return $this->basicOperation( 'deleteAll', $directory, array('delete'), $empty );
}
- public function rename($path1,$path2){
- $absolutePath1=$this->getAbsolutePath($path1);
- $absolutePath2=$this->getAbsolutePath($path2);
- if(OC_FileProxy::runPreProxies('rename',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){
- $path1=$this->getRelativePath($absolutePath1);
- $path2=$this->getRelativePath($absolutePath2);
- if($path1==null or $path2==null){
+ public function rename($path1, $path2) {
+ $absolutePath1 = $this->getAbsolutePath($path1);
+ $absolutePath2 = $this->getAbsolutePath($path2);
+ if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
+ $path1 = $this->getRelativePath($absolutePath1);
+ $path2 = $this->getRelativePath($absolutePath2);
+ if($path1 == null or $path2 == null) {
return false;
}
$run=true;
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
- if($run){
- $mp1=$this->getMountPoint($path1);
- $mp2=$this->getMountPoint($path2);
- if($mp1==$mp2){
- if($storage=$this->getStorage($path1)){
- $result=$storage->rename($this->getInternalPath($path1),$this->getInternalPath($path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
+ if($run) {
+ $mp1 = $this->getMountPoint($path1);
+ $mp2 = $this->getMountPoint($path2);
+ if($mp1 == $mp2) {
+ if($storage = $this->getStorage($path1)) {
+ $result = $storage->rename($this->getInternalPath($path1), $this->getInternalPath($path2));
}
- }else{
- $source=$this->fopen($path1,'r');
- $target=$this->fopen($path2,'w');
- $count=OC_Helper::streamCopy($source,$target);
- $storage1=$this->getStorage($path1);
+ } else {
+ $source = $this->fopen($path1, 'r');
+ $target = $this->fopen($path2, 'w');
+ $count = OC_Helper::streamCopy($source, $target);
+ $storage1 = $this->getStorage($path1);
$storage1->unlink($this->getInternalPath($path1));
- $result=$count>0;
+ $result = $count>0;
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, array( OC_Filesystem::signal_param_oldpath => $path1, OC_Filesystem::signal_param_newpath=>$path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_rename,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath => $path2
+ )
+ );
return $result;
}
}
}
- public function copy($path1,$path2){
- $absolutePath1=$this->getAbsolutePath($path1);
- $absolutePath2=$this->getAbsolutePath($path2);
- if(OC_FileProxy::runPreProxies('copy',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){
- $path1=$this->getRelativePath($absolutePath1);
- $path2=$this->getRelativePath($absolutePath2);
- if($path1==null or $path2==null){
+ public function copy($path1, $path2) {
+ $absolutePath1 = $this->getAbsolutePath($path1);
+ $absolutePath2 = $this->getAbsolutePath($path2);
+ if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
+ $path1 = $this->getRelativePath($absolutePath1);
+ $path2 = $this->getRelativePath($absolutePath2);
+ if($path1 == null or $path2 == null) {
return false;
}
$run=true;
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_copy,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath=>$path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
$exists=$this->file_exists($path2);
- if($run and !$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
+ if($run and !$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_create,
+ array(
+ OC_Filesystem::signal_param_path => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
}
- if($run){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
+ if($run) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_write,
+ array(
+ OC_Filesystem::signal_param_path => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
}
- if($run){
+ if($run) {
$mp1=$this->getMountPoint($path1);
$mp2=$this->getMountPoint($path2);
- if($mp1==$mp2){
- if($storage=$this->getStorage($path1)){
- $result=$storage->copy($this->getInternalPath($path1),$this->getInternalPath($path2));
+ if($mp1 == $mp2){
+ if($storage = $this->getStorage($path1)) {
+ $result=$storage->copy($this->getInternalPath($path1), $this->getInternalPath($path2));
}
- }else{
- $source=$this->fopen($path1,'r');
- $target=$this->fopen($path2,'w');
- $result=OC_Helper::streamCopy($source,$target);
+ } else {
+ $source = $this->fopen($path1, 'r');
+ $target = $this->fopen($path2, 'w');
+ $result = OC_Helper::streamCopy($source, $target);
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2));
- if(!$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_copy,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath=>$path2
+ )
+ );
+ if(!$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_create,
+ array(OC_Filesystem::signal_param_path => $path2)
+ );
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_write,
+ array( OC_Filesystem::signal_param_path => $path2)
+ );
return $result;
}
}
}
- public function fopen($path,$mode){
+ public function fopen($path, $mode) {
$hooks=array();
- switch($mode){
+ switch($mode) {
case 'r':
case 'rb':
$hooks[]='read';
@@ -355,49 +428,49 @@ class OC_FilesystemView {
OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR);
}
- return $this->basicOperation('fopen',$path,$hooks,$mode);
+ return $this->basicOperation('fopen', $path, $hooks, $mode);
}
- public function toTmpFile($path){
- if(OC_Filesystem::isValidPath($path)){
- $source=$this->fopen($path,'r');
- if($source){
+ public function toTmpFile($path) {
+ if(OC_Filesystem::isValidPath($path)) {
+ $source = $this->fopen($path, 'r');
+ if($source) {
$extension='';
- $extOffset=strpos($path,'.');
+ $extOffset=strpos($path, '.');
if($extOffset !== false) {
- $extension=substr($path,strrpos($path,'.'));
+ $extension=substr($path, strrpos($path,'.'));
}
- $tmpFile=OC_Helper::tmpFile($extension);
- file_put_contents($tmpFile,$source);
+ $tmpFile = OC_Helper::tmpFile($extension);
+ file_put_contents($tmpFile, $source);
return $tmpFile;
}
}
}
- public function fromTmpFile($tmpFile,$path){
- if(OC_Filesystem::isValidPath($path)){
- if(!$tmpFile){
+ public function fromTmpFile($tmpFile, $path) {
+ if(OC_Filesystem::isValidPath($path)) {
+ if(!$tmpFile) {
debug_print_backtrace();
}
- $source=fopen($tmpFile,'r');
- if($source){
- $this->file_put_contents($path,$source);
+ $source=fopen($tmpFile, 'r');
+ if($source) {
+ $this->file_put_contents($path, $source);
unlink($tmpFile);
return true;
- }else{
+ } else {
}
- }else{
+ } else {
return false;
}
}
- public function getMimeType($path){
- return $this->basicOperation('getMimeType',$path);
+ public function getMimeType($path) {
+ return $this->basicOperation('getMimeType', $path);
}
- public function hash($type,$path){
- return $this->basicOperation('hash',$path,array('read'));
+ public function hash($type, $path) {
+ return $this->basicOperation('hash', $path, array('read'), $type);
}
- public function free_space($path='/'){
- return $this->basicOperation('free_space',$path);
+ public function free_space($path='/') {
+ return $this->basicOperation('free_space', $path);
}
/**
@@ -407,41 +480,56 @@ class OC_FilesystemView {
* @param array (optional) hooks
* @param mixed (optional) $extraParam
* @return mixed
- *
- * This method takes requests for basic filesystem functions (e.g. reading & writing
- * files), processes hooks and proxies, sanitises paths, and finally passes them on to
+ *
+ * This method takes requests for basic filesystem functions (e.g. reading & writing
+ * files), processes hooks and proxies, sanitises paths, and finally passes them on to
* OC_Filestorage for delegation to a storage backend for execution
*/
- private function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
- $absolutePath=$this->getAbsolutePath($path);
- if(OC_FileProxy::runPreProxies($operation,$absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)){
- $path=$this->getRelativePath($absolutePath);
- if($path==null){
+ private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) {
+ $absolutePath = $this->getAbsolutePath($path);
+ if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) {
+ $path = $this->getRelativePath($absolutePath);
+ if($path == null) {
return false;
}
- $internalPath=$this->getInternalPath($path);
- $run=true;
- if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){
- foreach($hooks as $hook){
- if($hook!='read'){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
- }else{
- OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path));
+ $internalPath = $this->getInternalPath($path);
+ $run = true;
+ if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
+ foreach($hooks as $hook) {
+ if($hook!='read') {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ $hook,
+ array(
+ OC_Filesystem::signal_param_path => $path,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
+ } else {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ $hook,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
}
}
}
- if($run and $storage=$this->getStorage($path)){
- if(!is_null($extraParam)){
- $result=$storage->$operation($internalPath,$extraParam);
- }else{
- $result=$storage->$operation($internalPath);
+ if($run and $storage = $this->getStorage($path)) {
+ if(!is_null($extraParam)) {
+ $result = $storage->$operation($internalPath, $extraParam);
+ } else {
+ $result = $storage->$operation($internalPath);
}
- $result=OC_FileProxy::runPostProxies($operation,$this->getAbsolutePath($path),$result);
- if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){
- if($operation!='fopen'){//no post hooks for fopen, the file stream is still open
- foreach($hooks as $hook){
+ $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
+ if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
+ if($operation!='fopen') {//no post hooks for fopen, the file stream is still open
+ foreach($hooks as $hook) {
if($hook!='read'){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ 'post_'.$hook,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
}
}
}
@@ -457,7 +545,7 @@ class OC_FilesystemView {
* @param int $time
* @return bool
*/
- public function hasUpdated($path,$time){
- return $this->basicOperation('hasUpdated',$path,array(),$time);
+ public function hasUpdated($path, $time) {
+ return $this->basicOperation('hasUpdated', $path, array(), $time);
}
}
diff --git a/lib/group.php b/lib/group.php
index ceee5fa4edb..12e5f5ebb30 100644
--- a/lib/group.php
+++ b/lib/group.php
@@ -43,7 +43,7 @@ class OC_Group {
* @returns true/false
*/
public static function useBackend( $backend ){
- if($backend instanceof OC_Group_Backend){
+ if($backend instanceof OC_Group_Interface){
self::$_usedBackends[]=$backend;
}
}
@@ -168,7 +168,7 @@ class OC_Group {
if($run){
$succes=false;
-
+
//add the user to the all backends that have the group
foreach(self::$_usedBackends as $backend){
if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP))
@@ -245,7 +245,7 @@ class OC_Group {
asort($groups);
return $groups;
}
-
+
/**
* check if a group exists
* @param string $gid
@@ -259,7 +259,7 @@ class OC_Group {
}
return false;
}
-
+
/**
* @brief get a list of all users in a group
* @returns array with user ids
diff --git a/lib/group/backend.php b/lib/group/backend.php
index 24778afd1e5..ebc078f152a 100644
--- a/lib/group/backend.php
+++ b/lib/group/backend.php
@@ -37,7 +37,7 @@ define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000);
/**
* Abstract base class for user management
*/
-abstract class OC_Group_Backend {
+abstract class OC_Group_Backend implements OC_Group_Interface {
protected $possibleActions = array(
OC_GROUP_BACKEND_CREATE_GROUP => 'createGroup',
OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup',
diff --git a/lib/group/database.php b/lib/group/database.php
index fb173665eb8..2770ec185c4 100644
--- a/lib/group/database.php
+++ b/lib/group/database.php
@@ -41,7 +41,6 @@
* Class for group management in a SQL Database (e.g. MySQL, SQLite)
*/
class OC_Group_Database extends OC_Group_Backend {
- private $userGroupCache=array();
/**
* @brief Try to create a new group
@@ -116,7 +115,7 @@ class OC_Group_Database extends OC_Group_Backend {
// No duplicate entries!
if( !$this->inGroup( $uid, $gid )){
$query = OC_DB::prepare( "INSERT INTO `*PREFIX*group_user` ( `uid`, `gid` ) VALUES( ?, ? )" );
- $result = $query->execute( array( $uid, $gid ));
+ $query->execute( array( $uid, $gid ));
return true;
}else{
return false;
@@ -133,7 +132,7 @@ class OC_Group_Database extends OC_Group_Backend {
*/
public function removeFromGroup( $uid, $gid ){
$query = OC_DB::prepare( "DELETE FROM *PREFIX*group_user WHERE uid = ? AND gid = ?" );
- $result = $query->execute( array( $uid, $gid ));
+ $query->execute( array( $uid, $gid ));
return true;
}
diff --git a/lib/group/dummy.php b/lib/group/dummy.php
index 0825b10708a..1243891023f 100644
--- a/lib/group/dummy.php
+++ b/lib/group/dummy.php
@@ -126,7 +126,8 @@ class OC_Group_Dummy extends OC_Group_Backend {
*/
public function getUserGroups($uid){
$groups=array();
- foreach($this->groups as $group=>$user){
+ $allGroups=array_keys($this->groups);
+ foreach($allGroups as $group){
if($this->inGroup($uid,$group)){
$groups[]=$group;
}
diff --git a/lib/group/example.php b/lib/group/example.php
index c18562db7a4..9c9ece5ac77 100644
--- a/lib/group/example.php
+++ b/lib/group/example.php
@@ -34,7 +34,7 @@ abstract class OC_Group_Example {
* Trys to create a new group. If the group name already exists, false will
* be returned.
*/
- public static function createGroup($gid){}
+ abstract public static function createGroup($gid);
/**
* @brief delete a group
@@ -43,7 +43,7 @@ abstract class OC_Group_Example {
*
* Deletes a group and removes it from the group_user-table
*/
- public static function deleteGroup($gid){}
+ abstract public static function deleteGroup($gid);
/**
* @brief is user in group?
@@ -53,7 +53,7 @@ abstract class OC_Group_Example {
*
* Checks whether the user is member of a group or not.
*/
- public static function inGroup($uid, $gid){}
+ abstract public static function inGroup($uid, $gid);
/**
* @brief Add a user to a group
@@ -63,7 +63,7 @@ abstract class OC_Group_Example {
*
* Adds a user to a group.
*/
- public static function addToGroup($uid, $gid){}
+ abstract public static function addToGroup($uid, $gid);
/**
* @brief Removes a user from a group
@@ -73,7 +73,7 @@ abstract class OC_Group_Example {
*
* removes the user from a group.
*/
- public static function removeFromGroup($uid,$gid){}
+ abstract public static function removeFromGroup($uid,$gid);
/**
* @brief Get all groups a user belongs to
@@ -83,7 +83,7 @@ abstract class OC_Group_Example {
* This function fetches all groups a user belongs to. It does not check
* if the user exists at all.
*/
- public static function getUserGroups($uid){}
+ abstract public static function getUserGroups($uid);
/**
* @brief get a list of all groups
@@ -91,19 +91,19 @@ abstract class OC_Group_Example {
*
* Returns a list with all groups
*/
- public static function getGroups(){}
+ abstract public static function getGroups();
/**
* check if a group exists
* @param string $gid
* @return bool
*/
- public function groupExists($gid){}
+ abstract public function groupExists($gid);
/**
* @brief get a list of all users in a group
* @returns array with user ids
*/
- public static function usersInGroup($gid){}
+ abstract public static function usersInGroup($gid);
}
diff --git a/lib/group/interface.php b/lib/group/interface.php
new file mode 100644
index 00000000000..7cca6061e10
--- /dev/null
+++ b/lib/group/interface.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * ownCloud - group interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+interface OC_Group_Interface {
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_GROUP_BACKEND_CREATE_GROUP etc.
+ */
+ public function implementsActions($actions);
+
+ /**
+ * @brief is user in group?
+ * @param $uid uid of the user
+ * @param $gid gid of the group
+ * @returns true/false
+ *
+ * Checks whether the user is member of a group or not.
+ */
+ public function inGroup($uid, $gid);
+
+ /**
+ * @brief Get all groups a user belongs to
+ * @param $uid Name of the user
+ * @returns array with group names
+ *
+ * This function fetches all groups a user belongs to. It does not check
+ * if the user exists at all.
+ */
+ public function getUserGroups($uid);
+
+ /**
+ * @brief get a list of all groups
+ * @returns array with group names
+ *
+ * Returns a list with all groups
+ */
+ public function getGroups();
+
+ /**
+ * check if a group exists
+ * @param string $gid
+ * @return bool
+ */
+ public function groupExists($gid);
+
+ /**
+ * @brief get a list of all users in a group
+ * @returns array with user ids
+ */
+ public function usersInGroup($gid);
+
+} \ No newline at end of file
diff --git a/lib/helper.php b/lib/helper.php
index 0d18098a4e7..666bc6badfc 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -175,10 +175,8 @@ class OC_Helper {
*/
public static function mimetypeIcon( $mimetype ){
$alias=array('application/xml'=>'code/xml');
-// echo $mimetype;
if(isset($alias[$mimetype])){
$mimetype=$alias[$mimetype];
-// echo $mimetype;
}
// Replace slash with a minus
$mimetype = str_replace( "/", "-", $mimetype );
@@ -345,18 +343,24 @@ class OC_Helper {
*/
static function getMimeType($path){
$isWrapped=(strpos($path,'://')!==false) and (substr($path,0,7)=='file://');
- $mimeType='application/octet-stream';
- if ($mimeType=='application/octet-stream') {
- self::$mimetypes = include('mimetypes.fixlist.php');
- $extension=strtolower(strrchr(basename($path), "."));
- $extension=substr($extension,1);//remove leading .
- $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
- }
if (@is_dir($path)) {
// directories are easy
return "httpd/unix-directory";
}
+
+ if(strpos($path,'.')){
+ //try to guess the type by the file extension
+ if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
+ self::$mimetypes=include('mimetypes.list.php');
+ }
+ $extension=strtolower(strrchr(basename($path), "."));
+ $extension=substr($extension,1);//remove leading .
+ $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
+ }else{
+ $mimeType='application/octet-stream';
+ }
+
if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){
$info = @strtolower(finfo_file($finfo,$path));
if($info){
@@ -385,15 +389,6 @@ class OC_Helper {
}
}
- if ($mimeType=='application/octet-stream') {
- // Fallback solution: (try to guess the type by the file extension
- if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
- self::$mimetypes=include('mimetypes.list.php');
- }
- $extension=strtolower(strrchr(basename($path), "."));
- $extension=substr($extension,1);//remove leading .
- $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
- }
return $mimeType;
}
@@ -676,12 +671,38 @@ class OC_Helper {
*/
public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) {
$offset = -1;
- $length = mb_strlen($search, 'UTF-8');
- while(($i = mb_strrpos($subject, $search, $offset, 'UTF-8'))) {
+ $length = mb_strlen($search, $encoding);
+ while(($i = mb_strrpos($subject, $search, $offset, $encoding))) {
$subject = OC_Helper::mb_substr_replace($subject, $replace, $i, $length);
- $offset = $i - mb_strlen($subject, 'UTF-8') - 1;
+ $offset = $i - mb_strlen($subject, $encoding) - 1;
$count++;
}
return $subject;
}
+
+ /**
+ * @brief performs a search in a nested array
+ * @param haystack the array to be searched
+ * @param needle the search string
+ * @param $index optional, only search this key name
+ * @return the key of the matching field, otherwise false
+ *
+ * performs a search in a nested array
+ *
+ * taken from http://www.php.net/manual/en/function.array-search.php#97645
+ */
+ public static 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;
+ }
}
diff --git a/lib/image.php b/lib/image.php
index e5c59bacdc5..90c64320a7c 100644
--- a/lib/image.php
+++ b/lib/image.php
@@ -23,12 +23,12 @@
//From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php
if ( ! function_exists( 'exif_imagetype' ) ) {
- function exif_imagetype ( $filename ) {
- if ( ( list($width, $height, $type, $attr) = getimagesize( $filename ) ) !== false ) {
- return $type;
- }
- return false;
- }
+ function exif_imagetype ( $filename ) {
+ if ( ( $info = getimagesize( $filename ) ) !== false ) {
+ return $info[2];
+ }
+ return false;
+ }
}
function ellipsis($str, $maxlen) {
@@ -66,7 +66,6 @@ class OC_Image {
public function __construct($imageref = null) {
//OC_Log::write('core',__METHOD__.'(): start', OC_Log::DEBUG);
if(!extension_loaded('gd') || !function_exists('gd_info')) {
- //if(!function_exists('imagecreatefromjpeg')) {
OC_Log::write('core',__METHOD__.'(): GD module not installed', OC_Log::ERROR);
return false;
}
@@ -108,6 +107,56 @@ class OC_Image {
}
/**
+ * @brief Returns the width when the image orientation is top-left.
+ * @returns int
+ */
+ public function widthTopLeft() {
+ $o = $this->getOrientation();
+ OC_Log::write('core','OC_Image->widthTopLeft() Orientation: '.$o, OC_Log::DEBUG);
+ switch($o) {
+ case -1:
+ case 1:
+ case 2: // Not tested
+ case 3:
+ case 4: // Not tested
+ return $this->width();
+ break;
+ case 5: // Not tested
+ case 6:
+ case 7: // Not tested
+ case 8:
+ return $this->height();
+ break;
+ }
+ return $this->width();
+ }
+
+ /**
+ * @brief Returns the height when the image orientation is top-left.
+ * @returns int
+ */
+ public function heightTopLeft() {
+ $o = $this->getOrientation();
+ OC_Log::write('core','OC_Image->heightTopLeft() Orientation: '.$o, OC_Log::DEBUG);
+ switch($o) {
+ case -1:
+ case 1:
+ case 2: // Not tested
+ case 3:
+ case 4: // Not tested
+ return $this->height();
+ break;
+ case 5: // Not tested
+ case 6:
+ case 7: // Not tested
+ case 8:
+ return $this->width();
+ break;
+ }
+ return $this->height();
+ }
+
+ /**
* @brief Outputs the image.
* @returns bool
*/
@@ -209,34 +258,46 @@ class OC_Image {
/**
* (I'm open for suggestions on better method name ;)
- * @brief Fixes orientation based on EXIF data.
- * @returns bool.
+ * @brief Get the orientation based on EXIF data.
+ * @returns The orientation or -1 if no EXIF data is available.
*/
- public function fixOrientation() {
+ public function getOrientation() {
if(!is_callable('exif_read_data')){
OC_Log::write('core','OC_Image->fixOrientation() Exif module not enabled.', OC_Log::DEBUG);
- return false;
+ return -1;
}
if(!$this->valid()) {
OC_Log::write('core','OC_Image->fixOrientation() No image loaded.', OC_Log::DEBUG);
- return false;
+ return -1;
}
if(is_null($this->filepath) || !is_readable($this->filepath)) {
OC_Log::write('core','OC_Image->fixOrientation() No readable file path set.', OC_Log::DEBUG);
- return false;
+ return -1;
}
$exif = @exif_read_data($this->filepath, 'IFD0');
if(!$exif) {
- return false;
+ return -1;
}
if(!isset($exif['Orientation'])) {
- return true; // Nothing to fix
+ return -1;
}
- $o = $exif['Orientation'];
+ return $exif['Orientation'];
+ }
+
+ /**
+ * (I'm open for suggestions on better method name ;)
+ * @brief Fixes orientation based on EXIF data.
+ * @returns bool.
+ */
+ public function fixOrientation() {
+ $o = $this->getOrientation();
OC_Log::write('core','OC_Image->fixOrientation() Orientation: '.$o, OC_Log::DEBUG);
$rotate = 0;
$flip = false;
switch($o) {
+ case -1:
+ return false; //Nothing to fix
+ break;
case 1:
$rotate = 0;
$flip = false;
@@ -302,7 +363,7 @@ class OC_Image {
public function load($imageref) {
if(is_resource($imageref)) {
if(get_resource_type($imageref) == 'gd') {
- $this->resource = $res;
+ $this->resource = $imageref;
return $this->resource;
} elseif(in_array(get_resource_type($imageref), array('file','stream'))) {
return $this->loadFromFileHandle($imageref);
@@ -588,9 +649,6 @@ class OC_Image {
OC_Log::write('core',__METHOD__.'(): No image loaded', OC_Log::ERROR);
return false;
}
- $width_orig=imageSX($this->resource);
- $height_orig=imageSY($this->resource);
- //OC_Log::write('core',__METHOD__.'(): Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG);
$process = imagecreatetruecolor($w, $h);
if ($process == false) {
OC_Log::write('core',__METHOD__.'(): Error creating true color image',OC_Log::ERROR);
diff --git a/lib/installer.php b/lib/installer.php
index 00feb6d4709..a8b56cb34f2 100644
--- a/lib/installer.php
+++ b/lib/installer.php
@@ -126,19 +126,19 @@ class OC_Installer{
return false;
}
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
- // check the code for not allowed calls
- if(!OC_Installer::checkCode($info['id'],$extractDir)){
+ // check the code for not allowed calls
+ if(!OC_Installer::checkCode($info['id'],$extractDir)){
OC_Log::write('core','App can\'t be installed because of not allowed code in the App',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
- return false;
+ return false;
}
- // check if the app is compatible with this version of ownCloud
+ // check if the app is compatible with this version of ownCloud
$version=OC_Util::getVersion();
- if(!isset($info['require']) or ($version[0]>$info['require'])){
+ if(!isset($info['require']) or ($version[0]>$info['require'])){
OC_Log::write('core','App can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
- return false;
+ return false;
}
//check if an app with the same id is already installed
@@ -339,12 +339,12 @@ class OC_Installer{
}
- /**
- * check the code of an app with some static code checks
- * @param string $folder the folder of the app to check
- * @returns true for app is o.k. and false for app is not o.k.
- */
- public static function checkCode($appname,$folder){
+ /**
+ * check the code of an app with some static code checks
+ * @param string $folder the folder of the app to check
+ * @returns true for app is o.k. and false for app is not o.k.
+ */
+ public static function checkCode($appname,$folder){
$blacklist=array(
'exec(',
@@ -377,9 +377,7 @@ class OC_Installer{
return true;
}else{
- return true;
+ return true;
}
- }
-
-
+ }
}
diff --git a/lib/json.php b/lib/json.php
index c49b831c12b..b46878375d5 100644
--- a/lib/json.php
+++ b/lib/json.php
@@ -94,12 +94,12 @@ class OC_JSON{
* Encode and print $data in json format
*/
public static function encodedPrint($data,$setContentType=true){
- // Disable mimesniffing, don't move this to setContentTypeHeader!
- header( 'X-Content-Type-Options: nosniff' );
- if($setContentType){
- self::setContentTypeHeader();
- }
- array_walk_recursive($data, array('OC_JSON', 'to_string'));
- echo json_encode($data);
+ // Disable mimesniffing, don't move this to setContentTypeHeader!
+ header( 'X-Content-Type-Options: nosniff' );
+ if($setContentType){
+ self::setContentTypeHeader();
+ }
+ array_walk_recursive($data, array('OC_JSON', 'to_string'));
+ echo json_encode($data);
}
}
diff --git a/lib/l10n.php b/lib/l10n.php
index de8514573d3..e7f5ffea0e4 100644
--- a/lib/l10n.php
+++ b/lib/l10n.php
@@ -154,8 +154,15 @@ class OC_L10N{
*
* Returns the translation. If no translation is found, $textArray will be
* returned.
+ *
+ *
+ * @deprecated deprecated since ownCloud version 5.0
+ * This method will probably be removed with ownCloud 6.0
+ *
+ *
*/
public function tA($textArray){
+ OC_Log::write('core', 'DEPRECATED: the method tA is deprecated and will be removed soon.',OC_Log::WARN);
$result = array();
foreach($textArray as $key => $text){
$result[$key] = (string)$this->t($text);
diff --git a/lib/mail.php b/lib/mail.php
index 7343f5f0d97..7eb2c4770c5 100644
--- a/lib/mail.php
+++ b/lib/mail.php
@@ -36,7 +36,7 @@ class OC_Mail {
$SMTPPASSWORD = OC_Config::getValue( 'mail_smtppassword', '' );
- $mailo = new PHPMailer();
+ $mailo = new PHPMailer(true);
if($SMTPMODE=='sendmail') {
$mailo->IsSendmail();
}elseif($SMTPMODE=='smtp'){
@@ -56,33 +56,35 @@ class OC_Mail {
$mailo->From =$fromaddress;
$mailo->FromName = $fromname;;
$a=explode(' ',$toaddress);
- foreach($a as $ad) {
- $mailo->AddAddress($ad,$toname);
+ try {
+ foreach($a as $ad) {
+ $mailo->AddAddress($ad,$toname);
+ }
+
+ if($ccaddress<>'') $mailo->AddCC($ccaddress,$ccname);
+ if($bcc<>'') $mailo->AddBCC($bcc);
+
+ $mailo->AddReplyTo($fromaddress, $fromname);
+
+ $mailo->WordWrap = 50;
+ if($html==1) $mailo->IsHTML(true); else $mailo->IsHTML(false);
+
+ $mailo->Subject = $subject;
+ if($altbody=='') {
+ $mailo->Body = $mailtext.OC_MAIL::getfooter();
+ $mailo->AltBody = '';
+ }else{
+ $mailo->Body = $mailtext;
+ $mailo->AltBody = $altbody;
+ }
+ $mailo->CharSet = 'UTF-8';
+
+ $mailo->Send();
+ unset($mailo);
+ OC_Log::write('mail', 'Mail from '.$fromname.' ('.$fromaddress.')'.' to: '.$toname.'('.$toaddress.')'.' subject: '.$subject, OC_Log::DEBUG);
+ } catch (Exception $exception) {
+ OC_Log::write('mail', $exception->getMessage(), OC_Log::DEBUG);
}
-
- if($ccaddress<>'') $mailo->AddCC($ccaddress,$ccname);
- if($bcc<>'') $mailo->AddBCC($bcc);
-
- $mailo->AddReplyTo($fromaddress, $fromname);
-
- $mailo->WordWrap = 50;
- if($html==1) $mailo->IsHTML(true); else $mailo->IsHTML(false);
-
- $mailo->Subject = $subject;
- if($altbody=='') {
- $mailo->Body = $mailtext.OC_MAIL::getfooter();
- $mailo->AltBody = '';
- }else{
- $mailo->Body = $mailtext;
- $mailo->AltBody = $altbody;
- }
- $mailo->CharSet = 'UTF-8';
-
- $mailo->Send();
- unset($mailo);
-
- OC_Log::write('Mail from '.$fromname.' ('.$fromaddress.')'.' to: '.$toname.'('.$toaddress.')'.' subject: '.$subject,'mail',OC_Log::DEBUG);
-
}
diff --git a/lib/migrate.php b/lib/migrate.php
index f788a637d3c..1b6367ed6ec 100644
--- a/lib/migrate.php
+++ b/lib/migrate.php
@@ -91,7 +91,7 @@ class OC_Migrate{
if( self::$exporttype == 'user' ){
// Check user exists
if( !is_null($uid) ){
- $db = new OC_User_Database;
+ $db = new OC_User_Database;
if( !$db->userExists( $uid ) ){
OC_Log::write('migration', 'User: '.$uid.' is not in the database and so cannot be exported.', OC_Log::ERROR);
return json_encode( array( 'success' => false ) );
diff --git a/lib/mimetypes.fixlist.php b/lib/mimetypes.fixlist.php
deleted file mode 100644
index 13e3f16b369..00000000000
--- a/lib/mimetypes.fixlist.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-return array(
- 'ics'=>'text/calendar',
- 'ical'=>'text/calendar',
- 'js'=>'application/javascript',
- 'odt'=>'application/vnd.oasis.opendocument.text',
- 'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
- 'odg'=>'application/vnd.oasis.opendocument.graphics',
- 'odp'=>'application/vnd.oasis.opendocument.presentation',
- 'pl'=>'text/x-script.perl',
- 'py'=>'text/x-script.phyton',
- 'vcf' => 'text/vcard',
- 'vcard' => 'text/vcard',
- 'doc'=>'application/msword',
- 'docx'=>'application/msword',
- 'xls'=>'application/msexcel',
- 'xlsx'=>'application/msexcel',
- 'ppt'=>'application/mspowerpoint',
- 'pptx'=>'application/mspowerpoint',
- 'sgf' => 'application/sgf',
- 'cdr' => 'application/coreldraw'
-);
diff --git a/lib/mimetypes.list.php b/lib/mimetypes.list.php
index ccf47999b1c..f7207493f7f 100644
--- a/lib/mimetypes.list.php
+++ b/lib/mimetypes.list.php
@@ -78,5 +78,16 @@ return array(
'mpeg'=>'video/mpeg',
'mov'=>'video/quicktime',
'webm'=>'video/webm',
- 'wmv'=>'video/x-ms-asf'
+ 'wmv'=>'video/x-ms-asf',
+ 'py'=>'text/x-script.phyton',
+ 'vcf' => 'text/vcard',
+ 'vcard' => 'text/vcard',
+ 'doc'=>'application/msword',
+ 'docx'=>'application/msword',
+ 'xls'=>'application/msexcel',
+ 'xlsx'=>'application/msexcel',
+ 'ppt'=>'application/mspowerpoint',
+ 'pptx'=>'application/mspowerpoint',
+ 'sgf' => 'application/sgf',
+ 'cdr' => 'application/coreldraw',
);
diff --git a/lib/minimizer.php b/lib/minimizer.php
index 3bf5ff9980b..3dc89e331a6 100644
--- a/lib/minimizer.php
+++ b/lib/minimizer.php
@@ -46,3 +46,13 @@ abstract class OC_Minimizer {
echo $out;
}
}
+
+if (!function_exists('gzdecode')) {
+ function gzdecode($data,$maxlength=null,&$filename='',&$error='')
+ {
+ if (strcmp(substr($data,0,9),"\x1f\x8b\x8\0\0\0\0\0\0")) {
+ return null; // Not the GZIP format we expect (See RFC 1952)
+ }
+ return gzinflate(substr($data,10,-8));
+ }
+}
diff --git a/lib/ocs.php b/lib/ocs.php
index 5e697b48304..d7a7951fab5 100644
--- a/lib/ocs.php
+++ b/lib/ocs.php
@@ -23,8 +23,6 @@
*
*/
-
-
/**
* Class to handle open collaboration services API requests
*
@@ -92,77 +90,160 @@ class OC_OCS {
exit();
}
- // preprocess url
- $url = strtolower($_SERVER['REQUEST_URI']);
- if(substr($url,(strlen($url)-1))<>'/') $url.='/';
- $ex=explode('/',$url);
- $paracount=count($ex);
$format = self::readData($method, 'format', 'text', '');
- // eventhandler
+
+ $router = new OC_Router();
+ $router->useCollection('ocs');
// CONFIG
- // apiconfig - GET - CONFIG
- if(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'config')){
- OC_OCS::apiconfig($format);
+ $router->create('config', '/config.{format}')
+ ->defaults(array('format' => $format))
+ ->action('OC_OCS', 'apiConfig')
+ ->requirements(array('format'=>'xml|json'));
// PERSON
- // personcheck - POST - PERSON/CHECK
- }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='person') and ($ex[$paracount-2] == 'check')){
- $login = self::readData($method, 'login', 'text');
- $passwd = self::readData($method, 'password', 'text');
- OC_OCS::personcheck($format,$login,$passwd);
- } else if ($method == 'post' && $ex[$paracount - 4] == 'v1.php' && $ex[$paracount - 3] == 'person' && $ex[$paracount - 2] == 'add') {
- if (OC_Group::inGroup(self::checkPassword(), 'admin')) {
- $login = self::readData($method, 'login', 'text');
- $password = self::readData($method, 'password', 'text');
- try {
- OC_User::createUser($login, $password);
- echo self::generateXml($format, 'ok', 201, '');
- } catch (Exception $exception) {
- echo self::generateXml($format, 'fail', 400, $exception->getMessage());
- }
- } else {
- echo self::generateXml($format, 'fail', 403, 'Permission denied');
- }
+ $router->create('person_check', '/person/check.{format}')
+ ->post()
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $login = OC_OCS::readData('post', 'login', 'text');
+ $passwd = OC_OCS::readData('post', 'password', 'text');
+ OC_OCS::personCheck($format,$login,$passwd);
+ })
+ ->requirements(array('format'=>'xml|json'));
+
// ACTIVITY
// activityget - GET ACTIVITY page,pagesize als urlparameter
- }elseif(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){
- $page = self::readData($method, 'page', 'int', 0);
- $pagesize = self::readData($method, 'pagesize','int', 10);
- if($pagesize<1 or $pagesize>100) $pagesize=10;
- OC_OCS::activityget($format,$page,$pagesize);
-
+ $router->create('activity_get', '/activity.{format}')
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $page = OC_OCS::readData('get', 'page', 'int', 0);
+ $pagesize = OC_OCS::readData('get', 'pagesize', 'int', 10);
+ if($pagesize<1 or $pagesize>100) $pagesize=10;
+ OC_OCS::activityGet($format, $page, $pagesize);
+ })
+ ->requirements(array('format'=>'xml|json'));
// activityput - POST ACTIVITY
- }elseif(($method=='post') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){
- $message = self::readData($method, 'message', 'text');
- OC_OCS::activityput($format,$message);
+ $router->create('activity_put', '/activity.{format}')
+ ->post()
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $message = OC_OCS::readData('post', 'message', 'text');
+ OC_OCS::activityPut($format,$message);
+ })
+ ->requirements(array('format'=>'xml|json'));
// PRIVATEDATA
// get - GET DATA
- }elseif(($method=='get') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-2] == 'getattribute')){
- OC_OCS::privateDataGet($format);
-
- }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-3] == 'getattribute')){
- $app=$ex[$paracount-2];
- OC_OCS::privateDataGet($format, $app);
- }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'getattribute')){
-
- $key=$ex[$paracount-2];
- $app=$ex[$paracount-3];
- OC_OCS::privateDataGet($format, $app,$key);
-
+ $router->create('privatedata_get',
+ '/privatedata/getattribute/{app}/{key}.{format}')
+ ->defaults(array('app' => '', 'key' => '', 'format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $app = addslashes(strip_tags($parameters['app']));
+ $key = addslashes(strip_tags($parameters['key']));
+ OC_OCS::privateDataGet($format, $app, $key);
+ })
+ ->requirements(array('format'=>'xml|json'));
// set - POST DATA
- }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'setattribute')){
- $key=$ex[$paracount-2];
- $app=$ex[$paracount-3];
- $value = self::readData($method, 'value', 'text');
- OC_OCS::privatedataset($format, $app, $key, $value);
+ $router->create('privatedata_set',
+ '/privatedata/setattribute/{app}/{key}.{format}')
+ ->post()
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $app = addslashes(strip_tags($parameters['app']));
+ $key = addslashes(strip_tags($parameters['key']));
+ $value=OC_OCS::readData('post', 'value', 'text');
+ OC_OCS::privateDataSet($format, $app, $key, $value);
+ })
+ ->requirements(array('format'=>'xml|json'));
// delete - POST DATA
- }elseif(($method=='post') and ($ex[$paracount-6] =='v1.php') and ($ex[$paracount-4] == 'deleteattribute')){
- $key=$ex[$paracount-2];
- $app=$ex[$paracount-3];
- OC_OCS::privatedatadelete($format, $app, $key);
-
- }else{
+ $router->create('privatedata_delete',
+ '/privatedata/deleteattribute/{app}/{key}.{format}')
+ ->post()
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $app = addslashes(strip_tags($parameters['app']));
+ $key = addslashes(strip_tags($parameters['key']));
+ OC_OCS::privateDataDelete($format, $app, $key);
+ })
+ ->requirements(array('format'=>'xml|json'));
+
+ // CLOUD
+ // systemWebApps
+ $router->create('system_webapps',
+ '/cloud/system/webapps.{format}')
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ OC_OCS::systemwebapps($format);
+ })
+ ->requirements(array('format'=>'xml|json'));
+
+ // quotaget
+ $router->create('quota_get',
+ '/cloud/user/{user}.{format}')
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $user = $parameters['user'];
+ OC_OCS::quotaGet($format, $user);
+ })
+ ->requirements(array('format'=>'xml|json'));
+ // quotaset
+ $router->create('quota_set',
+ '/cloud/user/{user}.{format}')
+ ->post()
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $user = $parameters['user'];
+ $quota = self::readData('post', 'quota', 'int');
+ OC_OCS::quotaSet($format, $user, $quota);
+ })
+ ->requirements(array('format'=>'xml|json'));
+
+ // keygetpublic
+ $router->create('keygetpublic',
+ '/cloud/user/{user}/publickey.{format}')
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $user = $parameters['user'];
+ OC_OCS::publicKeyGet($format,$user);
+ })
+ ->requirements(array('format'=>'xml|json'));
+
+ // keygetprivate
+ $router->create('keygetpublic',
+ '/cloud/user/{user}/privatekey.{format}')
+ ->defaults(array('format' => $format))
+ ->action(function ($parameters) {
+ $format = $parameters['format'];
+ $user = $parameters['user'];
+ OC_OCS::privateKeyGet($format,$user);
+ })
+ ->requirements(array('format'=>'xml|json'));
+
+
+// add more calls here
+// please document all the call in the draft spec
+// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD
+
+// TODO:
+// users
+// groups
+// bookmarks
+// sharing
+// versioning
+// news (rss)
+ try {
+ $router->match($_SERVER['PATH_INFO']);
+ } catch (ResourceNotFoundException $e) {
$txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
$txt.=OC_OCS::getdebugoutput();
echo(OC_OCS::generatexml($format,'failed',999,$txt));
@@ -198,25 +279,25 @@ class OC_OCS {
if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
if(empty($authuser)) {
- if($forceuser){
- header('WWW-Authenticate: Basic realm="your valid user account or api key"');
- header('HTTP/1.0 401 Unauthorized');
- exit;
- }else{
- $identifieduser='';
- }
- }else{
- if(!OC_User::login($authuser,$authpw)){
if($forceuser){
- header('WWW-Authenticate: Basic realm="your valid user account or api key"');
- header('HTTP/1.0 401 Unauthorized');
- exit;
+ header('WWW-Authenticate: Basic realm="your valid user account or api key"');
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
}else{
- $identifieduser='';
+ $identifieduser='';
}
}else{
- $identifieduser=$authuser;
- }
+ if(!OC_User::login($authuser,$authpw)){
+ if($forceuser){
+ header('WWW-Authenticate: Basic realm="your valid user account or api key"');
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
+ }else{
+ $identifieduser='';
+ }
+ }else{
+ $identifieduser=$authuser;
+ }
}
return($identifieduser);
@@ -350,11 +431,12 @@ class OC_OCS {
* @param string $format
* @return string xml/json
*/
- private static function apiConfig($format) {
+ public static function apiConfig($parameters) {
+ $format = $parameters['format'];
$user=OC_OCS::checkpassword(false);
$url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).'';
- $xml['version']='1.5';
+ $xml['version']='1.7';
$xml['website']='ownCloud';
$xml['host']=OCP\Util::getServerHost();
$xml['contact']='';
@@ -524,4 +606,134 @@ class OC_OCS {
public static function deleteData($user, $app, $key) {
return OC_Preferences::deleteKey($user,$app,$key);
}
+
+
+ // CLOUD API #############################################
+
+ /**
+ * get a list of installed web apps
+ * @param string $format
+ * @return string xml/json
+ */
+ private static function systemWebApps($format) {
+ $login=OC_OCS::checkpassword();
+ $apps=OC_App::getEnabledApps();
+ $values=array();
+ foreach($apps as $app) {
+ $info=OC_App::getAppInfo($app);
+ if(isset($info['standalone'])) {
+ $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
+ $values[]=$newvalue;
+ }
+
+ }
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0);
+ echo($txt);
+
+ }
+
+
+ /**
+ * get the quota of a user
+ * @param string $format
+ * @param string $user
+ * @return string xml/json
+ */
+ private static function quotaGet($format,$user) {
+ $login=OC_OCS::checkpassword();
+ if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
+
+ if(OC_User::userExists($user)){
+ // calculate the disc space
+ $user_dir = '/'.$user.'/files';
+ OC_Filesystem::init($user_dir);
+ $rootInfo=OC_FileCache::get('');
+ $sharedInfo=OC_FileCache::get('/Shared');
+ $used=$rootInfo['size']-$sharedInfo['size'];
+ $free=OC_Filesystem::free_space();
+ $total=$free+$used;
+ if($total==0) $total=1; // prevent division by zero
+ $relative=round(($used/$total)*10000)/100;
+
+ $xml=array();
+ $xml['quota']=$total;
+ $xml['free']=$free;
+ $xml['used']=$used;
+ $xml['relative']=$relative;
+
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'User does not exist');
+ }
+ }else{
+ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+ }
+ }
+
+ /**
+ * set the quota of a user
+ * @param string $format
+ * @param string $user
+ * @param string $quota
+ * @return string xml/json
+ */
+ private static function quotaSet($format,$user,$quota) {
+ $login=OC_OCS::checkpassword();
+ if(OC_Group::inGroup($login, 'admin')) {
+
+ // todo
+ // not yet implemented
+ // add logic here
+ error_log('OCS call: user:'.$user.' quota:'.$quota);
+
+ $xml=array();
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+ }
+ }
+
+ /**
+ * get the public key of a user
+ * @param string $format
+ * @param string $user
+ * @return string xml/json
+ */
+ private static function publicKeyGet($format,$user) {
+ $login=OC_OCS::checkpassword();
+
+ if(OC_User::userExists($user)){
+ // calculate the disc space
+ $txt='this is the public key of '.$user;
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'User does not exist');
+ }
+ }
+
+ /**
+ * get the private key of a user
+ * @param string $format
+ * @param string $user
+ * @return string xml/json
+ */
+ private static function privateKeyGet($format,$user) {
+ $login=OC_OCS::checkpassword();
+ if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
+
+ if(OC_User::userExists($user)){
+ // calculate the disc space
+ $txt='this is the private key of '.$user;
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'User does not exist');
+ }
+ }else{
+ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+ }
+ }
+
+
}
diff --git a/lib/ocsclient.php b/lib/ocsclient.php
index 951d761d7e6..ae35470cff6 100644
--- a/lib/ocsclient.php
+++ b/lib/ocsclient.php
@@ -71,7 +71,7 @@ class OC_OCSClient{
$tmp=$data->data;
$cats=array();
- foreach($tmp->category as $key=>$value) {
+ foreach($tmp->category as $value) {
$id= (int) $value->id;
$name= (string) $value->name;
diff --git a/lib/preferences.php b/lib/preferences.php
index f72378ce94f..c91423e69bc 100644
--- a/lib/preferences.php
+++ b/lib/preferences.php
@@ -165,7 +165,7 @@ class OC_Preferences{
public static function deleteKey( $user, $app, $key ){
// No need for more comments
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE userid = ? AND appid = ? AND configkey = ?' );
- $result = $query->execute( array( $user, $app, $key ));
+ $query->execute( array( $user, $app, $key ));
return true;
}
@@ -181,7 +181,7 @@ class OC_Preferences{
public static function deleteApp( $user, $app ){
// No need for more comments
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE userid = ? AND appid = ?' );
- $result = $query->execute( array( $user, $app ));
+ $query->execute( array( $user, $app ));
return true;
}
@@ -196,7 +196,7 @@ class OC_Preferences{
public static function deleteUser( $user ){
// No need for more comments
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE userid = ?' );
- $result = $query->execute( array( $user ));
+ $query->execute( array( $user ));
return true;
}
@@ -211,7 +211,7 @@ class OC_Preferences{
public static function deleteAppFromAllUsers( $app ){
// No need for more comments
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE appid = ?' );
- $result = $query->execute( array( $app ));
+ $query->execute( array( $app ));
return true;
}
diff --git a/lib/public/app.php b/lib/public/app.php
index 9e2108818bf..28411933beb 100644
--- a/lib/public/app.php
+++ b/lib/public/app.php
@@ -34,28 +34,6 @@ namespace OCP;
* This class provides functions to manage apps in ownCloud
*/
class App {
-
- /**
- * @brief Makes owncloud aware of this app
- * @brief This call is deprecated and not necessary to use.
- * @param $data array with all information
- * @returns true/false
- *
- * This function registers the application. $data is an associative array.
- * The following keys are required:
- * - id: id of the application, has to be unique ('addressbook')
- * - name: Human readable name ('Addressbook')
- * - version: array with Version (major, minor, bugfix) ( array(1, 0, 2))
- *
- * The following keys are optional:
- * - order: integer, that influences the position of your application in
- * a list of applications. Lower values come first.
- *
- */
- public static function register( $data ){
- }
-
-
/**
* @brief adds an entry to the navigation
* @param $data array containing the data
@@ -158,6 +136,3 @@ class App {
}
-
-
-?>
diff --git a/lib/public/config.php b/lib/public/config.php
index 9f5abe672cb..ab01902ffe6 100644
--- a/lib/public/config.php
+++ b/lib/public/config.php
@@ -134,5 +134,3 @@ class Config {
}
-
-?>
diff --git a/lib/public/db.php b/lib/public/db.php
index f7564c0bb6a..3a33f7674d8 100644
--- a/lib/public/db.php
+++ b/lib/public/db.php
@@ -91,5 +91,3 @@ class DB {
}
-
-?>
diff --git a/lib/public/files.php b/lib/public/files.php
index fc3004434ba..32b3f036744 100644
--- a/lib/public/files.php
+++ b/lib/public/files.php
@@ -115,5 +115,3 @@ class Files {
}
-
-?>
diff --git a/lib/public/groupinterface.php b/lib/public/groupinterface.php
new file mode 100644
index 00000000000..97833028118
--- /dev/null
+++ b/lib/public/groupinterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Group Class.
+ *
+ */
+
+namespace OCP;
+
+interface GroupInterface extends \OC_Group_Interface {} \ No newline at end of file
diff --git a/lib/public/json.php b/lib/public/json.php
index b6edbd65bd5..99df79173eb 100644
--- a/lib/public/json.php
+++ b/lib/public/json.php
@@ -35,75 +35,140 @@ namespace OCP;
*/
class JSON {
-
/**
* @brief Encode and print $data in JSON format
* @param array $data The data to use
* @param string $setContentType the optional content type
+ * @return string json formatted string.
*/
public static function encodedPrint( $data, $setContentType=true ){
return(\OC_JSON::encodedPrint( $data, $setContentType ));
}
-
/**
- * @brief Check if the user is logged in, send json error msg if not
+ * Check if the user is logged in, send json error msg if not.
+ *
+ * This method checks if a user is logged in. If not, a json error
+ * response will be return and the method will exit from execution
+ * of the script.
+ * The returned json will be in the format:
+ *
+ * {"status":"error","data":{"message":"Authentication error."}}
+ *
+ * Add this call to the start of all ajax method files that requires
+ * an authenticated user.
+ *
+ * @return string json formatted error string if not authenticated.
*/
public static function checkLoggedIn(){
return(\OC_JSON::checkLoggedIn());
}
/**
- * @brief Check an ajax get/post call if the request token is valid.
- * @return json Error msg if not valid.
- */
+ * Check an ajax get/post call if the request token is valid.
+ *
+ * This method checks for a valid variable 'requesttoken' in $_GET,
+ * $_POST and $_SERVER. If a valid token is not found, a json error
+ * response will be return and the method will exit from execution
+ * of the script.
+ * The returned json will be in the format:
+ *
+ * {"status":"error","data":{"message":"Token expired. Please reload page."}}
+ *
+ * Add this call to the start of all ajax method files that creates,
+ * updates or deletes anything.
+ * In cases where you e.g. use an ajax call to load a dialog containing
+ * a submittable form, you will need to add the requesttoken first as a
+ * parameter to the ajax call, then assign it to the template and finally
+ * add a hidden input field also named 'requesttoken' containing the value.
+ *
+ * @return string json formatted error string if not valid.
+ */
public static function callCheck(){
return(\OC_JSON::callCheck());
}
/**
- * @brief Send json success msg
+ * Send json success msg
+ *
+ * Return a json success message with optional extra data.
+ * @see OCP\JSON::error() for the format to use.
+ *
* @param array $data The data to use
+ * @return string json formatted string.
*/
public static function success( $data = array() ){
return(\OC_JSON::success( $data ));
}
-
/**
- * @brief Send json error msg
+ * Send json error msg
+ *
+ * Return a json error message with optional extra data for
+ * error message or app specific data.
+ *
+ * Example use:
+ *
+ * $id = [some value]
+ * OCP\JSON::error(array('data':array('message':'An error happened', 'id': $id)));
+ *
+ * Will return the json formatted string:
+ *
+ * {"status":"error","data":{"message":"An error happened", "id":[some value]}}
+ *
* @param array $data The data to use
+ * @return string json formatted error string.
*/
public static function error( $data = array() ){
return(\OC_JSON::error( $data ));
}
-
/**
- * @brief set Content-Type header to jsonrequest
- * @param array $type The contwnt type header
- */
+ * @brief set Content-Type header to jsonrequest
+ * @param array $type The contwnt type header
+ * @return string json formatted string.
+ */
public static function setContentTypeHeader( $type='application/json' ){
return(\OC_JSON::setContentTypeHeader( $type ));
}
-
/**
- * @brief Check if the App is enabled and send JSON error message instead
- * @param string $app The app to check
- */
+ * Check if the App is enabled and send JSON error message instead
+ *
+ * This method checks if a specific app is enabled. If not, a json error
+ * response will be return and the method will exit from execution
+ * of the script.
+ * The returned json will be in the format:
+ *
+ * {"status":"error","data":{"message":"Application is not enabled."}}
+ *
+ * Add this call to the start of all ajax method files that requires
+ * a specific app to be enabled.
+ *
+ * @param string $app The app to check
+ * @return string json formatted string if not enabled.
+ */
public static function checkAppEnabled( $app ){
return(\OC_JSON::checkAppEnabled( $app ));
}
-
/**
- * @brief Check if the user is a admin, send json error msg if not
+ * Check if the user is a admin, send json error msg if not
+ *
+ * This method checks if the current user has admin rights. If not, a json error
+ * response will be return and the method will exit from execution
+ * of the script.
+ * The returned json will be in the format:
+ *
+ * {"status":"error","data":{"message":"Authentication error."}}
+ *
+ * Add this call to the start of all ajax method files that requires
+ * administrative rights.
+ *
+ * @return string json formatted string if not admin user.
*/
public static function checkAdminUser(){
return(\OC_JSON::checkAdminUser());
}
}
-
-?>
diff --git a/lib/public/response.php b/lib/public/response.php
index cc2137c5cae..8dff3bcd354 100644
--- a/lib/public/response.php
+++ b/lib/public/response.php
@@ -105,5 +105,3 @@ class Response {
}
-
-?>
diff --git a/lib/public/template.php b/lib/public/template.php
index b89088bdd06..a0ed618cb2c 100644
--- a/lib/public/template.php
+++ b/lib/public/template.php
@@ -104,6 +104,3 @@ function html_select_options($options, $selected, $params=array()) {
class Template extends \OC_Template {
}
-
-
-?>
diff --git a/lib/public/user.php b/lib/public/user.php
index a0c069f7379..713e366b968 100644
--- a/lib/public/user.php
+++ b/lib/public/user.php
@@ -120,6 +120,3 @@ class User {
}
-
-
-?>
diff --git a/lib/public/userinterface.php b/lib/public/userinterface.php
new file mode 100644
index 00000000000..b73a8f8d8b0
--- /dev/null
+++ b/lib/public/userinterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * User Class.
+ *
+ */
+
+namespace OCP;
+
+interface UserInterface extends \OC_User_Interface {} \ No newline at end of file
diff --git a/lib/public/util.php b/lib/public/util.php
index 41121091544..75ca29f7129 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -320,6 +320,15 @@ class Util {
public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) {
return(\OC_Helper::mb_str_replace($search, $replace, $subject, $encoding, $count));
}
-}
-?>
+ /**
+ * @brief performs a search in a nested array
+ * @param haystack the array to be searched
+ * @param needle the search string
+ * @param $index optional, only search this key name
+ * @return the key of the matching field, otherwise false
+ */
+ public static function recursiveArraySearch($haystack, $needle, $index = null) {
+ return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index));
+ }
+}
diff --git a/lib/route.php b/lib/route.php
new file mode 100644
index 00000000000..0d3339add6c
--- /dev/null
+++ b/lib/route.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+use Symfony\Component\Routing\Route;
+
+class OC_Route extends Route {
+ public function method($method) {
+ $this->setRequirement('_method', $method);
+ return $this;
+ }
+
+ public function post() {
+ $this->method('post');
+ return $this;
+ }
+
+ public function get() {
+ $this->method('get');
+ return $this;
+ }
+
+ public function put() {
+ $this->method('put');
+ return $this;
+ }
+
+ public function delete() {
+ $this->method('delete');
+ return $this;
+ }
+
+ public function defaults($defaults) {
+ $action = $this->getDefault('action');
+ $this->setDefaults($defaults);
+ if (isset($defaults['action'])) {
+ $action = $defaults['action'];
+ }
+ $this->action($action);
+ return $this;
+ }
+
+ public function requirements($requirements) {
+ $method = $this->getRequirement('_method');
+ $this->setRequirements($requirements);
+ if (isset($requirements['_method'])) {
+ $method = $requirements['_method'];
+ }
+ $this->method($method);
+ return $this;
+ }
+
+ public function action($class, $function = null) {
+ $action = array($class, $function);
+ if (is_null($function)) {
+ $action = $class;
+ }
+ $this->setDefault('action', $action);
+ return $this;
+ }
+}
diff --git a/lib/router.php b/lib/router.php
new file mode 100644
index 00000000000..f037ecdfef4
--- /dev/null
+++ b/lib/router.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+use Symfony\Component\Routing\Matcher\UrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\RouteCollection;
+//use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+
+class OC_Router {
+ protected $collections = array();
+ protected $collection = null;
+
+ public function useCollection($name) {
+ if (!isset($this->collections[$name])) {
+ $this->collections[$name] = new RouteCollection();
+ }
+ $this->collection = $this->collections[$name];
+ }
+
+ public function create($name, $pattern, array $defaults = array(), array $requirements = array()) {
+ $route = new OC_Route($pattern, $defaults, $requirements);
+ $this->collection->add($name, $route);
+ return $route;
+ }
+
+ public function match($url) {
+ $context = new RequestContext($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
+ $matcher = new UrlMatcher($this->collection, $context);
+ $parameters = $matcher->match($url);
+ if (isset($parameters['action'])) {
+ $action = $parameters['action'];
+ if (!is_callable($action)) {
+ var_dump($action);
+ throw new Exception('not a callable action');
+ }
+ unset($parameters['action']);
+ call_user_func($action, $parameters);
+ } elseif (isset($parameters['file'])) {
+ include ($parameters['file']);
+ } else {
+ throw new Exception('no action available');
+ }
+ }
+}
diff --git a/lib/search/provider.php b/lib/search/provider.php
index 838ab696d04..b3ee79b4770 100644
--- a/lib/search/provider.php
+++ b/lib/search/provider.php
@@ -2,13 +2,17 @@
/**
* provides search functionalty
*/
-class OC_Search_Provider {
- public function __construct($options){}
+abstract class OC_Search_Provider {
+ private $options;
+
+ public function __construct($options){
+ $this->options=$options;
+ }
/**
* search for $query
* @param string $query
* @return array An array of OC_Search_Result's
*/
- public function search($query){}
+ abstract public function search($query);
}
diff --git a/lib/setup.php b/lib/setup.php
index bad0f5301c7..4d71bed86e2 100644
--- a/lib/setup.php
+++ b/lib/setup.php
@@ -102,7 +102,6 @@ class OC_Setup {
}
else {
$oldUser=OC_Config::getValue('dbuser', false);
- $oldPassword=OC_Config::getValue('dbpassword', false);
$query="SELECT user FROM mysql.user WHERE user='$dbuser'"; //this should be enough to check for admin rights in mysql
if(mysql_query($query, $connection)) {
@@ -257,7 +256,7 @@ class OC_Setup {
OC_Installer::installShippedApps();
//create htaccess files for apache hosts
- if (strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
+ if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) {
self::createHtaccess();
}
@@ -380,5 +379,3 @@ class OC_Setup {
file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/index.html', '');
}
}
-
-?>
diff --git a/lib/streamwrappers.php b/lib/streamwrappers.php
index f1e0fa0e1d9..f502c6170bd 100644
--- a/lib/streamwrappers.php
+++ b/lib/streamwrappers.php
@@ -1,6 +1,4 @@
<?php
-global $FAKEDIRS;
-$FAKEDIRS=array();
class OC_FakeDirStream{
public static $dirs=array();
@@ -8,8 +6,6 @@ class OC_FakeDirStream{
private $index;
public function dir_opendir($path,$options){
- global $FAKEDIRS;
- $url=parse_url($path);
$this->name=substr($path,strlen('fakedir://'));
$this->index=0;
if(!isset(self::$dirs[$this->name])){
@@ -161,7 +157,6 @@ class OC_StaticStreamWrapper {
public function stream_write($data) {
if (!$this->writable) return 0;
$size = strlen($data);
- $len = strlen(self::$data[$this->path]);
if ($this->stream_eof()) {
self::$data[$this->path] .= $data;
} else {
diff --git a/lib/template.php b/lib/template.php
index 3b48c27b9b4..5b6999af533 100644
--- a/lib/template.php
+++ b/lib/template.php
@@ -82,7 +82,6 @@ function relative_modified_date($timestamp) {
$diffhours = round($diffminutes/60);
$diffdays = round($diffhours/24);
$diffmonths = round($diffdays/31);
- $diffyears = round($diffdays/365);
if($timediff < 60) { return $l->t('seconds ago'); }
else if($timediff < 120) { return $l->t('1 minute ago'); }
diff --git a/lib/templatelayout.php b/lib/templatelayout.php
index d33a87e9e4c..588a7845997 100644
--- a/lib/templatelayout.php
+++ b/lib/templatelayout.php
@@ -123,7 +123,7 @@ class OC_TemplateLayout extends OC_Template {
elseif(self::appendIfExist($files, $apps_dir['path'], $apps_dir['url'], "$style.css")) { $append =true; break; }
}
if(! $append) {
- echo('css file not found: style:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
+ echo('css file not found: style:'.$style.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT);
die();
}
}
diff --git a/lib/updater.php b/lib/updater.php
index 5d97178c30e..332cea03bfc 100644
--- a/lib/updater.php
+++ b/lib/updater.php
@@ -84,4 +84,3 @@ class OC_Updater{
}
}
-?>
diff --git a/lib/user.php b/lib/user.php
index d02c1208a8d..e3c9c23effa 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -21,7 +21,7 @@
*/
/**
- * This class provides wrapper methods for user management. Multiple backends are
+ * This class provides wrapper methods for user management. Multiple backends are
* supported. User management operations are delegated to the configured backend for
* execution.
*
@@ -50,8 +50,8 @@ class OC_User {
*
* Makes a list of backends that can be used by other modules
*/
- public static function registerBackend( $name ){
- self::$_backends[] = $name;
+ public static function registerBackend( $backend ){
+ self::$_backends[] = $backend;
return true;
}
@@ -83,28 +83,38 @@ class OC_User {
* Set the User Authentication Module
*/
public static function useBackend( $backend = 'database' ){
- // You'll never know what happens
- if( null === $backend OR !is_string( $backend )){
- $backend = 'database';
- }
+ if($backend instanceof OC_User_Interface){
+ self::$_usedBackends[get_class($backend)]=$backend;
+ }else{
+ // You'll never know what happens
+ if( null === $backend OR !is_string( $backend )){
+ $backend = 'database';
+ }
- // Load backend
- switch( $backend ){
- case 'database':
- case 'mysql':
- case 'sqlite':
- self::$_usedBackends[$backend] = new OC_User_Database();
- break;
- default:
- $className = 'OC_USER_' . strToUpper($backend);
- self::$_usedBackends[$backend] = new $className();
- break;
+ // Load backend
+ switch( $backend ){
+ case 'database':
+ case 'mysql':
+ case 'sqlite':
+ self::$_usedBackends[$backend] = new OC_User_Database();
+ break;
+ default:
+ $className = 'OC_USER_' . strToUpper($backend);
+ self::$_usedBackends[$backend] = new $className();
+ break;
+ }
}
-
true;
}
/**
+ * remove all used backends
+ */
+ public static function clearBackends(){
+ self::$_usedBackends=array();
+ }
+
+ /**
* @brief Create a new user
* @param $uid The username of the user to create
* @param $password The password of the new user
@@ -200,7 +210,7 @@ class OC_User {
if( $run ){
$uid=self::checkPassword( $uid, $password );
if($uid){
- session_regenerate_id();
+ session_regenerate_id(true);
self::setUserId($uid);
OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>$password ));
return true;
@@ -345,17 +355,13 @@ class OC_User {
* @return boolean
*/
public static function userExists($uid){
- static $user_exists_checked = null;
- if (!is_null($user_exists_checked)) {
- return $user_exists_checked;
- }
foreach(self::$_usedBackends as $backend){
$result=$backend->userExists($uid);
if($result===true){
- return $user_exists_checked = true;
+ return true;
}
}
- return $user_exists_checked = false;
+ return false;
}
/**
diff --git a/lib/user/backend.php b/lib/user/backend.php
index be068a63ce0..daa942d261c 100644
--- a/lib/user/backend.php
+++ b/lib/user/backend.php
@@ -42,7 +42,7 @@ define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100);
*
* Subclass this for your own backends, and see OC_User_Example for descriptions
*/
-abstract class OC_User_Backend {
+abstract class OC_User_Backend implements OC_User_Interface {
protected $possibleActions = array(
OC_USER_BACKEND_CREATE_USER => 'createUser',
diff --git a/lib/user/database.php b/lib/user/database.php
index a48b8357d64..cc27b3ddbfd 100644
--- a/lib/user/database.php
+++ b/lib/user/database.php
@@ -39,7 +39,6 @@ require_once 'phpass/PasswordHash.php';
* Class for user management in a SQL Database (e.g. MySQL, SQLite)
*/
class OC_User_Database extends OC_User_Backend {
- static private $userGroupCache=array();
/**
* @var PasswordHash
*/
@@ -87,7 +86,7 @@ class OC_User_Database extends OC_User_Backend {
public function deleteUser( $uid ){
// Delete user-group-relation
$query = OC_DB::prepare( "DELETE FROM `*PREFIX*users` WHERE uid = ?" );
- $result = $query->execute( array( $uid ));
+ $query->execute( array( $uid ));
return true;
}
@@ -104,11 +103,10 @@ class OC_User_Database extends OC_User_Backend {
$hasher=$this->getHasher();
$hash = $hasher->HashPassword($password.OC_Config::getValue('passwordsalt', ''));
$query = OC_DB::prepare( "UPDATE *PREFIX*users SET password = ? WHERE uid = ?" );
- $result = $query->execute( array( $hash, $uid ));
+ $query->execute( array( $hash, $uid ));
return true;
- }
- else{
+ }else{
return false;
}
}
diff --git a/lib/user/example.php b/lib/user/example.php
index 7f3fd1b8578..77246d8136c 100644
--- a/lib/user/example.php
+++ b/lib/user/example.php
@@ -35,9 +35,7 @@ abstract class OC_User_Example extends OC_User_Backend {
* Creates a new user. Basic checking of username is done in OC_User
* itself, not in its subclasses.
*/
- public function createUser($uid, $password){
- return OC_USER_BACKEND_NOT_IMPLEMENTED;
- }
+ abstract public function createUser($uid, $password);
/**
* @brief Set password
@@ -47,9 +45,7 @@ abstract class OC_User_Example extends OC_User_Backend {
*
* Change the password of a user
*/
- public function setPassword($uid, $password){
- return OC_USER_BACKEND_NOT_IMPLEMENTED;
- }
+ abstract public function setPassword($uid, $password);
/**
* @brief Check if the password is correct
@@ -60,7 +56,5 @@ abstract class OC_User_Example extends OC_User_Backend {
* Check if the password is correct without logging in the user
* returns the user id or false
*/
- public function checkPassword($uid, $password){
- return OC_USER_BACKEND_NOT_IMPLEMENTED;
- }
+ abstract public function checkPassword($uid, $password);
}
diff --git a/lib/user/interface.php b/lib/user/interface.php
new file mode 100644
index 00000000000..dc3685dc20d
--- /dev/null
+++ b/lib/user/interface.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * ownCloud - user interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+interface OC_User_Interface {
+
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function implementsActions($actions);
+
+ /**
+ * @brief delete a user
+ * @param $uid The username of the user to delete
+ * @returns true/false
+ *
+ * Deletes a user
+ */
+ public function deleteUser($uid);
+
+ /**
+ * @brief Get a list of all users
+ * @returns array with all uids
+ *
+ * Get a list of all users.
+ */
+ public function getUsers();
+
+ /**
+ * @brief check if a user exists
+ * @param string $uid the username
+ * @return boolean
+ */
+ public function userExists($uid);
+
+} \ No newline at end of file
diff --git a/lib/util.php b/lib/util.php
index 2a7b8a922f9..0c563278cc5 100755
--- a/lib/util.php
+++ b/lib/util.php
@@ -77,13 +77,13 @@ class OC_Util {
return '5 pre alpha';
}
- /**
- * get the current installed edition of ownCloud. There is the community edition that just returns an empty string and the enterprise edition that returns "Enterprise".
- * @return string
- */
- public static function getEditionString(){
- return '';
- }
+ /**
+ * get the current installed edition of ownCloud. There is the community edition that just returns an empty string and the enterprise edition that returns "Enterprise".
+ * @return string
+ */
+ public static function getEditionString(){
+ return '';
+ }
/**
* add a javascript file
@@ -131,12 +131,12 @@ class OC_Util {
self::$headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text);
}
- /**
- * formats a timestamp in the "right" way
- *
- * @param int timestamp $timestamp
- * @param bool dateOnly option to ommit time from the result
- */
+ /**
+ * formats a timestamp in the "right" way
+ *
+ * @param int timestamp $timestamp
+ * @param bool dateOnly option to ommit time from the result
+ */
public static function formatDate( $timestamp,$dateOnly=false){
if(isset($_SESSION['timezone'])){//adjust to clients timezone if we know it
$systemTimeZone = intval(date('O'));
@@ -189,8 +189,6 @@ class OC_Util {
if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') and !is_callable('pg_connect')){
$errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.<br/>','hint'=>'');//TODO: sane hint
}
- $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" );
- $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" );
//common hint for all file permissons error messages
$permissionsHint="Permissions can usually be fixed by giving the webserver write access to the ownCloud directory";
@@ -440,26 +438,25 @@ class OC_Util {
}
- /**
- * Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
- */
- public static function ishtaccessworking() {
-
+ /**
+ * Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
+ */
+ public static function ishtaccessworking() {
// testdata
$filename='/htaccesstest.txt';
$testcontent='testcontent';
// creating a test file
- $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
- $fp = @fopen($testfile, 'w');
- @fwrite($fp, $testcontent);
- @fclose($fp);
+ $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
+ $fp = @fopen($testfile, 'w');
+ @fwrite($fp, $testcontent);
+ @fclose($fp);
// accessing the file via http
- $url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename;
- $fp = @fopen($url, 'r');
- $content=@fread($fp, 2048);
- @fclose($fp);
+ $url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename;
+ $fp = @fopen($url, 'r');
+ $content=@fread($fp, 2048);
+ @fclose($fp);
// cleanup
@unlink($testfile);
@@ -469,13 +466,7 @@ class OC_Util {
return(false);
}else{
return(true);
-
}
-
- }
-
-
-
-
+ }
}
diff --git a/lib/vcategories.php b/lib/vcategories.php
index 8157c343868..d15b7b166ea 100644
--- a/lib/vcategories.php
+++ b/lib/vcategories.php
@@ -131,8 +131,10 @@ class OC_VCategories {
* }
* $categories->rescan($objects);
*/
- public function rescan($objects, $sync=true) {
- $this->categories = array();
+ public function rescan($objects, $sync=true, $reset=true) {
+ if($reset === true) {
+ $this->categories = array();
+ }
foreach($objects as $object) {
//OC_Log::write('core','OC_VCategories::rescan: '.substr($object, 0, 100).'(...)', OC_Log::DEBUG);
$vobject = OC_VObject::parse($object);
@@ -221,4 +223,3 @@ class OC_VCategories {
}
}
-?>
diff --git a/ocs/providers.php b/ocs/providers.php
index adaa28db6cd..cc6de32266b 100644
--- a/ocs/providers.php
+++ b/ocs/providers.php
@@ -35,11 +35,10 @@ echo('
<termsofuse></termsofuse>
<register></register>
<services>
- <activity ocsversion="1.5" />
+ <config ocsversion="1.7" />
+ <activity ocsversion="1.7" />
+ <cloud ocsversion="1.7" />
</services>
</provider>
</providers>
');
-
-
-?>
diff --git a/ocs/v1.php b/ocs/v1.php
index 77dd75b9fc2..ab0dc80f4ba 100644
--- a/ocs/v1.php
+++ b/ocs/v1.php
@@ -24,5 +24,3 @@
require_once('../lib/base.php');
@ob_clean();
OC_OCS::handle();
-
-?>
diff --git a/public.php b/public.php
index 8846769f467..8383f36a246 100644
--- a/public.php
+++ b/public.php
@@ -10,6 +10,7 @@ if(is_null($file)){
$parts=explode('/',$file,2);
$app=$parts[0];
+
OC_Util::checkAppEnabled($app);
OC_App::loadApp($app);
diff --git a/remote.php b/remote.php
index bdce867aaba..8461eea19ad 100644
--- a/remote.php
+++ b/remote.php
@@ -15,27 +15,27 @@ if (!$pos = strpos($path_info, '/', 1)) {
$pos = strlen($path_info);
}
$service=substr($path_info, 1, $pos-1);
+
$file = OC_AppConfig::getValue('core', 'remote_' . $service);
-$file = preg_replace('/apps\//','', $file); //Todo Remove after Multiappdir migration
if(is_null($file)){
OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
exit;
}
-$file = ltrim ($file, '/');
+$file=ltrim($file,'/');
$parts=explode('/', $file, 2);
$app=$parts[0];
switch ($app) {
+ case 'core':
+ $file = OC::$SERVERROOT .'/'. $file;
+ break;
default:
OC_Util::checkAppEnabled($app);
OC_App::loadApp($app);
$file = OC_App::getAppPath($app) .'/'. $parts[1];
break;
- case 'core':
- $file = OC::$SERVERROOT .'/'. $file;
- break;
}
$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
require_once($file);
diff --git a/search/ajax/search.php b/search/ajax/search.php
index 326724d60c4..95ddfedf8ba 100644
--- a/search/ajax/search.php
+++ b/search/ajax/search.php
@@ -35,5 +35,3 @@ if($query){
}else{
echo 'false';
}
-
-?>
diff --git a/search/index.php b/search/index.php
index 518695c56d2..de55aec3999 100644
--- a/search/index.php
+++ b/search/index.php
@@ -49,5 +49,3 @@ foreach($results as $result){
$tmpl = new OC_Template( 'search', 'index', 'user' );
$tmpl->assign('resultTypes',$resultTypes);
$tmpl->printPage();
-
-?>
diff --git a/settings/ajax/changepassword.php b/settings/ajax/changepassword.php
index 860ea987871..4ba6813517b 100644
--- a/settings/ajax/changepassword.php
+++ b/settings/ajax/changepassword.php
@@ -9,6 +9,8 @@ $oldPassword=isset($_POST["oldpassword"])?$_POST["oldpassword"]:'';
// Check if we are a user
OC_JSON::checkLoggedIn();
+OCP\JSON::callCheck();
+
if( (!OC_Group::inGroup( OC_User::getUser(), 'admin' ) && ($username!=OC_User::getUser() || !OC_User::checkPassword($username,$oldPassword)))) {
OC_JSON::error( array( "data" => array( "message" => "Authentication error" )));
exit();
@@ -21,5 +23,3 @@ if( OC_User::setPassword( $username, $password )){
else{
OC_JSON::error(array("data" => array( "message" => "Unable to change password" )));
}
-
-?>
diff --git a/settings/ajax/creategroup.php b/settings/ajax/creategroup.php
index 57d82e7bd94..af8ad3dd8c0 100644
--- a/settings/ajax/creategroup.php
+++ b/settings/ajax/creategroup.php
@@ -9,6 +9,8 @@ if( !OC_User::isLoggedIn() || !OC_Group::inGroup( OC_User::getUser(), 'admin' ))
exit();
}
+OCP\JSON::callCheck();
+
$groupname = $_POST["groupname"];
// Does the group exist?
@@ -24,5 +26,3 @@ if( OC_Group::createGroup( $groupname )){
else{
OC_JSON::error(array("data" => array( "message" => "Unable to add group" )));
}
-
-?>
diff --git a/settings/ajax/createuser.php b/settings/ajax/createuser.php
index 6714711bc87..c56df4bc15a 100644
--- a/settings/ajax/createuser.php
+++ b/settings/ajax/createuser.php
@@ -8,6 +8,7 @@ if( !OC_User::isLoggedIn() || !OC_Group::inGroup( OC_User::getUser(), 'admin' ))
OC_JSON::error(array("data" => array( "message" => "Authentication error" )));
exit();
}
+OCP\JSON::callCheck();
$groups = array();
if( isset( $_POST["groups"] )){
@@ -35,5 +36,3 @@ try {
} catch (Exception $exception) {
OC_JSON::error(array("data" => array( "message" => $exception->getMessage())));
}
-
-?>
diff --git a/settings/ajax/disableapp.php b/settings/ajax/disableapp.php
index 53e9be379e1..cc006988707 100644
--- a/settings/ajax/disableapp.php
+++ b/settings/ajax/disableapp.php
@@ -2,6 +2,7 @@
// Init owncloud
require_once('../../lib/base.php');
OC_JSON::checkAdminUser();
+OCP\JSON::callCheck();
OC_JSON::setContentTypeHeader();
OC_App::disable($_POST['appid']);
diff --git a/settings/ajax/enableapp.php b/settings/ajax/enableapp.php
index cb116ebe4e8..bd53a50210c 100644
--- a/settings/ajax/enableapp.php
+++ b/settings/ajax/enableapp.php
@@ -3,6 +3,7 @@
// Init owncloud
require_once('../../lib/base.php');
OC_JSON::checkAdminUser();
+OCP\JSON::callCheck();
OC_JSON::setContentTypeHeader();
if(OC_App::enable($_POST['appid'])){
diff --git a/settings/ajax/lostpassword.php b/settings/ajax/lostpassword.php
index c6df8551f52..803a424854c 100644
--- a/settings/ajax/lostpassword.php
+++ b/settings/ajax/lostpassword.php
@@ -2,8 +2,8 @@
// Init owncloud
require_once('../../lib/base.php');
-
OC_JSON::checkLoggedIn();
+OCP\JSON::callCheck();
$l=OC_L10N::get('core');
@@ -15,5 +15,3 @@ if( isset( $_POST['email'] ) && filter_var( $_POST['email'], FILTER_VALIDATE_EMA
}else{
OC_JSON::error(array("data" => array( "message" => $l->t("Invalid email") )));
}
-
-?>
diff --git a/settings/ajax/openid.php b/settings/ajax/openid.php
index 58d071255c2..bf4ead06020 100644
--- a/settings/ajax/openid.php
+++ b/settings/ajax/openid.php
@@ -6,6 +6,7 @@ require_once('../../lib/base.php');
$l=OC_L10N::get('settings');
OC_JSON::checkLoggedIn();
+OCP\JSON::callCheck();
OC_JSON::checkAppEnabled('user_openid');
// Get data
@@ -16,5 +17,3 @@ if( isset( $_POST['identity'] ) ){
}else{
OC_JSON::error(array("data" => array( "message" => $l->t("Invalid request") )));
}
-
-?>
diff --git a/settings/ajax/removegroup.php b/settings/ajax/removegroup.php
index 4d364781894..f8c2065956c 100644
--- a/settings/ajax/removegroup.php
+++ b/settings/ajax/removegroup.php
@@ -4,6 +4,7 @@
require_once('../../lib/base.php');
OC_JSON::checkAdminUser();
+OCP\JSON::callCheck();
$name = $_POST["groupname"];
@@ -14,5 +15,3 @@ if( OC_Group::deleteGroup( $name )){
else{
OC_JSON::error(array("data" => array( "message" => "Unable to delete group" )));
}
-
-?>
diff --git a/settings/ajax/removeuser.php b/settings/ajax/removeuser.php
index 2c288997a1f..230815217c3 100644
--- a/settings/ajax/removeuser.php
+++ b/settings/ajax/removeuser.php
@@ -4,6 +4,7 @@
require_once('../../lib/base.php');
OC_JSON::checkAdminUser();
+OCP\JSON::callCheck();
$username = $_POST["username"];
@@ -14,5 +15,3 @@ if( OC_User::deleteUser( $username )){
else{
OC_JSON::error(array("data" => array( "message" => "Unable to delete user" )));
}
-
-?>
diff --git a/settings/ajax/setlanguage.php b/settings/ajax/setlanguage.php
index e3b00c3bc80..54b103cd4fe 100644
--- a/settings/ajax/setlanguage.php
+++ b/settings/ajax/setlanguage.php
@@ -6,6 +6,7 @@ require_once('../../lib/base.php');
$l=OC_L10N::get('settings');
OC_JSON::checkLoggedIn();
+OCP\JSON::callCheck();
// Get data
@@ -21,5 +22,3 @@ if( isset( $_POST['lang'] ) ){
}else{
OC_JSON::error(array("data" => array( "message" => $l->t("Invalid request") )));
}
-
-?>
diff --git a/settings/ajax/setloglevel.php b/settings/ajax/setloglevel.php
index 298cbd64738..4b97ba2aa32 100644
--- a/settings/ajax/setloglevel.php
+++ b/settings/ajax/setloglevel.php
@@ -7,6 +7,7 @@
require_once('../../lib/base.php');
OC_Util::checkAdminUser();
+OCP\JSON::callCheck();
OC_Config::setValue( 'loglevel', $_POST['level'] );
diff --git a/settings/ajax/setquota.php b/settings/ajax/setquota.php
index f59017600ac..2b412c0f2fd 100644
--- a/settings/ajax/setquota.php
+++ b/settings/ajax/setquota.php
@@ -9,6 +9,7 @@
require_once('../../lib/base.php');
OC_JSON::checkAdminUser();
+OCP\JSON::callCheck();
$username = isset($_POST["username"])?$_POST["username"]:'';
@@ -34,4 +35,3 @@ if($username){
}
OC_JSON::success(array("data" => array( "username" => $username ,'quota'=>$quota)));
-?>
diff --git a/settings/ajax/togglegroups.php b/settings/ajax/togglegroups.php
index 7773c1049c3..95338ed0267 100644
--- a/settings/ajax/togglegroups.php
+++ b/settings/ajax/togglegroups.php
@@ -4,6 +4,7 @@
require_once('../../lib/base.php');
OC_JSON::checkAdminUser();
+OCP\JSON::callCheck();
$success = true;
$error = "add user to";
@@ -37,5 +38,3 @@ if( $success ){
else{
OC_JSON::error(array("data" => array( "message" => "Unable to $error group $group" )));
}
-
-?>
diff --git a/settings/apps.php b/settings/apps.php
index f4ae8b8d977..762395c031b 100644
--- a/settings/apps.php
+++ b/settings/apps.php
@@ -97,5 +97,3 @@ $appid = (isset($_GET['appid'])?strip_tags($_GET['appid']):'');
$tmpl->assign('appid',$appid);
$tmpl->printPage();
-
-?>
diff --git a/settings/help.php b/settings/help.php
index f0abed8f558..b1dc1c5be77 100644
--- a/settings/help.php
+++ b/settings/help.php
@@ -25,5 +25,3 @@ $tmpl->assign( "kbe", $kbe );
$tmpl->assign( "pagecount", $pagecount );
$tmpl->assign( "page", $page );
$tmpl->printPage();
-
-?>
diff --git a/settings/js/users.js b/settings/js/users.js
index dfa28e4c4cb..63ad426ecf4 100644
--- a/settings/js/users.js
+++ b/settings/js/users.js
@@ -47,25 +47,24 @@ UserList={
if( !UserList.deleteCanceled && UserList.deleteUid ){
// Delete user via ajax
- $.post(
- OC.filePath('settings','ajax','removeuser.php'),
- {username:UserList.deleteUid},
- function(result){
-
- // Remove undo option, & remove user from table
- boolOperationFinished(
- data, function(){
- $('#notification').fadeOut();
- $('tr').filterAttr( 'data-uid', username ).remove();
- UserList.deleteCanceled=true;
- UserList.deleteFiles=null;
- if( ready ){
- ready();
- }
+ $.ajax({
+ type: 'POST',
+ url: OC.filePath('settings', 'ajax', 'removeuser.php'),
+ async: false,
+ data: { username: UserList.deleteUid },
+ success: function(result) {
+ if (result.status == 'success') {
+ // Remove undo option, & remove user from table
+ $('#notification').fadeOut();
+ $('tr').filterAttr('data-uid', UserList.deleteUid).remove();
+ UserList.deleteCanceled = true;
+ UserList.deleteFiles = null;
+ if (ready) {
+ ready();
}
- );
+ }
}
- );
+ });
}
}
}
@@ -186,7 +185,7 @@ $(document).ready(function(){
})
$('input.quota-other').live('change',function(){
- var uid=$(this).parent().parent().data('uid');
+ var uid=$(this).parent().parent().parent().data('uid');
var quota=$(this).val();
var select=$(this).prev();
var other=$(this);
diff --git a/settings/personal.php b/settings/personal.php
index 26a9f601d9a..d82db0d0e7e 100644
--- a/settings/personal.php
+++ b/settings/personal.php
@@ -17,7 +17,7 @@ OC_App::setActiveNavigationEntry( 'personal' );
// calculate the disc space
$rootInfo=OC_FileCache::get('');
-$sharedInfo=OC_FileCache::get('/Shared');
+$sharedInfo=OC_FileCache::get('/Shared');
$used=$rootInfo['size']-$sharedInfo['size'];
$free=OC_Filesystem::free_space();
$total=$free+$used;
@@ -61,5 +61,3 @@ foreach($forms as $form){
$tmpl->append('forms',$form);
}
$tmpl->printPage();
-
-?>
diff --git a/settings/users.php b/settings/users.php
index 026a30a750c..c3259d2a3f1 100644
--- a/settings/users.php
+++ b/settings/users.php
@@ -48,6 +48,3 @@ $tmpl->assign( 'quota_preset', $quotaPreset);
$tmpl->assign( 'default_quota', $defaultQuota);
$tmpl->assign( 'share_notice', $shareNotice);
$tmpl->printPage();
-
-?>
-
diff --git a/status.php b/status.php
index 2d31702ecb3..f314a3a1c6f 100644
--- a/status.php
+++ b/status.php
@@ -29,6 +29,3 @@ if(OC_Config::getValue('installed')==1) $installed='true'; else $installed='fals
$values=array('installed'=>$installed,'version'=>implode('.',OC_Util::getVersion()),'versionstring'=>OC_Util::getVersionString(),'edition'=>OC_Util::getEditionString());
echo(json_encode($values));
-
-
-?>
diff --git a/tests/index.php b/tests/index.php
index 691bf2a5d45..0be27ee3fd7 100644
--- a/tests/index.php
+++ b/tests/index.php
@@ -26,39 +26,64 @@ require_once 'simpletest/mock_objects.php';
require_once 'simpletest/collector.php';
require_once 'simpletest/default_reporter.php';
+$testSuiteName="ownCloud Unit Test Suite";
+
+// prepare the reporter
+if(OC::$CLI){
+ $reporter=new TextReporter;
+ $test=isset($_SERVER['argv'][1])?$_SERVER['argv'][1]:false;
+ if($test=='xml'){
+ $reporter= new XmlReporter;
+ $test=false;
+
+ if(isset($_SERVER['argv'][2])){
+ $testSuiteName=$testSuiteName." (".$_SERVER['argv'][2].")";
+ }
+ }
+}else{
+ $reporter=new HtmlReporter;
+ $test=isset($_GET['test'])?$_GET['test']:false;
+}
+
+// test suite instance
+$testSuite=new TestSuite($testSuiteName);
+
//load core test cases
-loadTests(dirname(__FILE__));
+loadTests(dirname(__FILE__), $testSuite, $test);
//load app test cases
+
+//
+// TODO: define a list of apps to be enabled + enable them
+//
+
$apps=OC_App::getEnabledApps();
foreach($apps as $app){
if(is_dir(OC::$SERVERROOT.'/apps/'.$app.'/tests')){
- loadTests(OC::$SERVERROOT.'/apps/'.$app.'/tests');
+ loadTests(OC::$SERVERROOT.'/apps/'.$app.'/tests', $testSuite, $test);
}
}
-function loadTests($dir=''){
- if(OC::$CLI){
- $reporter='TextReporter';
- $test=isset($_SERVER['argv'][1])?$_SERVER['argv'][1]:false;
- }else{
- $reporter='HtmlReporter';
- $test=isset($_GET['test'])?$_GET['test']:false;
- }
+// run the suite
+if($testSuite->getSize()>0){
+ $testSuite->run($reporter);
+}
+
+// helper below
+function loadTests($dir,$testSuite, $test){
if($dh=opendir($dir)){
while($name=readdir($dh)){
if($name[0]!='.'){//no hidden files, '.' or '..'
$file=$dir.'/'.$name;
if(is_dir($file)){
- loadTests($file);
+ loadTests($file, $testSuite, $test);
}elseif(substr($file,-4)=='.php' and $file!=__FILE__){
$name=getTestName($file);
if($test===false or $test==$name or substr($name,0,strlen($test))==$test){
- $testCase=new TestSuite($name);
- $testCase->addFile($file);
- if($testCase->getSize()>0){
- $testCase->run(new $reporter());
- }
+ $extractor = new SimpleFileLoader();
+ $loadedSuite=$extractor->load($file);
+ if ($loadedSuite->getSize() > 0)
+ $testSuite->add($loadedSuite);
}
}
}
diff --git a/tests/lib/cache.php b/tests/lib/cache.php
index bb5cfc6ee19..511999be956 100644
--- a/tests/lib/cache.php
+++ b/tests/lib/cache.php
@@ -42,6 +42,27 @@ abstract class Test_Cache extends UnitTestCase {
$this->assertNull($this->instance->get('not_set'),'Unset value not equal to null');
$this->assertTrue($this->instance->remove('value1'));
+ $this->assertFalse($this->instance->hasKey('value1'));
+ }
+
+ function testClear(){
+ $value='ipsum lorum';
+ $this->instance->set('1_value1',$value);
+ $this->instance->set('1_value2',$value);
+ $this->instance->set('2_value1',$value);
+ $this->instance->set('3_value1',$value);
+
+ $this->assertTrue($this->instance->clear('1_'));
+ $this->assertFalse($this->instance->hasKey('1_value1'));
+ $this->assertFalse($this->instance->hasKey('1_value2'));
+ $this->assertTrue($this->instance->hasKey('2_value1'));
+ $this->assertTrue($this->instance->hasKey('3_value1'));
+
+ $this->assertTrue($this->instance->clear());
+ $this->assertFalse($this->instance->hasKey('1_value1'));
+ $this->assertFalse($this->instance->hasKey('1_value2'));
+ $this->assertFalse($this->instance->hasKey('2_value1'));
+ $this->assertFalse($this->instance->hasKey('3_value1'));
}
function testTTL(){
diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php
index 54e60e6569d..28778efb68c 100644
--- a/tests/lib/cache/file.php
+++ b/tests/lib/cache/file.php
@@ -21,8 +21,10 @@
*/
class Test_Cache_File extends Test_Cache {
+ private $user;
+
function skip() {
- $this->skipUnless(OC_User::isLoggedIn());
+ //$this->skipUnless(OC_User::isLoggedIn());
}
public function setUp(){
@@ -30,17 +32,32 @@ class Test_Cache_File extends Test_Cache {
OC_FileProxy::clearProxies();
OC_Hook::clear('OC_Filesystem');
- //enable only the encryption hook
- OC_FileProxy::register(new OC_FileProxy_Encryption());
+ //enable only the encryption hook if needed
+ if(OC_App::isEnabled('files_encryption')){
+ OC_FileProxy::register(new OC_FileProxy_Encryption());
+ }
//set up temporary storage
OC_Filesystem::clearMounts();
OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/');
+ OC_User::clearBackends();
+ OC_User::useBackend(new OC_User_Dummy());
+
+ //login
+ OC_User::createUser('test', 'test');
+
+ $this->user=OC_User::getUser();
+ OC_User::setUserId('test');
+
//set up the users dir
$rootView=new OC_FilesystemView('');
- $rootView->mkdir('/'.OC_User::getUser());
+ $rootView->mkdir('/test');
$this->instance=new OC_Cache_File();
}
+
+ public function tearDown(){
+ OC_User::setUserId($this->user);
+ }
}
diff --git a/tests/lib/user/database.php b/tests/lib/user/database.php
index b2fcce93c5b..f484ffa78f7 100644
--- a/tests/lib/user/database.php
+++ b/tests/lib/user/database.php
@@ -21,7 +21,6 @@
*/
class Test_User_Database extends Test_User_Backend {
- private $user=array();
/**
* get a new unique user name
* test cases can override this in order to clean up created user
diff --git a/webapps.php b/webapps.php
deleted file mode 100644
index b5fee9bf85f..00000000000
--- a/webapps.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-/**
-* ownCloud status page. usefull if you want to check from the outside if an owncloud installation exists
-*
-* @author Frank Karlitschek
-* @copyright 2012 Frank Karlitschek frank@owncloud.org
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-$RUNTIME_NOAPPS = TRUE; //no apps, yet
-
-require_once('lib/base.php');
-
-
-//valid user account
-if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
-if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
-
-if(!OC_User::login($authuser,$authpw)){
- header('WWW-Authenticate: Basic realm="your valid user account"');
- header('HTTP/1.0 401 Unauthorized');
- exit;
-}else{
-
- $apps=OC_App::getEnabledApps();
- $values=array();
- foreach($apps as $app) {
- $info=OC_App::getAppInfo($app);
- if(isset($info['standalone'])) {
- $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
- $values[]=$newvalue;
- }
-
- }
-
- echo(json_encode($values));
- exit;
-
-
-}
-
-?>