summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBart Visscher <bartv@thisnet.nl>2013-10-02 18:23:59 +0200
committerBart Visscher <bartv@thisnet.nl>2013-10-02 18:23:59 +0200
commita90ea2c069998d378ec49825ce53b7651a459c1a (patch)
tree7b1afe4ef7dd5509f25c4be7829aa6834877a979 /lib
parent5db98aadd30b9f1218dda8f836acca0062ce1d9f (diff)
parent551e80979046358b9cbc8a0f8db0ff9cdf919e33 (diff)
downloadnextcloud-server-a90ea2c069998d378ec49825ce53b7651a459c1a.tar.gz
nextcloud-server-a90ea2c069998d378ec49825ce53b7651a459c1a.zip
Merge remote-tracking branch 'origin/master' into setup
Diffstat (limited to 'lib')
-rw-r--r--lib/autoloader.php11
-rw-r--r--lib/base.php26
-rw-r--r--lib/cache/fileglobalgc.php8
-rw-r--r--lib/l10n/lt_LT.php30
-rw-r--r--lib/private/allconfig.php77
-rw-r--r--lib/private/api.php (renamed from lib/api.php)0
-rw-r--r--lib/private/app.php (renamed from lib/app.php)45
-rw-r--r--lib/private/appconfig.php (renamed from lib/appconfig.php)0
-rw-r--r--lib/private/appframework/app.php98
-rw-r--r--lib/private/appframework/controller/controller.php142
-rw-r--r--lib/private/appframework/core/api.php348
-rw-r--r--lib/private/appframework/dependencyinjection/dicontainer.php146
-rw-r--r--lib/private/appframework/http/dispatcher.php100
-rw-r--r--lib/private/appframework/http/downloadresponse.php50
-rw-r--r--lib/private/appframework/http/http.php148
-rw-r--r--lib/private/appframework/http/redirectresponse.php56
-rw-r--r--lib/private/appframework/http/request.php307
-rw-r--r--lib/private/appframework/middleware/middleware.php100
-rw-r--r--lib/private/appframework/middleware/middlewaredispatcher.php159
-rw-r--r--lib/private/appframework/middleware/security/securityexception.php41
-rw-r--r--lib/private/appframework/middleware/security/securitymiddleware.php136
-rw-r--r--lib/private/appframework/routing/routeactionhandler.php42
-rw-r--r--lib/private/appframework/routing/routeconfig.php186
-rw-r--r--lib/private/appframework/utility/methodannotationreader.php61
-rw-r--r--lib/private/appframework/utility/simplecontainer.php44
-rw-r--r--lib/private/appframework/utility/timefactory.php42
-rw-r--r--lib/private/archive.php (renamed from lib/archive.php)3
-rw-r--r--lib/private/archive/tar.php (renamed from lib/archive/tar.php)0
-rw-r--r--lib/private/archive/zip.php (renamed from lib/archive/zip.php)0
-rw-r--r--lib/private/arrayparser.php (renamed from lib/arrayparser.php)0
-rw-r--r--lib/private/avatar.php89
-rw-r--r--lib/private/backgroundjob.php (renamed from lib/backgroundjob.php)0
-rw-r--r--lib/private/backgroundjob/job.php (renamed from lib/backgroundjob/job.php)0
-rw-r--r--lib/private/backgroundjob/joblist.php (renamed from lib/backgroundjob/joblist.php)0
-rw-r--r--lib/private/backgroundjob/legacy/queuedjob.php (renamed from lib/backgroundjob/legacy/queuedjob.php)0
-rw-r--r--lib/private/backgroundjob/legacy/regularjob.php (renamed from lib/backgroundjob/legacy/regularjob.php)0
-rw-r--r--lib/private/backgroundjob/queuedjob.php (renamed from lib/backgroundjob/queuedjob.php)0
-rw-r--r--lib/private/backgroundjob/timedjob.php (renamed from lib/backgroundjob/timedjob.php)0
-rw-r--r--lib/private/cache.php (renamed from lib/cache.php)23
-rw-r--r--lib/private/cache/broker.php (renamed from lib/cache/broker.php)12
-rw-r--r--lib/private/cache/file.php (renamed from lib/cache/file.php)24
-rw-r--r--lib/private/cache/fileglobal.php (renamed from lib/cache/fileglobal.php)29
-rw-r--r--lib/private/cache/fileglobalgc.php9
-rw-r--r--lib/private/cache/usercache.php77
-rw-r--r--lib/private/config.php (renamed from lib/config.php)0
-rw-r--r--lib/private/connector/sabre/ServiceUnavailable.php (renamed from lib/connector/sabre/ServiceUnavailable.php)0
-rw-r--r--lib/private/connector/sabre/aborteduploaddetectionplugin.php101
-rw-r--r--lib/private/connector/sabre/auth.php (renamed from lib/connector/sabre/auth.php)0
-rw-r--r--lib/private/connector/sabre/directory.php (renamed from lib/connector/sabre/directory.php)21
-rw-r--r--lib/private/connector/sabre/file.php (renamed from lib/connector/sabre/file.php)9
-rw-r--r--lib/private/connector/sabre/locks.php (renamed from lib/connector/sabre/locks.php)0
-rw-r--r--lib/private/connector/sabre/maintenanceplugin.php (renamed from lib/connector/sabre/maintenanceplugin.php)0
-rw-r--r--lib/private/connector/sabre/node.php (renamed from lib/connector/sabre/node.php)11
-rw-r--r--lib/private/connector/sabre/objecttree.php (renamed from lib/connector/sabre/objecttree.php)52
-rw-r--r--lib/private/connector/sabre/principal.php (renamed from lib/connector/sabre/principal.php)0
-rw-r--r--lib/private/connector/sabre/quotaplugin.php (renamed from lib/connector/sabre/quotaplugin.php)0
-rw-r--r--lib/private/connector/sabre/request.php (renamed from lib/connector/sabre/request.php)0
-rw-r--r--lib/private/contactsmanager.php145
-rw-r--r--lib/private/db.php (renamed from lib/db.php)10
-rw-r--r--lib/private/db/adapter.php (renamed from lib/db/adapter.php)0
-rw-r--r--lib/private/db/adapteroci8.php (renamed from lib/db/adapteroci8.php)0
-rw-r--r--lib/private/db/adapterpgsql.php (renamed from lib/db/adapterpgsql.php)0
-rw-r--r--lib/private/db/adaptersqlite.php (renamed from lib/db/adaptersqlite.php)0
-rw-r--r--lib/private/db/adaptersqlsrv.php (renamed from lib/db/adaptersqlsrv.php)0
-rw-r--r--lib/private/db/connection.php (renamed from lib/db/connection.php)2
-rw-r--r--lib/private/db/mdb2schemamanager.php (renamed from lib/db/mdb2schemamanager.php)0
-rw-r--r--lib/private/db/mdb2schemareader.php (renamed from lib/db/mdb2schemareader.php)0
-rw-r--r--lib/private/db/mdb2schemawriter.php (renamed from lib/db/mdb2schemawriter.php)0
-rw-r--r--lib/private/db/oracleconnection.php50
-rw-r--r--lib/private/db/statementwrapper.php (renamed from lib/db/statementwrapper.php)0
-rw-r--r--lib/private/defaults.php (renamed from lib/defaults.php)0
-rw-r--r--lib/private/eventsource.php (renamed from lib/eventsource.php)0
-rw-r--r--lib/private/filechunking.php (renamed from lib/filechunking.php)2
-rw-r--r--lib/private/fileproxy.php (renamed from lib/fileproxy.php)0
-rw-r--r--lib/private/fileproxy/fileoperations.php (renamed from lib/fileproxy/fileoperations.php)0
-rw-r--r--lib/private/files.php (renamed from lib/files.php)0
-rw-r--r--lib/private/files/cache/backgroundwatcher.php (renamed from lib/files/cache/backgroundwatcher.php)0
-rw-r--r--lib/private/files/cache/cache.php (renamed from lib/files/cache/cache.php)4
-rw-r--r--lib/private/files/cache/legacy.php (renamed from lib/files/cache/legacy.php)0
-rw-r--r--lib/private/files/cache/permissions.php (renamed from lib/files/cache/permissions.php)0
-rw-r--r--lib/private/files/cache/scanner.php (renamed from lib/files/cache/scanner.php)78
-rw-r--r--lib/private/files/cache/storage.php (renamed from lib/files/cache/storage.php)0
-rw-r--r--lib/private/files/cache/updater.php (renamed from lib/files/cache/updater.php)0
-rw-r--r--lib/private/files/cache/upgrade.php (renamed from lib/files/cache/upgrade.php)0
-rw-r--r--lib/private/files/cache/watcher.php (renamed from lib/files/cache/watcher.php)0
-rw-r--r--lib/private/files/filesystem.php (renamed from lib/files/filesystem.php)0
-rw-r--r--lib/private/files/mapper.php (renamed from lib/files/mapper.php)0
-rw-r--r--lib/private/files/mount/manager.php (renamed from lib/files/mount/manager.php)0
-rw-r--r--lib/private/files/mount/mount.php (renamed from lib/files/mount/mount.php)0
-rw-r--r--lib/private/files/node/file.php155
-rw-r--r--lib/private/files/node/folder.php382
-rw-r--r--lib/private/files/node/node.php245
-rw-r--r--lib/private/files/node/nonexistingfile.php89
-rw-r--r--lib/private/files/node/nonexistingfolder.php113
-rw-r--r--lib/private/files/node/root.php337
-rw-r--r--lib/private/files/storage/common.php (renamed from lib/files/storage/common.php)21
-rw-r--r--lib/private/files/storage/commontest.php (renamed from lib/files/storage/commontest.php)0
-rw-r--r--lib/private/files/storage/loader.php (renamed from lib/files/storage/loader.php)0
-rw-r--r--lib/private/files/storage/local.php (renamed from lib/files/storage/local.php)0
-rw-r--r--lib/private/files/storage/mappedlocal.php (renamed from lib/files/storage/mappedlocal.php)18
-rw-r--r--lib/private/files/storage/storage.php (renamed from lib/files/storage/storage.php)2
-rw-r--r--lib/private/files/storage/temporary.php (renamed from lib/files/storage/temporary.php)0
-rw-r--r--lib/private/files/storage/wrapper/quota.php (renamed from lib/files/storage/wrapper/quota.php)0
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php (renamed from lib/files/storage/wrapper/wrapper.php)0
-rw-r--r--lib/private/files/stream/close.php (renamed from lib/files/stream/close.php)0
-rw-r--r--lib/private/files/stream/dir.php (renamed from lib/files/stream/dir.php)0
-rw-r--r--lib/private/files/stream/oc.php (renamed from lib/files/stream/oc.php)0
-rw-r--r--lib/private/files/stream/quota.php (renamed from lib/files/stream/quota.php)0
-rw-r--r--lib/private/files/stream/staticstream.php (renamed from lib/files/stream/staticstream.php)0
-rw-r--r--lib/private/files/type/detection.php (renamed from lib/files/type/detection.php)0
-rw-r--r--lib/private/files/type/templatemanager.php (renamed from lib/files/type/templatemanager.php)0
-rw-r--r--lib/private/files/utils/scanner.php (renamed from lib/files/utils/scanner.php)6
-rw-r--r--lib/private/files/view.php (renamed from lib/files/view.php)22
-rw-r--r--lib/private/geo.php (renamed from lib/geo.php)0
-rw-r--r--lib/private/group.php (renamed from lib/group.php)0
-rw-r--r--lib/private/group/backend.php (renamed from lib/group/backend.php)0
-rw-r--r--lib/private/group/database.php (renamed from lib/group/database.php)0
-rw-r--r--lib/private/group/dummy.php (renamed from lib/group/dummy.php)0
-rw-r--r--lib/private/group/example.php (renamed from lib/group/example.php)0
-rw-r--r--lib/private/group/group.php (renamed from lib/group/group.php)0
-rw-r--r--lib/private/group/interface.php (renamed from lib/group/interface.php)0
-rw-r--r--lib/private/group/manager.php (renamed from lib/group/manager.php)0
-rw-r--r--lib/private/helper.php (renamed from lib/helper.php)44
-rw-r--r--lib/private/hintexception.php (renamed from lib/hintexception.php)0
-rw-r--r--lib/private/hook.php (renamed from lib/hook.php)0
-rw-r--r--lib/private/hooks/basicemitter.php (renamed from lib/hooks/basicemitter.php)0
-rw-r--r--lib/private/hooks/emitter.php (renamed from lib/hooks/emitter.php)0
-rw-r--r--lib/private/hooks/forwardingemitter.php (renamed from lib/hooks/forwardingemitter.php)0
-rw-r--r--lib/private/hooks/legacyemitter.php (renamed from lib/hooks/legacyemitter.php)0
-rw-r--r--lib/private/hooks/publicemitter.php (renamed from lib/hooks/publicemitter.php)0
-rw-r--r--lib/private/image.php (renamed from lib/image.php)0
-rw-r--r--lib/private/installer.php (renamed from lib/installer.php)11
-rw-r--r--lib/private/json.php (renamed from lib/json.php)0
-rw-r--r--lib/private/l10n.php (renamed from lib/l10n.php)0
-rw-r--r--lib/private/l10n/ach.php (renamed from lib/l10n/ach.php)0
-rw-r--r--lib/private/l10n/af_ZA.php (renamed from lib/l10n/af_ZA.php)0
-rw-r--r--lib/private/l10n/ar.php (renamed from lib/l10n/ar.php)0
-rw-r--r--lib/private/l10n/be.php (renamed from lib/l10n/be.php)0
-rw-r--r--lib/private/l10n/bg_BG.php (renamed from lib/l10n/bg_BG.php)0
-rw-r--r--lib/private/l10n/bn_BD.php (renamed from lib/l10n/bn_BD.php)0
-rw-r--r--lib/private/l10n/bs.php (renamed from lib/l10n/bs.php)0
-rw-r--r--lib/private/l10n/ca.php (renamed from lib/l10n/ca.php)3
-rw-r--r--lib/private/l10n/cs_CZ.php (renamed from lib/l10n/cs_CZ.php)3
-rw-r--r--lib/private/l10n/cy_GB.php (renamed from lib/l10n/cy_GB.php)0
-rw-r--r--lib/private/l10n/da.php (renamed from lib/l10n/da.php)3
-rw-r--r--lib/private/l10n/de.php (renamed from lib/l10n/de.php)3
-rw-r--r--lib/private/l10n/de_AT.php (renamed from lib/l10n/de_AT.php)0
-rw-r--r--lib/private/l10n/de_CH.php (renamed from lib/l10n/de_CH.php)0
-rw-r--r--lib/private/l10n/de_DE.php (renamed from lib/l10n/de_DE.php)3
-rw-r--r--lib/private/l10n/el.php (renamed from lib/l10n/el.php)0
-rw-r--r--lib/private/l10n/en@pirate.php (renamed from lib/l10n/en@pirate.php)0
-rw-r--r--lib/private/l10n/en_GB.php (renamed from lib/l10n/en_GB.php)11
-rw-r--r--lib/private/l10n/eo.php (renamed from lib/l10n/eo.php)0
-rw-r--r--lib/private/l10n/es.php (renamed from lib/l10n/es.php)0
-rw-r--r--lib/private/l10n/es_AR.php (renamed from lib/l10n/es_AR.php)0
-rw-r--r--lib/private/l10n/es_MX.php (renamed from lib/l10n/es_MX.php)0
-rw-r--r--lib/private/l10n/et_EE.php (renamed from lib/l10n/et_EE.php)3
-rw-r--r--lib/private/l10n/eu.php (renamed from lib/l10n/eu.php)0
-rw-r--r--lib/private/l10n/fa.php (renamed from lib/l10n/fa.php)0
-rw-r--r--lib/private/l10n/fi.php (renamed from lib/l10n/fi.php)0
-rw-r--r--lib/private/l10n/fi_FI.php (renamed from lib/l10n/fi_FI.php)7
-rw-r--r--lib/private/l10n/fr.php (renamed from lib/l10n/fr.php)3
-rw-r--r--lib/private/l10n/gl.php (renamed from lib/l10n/gl.php)3
-rw-r--r--lib/private/l10n/he.php (renamed from lib/l10n/he.php)0
-rw-r--r--lib/private/l10n/hi.php (renamed from lib/l10n/hi.php)0
-rw-r--r--lib/private/l10n/hr.php (renamed from lib/l10n/hr.php)0
-rw-r--r--lib/private/l10n/hu_HU.php (renamed from lib/l10n/hu_HU.php)11
-rw-r--r--lib/private/l10n/hy.php (renamed from lib/l10n/hy.php)0
-rw-r--r--lib/private/l10n/ia.php (renamed from lib/l10n/ia.php)0
-rw-r--r--lib/private/l10n/id.php (renamed from lib/l10n/id.php)0
-rw-r--r--lib/private/l10n/is.php (renamed from lib/l10n/is.php)0
-rw-r--r--lib/private/l10n/it.php (renamed from lib/l10n/it.php)3
-rw-r--r--lib/private/l10n/ja_JP.php (renamed from lib/l10n/ja_JP.php)3
-rw-r--r--lib/private/l10n/ka.php (renamed from lib/l10n/ka.php)0
-rw-r--r--lib/private/l10n/ka_GE.php (renamed from lib/l10n/ka_GE.php)0
-rw-r--r--lib/private/l10n/km.php (renamed from lib/l10n/kn.php)0
-rw-r--r--lib/private/l10n/kn.php (renamed from lib/l10n/nqo.php)0
-rw-r--r--lib/private/l10n/ko.php (renamed from lib/l10n/ko.php)8
-rw-r--r--lib/private/l10n/ku_IQ.php (renamed from lib/l10n/ku_IQ.php)0
-rw-r--r--lib/private/l10n/lb.php (renamed from lib/l10n/lb.php)0
-rw-r--r--lib/private/l10n/lt_LT.php72
-rw-r--r--lib/private/l10n/lv.php (renamed from lib/l10n/lv.php)0
-rw-r--r--lib/private/l10n/mk.php (renamed from lib/l10n/mk.php)0
-rw-r--r--lib/private/l10n/ml_IN.php (renamed from lib/l10n/ml_IN.php)0
-rw-r--r--lib/private/l10n/ms_MY.php (renamed from lib/l10n/ms_MY.php)0
-rw-r--r--lib/private/l10n/my_MM.php (renamed from lib/l10n/my_MM.php)0
-rw-r--r--lib/private/l10n/nb_NO.php (renamed from lib/l10n/nb_NO.php)0
-rw-r--r--lib/private/l10n/ne.php (renamed from lib/l10n/ne.php)0
-rw-r--r--lib/private/l10n/nl.php (renamed from lib/l10n/nl.php)16
-rw-r--r--lib/private/l10n/nn_NO.php (renamed from lib/l10n/nn_NO.php)2
-rw-r--r--lib/private/l10n/nqo.php8
-rw-r--r--lib/private/l10n/oc.php (renamed from lib/l10n/oc.php)0
-rw-r--r--lib/private/l10n/pa.php16
-rw-r--r--lib/private/l10n/pl.php (renamed from lib/l10n/pl.php)7
-rw-r--r--lib/private/l10n/pl_PL.php (renamed from lib/l10n/pl_PL.php)0
-rw-r--r--lib/private/l10n/pt_BR.php (renamed from lib/l10n/pt_BR.php)3
-rw-r--r--lib/private/l10n/pt_PT.php (renamed from lib/l10n/pt_PT.php)2
-rw-r--r--lib/private/l10n/ro.php (renamed from lib/l10n/ro.php)8
-rw-r--r--lib/private/l10n/ru.php (renamed from lib/l10n/ru.php)17
-rw-r--r--lib/private/l10n/si_LK.php (renamed from lib/l10n/si_LK.php)0
-rw-r--r--lib/private/l10n/sk.php (renamed from lib/l10n/sk.php)0
-rw-r--r--lib/private/l10n/sk_SK.php (renamed from lib/l10n/sk_SK.php)0
-rw-r--r--lib/private/l10n/sl.php (renamed from lib/l10n/sl.php)0
-rw-r--r--lib/private/l10n/sq.php (renamed from lib/l10n/sq.php)0
-rw-r--r--lib/private/l10n/sr.php (renamed from lib/l10n/sr.php)0
-rw-r--r--lib/private/l10n/sr@latin.php (renamed from lib/l10n/sr@latin.php)8
-rw-r--r--lib/private/l10n/string.php (renamed from lib/l10n/string.php)0
-rw-r--r--lib/private/l10n/sv.php (renamed from lib/l10n/sv.php)0
-rw-r--r--lib/private/l10n/sw_KE.php (renamed from lib/l10n/sw_KE.php)0
-rw-r--r--lib/private/l10n/ta_LK.php (renamed from lib/l10n/ta_LK.php)0
-rw-r--r--lib/private/l10n/te.php (renamed from lib/l10n/te.php)0
-rw-r--r--lib/private/l10n/th_TH.php (renamed from lib/l10n/th_TH.php)0
-rw-r--r--lib/private/l10n/tr.php (renamed from lib/l10n/tr.php)0
-rw-r--r--lib/private/l10n/ug.php (renamed from lib/l10n/ug.php)0
-rw-r--r--lib/private/l10n/uk.php (renamed from lib/l10n/uk.php)0
-rw-r--r--lib/private/l10n/ur_PK.php (renamed from lib/l10n/ur_PK.php)0
-rw-r--r--lib/private/l10n/vi.php (renamed from lib/l10n/vi.php)0
-rw-r--r--lib/private/l10n/zh_CN.php (renamed from lib/l10n/zh_CN.php)0
-rw-r--r--lib/private/l10n/zh_HK.php (renamed from lib/l10n/zh_HK.php)0
-rw-r--r--lib/private/l10n/zh_TW.php (renamed from lib/l10n/zh_TW.php)0
-rw-r--r--lib/private/legacy/cache.php10
-rw-r--r--lib/private/legacy/config.php (renamed from lib/legacy/config.php)0
-rw-r--r--lib/private/legacy/filesystem.php (renamed from lib/legacy/filesystem.php)0
-rw-r--r--lib/private/legacy/filesystemview.php (renamed from lib/legacy/filesystemview.php)0
-rw-r--r--lib/private/legacy/log.php (renamed from lib/legacy/log.php)0
-rw-r--r--lib/private/legacy/preferences.php146
-rw-r--r--lib/private/legacy/updater.php (renamed from lib/legacy/updater.php)0
-rw-r--r--lib/private/log.php (renamed from lib/log.php)0
-rw-r--r--lib/private/log/errorhandler.php (renamed from lib/log/errorhandler.php)0
-rw-r--r--lib/private/log/owncloud.php (renamed from lib/log/owncloud.php)0
-rw-r--r--lib/private/log/rotate.php (renamed from lib/log/rotate.php)0
-rw-r--r--lib/private/log/syslog.php (renamed from lib/log/syslog.php)0
-rw-r--r--lib/private/mail.php (renamed from lib/mail.php)0
-rw-r--r--lib/private/memcache/apc.php (renamed from lib/memcache/apc.php)0
-rw-r--r--lib/private/memcache/apcu.php (renamed from lib/memcache/apcu.php)0
-rw-r--r--lib/private/memcache/cache.php (renamed from lib/memcache/cache.php)0
-rw-r--r--lib/private/memcache/factory.php (renamed from lib/memcache/factory.php)0
-rw-r--r--lib/private/memcache/memcached.php (renamed from lib/memcache/memcached.php)0
-rw-r--r--lib/private/memcache/xcache.php (renamed from lib/memcache/xcache.php)0
-rw-r--r--lib/private/migrate.php (renamed from lib/migrate.php)0
-rw-r--r--lib/private/migration/content.php (renamed from lib/migration/content.php)3
-rw-r--r--lib/private/migration/provider.php (renamed from lib/migration/provider.php)0
-rw-r--r--lib/private/mimetypes.list.php (renamed from lib/mimetypes.list.php)0
-rw-r--r--lib/private/minimizer.php (renamed from lib/minimizer.php)0
-rw-r--r--lib/private/minimizer/css.php (renamed from lib/minimizer/css.php)0
-rw-r--r--lib/private/minimizer/js.php (renamed from lib/minimizer/js.php)0
-rw-r--r--lib/private/navigationmanager.php64
-rw-r--r--lib/private/notsquareexception.php12
-rw-r--r--lib/private/ocs.php (renamed from lib/ocs.php)0
-rw-r--r--lib/private/ocs/cloud.php (renamed from lib/ocs/cloud.php)0
-rw-r--r--lib/private/ocs/config.php (renamed from lib/ocs/config.php)0
-rw-r--r--lib/private/ocs/person.php (renamed from lib/ocs/person.php)0
-rw-r--r--lib/private/ocs/privatedata.php (renamed from lib/ocs/privatedata.php)0
-rw-r--r--lib/private/ocs/result.php (renamed from lib/ocs/result.php)0
-rw-r--r--lib/private/ocsclient.php (renamed from lib/ocsclient.php)7
-rw-r--r--lib/private/preferences.php (renamed from lib/preferences.php)153
-rwxr-xr-xlib/private/preview.php (renamed from lib/preview.php)5
-rw-r--r--lib/private/preview/image.php (renamed from lib/preview/image.php)0
-rw-r--r--lib/private/preview/movies.php (renamed from lib/preview/movies.php)0
-rw-r--r--lib/private/preview/mp3.php (renamed from lib/preview/mp3.php)0
-rw-r--r--lib/private/preview/office-cl.php (renamed from lib/preview/office-cl.php)0
-rw-r--r--lib/private/preview/office-fallback.php (renamed from lib/preview/office-fallback.php)0
-rw-r--r--lib/private/preview/office.php (renamed from lib/preview/office.php)0
-rw-r--r--lib/private/preview/pdf.php (renamed from lib/preview/pdf.php)0
-rw-r--r--lib/private/preview/provider.php (renamed from lib/preview/provider.php)0
-rw-r--r--lib/private/preview/svg.php (renamed from lib/preview/svg.php)0
-rw-r--r--lib/private/preview/txt.php (renamed from lib/preview/txt.php)10
-rw-r--r--lib/private/preview/unknown.php (renamed from lib/preview/unknown.php)0
-rwxr-xr-xlib/private/previewmanager.php38
-rwxr-xr-xlib/private/request.php (renamed from lib/request.php)0
-rw-r--r--lib/private/response.php (renamed from lib/response.php)0
-rw-r--r--lib/private/route.php (renamed from lib/route.php)0
-rw-r--r--lib/private/router.php (renamed from lib/router.php)0
-rw-r--r--lib/private/search.php (renamed from lib/search.php)0
-rw-r--r--lib/private/search/provider.php (renamed from lib/search/provider.php)0
-rw-r--r--lib/private/search/provider/file.php (renamed from lib/search/provider/file.php)3
-rw-r--r--lib/private/search/result.php (renamed from lib/search/result.php)4
-rw-r--r--lib/private/server.php255
-rw-r--r--lib/private/session/internal.php (renamed from lib/session/internal.php)0
-rw-r--r--lib/private/session/memory.php (renamed from lib/session/memory.php)0
-rw-r--r--lib/private/session/session.php (renamed from lib/session/session.php)2
-rw-r--r--lib/private/setup.php (renamed from lib/setup.php)0
-rw-r--r--lib/private/setup/abstractdatabase.php (renamed from lib/setup/abstractdatabase.php)0
-rw-r--r--lib/private/setup/mssql.php (renamed from lib/setup/mssql.php)0
-rw-r--r--lib/private/setup/mysql.php (renamed from lib/setup/mysql.php)0
-rw-r--r--lib/private/setup/oci.php (renamed from lib/setup/oci.php)0
-rw-r--r--lib/private/setup/postgresql.php (renamed from lib/setup/postgresql.php)0
-rw-r--r--lib/private/setup/sqlite.php (renamed from lib/setup/sqlite.php)0
-rw-r--r--lib/private/subadmin.php (renamed from lib/subadmin.php)0
-rw-r--r--lib/private/tagmanager.php68
-rw-r--r--lib/private/tags.php642
-rw-r--r--lib/private/template.php (renamed from lib/template.php)0
-rw-r--r--lib/private/template/base.php (renamed from lib/template/base.php)0
-rw-r--r--lib/private/template/cssresourcelocator.php (renamed from lib/template/cssresourcelocator.php)0
-rw-r--r--lib/private/template/functions.php (renamed from lib/template/functions.php)0
-rw-r--r--lib/private/template/jsresourcelocator.php (renamed from lib/template/jsresourcelocator.php)0
-rw-r--r--lib/private/template/resourcelocator.php (renamed from lib/template/resourcelocator.php)0
-rw-r--r--lib/private/template/templatefilelocator.php (renamed from lib/template/templatefilelocator.php)0
-rw-r--r--lib/private/templatelayout.php (renamed from lib/templatelayout.php)1
-rw-r--r--lib/private/updater.php (renamed from lib/updater.php)2
-rw-r--r--lib/private/user.php (renamed from lib/user.php)60
-rw-r--r--lib/private/user/backend.php (renamed from lib/user/backend.php)0
-rw-r--r--lib/private/user/database.php (renamed from lib/user/database.php)0
-rw-r--r--lib/private/user/dummy.php (renamed from lib/user/dummy.php)0
-rw-r--r--lib/private/user/example.php (renamed from lib/user/example.php)0
-rw-r--r--lib/private/user/http.php (renamed from lib/user/http.php)6
-rw-r--r--lib/private/user/interface.php (renamed from lib/user/interface.php)0
-rw-r--r--lib/private/user/manager.php (renamed from lib/user/manager.php)19
-rw-r--r--lib/private/user/session.php (renamed from lib/user/session.php)21
-rw-r--r--lib/private/user/user.php (renamed from lib/user/user.php)18
-rwxr-xr-xlib/private/util.php (renamed from lib/util.php)102
-rw-r--r--lib/private/vobject.php (renamed from lib/vobject.php)0
-rw-r--r--lib/private/vobject/compoundproperty.php (renamed from lib/vobject/compoundproperty.php)0
-rw-r--r--lib/private/vobject/stringproperty.php (renamed from lib/vobject/stringproperty.php)0
-rw-r--r--lib/public/app.php16
-rw-r--r--lib/public/appframework/app.php81
-rw-r--r--lib/public/appframework/http/http.php89
-rw-r--r--lib/public/appframework/http/jsonresponse.php74
-rw-r--r--lib/public/appframework/http/response.php169
-rw-r--r--lib/public/appframework/http/templateresponse.php126
-rw-r--r--lib/public/appframework/iapi.php151
-rw-r--r--lib/public/appframework/iappcontainer.php57
-rw-r--r--lib/public/appframework/imiddleware.php88
-rw-r--r--lib/public/contacts.php55
-rw-r--r--lib/public/contacts/imanager.php150
-rw-r--r--lib/public/db.php11
-rw-r--r--lib/public/files/alreadyexistsexception.php11
-rw-r--r--lib/public/files/file.php53
-rw-r--r--lib/public/files/folder.php119
-rw-r--r--lib/public/files/node.php159
-rw-r--r--lib/public/files/notenoughspaceexception.php11
-rw-r--r--lib/public/files/notfoundexception.php11
-rw-r--r--lib/public/files/notpermittedexception.php11
-rw-r--r--lib/public/files/storage.php297
-rw-r--r--lib/public/icache.php55
-rw-r--r--lib/public/iconfig.php65
-rw-r--r--lib/public/icontainer.php64
-rw-r--r--lib/public/idbconnection.php74
-rw-r--r--lib/public/inavigationmanager.php27
-rw-r--r--lib/public/ipreview.php35
-rw-r--r--lib/public/irequest.php96
-rw-r--r--lib/public/iservercontainer.php125
-rw-r--r--lib/public/isession.php56
-rw-r--r--lib/public/itagmanager.php48
-rw-r--r--lib/public/itags.php164
-rw-r--r--lib/public/iusersession.php30
-rw-r--r--lib/public/preview.php34
-rw-r--r--lib/public/share.php41
-rw-r--r--lib/public/user.php2
-rw-r--r--lib/vcategories.php821
350 files changed, 8644 insertions, 1308 deletions
diff --git a/lib/autoloader.php b/lib/autoloader.php
index 01841f831be..b5b58918372 100644
--- a/lib/autoloader.php
+++ b/lib/autoloader.php
@@ -73,9 +73,10 @@ class Autoloader {
}
} elseif (strpos($class, 'OC_') === 0) {
// first check for legacy classes if underscores are used
- $paths[] = 'legacy/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php');
- $paths[] = strtolower(str_replace('_', '/', substr($class, 3)) . '.php');
+ $paths[] = 'private/legacy/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php');
+ $paths[] = 'private/' . strtolower(str_replace('_', '/', substr($class, 3)) . '.php');
} elseif (strpos($class, 'OC\\') === 0) {
+ $paths[] = 'private/' . strtolower(str_replace('\\', '/', substr($class, 3)) . '.php');
$paths[] = strtolower(str_replace('\\', '/', substr($class, 3)) . '.php');
} elseif (strpos($class, 'OCP\\') === 0) {
$paths[] = 'public/' . strtolower(str_replace('\\', '/', substr($class, 4)) . '.php');
@@ -117,7 +118,11 @@ class Autoloader {
// Does this PHP have an in-memory cache? We cache the paths there
if ($this->constructingMemoryCache && !$this->memoryCache) {
$this->constructingMemoryCache = false;
- $this->memoryCache = \OC\Memcache\Factory::createLowLatency('Autoloader');
+ try {
+ $this->memoryCache = \OC\Memcache\Factory::createLowLatency('Autoloader');
+ } catch(\Exception $ex) {
+ // no caching then - fine with me
+ }
}
if ($this->memoryCache) {
$pathsToRequire = $this->memoryCache->get($class);
diff --git a/lib/base.php b/lib/base.php
index aa91176d218..1246aee8110 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -84,6 +84,11 @@ class OC {
*/
public static $loader = null;
+ /**
+ * @var \OC\Server
+ */
+ public static $server = null;
+
public static function initPaths() {
// calculate the root directories
OC::$SERVERROOT = str_replace("\\", '/', substr(__DIR__, 0, -4));
@@ -159,7 +164,7 @@ class OC {
// set the right include path
set_include_path(
- OC::$SERVERROOT . '/lib' . PATH_SEPARATOR .
+ OC::$SERVERROOT . '/lib/private' . PATH_SEPARATOR .
OC::$SERVERROOT . '/config' . PATH_SEPARATOR .
OC::$THIRDPARTYROOT . '/3rdparty' . PATH_SEPARATOR .
implode($paths, PATH_SEPARATOR) . PATH_SEPARATOR .
@@ -266,6 +271,14 @@ class OC {
OC_Util::addScript('router');
OC_Util::addScript("oc-requesttoken");
+ // avatars
+ if (\OC_Config::getValue('enable_avatars', true) === true) {
+ \OC_Util::addScript('placeholder');
+ \OC_Util::addScript('3rdparty', 'md5/md5.min');
+ \OC_Util::addScript('jquery.avatar');
+ \OC_Util::addScript('avatar');
+ }
+
OC_Util::addStyle("styles");
OC_Util::addStyle("apps");
OC_Util::addStyle("fixes");
@@ -358,6 +371,7 @@ class OC {
self::$loader->registerPrefix('Doctrine\\Common', 'doctrine/common/lib');
self::$loader->registerPrefix('Doctrine\\DBAL', 'doctrine/dbal/lib');
self::$loader->registerPrefix('Symfony\\Component\\Routing', 'symfony/routing');
+ self::$loader->registerPrefix('Symfony\\Component\\Console', 'symfony/console');
self::$loader->registerPrefix('Sabre\\VObject', '3rdparty');
self::$loader->registerPrefix('Sabre_', '3rdparty');
self::$loader->registerPrefix('Patchwork', '3rdparty');
@@ -442,6 +456,9 @@ class OC {
stream_wrapper_register('quota', 'OC\Files\Stream\Quota');
stream_wrapper_register('oc', 'OC\Files\Stream\OC');
+ // setup the basic server
+ self::$server = new \OC\Server();
+
self::initTemplateEngine();
if (!self::$CLI) {
self::initSession();
@@ -548,11 +565,13 @@ class OC {
if (OC_Config::getValue('installed', false)) { //don't try to do this before we are properly setup
// register cache cleanup jobs
try { //if this is executed before the upgrade to the new backgroundjob system is completed it will throw an exception
- \OCP\BackgroundJob::registerJob('OC_Cache_FileGlobalGC');
+ \OCP\BackgroundJob::registerJob('OC\Cache\FileGlobalGC');
} catch (Exception $e) {
}
- OC_Hook::connect('OC_User', 'post_login', 'OC_Cache_File', 'loginListener');
+ // NOTE: This will be replaced to use OCP
+ $userSession = \OC_User::getUserSession();
+ $userSession->listen('postLogin', '\OC\Cache\File', 'loginListener');
}
}
@@ -752,6 +771,7 @@ class OC {
|| !isset($_COOKIE["oc_token"])
|| !isset($_COOKIE["oc_username"])
|| !$_COOKIE["oc_remember_login"]
+ || !OC_Util::rememberLoginAllowed()
) {
return false;
}
diff --git a/lib/cache/fileglobalgc.php b/lib/cache/fileglobalgc.php
deleted file mode 100644
index a29c31f9063..00000000000
--- a/lib/cache/fileglobalgc.php
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-
-class OC_Cache_FileGlobalGC extends \OC\BackgroundJob\Job{
- public function run($argument){
- OC_Cache_FileGlobal::gc();
- }
-}
diff --git a/lib/l10n/lt_LT.php b/lib/l10n/lt_LT.php
deleted file mode 100644
index 242b0a23106..00000000000
--- a/lib/l10n/lt_LT.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-$TRANSLATIONS = array(
-"Help" => "Pagalba",
-"Personal" => "Asmeniniai",
-"Settings" => "Nustatymai",
-"Users" => "Vartotojai",
-"Admin" => "Administravimas",
-"web services under your control" => "jūsų valdomos web paslaugos",
-"ZIP download is turned off." => "ZIP atsisiuntimo galimybė yra išjungta.",
-"Files need to be downloaded one by one." => "Failai turi būti parsiunčiami vienas po kito.",
-"Back to Files" => "Atgal į Failus",
-"Selected files too large to generate zip file." => "Pasirinkti failai per dideli archyvavimui į ZIP.",
-"Application is not enabled" => "Programa neįjungta",
-"Authentication error" => "Autentikacijos klaida",
-"Token expired. Please reload page." => "Sesija baigėsi. Prašome perkrauti puslapį.",
-"Files" => "Failai",
-"Text" => "Žinučių",
-"Images" => "Paveikslėliai",
-"seconds ago" => "prieš sekundę",
-"_%n minute ago_::_%n minutes ago_" => array("",""," prieš %n minučių"),
-"_%n hour ago_::_%n hours ago_" => array("","","prieš %n valandų"),
-"today" => "šiandien",
-"yesterday" => "vakar",
-"_%n day go_::_%n days ago_" => array("","",""),
-"last month" => "praeitą mėnesį",
-"_%n month ago_::_%n months ago_" => array("","","prieš %n mėnesių"),
-"last year" => "praeitais metais",
-"years ago" => "prieš metus"
-);
-$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/private/allconfig.php b/lib/private/allconfig.php
new file mode 100644
index 00000000000..72aabf60793
--- /dev/null
+++ b/lib/private/allconfig.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OC;
+
+/**
+ * Class to combine all the configuration options ownCloud offers
+ */
+class AllConfig implements \OCP\IConfig {
+ /**
+ * Sets a new system wide value
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ * @todo need a use case for this
+ */
+// public function setSystemValue($key, $value) {
+// \OCP\Config::setSystemValue($key, $value);
+// }
+
+ /**
+ * Looks up a system wide defined value
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getSystemValue($key) {
+ return \OCP\Config::getSystemValue($key, '');
+ }
+
+
+ /**
+ * Writes a new app wide value
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ */
+ public function setAppValue($appName, $key, $value) {
+ \OCP\Config::setAppValue($appName, $key, $value);
+ }
+
+ /**
+ * Looks up an app wide defined value
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getAppValue($appName, $key) {
+ return \OCP\Config::getAppValue($appName, $key, '');
+ }
+
+
+ /**
+ * Set a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key under which the value is being stored
+ * @param string $value the value that you want to store
+ */
+ public function setUserValue($userId, $appName, $key, $value) {
+ \OCP\Config::setUserValue($userId, $appName, $key, $value);
+ }
+
+ /**
+ * Shortcut for getting a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key under which the value is being stored
+ */
+ public function getUserValue($userId, $appName, $key){
+ return \OCP\Config::getUserValue($userId, $appName, $key);
+ }
+}
diff --git a/lib/api.php b/lib/private/api.php
index 31f3f968d9b..31f3f968d9b 100644
--- a/lib/api.php
+++ b/lib/private/api.php
diff --git a/lib/app.php b/lib/private/app.php
index 1a0a7e6f9a9..0ab1ee57f63 100644
--- a/lib/app.php
+++ b/lib/private/app.php
@@ -27,8 +27,6 @@
* upgrading and removing apps.
*/
class OC_App{
- static private $activeapp = '';
- static private $navigation = array();
static private $settingsForms = array();
static private $adminForms = array();
static private $personalForms = array();
@@ -271,7 +269,7 @@ class OC_App{
/**
* @brief adds an entry to the navigation
- * @param string $data array containing the data
+ * @param array $data array containing the data
* @return bool
*
* This function adds a new entry to the navigation visible to users. $data
@@ -287,11 +285,7 @@ class OC_App{
* the navigation. Lower values come first.
*/
public static function addNavigationEntry( $data ) {
- $data['active']=false;
- if(!isset($data['icon'])) {
- $data['icon']='';
- }
- OC_App::$navigation[] = $data;
+ OC::$server->getNavigationManager()->add($data);
return true;
}
@@ -305,9 +299,7 @@ class OC_App{
* highlighting the current position of the user.
*/
public static function setActiveNavigationEntry( $id ) {
- // load all the apps, to make sure we have all the navigation entries
- self::loadApps();
- self::$activeapp = $id;
+ OC::$server->getNavigationManager()->setActiveEntry($id);
return true;
}
@@ -315,15 +307,14 @@ class OC_App{
* @brief Get the navigation entries for the $app
* @param string $app app
* @return array of the $data added with addNavigationEntry
+ *
+ * Warning: destroys the existing entries
*/
public static function getAppNavigationEntries($app) {
if(is_file(self::getAppPath($app).'/appinfo/app.php')) {
- $save = self::$navigation;
- self::$navigation = array();
+ OC::$server->getNavigationManager()->clear();
require $app.'/appinfo/app.php';
- $app_entries = self::$navigation;
- self::$navigation = $save;
- return $app_entries;
+ return OC::$server->getNavigationManager()->getAll();
}
return array();
}
@@ -336,7 +327,7 @@ class OC_App{
* setActiveNavigationEntry
*/
public static function getActiveNavigationEntry() {
- return self::$activeapp;
+ return OC::$server->getNavigationManager()->getActiveEntry();
}
/**
@@ -419,8 +410,9 @@ class OC_App{
// This is private as well. It simply works, so don't ask for more details
private static function proceedNavigation( $list ) {
+ $activeapp = OC::$server->getNavigationManager()->getActiveEntry();
foreach( $list as &$naventry ) {
- if( $naventry['id'] == self::$activeapp ) {
+ if( $naventry['id'] == $activeapp ) {
$naventry['active'] = true;
}
else{
@@ -572,7 +564,8 @@ class OC_App{
* - active: boolean, signals if the user is on this navigation entry
*/
public static function getNavigation() {
- $navigation = self::proceedNavigation( self::$navigation );
+ $entries = OC::$server->getNavigationManager()->getAll();
+ $navigation = self::proceedNavigation( $entries );
return $navigation;
}
@@ -667,14 +660,16 @@ class OC_App{
}
$dh = opendir( $apps_dir['path'] );
- while (($file = readdir($dh)) !== false) {
+ if(is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
- if ($file[0] != '.' and is_file($apps_dir['path'].'/'.$file.'/appinfo/app.php')) {
+ if ($file[0] != '.' and is_file($apps_dir['path'].'/'.$file.'/appinfo/app.php')) {
- $apps[] = $file;
+ $apps[] = $file;
- }
+ }
+ }
}
}
@@ -868,10 +863,10 @@ class OC_App{
/**
- * Compares the app version with the owncloud version to see if the app
+ * Compares the app version with the owncloud version to see if the app
* requires a newer version than the currently active one
* @param array $owncloudVersions array with 3 entries: major minor bugfix
- * @param string $appRequired the required version from the xml
+ * @param string $appRequired the required version from the xml
* major.minor.bugfix
* @return boolean true if compatible, otherwise false
*/
diff --git a/lib/appconfig.php b/lib/private/appconfig.php
index e615d838173..e615d838173 100644
--- a/lib/appconfig.php
+++ b/lib/private/appconfig.php
diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php
new file mode 100644
index 00000000000..7ff55bb809d
--- /dev/null
+++ b/lib/private/appframework/app.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework;
+
+use OC\AppFramework\DependencyInjection\DIContainer;
+use OCP\AppFramework\IAppContainer;
+
+
+/**
+ * Entry point for every request in your app. You can consider this as your
+ * public static void main() method
+ *
+ * Handles all the dependency injection, controllers and output flow
+ */
+class App {
+
+
+ /**
+ * Shortcut for calling a controller method and printing the result
+ * @param string $controllerName the name of the controller under which it is
+ * stored in the DI container
+ * @param string $methodName the method that you want to call
+ * @param array $urlParams an array with variables extracted from the routes
+ * @param DIContainer $container an instance of a pimple container.
+ */
+ public static function main($controllerName, $methodName, array $urlParams,
+ IAppContainer $container) {
+ $container['urlParams'] = $urlParams;
+ $controller = $container[$controllerName];
+
+ // initialize the dispatcher and run all the middleware before the controller
+ $dispatcher = $container['Dispatcher'];
+
+ list($httpHeaders, $responseHeaders, $output) =
+ $dispatcher->dispatch($controller, $methodName);
+
+ if(!is_null($httpHeaders)) {
+ header($httpHeaders);
+ }
+
+ foreach($responseHeaders as $name => $value) {
+ header($name . ': ' . $value);
+ }
+
+ if(!is_null($output)) {
+ header('Content-Length: ' . strlen($output));
+ print($output);
+ }
+
+ }
+
+ /**
+ * Shortcut for calling a controller method and printing the result.
+ * Similar to App:main except that no headers will be sent.
+ * This should be used for example when registering sections via
+ * \OC\AppFramework\Core\API::registerAdmin()
+ *
+ * @param string $controllerName the name of the controller under which it is
+ * stored in the DI container
+ * @param string $methodName the method that you want to call
+ * @param array $urlParams an array with variables extracted from the routes
+ * @param DIContainer $container an instance of a pimple container.
+ */
+ public static function part($controllerName, $methodName, array $urlParams,
+ DIContainer $container){
+
+ $container['urlParams'] = $urlParams;
+ $controller = $container[$controllerName];
+
+ $dispatcher = $container['Dispatcher'];
+
+ list(, , $output) = $dispatcher->dispatch($controller, $methodName);
+ return $output;
+ }
+
+}
diff --git a/lib/private/appframework/controller/controller.php b/lib/private/appframework/controller/controller.php
new file mode 100644
index 00000000000..0ea0a38cc09
--- /dev/null
+++ b/lib/private/appframework/controller/controller.php
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Controller;
+
+use OC\AppFramework\Http\Request;
+use OC\AppFramework\Core\API;
+use OCP\AppFramework\Http\TemplateResponse;
+
+
+/**
+ * Base class to inherit your controllers from
+ */
+abstract class Controller {
+
+ /**
+ * @var API instance of the api layer
+ */
+ protected $api;
+
+ protected $request;
+
+ /**
+ * @param API $api an api wrapper instance
+ * @param Request $request an instance of the request
+ */
+ public function __construct(API $api, Request $request){
+ $this->api = $api;
+ $this->request = $request;
+ }
+
+
+ /**
+ * Lets you access post and get parameters by the index
+ * @param string $key the key which you want to access in the URL Parameter
+ * placeholder, $_POST or $_GET array.
+ * The priority how they're returned is the following:
+ * 1. URL parameters
+ * 2. POST parameters
+ * 3. GET parameters
+ * @param mixed $default If the key is not found, this value will be returned
+ * @return mixed the content of the array
+ */
+ public function params($key, $default=null){
+ return $this->request->getParam($key, $default);
+ }
+
+
+ /**
+ * Returns all params that were received, be it from the request
+ * (as GET or POST) or throuh the URL by the route
+ * @return array the array with all parameters
+ */
+ public function getParams() {
+ return $this->request->getParams();
+ }
+
+
+ /**
+ * Returns the method of the request
+ * @return string the method of the request (POST, GET, etc)
+ */
+ public function method() {
+ return $this->request->getMethod();
+ }
+
+
+ /**
+ * Shortcut for accessing an uploaded file through the $_FILES array
+ * @param string $key the key that will be taken from the $_FILES array
+ * @return array the file in the $_FILES element
+ */
+ public function getUploadedFile($key) {
+ return $this->request->getUploadedFile($key);
+ }
+
+
+ /**
+ * Shortcut for getting env variables
+ * @param string $key the key that will be taken from the $_ENV array
+ * @return array the value in the $_ENV element
+ */
+ public function env($key) {
+ return $this->request->getEnv($key);
+ }
+
+
+ /**
+ * Shortcut for getting cookie variables
+ * @param string $key the key that will be taken from the $_COOKIE array
+ * @return array the value in the $_COOKIE element
+ */
+ public function cookie($key) {
+ return $this->request->getCookie($key);
+ }
+
+
+ /**
+ * Shortcut for rendering a template
+ * @param string $templateName the name of the template
+ * @param array $params the template parameters in key => value structure
+ * @param string $renderAs user renders a full page, blank only your template
+ * admin an entry in the admin settings
+ * @param array $headers set additional headers in name/value pairs
+ * @return \OCP\AppFramework\Http\TemplateResponse containing the page
+ */
+ public function render($templateName, array $params=array(),
+ $renderAs='user', array $headers=array()){
+ $response = new TemplateResponse($this->api, $templateName);
+ $response->setParams($params);
+ $response->renderAs($renderAs);
+
+ foreach($headers as $name => $value){
+ $response->addHeader($name, $value);
+ }
+
+ return $response;
+ }
+
+
+}
diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php
new file mode 100644
index 00000000000..39522ee3dd5
--- /dev/null
+++ b/lib/private/appframework/core/api.php
@@ -0,0 +1,348 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Core;
+use OCP\AppFramework\IApi;
+
+
+/**
+ * This is used to wrap the owncloud static api calls into an object to make the
+ * code better abstractable for use in the dependency injection container
+ *
+ * Should you find yourself in need for more methods, simply inherit from this
+ * class and add your methods
+ */
+class API implements IApi{
+
+ private $appName;
+
+ /**
+ * constructor
+ * @param string $appName the name of your application
+ */
+ public function __construct($appName){
+ $this->appName = $appName;
+ }
+
+
+ /**
+ * Gets the userid of the current user
+ * @return string the user id of the current user
+ */
+ public function getUserId(){
+ return \OCP\User::getUser();
+ }
+
+
+ /**
+ * Adds a new javascript file
+ * @param string $scriptName the name of the javascript in js/ without the suffix
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ public function addScript($scriptName, $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+ \OCP\Util::addScript($appName, $scriptName);
+ }
+
+
+ /**
+ * Adds a new css file
+ * @param string $styleName the name of the css file in css/without the suffix
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ public function addStyle($styleName, $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+ \OCP\Util::addStyle($appName, $styleName);
+ }
+
+
+ /**
+ * shorthand for addScript for files in the 3rdparty directory
+ * @param string $name the name of the file without the suffix
+ */
+ public function add3rdPartyScript($name){
+ \OCP\Util::addScript($this->appName . '/3rdparty', $name);
+ }
+
+
+ /**
+ * shorthand for addStyle for files in the 3rdparty directory
+ * @param string $name the name of the file without the suffix
+ */
+ public function add3rdPartyStyle($name){
+ \OCP\Util::addStyle($this->appName . '/3rdparty', $name);
+ }
+
+
+ /**
+ * Returns the translation object
+ * @return \OC_L10N the translation object
+ */
+ public function getTrans(){
+ # TODO: use public api
+ return \OC_L10N::get($this->appName);
+ }
+
+
+ /**
+ * Returns the URL for a route
+ * @param string $routeName the name of the route
+ * @param array $arguments an array with arguments which will be filled into the url
+ * @return string the url
+ */
+ public function linkToRoute($routeName, $arguments=array()){
+ return \OCP\Util::linkToRoute($routeName, $arguments);
+ }
+
+
+ /**
+ * Returns an URL for an image or file
+ * @param string $file the name of the file
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ public function linkTo($file, $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+ return \OCP\Util::linkTo($appName, $file);
+ }
+
+
+ /**
+ * Returns the link to an image, like link to but only with prepending img/
+ * @param string $file the name of the file
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ public function imagePath($file, $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+ return \OCP\Util::imagePath($appName, $file);
+ }
+
+
+ /**
+ * Makes an URL absolute
+ * @param string $url the url
+ * @return string the absolute url
+ */
+ public function getAbsoluteURL($url){
+ # TODO: use public api
+ return \OC_Helper::makeURLAbsolute($url);
+ }
+
+
+ /**
+ * links to a file
+ * @param string $file the name of the file
+ * @param string $appName the name of the app, defaults to the current one
+ * @deprecated replaced with linkToRoute()
+ * @return string the url
+ */
+ public function linkToAbsolute($file, $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+ return \OCP\Util::linkToAbsolute($appName, $file);
+ }
+
+
+ /**
+ * Checks if the CSRF check was correct
+ * @return bool true if CSRF check passed
+ */
+ public function passesCSRFCheck(){
+ # TODO: use public api
+ return \OC_Util::isCallRegistered();
+ }
+
+
+ /**
+ * Checks if an app is enabled
+ * @param string $appName the name of an app
+ * @return bool true if app is enabled
+ */
+ public function isAppEnabled($appName){
+ return \OCP\App::isEnabled($appName);
+ }
+
+
+ /**
+ * Writes a function into the error log
+ * @param string $msg the error message to be logged
+ * @param int $level the error level
+ */
+ public function log($msg, $level=null){
+ switch($level){
+ case 'debug':
+ $level = \OCP\Util::DEBUG;
+ break;
+ case 'info':
+ $level = \OCP\Util::INFO;
+ break;
+ case 'warn':
+ $level = \OCP\Util::WARN;
+ break;
+ case 'fatal':
+ $level = \OCP\Util::FATAL;
+ break;
+ default:
+ $level = \OCP\Util::ERROR;
+ break;
+ }
+ \OCP\Util::writeLog($this->appName, $msg, $level);
+ }
+
+
+ /**
+ * turns an owncloud path into a path on the filesystem
+ * @param string path the path to the file on the oc filesystem
+ * @return string the filepath in the filesystem
+ */
+ public function getLocalFilePath($path){
+ # TODO: use public api
+ return \OC_Filesystem::getLocalFile($path);
+ }
+
+
+ /**
+ * used to return and open a new eventsource
+ * @return \OC_EventSource a new open EventSource class
+ */
+ public function openEventSource(){
+ # TODO: use public api
+ return new \OC_EventSource();
+ }
+
+ /**
+ * @brief connects a function to a hook
+ * @param string $signalClass class name of emitter
+ * @param string $signalName name of signal
+ * @param string $slotClass class name of slot
+ * @param string $slotName name of slot, in another word, this is the
+ * name of the method that will be called when registered
+ * signal is emitted.
+ * @return bool, always true
+ */
+ public function connectHook($signalClass, $signalName, $slotClass, $slotName) {
+ return \OCP\Util::connectHook($signalClass, $signalName, $slotClass, $slotName);
+ }
+
+ /**
+ * @brief Emits a signal. To get data from the slot use references!
+ * @param string $signalClass class name of emitter
+ * @param string $signalName name of signal
+ * @param array $params defautl: array() array with additional data
+ * @return bool, true if slots exists or false if not
+ */
+ public function emitHook($signalClass, $signalName, $params = array()) {
+ return \OCP\Util::emitHook($signalClass, $signalName, $params);
+ }
+
+ /**
+ * @brief clear hooks
+ * @param string $signalClass
+ * @param string $signalName
+ */
+ public function clearHook($signalClass=false, $signalName=false) {
+ if ($signalClass) {
+ \OC_Hook::clear($signalClass, $signalName);
+ }
+ }
+
+ /**
+ * Gets the content of an URL by using CURL or a fallback if it is not
+ * installed
+ * @param string $url the url that should be fetched
+ * @return string the content of the webpage
+ */
+ public function getUrlContent($url) {
+ return \OC_Util::getUrlContent($url);
+ }
+
+ /**
+ * Register a backgroundjob task
+ * @param string $className full namespace and class name of the class
+ * @param string $methodName the name of the static method that should be
+ * called
+ */
+ public function addRegularTask($className, $methodName) {
+ \OCP\Backgroundjob::addRegularTask($className, $methodName);
+ }
+
+ /**
+ * Returns a template
+ * @param string $templateName the name of the template
+ * @param string $renderAs how it should be rendered
+ * @param string $appName the name of the app
+ * @return \OCP\Template a new template
+ */
+ public function getTemplate($templateName, $renderAs='user', $appName=null){
+ if($appName === null){
+ $appName = $this->appName;
+ }
+
+ if($renderAs === 'blank'){
+ return new \OCP\Template($appName, $templateName);
+ } else {
+ return new \OCP\Template($appName, $templateName, $renderAs);
+ }
+ }
+
+
+ /**
+ * Tells ownCloud to include a template in the admin overview
+ * @param string $mainPath the path to the main php file without the php
+ * suffix, relative to your apps directory! not the template directory
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ public function registerAdmin($mainPath, $appName=null) {
+ if($appName === null){
+ $appName = $this->appName;
+ }
+
+ \OCP\App::registerAdmin($appName, $mainPath);
+ }
+
+
+ /**
+ * get the filesystem info
+ *
+ * @param string $path
+ * @return array with the following keys:
+ * - size
+ * - mtime
+ * - mimetype
+ * - encrypted
+ * - versioned
+ */
+ public function getFileInfo($path) {
+ return \OC\Files\Filesystem::getFileInfo($path);
+ }
+
+}
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
new file mode 100644
index 00000000000..3755d45fa09
--- /dev/null
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\DependencyInjection;
+
+use OC\AppFramework\Http\Http;
+use OC\AppFramework\Http\Request;
+use OC\AppFramework\Http\Dispatcher;
+use OC\AppFramework\Core\API;
+use OC\AppFramework\Middleware\MiddlewareDispatcher;
+use OC\AppFramework\Middleware\Security\SecurityMiddleware;
+use OC\AppFramework\Utility\SimpleContainer;
+use OC\AppFramework\Utility\TimeFactory;
+use OCP\AppFramework\IApi;
+use OCP\AppFramework\IAppContainer;
+use OCP\AppFramework\IMiddleWare;
+use OCP\IServerContainer;
+
+
+class DIContainer extends SimpleContainer implements IAppContainer{
+
+ /**
+ * @var array
+ */
+ private $middleWares = array();
+
+ /**
+ * Put your class dependencies in here
+ * @param string $appName the name of the app
+ */
+ public function __construct($appName){
+
+ $this['AppName'] = $appName;
+
+ $this->registerParameter('ServerContainer', \OC::$server);
+
+ $this['API'] = $this->share(function($c){
+ return new API($c['AppName']);
+ });
+
+ /**
+ * Http
+ */
+ $this['Request'] = $this->share(function($c) {
+ /** @var $c SimpleContainer */
+ /** @var $server IServerContainer */
+ $server = $c->query('ServerContainer');
+ return $server->getRequest();
+ });
+
+ $this['Protocol'] = $this->share(function($c){
+ if(isset($_SERVER['SERVER_PROTOCOL'])) {
+ return new Http($_SERVER, $_SERVER['SERVER_PROTOCOL']);
+ } else {
+ return new Http($_SERVER);
+ }
+ });
+
+ $this['Dispatcher'] = $this->share(function($c) {
+ return new Dispatcher($c['Protocol'], $c['MiddlewareDispatcher']);
+ });
+
+
+ /**
+ * Middleware
+ */
+ $this['SecurityMiddleware'] = $this->share(function($c){
+ return new SecurityMiddleware($c['API'], $c['Request']);
+ });
+
+ $this['MiddlewareDispatcher'] = $this->share(function($c){
+ $dispatcher = new MiddlewareDispatcher();
+ $dispatcher->registerMiddleware($c['SecurityMiddleware']);
+
+ foreach($this->middleWares as $middleWare) {
+ $dispatcher->registerMiddleware($middleWare);
+ }
+
+ return $dispatcher;
+ });
+
+
+ /**
+ * Utilities
+ */
+ $this['TimeFactory'] = $this->share(function($c){
+ return new TimeFactory();
+ });
+
+
+ }
+
+
+ /**
+ * @return IApi
+ */
+ function getCoreApi()
+ {
+ return $this->query('API');
+ }
+
+ /**
+ * @return \OCP\IServerContainer
+ */
+ function getServer()
+ {
+ return $this->query('ServerContainer');
+ }
+
+ /**
+ * @param IMiddleWare $middleWare
+ * @return boolean
+ */
+ function registerMiddleWare(IMiddleWare $middleWare) {
+ array_push($this->middleWares, $middleWare);
+ }
+
+ /**
+ * used to return the appname of the set application
+ * @return string the name of your application
+ */
+ function getAppName() {
+ return $this->query('AppName');
+ }
+}
diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php
new file mode 100644
index 00000000000..ea57a6860cc
--- /dev/null
+++ b/lib/private/appframework/http/dispatcher.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Http;
+
+use \OC\AppFramework\Controller\Controller;
+use \OC\AppFramework\Middleware\MiddlewareDispatcher;
+
+
+/**
+ * Class to dispatch the request to the middleware dispatcher
+ */
+class Dispatcher {
+
+ private $middlewareDispatcher;
+ private $protocol;
+
+
+ /**
+ * @param Http $protocol the http protocol with contains all status headers
+ * @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which
+ * runs the middleware
+ */
+ public function __construct(Http $protocol,
+ MiddlewareDispatcher $middlewareDispatcher) {
+ $this->protocol = $protocol;
+ $this->middlewareDispatcher = $middlewareDispatcher;
+ }
+
+
+ /**
+ * Handles a request and calls the dispatcher on the controller
+ * @param Controller $controller the controller which will be called
+ * @param string $methodName the method name which will be called on
+ * the controller
+ * @return array $array[0] contains a string with the http main header,
+ * $array[1] contains headers in the form: $key => value, $array[2] contains
+ * the response output
+ */
+ public function dispatch(Controller $controller, $methodName) {
+ $out = array(null, array(), null);
+
+ try {
+
+ $this->middlewareDispatcher->beforeController($controller,
+ $methodName);
+ $response = $controller->$methodName();
+
+ // if an exception appears, the middleware checks if it can handle the
+ // exception and creates a response. If no response is created, it is
+ // assumed that theres no middleware who can handle it and the error is
+ // thrown again
+ } catch(\Exception $exception){
+ $response = $this->middlewareDispatcher->afterException(
+ $controller, $methodName, $exception);
+ if (is_null($response)) {
+ throw $exception;
+ }
+ }
+
+ $response = $this->middlewareDispatcher->afterController(
+ $controller, $methodName, $response);
+
+ // get the output which should be printed and run the after output
+ // middleware to modify the response
+ $output = $response->render();
+ $out[2] = $this->middlewareDispatcher->beforeOutput(
+ $controller, $methodName, $output);
+
+ // depending on the cache object the headers need to be changed
+ $out[0] = $this->protocol->getStatusHeader($response->getStatus(),
+ $response->getLastModified(), $response->getETag());
+ $out[1] = $response->getHeaders();
+
+ return $out;
+ }
+
+
+}
diff --git a/lib/private/appframework/http/downloadresponse.php b/lib/private/appframework/http/downloadresponse.php
new file mode 100644
index 00000000000..67b9542dba6
--- /dev/null
+++ b/lib/private/appframework/http/downloadresponse.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Http;
+
+
+/**
+ * Prompts the user to download the a file
+ */
+class DownloadResponse extends \OCP\AppFramework\Http\Response {
+
+ private $filename;
+ private $contentType;
+
+ /**
+ * Creates a response that prompts the user to download the file
+ * @param string $filename the name that the downloaded file should have
+ * @param string $contentType the mimetype that the downloaded file should have
+ */
+ public function __construct($filename, $contentType) {
+ $this->filename = $filename;
+ $this->contentType = $contentType;
+
+ $this->addHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
+ $this->addHeader('Content-Type', $contentType);
+ }
+
+
+}
diff --git a/lib/private/appframework/http/http.php b/lib/private/appframework/http/http.php
new file mode 100644
index 00000000000..e00dc9cdc4a
--- /dev/null
+++ b/lib/private/appframework/http/http.php
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Http;
+
+
+class Http extends \OCP\AppFramework\Http\Http{
+
+ private $server;
+ private $protocolVersion;
+ protected $headers;
+
+ /**
+ * @param $_SERVER $server
+ * @param string $protocolVersion the http version to use defaults to HTTP/1.1
+ */
+ public function __construct($server, $protocolVersion='HTTP/1.1') {
+ $this->server = $server;
+ $this->protocolVersion = $protocolVersion;
+
+ $this->headers = array(
+ self::STATUS_CONTINUE => 'Continue',
+ self::STATUS_SWITCHING_PROTOCOLS => 'Switching Protocols',
+ self::STATUS_PROCESSING => 'Processing',
+ self::STATUS_OK => 'OK',
+ self::STATUS_CREATED => 'Created',
+ self::STATUS_ACCEPTED => 'Accepted',
+ self::STATUS_NON_AUTHORATIVE_INFORMATION => 'Non-Authorative Information',
+ self::STATUS_NO_CONTENT => 'No Content',
+ self::STATUS_RESET_CONTENT => 'Reset Content',
+ self::STATUS_PARTIAL_CONTENT => 'Partial Content',
+ self::STATUS_MULTI_STATUS => 'Multi-Status', // RFC 4918
+ self::STATUS_ALREADY_REPORTED => 'Already Reported', // RFC 5842
+ self::STATUS_IM_USED => 'IM Used', // RFC 3229
+ self::STATUS_MULTIPLE_CHOICES => 'Multiple Choices',
+ self::STATUS_MOVED_PERMANENTLY => 'Moved Permanently',
+ self::STATUS_FOUND => 'Found',
+ self::STATUS_SEE_OTHER => 'See Other',
+ self::STATUS_NOT_MODIFIED => 'Not Modified',
+ self::STATUS_USE_PROXY => 'Use Proxy',
+ self::STATUS_RESERVED => 'Reserved',
+ self::STATUS_TEMPORARY_REDIRECT => 'Temporary Redirect',
+ self::STATUS_BAD_REQUEST => 'Bad request',
+ self::STATUS_UNAUTHORIZED => 'Unauthorized',
+ self::STATUS_PAYMENT_REQUIRED => 'Payment Required',
+ self::STATUS_FORBIDDEN => 'Forbidden',
+ self::STATUS_NOT_FOUND => 'Not Found',
+ self::STATUS_METHOD_NOT_ALLOWED => 'Method Not Allowed',
+ self::STATUS_NOT_ACCEPTABLE => 'Not Acceptable',
+ self::STATUS_PROXY_AUTHENTICATION_REQUIRED => 'Proxy Authentication Required',
+ self::STATUS_REQUEST_TIMEOUT => 'Request Timeout',
+ self::STATUS_CONFLICT => 'Conflict',
+ self::STATUS_GONE => 'Gone',
+ self::STATUS_LENGTH_REQUIRED => 'Length Required',
+ self::STATUS_PRECONDITION_FAILED => 'Precondition failed',
+ self::STATUS_REQUEST_ENTITY_TOO_LARGE => 'Request Entity Too Large',
+ self::STATUS_REQUEST_URI_TOO_LONG => 'Request-URI Too Long',
+ self::STATUS_UNSUPPORTED_MEDIA_TYPE => 'Unsupported Media Type',
+ self::STATUS_REQUEST_RANGE_NOT_SATISFIABLE => 'Requested Range Not Satisfiable',
+ self::STATUS_EXPECTATION_FAILED => 'Expectation Failed',
+ self::STATUS_IM_A_TEAPOT => 'I\'m a teapot', // RFC 2324
+ self::STATUS_UNPROCESSABLE_ENTITY => 'Unprocessable Entity', // RFC 4918
+ self::STATUS_LOCKED => 'Locked', // RFC 4918
+ self::STATUS_FAILED_DEPENDENCY => 'Failed Dependency', // RFC 4918
+ self::STATUS_UPGRADE_REQUIRED => 'Upgrade required',
+ self::STATUS_PRECONDITION_REQUIRED => 'Precondition required', // draft-nottingham-http-new-status
+ self::STATUS_TOO_MANY_REQUESTS => 'Too Many Requests', // draft-nottingham-http-new-status
+ self::STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE => 'Request Header Fields Too Large', // draft-nottingham-http-new-status
+ self::STATUS_INTERNAL_SERVER_ERROR => 'Internal Server Error',
+ self::STATUS_NOT_IMPLEMENTED => 'Not Implemented',
+ self::STATUS_BAD_GATEWAY => 'Bad Gateway',
+ self::STATUS_SERVICE_UNAVAILABLE => 'Service Unavailable',
+ self::STATUS_GATEWAY_TIMEOUT => 'Gateway Timeout',
+ self::STATUS_HTTP_VERSION_NOT_SUPPORTED => 'HTTP Version not supported',
+ self::STATUS_VARIANT_ALSO_NEGOTIATES => 'Variant Also Negotiates',
+ self::STATUS_INSUFFICIENT_STORAGE => 'Insufficient Storage', // RFC 4918
+ self::STATUS_LOOP_DETECTED => 'Loop Detected', // RFC 5842
+ self::STATUS_BANDWIDTH_LIMIT_EXCEEDED => 'Bandwidth Limit Exceeded', // non-standard
+ self::STATUS_NOT_EXTENDED => 'Not extended',
+ self::STATUS_NETWORK_AUTHENTICATION_REQUIRED => 'Network Authentication Required', // draft-nottingham-http-new-status
+ );
+ }
+
+
+ /**
+ * Gets the correct header
+ * @param Http::CONSTANT $status the constant from the Http class
+ * @param \DateTime $lastModified formatted last modified date
+ * @param string $Etag the etag
+ */
+ public function getStatusHeader($status, \DateTime $lastModified=null,
+ $ETag=null) {
+
+ if(!is_null($lastModified)) {
+ $lastModified = $lastModified->format(\DateTime::RFC2822);
+ }
+
+ // if etag or lastmodified have not changed, return a not modified
+ if ((isset($this->server['HTTP_IF_NONE_MATCH'])
+ && trim($this->server['HTTP_IF_NONE_MATCH']) === $ETag)
+
+ ||
+
+ (isset($this->server['HTTP_IF_MODIFIED_SINCE'])
+ && trim($this->server['HTTP_IF_MODIFIED_SINCE']) ===
+ $lastModified)) {
+
+ $status = self::STATUS_NOT_MODIFIED;
+ }
+
+ // we have one change currently for the http 1.0 header that differs
+ // from 1.1: STATUS_TEMPORARY_REDIRECT should be STATUS_FOUND
+ // if this differs any more, we want to create childclasses for this
+ if($status === self::STATUS_TEMPORARY_REDIRECT
+ && $this->protocolVersion === 'HTTP/1.0') {
+
+ $status = self::STATUS_FOUND;
+ }
+
+ return $this->protocolVersion . ' ' . $status . ' ' .
+ $this->headers[$status];
+ }
+
+
+}
+
+
diff --git a/lib/private/appframework/http/redirectresponse.php b/lib/private/appframework/http/redirectresponse.php
new file mode 100644
index 00000000000..688447f1618
--- /dev/null
+++ b/lib/private/appframework/http/redirectresponse.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Http;
+
+use OCP\AppFramework\Http\Response;
+
+
+/**
+ * Redirects to a different URL
+ */
+class RedirectResponse extends Response {
+
+ private $redirectURL;
+
+ /**
+ * Creates a response that redirects to a url
+ * @param string $redirectURL the url to redirect to
+ */
+ public function __construct($redirectURL) {
+ $this->redirectURL = $redirectURL;
+ $this->setStatus(Http::STATUS_TEMPORARY_REDIRECT);
+ $this->addHeader('Location', $redirectURL);
+ }
+
+
+ /**
+ * @return string the url to redirect
+ */
+ public function getRedirectURL() {
+ return $this->redirectURL;
+ }
+
+
+}
diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php
new file mode 100644
index 00000000000..34605acdfea
--- /dev/null
+++ b/lib/private/appframework/http/request.php
@@ -0,0 +1,307 @@
+<?php
+/**
+ * ownCloud - Request
+ *
+ * @author Thomas Tanghus
+ * @copyright 2013 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/>.
+ *
+ */
+
+namespace OC\AppFramework\Http;
+
+use OCP\IRequest;
+
+/**
+ * Class for accessing variables in the request.
+ * This class provides an immutable object with request variables.
+ */
+
+class Request implements \ArrayAccess, \Countable, IRequest {
+
+ protected $items = array();
+ protected $allowedKeys = array(
+ 'get',
+ 'post',
+ 'files',
+ 'server',
+ 'env',
+ 'cookies',
+ 'urlParams',
+ 'params',
+ 'parameters',
+ 'method'
+ );
+
+ /**
+ * @param array $vars An associative array with the following optional values:
+ * @param array 'params' the parsed json array
+ * @param array 'urlParams' the parameters which were matched from the URL
+ * @param array 'get' the $_GET array
+ * @param array 'post' the $_POST array
+ * @param array 'files' the $_FILES array
+ * @param array 'server' the $_SERVER array
+ * @param array 'env' the $_ENV array
+ * @param array 'session' the $_SESSION array
+ * @param array 'cookies' the $_COOKIE array
+ * @param string 'method' the request method (GET, POST etc)
+ * @see http://www.php.net/manual/en/reserved.variables.php
+ */
+ public function __construct(array $vars=array()) {
+
+ foreach($this->allowedKeys as $name) {
+ $this->items[$name] = isset($vars[$name])
+ ? $vars[$name]
+ : array();
+ }
+
+ $this->items['parameters'] = array_merge(
+ $this->items['params'],
+ $this->items['get'],
+ $this->items['post'],
+ $this->items['urlParams']
+ );
+
+ }
+
+ // Countable method.
+ public function count() {
+ return count(array_keys($this->items['parameters']));
+ }
+
+ /**
+ * ArrayAccess methods
+ *
+ * Gives access to the combined GET, POST and urlParams arrays
+ *
+ * Examples:
+ *
+ * $var = $request['myvar'];
+ *
+ * or
+ *
+ * if(!isset($request['myvar']) {
+ * // Do something
+ * }
+ *
+ * $request['myvar'] = 'something'; // This throws an exception.
+ *
+ * @param string $offset The key to lookup
+ * @return string|null
+ */
+ public function offsetExists($offset) {
+ return isset($this->items['parameters'][$offset]);
+ }
+
+ /**
+ * @see offsetExists
+ */
+ public function offsetGet($offset) {
+ return isset($this->items['parameters'][$offset])
+ ? $this->items['parameters'][$offset]
+ : null;
+ }
+
+ /**
+ * @see offsetExists
+ */
+ public function offsetSet($offset, $value) {
+ throw new \RuntimeException('You cannot change the contents of the request object');
+ }
+
+ /**
+ * @see offsetExists
+ */
+ public function offsetUnset($offset) {
+ throw new \RuntimeException('You cannot change the contents of the request object');
+ }
+
+ // Magic property accessors
+ public function __set($name, $value) {
+ throw new \RuntimeException('You cannot change the contents of the request object');
+ }
+
+ /**
+ * Access request variables by method and name.
+ * Examples:
+ *
+ * $request->post['myvar']; // Only look for POST variables
+ * $request->myvar; or $request->{'myvar'}; or $request->{$myvar}
+ * Looks in the combined GET, POST and urlParams array.
+ *
+ * if($request->method !== 'POST') {
+ * throw new Exception('This function can only be invoked using POST');
+ * }
+ *
+ * @param string $name The key to look for.
+ * @return mixed|null
+ */
+ public function __get($name) {
+ switch($name) {
+ case 'get':
+ case 'post':
+ case 'files':
+ case 'server':
+ case 'env':
+ case 'cookies':
+ case 'parameters':
+ case 'params':
+ case 'urlParams':
+ return isset($this->items[$name])
+ ? $this->items[$name]
+ : null;
+ break;
+ case 'method':
+ return $this->items['method'];
+ break;
+ default;
+ return isset($this[$name])
+ ? $this[$name]
+ : null;
+ break;
+ }
+ }
+
+
+ public function __isset($name) {
+ return isset($this->items['parameters'][$name]);
+ }
+
+
+ public function __unset($id) {
+ throw new \RunTimeException('You cannot change the contents of the request object');
+ }
+
+ /**
+ * Returns the value for a specific http header.
+ *
+ * This method returns null if the header did not exist.
+ *
+ * @param string $name
+ * @return string
+ */
+ public function getHeader($name) {
+
+ $name = strtoupper(str_replace(array('-'),array('_'),$name));
+ if (isset($this->server['HTTP_' . $name])) {
+ return $this->server['HTTP_' . $name];
+ }
+
+ // There's a few headers that seem to end up in the top-level
+ // server array.
+ switch($name) {
+ case 'CONTENT_TYPE' :
+ case 'CONTENT_LENGTH' :
+ if (isset($this->server[$name])) {
+ return $this->server[$name];
+ }
+ break;
+
+ }
+
+ return null;
+ }
+
+ /**
+ * Lets you access post and get parameters by the index
+ * In case of json requests the encoded json body is accessed
+ *
+ * @param string $key the key which you want to access in the URL Parameter
+ * placeholder, $_POST or $_GET array.
+ * The priority how they're returned is the following:
+ * 1. URL parameters
+ * 2. POST parameters
+ * 3. GET parameters
+ * @param mixed $default If the key is not found, this value will be returned
+ * @return mixed the content of the array
+ */
+ public function getParam($key, $default = null) {
+ return isset($this->parameters[$key])
+ ? $this->parameters[$key]
+ : $default;
+ }
+
+ /**
+ * Returns all params that were received, be it from the request
+ * (as GET or POST) or throuh the URL by the route
+ * @return array the array with all parameters
+ */
+ public function getParams() {
+ return $this->parameters;
+ }
+
+ /**
+ * Returns the method of the request
+ * @return string the method of the request (POST, GET, etc)
+ */
+ public function getMethod() {
+ return $this->method;
+ }
+
+ /**
+ * Shortcut for accessing an uploaded file through the $_FILES array
+ * @param string $key the key that will be taken from the $_FILES array
+ * @return array the file in the $_FILES element
+ */
+ public function getUploadedFile($key) {
+ return isset($this->files[$key]) ? $this->files[$key] : null;
+ }
+
+ /**
+ * Shortcut for getting env variables
+ * @param string $key the key that will be taken from the $_ENV array
+ * @return array the value in the $_ENV element
+ */
+ public function getEnv($key) {
+ return isset($this->env[$key]) ? $this->env[$key] : null;
+ }
+
+ /**
+ * Shortcut for getting cookie variables
+ * @param string $key the key that will be taken from the $_COOKIE array
+ * @return array the value in the $_COOKIE element
+ */
+ function getCookie($key) {
+ return isset($this->cookies[$key]) ? $this->cookies[$key] : null;
+ }
+
+ /**
+ * Returns the request body content.
+ *
+ * @param Boolean $asResource If true, a resource will be returned
+ *
+ * @return string|resource The request body content or a resource to read the body stream.
+ *
+ * @throws \LogicException
+ */
+ function getContent($asResource = false) {
+ return null;
+// if (false === $this->content || (true === $asResource && null !== $this->content)) {
+// throw new \LogicException('getContent() can only be called once when using the resource return type.');
+// }
+//
+// if (true === $asResource) {
+// $this->content = false;
+//
+// return fopen('php://input', 'rb');
+// }
+//
+// if (null === $this->content) {
+// $this->content = file_get_contents('php://input');
+// }
+//
+// return $this->content;
+ }
+}
diff --git a/lib/private/appframework/middleware/middleware.php b/lib/private/appframework/middleware/middleware.php
new file mode 100644
index 00000000000..b12c03c3eb8
--- /dev/null
+++ b/lib/private/appframework/middleware/middleware.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Middleware;
+
+use OCP\AppFramework\Http\Response;
+
+
+/**
+ * Middleware is used to provide hooks before or after controller methods and
+ * deal with possible exceptions raised in the controller methods.
+ * They're modeled after Django's middleware system:
+ * https://docs.djangoproject.com/en/dev/topics/http/middleware/
+ */
+abstract class Middleware {
+
+
+ /**
+ * This is being run in normal order before the controller is being
+ * called which allows several modifications and checks
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ */
+ public function beforeController($controller, $methodName){
+
+ }
+
+
+ /**
+ * This is being run when either the beforeController method or the
+ * controller method itself is throwing an exception. The middleware is
+ * asked in reverse order to handle the exception and to return a response.
+ * If the response is null, it is assumed that the exception could not be
+ * handled and the error will be thrown again
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param \Exception $exception the thrown exception
+ * @throws \Exception the passed in exception if it cant handle it
+ * @return Response a Response object in case that the exception was handled
+ */
+ public function afterException($controller, $methodName, \Exception $exception){
+ throw $exception;
+ }
+
+
+ /**
+ * This is being run after a successful controllermethod call and allows
+ * the manipulation of a Response object. The middleware is run in reverse order
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param Response $response the generated response from the controller
+ * @return Response a Response object
+ */
+ public function afterController($controller, $methodName, Response $response){
+ return $response;
+ }
+
+
+ /**
+ * This is being run after the response object has been rendered and
+ * allows the manipulation of the output. The middleware is run in reverse order
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param string $output the generated output from a response
+ * @return string the output that should be printed
+ */
+ public function beforeOutput($controller, $methodName, $output){
+ return $output;
+ }
+
+}
diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/appframework/middleware/middlewaredispatcher.php
new file mode 100644
index 00000000000..70ab108e6b8
--- /dev/null
+++ b/lib/private/appframework/middleware/middlewaredispatcher.php
@@ -0,0 +1,159 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Middleware;
+
+use OC\AppFramework\Controller\Controller;
+use OCP\AppFramework\Http\Response;
+
+
+/**
+ * This class is used to store and run all the middleware in correct order
+ */
+class MiddlewareDispatcher {
+
+ /**
+ * @var array array containing all the middlewares
+ */
+ private $middlewares;
+
+ /**
+ * @var int counter which tells us what middlware was executed once an
+ * exception occurs
+ */
+ private $middlewareCounter;
+
+
+ /**
+ * Constructor
+ */
+ public function __construct(){
+ $this->middlewares = array();
+ $this->middlewareCounter = 0;
+ }
+
+
+ /**
+ * Adds a new middleware
+ * @param Middleware $middleware the middleware which will be added
+ */
+ public function registerMiddleware(Middleware $middleWare){
+ array_push($this->middlewares, $middleWare);
+ }
+
+
+ /**
+ * returns an array with all middleware elements
+ * @return array the middlewares
+ */
+ public function getMiddlewares(){
+ return $this->middlewares;
+ }
+
+
+ /**
+ * This is being run in normal order before the controller is being
+ * called which allows several modifications and checks
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ */
+ public function beforeController(Controller $controller, $methodName){
+ // we need to count so that we know which middlewares we have to ask in
+ // case theres an exception
+ for($i=0; $i<count($this->middlewares); $i++){
+ $this->middlewareCounter++;
+ $middleware = $this->middlewares[$i];
+ $middleware->beforeController($controller, $methodName);
+ }
+ }
+
+
+ /**
+ * This is being run when either the beforeController method or the
+ * controller method itself is throwing an exception. The middleware is asked
+ * in reverse order to handle the exception and to return a response.
+ * If the response is null, it is assumed that the exception could not be
+ * handled and the error will be thrown again
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param \Exception $exception the thrown exception
+ * @return Response a Response object if the middleware can handle the
+ * exception
+ * @throws \Exception the passed in exception if it cant handle it
+ */
+ public function afterException(Controller $controller, $methodName, \Exception $exception){
+ for($i=$this->middlewareCounter-1; $i>=0; $i--){
+ $middleware = $this->middlewares[$i];
+ try {
+ return $middleware->afterException($controller, $methodName, $exception);
+ } catch(\Exception $exception){
+ continue;
+ }
+ }
+ throw $exception;
+ }
+
+
+ /**
+ * This is being run after a successful controllermethod call and allows
+ * the manipulation of a Response object. The middleware is run in reverse order
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param Response $response the generated response from the controller
+ * @return Response a Response object
+ */
+ public function afterController(Controller $controller, $methodName, Response $response){
+ for($i=count($this->middlewares)-1; $i>=0; $i--){
+ $middleware = $this->middlewares[$i];
+ $response = $middleware->afterController($controller, $methodName, $response);
+ }
+ return $response;
+ }
+
+
+ /**
+ * This is being run after the response object has been rendered and
+ * allows the manipulation of the output. The middleware is run in reverse order
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param string $output the generated output from a response
+ * @return string the output that should be printed
+ */
+ public function beforeOutput(Controller $controller, $methodName, $output){
+ for($i=count($this->middlewares)-1; $i>=0; $i--){
+ $middleware = $this->middlewares[$i];
+ $output = $middleware->beforeOutput($controller, $methodName, $output);
+ }
+ return $output;
+ }
+
+}
diff --git a/lib/private/appframework/middleware/security/securityexception.php b/lib/private/appframework/middleware/security/securityexception.php
new file mode 100644
index 00000000000..b32a2769ff5
--- /dev/null
+++ b/lib/private/appframework/middleware/security/securityexception.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Middleware\Security;
+
+
+/**
+ * Thrown when the security middleware encounters a security problem
+ */
+class SecurityException extends \Exception {
+
+ /**
+ * @param string $msg the security error message
+ * @param bool $ajax true if it resulted because of an ajax request
+ */
+ public function __construct($msg, $code = 0) {
+ parent::__construct($msg, $code);
+ }
+
+}
diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php
new file mode 100644
index 00000000000..4f1447e1afb
--- /dev/null
+++ b/lib/private/appframework/middleware/security/securitymiddleware.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Middleware\Security;
+
+use OC\AppFramework\Controller\Controller;
+use OC\AppFramework\Http\Http;
+use OC\AppFramework\Http\Request;
+use OC\AppFramework\Http\RedirectResponse;
+use OC\AppFramework\Utility\MethodAnnotationReader;
+use OC\AppFramework\Middleware\Middleware;
+use OC\AppFramework\Core\API;
+use OCP\AppFramework\Http\Response;
+use OCP\AppFramework\Http\JSONResponse;
+
+
+/**
+ * Used to do all the authentication and checking stuff for a controller method
+ * It reads out the annotations of a controller method and checks which if
+ * security things should be checked and also handles errors in case a security
+ * check fails
+ */
+class SecurityMiddleware extends Middleware {
+
+ private $api;
+
+ /**
+ * @var \OC\AppFramework\Http\Request
+ */
+ private $request;
+
+ /**
+ * @param API $api an instance of the api
+ */
+ public function __construct(API $api, Request $request){
+ $this->api = $api;
+ $this->request = $request;
+ }
+
+
+ /**
+ * This runs all the security checks before a method call. The
+ * security checks are determined by inspecting the controller method
+ * annotations
+ * @param string/Controller $controller the controllername or string
+ * @param string $methodName the name of the method
+ * @throws SecurityException when a security check fails
+ */
+ public function beforeController($controller, $methodName){
+
+ // get annotations from comments
+ $annotationReader = new MethodAnnotationReader($controller, $methodName);
+
+ // this will set the current navigation entry of the app, use this only
+ // for normal HTML requests and not for AJAX requests
+ $this->api->activateNavigationEntry();
+
+ // security checks
+ $isPublicPage = $annotationReader->hasAnnotation('PublicPage');
+ if(!$isPublicPage) {
+ if(!$this->api->isLoggedIn()) {
+ throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED);
+ }
+
+ if(!$annotationReader->hasAnnotation('NoAdminRequired')) {
+ if(!$this->api->isAdminUser($this->api->getUserId())) {
+ throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN);
+ }
+ }
+ }
+
+ if(!$annotationReader->hasAnnotation('NoCSRFRequired')) {
+ if(!$this->api->passesCSRFCheck()) {
+ throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED);
+ }
+ }
+
+ }
+
+
+ /**
+ * If an SecurityException is being caught, ajax requests return a JSON error
+ * response and non ajax requests redirect to the index
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param \Exception $exception the thrown exception
+ * @throws \Exception the passed in exception if it cant handle it
+ * @return Response a Response object or null in case that the exception could not be handled
+ */
+ public function afterException($controller, $methodName, \Exception $exception){
+ if($exception instanceof SecurityException){
+
+ if (stripos($this->request->getHeader('Accept'),'html')===false) {
+
+ $response = new JSONResponse(
+ array('message' => $exception->getMessage()),
+ $exception->getCode()
+ );
+ $this->api->log($exception->getMessage(), 'debug');
+ } else {
+
+ $url = $this->api->linkToAbsolute('index.php', ''); // TODO: replace with link to route
+ $response = new RedirectResponse($url);
+ $this->api->log($exception->getMessage(), 'debug');
+ }
+
+ return $response;
+
+ }
+
+ throw $exception;
+ }
+
+}
diff --git a/lib/private/appframework/routing/routeactionhandler.php b/lib/private/appframework/routing/routeactionhandler.php
new file mode 100644
index 00000000000..7fb56f14eab
--- /dev/null
+++ b/lib/private/appframework/routing/routeactionhandler.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * ownCloud - App Framework
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu
+ *
+ * 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 OC\AppFramework\routing;
+
+use \OC\AppFramework\App;
+use \OC\AppFramework\DependencyInjection\DIContainer;
+
+class RouteActionHandler {
+ private $controllerName;
+ private $actionName;
+ private $container;
+
+ public function __construct(DIContainer $container, $controllerName, $actionName) {
+ $this->controllerName = $controllerName;
+ $this->actionName = $actionName;
+ $this->container = $container;
+ }
+
+ public function __invoke($params) {
+ App::main($this->controllerName, $this->actionName, $params, $this->container);
+ }
+}
diff --git a/lib/private/appframework/routing/routeconfig.php b/lib/private/appframework/routing/routeconfig.php
new file mode 100644
index 00000000000..53ab11bf2f5
--- /dev/null
+++ b/lib/private/appframework/routing/routeconfig.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * ownCloud - App Framework
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu
+ *
+ * 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 OC\AppFramework\routing;
+
+use OC\AppFramework\DependencyInjection\DIContainer;
+
+/**
+ * Class RouteConfig
+ * @package OC\AppFramework\routing
+ */
+class RouteConfig {
+ private $container;
+ private $router;
+ private $routes;
+ private $appName;
+
+ /**
+ * @param \OC\AppFramework\DependencyInjection\DIContainer $container
+ * @param \OC_Router $router
+ * @param string $pathToYml
+ * @internal param $appName
+ */
+ public function __construct(DIContainer $container, \OC_Router $router, $routes) {
+ $this->routes = $routes;
+ $this->container = $container;
+ $this->router = $router;
+ $this->appName = $container['AppName'];
+ }
+
+ /**
+ * The routes and resource will be registered to the \OC_Router
+ */
+ public function register() {
+
+ // parse simple
+ $this->processSimpleRoutes($this->routes);
+
+ // parse resources
+ $this->processResources($this->routes);
+ }
+
+ /**
+ * Creates one route base on the give configuration
+ * @param $routes
+ * @throws \UnexpectedValueException
+ */
+ private function processSimpleRoutes($routes)
+ {
+ $simpleRoutes = isset($routes['routes']) ? $routes['routes'] : array();
+ foreach ($simpleRoutes as $simpleRoute) {
+ $name = $simpleRoute['name'];
+ $url = $simpleRoute['url'];
+ $verb = isset($simpleRoute['verb']) ? strtoupper($simpleRoute['verb']) : 'GET';
+
+ $split = explode('#', $name, 2);
+ if (count($split) != 2) {
+ throw new \UnexpectedValueException('Invalid route name');
+ }
+ $controller = $split[0];
+ $action = $split[1];
+
+ $controllerName = $this->buildControllerName($controller);
+ $actionName = $this->buildActionName($action);
+
+ // register the route
+ $handler = new RouteActionHandler($this->container, $controllerName, $actionName);
+ $this->router->create($this->appName.'.'.$controller.'.'.$action, $url)->method($verb)->action($handler);
+ }
+ }
+
+ /**
+ * For a given name and url restful routes are created:
+ * - index
+ * - show
+ * - new
+ * - create
+ * - update
+ * - destroy
+ *
+ * @param $routes
+ */
+ private function processResources($routes)
+ {
+ // declaration of all restful actions
+ $actions = array(
+ array('name' => 'index', 'verb' => 'GET', 'on-collection' => true),
+ array('name' => 'show', 'verb' => 'GET'),
+ array('name' => 'create', 'verb' => 'POST', 'on-collection' => true),
+ array('name' => 'update', 'verb' => 'PUT'),
+ array('name' => 'destroy', 'verb' => 'DELETE'),
+ );
+
+ $resources = isset($routes['resources']) ? $routes['resources'] : array();
+ foreach ($resources as $resource => $config) {
+
+ // the url parameter used as id to the resource
+ $resourceId = $this->buildResourceId($resource);
+ foreach($actions as $action) {
+ $url = $config['url'];
+ $method = $action['name'];
+ $verb = isset($action['verb']) ? strtoupper($action['verb']) : 'GET';
+ $collectionAction = isset($action['on-collection']) ? $action['on-collection'] : false;
+ if (!$collectionAction) {
+ $url = $url . '/' . $resourceId;
+ }
+ if (isset($action['url-postfix'])) {
+ $url = $url . '/' . $action['url-postfix'];
+ }
+
+ $controller = $resource;
+
+ $controllerName = $this->buildControllerName($controller);
+ $actionName = $this->buildActionName($method);
+
+ $routeName = $this->appName . '.' . strtolower($resource) . '.' . strtolower($method);
+
+ $this->router->create($routeName, $url)->method($verb)->action(
+ new RouteActionHandler($this->container, $controllerName, $actionName)
+ );
+ }
+ }
+ }
+
+ /**
+ * Based on a given route name the controller name is generated
+ * @param $controller
+ * @return string
+ */
+ private function buildControllerName($controller)
+ {
+ return $this->underScoreToCamelCase(ucfirst($controller)) . 'Controller';
+ }
+
+ /**
+ * Based on the action part of the route name the controller method name is generated
+ * @param $action
+ * @return string
+ */
+ private function buildActionName($action) {
+ return $this->underScoreToCamelCase($action);
+ }
+
+ /**
+ * Generates the id used in the url part o the route url
+ * @param $resource
+ * @return string
+ */
+ private function buildResourceId($resource) {
+ return '{'.$this->underScoreToCamelCase(rtrim($resource, 's')).'Id}';
+ }
+
+ /**
+ * Underscored strings are converted to camel case strings
+ * @param $str string
+ * @return string
+ */
+ private function underScoreToCamelCase($str) {
+ $pattern = "/_[a-z]?/";
+ return preg_replace_callback(
+ $pattern,
+ function ($matches) {
+ return strtoupper(ltrim($matches[0], "_"));
+ },
+ $str);
+ }
+}
diff --git a/lib/private/appframework/utility/methodannotationreader.php b/lib/private/appframework/utility/methodannotationreader.php
new file mode 100644
index 00000000000..42060a08529
--- /dev/null
+++ b/lib/private/appframework/utility/methodannotationreader.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Utility;
+
+
+/**
+ * Reads and parses annotations from doc comments
+ */
+class MethodAnnotationReader {
+
+ private $annotations;
+
+ /**
+ * @param object $object an object or classname
+ * @param string $method the method which we want to inspect for annotations
+ */
+ public function __construct($object, $method){
+ $this->annotations = array();
+
+ $reflection = new \ReflectionMethod($object, $method);
+ $docs = $reflection->getDocComment();
+
+ // extract everything prefixed by @ and first letter uppercase
+ preg_match_all('/@([A-Z]\w+)/', $docs, $matches);
+ $this->annotations = $matches[1];
+ }
+
+
+ /**
+ * Check if a method contains an annotation
+ * @param string $name the name of the annotation
+ * @return bool true if the annotation is found
+ */
+ public function hasAnnotation($name){
+ return in_array($name, $this->annotations);
+ }
+
+
+}
diff --git a/lib/private/appframework/utility/simplecontainer.php b/lib/private/appframework/utility/simplecontainer.php
new file mode 100644
index 00000000000..7e4db63bde5
--- /dev/null
+++ b/lib/private/appframework/utility/simplecontainer.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace OC\AppFramework\Utility;
+
+// register 3rdparty autoloaders
+require_once __DIR__ . '/../../../../3rdparty/Pimple/Pimple.php';
+
+/**
+ * Class SimpleContainer
+ *
+ * SimpleContainer is a simple implementation of IContainer on basis of \Pimple
+ */
+class SimpleContainer extends \Pimple implements \OCP\IContainer {
+
+ /**
+ * @param string $name name of the service to query for
+ * @return object registered service for the given $name
+ */
+ public function query($name) {
+ return $this->offsetGet($name);
+ }
+
+ function registerParameter($name, $value)
+ {
+ $this[$name] = $value;
+ }
+
+ /**
+ * The given closure is call the first time the given service is queried.
+ * The closure has to return the instance for the given service.
+ * Created instance will be cached in case $shared is true.
+ *
+ * @param string $name name of the service to register another backend for
+ * @param callable $closure the closure to be called on service creation
+ */
+ function registerService($name, \Closure $closure, $shared = true)
+ {
+ if ($shared) {
+ $this[$name] = \Pimple::share($closure);
+ } else {
+ $this[$name] = $closure;
+ }
+ }
+}
diff --git a/lib/private/appframework/utility/timefactory.php b/lib/private/appframework/utility/timefactory.php
new file mode 100644
index 00000000000..2c3dd6cf5e3
--- /dev/null
+++ b/lib/private/appframework/utility/timefactory.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Utility;
+
+
+/**
+ * Needed to mock calls to time()
+ */
+class TimeFactory {
+
+
+ /**
+ * @return int the result of a call to time()
+ */
+ public function getTime() {
+ return time();
+ }
+
+
+}
diff --git a/lib/archive.php b/lib/private/archive.php
index 364cd5a74a1..85bfae57295 100644
--- a/lib/archive.php
+++ b/lib/private/archive.php
@@ -119,7 +119,8 @@ abstract class OC_Archive{
* @return bool
*/
function addRecursive($path, $source) {
- if($dh=opendir($source)) {
+ $dh = opendir($source);
+ if(is_resource($dh)) {
$this->addFolder($path);
while (($file = readdir($dh)) !== false) {
if($file=='.' or $file=='..') {
diff --git a/lib/archive/tar.php b/lib/private/archive/tar.php
index a1c0535b1c3..a1c0535b1c3 100644
--- a/lib/archive/tar.php
+++ b/lib/private/archive/tar.php
diff --git a/lib/archive/zip.php b/lib/private/archive/zip.php
index 8a866716a79..8a866716a79 100644
--- a/lib/archive/zip.php
+++ b/lib/private/archive/zip.php
diff --git a/lib/arrayparser.php b/lib/private/arrayparser.php
index 3bb394a5163..3bb394a5163 100644
--- a/lib/arrayparser.php
+++ b/lib/private/arrayparser.php
diff --git a/lib/private/avatar.php b/lib/private/avatar.php
new file mode 100644
index 00000000000..f20980c364b
--- /dev/null
+++ b/lib/private/avatar.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+/**
+ * This class gets and sets users avatars.
+ */
+
+class OC_Avatar {
+
+ private $view;
+
+ /**
+ * @brief constructor
+ * @param $user string user to do avatar-management with
+ */
+ public function __construct ($user) {
+ $this->view = new \OC\Files\View('/'.$user);
+ }
+
+ /**
+ * @brief get the users avatar
+ * @param $size integer size in px of the avatar, defaults to 64
+ * @return boolean|\OC_Image containing the avatar or false if there's no image
+ */
+ public function get ($size = 64) {
+ if ($this->view->file_exists('avatar.jpg')) {
+ $ext = 'jpg';
+ } elseif ($this->view->file_exists('avatar.png')) {
+ $ext = 'png';
+ } else {
+ return false;
+ }
+
+ $avatar = new OC_Image();
+ $avatar->loadFromData($this->view->file_get_contents('avatar.'.$ext));
+ $avatar->resize($size);
+ return $avatar;
+ }
+
+ /**
+ * @brief sets the users avatar
+ * @param $data mixed imagedata or path to set a new avatar
+ * @throws Exception if the provided file is not a jpg or png image
+ * @throws Exception if the provided image is not valid
+ * @throws \OC\NotSquareException if the image is not square
+ * @return void
+ */
+ public function set ($data) {
+ if (\OC_App::isEnabled('files_encryption')) {
+ $l = \OC_L10N::get('lib');
+ throw new \Exception($l->t("Custom profile pictures don't work with encryption yet"));
+ }
+
+ $img = new OC_Image($data);
+ $type = substr($img->mimeType(), -3);
+ if ($type === 'peg') { $type = 'jpg'; }
+ if ($type !== 'jpg' && $type !== 'png') {
+ $l = \OC_L10N::get('lib');
+ throw new \Exception($l->t("Unknown filetype"));
+ }
+
+ if (!$img->valid()) {
+ $l = \OC_L10N::get('lib');
+ throw new \Exception($l->t("Invalid image"));
+ }
+
+ if (!($img->height() === $img->width())) {
+ throw new \OC\NotSquareException();
+ }
+
+ $this->view->unlink('avatar.jpg');
+ $this->view->unlink('avatar.png');
+ $this->view->file_put_contents('avatar.'.$type, $data);
+ }
+
+ /**
+ * @brief remove the users avatar
+ * @return void
+ */
+ public function remove () {
+ $this->view->unlink('avatar.jpg');
+ $this->view->unlink('avatar.png');
+ }
+}
diff --git a/lib/backgroundjob.php b/lib/private/backgroundjob.php
index 9619dcb732c..9619dcb732c 100644
--- a/lib/backgroundjob.php
+++ b/lib/private/backgroundjob.php
diff --git a/lib/backgroundjob/job.php b/lib/private/backgroundjob/job.php
index 49fbffbd684..49fbffbd684 100644
--- a/lib/backgroundjob/job.php
+++ b/lib/private/backgroundjob/job.php
diff --git a/lib/backgroundjob/joblist.php b/lib/private/backgroundjob/joblist.php
index cc803dd9b5f..cc803dd9b5f 100644
--- a/lib/backgroundjob/joblist.php
+++ b/lib/private/backgroundjob/joblist.php
diff --git a/lib/backgroundjob/legacy/queuedjob.php b/lib/private/backgroundjob/legacy/queuedjob.php
index 2bc001103b8..2bc001103b8 100644
--- a/lib/backgroundjob/legacy/queuedjob.php
+++ b/lib/private/backgroundjob/legacy/queuedjob.php
diff --git a/lib/backgroundjob/legacy/regularjob.php b/lib/private/backgroundjob/legacy/regularjob.php
index d4cfa348cea..d4cfa348cea 100644
--- a/lib/backgroundjob/legacy/regularjob.php
+++ b/lib/private/backgroundjob/legacy/regularjob.php
diff --git a/lib/backgroundjob/queuedjob.php b/lib/private/backgroundjob/queuedjob.php
index 1714182820d..1714182820d 100644
--- a/lib/backgroundjob/queuedjob.php
+++ b/lib/private/backgroundjob/queuedjob.php
diff --git a/lib/backgroundjob/timedjob.php b/lib/private/backgroundjob/timedjob.php
index ae9f33505ab..ae9f33505ab 100644
--- a/lib/backgroundjob/timedjob.php
+++ b/lib/private/backgroundjob/timedjob.php
diff --git a/lib/cache.php b/lib/private/cache.php
index 48b9964ba9d..a311f10a00f 100644
--- a/lib/cache.php
+++ b/lib/private/cache.php
@@ -6,34 +6,36 @@
* See the COPYING-README file.
*/
-class OC_Cache {
+namespace OC;
+
+class Cache {
/**
- * @var OC_Cache $user_cache
+ * @var Cache $user_cache
*/
static protected $user_cache;
/**
- * @var OC_Cache $global_cache
+ * @var Cache $global_cache
*/
static protected $global_cache;
/**
* get the global cache
- * @return OC_Cache
+ * @return Cache
*/
static public function getGlobalCache() {
if (!self::$global_cache) {
- self::$global_cache = new OC_Cache_FileGlobal();
+ self::$global_cache = new Cache\FileGlobal();
}
return self::$global_cache;
}
/**
* get the user cache
- * @return OC_Cache
+ * @return Cache
*/
static public function getUserCache() {
if (!self::$user_cache) {
- self::$user_cache = new OC_Cache_File();
+ self::$user_cache = new Cache\File();
}
return self::$user_cache;
}
@@ -85,7 +87,7 @@ class OC_Cache {
/**
* clear the user cache of all entries starting with a prefix
- * @param string prefix (optional)
+ * @param string $prefix (optional)
* @return bool
*/
static public function clear($prefix='') {
@@ -93,6 +95,11 @@ class OC_Cache {
return $user_cache->clear($prefix);
}
+ /**
+ * creates cache key based on the files given
+ * @param $files
+ * @return string
+ */
static public function generateCacheKeyFromFiles($files) {
$key = '';
sort($files);
diff --git a/lib/cache/broker.php b/lib/private/cache/broker.php
index a161dbfa3bb..9b7e837e1bc 100644
--- a/lib/cache/broker.php
+++ b/lib/private/cache/broker.php
@@ -6,8 +6,18 @@
* See the COPYING-README file.
*/
-class OC_Cache_Broker {
+namespace OC\Cache;
+
+class Broker {
+
+ /**
+ * @var \OC\Cache
+ */
protected $fast_cache;
+
+ /**
+ * @var \OC\Cache
+ */
protected $slow_cache;
public function __construct($fast_cache, $slow_cache) {
diff --git a/lib/cache/file.php b/lib/private/cache/file.php
index 9fee6034a71..2ab914d17b8 100644
--- a/lib/cache/file.php
+++ b/lib/private/cache/file.php
@@ -6,24 +6,25 @@
* See the COPYING-README file.
*/
+namespace OC\Cache;
-class OC_Cache_File{
+class File {
protected $storage;
protected function getStorage() {
if (isset($this->storage)) {
return $this->storage;
}
- if(OC_User::isLoggedIn()) {
- \OC\Files\Filesystem::initMountPoints(OC_User::getUser());
+ if(\OC_User::isLoggedIn()) {
+ \OC\Files\Filesystem::initMountPoints(\OC_User::getUser());
$subdir = 'cache';
- $view = new \OC\Files\View('/'.OC_User::getUser());
+ $view = new \OC\Files\View('/' . \OC_User::getUser());
if(!$view->file_exists($subdir)) {
$view->mkdir($subdir);
}
- $this->storage = new \OC\Files\View('/'.OC_User::getUser().'/'.$subdir);
+ $this->storage = new \OC\Files\View('/' . \OC_User::getUser().'/'.$subdir);
return $this->storage;
}else{
- OC_Log::write('core', 'Can\'t get cache storage, user not logged in', OC_Log::ERROR);
+ \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR);
return false;
}
}
@@ -80,9 +81,11 @@ class OC_Cache_File{
$storage = $this->getStorage();
if($storage and $storage->is_dir('/')) {
$dh=$storage->opendir('/');
- while (($file = readdir($dh)) !== false) {
- if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)) {
- $storage->unlink('/'.$file);
+ if(is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)) {
+ $storage->unlink('/'.$file);
+ }
}
}
}
@@ -94,6 +97,9 @@ class OC_Cache_File{
if($storage and $storage->is_dir('/')) {
$now = time();
$dh=$storage->opendir('/');
+ if(!is_resource($dh)) {
+ return null;
+ }
while (($file = readdir($dh)) !== false) {
if($file!='.' and $file!='..') {
$mtime = $storage->filemtime('/'.$file);
diff --git a/lib/cache/fileglobal.php b/lib/private/cache/fileglobal.php
index 2fbd8ca3edb..bd049bba4d0 100644
--- a/lib/cache/fileglobal.php
+++ b/lib/private/cache/fileglobal.php
@@ -6,10 +6,11 @@
* See the COPYING-README file.
*/
+namespace OC\Cache;
-class OC_Cache_FileGlobal{
+class FileGlobal {
static protected function getCacheDir() {
- $cache_dir = get_temp_dir().'/owncloud-'.OC_Util::getInstanceId().'/';
+ $cache_dir = get_temp_dir().'/owncloud-' . \OC_Util::getInstanceId().'/';
if (!is_dir($cache_dir)) {
mkdir($cache_dir);
}
@@ -69,30 +70,34 @@ class OC_Cache_FileGlobal{
$prefix = $this->fixKey($prefix);
if($cache_dir and is_dir($cache_dir)) {
$dh=opendir($cache_dir);
- while (($file = readdir($dh)) !== false) {
- if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)) {
- unlink($cache_dir.$file);
+ if(is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)) {
+ unlink($cache_dir.$file);
+ }
}
}
}
}
static public function gc() {
- $last_run = OC_AppConfig::getValue('core', 'global_cache_gc_lastrun', 0);
+ $last_run = \OC_AppConfig::getValue('core', 'global_cache_gc_lastrun', 0);
$now = time();
if (($now - $last_run) < 300) {
// only do cleanup every 5 minutes
return;
}
- OC_AppConfig::setValue('core', 'global_cache_gc_lastrun', $now);
+ \OC_AppConfig::setValue('core', 'global_cache_gc_lastrun', $now);
$cache_dir = self::getCacheDir();
if($cache_dir and is_dir($cache_dir)) {
$dh=opendir($cache_dir);
- while (($file = readdir($dh)) !== false) {
- if($file!='.' and $file!='..') {
- $mtime = filemtime($cache_dir.$file);
- if ($mtime < $now) {
- unlink($cache_dir.$file);
+ if(is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ if($file!='.' and $file!='..') {
+ $mtime = filemtime($cache_dir.$file);
+ if ($mtime < $now) {
+ unlink($cache_dir.$file);
+ }
}
}
}
diff --git a/lib/private/cache/fileglobalgc.php b/lib/private/cache/fileglobalgc.php
new file mode 100644
index 00000000000..399dd5e6f94
--- /dev/null
+++ b/lib/private/cache/fileglobalgc.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace OC\Cache;
+
+class FileGlobalGC extends \OC\BackgroundJob\Job{
+ public function run($argument){
+ FileGlobal::gc();
+ }
+}
diff --git a/lib/private/cache/usercache.php b/lib/private/cache/usercache.php
new file mode 100644
index 00000000000..baa8820700b
--- /dev/null
+++ b/lib/private/cache/usercache.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net)
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+namespace OC\Cache;
+
+/**
+ * This interface defines method for accessing the file based user cache.
+ */
+class UserCache implements \OCP\ICache {
+
+ /**
+ * @var \OC\Cache\File $userCache
+ */
+ protected $userCache;
+
+ public function __construct() {
+ $this->userCache = new File();
+ }
+
+ /**
+ * Get a value from the user cache
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function get($key) {
+ return $this->userCache->get($key);
+ }
+
+ /**
+ * Set a value in the user cache
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function set($key, $value, $ttl = 0) {
+ if (empty($key)) {
+ return false;
+ }
+ return $this->userCache->set($key, $value, $ttl);
+ }
+
+ /**
+ * Check if a value is set in the user cache
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function hasKey($key) {
+ return $this->userCache->hasKey($key);
+ }
+
+ /**
+ * Remove an item from the user cache
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function remove($key) {
+ return $this->userCache->remove($key);
+ }
+
+ /**
+ * clear the user cache of all entries starting with a prefix
+ * @param string $prefix (optional)
+ * @return bool
+ */
+ public function clear($prefix = '') {
+ return $this->userCache->clear($prefix);
+ }
+}
diff --git a/lib/config.php b/lib/private/config.php
index e773e6e2eb0..e773e6e2eb0 100644
--- a/lib/config.php
+++ b/lib/private/config.php
diff --git a/lib/connector/sabre/ServiceUnavailable.php b/lib/private/connector/sabre/ServiceUnavailable.php
index c1cc815c989..c1cc815c989 100644
--- a/lib/connector/sabre/ServiceUnavailable.php
+++ b/lib/private/connector/sabre/ServiceUnavailable.php
diff --git a/lib/private/connector/sabre/aborteduploaddetectionplugin.php b/lib/private/connector/sabre/aborteduploaddetectionplugin.php
new file mode 100644
index 00000000000..15dca3a6809
--- /dev/null
+++ b/lib/private/connector/sabre/aborteduploaddetectionplugin.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Müller <thomas.mueller@tmit.eu>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+/**
+ * Class OC_Connector_Sabre_AbortedUploadDetectionPlugin
+ *
+ * This plugin will verify if the uploaded data has been stored completely.
+ * This is done by comparing the content length of the request with the file size on storage.
+ */
+class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPlugin {
+
+ /**
+ * Reference to main server object
+ *
+ * @var Sabre_DAV_Server
+ */
+ private $server;
+
+ /**
+ * is kept public to allow overwrite for unit testing
+ *
+ * @var \OC\Files\View
+ */
+ public $fileView;
+
+ /**
+ * This initializes the plugin.
+ *
+ * This function is called by Sabre_DAV_Server, after
+ * addPlugin is called.
+ *
+ * This method should set up the requires event subscriptions.
+ *
+ * @param Sabre_DAV_Server $server
+ */
+ public function initialize(Sabre_DAV_Server $server) {
+
+ $this->server = $server;
+
+ $server->subscribeEvent('afterCreateFile', array($this, 'verifyContentLength'), 10);
+ $server->subscribeEvent('afterWriteContent', array($this, 'verifyContentLength'), 10);
+ }
+
+ /**
+ * @param $filePath
+ * @param Sabre_DAV_INode $node
+ * @throws Sabre_DAV_Exception_BadRequest
+ */
+ public function verifyContentLength($filePath, Sabre_DAV_INode $node = null) {
+
+ // ownCloud chunked upload will be handled in its own plugin
+ $chunkHeader = $this->server->httpRequest->getHeader('OC-Chunked');
+ if ($chunkHeader) {
+ return;
+ }
+
+ // compare expected and actual size
+ $expected = $this->getLength();
+ if (!$expected) {
+ return;
+ }
+ $actual = $this->getFileView()->filesize($filePath);
+ if ($actual != $expected) {
+ $this->getFileView()->unlink($filePath);
+ throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $actual);
+ }
+
+ }
+
+ /**
+ * @return string
+ */
+ public function getLength()
+ {
+ $req = $this->server->httpRequest;
+ $length = $req->getHeader('X-Expected-Entity-Length');
+ if (!$length) {
+ $length = $req->getHeader('Content-Length');
+ }
+
+ return $length;
+ }
+
+ /**
+ * @return \OC\Files\View
+ */
+ public function getFileView()
+ {
+ if (is_null($this->fileView)) {
+ // initialize fileView
+ $this->fileView = \OC\Files\Filesystem::getView();
+ }
+
+ return $this->fileView;
+ }
+}
diff --git a/lib/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php
index bf3a49593cb..bf3a49593cb 100644
--- a/lib/connector/sabre/auth.php
+++ b/lib/private/connector/sabre/auth.php
diff --git a/lib/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index 3181a4b310f..382bdf06df1 100644
--- a/lib/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -74,21 +74,14 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
\OC\Files\Filesystem::file_put_contents($partpath, $data);
- //detect aborted upload
- if (isset ($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'PUT' ) {
- if (isset($_SERVER['CONTENT_LENGTH'])) {
- $expected = $_SERVER['CONTENT_LENGTH'];
- $actual = \OC\Files\Filesystem::filesize($partpath);
- if ($actual != $expected) {
- \OC\Files\Filesystem::unlink($partpath);
- throw new Sabre_DAV_Exception_BadRequest(
- 'expected filesize ' . $expected . ' got ' . $actual);
- }
- }
- }
-
// rename to correct path
- \OC\Files\Filesystem::rename($partpath, $newPath);
+ $renameOkay = \OC\Files\Filesystem::rename($partpath, $newPath);
+ $fileExists = \OC\Files\Filesystem::file_exists($newPath);
+ if ($renameOkay === false || $fileExists === false) {
+ \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
+ \OC\Files\Filesystem::unlink($partpath);
+ throw new Sabre_DAV_Exception();
+ }
// allow sync clients to send the mtime along in a header
$mtime = OC_Request::hasModificationTime();
diff --git a/lib/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 61bdcd5e0ae..433b1148552 100644
--- a/lib/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -74,7 +74,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
}
// rename to correct path
- \OC\Files\Filesystem::rename($partpath, $this->path);
+ $renameOkay = \OC\Files\Filesystem::rename($partpath, $this->path);
+ $fileExists = \OC\Files\Filesystem::file_exists($this->path);
+ if ($renameOkay === false || $fileExists === false) {
+ \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
+ \OC\Files\Filesystem::unlink($partpath);
+ throw new Sabre_DAV_Exception();
+ }
+
//allow sync clients to send the mtime along in a header
$mtime = OC_Request::hasModificationTime();
diff --git a/lib/connector/sabre/locks.php b/lib/private/connector/sabre/locks.php
index 69496c15ada..69496c15ada 100644
--- a/lib/connector/sabre/locks.php
+++ b/lib/private/connector/sabre/locks.php
diff --git a/lib/connector/sabre/maintenanceplugin.php b/lib/private/connector/sabre/maintenanceplugin.php
index 2eda269afc2..2eda269afc2 100644
--- a/lib/connector/sabre/maintenanceplugin.php
+++ b/lib/private/connector/sabre/maintenanceplugin.php
diff --git a/lib/connector/sabre/node.php b/lib/private/connector/sabre/node.php
index 0bffa58af78..29b7f9e53a5 100644
--- a/lib/connector/sabre/node.php
+++ b/lib/private/connector/sabre/node.php
@@ -78,6 +78,11 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
*/
public function setName($name) {
+ // rename is only allowed if the update privilege is granted
+ if (!\OC\Files\Filesystem::isUpdatable($this->path)) {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
+
list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path);
list(, $newName) = Sabre_DAV_URLUtil::splitPath($name);
@@ -135,6 +140,12 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* Even if the modification time is set to a custom value the access time is set to now.
*/
public function touch($mtime) {
+
+ // touch is only allowed if the update privilege is granted
+ if (!\OC\Files\Filesystem::isUpdatable($this->path)) {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
+
\OC\Files\Filesystem::touch($this->path, $mtime);
}
diff --git a/lib/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index b298813a202..80c3840b99d 100644
--- a/lib/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -11,6 +11,14 @@ namespace OC\Connector\Sabre;
use OC\Files\Filesystem;
class ObjectTree extends \Sabre_DAV_ObjectTree {
+
+ /**
+ * keep this public to allow mock injection during unit test
+ *
+ * @var \OC\Files\View
+ */
+ public $fileView;
+
/**
* Returns the INode object for the requested path
*
@@ -21,14 +29,16 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
public function getNodeForPath($path) {
$path = trim($path, '/');
- if (isset($this->cache[$path])) return $this->cache[$path];
+ if (isset($this->cache[$path])) {
+ return $this->cache[$path];
+ }
// Is it the root node?
if (!strlen($path)) {
return $this->rootNode;
}
- $info = Filesystem::getFileInfo($path);
+ $info = $this->getFileView()->getFileInfo($path);
if (!$info) {
throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
@@ -64,7 +74,25 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
list($sourceDir,) = \Sabre_DAV_URLUtil::splitPath($sourcePath);
list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destinationPath);
- Filesystem::rename($sourcePath, $destinationPath);
+ // check update privileges
+ $fs = $this->getFileView();
+ if (!$fs->isUpdatable($sourcePath)) {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
+ if ($sourceDir !== $destinationDir) {
+ // for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
+ if (!$fs->isUpdatable($sourceDir)) {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
+ if (!$fs->isUpdatable($destinationDir)) {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
+ }
+
+ $renameOkay = $fs->rename($sourcePath, $destinationPath);
+ if (!$renameOkay) {
+ throw new \Sabre_DAV_Exception_Forbidden('');
+ }
$this->markDirty($sourceDir);
$this->markDirty($destinationDir);
@@ -88,15 +116,27 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
} else {
Filesystem::mkdir($destination);
$dh = Filesystem::opendir($source);
- while (($subnode = readdir($dh)) !== false) {
+ if(is_resource($dh)) {
+ while (($subnode = readdir($dh)) !== false) {
- if ($subnode == '.' || $subnode == '..') continue;
- $this->copy($source . '/' . $subnode, $destination . '/' . $subnode);
+ if ($subnode == '.' || $subnode == '..') continue;
+ $this->copy($source . '/' . $subnode, $destination . '/' . $subnode);
+ }
}
}
list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destination);
$this->markDirty($destinationDir);
}
+
+ /**
+ * @return \OC\Files\View
+ */
+ public function getFileView() {
+ if (is_null($this->fileView)) {
+ $this->fileView = \OC\Files\Filesystem::getView();
+ }
+ return $this->fileView;
+ }
}
diff --git a/lib/connector/sabre/principal.php b/lib/private/connector/sabre/principal.php
index 59a96797c16..59a96797c16 100644
--- a/lib/connector/sabre/principal.php
+++ b/lib/private/connector/sabre/principal.php
diff --git a/lib/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php
index ea2cb81d1f7..ea2cb81d1f7 100644
--- a/lib/connector/sabre/quotaplugin.php
+++ b/lib/private/connector/sabre/quotaplugin.php
diff --git a/lib/connector/sabre/request.php b/lib/private/connector/sabre/request.php
index d70c25c4e70..d70c25c4e70 100644
--- a/lib/connector/sabre/request.php
+++ b/lib/private/connector/sabre/request.php
diff --git a/lib/private/contactsmanager.php b/lib/private/contactsmanager.php
new file mode 100644
index 00000000000..fc6745b4505
--- /dev/null
+++ b/lib/private/contactsmanager.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu
+ *
+ * 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 OC {
+
+ class ContactsManager implements \OCP\Contacts\IManager {
+
+ /**
+ * This function is used to search and find contacts within the users address books.
+ * In case $pattern is empty all contacts will be returned.
+ *
+ * @param string $pattern which should match within the $searchProperties
+ * @param array $searchProperties defines the properties within the query pattern should match
+ * @param array $options - for future use. One should always have options!
+ * @return array of contacts which are arrays of key-value-pairs
+ */
+ public function search($pattern, $searchProperties = array(), $options = array()) {
+ $result = array();
+ foreach($this->address_books as $address_book) {
+ $r = $address_book->search($pattern, $searchProperties, $options);
+ $result = array_merge($result, $r);
+ }
+
+ return $result;
+ }
+
+ /**
+ * This function can be used to delete the contact identified by the given id
+ *
+ * @param object $id the unique identifier to a contact
+ * @param $address_book_key
+ * @return bool successful or not
+ */
+ public function delete($id, $address_book_key) {
+ if (!array_key_exists($address_book_key, $this->address_books))
+ return null;
+
+ $address_book = $this->address_books[$address_book_key];
+ if ($address_book->getPermissions() & \OCP\PERMISSION_DELETE)
+ return null;
+
+ return $address_book->delete($id);
+ }
+
+ /**
+ * This function is used to create a new contact if 'id' is not given or not present.
+ * Otherwise the contact will be updated by replacing the entire data set.
+ *
+ * @param array $properties this array if key-value-pairs defines a contact
+ * @param $address_book_key string to identify the address book in which the contact shall be created or updated
+ * @return array representing the contact just created or updated
+ */
+ public function createOrUpdate($properties, $address_book_key) {
+
+ if (!array_key_exists($address_book_key, $this->address_books))
+ return null;
+
+ $address_book = $this->address_books[$address_book_key];
+ if ($address_book->getPermissions() & \OCP\PERMISSION_CREATE)
+ return null;
+
+ return $address_book->createOrUpdate($properties);
+ }
+
+ /**
+ * Check if contacts are available (e.g. contacts app enabled)
+ *
+ * @return bool true if enabled, false if not
+ */
+ public function isEnabled() {
+ return !empty($this->address_books);
+ }
+
+ /**
+ * @param \OCP\IAddressBook $address_book
+ */
+ public function registerAddressBook(\OCP\IAddressBook $address_book) {
+ $this->address_books[$address_book->getKey()] = $address_book;
+ }
+
+ /**
+ * @param \OCP\IAddressBook $address_book
+ */
+ public function unregisterAddressBook(\OCP\IAddressBook $address_book) {
+ unset($this->address_books[$address_book->getKey()]);
+ }
+
+ /**
+ * @return array
+ */
+ public function getAddressBooks() {
+ $result = array();
+ foreach($this->address_books as $address_book) {
+ $result[$address_book->getKey()] = $address_book->getDisplayName();
+ }
+
+ return $result;
+ }
+
+ /**
+ * removes all registered address book instances
+ */
+ public function clear() {
+ $this->address_books = array();
+ }
+
+ /**
+ * @var \OCP\IAddressBook[] which holds all registered address books
+ */
+ private $address_books = array();
+
+ /**
+ * In order to improve lazy loading a closure can be registered which will be called in case
+ * address books are actually requested
+ *
+ * @param string $key
+ * @param \Closure $callable
+ */
+ function register($key, \Closure $callable)
+ {
+ //
+ //TODO: implement me
+ //
+ }
+ }
+}
diff --git a/lib/db.php b/lib/private/db.php
index f090f474243..1e5d12649df 100644
--- a/lib/db.php
+++ b/lib/private/db.php
@@ -75,6 +75,7 @@ class OC_DB {
// do nothing if the connection already has been established
if (!self::$connection) {
$config = new \Doctrine\DBAL\Configuration();
+ $eventManager = new \Doctrine\Common\EventManager();
switch($type) {
case 'sqlite':
case 'sqlite3':
@@ -86,6 +87,7 @@ class OC_DB {
'driver' => 'pdo_sqlite',
);
$connectionParams['adapter'] = '\OC\DB\AdapterSqlite';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
case 'mysql':
$connectionParams = array(
@@ -98,6 +100,7 @@ class OC_DB {
'driver' => 'pdo_mysql',
);
$connectionParams['adapter'] = '\OC\DB\Adapter';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
case 'pgsql':
$connectionParams = array(
@@ -109,6 +112,7 @@ class OC_DB {
'driver' => 'pdo_pgsql',
);
$connectionParams['adapter'] = '\OC\DB\AdapterPgSql';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
case 'oci':
$connectionParams = array(
@@ -123,6 +127,8 @@ class OC_DB {
$connectionParams['port'] = $port;
}
$connectionParams['adapter'] = '\OC\DB\AdapterOCI8';
+ $connectionParams['wrapperClass'] = 'OC\DB\OracleConnection';
+ $eventManager->addEventSubscriber(new \Doctrine\DBAL\Event\Listeners\OracleSessionInit);
break;
case 'mssql':
$connectionParams = array(
@@ -135,14 +141,14 @@ class OC_DB {
'driver' => 'pdo_sqlsrv',
);
$connectionParams['adapter'] = '\OC\DB\AdapterSQLSrv';
+ $connectionParams['wrapperClass'] = 'OC\DB\Connection';
break;
default:
return false;
}
- $connectionParams['wrapperClass'] = 'OC\DB\Connection';
$connectionParams['tablePrefix'] = OC_Config::getValue('dbtableprefix', 'oc_' );
try {
- self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);
+ self::$connection = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config, $eventManager);
if ($type === 'sqlite' || $type === 'sqlite3') {
// Sqlite doesn't handle query caching and schema changes
// TODO: find a better way to handle this
diff --git a/lib/db/adapter.php b/lib/private/db/adapter.php
index 6b31f37dd98..6b31f37dd98 100644
--- a/lib/db/adapter.php
+++ b/lib/private/db/adapter.php
diff --git a/lib/db/adapteroci8.php b/lib/private/db/adapteroci8.php
index bc226e979ec..bc226e979ec 100644
--- a/lib/db/adapteroci8.php
+++ b/lib/private/db/adapteroci8.php
diff --git a/lib/db/adapterpgsql.php b/lib/private/db/adapterpgsql.php
index 990d71c9f29..990d71c9f29 100644
--- a/lib/db/adapterpgsql.php
+++ b/lib/private/db/adapterpgsql.php
diff --git a/lib/db/adaptersqlite.php b/lib/private/db/adaptersqlite.php
index fa6d308ae32..fa6d308ae32 100644
--- a/lib/db/adaptersqlite.php
+++ b/lib/private/db/adaptersqlite.php
diff --git a/lib/db/adaptersqlsrv.php b/lib/private/db/adaptersqlsrv.php
index d0a67af28a7..d0a67af28a7 100644
--- a/lib/db/adaptersqlsrv.php
+++ b/lib/private/db/adaptersqlsrv.php
diff --git a/lib/db/connection.php b/lib/private/db/connection.php
index 2581969dbd0..2d3193a148a 100644
--- a/lib/db/connection.php
+++ b/lib/private/db/connection.php
@@ -12,7 +12,7 @@ use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\Common\EventManager;
-class Connection extends \Doctrine\DBAL\Connection {
+class Connection extends \Doctrine\DBAL\Connection implements \OCP\IDBConnection {
/**
* @var string $tablePrefix
*/
diff --git a/lib/db/mdb2schemamanager.php b/lib/private/db/mdb2schemamanager.php
index 8e76f46c78f..8e76f46c78f 100644
--- a/lib/db/mdb2schemamanager.php
+++ b/lib/private/db/mdb2schemamanager.php
diff --git a/lib/db/mdb2schemareader.php b/lib/private/db/mdb2schemareader.php
index b7128a2f176..b7128a2f176 100644
--- a/lib/db/mdb2schemareader.php
+++ b/lib/private/db/mdb2schemareader.php
diff --git a/lib/db/mdb2schemawriter.php b/lib/private/db/mdb2schemawriter.php
index 21b43cbfe80..21b43cbfe80 100644
--- a/lib/db/mdb2schemawriter.php
+++ b/lib/private/db/mdb2schemawriter.php
diff --git a/lib/private/db/oracleconnection.php b/lib/private/db/oracleconnection.php
new file mode 100644
index 00000000000..e2fc4644f47
--- /dev/null
+++ b/lib/private/db/oracleconnection.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\DB;
+
+class OracleConnection extends Connection {
+ /**
+ * Quote the keys of the array
+ */
+ private function quoteKeys(array $data) {
+ $return = array();
+ foreach($data as $key => $value) {
+ $return[$this->quoteIdentifier($key)] = $value;
+ }
+ return $return;
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ public function insert($tableName, array $data, array $types = array()) {
+ $tableName = $this->quoteIdentifier($tableName);
+ $data = $this->quoteKeys($data);
+ return parent::insert($tableName, $data, $types);
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ public function update($tableName, array $data, array $identifier, array $types = array()) {
+ $tableName = $this->quoteIdentifier($tableName);
+ $data = $this->quoteKeys($data);
+ $identifier = $this->quoteKeys($identifier);
+ return parent::update($tableName, $data, $identifier, $types);
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ public function delete($tableName, array $identifier) {
+ $tableName = $this->quoteIdentifier($tableName);
+ $identifier = $this->quoteKeys($identifier);
+ return parent::delete($tableName, $identifier);
+ }
+}
diff --git a/lib/db/statementwrapper.php b/lib/private/db/statementwrapper.php
index b8da1afc0e5..b8da1afc0e5 100644
--- a/lib/db/statementwrapper.php
+++ b/lib/private/db/statementwrapper.php
diff --git a/lib/defaults.php b/lib/private/defaults.php
index 10813a3e8d8..10813a3e8d8 100644
--- a/lib/defaults.php
+++ b/lib/private/defaults.php
diff --git a/lib/eventsource.php b/lib/private/eventsource.php
index a83084d9251..a83084d9251 100644
--- a/lib/eventsource.php
+++ b/lib/private/eventsource.php
diff --git a/lib/filechunking.php b/lib/private/filechunking.php
index e6d69273a44..313a6ee87d2 100644
--- a/lib/filechunking.php
+++ b/lib/private/filechunking.php
@@ -29,7 +29,7 @@ class OC_FileChunking {
protected function getCache() {
if (!isset($this->cache)) {
- $this->cache = new OC_Cache_File();
+ $this->cache = new \OC\Cache\File();
}
return $this->cache;
}
diff --git a/lib/fileproxy.php b/lib/private/fileproxy.php
index 52ec79b4bdb..52ec79b4bdb 100644
--- a/lib/fileproxy.php
+++ b/lib/private/fileproxy.php
diff --git a/lib/fileproxy/fileoperations.php b/lib/private/fileproxy/fileoperations.php
index b2ff2e7e5e9..b2ff2e7e5e9 100644
--- a/lib/fileproxy/fileoperations.php
+++ b/lib/private/fileproxy/fileoperations.php
diff --git a/lib/files.php b/lib/private/files.php
index c705d2adb1a..c705d2adb1a 100644
--- a/lib/files.php
+++ b/lib/private/files.php
diff --git a/lib/files/cache/backgroundwatcher.php b/lib/private/files/cache/backgroundwatcher.php
index 923804f48d0..923804f48d0 100644
--- a/lib/files/cache/backgroundwatcher.php
+++ b/lib/private/files/cache/backgroundwatcher.php
diff --git a/lib/files/cache/cache.php b/lib/private/files/cache/cache.php
index 39e36684b7b..e69733727af 100644
--- a/lib/files/cache/cache.php
+++ b/lib/private/files/cache/cache.php
@@ -201,7 +201,6 @@ class Cache {
$data['path'] = $file;
$data['parent'] = $this->getParentId($file);
$data['name'] = \OC_Util::basename($file);
- $data['encrypted'] = isset($data['encrypted']) ? ((int)$data['encrypted']) : 0;
list($queryParts, $params) = $this->buildParts($data);
$queryParts[] = '`storage`';
@@ -265,6 +264,9 @@ class Cache {
$params[] = $value;
$queryParts[] = '`mtime`';
}
+ } elseif ($name === 'encrypted') {
+ // Boolean to integer conversion
+ $value = $value ? 1 : 0;
}
$params[] = $value;
$queryParts[] = '`' . $name . '`';
diff --git a/lib/files/cache/legacy.php b/lib/private/files/cache/legacy.php
index 8eed1f67a5d..8eed1f67a5d 100644
--- a/lib/files/cache/legacy.php
+++ b/lib/private/files/cache/legacy.php
diff --git a/lib/files/cache/permissions.php b/lib/private/files/cache/permissions.php
index 2e2bdb20b78..2e2bdb20b78 100644
--- a/lib/files/cache/permissions.php
+++ b/lib/private/files/cache/permissions.php
diff --git a/lib/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index 87fa7c1365a..96f84609cf2 100644
--- a/lib/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -36,6 +36,11 @@ class Scanner extends BasicEmitter {
*/
private $cache;
+ /**
+ * @var \OC\Files\Cache\Permissions $permissionsCache
+ */
+ private $permissionsCache;
+
const SCAN_RECURSIVE = true;
const SCAN_SHALLOW = false;
@@ -46,6 +51,7 @@ class Scanner extends BasicEmitter {
$this->storage = $storage;
$this->storageId = $this->storage->getId();
$this->cache = $storage->getCache();
+ $this->permissionsCache = $storage->getPermissionsCache();
}
/**
@@ -96,22 +102,48 @@ class Scanner extends BasicEmitter {
}
}
$newData = $data;
- if ($reuseExisting and $cacheData = $this->cache->get($file)) {
- // only reuse data if the file hasn't explicitly changed
- if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) {
- if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
- $data['size'] = $cacheData['size'];
+ $cacheData = $this->cache->get($file);
+ if ($cacheData) {
+ $this->permissionsCache->remove($cacheData['fileid']);
+ if ($reuseExisting) {
+ // prevent empty etag
+ $etag = $cacheData['etag'];
+ $propagateETagChange = false;
+ if (empty($etag)) {
+ $etag = $data['etag'];
+ $propagateETagChange = true;
}
- if ($reuseExisting & self::REUSE_ETAG) {
- $data['etag'] = $cacheData['etag'];
+ // only reuse data if the file hasn't explicitly changed
+ if (isset($data['mtime']) && isset($cacheData['mtime']) && $data['mtime'] === $cacheData['mtime']) {
+ if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
+ $data['size'] = $cacheData['size'];
+ }
+ if ($reuseExisting & self::REUSE_ETAG) {
+ $data['etag'] = $etag;
+ if ($propagateETagChange) {
+ $parent = $file;
+ while ($parent !== '') {
+ $parent = dirname($parent);
+ if ($parent === '.') {
+ $parent = '';
+ }
+ $parentCacheData = $this->cache->get($parent);
+ $this->cache->update($parentCacheData['fileid'], array(
+ 'etag' => $this->storage->getETag($parent),
+ ));
+ }
+ }
+ }
}
+ // Only update metadata that has changed
+ $newData = array_diff($data, $cacheData);
}
- // Only update metadata that has changed
- $newData = array_diff($data, $cacheData);
}
if (!empty($newData)) {
$this->cache->put($file, $newData);
}
+ } else {
+ $this->cache->remove($file);
}
return $data;
}
@@ -159,20 +191,22 @@ class Scanner extends BasicEmitter {
$newChildren = array();
if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) {
\OC_DB::beginTransaction();
- while (($file = readdir($dh)) !== false) {
- $child = ($path) ? $path . '/' . $file : $file;
- if (!Filesystem::isIgnoredDir($file)) {
- $newChildren[] = $file;
- $data = $this->scanFile($child, $reuse, true);
- if ($data) {
- if ($data['size'] === -1) {
- if ($recursive === self::SCAN_RECURSIVE) {
- $childQueue[] = $child;
- } else {
- $size = -1;
+ if (is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ $child = ($path) ? $path . '/' . $file : $file;
+ if (!Filesystem::isIgnoredDir($file)) {
+ $newChildren[] = $file;
+ $data = $this->scanFile($child, $reuse, true);
+ if ($data) {
+ if ($data['size'] === -1) {
+ if ($recursive === self::SCAN_RECURSIVE) {
+ $childQueue[] = $child;
+ } else {
+ $size = -1;
+ }
+ } else if ($size !== -1) {
+ $size += $data['size'];
}
- } else if ($size !== -1) {
- $size += $data['size'];
}
}
}
diff --git a/lib/files/cache/storage.php b/lib/private/files/cache/storage.php
index 8a9e47ca36d..8a9e47ca36d 100644
--- a/lib/files/cache/storage.php
+++ b/lib/private/files/cache/storage.php
diff --git a/lib/files/cache/updater.php b/lib/private/files/cache/updater.php
index 1f30173a8f8..1f30173a8f8 100644
--- a/lib/files/cache/updater.php
+++ b/lib/private/files/cache/updater.php
diff --git a/lib/files/cache/upgrade.php b/lib/private/files/cache/upgrade.php
index cfb9a117311..cfb9a117311 100644
--- a/lib/files/cache/upgrade.php
+++ b/lib/private/files/cache/upgrade.php
diff --git a/lib/files/cache/watcher.php b/lib/private/files/cache/watcher.php
index 8bfd4602f3a..8bfd4602f3a 100644
--- a/lib/files/cache/watcher.php
+++ b/lib/private/files/cache/watcher.php
diff --git a/lib/files/filesystem.php b/lib/private/files/filesystem.php
index 10ec5c41d11..10ec5c41d11 100644
--- a/lib/files/filesystem.php
+++ b/lib/private/files/filesystem.php
diff --git a/lib/files/mapper.php b/lib/private/files/mapper.php
index 47abd4e52fe..47abd4e52fe 100644
--- a/lib/files/mapper.php
+++ b/lib/private/files/mapper.php
diff --git a/lib/files/mount/manager.php b/lib/private/files/mount/manager.php
index 4c432dcf724..4c432dcf724 100644
--- a/lib/files/mount/manager.php
+++ b/lib/private/files/mount/manager.php
diff --git a/lib/files/mount/mount.php b/lib/private/files/mount/mount.php
index 0ce2f5975c7..0ce2f5975c7 100644
--- a/lib/files/mount/mount.php
+++ b/lib/private/files/mount/mount.php
diff --git a/lib/private/files/node/file.php b/lib/private/files/node/file.php
new file mode 100644
index 00000000000..75d5e0166b6
--- /dev/null
+++ b/lib/private/files/node/file.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Node;
+
+use OCP\Files\NotPermittedException;
+
+class File extends Node implements \OCP\Files\File {
+ /**
+ * @return string
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function getContent() {
+ if ($this->checkPermissions(\OCP\PERMISSION_READ)) {
+ /**
+ * @var \OC\Files\Storage\Storage $storage;
+ */
+ return $this->view->file_get_contents($this->path);
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $data
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function putContent($data) {
+ if ($this->checkPermissions(\OCP\PERMISSION_UPDATE)) {
+ $this->sendHooks(array('preWrite'));
+ $this->view->file_put_contents($this->path, $data);
+ $this->sendHooks(array('postWrite'));
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getMimeType() {
+ return $this->view->getMimeType($this->path);
+ }
+
+ /**
+ * @param string $mode
+ * @return resource
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function fopen($mode) {
+ $preHooks = array();
+ $postHooks = array();
+ $requiredPermissions = \OCP\PERMISSION_READ;
+ switch ($mode) {
+ case 'r+':
+ case 'rb+':
+ case 'w+':
+ case 'wb+':
+ case 'x+':
+ case 'xb+':
+ case 'a+':
+ case 'ab+':
+ case 'w':
+ case 'wb':
+ case 'x':
+ case 'xb':
+ case 'a':
+ case 'ab':
+ $preHooks[] = 'preWrite';
+ $postHooks[] = 'postWrite';
+ $requiredPermissions |= \OCP\PERMISSION_UPDATE;
+ break;
+ }
+
+ if ($this->checkPermissions($requiredPermissions)) {
+ $this->sendHooks($preHooks);
+ $result = $this->view->fopen($this->path, $mode);
+ $this->sendHooks($postHooks);
+ return $result;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ public function delete() {
+ if ($this->checkPermissions(\OCP\PERMISSION_DELETE)) {
+ $this->sendHooks(array('preDelete'));
+ $this->view->unlink($this->path);
+ $nonExisting = new NonExistingFile($this->root, $this->view, $this->path);
+ $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
+ $this->exists = false;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function copy($targetPath) {
+ $targetPath = $this->normalizePath($targetPath);
+ $parent = $this->root->get(dirname($targetPath));
+ if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
+ $nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
+ $this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
+ $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
+ $this->view->copy($this->path, $targetPath);
+ $targetNode = $this->root->get($targetPath);
+ $this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
+ $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
+ return $targetNode;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function move($targetPath) {
+ $targetPath = $this->normalizePath($targetPath);
+ $parent = $this->root->get(dirname($targetPath));
+ if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
+ $nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
+ $this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
+ $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
+ $this->view->rename($this->path, $targetPath);
+ $targetNode = $this->root->get($targetPath);
+ $this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
+ $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
+ $this->path = $targetPath;
+ return $targetNode;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $type
+ * @param bool $raw
+ * @return string
+ */
+ public function hash($type, $raw = false) {
+ return $this->view->hash($type, $this->path, $raw);
+ }
+}
diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php
new file mode 100644
index 00000000000..923f53821b2
--- /dev/null
+++ b/lib/private/files/node/folder.php
@@ -0,0 +1,382 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Node;
+
+use OC\Files\Cache\Cache;
+use OC\Files\Cache\Scanner;
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+
+class Folder extends Node implements \OCP\Files\Folder {
+ /**
+ * @param string $path path relative to the folder
+ * @return string
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function getFullPath($path) {
+ if (!$this->isValidPath($path)) {
+ throw new NotPermittedException();
+ }
+ return $this->path . $this->normalizePath($path);
+ }
+
+ /**
+ * @param string $path
+ * @throws \OCP\Files\NotFoundException
+ * @return string
+ */
+ public function getRelativePath($path) {
+ if ($this->path === '' or $this->path === '/') {
+ return $this->normalizePath($path);
+ }
+ if (strpos($path, $this->path) !== 0) {
+ throw new NotFoundException();
+ } else {
+ $path = substr($path, strlen($this->path));
+ if (strlen($path) === 0) {
+ return '/';
+ } else {
+ return $this->normalizePath($path);
+ }
+ }
+ }
+
+ /**
+ * check if a node is a (grand-)child of the folder
+ *
+ * @param \OC\Files\Node\Node $node
+ * @return bool
+ */
+ public function isSubNode($node) {
+ return strpos($node->getPath(), $this->path . '/') === 0;
+ }
+
+ /**
+ * get the content of this directory
+ *
+ * @throws \OCP\Files\NotFoundException
+ * @return Node[]
+ */
+ public function getDirectoryListing() {
+ $result = array();
+
+ /**
+ * @var \OC\Files\Storage\Storage $storage
+ */
+ list($storage, $internalPath) = $this->view->resolvePath($this->path);
+ if ($storage) {
+ $cache = $storage->getCache($internalPath);
+ $permissionsCache = $storage->getPermissionsCache($internalPath);
+
+ //trigger cache update check
+ $this->view->getFileInfo($this->path);
+
+ $files = $cache->getFolderContents($internalPath);
+ $permissions = $permissionsCache->getDirectoryPermissions($this->getId(), $this->root->getUser()->getUID());
+ } else {
+ $files = array();
+ }
+
+ //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
+ $mounts = $this->root->getMountsIn($this->path);
+ $dirLength = strlen($this->path);
+ foreach ($mounts as $mount) {
+ $subStorage = $mount->getStorage();
+ if ($subStorage) {
+ $subCache = $subStorage->getCache('');
+
+ if ($subCache->getStatus('') === Cache::NOT_FOUND) {
+ $subScanner = $subStorage->getScanner('');
+ $subScanner->scanFile('');
+ }
+
+ $rootEntry = $subCache->get('');
+ if ($rootEntry) {
+ $relativePath = trim(substr($mount->getMountPoint(), $dirLength), '/');
+ if ($pos = strpos($relativePath, '/')) {
+ //mountpoint inside subfolder add size to the correct folder
+ $entryName = substr($relativePath, 0, $pos);
+ foreach ($files as &$entry) {
+ if ($entry['name'] === $entryName) {
+ if ($rootEntry['size'] >= 0) {
+ $entry['size'] += $rootEntry['size'];
+ } else {
+ $entry['size'] = -1;
+ }
+ }
+ }
+ } else { //mountpoint in this folder, add an entry for it
+ $rootEntry['name'] = $relativePath;
+ $rootEntry['storageObject'] = $subStorage;
+
+ //remove any existing entry with the same name
+ foreach ($files as $i => $file) {
+ if ($file['name'] === $rootEntry['name']) {
+ $files[$i] = null;
+ break;
+ }
+ }
+ $files[] = $rootEntry;
+ }
+ }
+ }
+ }
+
+ foreach ($files as $file) {
+ if ($file) {
+ if (isset($permissions[$file['fileid']])) {
+ $file['permissions'] = $permissions[$file['fileid']];
+ }
+ $node = $this->createNode($this->path . '/' . $file['name'], $file);
+ $result[] = $node;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param string $path
+ * @param array $info
+ * @return File|Folder
+ */
+ protected function createNode($path, $info = array()) {
+ if (!isset($info['mimetype'])) {
+ $isDir = $this->view->is_dir($path);
+ } else {
+ $isDir = $info['mimetype'] === 'httpd/unix-directory';
+ }
+ if ($isDir) {
+ return new Folder($this->root, $this->view, $path);
+ } else {
+ return new File($this->root, $this->view, $path);
+ }
+ }
+
+ /**
+ * Get the node at $path
+ *
+ * @param string $path
+ * @return \OC\Files\Node\Node
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function get($path) {
+ return $this->root->get($this->getFullPath($path));
+ }
+
+ /**
+ * @param string $path
+ * @return bool
+ */
+ public function nodeExists($path) {
+ try {
+ $this->get($path);
+ return true;
+ } catch (NotFoundException $e) {
+ return false;
+ }
+ }
+
+ /**
+ * @param string $path
+ * @return \OC\Files\Node\Folder
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function newFolder($path) {
+ if ($this->checkPermissions(\OCP\PERMISSION_CREATE)) {
+ $fullPath = $this->getFullPath($path);
+ $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
+ $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
+ $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
+ $this->view->mkdir($fullPath);
+ $node = new Folder($this->root, $this->view, $fullPath);
+ $this->root->emit('\OC\Files', 'postWrite', array($node));
+ $this->root->emit('\OC\Files', 'postCreate', array($node));
+ return $node;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $path
+ * @return \OC\Files\Node\File
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function newFile($path) {
+ if ($this->checkPermissions(\OCP\PERMISSION_CREATE)) {
+ $fullPath = $this->getFullPath($path);
+ $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
+ $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
+ $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
+ $this->view->touch($fullPath);
+ $node = new File($this->root, $this->view, $fullPath);
+ $this->root->emit('\OC\Files', 'postWrite', array($node));
+ $this->root->emit('\OC\Files', 'postCreate', array($node));
+ return $node;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * search for files with the name matching $query
+ *
+ * @param string $query
+ * @return \OC\Files\Node\Node[]
+ */
+ public function search($query) {
+ return $this->searchCommon('%' . $query . '%', 'search');
+ }
+
+ /**
+ * search for files by mimetype
+ *
+ * @param string $mimetype
+ * @return Node[]
+ */
+ public function searchByMime($mimetype) {
+ return $this->searchCommon($mimetype, 'searchByMime');
+ }
+
+ /**
+ * @param string $query
+ * @param string $method
+ * @return \OC\Files\Node\Node[]
+ */
+ private function searchCommon($query, $method) {
+ $files = array();
+ $rootLength = strlen($this->path);
+ /**
+ * @var \OC\Files\Storage\Storage $storage
+ */
+ list($storage, $internalPath) = $this->view->resolvePath($this->path);
+ $internalRootLength = strlen($internalPath);
+
+ $cache = $storage->getCache('');
+
+ $results = $cache->$method($query);
+ foreach ($results as $result) {
+ if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
+ $result['internalPath'] = $result['path'];
+ $result['path'] = substr($result['path'], $internalRootLength);
+ $result['storage'] = $storage;
+ $files[] = $result;
+ }
+ }
+
+ $mounts = $this->root->getMountsIn($this->path);
+ foreach ($mounts as $mount) {
+ $storage = $mount->getStorage();
+ if ($storage) {
+ $cache = $storage->getCache('');
+
+ $relativeMountPoint = substr($mount->getMountPoint(), $rootLength);
+ $results = $cache->$method($query);
+ foreach ($results as $result) {
+ $result['internalPath'] = $result['path'];
+ $result['path'] = $relativeMountPoint . $result['path'];
+ $result['storage'] = $storage;
+ $files[] = $result;
+ }
+ }
+ }
+
+ $result = array();
+ foreach ($files as $file) {
+ $result[] = $this->createNode($this->normalizePath($this->path . '/' . $file['path']), $file);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param $id
+ * @return \OC\Files\Node\Node[]
+ */
+ public function getById($id) {
+ $nodes = $this->root->getById($id);
+ $result = array();
+ foreach ($nodes as $node) {
+ $pathPart = substr($node->getPath(), 0, strlen($this->getPath()) + 1);
+ if ($this->path === '/' or $pathPart === $this->getPath() . '/') {
+ $result[] = $node;
+ }
+ }
+ return $result;
+ }
+
+ public function getFreeSpace() {
+ return $this->view->free_space($this->path);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCreatable() {
+ return $this->checkPermissions(\OCP\PERMISSION_CREATE);
+ }
+
+ public function delete() {
+ if ($this->checkPermissions(\OCP\PERMISSION_DELETE)) {
+ $this->sendHooks(array('preDelete'));
+ $this->view->rmdir($this->path);
+ $nonExisting = new NonExistingFolder($this->root, $this->view, $this->path);
+ $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
+ $this->exists = false;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function copy($targetPath) {
+ $targetPath = $this->normalizePath($targetPath);
+ $parent = $this->root->get(dirname($targetPath));
+ if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
+ $nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
+ $this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
+ $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
+ $this->view->copy($this->path, $targetPath);
+ $targetNode = $this->root->get($targetPath);
+ $this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
+ $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
+ return $targetNode;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function move($targetPath) {
+ $targetPath = $this->normalizePath($targetPath);
+ $parent = $this->root->get(dirname($targetPath));
+ if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
+ $nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
+ $this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
+ $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
+ $this->view->rename($this->path, $targetPath);
+ $targetNode = $this->root->get($targetPath);
+ $this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
+ $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
+ $this->path = $targetPath;
+ return $targetNode;
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+}
diff --git a/lib/private/files/node/node.php b/lib/private/files/node/node.php
new file mode 100644
index 00000000000..063e2424a64
--- /dev/null
+++ b/lib/private/files/node/node.php
@@ -0,0 +1,245 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Node;
+
+use OC\Files\Cache\Cache;
+use OC\Files\Cache\Scanner;
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+
+class Node implements \OCP\Files\Node {
+ /**
+ * @var \OC\Files\View $view
+ */
+ protected $view;
+
+ /**
+ * @var \OC\Files\Node\Root $root
+ */
+ protected $root;
+
+ /**
+ * @var string $path
+ */
+ protected $path;
+
+ /**
+ * @param \OC\Files\View $view
+ * @param \OC\Files\Node\Root Root $root
+ * @param string $path
+ */
+ public function __construct($root, $view, $path) {
+ $this->view = $view;
+ $this->root = $root;
+ $this->path = $path;
+ }
+
+ /**
+ * @param string[] $hooks
+ */
+ protected function sendHooks($hooks) {
+ foreach ($hooks as $hook) {
+ $this->root->emit('\OC\Files', $hook, array($this));
+ }
+ }
+
+ /**
+ * @param int $permissions
+ * @return bool
+ */
+ protected function checkPermissions($permissions) {
+ return ($this->getPermissions() & $permissions) === $permissions;
+ }
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function move($targetPath) {
+ return;
+ }
+
+ public function delete() {
+ return;
+ }
+
+ /**
+ * @param string $targetPath
+ * @return \OC\Files\Node\Node
+ */
+ public function copy($targetPath) {
+ return;
+ }
+
+ /**
+ * @param int $mtime
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function touch($mtime = null) {
+ if ($this->checkPermissions(\OCP\PERMISSION_UPDATE)) {
+ $this->sendHooks(array('preTouch'));
+ $this->view->touch($this->path, $mtime);
+ $this->sendHooks(array('postTouch'));
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * @return \OC\Files\Storage\Storage
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function getStorage() {
+ list($storage,) = $this->view->resolvePath($this->path);
+ return $storage;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPath() {
+ return $this->path;
+ }
+
+ /**
+ * @return string
+ */
+ public function getInternalPath() {
+ list(, $internalPath) = $this->view->resolvePath($this->path);
+ return $internalPath;
+ }
+
+ /**
+ * @return int
+ */
+ public function getId() {
+ $info = $this->view->getFileInfo($this->path);
+ return $info['fileid'];
+ }
+
+ /**
+ * @return array
+ */
+ public function stat() {
+ return $this->view->stat($this->path);
+ }
+
+ /**
+ * @return int
+ */
+ public function getMTime() {
+ return $this->view->filemtime($this->path);
+ }
+
+ /**
+ * @return int
+ */
+ public function getSize() {
+ return $this->view->filesize($this->path);
+ }
+
+ /**
+ * @return string
+ */
+ public function getEtag() {
+ $info = $this->view->getFileInfo($this->path);
+ return $info['etag'];
+ }
+
+ /**
+ * @return int
+ */
+ public function getPermissions() {
+ $info = $this->view->getFileInfo($this->path);
+ return $info['permissions'];
+ }
+
+ /**
+ * @return bool
+ */
+ public function isReadable() {
+ return $this->checkPermissions(\OCP\PERMISSION_READ);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isUpdateable() {
+ return $this->checkPermissions(\OCP\PERMISSION_UPDATE);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isDeletable() {
+ return $this->checkPermissions(\OCP\PERMISSION_DELETE);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isShareable() {
+ return $this->checkPermissions(\OCP\PERMISSION_SHARE);
+ }
+
+ /**
+ * @return Node
+ */
+ public function getParent() {
+ return $this->root->get(dirname($this->path));
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return basename($this->path);
+ }
+
+ /**
+ * @param string $path
+ * @return string
+ */
+ protected function normalizePath($path) {
+ if ($path === '' or $path === '/') {
+ return '/';
+ }
+ //no windows style slashes
+ $path = str_replace('\\', '/', $path);
+ //add leading slash
+ if ($path[0] !== '/') {
+ $path = '/' . $path;
+ }
+ //remove duplicate slashes
+ while (strpos($path, '//') !== false) {
+ $path = str_replace('//', '/', $path);
+ }
+ //remove trailing slash
+ $path = rtrim($path, '/');
+
+ return $path;
+ }
+
+ /**
+ * check if the requested path is valid
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isValidPath($path) {
+ if (!$path || $path[0] !== '/') {
+ $path = '/' . $path;
+ }
+ if (strstr($path, '/../') || strrchr($path, '/') === '/..') {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/lib/private/files/node/nonexistingfile.php b/lib/private/files/node/nonexistingfile.php
new file mode 100644
index 00000000000..d45076f7fee
--- /dev/null
+++ b/lib/private/files/node/nonexistingfile.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Node;
+
+use OCP\Files\NotFoundException;
+
+class NonExistingFile extends File {
+ /**
+ * @param string $newPath
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function rename($newPath) {
+ throw new NotFoundException();
+ }
+
+ public function delete() {
+ throw new NotFoundException();
+ }
+
+ public function copy($newPath) {
+ throw new NotFoundException();
+ }
+
+ public function touch($mtime = null) {
+ throw new NotFoundException();
+ }
+
+ public function getId() {
+ throw new NotFoundException();
+ }
+
+ public function stat() {
+ throw new NotFoundException();
+ }
+
+ public function getMTime() {
+ throw new NotFoundException();
+ }
+
+ public function getSize() {
+ throw new NotFoundException();
+ }
+
+ public function getEtag() {
+ throw new NotFoundException();
+ }
+
+ public function getPermissions() {
+ throw new NotFoundException();
+ }
+
+ public function isReadable() {
+ throw new NotFoundException();
+ }
+
+ public function isUpdateable() {
+ throw new NotFoundException();
+ }
+
+ public function isDeletable() {
+ throw new NotFoundException();
+ }
+
+ public function isShareable() {
+ throw new NotFoundException();
+ }
+
+ public function getContent() {
+ throw new NotFoundException();
+ }
+
+ public function putContent($data) {
+ throw new NotFoundException();
+ }
+
+ public function getMimeType() {
+ throw new NotFoundException();
+ }
+
+ public function fopen($mode) {
+ throw new NotFoundException();
+ }
+}
diff --git a/lib/private/files/node/nonexistingfolder.php b/lib/private/files/node/nonexistingfolder.php
new file mode 100644
index 00000000000..0346cbf1e21
--- /dev/null
+++ b/lib/private/files/node/nonexistingfolder.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Node;
+
+use OCP\Files\NotFoundException;
+
+class NonExistingFolder extends Folder {
+ /**
+ * @param string $newPath
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function rename($newPath) {
+ throw new NotFoundException();
+ }
+
+ public function delete() {
+ throw new NotFoundException();
+ }
+
+ public function copy($newPath) {
+ throw new NotFoundException();
+ }
+
+ public function touch($mtime = null) {
+ throw new NotFoundException();
+ }
+
+ public function getId() {
+ throw new NotFoundException();
+ }
+
+ public function stat() {
+ throw new NotFoundException();
+ }
+
+ public function getMTime() {
+ throw new NotFoundException();
+ }
+
+ public function getSize() {
+ throw new NotFoundException();
+ }
+
+ public function getEtag() {
+ throw new NotFoundException();
+ }
+
+ public function getPermissions() {
+ throw new NotFoundException();
+ }
+
+ public function isReadable() {
+ throw new NotFoundException();
+ }
+
+ public function isUpdateable() {
+ throw new NotFoundException();
+ }
+
+ public function isDeletable() {
+ throw new NotFoundException();
+ }
+
+ public function isShareable() {
+ throw new NotFoundException();
+ }
+
+ public function get($path) {
+ throw new NotFoundException();
+ }
+
+ public function getDirectoryListing() {
+ throw new NotFoundException();
+ }
+
+ public function nodeExists($path) {
+ return false;
+ }
+
+ public function newFolder($path) {
+ throw new NotFoundException();
+ }
+
+ public function newFile($path) {
+ throw new NotFoundException();
+ }
+
+ public function search($pattern) {
+ throw new NotFoundException();
+ }
+
+ public function searchByMime($mime) {
+ throw new NotFoundException();
+ }
+
+ public function getById($id) {
+ throw new NotFoundException();
+ }
+
+ public function getFreeSpace() {
+ throw new NotFoundException();
+ }
+
+ public function isCreatable() {
+ throw new NotFoundException();
+ }
+}
diff --git a/lib/private/files/node/root.php b/lib/private/files/node/root.php
new file mode 100644
index 00000000000..e3d58476e9c
--- /dev/null
+++ b/lib/private/files/node/root.php
@@ -0,0 +1,337 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Node;
+
+use OC\Files\Cache\Cache;
+use OC\Files\Cache\Scanner;
+use OC\Files\Mount\Manager;
+use OC\Files\Mount\Mount;
+use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+use OC\Hooks\Emitter;
+use OC\Hooks\PublicEmitter;
+
+/**
+ * Class Root
+ *
+ * Hooks available in scope \OC\Files
+ * - preWrite(\OCP\Files\Node $node)
+ * - postWrite(\OCP\Files\Node $node)
+ * - preCreate(\OCP\Files\Node $node)
+ * - postCreate(\OCP\Files\Node $node)
+ * - preDelete(\OCP\Files\Node $node)
+ * - postDelete(\OCP\Files\Node $node)
+ * - preTouch(\OC\FilesP\Node $node, int $mtime)
+ * - postTouch(\OCP\Files\Node $node)
+ * - preCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
+ * - postCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
+ * - preRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
+ * - postRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
+ *
+ * @package OC\Files\Node
+ */
+class Root extends Folder implements Emitter {
+
+ /**
+ * @var \OC\Files\Mount\Manager $mountManager
+ */
+ private $mountManager;
+
+ /**
+ * @var \OC\Hooks\PublicEmitter
+ */
+ private $emitter;
+
+ /**
+ * @var \OC\User\User $user
+ */
+ private $user;
+
+ /**
+ * @param \OC\Files\Mount\Manager $manager
+ * @param \OC\Files\View $view
+ * @param \OC\User\User $user
+ */
+ public function __construct($manager, $view, $user) {
+ parent::__construct($this, $view, '');
+ $this->mountManager = $manager;
+ $this->user = $user;
+ $this->emitter = new PublicEmitter();
+ }
+
+ /**
+ * Get the user for which the filesystem is setup
+ *
+ * @return \OC\User\User
+ */
+ public function getUser() {
+ return $this->user;
+ }
+
+ /**
+ * @param string $scope
+ * @param string $method
+ * @param callable $callback
+ */
+ public function listen($scope, $method, $callback) {
+ $this->emitter->listen($scope, $method, $callback);
+ }
+
+ /**
+ * @param string $scope optional
+ * @param string $method optional
+ * @param callable $callback optional
+ */
+ public function removeListener($scope = null, $method = null, $callback = null) {
+ $this->emitter->removeListener($scope, $method, $callback);
+ }
+
+ /**
+ * @param string $scope
+ * @param string $method
+ * @param array $arguments
+ */
+ public function emit($scope, $method, $arguments = array()) {
+ $this->emitter->emit($scope, $method, $arguments);
+ }
+
+ /**
+ * @param \OC\Files\Storage\Storage $storage
+ * @param string $mountPoint
+ * @param array $arguments
+ */
+ public function mount($storage, $mountPoint, $arguments = array()) {
+ $mount = new Mount($storage, $mountPoint, $arguments);
+ $this->mountManager->addMount($mount);
+ }
+
+ /**
+ * @param string $mountPoint
+ * @return \OC\Files\Mount\Mount
+ */
+ public function getMount($mountPoint) {
+ return $this->mountManager->find($mountPoint);
+ }
+
+ /**
+ * @param string $mountPoint
+ * @return \OC\Files\Mount\Mount[]
+ */
+ public function getMountsIn($mountPoint) {
+ return $this->mountManager->findIn($mountPoint);
+ }
+
+ /**
+ * @param string $storageId
+ * @return \OC\Files\Mount\Mount[]
+ */
+ public function getMountByStorageId($storageId) {
+ return $this->mountManager->findByStorageId($storageId);
+ }
+
+ /**
+ * @param int $numericId
+ * @return Mount[]
+ */
+ public function getMountByNumericStorageId($numericId) {
+ return $this->mountManager->findByNumericId($numericId);
+ }
+
+ /**
+ * @param \OC\Files\Mount\Mount $mount
+ */
+ public function unMount($mount) {
+ $this->mountManager->remove($mount);
+ }
+
+ /**
+ * @param string $path
+ * @throws \OCP\Files\NotFoundException
+ * @throws \OCP\Files\NotPermittedException
+ * @return Node
+ */
+ public function get($path) {
+ $path = $this->normalizePath($path);
+ if ($this->isValidPath($path)) {
+ $fullPath = $this->getFullPath($path);
+ if ($this->view->file_exists($fullPath)) {
+ return $this->createNode($fullPath);
+ } else {
+ throw new NotFoundException();
+ }
+ } else {
+ throw new NotPermittedException();
+ }
+ }
+
+ /**
+ * search file by id
+ *
+ * An array is returned because in the case where a single storage is mounted in different places the same file
+ * can exist in different places
+ *
+ * @param int $id
+ * @throws \OCP\Files\NotFoundException
+ * @return Node[]
+ */
+ public function getById($id) {
+ $result = Cache::getById($id);
+ if (is_null($result)) {
+ throw new NotFoundException();
+ } else {
+ list($storageId, $internalPath) = $result;
+ $nodes = array();
+ $mounts = $this->mountManager->findByStorageId($storageId);
+ foreach ($mounts as $mount) {
+ $nodes[] = $this->get($mount->getMountPoint() . $internalPath);
+ }
+ return $nodes;
+ }
+
+ }
+
+ //most operations cant be done on the root
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function rename($targetPath) {
+ throw new NotPermittedException();
+ }
+
+ public function delete() {
+ throw new NotPermittedException();
+ }
+
+ /**
+ * @param string $targetPath
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OC\Files\Node\Node
+ */
+ public function copy($targetPath) {
+ throw new NotPermittedException();
+ }
+
+ /**
+ * @param int $mtime
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function touch($mtime = null) {
+ throw new NotPermittedException();
+ }
+
+ /**
+ * @return \OC\Files\Storage\Storage
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function getStorage() {
+ throw new NotFoundException();
+ }
+
+ /**
+ * @return string
+ */
+ public function getPath() {
+ return '/';
+ }
+
+ /**
+ * @return string
+ */
+ public function getInternalPath() {
+ return '';
+ }
+
+ /**
+ * @return int
+ */
+ public function getId() {
+ return null;
+ }
+
+ /**
+ * @return array
+ */
+ public function stat() {
+ return null;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMTime() {
+ return null;
+ }
+
+ /**
+ * @return int
+ */
+ public function getSize() {
+ return null;
+ }
+
+ /**
+ * @return string
+ */
+ public function getEtag() {
+ return null;
+ }
+
+ /**
+ * @return int
+ */
+ public function getPermissions() {
+ return \OCP\PERMISSION_CREATE;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isReadable() {
+ return false;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isUpdateable() {
+ return false;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isDeletable() {
+ return false;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isShareable() {
+ return false;
+ }
+
+ /**
+ * @return Node
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function getParent() {
+ throw new NotFoundException();
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return '';
+ }
+}
diff --git a/lib/files/storage/common.php b/lib/private/files/storage/common.php
index 01560f34fde..a5b79f0e967 100644
--- a/lib/files/storage/common.php
+++ b/lib/private/files/storage/common.php
@@ -142,13 +142,15 @@ abstract class Common implements \OC\Files\Storage\Storage {
return false;
} else {
$directoryHandle = $this->opendir($directory);
- while (($contents = readdir($directoryHandle)) !== false) {
- if (!\OC\Files\Filesystem::isIgnoredDir($contents)) {
- $path = $directory . '/' . $contents;
- if ($this->is_dir($path)) {
- $this->deleteAll($path);
- } else {
- $this->unlink($path);
+ if(is_resource($directoryHandle)) {
+ while (($contents = readdir($directoryHandle)) !== false) {
+ if (!\OC\Files\Filesystem::isIgnoredDir($contents)) {
+ $path = $directory . '/' . $contents;
+ if ($this->is_dir($path)) {
+ $this->deleteAll($path);
+ } else {
+ $this->unlink($path);
+ }
}
}
}
@@ -224,7 +226,8 @@ abstract class Common implements \OC\Files\Storage\Storage {
}
private function addLocalFolder($path, $target) {
- if ($dh = $this->opendir($path)) {
+ $dh = $this->opendir($path);
+ if(is_resource($dh)) {
while (($file = readdir($dh)) !== false) {
if ($file !== '.' and $file !== '..') {
if ($this->is_dir($path . '/' . $file)) {
@@ -242,7 +245,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
protected function searchInDir($query, $dir = '') {
$files = array();
$dh = $this->opendir($dir);
- if ($dh) {
+ if (is_resource($dh)) {
while (($item = readdir($dh)) !== false) {
if ($item == '.' || $item == '..') continue;
if (strstr(strtolower($item), strtolower($query)) !== false) {
diff --git a/lib/files/storage/commontest.php b/lib/private/files/storage/commontest.php
index c3f1eb31955..c3f1eb31955 100644
--- a/lib/files/storage/commontest.php
+++ b/lib/private/files/storage/commontest.php
diff --git a/lib/files/storage/loader.php b/lib/private/files/storage/loader.php
index 2572ef443bc..2572ef443bc 100644
--- a/lib/files/storage/loader.php
+++ b/lib/private/files/storage/loader.php
diff --git a/lib/files/storage/local.php b/lib/private/files/storage/local.php
index 5209fabc30a..5209fabc30a 100644
--- a/lib/files/storage/local.php
+++ b/lib/private/files/storage/local.php
diff --git a/lib/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php
index fbf1b4ebf96..ba5ac4191c5 100644
--- a/lib/files/storage/mappedlocal.php
+++ b/lib/private/files/storage/mappedlocal.php
@@ -65,16 +65,18 @@ class MappedLocal extends \OC\Files\Storage\Common{
$logicalPath = $this->mapper->physicalToLogic($physicalPath);
$dh = opendir($physicalPath);
- while (($file = readdir($dh)) !== false) {
- if ($file === '.' or $file === '..') {
- continue;
- }
+ if(is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ if ($file === '.' or $file === '..') {
+ continue;
+ }
- $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file);
+ $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.'/'.$file);
- $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath);
- $file = $this->stripLeading($file);
- $files[]= $file;
+ $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath);
+ $file = $this->stripLeading($file);
+ $files[]= $file;
+ }
}
\OC\Files\Stream\Dir::register('local-win32'.$path, $files);
diff --git a/lib/files/storage/storage.php b/lib/private/files/storage/storage.php
index c96caebf4af..b673bb9a32d 100644
--- a/lib/files/storage/storage.php
+++ b/lib/private/files/storage/storage.php
@@ -13,7 +13,7 @@ namespace OC\Files\Storage;
*
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
*/
-interface Storage {
+interface Storage extends \OCP\Files\Storage {
/**
* $parameters is a free form array with the configuration options needed to construct the storage
*
diff --git a/lib/files/storage/temporary.php b/lib/private/files/storage/temporary.php
index d84dbda2e39..d84dbda2e39 100644
--- a/lib/files/storage/temporary.php
+++ b/lib/private/files/storage/temporary.php
diff --git a/lib/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
index e2da8cf2e05..e2da8cf2e05 100644
--- a/lib/files/storage/wrapper/quota.php
+++ b/lib/private/files/storage/wrapper/quota.php
diff --git a/lib/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
index 0336c27efa1..0336c27efa1 100644
--- a/lib/files/storage/wrapper/wrapper.php
+++ b/lib/private/files/storage/wrapper/wrapper.php
diff --git a/lib/files/stream/close.php b/lib/private/files/stream/close.php
index 80de3497c36..80de3497c36 100644
--- a/lib/files/stream/close.php
+++ b/lib/private/files/stream/close.php
diff --git a/lib/files/stream/dir.php b/lib/private/files/stream/dir.php
index 6ca884fc994..6ca884fc994 100644
--- a/lib/files/stream/dir.php
+++ b/lib/private/files/stream/dir.php
diff --git a/lib/files/stream/oc.php b/lib/private/files/stream/oc.php
index 88e7e062df9..88e7e062df9 100644
--- a/lib/files/stream/oc.php
+++ b/lib/private/files/stream/oc.php
diff --git a/lib/files/stream/quota.php b/lib/private/files/stream/quota.php
index 53d8a03d30f..53d8a03d30f 100644
--- a/lib/files/stream/quota.php
+++ b/lib/private/files/stream/quota.php
diff --git a/lib/files/stream/staticstream.php b/lib/private/files/stream/staticstream.php
index 45b1a7a81f8..45b1a7a81f8 100644
--- a/lib/files/stream/staticstream.php
+++ b/lib/private/files/stream/staticstream.php
diff --git a/lib/files/type/detection.php b/lib/private/files/type/detection.php
index 242a81cb5a4..242a81cb5a4 100644
--- a/lib/files/type/detection.php
+++ b/lib/private/files/type/detection.php
diff --git a/lib/files/type/templatemanager.php b/lib/private/files/type/templatemanager.php
index cd1536d2732..cd1536d2732 100644
--- a/lib/files/type/templatemanager.php
+++ b/lib/private/files/type/templatemanager.php
diff --git a/lib/files/utils/scanner.php b/lib/private/files/utils/scanner.php
index f0dc41ffad3..2cad7dd77bd 100644
--- a/lib/files/utils/scanner.php
+++ b/lib/private/files/utils/scanner.php
@@ -72,6 +72,9 @@ class Scanner extends PublicEmitter {
public function backgroundScan($dir) {
$mounts = $this->getMounts($dir);
foreach ($mounts as $mount) {
+ if (is_null($mount->getStorage())) {
+ continue;
+ }
$scanner = $mount->getStorage()->getScanner();
$this->attachListener($mount);
$scanner->backgroundScan();
@@ -81,6 +84,9 @@ class Scanner extends PublicEmitter {
public function scan($dir) {
$mounts = $this->getMounts($dir);
foreach ($mounts as $mount) {
+ if (is_null($mount->getStorage())) {
+ continue;
+ }
$scanner = $mount->getStorage()->getScanner();
$this->attachListener($mount);
$scanner->scan('', \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG);
diff --git a/lib/files/view.php b/lib/private/files/view.php
index 98a04486690..aa08a5f7cc9 100644
--- a/lib/files/view.php
+++ b/lib/private/files/view.php
@@ -30,7 +30,7 @@ class View {
private $internal_path_cache = array();
private $storage_cache = array();
- public function __construct($root) {
+ public function __construct($root = '') {
$this->fakeRoot = $root;
}
@@ -500,9 +500,11 @@ class View {
} else {
if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) {
$result = $this->mkdir($path2);
- while (($file = readdir($dh)) !== false) {
- if (!Filesystem::isIgnoredDir($file)) {
- $result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file);
+ if (is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ if (!Filesystem::isIgnoredDir($file)) {
+ $result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file);
+ }
}
}
} else {
@@ -973,7 +975,7 @@ class View {
/**
* search for files by mimetype
*
- * @param string $query
+ * @param string $mimetype
* @return array
*/
public function searchByMime($mimetype) {
@@ -996,7 +998,7 @@ class View {
$results = $cache->$method($query);
foreach ($results as $result) {
- if (substr($mountPoint . $result['path'], 0, $rootLength) === $this->fakeRoot) {
+ if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') {
$result['path'] = substr($mountPoint . $result['path'], $rootLength);
$files[] = $result;
}
@@ -1010,9 +1012,11 @@ class View {
$relativeMountPoint = substr($mountPoint, $rootLength);
$results = $cache->$method($query);
- foreach ($results as $result) {
- $result['path'] = $relativeMountPoint . $result['path'];
- $files[] = $result;
+ if ($results) {
+ foreach ($results as $result) {
+ $result['path'] = $relativeMountPoint . $result['path'];
+ $files[] = $result;
+ }
}
}
}
diff --git a/lib/geo.php b/lib/private/geo.php
index ed01ad0b616..ed01ad0b616 100644
--- a/lib/geo.php
+++ b/lib/private/geo.php
diff --git a/lib/group.php b/lib/private/group.php
index ba93dc129a1..ba93dc129a1 100644
--- a/lib/group.php
+++ b/lib/private/group.php
diff --git a/lib/group/backend.php b/lib/private/group/backend.php
index 2e17b5d0b7f..2e17b5d0b7f 100644
--- a/lib/group/backend.php
+++ b/lib/private/group/backend.php
diff --git a/lib/group/database.php b/lib/private/group/database.php
index d0974685ff6..d0974685ff6 100644
--- a/lib/group/database.php
+++ b/lib/private/group/database.php
diff --git a/lib/group/dummy.php b/lib/private/group/dummy.php
index 9516fd52ff8..9516fd52ff8 100644
--- a/lib/group/dummy.php
+++ b/lib/private/group/dummy.php
diff --git a/lib/group/example.php b/lib/private/group/example.php
index 3519b9ed92f..3519b9ed92f 100644
--- a/lib/group/example.php
+++ b/lib/private/group/example.php
diff --git a/lib/group/group.php b/lib/private/group/group.php
index bcd2419b309..bcd2419b309 100644
--- a/lib/group/group.php
+++ b/lib/private/group/group.php
diff --git a/lib/group/interface.php b/lib/private/group/interface.php
index 4ef3663837f..4ef3663837f 100644
--- a/lib/group/interface.php
+++ b/lib/private/group/interface.php
diff --git a/lib/group/manager.php b/lib/private/group/manager.php
index bf469d51d12..bf469d51d12 100644
--- a/lib/group/manager.php
+++ b/lib/private/group/manager.php
diff --git a/lib/helper.php b/lib/private/helper.php
index 1f1ce8451c0..66e7acb407a 100644
--- a/lib/helper.php
+++ b/lib/private/helper.php
@@ -282,7 +282,6 @@ class OC_Helper {
*/
public static function humanFileSize($bytes) {
if ($bytes < 0) {
- $l = OC_L10N::get('lib');
return "?";
}
if ($bytes < 1024) {
@@ -296,10 +295,17 @@ class OC_Helper {
if ($bytes < 1024) {
return "$bytes MB";
}
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes GB";
+ }
+ $bytes = round($bytes / 1024, 1);
+ if ($bytes < 1024) {
+ return "$bytes TB";
+ }
- // Wow, heavy duty for owncloud
$bytes = round($bytes / 1024, 1);
- return "$bytes GB";
+ return "$bytes PB";
}
/**
@@ -349,17 +355,19 @@ class OC_Helper {
if (!is_dir($path))
return chmod($path, $filemode);
$dh = opendir($path);
- while (($file = readdir($dh)) !== false) {
- if ($file != '.' && $file != '..') {
- $fullpath = $path . '/' . $file;
- if (is_link($fullpath))
- return false;
- elseif (!is_dir($fullpath) && !@chmod($fullpath, $filemode))
- return false; elseif (!self::chmodr($fullpath, $filemode))
- return false;
+ if(is_resource($dh)) {
+ while (($file = readdir($dh)) !== false) {
+ if ($file != '.' && $file != '..') {
+ $fullpath = $path . '/' . $file;
+ if (is_link($fullpath))
+ return false;
+ elseif (!is_dir($fullpath) && !@chmod($fullpath, $filemode))
+ return false; elseif (!self::chmodr($fullpath, $filemode))
+ return false;
+ }
}
+ closedir($dh);
}
- closedir($dh);
if (@chmod($path, $filemode))
return true;
else
@@ -657,9 +665,11 @@ class OC_Helper {
// if oc-noclean is empty delete it
$isTmpDirNoCleanEmpty = true;
$tmpDirNoClean = opendir($tmpDirNoCleanName);
- while (false !== ($file = readdir($tmpDirNoClean))) {
- if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
- $isTmpDirNoCleanEmpty = false;
+ if(is_resource($tmpDirNoClean)) {
+ while (false !== ($file = readdir($tmpDirNoClean))) {
+ if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
+ $isTmpDirNoCleanEmpty = false;
+ }
}
}
if ($isTmpDirNoCleanEmpty) {
@@ -702,7 +712,7 @@ class OC_Helper {
$newpath = $path . '/' . $filename;
if ($view->file_exists($newpath)) {
if (preg_match_all('/\((\d+)\)/', $name, $matches, PREG_OFFSET_CAPTURE)) {
- //Replace the last "(number)" with "(number+1)"
+ //Replace the last "(number)" with "(number+1)"
$last_match = count($matches[0]) - 1;
$counter = $matches[1][$last_match][0] + 1;
$offset = $matches[0][$last_match][1];
@@ -713,7 +723,7 @@ class OC_Helper {
}
do {
if ($offset) {
- //Replace the last "(number)" with "(number+1)"
+ //Replace the last "(number)" with "(number+1)"
$newname = substr_replace($name, '(' . $counter . ')', $offset, $match_length);
} else {
$newname = $name . ' (' . $counter . ')';
diff --git a/lib/hintexception.php b/lib/private/hintexception.php
index 3934ae2a4c2..3934ae2a4c2 100644
--- a/lib/hintexception.php
+++ b/lib/private/hintexception.php
diff --git a/lib/hook.php b/lib/private/hook.php
index 8516cf0dcff..8516cf0dcff 100644
--- a/lib/hook.php
+++ b/lib/private/hook.php
diff --git a/lib/hooks/basicemitter.php b/lib/private/hooks/basicemitter.php
index 9ffe1af2314..9ffe1af2314 100644
--- a/lib/hooks/basicemitter.php
+++ b/lib/private/hooks/basicemitter.php
diff --git a/lib/hooks/emitter.php b/lib/private/hooks/emitter.php
index 8e9074bad67..8e9074bad67 100644
--- a/lib/hooks/emitter.php
+++ b/lib/private/hooks/emitter.php
diff --git a/lib/hooks/forwardingemitter.php b/lib/private/hooks/forwardingemitter.php
index 1aacc4012e0..1aacc4012e0 100644
--- a/lib/hooks/forwardingemitter.php
+++ b/lib/private/hooks/forwardingemitter.php
diff --git a/lib/hooks/legacyemitter.php b/lib/private/hooks/legacyemitter.php
index a2d16ace9a7..a2d16ace9a7 100644
--- a/lib/hooks/legacyemitter.php
+++ b/lib/private/hooks/legacyemitter.php
diff --git a/lib/hooks/publicemitter.php b/lib/private/hooks/publicemitter.php
index e2371713ac3..e2371713ac3 100644
--- a/lib/hooks/publicemitter.php
+++ b/lib/private/hooks/publicemitter.php
diff --git a/lib/image.php b/lib/private/image.php
index 7761a3c7737..7761a3c7737 100644
--- a/lib/image.php
+++ b/lib/private/image.php
diff --git a/lib/installer.php b/lib/private/installer.php
index b9684eaeea0..e082c7eeee9 100644
--- a/lib/installer.php
+++ b/lib/private/installer.php
@@ -107,10 +107,12 @@ class OC_Installer{
if(!is_file($extractDir.'/appinfo/info.xml')) {
//try to find it in a subdir
$dh=opendir($extractDir);
- while (($folder = readdir($dh)) !== false) {
- if($folder[0]!='.' and is_dir($extractDir.'/'.$folder)) {
- if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')) {
- $extractDir.='/'.$folder;
+ if(is_resource($dh)) {
+ while (($folder = readdir($dh)) !== false) {
+ if($folder[0]!='.' and is_dir($extractDir.'/'.$folder)) {
+ if(is_file($extractDir.'/'.$folder.'/appinfo/info.xml')) {
+ $extractDir.='/'.$folder;
+ }
}
}
}
@@ -426,6 +428,7 @@ class OC_Installer{
'OC_API::',
'OC_App::',
'OC_AppConfig::',
+ 'OC_Avatar',
'OC_BackgroundJob::',
'OC_Config::',
'OC_DB::',
diff --git a/lib/json.php b/lib/private/json.php
index 6ba0b13806b..6ba0b13806b 100644
--- a/lib/json.php
+++ b/lib/private/json.php
diff --git a/lib/l10n.php b/lib/private/l10n.php
index f93443b886a..f93443b886a 100644
--- a/lib/l10n.php
+++ b/lib/private/l10n.php
diff --git a/lib/l10n/ach.php b/lib/private/l10n/ach.php
index 406ff5f5a26..406ff5f5a26 100644
--- a/lib/l10n/ach.php
+++ b/lib/private/l10n/ach.php
diff --git a/lib/l10n/af_ZA.php b/lib/private/l10n/af_ZA.php
index d6bf5771e8d..d6bf5771e8d 100644
--- a/lib/l10n/af_ZA.php
+++ b/lib/private/l10n/af_ZA.php
diff --git a/lib/l10n/ar.php b/lib/private/l10n/ar.php
index f626dcdfda6..f626dcdfda6 100644
--- a/lib/l10n/ar.php
+++ b/lib/private/l10n/ar.php
diff --git a/lib/l10n/be.php b/lib/private/l10n/be.php
index 1570411eb86..1570411eb86 100644
--- a/lib/l10n/be.php
+++ b/lib/private/l10n/be.php
diff --git a/lib/l10n/bg_BG.php b/lib/private/l10n/bg_BG.php
index b6cc949eb8a..b6cc949eb8a 100644
--- a/lib/l10n/bg_BG.php
+++ b/lib/private/l10n/bg_BG.php
diff --git a/lib/l10n/bn_BD.php b/lib/private/l10n/bn_BD.php
index a42435a2a47..a42435a2a47 100644
--- a/lib/l10n/bn_BD.php
+++ b/lib/private/l10n/bn_BD.php
diff --git a/lib/l10n/bs.php b/lib/private/l10n/bs.php
index 3cb98906e62..3cb98906e62 100644
--- a/lib/l10n/bs.php
+++ b/lib/private/l10n/bs.php
diff --git a/lib/l10n/ca.php b/lib/private/l10n/ca.php
index 166455e652c..a8769224705 100644
--- a/lib/l10n/ca.php
+++ b/lib/private/l10n/ca.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Usuaris",
"Admin" => "Administració",
"Failed to upgrade \"%s\"." => "Ha fallat l'actualització \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Les imatges de perfil personals encara no funcionen amb encriptació",
+"Unknown filetype" => "Tipus de fitxer desconegut",
+"Invalid image" => "Imatge no vàlida",
"web services under your control" => "controleu els vostres serveis web",
"cannot open \"%s\"" => "no es pot obrir \"%s\"",
"ZIP download is turned off." => "La baixada en ZIP està desactivada.",
diff --git a/lib/l10n/cs_CZ.php b/lib/private/l10n/cs_CZ.php
index fed9ad03c01..ed31ae79529 100644
--- a/lib/l10n/cs_CZ.php
+++ b/lib/private/l10n/cs_CZ.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Uživatelé",
"Admin" => "Administrace",
"Failed to upgrade \"%s\"." => "Selhala aktualizace verze \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Vlastní profilové obrázky zatím nefungují v kombinaci se šifrováním",
+"Unknown filetype" => "Neznámý typ souboru",
+"Invalid image" => "Chybný obrázek",
"web services under your control" => "webové služby pod Vaší kontrolou",
"cannot open \"%s\"" => "nelze otevřít \"%s\"",
"ZIP download is turned off." => "Stahování v ZIPu je vypnuto.",
diff --git a/lib/l10n/cy_GB.php b/lib/private/l10n/cy_GB.php
index 6973b51878f..6973b51878f 100644
--- a/lib/l10n/cy_GB.php
+++ b/lib/private/l10n/cy_GB.php
diff --git a/lib/l10n/da.php b/lib/private/l10n/da.php
index 26903142763..05a43f42ed9 100644
--- a/lib/l10n/da.php
+++ b/lib/private/l10n/da.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Brugere",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Upgradering af \"%s\" fejlede",
+"Custom profile pictures don't work with encryption yet" => "Personligt profilbillede virker endnu ikke sammen med kryptering",
+"Unknown filetype" => "Ukendt filtype",
+"Invalid image" => "Ugyldigt billede",
"web services under your control" => "Webtjenester under din kontrol",
"cannot open \"%s\"" => "Kan ikke åbne \"%s\"",
"ZIP download is turned off." => "ZIP-download er slået fra.",
diff --git a/lib/l10n/de.php b/lib/private/l10n/de.php
index 7a3e2c43e6b..87e7a67b47b 100644
--- a/lib/l10n/de.php
+++ b/lib/private/l10n/de.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Benutzer",
"Admin" => "Administration",
"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.",
+"Custom profile pictures don't work with encryption yet" => "Individuelle Profilbilder werden noch nicht von der Verschlüsselung unterstützt",
+"Unknown filetype" => "Unbekannter Dateityp",
+"Invalid image" => "Ungültiges Bild",
"web services under your control" => "Web-Services unter Deiner Kontrolle",
"cannot open \"%s\"" => "Öffnen von \"%s\" fehlgeschlagen",
"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.",
diff --git a/lib/l10n/de_AT.php b/lib/private/l10n/de_AT.php
index 15f78e0bce6..15f78e0bce6 100644
--- a/lib/l10n/de_AT.php
+++ b/lib/private/l10n/de_AT.php
diff --git a/lib/l10n/de_CH.php b/lib/private/l10n/de_CH.php
index 33f3446a693..33f3446a693 100644
--- a/lib/l10n/de_CH.php
+++ b/lib/private/l10n/de_CH.php
diff --git a/lib/l10n/de_DE.php b/lib/private/l10n/de_DE.php
index 0a72f443e4d..09be0eea22d 100644
--- a/lib/l10n/de_DE.php
+++ b/lib/private/l10n/de_DE.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Benutzer",
"Admin" => "Administrator",
"Failed to upgrade \"%s\"." => "Konnte \"%s\" nicht aktualisieren.",
+"Custom profile pictures don't work with encryption yet" => "Individuelle Profilbilder werden noch nicht von der Verschlüsselung unterstützt",
+"Unknown filetype" => "Unbekannter Dateityp",
+"Invalid image" => "Ungültiges Bild",
"web services under your control" => "Web-Services unter Ihrer Kontrolle",
"cannot open \"%s\"" => "Öffnen von \"%s\" fehlgeschlagen",
"ZIP download is turned off." => "Der ZIP-Download ist deaktiviert.",
diff --git a/lib/l10n/el.php b/lib/private/l10n/el.php
index dcbf82d4a4b..dcbf82d4a4b 100644
--- a/lib/l10n/el.php
+++ b/lib/private/l10n/el.php
diff --git a/lib/l10n/en@pirate.php b/lib/private/l10n/en@pirate.php
index a8175b1400f..a8175b1400f 100644
--- a/lib/l10n/en@pirate.php
+++ b/lib/private/l10n/en@pirate.php
diff --git a/lib/l10n/en_GB.php b/lib/private/l10n/en_GB.php
index f799c071c76..d02f553eda8 100644
--- a/lib/l10n/en_GB.php
+++ b/lib/private/l10n/en_GB.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Users",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Failed to upgrade \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Custom profile pictures don't work with encryption yet",
+"Unknown filetype" => "Unknown filetype",
+"Invalid image" => "Invalid image",
"web services under your control" => "web services under your control",
"cannot open \"%s\"" => "cannot open \"%s\"",
"ZIP download is turned off." => "ZIP download is turned off.",
@@ -54,13 +57,13 @@ $TRANSLATIONS = array(
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Your web server is not yet properly setup to allow files synchronisation because the WebDAV interface seems to be broken.",
"Please double check the <a href='%s'>installation guides</a>." => "Please double check the <a href='%s'>installation guides</a>.",
"seconds ago" => "seconds ago",
-"_%n minute ago_::_%n minutes ago_" => array("","%n minutes ago"),
-"_%n hour ago_::_%n hours ago_" => array("","%n hours ago"),
+"_%n minute ago_::_%n minutes ago_" => array("%n minute ago","%n minutes ago"),
+"_%n hour ago_::_%n hours ago_" => array("%n hour ago","%n hours ago"),
"today" => "today",
"yesterday" => "yesterday",
-"_%n day go_::_%n days ago_" => array("","%n days ago"),
+"_%n day go_::_%n days ago_" => array("%n day go","%n days ago"),
"last month" => "last month",
-"_%n month ago_::_%n months ago_" => array("","%n months ago"),
+"_%n month ago_::_%n months ago_" => array("%n month ago","%n months ago"),
"last year" => "last year",
"years ago" => "years ago",
"Caused by:" => "Caused by:",
diff --git a/lib/l10n/eo.php b/lib/private/l10n/eo.php
index 5311dd6eb15..5311dd6eb15 100644
--- a/lib/l10n/eo.php
+++ b/lib/private/l10n/eo.php
diff --git a/lib/l10n/es.php b/lib/private/l10n/es.php
index 047d5d955bb..047d5d955bb 100644
--- a/lib/l10n/es.php
+++ b/lib/private/l10n/es.php
diff --git a/lib/l10n/es_AR.php b/lib/private/l10n/es_AR.php
index f637eb403ed..f637eb403ed 100644
--- a/lib/l10n/es_AR.php
+++ b/lib/private/l10n/es_AR.php
diff --git a/lib/l10n/es_MX.php b/lib/private/l10n/es_MX.php
index 15f78e0bce6..15f78e0bce6 100644
--- a/lib/l10n/es_MX.php
+++ b/lib/private/l10n/es_MX.php
diff --git a/lib/l10n/et_EE.php b/lib/private/l10n/et_EE.php
index 8e3aa55c4ed..85dfaeb52d5 100644
--- a/lib/l10n/et_EE.php
+++ b/lib/private/l10n/et_EE.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Kasutajad",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Ebaõnnestunud uuendus \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Kohandatud profiili pildid ei toimi veel koos krüpteeringuga",
+"Unknown filetype" => "Tundmatu failitüüp",
+"Invalid image" => "Vigane pilt",
"web services under your control" => "veebitenused sinu kontrolli all",
"cannot open \"%s\"" => "ei suuda avada \"%s\"",
"ZIP download is turned off." => "ZIP-ina allalaadimine on välja lülitatud.",
diff --git a/lib/l10n/eu.php b/lib/private/l10n/eu.php
index 413819f4f94..413819f4f94 100644
--- a/lib/l10n/eu.php
+++ b/lib/private/l10n/eu.php
diff --git a/lib/l10n/fa.php b/lib/private/l10n/fa.php
index e9cb695bade..e9cb695bade 100644
--- a/lib/l10n/fa.php
+++ b/lib/private/l10n/fa.php
diff --git a/lib/l10n/fi.php b/lib/private/l10n/fi.php
index ac1f80a8f73..ac1f80a8f73 100644
--- a/lib/l10n/fi.php
+++ b/lib/private/l10n/fi.php
diff --git a/lib/l10n/fi_FI.php b/lib/private/l10n/fi_FI.php
index 2e69df43ad2..1d2bdab749c 100644
--- a/lib/l10n/fi_FI.php
+++ b/lib/private/l10n/fi_FI.php
@@ -1,11 +1,16 @@
<?php
$TRANSLATIONS = array(
"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Sovellusta \"%s\" ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa.",
+"No app name specified" => "Sovelluksen nimeä ei määritelty",
"Help" => "Ohje",
"Personal" => "Henkilökohtainen",
"Settings" => "Asetukset",
"Users" => "Käyttäjät",
"Admin" => "Ylläpitäjä",
+"Failed to upgrade \"%s\"." => "Kohteen \"%s\" päivitys epäonnistui.",
+"Custom profile pictures don't work with encryption yet" => "Omavalintaiset profiilikuvat eivät toimi salauksen kanssa vielä",
+"Unknown filetype" => "Tuntematon tiedostotyyppi",
+"Invalid image" => "Virheellinen kuva",
"web services under your control" => "verkkopalvelut hallinnassasi",
"ZIP download is turned off." => "ZIP-lataus on poistettu käytöstä.",
"Files need to be downloaded one by one." => "Tiedostot on ladattava yksittäin.",
@@ -15,6 +20,8 @@ $TRANSLATIONS = array(
"No path specified when installing app from local file" => "Polkua ei määritelty sovellusta asennettaessa paikallisesta tiedostosta",
"Archives of type %s are not supported" => "Tyypin %s arkistot eivät ole tuettuja",
"App does not provide an info.xml file" => "Sovellus ei sisällä info.xml-tiedostoa",
+"App can't be installed because of not allowed code in the App" => "Sovellusta ei voi asentaa, koska sovellus sisältää kiellettyä koodia",
+"App can't be installed because it is not compatible with this version of ownCloud" => "Sovellusta ei voi asentaa, koska se ei ole yhteensopiva käytössä olevan ownCloud-version kanssa",
"App directory already exists" => "Sovelluskansio on jo olemassa",
"Can't create app folder. Please fix permissions. %s" => "Sovelluskansion luominen ei onnistu. Korjaa käyttöoikeudet. %s",
"Application is not enabled" => "Sovellusta ei ole otettu käyttöön",
diff --git a/lib/l10n/fr.php b/lib/private/l10n/fr.php
index da3ec4ce372..ab3d618849e 100644
--- a/lib/l10n/fr.php
+++ b/lib/private/l10n/fr.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Utilisateurs",
"Admin" => "Administration",
"Failed to upgrade \"%s\"." => "Echec de la mise à niveau \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Les images de profil personnalisées ne fonctionnent pas encore avec le système de chiffrement.",
+"Unknown filetype" => "Type de fichier inconnu",
+"Invalid image" => "Image invalide",
"web services under your control" => "services web sous votre contrôle",
"cannot open \"%s\"" => "impossible d'ouvrir \"%s\"",
"ZIP download is turned off." => "Téléchargement ZIP désactivé.",
diff --git a/lib/l10n/gl.php b/lib/private/l10n/gl.php
index a8fee3b1bc1..406272d690f 100644
--- a/lib/l10n/gl.php
+++ b/lib/private/l10n/gl.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Usuarios",
"Admin" => "Administración",
"Failed to upgrade \"%s\"." => "Non foi posíbel anovar «%s».",
+"Custom profile pictures don't work with encryption yet" => "As imaxes personalizadas de perfil aínda non funcionan co cifrado",
+"Unknown filetype" => "Tipo de ficheiro descoñecido",
+"Invalid image" => "Imaxe incorrecta",
"web services under your control" => "servizos web baixo o seu control",
"cannot open \"%s\"" => "non foi posíbel abrir «%s»",
"ZIP download is turned off." => "As descargas ZIP están desactivadas.",
diff --git a/lib/l10n/he.php b/lib/private/l10n/he.php
index ced6244ee91..ced6244ee91 100644
--- a/lib/l10n/he.php
+++ b/lib/private/l10n/he.php
diff --git a/lib/l10n/hi.php b/lib/private/l10n/hi.php
index 039dfa4465d..039dfa4465d 100644
--- a/lib/l10n/hi.php
+++ b/lib/private/l10n/hi.php
diff --git a/lib/l10n/hr.php b/lib/private/l10n/hr.php
index d217f924099..d217f924099 100644
--- a/lib/l10n/hr.php
+++ b/lib/private/l10n/hr.php
diff --git a/lib/l10n/hu_HU.php b/lib/private/l10n/hu_HU.php
index 7ec7621a655..e944291caee 100644
--- a/lib/l10n/hu_HU.php
+++ b/lib/private/l10n/hu_HU.php
@@ -1,11 +1,14 @@
<?php
$TRANSLATIONS = array(
+"No app name specified" => "Nincs az alkalmazás név megadva.",
"Help" => "Súgó",
"Personal" => "Személyes",
"Settings" => "Beállítások",
"Users" => "Felhasználók",
"Admin" => "Adminsztráció",
"Failed to upgrade \"%s\"." => "Sikertelen Frissítés \"%s\".",
+"Unknown filetype" => "Ismeretlen file tipús",
+"Invalid image" => "Hibás kép",
"web services under your control" => "webszolgáltatások saját kézben",
"cannot open \"%s\"" => "nem sikerült megnyitni \"%s\"",
"ZIP download is turned off." => "A ZIP-letöltés nincs engedélyezve.",
@@ -13,6 +16,10 @@ $TRANSLATIONS = array(
"Back to Files" => "Vissza a Fájlokhoz",
"Selected files too large to generate zip file." => "A kiválasztott fájlok túl nagyok a zip tömörítéshez.",
"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Tölts le a fileokat kisebb chunkokban, kölün vagy kérj segitséget a rendszergazdádtól.",
+"App does not provide an info.xml file" => "Az alkalmazás nem szolgáltatott info.xml file-t",
+"App can't be installed because it is not compatible with this version of ownCloud" => "Az alalmazás nem telepíthető, mert nem kompatibilis az ownClod ezzel a verziójával.",
+"App directory already exists" => "Az alkalmazás mappája már létezik",
+"Can't create app folder. Please fix permissions. %s" => "Nem lehetett létrehozni az alkalmzás mappáját. Kérlek ellenőrizd a jogosultásgokat. %s",
"Application is not enabled" => "Az alkalmazás nincs engedélyezve",
"Authentication error" => "Azonosítási hiba",
"Token expired. Please reload page." => "A token lejárt. Frissítse az oldalt.",
@@ -39,6 +46,7 @@ $TRANSLATIONS = array(
"Set an admin password." => "Állítson be egy jelszót az adminisztrációhoz.",
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Az Ön webkiszolgálója nincs megfelelően beállítva az állományok szinkronizálásához, mert a WebDAV-elérés úgy tűnik, nem működik.",
"Please double check the <a href='%s'>installation guides</a>." => "Kérjük tüzetesen tanulmányozza át a <a href='%s'>telepítési útmutatót</a>.",
+"Could not find category \"%s\"" => "Ez a kategória nem található: \"%s\"",
"seconds ago" => "pár másodperce",
"_%n minute ago_::_%n minutes ago_" => array("",""),
"_%n hour ago_::_%n hours ago_" => array("",""),
@@ -49,7 +57,6 @@ $TRANSLATIONS = array(
"_%n month ago_::_%n months ago_" => array("",""),
"last year" => "tavaly",
"years ago" => "több éve",
-"Caused by:" => "Okozta:",
-"Could not find category \"%s\"" => "Ez a kategória nem található: \"%s\""
+"Caused by:" => "Okozta:"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/hy.php b/lib/private/l10n/hy.php
index 15f78e0bce6..15f78e0bce6 100644
--- a/lib/l10n/hy.php
+++ b/lib/private/l10n/hy.php
diff --git a/lib/l10n/ia.php b/lib/private/l10n/ia.php
index 34f43bc424a..34f43bc424a 100644
--- a/lib/l10n/ia.php
+++ b/lib/private/l10n/ia.php
diff --git a/lib/l10n/id.php b/lib/private/l10n/id.php
index 080faddb321..080faddb321 100644
--- a/lib/l10n/id.php
+++ b/lib/private/l10n/id.php
diff --git a/lib/l10n/is.php b/lib/private/l10n/is.php
index 7512d278fb8..7512d278fb8 100644
--- a/lib/l10n/is.php
+++ b/lib/private/l10n/is.php
diff --git a/lib/l10n/it.php b/lib/private/l10n/it.php
index c3a040048ec..b00789bc86f 100644
--- a/lib/l10n/it.php
+++ b/lib/private/l10n/it.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Utenti",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Aggiornamento non riuscito \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Le immagini personalizzate del profilo non funzionano ancora con la cifratura",
+"Unknown filetype" => "Tipo di file sconosciuto",
+"Invalid image" => "Immagine non valida",
"web services under your control" => "servizi web nelle tue mani",
"cannot open \"%s\"" => "impossibile aprire \"%s\"",
"ZIP download is turned off." => "Lo scaricamento in formato ZIP è stato disabilitato.",
diff --git a/lib/l10n/ja_JP.php b/lib/private/l10n/ja_JP.php
index 2d37001ca19..b9e6a0e6924 100644
--- a/lib/l10n/ja_JP.php
+++ b/lib/private/l10n/ja_JP.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "ユーザ",
"Admin" => "管理",
"Failed to upgrade \"%s\"." => "\"%s\" へのアップグレードに失敗しました。",
+"Custom profile pictures don't work with encryption yet" => "暗号無しでは利用不可なカスタムプロフィール画像",
+"Unknown filetype" => "不明なファイルタイプ",
+"Invalid image" => "無効な画像",
"web services under your control" => "管理下のウェブサービス",
"cannot open \"%s\"" => "\"%s\" が開けません",
"ZIP download is turned off." => "ZIPダウンロードは無効です。",
diff --git a/lib/l10n/ka.php b/lib/private/l10n/ka.php
index 04fefe8bdf1..04fefe8bdf1 100644
--- a/lib/l10n/ka.php
+++ b/lib/private/l10n/ka.php
diff --git a/lib/l10n/ka_GE.php b/lib/private/l10n/ka_GE.php
index 8fbe34e6786..8fbe34e6786 100644
--- a/lib/l10n/ka_GE.php
+++ b/lib/private/l10n/ka_GE.php
diff --git a/lib/l10n/kn.php b/lib/private/l10n/km.php
index e7b09649a24..e7b09649a24 100644
--- a/lib/l10n/kn.php
+++ b/lib/private/l10n/km.php
diff --git a/lib/l10n/nqo.php b/lib/private/l10n/kn.php
index e7b09649a24..e7b09649a24 100644
--- a/lib/l10n/nqo.php
+++ b/lib/private/l10n/kn.php
diff --git a/lib/l10n/ko.php b/lib/private/l10n/ko.php
index eec5be65abd..3ef39fefa60 100644
--- a/lib/l10n/ko.php
+++ b/lib/private/l10n/ko.php
@@ -8,12 +8,16 @@ $TRANSLATIONS = array(
"Users" => "사용자",
"Admin" => "관리자",
"Failed to upgrade \"%s\"." => "\"%s\" 업그레이드에 실패했습니다.",
+"Custom profile pictures don't work with encryption yet" => "개개인의 프로필 사진은 아직은 암호화 되지 않습니다",
+"Unknown filetype" => "알수없는 파일형식",
+"Invalid image" => "잘못된 그림",
"web services under your control" => "내가 관리하는 웹 서비스",
"cannot open \"%s\"" => "\"%s\"을(를) 열 수 없습니다.",
"ZIP download is turned off." => "ZIP 다운로드가 비활성화되었습니다.",
"Files need to be downloaded one by one." => "파일을 개별적으로 다운로드해야 합니다.",
"Back to Files" => "파일로 돌아가기",
"Selected files too large to generate zip file." => "선택한 파일들은 ZIP 파일을 생성하기에 너무 큽니다.",
+"Download the files in smaller chunks, seperately or kindly ask your administrator." => "작은 조각들 안에 들어있는 파일들을 받고자 하신다면, 나누어서 받으시거나 혹은 시스템 관리자에게 정중하게 물어보십시오",
"No source specified when installing app" => "앱을 설치할 때 소스가 지정되지 않았습니다.",
"No href specified when installing app from http" => "http에서 앱을 설치할 대 href가 지정되지 않았습니다.",
"No path specified when installing app from local file" => "로컬 파일에서 앱을 설치할 때 경로가 지정되지 않았습니다.",
@@ -52,6 +56,7 @@ $TRANSLATIONS = array(
"Set an admin password." => "관리자 비밀번호 설정",
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "WebDAV 인터페이스가 제대로 작동하지 않습니다. 웹 서버에서 파일 동기화를 사용할 수 있도록 설정이 제대로 되지 않은 것 같습니다.",
"Please double check the <a href='%s'>installation guides</a>." => "<a href='%s'>설치 가이드</a>를 다시 한 번 확인하십시오.",
+"Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다.",
"seconds ago" => "초 전",
"_%n minute ago_::_%n minutes ago_" => array("%n분 전 "),
"_%n hour ago_::_%n hours ago_" => array("%n시간 전 "),
@@ -62,7 +67,6 @@ $TRANSLATIONS = array(
"_%n month ago_::_%n months ago_" => array("%n달 전 "),
"last year" => "작년",
"years ago" => "년 전",
-"Caused by:" => "원인: ",
-"Could not find category \"%s\"" => "분류 \"%s\"을(를) 찾을 수 없습니다."
+"Caused by:" => "원인: "
);
$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/ku_IQ.php b/lib/private/l10n/ku_IQ.php
index c99f9dd2a12..c99f9dd2a12 100644
--- a/lib/l10n/ku_IQ.php
+++ b/lib/private/l10n/ku_IQ.php
diff --git a/lib/l10n/lb.php b/lib/private/l10n/lb.php
index c25f5b55bd5..c25f5b55bd5 100644
--- a/lib/l10n/lb.php
+++ b/lib/private/l10n/lb.php
diff --git a/lib/private/l10n/lt_LT.php b/lib/private/l10n/lt_LT.php
new file mode 100644
index 00000000000..db8d96c1018
--- /dev/null
+++ b/lib/private/l10n/lt_LT.php
@@ -0,0 +1,72 @@
+<?php
+$TRANSLATIONS = array(
+"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Programa „%s“ negali būti įdiegta, nes yra nesuderinama su šia ownCloud versija.",
+"No app name specified" => "Nenurodytas programos pavadinimas",
+"Help" => "Pagalba",
+"Personal" => "Asmeniniai",
+"Settings" => "Nustatymai",
+"Users" => "Vartotojai",
+"Admin" => "Administravimas",
+"Failed to upgrade \"%s\"." => "Nepavyko pakelti „%s“ versijos.",
+"Custom profile pictures don't work with encryption yet" => "Saviti profilio paveiksliukai dar neveikia su šifravimu",
+"Unknown filetype" => "Nežinomas failo tipas",
+"Invalid image" => "Netinkamas paveikslėlis",
+"web services under your control" => "jūsų valdomos web paslaugos",
+"cannot open \"%s\"" => "nepavyksta atverti „%s“",
+"ZIP download is turned off." => "ZIP atsisiuntimo galimybė yra išjungta.",
+"Files need to be downloaded one by one." => "Failai turi būti parsiunčiami vienas po kito.",
+"Back to Files" => "Atgal į Failus",
+"Selected files too large to generate zip file." => "Pasirinkti failai per dideli archyvavimui į ZIP.",
+"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Atsisiųskite failus mažesnėmis dalimis atskirai, arba mandagiai prašykite savo administratoriaus.",
+"No source specified when installing app" => "Nenurodytas šaltinis diegiant programą",
+"No href specified when installing app from http" => "Nenurodytas href diegiant programą iš http",
+"No path specified when installing app from local file" => "Nenurodytas kelias diegiant programą iš vietinio failo",
+"Archives of type %s are not supported" => "%s tipo archyvai nepalaikomi",
+"Failed to open archive when installing app" => "Nepavyko atverti archyvo diegiant programą",
+"App does not provide an info.xml file" => "Programa nepateikia info.xml failo",
+"App can't be installed because of not allowed code in the App" => "Programa negali būti įdiegta, nes turi neleistiną kodą",
+"App can't be installed because it is not compatible with this version of ownCloud" => "Programa negali būti įdiegta, nes yra nesuderinama su šia ownCloud versija",
+"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Programa negali būti įdiegta, nes turi <shipped>true</shipped> žymę, kuri yra neleistina ne kartu platinamoms programoms",
+"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Programa negali būti įdiegta, nes versija pateikta info.xml/version nesutampa su versija deklaruota programų saugykloje",
+"App directory already exists" => "Programos aplankas jau egzistuoja",
+"Can't create app folder. Please fix permissions. %s" => "Nepavyksta sukurti aplanko. Prašome pataisyti leidimus. %s",
+"Application is not enabled" => "Programa neįjungta",
+"Authentication error" => "Autentikacijos klaida",
+"Token expired. Please reload page." => "Sesija baigėsi. Prašome perkrauti puslapį.",
+"Files" => "Failai",
+"Text" => "Žinučių",
+"Images" => "Paveikslėliai",
+"%s enter the database username." => "%s įrašykite duombazės naudotojo vardą.",
+"%s enter the database name." => "%s įrašykite duombazės pavadinimą.",
+"%s you may not use dots in the database name" => "%s negalite naudoti taškų duombazės pavadinime",
+"MS SQL username and/or password not valid: %s" => "MS SQL naudotojo vardas ir/arba slaptažodis netinka: %s",
+"You need to enter either an existing account or the administrator." => "Turite prisijungti su egzistuojančia paskyra arba su administratoriumi.",
+"MySQL username and/or password not valid" => "Neteisingas MySQL naudotojo vardas ir/arba slaptažodis",
+"DB Error: \"%s\"" => "DB klaida: \"%s\"",
+"Offending command was: \"%s\"" => "Vykdyta komanda buvo: \"%s\"",
+"MySQL user '%s'@'localhost' exists already." => "MySQL naudotojas '%s'@'localhost' jau egzistuoja.",
+"Drop this user from MySQL" => "Pašalinti šį naudotoją iš MySQL",
+"MySQL user '%s'@'%%' already exists" => "MySQL naudotojas '%s'@'%%' jau egzistuoja",
+"Drop this user from MySQL." => "Pašalinti šį naudotoją iš MySQL.",
+"Oracle connection could not be established" => "Nepavyko sukurti Oracle ryšio",
+"Oracle username and/or password not valid" => "Neteisingas Oracle naudotojo vardas ir/arba slaptažodis",
+"Offending command was: \"%s\", name: %s, password: %s" => "Vykdyta komanda buvo: \"%s\", name: %s, password: %s",
+"PostgreSQL username and/or password not valid" => "Neteisingas PostgreSQL naudotojo vardas ir/arba slaptažodis",
+"Set an admin username." => "Nustatyti administratoriaus naudotojo vardą.",
+"Set an admin password." => "Nustatyti administratoriaus slaptažodį.",
+"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Jūsų serveris nėra tvarkingai nustatytas leisti failų sinchronizaciją, nes WebDAV sąsaja panašu, kad yra sugadinta.",
+"Please double check the <a href='%s'>installation guides</a>." => "Prašome pažiūrėkite dar kartą <a href='%s'>diegimo instrukcijas</a>.",
+"seconds ago" => "prieš sekundę",
+"_%n minute ago_::_%n minutes ago_" => array("prieš %n min.","Prieš % minutes","Prieš %n minučių"),
+"_%n hour ago_::_%n hours ago_" => array("Prieš %n valandą","Prieš %n valandas","Prieš %n valandų"),
+"today" => "šiandien",
+"yesterday" => "vakar",
+"_%n day go_::_%n days ago_" => array("Prieš %n dieną","Prieš %n dienas","Prieš %n dienų"),
+"last month" => "praeitą mėnesį",
+"_%n month ago_::_%n months ago_" => array("Prieš %n mėnesį","Prieš %n mėnesius","Prieš %n mėnesių"),
+"last year" => "praeitais metais",
+"years ago" => "prieš metus",
+"Caused by:" => "Iššaukė:",
+"Could not find category \"%s\"" => "Nepavyko rasti kategorijos „%s“"
+);
+$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/lv.php b/lib/private/l10n/lv.php
index 4090a36edcc..4090a36edcc 100644
--- a/lib/l10n/lv.php
+++ b/lib/private/l10n/lv.php
diff --git a/lib/l10n/mk.php b/lib/private/l10n/mk.php
index 69d4a1cb694..69d4a1cb694 100644
--- a/lib/l10n/mk.php
+++ b/lib/private/l10n/mk.php
diff --git a/lib/l10n/ml_IN.php b/lib/private/l10n/ml_IN.php
index 15f78e0bce6..15f78e0bce6 100644
--- a/lib/l10n/ml_IN.php
+++ b/lib/private/l10n/ml_IN.php
diff --git a/lib/l10n/ms_MY.php b/lib/private/l10n/ms_MY.php
index 17ef07f83dd..17ef07f83dd 100644
--- a/lib/l10n/ms_MY.php
+++ b/lib/private/l10n/ms_MY.php
diff --git a/lib/l10n/my_MM.php b/lib/private/l10n/my_MM.php
index 5f4b6ddc820..5f4b6ddc820 100644
--- a/lib/l10n/my_MM.php
+++ b/lib/private/l10n/my_MM.php
diff --git a/lib/l10n/nb_NO.php b/lib/private/l10n/nb_NO.php
index 8e7d095d369..8e7d095d369 100644
--- a/lib/l10n/nb_NO.php
+++ b/lib/private/l10n/nb_NO.php
diff --git a/lib/l10n/ne.php b/lib/private/l10n/ne.php
index 15f78e0bce6..15f78e0bce6 100644
--- a/lib/l10n/ne.php
+++ b/lib/private/l10n/ne.php
diff --git a/lib/l10n/nl.php b/lib/private/l10n/nl.php
index e546c1f3179..20374f1f0f8 100644
--- a/lib/l10n/nl.php
+++ b/lib/private/l10n/nl.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "App \"%s\" kan niet worden geïnstalleerd omdat die niet compatible is met deze versie van ownCloud.",
"No app name specified" => "De app naam is niet gespecificeerd.",
"Help" => "Help",
"Personal" => "Persoonlijk",
@@ -7,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Gebruikers",
"Admin" => "Beheerder",
"Failed to upgrade \"%s\"." => "Upgrade \"%s\" mislukt.",
+"Custom profile pictures don't work with encryption yet" => "Maatwerk profielafbeelding werkt nog niet met versleuteling",
+"Unknown filetype" => "Onbekend bestandsformaat",
+"Invalid image" => "Ongeldige afbeelding",
"web services under your control" => "Webdiensten in eigen beheer",
"cannot open \"%s\"" => "Kon \"%s\" niet openen",
"ZIP download is turned off." => "ZIP download is uitgeschakeld.",
@@ -14,6 +18,18 @@ $TRANSLATIONS = array(
"Back to Files" => "Terug naar bestanden",
"Selected files too large to generate zip file." => "De geselecteerde bestanden zijn te groot om een zip bestand te maken.",
"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Download de bestanden in kleinere brokken, appart of vraag uw administrator.",
+"No source specified when installing app" => "Geen bron opgegeven bij installatie van de app",
+"No href specified when installing app from http" => "Geen href opgegeven bij installeren van de app vanaf http",
+"No path specified when installing app from local file" => "Geen pad opgegeven bij installeren van de app vanaf een lokaal bestand",
+"Archives of type %s are not supported" => "Archiefbestanden van type %s niet ondersteund",
+"Failed to open archive when installing app" => "Kon archiefbestand bij installatie van de app niet openen",
+"App does not provide an info.xml file" => "De app heeft geen info.xml bestand",
+"App can't be installed because of not allowed code in the App" => "De app kan niet worden geïnstalleerd wegens onjuiste code in de app",
+"App can't be installed because it is not compatible with this version of ownCloud" => "De app kan niet worden geïnstalleerd omdat die niet compatible is met deze versie van ownCloud",
+"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "De app kan niet worden geïnstallerd omdat het de <shipped>true</shipped> tag bevat die niet is toegestaan voor niet gepubliceerde apps",
+"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "De app kan niet worden geïnstalleerd omdat de versie in info.xml/version niet dezelfde is als de versie zoals die in de app store staat vermeld",
+"App directory already exists" => "App directory bestaat al",
+"Can't create app folder. Please fix permissions. %s" => "Kan de app map niet aanmaken, Herstel de permissies. %s",
"Application is not enabled" => "De applicatie is niet actief",
"Authentication error" => "Authenticatie fout",
"Token expired. Please reload page." => "Token verlopen. Herlaad de pagina.",
diff --git a/lib/l10n/nn_NO.php b/lib/private/l10n/nn_NO.php
index d5da8c64415..e8bf8dfdef4 100644
--- a/lib/l10n/nn_NO.php
+++ b/lib/private/l10n/nn_NO.php
@@ -5,6 +5,8 @@ $TRANSLATIONS = array(
"Settings" => "Innstillingar",
"Users" => "Brukarar",
"Admin" => "Administrer",
+"Unknown filetype" => "Ukjend filtype",
+"Invalid image" => "Ugyldig bilete",
"web services under your control" => "Vev tjenester under din kontroll",
"Authentication error" => "Feil i autentisering",
"Files" => "Filer",
diff --git a/lib/private/l10n/nqo.php b/lib/private/l10n/nqo.php
new file mode 100644
index 00000000000..e7b09649a24
--- /dev/null
+++ b/lib/private/l10n/nqo.php
@@ -0,0 +1,8 @@
+<?php
+$TRANSLATIONS = array(
+"_%n minute ago_::_%n minutes ago_" => array(""),
+"_%n hour ago_::_%n hours ago_" => array(""),
+"_%n day go_::_%n days ago_" => array(""),
+"_%n month ago_::_%n months ago_" => array("")
+);
+$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/lib/l10n/oc.php b/lib/private/l10n/oc.php
index 40a527cc76c..40a527cc76c 100644
--- a/lib/l10n/oc.php
+++ b/lib/private/l10n/oc.php
diff --git a/lib/private/l10n/pa.php b/lib/private/l10n/pa.php
new file mode 100644
index 00000000000..069fea6e710
--- /dev/null
+++ b/lib/private/l10n/pa.php
@@ -0,0 +1,16 @@
+<?php
+$TRANSLATIONS = array(
+"Settings" => "ਸੈਟਿੰਗ",
+"Files" => "ਫਾਇਲਾਂ",
+"seconds ago" => "ਸਕਿੰਟ ਪਹਿਲਾਂ",
+"_%n minute ago_::_%n minutes ago_" => array("",""),
+"_%n hour ago_::_%n hours ago_" => array("",""),
+"today" => "ਅੱਜ",
+"yesterday" => "ਕੱਲ੍ਹ",
+"_%n day go_::_%n days ago_" => array("",""),
+"last month" => "ਪਿਛਲੇ ਮਹੀਨੇ",
+"_%n month ago_::_%n months ago_" => array("",""),
+"last year" => "ਪਿਛਲੇ ਸਾਲ",
+"years ago" => "ਸਾਲਾਂ ਪਹਿਲਾਂ"
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/lib/l10n/pl.php b/lib/private/l10n/pl.php
index 4acd735d692..270559b4e50 100644
--- a/lib/l10n/pl.php
+++ b/lib/private/l10n/pl.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Użytkownicy",
"Admin" => "Administrator",
"Failed to upgrade \"%s\"." => "Błąd przy aktualizacji \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Domyślny profil zdjęć nie działa z szyfrowaniem jeszcze",
+"Unknown filetype" => "Nieznany typ pliku",
+"Invalid image" => "Błędne zdjęcie",
"web services under your control" => "Kontrolowane serwisy",
"cannot open \"%s\"" => "Nie można otworzyć \"%s\"",
"ZIP download is turned off." => "Pobieranie ZIP jest wyłączone.",
@@ -53,6 +56,7 @@ $TRANSLATIONS = array(
"Set an admin password." => "Ustaw hasło administratora.",
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serwer internetowy nie jest jeszcze poprawnie skonfigurowany, aby umożliwić synchronizację plików, ponieważ interfejs WebDAV wydaje się być uszkodzony.",
"Please double check the <a href='%s'>installation guides</a>." => "Sprawdź ponownie <a href='%s'>przewodniki instalacji</a>.",
+"Could not find category \"%s\"" => "Nie można odnaleźć kategorii \"%s\"",
"seconds ago" => "sekund temu",
"_%n minute ago_::_%n minutes ago_" => array("%n minute temu","%n minut temu","%n minut temu"),
"_%n hour ago_::_%n hours ago_" => array("%n godzinę temu","%n godzin temu","%n godzin temu"),
@@ -63,7 +67,6 @@ $TRANSLATIONS = array(
"_%n month ago_::_%n months ago_" => array("%n miesiąc temu","%n miesięcy temu","%n miesięcy temu"),
"last year" => "w zeszłym roku",
"years ago" => "lat temu",
-"Caused by:" => "Spowodowane przez:",
-"Could not find category \"%s\"" => "Nie można odnaleźć kategorii \"%s\""
+"Caused by:" => "Spowodowane przez:"
);
$PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/pl_PL.php b/lib/private/l10n/pl_PL.php
index 5494e3dab25..5494e3dab25 100644
--- a/lib/l10n/pl_PL.php
+++ b/lib/private/l10n/pl_PL.php
diff --git a/lib/l10n/pt_BR.php b/lib/private/l10n/pt_BR.php
index 72bc1f36a1e..7a580799701 100644
--- a/lib/l10n/pt_BR.php
+++ b/lib/private/l10n/pt_BR.php
@@ -8,6 +8,9 @@ $TRANSLATIONS = array(
"Users" => "Usuários",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Falha na atualização de \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Fotos de perfil personalizados ainda não funcionam com criptografia",
+"Unknown filetype" => "Tipo de arquivo desconhecido",
+"Invalid image" => "Imagem inválida",
"web services under your control" => "serviços web sob seu controle",
"cannot open \"%s\"" => "não pode abrir \"%s\"",
"ZIP download is turned off." => "Download ZIP está desligado.",
diff --git a/lib/l10n/pt_PT.php b/lib/private/l10n/pt_PT.php
index bf540012249..6e2bcba7b10 100644
--- a/lib/l10n/pt_PT.php
+++ b/lib/private/l10n/pt_PT.php
@@ -6,6 +6,8 @@ $TRANSLATIONS = array(
"Users" => "Utilizadores",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "A actualização \"%s\" falhou.",
+"Unknown filetype" => "Ficheiro desconhecido",
+"Invalid image" => "Imagem inválida",
"web services under your control" => "serviços web sob o seu controlo",
"cannot open \"%s\"" => "Não foi possível abrir \"%s\"",
"ZIP download is turned off." => "Descarregamento em ZIP está desligado.",
diff --git a/lib/l10n/ro.php b/lib/private/l10n/ro.php
index b338b349239..76dafcd03e0 100644
--- a/lib/l10n/ro.php
+++ b/lib/private/l10n/ro.php
@@ -5,6 +5,8 @@ $TRANSLATIONS = array(
"Settings" => "Setări",
"Users" => "Utilizatori",
"Admin" => "Admin",
+"Unknown filetype" => "Tip fișier necunoscut",
+"Invalid image" => "Imagine invalidă",
"web services under your control" => "servicii web controlate de tine",
"ZIP download is turned off." => "Descărcarea ZIP este dezactivată.",
"Files need to be downloaded one by one." => "Fișierele trebuie descărcate unul câte unul.",
@@ -19,11 +21,11 @@ $TRANSLATIONS = array(
"Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken." => "Serverul de web nu este încă setat corespunzător pentru a permite sincronizarea fișierelor deoarece interfața WebDAV pare a fi întreruptă.",
"Please double check the <a href='%s'>installation guides</a>." => "Vă rugăm să verificați <a href='%s'>ghiduri de instalare</a>.",
"seconds ago" => "secunde în urmă",
-"_%n minute ago_::_%n minutes ago_" => array("","",""),
-"_%n hour ago_::_%n hours ago_" => array("","",""),
+"_%n minute ago_::_%n minutes ago_" => array("","","acum %n minute"),
+"_%n hour ago_::_%n hours ago_" => array("","","acum %n ore"),
"today" => "astăzi",
"yesterday" => "ieri",
-"_%n day go_::_%n days ago_" => array("","",""),
+"_%n day go_::_%n days ago_" => array("","","acum %n zile"),
"last month" => "ultima lună",
"_%n month ago_::_%n months ago_" => array("","",""),
"last year" => "ultimul an",
diff --git a/lib/l10n/ru.php b/lib/private/l10n/ru.php
index c3b6a077b72..501065f8b5f 100644
--- a/lib/l10n/ru.php
+++ b/lib/private/l10n/ru.php
@@ -1,11 +1,16 @@
<?php
$TRANSLATIONS = array(
+"App \"%s\" can't be installed because it is not compatible with this version of ownCloud." => "Приложение \"%s\" нельзя установить, так как оно не совместимо с текущей версией ownCloud.",
+"No app name specified" => "Не выбрано имя приложения",
"Help" => "Помощь",
"Personal" => "Личное",
"Settings" => "Конфигурация",
"Users" => "Пользователи",
"Admin" => "Admin",
"Failed to upgrade \"%s\"." => "Не смог обновить \"%s\".",
+"Custom profile pictures don't work with encryption yet" => "Пользовательские картинки профиля ещё не поддерживают шифрование",
+"Unknown filetype" => "Неизвестный тип файла",
+"Invalid image" => "Изображение повреждено",
"web services under your control" => "веб-сервисы под вашим управлением",
"cannot open \"%s\"" => "не могу открыть \"%s\"",
"ZIP download is turned off." => "ZIP-скачивание отключено.",
@@ -13,6 +18,18 @@ $TRANSLATIONS = array(
"Back to Files" => "Назад к файлам",
"Selected files too large to generate zip file." => "Выбранные файлы слишком велики, чтобы создать zip файл.",
"Download the files in smaller chunks, seperately or kindly ask your administrator." => "Загрузите файл маленьшими порциями, раздельно или вежливо попросите Вашего администратора.",
+"No source specified when installing app" => "Не указан источник при установке приложения",
+"No href specified when installing app from http" => "Не указан атрибут href при установке приложения через http",
+"No path specified when installing app from local file" => "Не указан путь при установке приложения из локального файла",
+"Archives of type %s are not supported" => "Архивы %s не поддерживаются",
+"Failed to open archive when installing app" => "Не возможно открыть архив при установке приложения",
+"App does not provide an info.xml file" => "Приложение не имеет файла info.xml",
+"App can't be installed because of not allowed code in the App" => "Приложение невозможно установить. В нем содержится запрещенный код.",
+"App can't be installed because it is not compatible with this version of ownCloud" => "Приложение невозможно установить. Не совместимо с текущей версией ownCloud.",
+"App can't be installed because it contains the <shipped>true</shipped> tag which is not allowed for non shipped apps" => "Приложение невозможно установить. Оно содержит параметр <shipped>true</shipped> который не допустим для приложений, не входящих в поставку.",
+"App can't be installed because the version in info.xml/version is not the same as the version reported from the app store" => "Приложение невозможно установить. Версия в info.xml/version не совпадает с версией заявленной в магазине приложений",
+"App directory already exists" => "Папка приложения уже существует",
+"Can't create app folder. Please fix permissions. %s" => "Не удалось создать директорию. Исправьте права доступа. %s",
"Application is not enabled" => "Приложение не разрешено",
"Authentication error" => "Ошибка аутентификации",
"Token expired. Please reload page." => "Токен просрочен. Перезагрузите страницу.",
diff --git a/lib/l10n/si_LK.php b/lib/private/l10n/si_LK.php
index d10804cae69..d10804cae69 100644
--- a/lib/l10n/si_LK.php
+++ b/lib/private/l10n/si_LK.php
diff --git a/lib/l10n/sk.php b/lib/private/l10n/sk.php
index 54812b15a6f..54812b15a6f 100644
--- a/lib/l10n/sk.php
+++ b/lib/private/l10n/sk.php
diff --git a/lib/l10n/sk_SK.php b/lib/private/l10n/sk_SK.php
index 13487b039d6..13487b039d6 100644
--- a/lib/l10n/sk_SK.php
+++ b/lib/private/l10n/sk_SK.php
diff --git a/lib/l10n/sl.php b/lib/private/l10n/sl.php
index 5722191aedf..5722191aedf 100644
--- a/lib/l10n/sl.php
+++ b/lib/private/l10n/sl.php
diff --git a/lib/l10n/sq.php b/lib/private/l10n/sq.php
index edaa1df2b86..edaa1df2b86 100644
--- a/lib/l10n/sq.php
+++ b/lib/private/l10n/sq.php
diff --git a/lib/l10n/sr.php b/lib/private/l10n/sr.php
index 9441d0578fc..9441d0578fc 100644
--- a/lib/l10n/sr.php
+++ b/lib/private/l10n/sr.php
diff --git a/lib/l10n/sr@latin.php b/lib/private/l10n/sr@latin.php
index 5ba51bc0ba7..d8fa9289221 100644
--- a/lib/l10n/sr@latin.php
+++ b/lib/private/l10n/sr@latin.php
@@ -8,9 +8,15 @@ $TRANSLATIONS = array(
"Authentication error" => "Greška pri autentifikaciji",
"Files" => "Fajlovi",
"Text" => "Tekst",
+"seconds ago" => "Pre par sekundi",
"_%n minute ago_::_%n minutes ago_" => array("","",""),
"_%n hour ago_::_%n hours ago_" => array("","",""),
+"today" => "Danas",
+"yesterday" => "juče",
"_%n day go_::_%n days ago_" => array("","",""),
-"_%n month ago_::_%n months ago_" => array("","","")
+"last month" => "prošlog meseca",
+"_%n month ago_::_%n months ago_" => array("","",""),
+"last year" => "prošle godine",
+"years ago" => "pre nekoliko godina"
);
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/lib/l10n/string.php b/lib/private/l10n/string.php
index 88c85b32e70..88c85b32e70 100644
--- a/lib/l10n/string.php
+++ b/lib/private/l10n/string.php
diff --git a/lib/l10n/sv.php b/lib/private/l10n/sv.php
index e7c3420a85b..e7c3420a85b 100644
--- a/lib/l10n/sv.php
+++ b/lib/private/l10n/sv.php
diff --git a/lib/l10n/sw_KE.php b/lib/private/l10n/sw_KE.php
index 15f78e0bce6..15f78e0bce6 100644
--- a/lib/l10n/sw_KE.php
+++ b/lib/private/l10n/sw_KE.php
diff --git a/lib/l10n/ta_LK.php b/lib/private/l10n/ta_LK.php
index e70e65845be..e70e65845be 100644
--- a/lib/l10n/ta_LK.php
+++ b/lib/private/l10n/ta_LK.php
diff --git a/lib/l10n/te.php b/lib/private/l10n/te.php
index 524ea0c6024..524ea0c6024 100644
--- a/lib/l10n/te.php
+++ b/lib/private/l10n/te.php
diff --git a/lib/l10n/th_TH.php b/lib/private/l10n/th_TH.php
index 3344d0bb18e..3344d0bb18e 100644
--- a/lib/l10n/th_TH.php
+++ b/lib/private/l10n/th_TH.php
diff --git a/lib/l10n/tr.php b/lib/private/l10n/tr.php
index b63c37c7240..b63c37c7240 100644
--- a/lib/l10n/tr.php
+++ b/lib/private/l10n/tr.php
diff --git a/lib/l10n/ug.php b/lib/private/l10n/ug.php
index e2cf38ecc8c..e2cf38ecc8c 100644
--- a/lib/l10n/ug.php
+++ b/lib/private/l10n/ug.php
diff --git a/lib/l10n/uk.php b/lib/private/l10n/uk.php
index c1513c5bb79..c1513c5bb79 100644
--- a/lib/l10n/uk.php
+++ b/lib/private/l10n/uk.php
diff --git a/lib/l10n/ur_PK.php b/lib/private/l10n/ur_PK.php
index 7dc967ccd93..7dc967ccd93 100644
--- a/lib/l10n/ur_PK.php
+++ b/lib/private/l10n/ur_PK.php
diff --git a/lib/l10n/vi.php b/lib/private/l10n/vi.php
index dc0045c35ca..dc0045c35ca 100644
--- a/lib/l10n/vi.php
+++ b/lib/private/l10n/vi.php
diff --git a/lib/l10n/zh_CN.php b/lib/private/l10n/zh_CN.php
index 2c34356ea10..2c34356ea10 100644
--- a/lib/l10n/zh_CN.php
+++ b/lib/private/l10n/zh_CN.php
diff --git a/lib/l10n/zh_HK.php b/lib/private/l10n/zh_HK.php
index ca3e6d504e7..ca3e6d504e7 100644
--- a/lib/l10n/zh_HK.php
+++ b/lib/private/l10n/zh_HK.php
diff --git a/lib/l10n/zh_TW.php b/lib/private/l10n/zh_TW.php
index 210c766aa59..210c766aa59 100644
--- a/lib/l10n/zh_TW.php
+++ b/lib/private/l10n/zh_TW.php
diff --git a/lib/private/legacy/cache.php b/lib/private/legacy/cache.php
new file mode 100644
index 00000000000..f915eb516b1
--- /dev/null
+++ b/lib/private/legacy/cache.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net)
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+class OC_Cache extends \OC\Cache {
+} \ No newline at end of file
diff --git a/lib/legacy/config.php b/lib/private/legacy/config.php
index 7e498013737..7e498013737 100644
--- a/lib/legacy/config.php
+++ b/lib/private/legacy/config.php
diff --git a/lib/legacy/filesystem.php b/lib/private/legacy/filesystem.php
index 34f92b357ca..34f92b357ca 100644
--- a/lib/legacy/filesystem.php
+++ b/lib/private/legacy/filesystem.php
diff --git a/lib/legacy/filesystemview.php b/lib/private/legacy/filesystemview.php
index d6bca62e06a..d6bca62e06a 100644
--- a/lib/legacy/filesystemview.php
+++ b/lib/private/legacy/filesystemview.php
diff --git a/lib/legacy/log.php b/lib/private/legacy/log.php
index 027cb89e97c..027cb89e97c 100644
--- a/lib/legacy/log.php
+++ b/lib/private/legacy/log.php
diff --git a/lib/private/legacy/preferences.php b/lib/private/legacy/preferences.php
new file mode 100644
index 00000000000..a663db7598b
--- /dev/null
+++ b/lib/private/legacy/preferences.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Frank Karlitschek
+ * @author Jakob Sack
+ * @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/>.
+ *
+ */
+
+/**
+ * This class provides an easy way for storing user preferences.
+ */
+OC_Preferences::$object = new \OC\Preferences(OC_DB::getConnection());
+class OC_Preferences{
+ public static $object;
+ /**
+ * @brief Get all users using the preferences
+ * @return array with user ids
+ *
+ * This function returns a list of all users that have at least one entry
+ * in the preferences table.
+ */
+ public static function getUsers() {
+ return self::$object->getUsers();
+ }
+
+ /**
+ * @brief Get all apps of a user
+ * @param string $user user
+ * @return array with app ids
+ *
+ * This function returns a list of all apps of the user that have at least
+ * one entry in the preferences table.
+ */
+ public static function getApps( $user ) {
+ return self::$object->getApps( $user );
+ }
+
+ /**
+ * @brief Get the available keys for an app
+ * @param string $user user
+ * @param string $app the app we are looking for
+ * @return array with key names
+ *
+ * This function gets all keys of an app of an user. Please note that the
+ * values are not returned.
+ */
+ public static function getKeys( $user, $app ) {
+ return self::$object->getKeys( $user, $app );
+ }
+
+ /**
+ * @brief Gets the preference
+ * @param string $user user
+ * @param string $app app
+ * @param string $key key
+ * @param string $default = null, default value if the key does not exist
+ * @return string the value or $default
+ *
+ * This function gets a value from the preferences table. If the key does
+ * not exist the default value will be returned
+ */
+ public static function getValue( $user, $app, $key, $default = null ) {
+ return self::$object->getValue( $user, $app, $key, $default );
+ }
+
+ /**
+ * @brief sets a value in the preferences
+ * @param string $user user
+ * @param string $app app
+ * @param string $key key
+ * @param string $value value
+ * @return bool
+ *
+ * Adds a value to the preferences. If the key did not exist before, it
+ * will be added automagically.
+ */
+ public static function setValue( $user, $app, $key, $value ) {
+ self::$object->setValue( $user, $app, $key, $value );
+ return true;
+ }
+
+ /**
+ * @brief Deletes a key
+ * @param string $user user
+ * @param string $app app
+ * @param string $key key
+ *
+ * Deletes a key.
+ */
+ public static function deleteKey( $user, $app, $key ) {
+ self::$object->deleteKey( $user, $app, $key );
+ return true;
+ }
+
+ /**
+ * @brief Remove app of user from preferences
+ * @param string $user user
+ * @param string $app app
+ * @return bool
+ *
+ * Removes all keys in preferences belonging to the app and the user.
+ */
+ public static function deleteApp( $user, $app ) {
+ self::$object->deleteApp( $user, $app );
+ return true;
+ }
+
+ /**
+ * @brief Remove user from preferences
+ * @param string $user user
+ * @return bool
+ *
+ * Removes all keys in preferences belonging to the user.
+ */
+ public static function deleteUser( $user ) {
+ self::$object->deleteUser( $user );
+ return true;
+ }
+
+ /**
+ * @brief Remove app from all users
+ * @param string $app app
+ * @return bool
+ *
+ * Removes all keys in preferences belonging to the app.
+ */
+ public static function deleteAppFromAllUsers( $app ) {
+ self::$object->deleteAppFromAllUsers( $app );
+ return true;
+ }
+}
diff --git a/lib/legacy/updater.php b/lib/private/legacy/updater.php
index eea7bb129cf..eea7bb129cf 100644
--- a/lib/legacy/updater.php
+++ b/lib/private/legacy/updater.php
diff --git a/lib/log.php b/lib/private/log.php
index e0b9fe3c696..e0b9fe3c696 100644
--- a/lib/log.php
+++ b/lib/private/log.php
diff --git a/lib/log/errorhandler.php b/lib/private/log/errorhandler.php
index 69cb960de91..69cb960de91 100644
--- a/lib/log/errorhandler.php
+++ b/lib/private/log/errorhandler.php
diff --git a/lib/log/owncloud.php b/lib/private/log/owncloud.php
index d16b9537a16..d16b9537a16 100644
--- a/lib/log/owncloud.php
+++ b/lib/private/log/owncloud.php
diff --git a/lib/log/rotate.php b/lib/private/log/rotate.php
index bf23ad588b3..bf23ad588b3 100644
--- a/lib/log/rotate.php
+++ b/lib/private/log/rotate.php
diff --git a/lib/log/syslog.php b/lib/private/log/syslog.php
index c98deab7109..c98deab7109 100644
--- a/lib/log/syslog.php
+++ b/lib/private/log/syslog.php
diff --git a/lib/mail.php b/lib/private/mail.php
index b339b33e962..b339b33e962 100644
--- a/lib/mail.php
+++ b/lib/private/mail.php
diff --git a/lib/memcache/apc.php b/lib/private/memcache/apc.php
index 575ee4427db..575ee4427db 100644
--- a/lib/memcache/apc.php
+++ b/lib/private/memcache/apc.php
diff --git a/lib/memcache/apcu.php b/lib/private/memcache/apcu.php
index ccc1aa6e562..ccc1aa6e562 100644
--- a/lib/memcache/apcu.php
+++ b/lib/private/memcache/apcu.php
diff --git a/lib/memcache/cache.php b/lib/private/memcache/cache.php
index 0ad1cc7ec03..0ad1cc7ec03 100644
--- a/lib/memcache/cache.php
+++ b/lib/private/memcache/cache.php
diff --git a/lib/memcache/factory.php b/lib/private/memcache/factory.php
index fde7d947567..fde7d947567 100644
--- a/lib/memcache/factory.php
+++ b/lib/private/memcache/factory.php
diff --git a/lib/memcache/memcached.php b/lib/private/memcache/memcached.php
index 978e6c2eff1..978e6c2eff1 100644
--- a/lib/memcache/memcached.php
+++ b/lib/private/memcache/memcached.php
diff --git a/lib/memcache/xcache.php b/lib/private/memcache/xcache.php
index 33de30562f9..33de30562f9 100644
--- a/lib/memcache/xcache.php
+++ b/lib/private/memcache/xcache.php
diff --git a/lib/migrate.php b/lib/private/migrate.php
index 0b319177400..0b319177400 100644
--- a/lib/migrate.php
+++ b/lib/private/migrate.php
diff --git a/lib/migration/content.php b/lib/private/migration/content.php
index 2d8268a1d74..4413d722731 100644
--- a/lib/migration/content.php
+++ b/lib/private/migration/content.php
@@ -191,7 +191,8 @@ class OC_Migration_Content{
if( !file_exists( $dir ) ) {
return false;
}
- if ($dirhandle = opendir($dir)) {
+ $dirhandle = opendir($dir);
+ if(is_resource($dirhandle)) {
while (false !== ( $file = readdir($dirhandle))) {
if (( $file != '.' ) && ( $file != '..' )) {
diff --git a/lib/migration/provider.php b/lib/private/migration/provider.php
index 234ab3351f3..234ab3351f3 100644
--- a/lib/migration/provider.php
+++ b/lib/private/migration/provider.php
diff --git a/lib/mimetypes.list.php b/lib/private/mimetypes.list.php
index 8ab8ac81bd8..8ab8ac81bd8 100644
--- a/lib/mimetypes.list.php
+++ b/lib/private/mimetypes.list.php
diff --git a/lib/minimizer.php b/lib/private/minimizer.php
index db522de74dc..db522de74dc 100644
--- a/lib/minimizer.php
+++ b/lib/private/minimizer.php
diff --git a/lib/minimizer/css.php b/lib/private/minimizer/css.php
index 8d130572e2b..8d130572e2b 100644
--- a/lib/minimizer/css.php
+++ b/lib/private/minimizer/css.php
diff --git a/lib/minimizer/js.php b/lib/private/minimizer/js.php
index bd2d836deb0..bd2d836deb0 100644
--- a/lib/minimizer/js.php
+++ b/lib/private/minimizer/js.php
diff --git a/lib/private/navigationmanager.php b/lib/private/navigationmanager.php
new file mode 100644
index 00000000000..1f657b9ad80
--- /dev/null
+++ b/lib/private/navigationmanager.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OC;
+
+/**
+ * Manages the ownCloud navigation
+ */
+class NavigationManager implements \OCP\INavigationManager {
+ protected $entries = array();
+ protected $activeEntry;
+
+ /**
+ * Creates a new navigation entry
+ * @param array $entry containing: id, name, order, icon and href key
+ */
+ public function add(array $entry) {
+ $entry['active'] = false;
+ if(!isset($entry['icon'])) {
+ $entry['icon'] = '';
+ }
+ $this->entries[] = $entry;
+ }
+
+ /**
+ * @brief returns all the added Menu entries
+ * @return array of the added entries
+ */
+ public function getAll() {
+ return $this->entries;
+ }
+
+ /**
+ * @brief removes all the entries
+ */
+ public function clear() {
+ $this->entries = array();
+ }
+
+ /**
+ * Sets the current navigation entry of the currently running app
+ * @param string $id of the app entry to activate (from added $entry)
+ */
+ public function setActiveEntry($id) {
+ $this->activeEntry = $id;
+ }
+
+ /**
+ * @brief gets the active Menu entry
+ * @return string id or empty string
+ *
+ * This function returns the id of the active navigation entry (set by
+ * setActiveEntry
+ */
+ public function getActiveEntry() {
+ return $this->activeEntry;
+ }
+}
diff --git a/lib/private/notsquareexception.php b/lib/private/notsquareexception.php
new file mode 100644
index 00000000000..03dba8fb25f
--- /dev/null
+++ b/lib/private/notsquareexception.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright (c) 2013 Christopher Schäpers <christopher@schaepers.it>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC;
+
+class NotSquareException extends \Exception {
+}
diff --git a/lib/ocs.php b/lib/private/ocs.php
index 93e8931ce2e..93e8931ce2e 100644
--- a/lib/ocs.php
+++ b/lib/private/ocs.php
diff --git a/lib/ocs/cloud.php b/lib/private/ocs/cloud.php
index 2dd99319057..2dd99319057 100644
--- a/lib/ocs/cloud.php
+++ b/lib/private/ocs/cloud.php
diff --git a/lib/ocs/config.php b/lib/private/ocs/config.php
index f19121f4b2b..f19121f4b2b 100644
--- a/lib/ocs/config.php
+++ b/lib/private/ocs/config.php
diff --git a/lib/ocs/person.php b/lib/private/ocs/person.php
index 1c8210d0825..1c8210d0825 100644
--- a/lib/ocs/person.php
+++ b/lib/private/ocs/person.php
diff --git a/lib/ocs/privatedata.php b/lib/private/ocs/privatedata.php
index 4dfd0a6e66e..4dfd0a6e66e 100644
--- a/lib/ocs/privatedata.php
+++ b/lib/private/ocs/privatedata.php
diff --git a/lib/ocs/result.php b/lib/private/ocs/result.php
index 84f06fa01c7..84f06fa01c7 100644
--- a/lib/ocs/result.php
+++ b/lib/private/ocs/result.php
diff --git a/lib/ocsclient.php b/lib/private/ocsclient.php
index 58636f806be..e35556d92b8 100644
--- a/lib/ocsclient.php
+++ b/lib/private/ocsclient.php
@@ -36,7 +36,12 @@ class OC_OCSClient{
* to set it in the config file or it will fallback to the default
*/
private static function getAppStoreURL() {
- $url = OC_Config::getValue('appstoreurl', 'http://api.apps.owncloud.com/v1');
+ if(OC_Util::getEditionString()===''){
+ $default='http://api.apps.owncloud.com/v1';
+ }else{
+ $default='';
+ }
+ $url = OC_Config::getValue('appstoreurl', $default);
return($url);
}
diff --git a/lib/preferences.php b/lib/private/preferences.php
index 11ca760830e..359d9a83589 100644
--- a/lib/preferences.php
+++ b/lib/private/preferences.php
@@ -34,10 +34,21 @@
*
*/
+namespace OC;
+
+use \OC\DB\Connection;
+
+
/**
* This class provides an easy way for storing user preferences.
*/
-class OC_Preferences{
+class Preferences {
+ protected $conn;
+
+ public function __construct(Connection $conn) {
+ $this->conn = $conn;
+ }
+
/**
* @brief Get all users using the preferences
* @return array with user ids
@@ -45,14 +56,13 @@ class OC_Preferences{
* This function returns a list of all users that have at least one entry
* in the preferences table.
*/
- public static function getUsers() {
- // No need for more comments
- $query = OC_DB::prepare( 'SELECT DISTINCT( `userid` ) FROM `*PREFIX*preferences`' );
- $result = $query->execute();
+ public function getUsers() {
+ $query = 'SELECT DISTINCT `userid` FROM `*PREFIX*preferences`';
+ $result = $this->conn->executeQuery( $query );
$users = array();
- while( $row = $result->fetchRow()) {
- $users[] = $row["userid"];
+ while( $userid = $result->fetchColumn()) {
+ $users[] = $userid;
}
return $users;
@@ -66,14 +76,13 @@ class OC_Preferences{
* This function returns a list of all apps of the user that have at least
* one entry in the preferences table.
*/
- public static function getApps( $user ) {
- // No need for more comments
- $query = OC_DB::prepare( 'SELECT DISTINCT( `appid` ) FROM `*PREFIX*preferences` WHERE `userid` = ?' );
- $result = $query->execute( array( $user ));
+ public function getApps( $user ) {
+ $query = 'SELECT DISTINCT `appid` FROM `*PREFIX*preferences` WHERE `userid` = ?';
+ $result = $this->conn->executeQuery( $query, array( $user ) );
$apps = array();
- while( $row = $result->fetchRow()) {
- $apps[] = $row["appid"];
+ while( $appid = $result->fetchColumn()) {
+ $apps[] = $appid;
}
return $apps;
@@ -88,14 +97,13 @@ class OC_Preferences{
* This function gets all keys of an app of an user. Please note that the
* values are not returned.
*/
- public static function getKeys( $user, $app ) {
- // No need for more comments
- $query = OC_DB::prepare( 'SELECT `configkey` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ?' );
- $result = $query->execute( array( $user, $app ));
+ public function getKeys( $user, $app ) {
+ $query = 'SELECT `configkey` FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ?';
+ $result = $this->conn->executeQuery( $query, array( $user, $app ));
$keys = array();
- while( $row = $result->fetchRow()) {
- $keys[] = $row["configkey"];
+ while( $key = $result->fetchColumn()) {
+ $keys[] = $key;
}
return $keys;
@@ -112,16 +120,14 @@ class OC_Preferences{
* This function gets a value from the preferences table. If the key does
* not exist the default value will be returned
*/
- public static function getValue( $user, $app, $key, $default = null ) {
+ public function getValue( $user, $app, $key, $default = null ) {
// Try to fetch the value, return default if not exists.
- $query = OC_DB::prepare( 'SELECT `configvalue` FROM `*PREFIX*preferences`'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $result = $query->execute( array( $user, $app, $key ));
-
- $row = $result->fetchRow();
+ $query = 'SELECT `configvalue` FROM `*PREFIX*preferences`'
+ .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
+ $row = $this->conn->fetchAssoc( $query, array( $user, $app, $key ));
if($row) {
return $row["configvalue"];
- }else{
+ } else {
return $default;
}
}
@@ -132,29 +138,36 @@ class OC_Preferences{
* @param string $app app
* @param string $key key
* @param string $value value
- * @return bool
*
* Adds a value to the preferences. If the key did not exist before, it
* will be added automagically.
*/
- public static function setValue( $user, $app, $key, $value ) {
+ public function setValue( $user, $app, $key, $value ) {
// Check if the key does exist
- $query = OC_DB::prepare( 'SELECT `configvalue` FROM `*PREFIX*preferences`'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $values=$query->execute(array($user, $app, $key))->fetchAll();
- $exists=(count($values)>0);
+ $query = 'SELECT COUNT(*) FROM `*PREFIX*preferences`'
+ .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?';
+ $count = $this->conn->fetchColumn( $query, array( $user, $app, $key ));
+ $exists = $count > 0;
if( !$exists ) {
- $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*preferences`'
- .' ( `userid`, `appid`, `configkey`, `configvalue` ) VALUES( ?, ?, ?, ? )' );
- $query->execute( array( $user, $app, $key, $value ));
+ $data = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ 'configkey' => $key,
+ 'configvalue' => $value,
+ );
+ $this->conn->insert('*PREFIX*preferences', $data);
+ } else {
+ $data = array(
+ 'configvalue' => $value,
+ );
+ $where = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ 'configkey' => $key,
+ );
+ $this->conn->update('*PREFIX*preferences', $data, $where);
}
- else{
- $query = OC_DB::prepare( 'UPDATE `*PREFIX*preferences` SET `configvalue` = ?'
- .' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ?' );
- $query->execute( array( $value, $user, $app, $key ));
- }
- return true;
}
/**
@@ -162,62 +175,58 @@ class OC_Preferences{
* @param string $user user
* @param string $app app
* @param string $key key
- * @return bool
*
* Deletes a key.
*/
- 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` = ?' );
- $query->execute( array( $user, $app, $key ));
-
- return true;
+ public function deleteKey( $user, $app, $key ) {
+ $where = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ 'configkey' => $key,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
/**
* @brief Remove app of user from preferences
* @param string $user user
* @param string $app app
- * @return bool
*
- * Removes all keys in appconfig belonging to the app and the user.
+ * Removes all keys in preferences belonging to the app and the user.
*/
- public static function deleteApp( $user, $app ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences` WHERE `userid` = ? AND `appid` = ?' );
- $query->execute( array( $user, $app ));
-
- return true;
+ public function deleteApp( $user, $app ) {
+ $where = array(
+ 'userid' => $user,
+ 'appid' => $app,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
/**
* @brief Remove user from preferences
* @param string $user user
- * @return bool
*
- * Removes all keys in appconfig belonging to the user.
+ * Removes all keys in preferences belonging to the user.
*/
- public static function deleteUser( $user ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences` WHERE `userid` = ?' );
- $query->execute( array( $user ));
-
- return true;
+ public function deleteUser( $user ) {
+ $where = array(
+ 'userid' => $user,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
/**
* @brief Remove app from all users
* @param string $app app
- * @return bool
*
* Removes all keys in preferences belonging to the app.
*/
- public static function deleteAppFromAllUsers( $app ) {
- // No need for more comments
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*preferences` WHERE `appid` = ?' );
- $query->execute( array( $app ));
-
- return true;
+ public function deleteAppFromAllUsers( $app ) {
+ $where = array(
+ 'appid' => $app,
+ );
+ $this->conn->delete('*PREFIX*preferences', $where);
}
}
+
+require_once __DIR__.'/legacy/'.basename(__FILE__);
diff --git a/lib/preview.php b/lib/private/preview.php
index b40ba191fba..266f7795f12 100755
--- a/lib/preview.php
+++ b/lib/private/preview.php
@@ -42,6 +42,9 @@ class Preview {
private $scalingup;
//preview images object
+ /**
+ * @var \OC_Image
+ */
private $preview;
//preview providers
@@ -624,4 +627,4 @@ class Preview {
}
return false;
}
-} \ No newline at end of file
+}
diff --git a/lib/preview/image.php b/lib/private/preview/image.php
index 9aec967282d..9aec967282d 100644
--- a/lib/preview/image.php
+++ b/lib/private/preview/image.php
diff --git a/lib/preview/movies.php b/lib/private/preview/movies.php
index c318137ff0e..c318137ff0e 100644
--- a/lib/preview/movies.php
+++ b/lib/private/preview/movies.php
diff --git a/lib/preview/mp3.php b/lib/private/preview/mp3.php
index 1eed566315c..1eed566315c 100644
--- a/lib/preview/mp3.php
+++ b/lib/private/preview/mp3.php
diff --git a/lib/preview/office-cl.php b/lib/private/preview/office-cl.php
index 112909d6523..112909d6523 100644
--- a/lib/preview/office-cl.php
+++ b/lib/private/preview/office-cl.php
diff --git a/lib/preview/office-fallback.php b/lib/private/preview/office-fallback.php
index e69ab0ab8cb..e69ab0ab8cb 100644
--- a/lib/preview/office-fallback.php
+++ b/lib/private/preview/office-fallback.php
diff --git a/lib/preview/office.php b/lib/private/preview/office.php
index 5287bbd6ac1..5287bbd6ac1 100644
--- a/lib/preview/office.php
+++ b/lib/private/preview/office.php
diff --git a/lib/preview/pdf.php b/lib/private/preview/pdf.php
index cc974b68818..cc974b68818 100644
--- a/lib/preview/pdf.php
+++ b/lib/private/preview/pdf.php
diff --git a/lib/preview/provider.php b/lib/private/preview/provider.php
index e4a730bafc8..e4a730bafc8 100644
--- a/lib/preview/provider.php
+++ b/lib/private/preview/provider.php
diff --git a/lib/preview/svg.php b/lib/private/preview/svg.php
index b49e51720fa..b49e51720fa 100644
--- a/lib/preview/svg.php
+++ b/lib/private/preview/svg.php
diff --git a/lib/preview/txt.php b/lib/private/preview/txt.php
index a487330691e..77e728eb364 100644
--- a/lib/preview/txt.php
+++ b/lib/private/preview/txt.php
@@ -9,11 +9,21 @@ namespace OC\Preview;
class TXT extends Provider {
+ private static $blacklist = array(
+ 'text/calendar',
+ 'text/vcard',
+ );
+
public function getMimeType() {
return '/text\/.*/';
}
public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
+ $mimetype = $fileview->getMimeType($path);
+ if(in_array($mimetype, self::$blacklist)) {
+ return false;
+ }
+
$content = $fileview->fopen($path, 'r');
$content = stream_get_contents($content);
diff --git a/lib/preview/unknown.php b/lib/private/preview/unknown.php
index 9e6cd68d401..9e6cd68d401 100644
--- a/lib/preview/unknown.php
+++ b/lib/private/preview/unknown.php
diff --git a/lib/private/previewmanager.php b/lib/private/previewmanager.php
new file mode 100755
index 00000000000..ac9a866a75b
--- /dev/null
+++ b/lib/private/previewmanager.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Müller thomas.mueller@tmit.eu
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+namespace OC;
+
+use OCP\image;
+use OCP\IPreview;
+
+class PreviewManager implements IPreview {
+ /**
+ * @brief return a preview of a file
+ * @param string $file The path to the file where you want a thumbnail from
+ * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image
+ * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
+ * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly
+ * @return \OCP\Image
+ */
+ function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false)
+ {
+ $preview = new \OC\Preview('', '/', $file, $maxX, $maxY, $scaleUp);
+ return $preview->getPreview();
+ }
+
+ /**
+ * @brief returns true if the passed mime type is supported
+ * @param string $mimeType
+ * @return boolean
+ */
+ function isMimeSupported($mimeType = '*')
+ {
+ return \OC\Preview::isMimeSupported($mimeType);
+ }
+}
diff --git a/lib/request.php b/lib/private/request.php
index df33217f95d..df33217f95d 100755
--- a/lib/request.php
+++ b/lib/private/request.php
diff --git a/lib/response.php b/lib/private/response.php
index 674176d078b..674176d078b 100644
--- a/lib/response.php
+++ b/lib/private/response.php
diff --git a/lib/route.php b/lib/private/route.php
index 5901717c094..5901717c094 100644
--- a/lib/route.php
+++ b/lib/private/route.php
diff --git a/lib/router.php b/lib/private/router.php
index dbaca9e0d5d..dbaca9e0d5d 100644
--- a/lib/router.php
+++ b/lib/private/router.php
diff --git a/lib/search.php b/lib/private/search.php
index b9c75dfc333..b9c75dfc333 100644
--- a/lib/search.php
+++ b/lib/private/search.php
diff --git a/lib/search/provider.php b/lib/private/search/provider.php
index b617b9c5d94..b617b9c5d94 100644
--- a/lib/search/provider.php
+++ b/lib/private/search/provider.php
diff --git a/lib/search/provider/file.php b/lib/private/search/provider/file.php
index 4d88c2a87f1..9bd50931517 100644
--- a/lib/search/provider/file.php
+++ b/lib/private/search/provider/file.php
@@ -10,6 +10,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{
$mime = $fileData['mimetype'];
$name = basename($path);
+ $container = dirname($path);
$text = '';
$skip = false;
if($mime=='httpd/unix-directory') {
@@ -37,7 +38,7 @@ class OC_Search_Provider_File extends OC_Search_Provider{
}
}
if(!$skip) {
- $results[] = new OC_Search_Result($name, $text, $link, $type);
+ $results[] = new OC_Search_Result($name, $text, $link, $type, $container);
}
}
return $results;
diff --git a/lib/search/result.php b/lib/private/search/result.php
index 08beaea151c..42275c2df11 100644
--- a/lib/search/result.php
+++ b/lib/private/search/result.php
@@ -7,6 +7,7 @@ class OC_Search_Result{
public $text;
public $link;
public $type;
+ public $container;
/**
* create a new search result
@@ -15,10 +16,11 @@ class OC_Search_Result{
* @param string $link link for the result
* @param string $type the type of result as human readable string ('File', 'Music', etc)
*/
- public function __construct($name, $text, $link, $type) {
+ public function __construct($name, $text, $link, $type, $container) {
$this->name=$name;
$this->text=$text;
$this->link=$link;
$this->type=$type;
+ $this->container=$container;
}
}
diff --git a/lib/private/server.php b/lib/private/server.php
new file mode 100644
index 00000000000..cabb15324ec
--- /dev/null
+++ b/lib/private/server.php
@@ -0,0 +1,255 @@
+<?php
+
+namespace OC;
+
+use OC\AppFramework\Http\Request;
+use OC\AppFramework\Utility\SimpleContainer;
+use OC\Cache\UserCache;
+use OC\Files\Node\Root;
+use OC\Files\View;
+use OCP\IServerContainer;
+
+/**
+ * Class Server
+ * @package OC
+ *
+ * TODO: hookup all manager classes
+ */
+class Server extends SimpleContainer implements IServerContainer {
+
+ function __construct() {
+ $this->registerService('ContactsManager', function($c) {
+ return new ContactsManager();
+ });
+ $this->registerService('Request', function($c) {
+ $params = array();
+
+ // we json decode the body only in case of content type json
+ if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'],'json') !== false ) {
+ $params = json_decode(file_get_contents('php://input'), true);
+ $params = is_array($params) ? $params: array();
+ }
+
+ return new Request(
+ array(
+ 'get' => $_GET,
+ 'post' => $_POST,
+ 'files' => $_FILES,
+ 'server' => $_SERVER,
+ 'env' => $_ENV,
+ 'cookies' => $_COOKIE,
+ 'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD']))
+ ? $_SERVER['REQUEST_METHOD']
+ : null,
+ 'params' => $params,
+ 'urlParams' => $c['urlParams']
+ )
+ );
+ });
+ $this->registerService('PreviewManager', function($c) {
+ return new PreviewManager();
+ });
+ $this->registerService('TagManager', function($c) {
+ $user = \OC_User::getUser();
+ return new TagManager($user);
+ });
+ $this->registerService('RootFolder', function($c) {
+ // TODO: get user and user manager from container as well
+ $user = \OC_User::getUser();
+ /** @var $c SimpleContainer */
+ $userManager = $c->query('UserManager');
+ $user = $userManager->get($user);
+ $manager = \OC\Files\Filesystem::getMountManager();
+ $view = new View();
+ return new Root($manager, $view, $user);
+ });
+ $this->registerService('UserManager', function($c) {
+ return new \OC\User\Manager();
+ });
+ $this->registerService('UserSession', function($c) {
+ /** @var $c SimpleContainer */
+ $manager = $c->query('UserManager');
+ $userSession = new \OC\User\Session($manager, \OC::$session);
+ $userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
+ \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'preDelete', function ($user) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
+ });
+ $userSession->listen('\OC\User', 'postDelete', function ($user) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
+ });
+ $userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
+ });
+ $userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
+ });
+ $userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
+ \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
+ /** @var $user \OC\User\User */
+ \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
+ });
+ $userSession->listen('\OC\User', 'logout', function () {
+ \OC_Hook::emit('OC_User', 'logout', array());
+ });
+ return $userSession;
+ });
+ $this->registerService('NavigationManager', function($c) {
+ return new \OC\NavigationManager();
+ });
+ $this->registerService('AllConfig', function($c) {
+ return new \OC\AllConfig();
+ });
+ $this->registerService('UserCache', function($c) {
+ return new UserCache();
+ });
+ }
+
+ /**
+ * @return \OCP\Contacts\IManager
+ */
+ function getContactsManager() {
+ return $this->query('ContactsManager');
+ }
+
+ /**
+ * The current request object holding all information about the request
+ * currently being processed is returned from this method.
+ * In case the current execution was not initiated by a web request null is returned
+ *
+ * @return \OCP\IRequest|null
+ */
+ function getRequest() {
+ return $this->query('Request');
+ }
+
+ /**
+ * Returns the preview manager which can create preview images for a given file
+ *
+ * @return \OCP\IPreview
+ */
+ function getPreviewManager() {
+ return $this->query('PreviewManager');
+ }
+
+ /**
+ * Returns the tag manager which can get and set tags for different object types
+ *
+ * @see \OCP\ITagManager::load()
+ * @return \OCP\ITagManager
+ */
+ function getTagManager() {
+ return $this->query('TagManager');
+ }
+
+ /**
+ * Returns the root folder of ownCloud's data directory
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getRootFolder() {
+ return $this->query('RootFolder');
+ }
+
+ /**
+ * Returns a view to ownCloud's files folder
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getUserFolder() {
+
+ $dir = '/files';
+ $root = $this->getRootFolder();
+ $folder = null;
+ if(!$root->nodeExists($dir)) {
+ $folder = $root->newFolder($dir);
+ } else {
+ $folder = $root->get($dir);
+ }
+ return $folder;
+ }
+
+ /**
+ * Returns an app-specific view in ownClouds data directory
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getAppFolder() {
+
+ $dir = '/' . \OC_App::getCurrentApp();
+ $root = $this->getRootFolder();
+ $folder = null;
+ if(!$root->nodeExists($dir)) {
+ $folder = $root->newFolder($dir);
+ } else {
+ $folder = $root->get($dir);
+ }
+ return $folder;
+ }
+
+ /**
+ * @return \OC\User\Manager
+ */
+ function getUserManager() {
+ return $this->query('UserManager');
+ }
+
+ /**
+ * @return \OC\User\Session
+ */
+ function getUserSession() {
+ return $this->query('UserSession');
+ }
+
+ /**
+ * @return \OC\NavigationManager
+ */
+ function getNavigationManager() {
+ return $this->query('NavigationManager');
+ }
+
+ /**
+ * @return \OC\Config
+ */
+ function getConfig() {
+ return $this->query('AllConfig');
+ }
+
+ /**
+ * Returns an ICache instance
+ *
+ * @return \OCP\ICache
+ */
+ function getCache() {
+ return $this->query('UserCache');
+ }
+
+ /**
+ * Returns the current session
+ *
+ * @return \OCP\ISession
+ */
+ function getSession() {
+ return \OC::$session;
+ }
+
+ /**
+ * Returns the current session
+ *
+ * @return \OCP\IDBConnection
+ */
+ function getDatabaseConnection() {
+ return \OC_DB::getConnection();
+ }
+}
diff --git a/lib/session/internal.php b/lib/private/session/internal.php
index 60aecccc8aa..60aecccc8aa 100644
--- a/lib/session/internal.php
+++ b/lib/private/session/internal.php
diff --git a/lib/session/memory.php b/lib/private/session/memory.php
index c148ff4b9b9..c148ff4b9b9 100644
--- a/lib/session/memory.php
+++ b/lib/private/session/memory.php
diff --git a/lib/session/session.php b/lib/private/session/session.php
index 55515f57a87..c55001eccac 100644
--- a/lib/session/session.php
+++ b/lib/private/session/session.php
@@ -8,7 +8,7 @@
namespace OC\Session;
-abstract class Session implements \ArrayAccess {
+abstract class Session implements \ArrayAccess, \OCP\ISession {
/**
* $name serves as a namespace for the session keys
*
diff --git a/lib/setup.php b/lib/private/setup.php
index 6bf3c88370f..6bf3c88370f 100644
--- a/lib/setup.php
+++ b/lib/private/setup.php
diff --git a/lib/setup/abstractdatabase.php b/lib/private/setup/abstractdatabase.php
index 0beada7bd29..0beada7bd29 100644
--- a/lib/setup/abstractdatabase.php
+++ b/lib/private/setup/abstractdatabase.php
diff --git a/lib/setup/mssql.php b/lib/private/setup/mssql.php
index b8329f99079..b8329f99079 100644
--- a/lib/setup/mssql.php
+++ b/lib/private/setup/mssql.php
diff --git a/lib/setup/mysql.php b/lib/private/setup/mysql.php
index d97b6d2602f..d97b6d2602f 100644
--- a/lib/setup/mysql.php
+++ b/lib/private/setup/mysql.php
diff --git a/lib/setup/oci.php b/lib/private/setup/oci.php
index 326d7a00531..326d7a00531 100644
--- a/lib/setup/oci.php
+++ b/lib/private/setup/oci.php
diff --git a/lib/setup/postgresql.php b/lib/private/setup/postgresql.php
index 89d328ada19..89d328ada19 100644
--- a/lib/setup/postgresql.php
+++ b/lib/private/setup/postgresql.php
diff --git a/lib/setup/sqlite.php b/lib/private/setup/sqlite.php
index fd4df792d62..fd4df792d62 100644
--- a/lib/setup/sqlite.php
+++ b/lib/private/setup/sqlite.php
diff --git a/lib/subadmin.php b/lib/private/subadmin.php
index 8cda7240ac9..8cda7240ac9 100644
--- a/lib/subadmin.php
+++ b/lib/private/subadmin.php
diff --git a/lib/private/tagmanager.php b/lib/private/tagmanager.php
new file mode 100644
index 00000000000..9a371a11253
--- /dev/null
+++ b/lib/private/tagmanager.php
@@ -0,0 +1,68 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2013 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/>.
+*
+*/
+
+/**
+ * Factory class creating instances of \OCP\ITags
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+namespace OC;
+
+class TagManager implements \OCP\ITagManager {
+
+ /**
+ * User
+ *
+ * @var string
+ */
+ private $user = null;
+
+ /**
+ * Constructor.
+ *
+ * @param string $user The user whos data the object will operate on.
+ */
+ public function __construct($user) {
+
+ $this->user = $user;
+
+ }
+
+ /**
+ * Create a new \OCP\ITags instance and load tags from db.
+ *
+ * @see \OCP\ITags
+ * @param string $type The type identifier e.g. 'contact' or 'event'.
+ * @param array $defaultTags An array of default tags to be used if none are stored.
+ * @return \OCP\ITags
+ */
+ public function load($type, $defaultTags=array()) {
+ return new Tags($this->user, $type, $defaultTags);
+ }
+
+} \ No newline at end of file
diff --git a/lib/private/tags.php b/lib/private/tags.php
new file mode 100644
index 00000000000..9fdb35a7d6e
--- /dev/null
+++ b/lib/private/tags.php
@@ -0,0 +1,642 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2012-2013 Thomas Tanghus <thomas@tanghus.net>
+* @copyright 2012 Bart Visscher bartv@thisnet.nl
+*
+* 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 for easily tagging objects by their id
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+namespace OC;
+
+class Tags implements \OCP\ITags {
+
+ /**
+ * Tags
+ *
+ * @var array
+ */
+ private $tags = array();
+
+ /**
+ * Used for storing objectid/categoryname pairs while rescanning.
+ *
+ * @var array
+ */
+ private static $relations = array();
+
+ /**
+ * Type
+ *
+ * @var string
+ */
+ private $type = null;
+
+ /**
+ * User
+ *
+ * @var string
+ */
+ private $user = null;
+
+ const TAG_TABLE = '*PREFIX*vcategory';
+ const RELATION_TABLE = '*PREFIX*vcategory_to_object';
+
+ const TAG_FAVORITE = '_$!<Favorite>!$_';
+
+ /**
+ * Constructor.
+ *
+ * @param string $user The user whos data the object will operate on.
+ */
+ public function __construct($user, $type, $defaultTags = array()) {
+ $this->user = $user;
+ $this->type = $type;
+ $this->loadTags($defaultTags);
+ }
+
+ /**
+ * Load tags from db.
+ *
+ * @param string $type The type identifier e.g. 'contact' or 'event'.
+ * @param array $defaultTags An array of default tags to be used if none are stored.
+ */
+ protected function loadTags($defaultTags=array()) {
+ $this->tags = array();
+ $result = null;
+ $sql = 'SELECT `id`, `category` FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`';
+ try {
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($this->user, $this->type));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+
+ if(!is_null($result)) {
+ while( $row = $result->fetchRow()) {
+ $this->tags[$row['id']] = $row['category'];
+ }
+ }
+
+ if(count($defaultTags) > 0 && count($this->tags) === 0) {
+ $this->addMultiple($defaultTags, true);
+ }
+ \OCP\Util::writeLog('core', __METHOD__.', tags: ' . print_r($this->tags, true),
+ \OCP\Util::DEBUG);
+
+ }
+
+ /**
+ * Check if any tags are saved for this type and user.
+ *
+ * @return boolean.
+ */
+ public function isEmpty() {
+ $sql = 'SELECT COUNT(*) FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ? AND `type` = ?';
+ try {
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($this->user, $this->type));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ return ((int)$result->fetchOne() === 0);
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ }
+
+ /**
+ * Get the tags for a specific user.
+ *
+ * This returns an array with id/name maps:
+ * [
+ * ['id' => 0, 'name' = 'First tag'],
+ * ['id' => 1, 'name' = 'Second tag'],
+ * ]
+ *
+ * @return array
+ */
+ public function getTags() {
+ if(!count($this->tags)) {
+ return array();
+ }
+
+ $tags = array_values($this->tags);
+ uasort($tags, 'strnatcasecmp');
+ $tagMap = array();
+
+ foreach($tags as $tag) {
+ if($tag !== self::TAG_FAVORITE) {
+ $tagMap[] = array(
+ 'id' => $this->array_searchi($tag, $this->tags),
+ 'name' => $tag
+ );
+ }
+ }
+ return $tagMap;
+
+ }
+
+ /**
+ * Get the a list if items tagged with $tag.
+ *
+ * Throws an exception if the tag could not be found.
+ *
+ * @param string|integer $tag Tag id or name.
+ * @return array An array of object ids or false on error.
+ */
+ public function getIdsForTag($tag) {
+ $result = null;
+ if(is_numeric($tag)) {
+ $tagId = $tag;
+ } elseif(is_string($tag)) {
+ $tag = trim($tag);
+ $tagId = $this->array_searchi($tag, $this->tags);
+ }
+
+ if($tagId === false) {
+ $l10n = \OC_L10N::get('core');
+ throw new \Exception(
+ $l10n->t('Could not find category "%s"', $tag)
+ );
+ }
+
+ $ids = array();
+ $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
+ . '` WHERE `categoryid` = ?';
+
+ try {
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($tagId));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+
+ if(!is_null($result)) {
+ while( $row = $result->fetchRow()) {
+ $ids[] = (int)$row['objid'];
+ }
+ }
+
+ return $ids;
+ }
+
+ /**
+ * Checks whether a tag is already saved.
+ *
+ * @param string $name The name to check for.
+ * @return bool
+ */
+ public function hasTag($name) {
+ return $this->in_arrayi($name, $this->tags);
+ }
+
+ /**
+ * Add a new tag.
+ *
+ * @param string $name A string with a name of the tag
+ * @return int the id of the added tag or false if it already exists.
+ */
+ public function add($name) {
+ $name = trim($name);
+
+ if($this->hasTag($name)) {
+ \OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', \OCP\Util::DEBUG);
+ return false;
+ }
+ try {
+ $result = \OCP\DB::insertIfNotExist(
+ self::TAG_TABLE,
+ array(
+ 'uid' => $this->user,
+ 'type' => $this->type,
+ 'category' => $name,
+ )
+ );
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ } elseif((int)$result === 0) {
+ \OCP\Util::writeLog('core', __METHOD__.', Tag already exists: ' . $name, \OCP\Util::DEBUG);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ $id = \OCP\DB::insertid(self::TAG_TABLE);
+ \OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, \OCP\Util::DEBUG);
+ $this->tags[$id] = $name;
+ return $id;
+ }
+
+ /**
+ * Rename tag.
+ *
+ * @param string $from The name of the existing tag
+ * @param string $to The new name of the tag.
+ * @return bool
+ */
+ public function rename($from, $to) {
+ $from = trim($from);
+ $to = trim($to);
+ $id = $this->array_searchi($from, $this->tags);
+ if($id === false) {
+ \OCP\Util::writeLog('core', __METHOD__.', tag: ' . $from. ' does not exist', \OCP\Util::DEBUG);
+ return false;
+ }
+
+ $sql = 'UPDATE `' . self::TAG_TABLE . '` SET `category` = ? '
+ . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?';
+ try {
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($to, $this->user, $this->type, $id));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ $this->tags[$id] = $to;
+ return true;
+ }
+
+ /**
+ * Add a list of new tags.
+ *
+ * @param string[] $names A string with a name or an array of strings containing
+ * the name(s) of the to add.
+ * @param bool $sync When true, save the tags
+ * @param int|null $id int Optional object id to add to this|these tag(s)
+ * @return bool Returns false on error.
+ */
+ public function addMultiple($names, $sync=false, $id = null) {
+ if(!is_array($names)) {
+ $names = array($names);
+ }
+ $names = array_map('trim', $names);
+ $newones = array();
+ foreach($names as $name) {
+ if(($this->in_arrayi(
+ $name, $this->tags) == false) && $name !== '') {
+ $newones[] = $name;
+ }
+ if(!is_null($id) ) {
+ // Insert $objectid, $categoryid pairs if not exist.
+ self::$relations[] = array('objid' => $id, 'tag' => $name);
+ }
+ }
+ $this->tags = array_merge($this->tags, $newones);
+ if($sync === true) {
+ $this->save();
+ }
+
+ return true;
+ }
+
+ /**
+ * Save the list of tags and their object relations
+ */
+ protected function save() {
+ if(is_array($this->tags)) {
+ foreach($this->tags as $tag) {
+ try {
+ \OCP\DB::insertIfNotExist(self::TAG_TABLE,
+ array(
+ 'uid' => $this->user,
+ 'type' => $this->type,
+ 'category' => $tag,
+ ));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ // reload tags to get the proper ids.
+ $this->loadTags();
+ // Loop through temporarily cached objectid/tagname pairs
+ // and save relations.
+ $tags = $this->tags;
+ // For some reason this is needed or array_search(i) will return 0..?
+ ksort($tags);
+ foreach(self::$relations as $relation) {
+ $tagId = $this->array_searchi($relation['tag'], $tags);
+ \OCP\Util::writeLog('core', __METHOD__ . 'catid, ' . $relation['tag'] . ' ' . $tagId, \OCP\Util::DEBUG);
+ if($tagId) {
+ try {
+ \OCP\DB::insertIfNotExist(self::RELATION_TABLE,
+ array(
+ 'objid' => $relation['objid'],
+ 'categoryid' => $tagId,
+ 'type' => $this->type,
+ ));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ }
+ self::$relations = array(); // reset
+ } else {
+ \OCP\Util::writeLog('core', __METHOD__.', $this->tags is not an array! '
+ . print_r($this->tags, true), \OCP\Util::ERROR);
+ }
+ }
+
+ /**
+ * Delete tags and tag/object relations for a user.
+ *
+ * For hooking up on post_deleteUser
+ *
+ * @param array
+ */
+ public static function post_deleteUser($arguments) {
+ // Find all objectid/tagId pairs.
+ $result = null;
+ try {
+ $stmt = \OCP\DB::prepare('SELECT `id` FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ?');
+ $result = $stmt->execute(array($arguments['uid']));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+
+ if(!is_null($result)) {
+ try {
+ $stmt = \OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
+ . 'WHERE `categoryid` = ?');
+ while( $row = $result->fetchRow()) {
+ try {
+ $stmt->execute(array($row['id']));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ }
+ }
+ try {
+ $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` '
+ . 'WHERE `uid` = ?');
+ $result = $stmt->execute(array($arguments['uid']));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. ', DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__ . ', exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ }
+ }
+
+ /**
+ * Delete tag/object relations from the db
+ *
+ * @param array $ids The ids of the objects
+ * @return boolean Returns false on error.
+ */
+ public function purgeObjects(array $ids) {
+ if(count($ids) === 0) {
+ // job done ;)
+ return true;
+ }
+ $updates = $ids;
+ try {
+ $query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
+ $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
+ $query .= 'AND `type`= ?';
+ $updates[] = $this->type;
+ $stmt = \OCP\DB::prepare($query);
+ $result = $stmt->execute($updates);
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get favorites for an object type
+ *
+ * @return array An array of object ids.
+ */
+ public function getFavorites() {
+ try {
+ return $this->getIdsForTag(self::TAG_FAVORITE);
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(),
+ \OCP\Util::ERROR);
+ return array();
+ }
+ }
+
+ /**
+ * Add an object to favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function addToFavorites($objid) {
+ if(!$this->hasTag(self::TAG_FAVORITE)) {
+ $this->add(self::TAG_FAVORITE, true);
+ }
+ return $this->tagAs($objid, self::TAG_FAVORITE, $this->type);
+ }
+
+ /**
+ * Remove an object from favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function removeFromFavorites($objid) {
+ return $this->unTag($objid, self::TAG_FAVORITE, $this->type);
+ }
+
+ /**
+ * Creates a tag/object relation.
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean Returns false on database error.
+ */
+ public function tagAs($objid, $tag) {
+ if(is_string($tag) && !is_numeric($tag)) {
+ $tag = trim($tag);
+ if(!$this->hasTag($tag)) {
+ $this->add($tag, true);
+ }
+ $tagId = $this->array_searchi($tag, $this->tags);
+ } else {
+ $tagId = $tag;
+ }
+ try {
+ \OCP\DB::insertIfNotExist(self::RELATION_TABLE,
+ array(
+ 'objid' => $objid,
+ 'categoryid' => $tagId,
+ 'type' => $this->type,
+ ));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Delete single tag/object relation from the db
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean
+ */
+ public function unTag($objid, $tag) {
+ if(is_string($tag) && !is_numeric($tag)) {
+ $tag = trim($tag);
+ $tagId = $this->array_searchi($tag, $this->tags);
+ } else {
+ $tagId = $tag;
+ }
+
+ try {
+ $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
+ . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
+ $stmt = \OCP\DB::prepare($sql);
+ $stmt->execute(array($objid, $tagId, $this->type));
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Delete tags from the
+ *
+ * @param string[] $names An array of tags to delete
+ * @return bool Returns false on error
+ */
+ public function delete($names) {
+ if(!is_array($names)) {
+ $names = array($names);
+ }
+
+ $names = array_map('trim', $names);
+
+ \OCP\Util::writeLog('core', __METHOD__ . ', before: '
+ . print_r($this->tags, true), \OCP\Util::DEBUG);
+ foreach($names as $name) {
+ $id = null;
+
+ if($this->hasTag($name)) {
+ $id = $this->array_searchi($name, $this->tags);
+ unset($this->tags[$id]);
+ }
+ try {
+ $stmt = \OCP\DB::prepare('DELETE FROM `' . self::TAG_TABLE . '` WHERE '
+ . '`uid` = ? AND `type` = ? AND `category` = ?');
+ $result = $stmt->execute(array($this->user, $this->type, $name));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core', __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result), \OCP\Util::ERROR);
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__ . ', exception: '
+ . $e->getMessage(), \OCP\Util::ERROR);
+ return false;
+ }
+ if(!is_null($id) && $id !== false) {
+ try {
+ $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
+ . 'WHERE `categoryid` = ?';
+ $stmt = \OCP\DB::prepare($sql);
+ $result = $stmt->execute(array($id));
+ if (\OCP\DB::isError($result)) {
+ \OCP\Util::writeLog('core',
+ __METHOD__. 'DB error: ' . \OCP\DB::getErrorMessage($result),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ } catch(\Exception $e) {
+ \OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
+ \OCP\Util::ERROR);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ // case-insensitive in_array
+ private function in_arrayi($needle, $haystack) {
+ if(!is_array($haystack)) {
+ return false;
+ }
+ return in_array(strtolower($needle), array_map('strtolower', $haystack));
+ }
+
+ // case-insensitive array_search
+ private function array_searchi($needle, $haystack) {
+ if(!is_array($haystack)) {
+ return false;
+ }
+ return array_search(strtolower($needle), array_map('strtolower', $haystack));
+ }
+}
diff --git a/lib/template.php b/lib/private/template.php
index 9b2c1211e61..9b2c1211e61 100644
--- a/lib/template.php
+++ b/lib/private/template.php
diff --git a/lib/template/base.php b/lib/private/template/base.php
index 88941bc7132..88941bc7132 100644
--- a/lib/template/base.php
+++ b/lib/private/template/base.php
diff --git a/lib/template/cssresourcelocator.php b/lib/private/template/cssresourcelocator.php
index 8e7831ca549..8e7831ca549 100644
--- a/lib/template/cssresourcelocator.php
+++ b/lib/private/template/cssresourcelocator.php
diff --git a/lib/template/functions.php b/lib/private/template/functions.php
index 501f8081bff..501f8081bff 100644
--- a/lib/template/functions.php
+++ b/lib/private/template/functions.php
diff --git a/lib/template/jsresourcelocator.php b/lib/private/template/jsresourcelocator.php
index f8fe3817ce6..f8fe3817ce6 100644
--- a/lib/template/jsresourcelocator.php
+++ b/lib/private/template/jsresourcelocator.php
diff --git a/lib/template/resourcelocator.php b/lib/private/template/resourcelocator.php
index 9f83673664d..9f83673664d 100644
--- a/lib/template/resourcelocator.php
+++ b/lib/private/template/resourcelocator.php
diff --git a/lib/template/templatefilelocator.php b/lib/private/template/templatefilelocator.php
index d5a484b1a14..d5a484b1a14 100644
--- a/lib/template/templatefilelocator.php
+++ b/lib/private/template/templatefilelocator.php
diff --git a/lib/templatelayout.php b/lib/private/templatelayout.php
index 0b868a39e49..625f3424a04 100644
--- a/lib/templatelayout.php
+++ b/lib/private/templatelayout.php
@@ -46,6 +46,7 @@ class OC_TemplateLayout extends OC_Template {
$user_displayname = OC_User::getDisplayName();
$this->assign( 'user_displayname', $user_displayname );
$this->assign( 'user_uid', OC_User::getUser() );
+ $this->assign('enableAvatars', \OC_Config::getValue('enable_avatars', true));
} else if ($renderas == 'guest' || $renderas == 'error') {
parent::__construct('core', 'layout.guest');
} else {
diff --git a/lib/updater.php b/lib/private/updater.php
index df7332a96a9..9827d8a8c12 100644
--- a/lib/updater.php
+++ b/lib/private/updater.php
@@ -56,7 +56,7 @@ class Updater extends BasicEmitter {
$version = \OC_Util::getVersion();
$version['installed'] = \OC_Appconfig::getValue('core', 'installedat');
$version['updated'] = \OC_Appconfig::getValue('core', 'lastupdatedat');
- $version['updatechannel'] = 'stable';
+ $version['updatechannel'] = \OC_Util::getChannel();
$version['edition'] = \OC_Util::getEditionString();
$versionString = implode('x', $version);
diff --git a/lib/user.php b/lib/private/user.php
index 0f6f40aec9a..15e807088b4 100644
--- a/lib/user.php
+++ b/lib/private/user.php
@@ -37,54 +37,15 @@
* logout()
*/
class OC_User {
- public static $userSession = null;
-
public static function getUserSession() {
- if (!self::$userSession) {
- $manager = new \OC\User\Manager();
- self::$userSession = new \OC\User\Session($manager, \OC::$session);
- self::$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
- \OC_Hook::emit('OC_User', 'pre_createUser', array('run' => true, 'uid' => $uid, 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'postCreateUser', function ($user, $password) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_createUser', array('uid' => $user->getUID(), 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'preDelete', function ($user) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'pre_deleteUser', array('run' => true, 'uid' => $user->getUID()));
- });
- self::$userSession->listen('\OC\User', 'postDelete', function ($user) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_deleteUser', array('uid' => $user->getUID()));
- });
- self::$userSession->listen('\OC\User', 'preSetPassword', function ($user, $password, $recoveryPassword) {
- /** @var $user \OC\User\User */
- OC_Hook::emit('OC_User', 'pre_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
- });
- self::$userSession->listen('\OC\User', 'postSetPassword', function ($user, $password, $recoveryPassword) {
- /** @var $user \OC\User\User */
- OC_Hook::emit('OC_User', 'post_setPassword', array('run' => true, 'uid' => $user->getUID(), 'password' => $password, 'recoveryPassword' => $recoveryPassword));
- });
- self::$userSession->listen('\OC\User', 'preLogin', function ($uid, $password) {
- \OC_Hook::emit('OC_User', 'pre_login', array('run' => true, 'uid' => $uid, 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'postLogin', function ($user, $password) {
- /** @var $user \OC\User\User */
- \OC_Hook::emit('OC_User', 'post_login', array('run' => true, 'uid' => $user->getUID(), 'password' => $password));
- });
- self::$userSession->listen('\OC\User', 'logout', function () {
- \OC_Hook::emit('OC_User', 'logout', array());
- });
- }
- return self::$userSession;
+ return OC::$server->getUserSession();
}
/**
* @return \OC\User\Manager
*/
public static function getManager() {
- return self::getUserSession()->getManager();
+ return OC::$server->getUserManager();
}
private static $_backends = array();
@@ -177,6 +138,7 @@ class OC_User {
* setup the configured backends in config.php
*/
public static function setupBackends() {
+ OC_App::loadApps(array('prelogin'));
$backends = OC_Config::getValue('user_backends', array());
foreach ($backends as $i => $config) {
$class = $config['class'];
@@ -410,22 +372,18 @@ class OC_User {
* @brief Check if the password is correct
* @param string $uid The username
* @param string $password The password
- * @return bool
+ * @return mixed user id a string on success, false otherwise
*
* Check if the password is correct without logging in the user
* returns the user id or false
*/
public static function checkPassword($uid, $password) {
- $user = self::getManager()->get($uid);
- if ($user) {
- if ($user->checkPassword($password)) {
- return $user->getUID();
- } else {
- return false;
- }
- } else {
- return false;
+ $manager = self::getManager();
+ $username = $manager->checkPassword($uid, $password);
+ if ($username !== false) {
+ return $username->getUID();
}
+ return false;
}
/**
diff --git a/lib/user/backend.php b/lib/private/user/backend.php
index e9be08e429c..e9be08e429c 100644
--- a/lib/user/backend.php
+++ b/lib/private/user/backend.php
diff --git a/lib/user/database.php b/lib/private/user/database.php
index 9f00a022d9f..9f00a022d9f 100644
--- a/lib/user/database.php
+++ b/lib/private/user/database.php
diff --git a/lib/user/dummy.php b/lib/private/user/dummy.php
index b5b7a6c3c7a..b5b7a6c3c7a 100644
--- a/lib/user/dummy.php
+++ b/lib/private/user/dummy.php
diff --git a/lib/user/example.php b/lib/private/user/example.php
index b2d0dc25410..b2d0dc25410 100644
--- a/lib/user/example.php
+++ b/lib/private/user/example.php
diff --git a/lib/user/http.php b/lib/private/user/http.php
index 1e044ed4188..e99afe59ba7 100644
--- a/lib/user/http.php
+++ b/lib/private/user/http.php
@@ -79,7 +79,11 @@ class OC_User_HTTP extends OC_User_Backend {
curl_close($ch);
- return $status==200;
+ if($status === 200) {
+ return $uid;
+ }
+
+ return false;
}
/**
diff --git a/lib/user/interface.php b/lib/private/user/interface.php
index c72bdfaf3fd..c72bdfaf3fd 100644
--- a/lib/user/interface.php
+++ b/lib/private/user/interface.php
diff --git a/lib/user/manager.php b/lib/private/user/manager.php
index 8dc9bfe2729..13286bc28a4 100644
--- a/lib/user/manager.php
+++ b/lib/private/user/manager.php
@@ -119,6 +119,25 @@ class Manager extends PublicEmitter {
}
/**
+ * Check if the password is valid for the user
+ *
+ * @param $loginname
+ * @param $password
+ * @return mixed the User object on success, false otherwise
+ */
+ public function checkPassword($loginname, $password) {
+ foreach ($this->backends as $backend) {
+ if($backend->implementsActions(\OC_USER_BACKEND_CHECK_PASSWORD)) {
+ $uid = $backend->checkPassword($loginname, $password);
+ if ($uid !== false) {
+ return $this->getUserObject($uid, $backend);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* search by user id
*
* @param string $pattern
diff --git a/lib/user/session.php b/lib/private/user/session.php
index 9a6c669e935..525c65ab8a1 100644
--- a/lib/user/session.php
+++ b/lib/private/user/session.php
@@ -27,7 +27,7 @@ use OC\Hooks\Emitter;
*
* @package OC\User
*/
-class Session implements Emitter {
+class Session implements Emitter, \OCP\IUserSession {
/**
* @var \OC\User\Manager $manager
*/
@@ -121,15 +121,16 @@ class Session implements Emitter {
*/
public function login($uid, $password) {
$this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
- $user = $this->manager->get($uid);
- if ($user) {
- $result = $user->checkPassword($password);
- if ($result and $user->isEnabled()) {
- $this->setUser($user);
- $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
- return true;
- } else {
- return false;
+ $user = $this->manager->checkPassword($uid, $password);
+ if($user !== false) {
+ if (!is_null($user)) {
+ if ($user->isEnabled()) {
+ $this->setUser($user);
+ $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
+ return true;
+ } else {
+ return false;
+ }
}
} else {
return false;
diff --git a/lib/user/user.php b/lib/private/user/user.php
index 8115c43198c..e5f842944f1 100644
--- a/lib/user/user.php
+++ b/lib/private/user/user.php
@@ -106,24 +106,6 @@ class User {
}
/**
- * Check if the password is valid for the user
- *
- * @param $password
- * @return bool
- */
- public function checkPassword($password) {
- if ($this->backend->implementsActions(\OC_USER_BACKEND_CHECK_PASSWORD)) {
- $result = $this->backend->checkPassword($this->uid, $password);
- if ($result !== false) {
- $this->uid = $result;
- }
- return !($result === false);
- } else {
- return false;
- }
- }
-
- /**
* Set the password of the user
*
* @param string $password
diff --git a/lib/util.php b/lib/private/util.php
index e8e3bc37e5f..43d1d393da7 100755
--- a/lib/util.php
+++ b/lib/private/util.php
@@ -106,9 +106,8 @@ class OC_Util {
* @return array
*/
public static function getVersion() {
- // hint: We only can count up. Reset minor/patchlevel when
- // updating major/minor version number.
- return array(5, 80, 07);
+ OC_Util::loadVersion();
+ return \OC::$server->getSession()->get('OC_Version');
}
/**
@@ -116,7 +115,8 @@ class OC_Util {
* @return string
*/
public static function getVersionString() {
- return '6.0 pre alpha';
+ OC_Util::loadVersion();
+ return \OC::$server->getSession()->get('OC_VersionString');
}
/**
@@ -126,7 +126,46 @@ class OC_Util {
* @return string
*/
public static function getEditionString() {
- return '';
+ OC_Util::loadVersion();
+ return \OC::$server->getSession()->get('OC_Edition');
+ }
+
+ /**
+ * @description get the update channel of the current installed of ownCloud.
+ * @return string
+ */
+ public static function getChannel() {
+ OC_Util::loadVersion();
+ return \OC::$server->getSession()->get('OC_Channel');
+ }
+
+ /**
+ * @description get the build number of the current installed of ownCloud.
+ * @return string
+ */
+ public static function getBuild() {
+ OC_Util::loadVersion();
+ return \OC::$server->getSession()->get('OC_Build');
+ }
+
+ /**
+ * @description load the version.php into the session as cache
+ */
+ private static function loadVersion() {
+ if(!\OC::$server->getSession()->exists('OC_Version')) {
+ require 'version.php';
+ $session = \OC::$server->getSession();
+ /** @var $OC_Version string */
+ $session->set('OC_Version', $OC_Version);
+ /** @var $OC_VersionString string */
+ $session->set('OC_VersionString', $OC_VersionString);
+ /** @var $OC_Edition string */
+ $session->set('OC_Edition', $OC_Edition);
+ /** @var $OC_Channel string */
+ $session->set('OC_Channel', $OC_Channel);
+ /** @var $OC_Build string */
+ $session->set('OC_Build', $OC_Build);
+ }
}
/**
@@ -410,14 +449,18 @@ class OC_Util {
$encryptedFiles = false;
if (OC_App::isEnabled('files_encryption') === false) {
$view = new OC\Files\View('/' . OCP\User::getUser());
- if ($view->file_exists('/files_encryption/keyfiles')) {
- $encryptedFiles = true;
+ $keyfilePath = '/files_encryption/keyfiles';
+ if ($view->is_dir($keyfilePath)) {
+ $dircontent = $view->getDirectoryContent($keyfilePath);
+ if (!empty($dircontent)) {
+ $encryptedFiles = true;
+ }
}
}
-
+
return $encryptedFiles;
}
-
+
/**
* @brief Check for correct file permissions of data directory
* @paran string $dataDirectory
@@ -467,6 +510,7 @@ class OC_Util {
}
$parameters['alt_login'] = OC_App::getAlternativeLogIns();
+ $parameters['rememberLoginAllowed'] = self::rememberLoginAllowed();
OC_Template::printGuestPage("", "login", $parameters);
}
@@ -509,6 +553,27 @@ class OC_Util {
}
/**
+ * Check if it is allowed to remember login.
+ *
+ * @note Every app can set 'rememberlogin' to 'false' to disable the remember login feature
+ *
+ * @return bool
+ */
+ public static function rememberLoginAllowed() {
+
+ $apps = OC_App::getEnabledApps();
+
+ foreach ($apps as $app) {
+ $appInfo = OC_App::getAppInfo($app);
+ if (isset($appInfo['rememberlogin']) && $appInfo['rememberlogin'] === 'false') {
+ return false;
+ }
+
+ }
+ return true;
+ }
+
+ /**
* @brief Check if the user is a subadmin, redirects to home if not
* @return array $groups where the current user is subadmin
*/
@@ -552,7 +617,7 @@ class OC_Util {
if(is_null($id)) {
// We need to guarantee at least one letter in instanceid so it can be used as the session_name
$id = 'oc' . self::generateRandomBytes(10);
- OC_Config::setValue('instanceid', $id);
+ OC_Config::$object->setValue('instanceid', $id);
}
return $id;
}
@@ -654,16 +719,16 @@ class OC_Util {
}
return $value;
}
-
+
/**
* @brief Public function to encode url parameters
*
* This function is used to encode path to file before output.
* Encoding is done according to RFC 3986 with one exception:
- * Character '/' is preserved as is.
+ * Character '/' is preserved as is.
*
* @param string $component part of URI to encode
- * @return string
+ * @return string
*/
public static function encodePath($component) {
$encoded = rawurlencode($component);
@@ -734,12 +799,6 @@ class OC_Util {
'baseUri' => OC_Helper::linkToRemote('webdav'),
);
- // save the old timeout so that we can restore it later
- $oldTimeout = ini_get("default_socket_timeout");
-
- // use a 5 sec timeout for the check. Should be enough for local requests.
- ini_set("default_socket_timeout", 5);
-
$client = new \Sabre_DAV_Client($settings);
// for this self test we don't care if the ssl certificate is self signed and the peer cannot be verified.
@@ -756,9 +815,6 @@ class OC_Util {
$return = false;
}
- // restore the original timeout
- ini_set("default_socket_timeout", $oldTimeout);
-
return $return;
}
@@ -814,7 +870,7 @@ class OC_Util {
}
}
}
-
+
/**
* @brief Check if the connection to the internet is disabled on purpose
* @return bool
diff --git a/lib/vobject.php b/lib/private/vobject.php
index 267176ebc07..267176ebc07 100644
--- a/lib/vobject.php
+++ b/lib/private/vobject.php
diff --git a/lib/vobject/compoundproperty.php b/lib/private/vobject/compoundproperty.php
index 7fe42574bed..7fe42574bed 100644
--- a/lib/vobject/compoundproperty.php
+++ b/lib/private/vobject/compoundproperty.php
diff --git a/lib/vobject/stringproperty.php b/lib/private/vobject/stringproperty.php
index a9d63a0a789..a9d63a0a789 100644
--- a/lib/vobject/stringproperty.php
+++ b/lib/private/vobject/stringproperty.php
diff --git a/lib/public/app.php b/lib/public/app.php
index a1ecf524cc8..0a5721b334e 100644
--- a/lib/public/app.php
+++ b/lib/public/app.php
@@ -35,10 +35,10 @@ namespace OCP;
*/
class App {
/**
- * @brief Makes owncloud aware of this 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
+ * @returns boolean
*
* @deprecated this method is deprecated
* Do not call it anymore
@@ -52,7 +52,7 @@ class App {
/**
* @brief adds an entry to the navigation
* @param $data array containing the data
- * @returns true/false
+ * @returns boolean
*
* This function adds a new entry to the navigation visible to users. $data
* is an associative array.
@@ -72,8 +72,8 @@ class App {
/**
* @brief marks a navigation entry as active
- * @param $id id of the entry
- * @returns true/false
+ * @param $id string id of the entry
+ * @returns boolean
*
* This function sets a navigation entry as active and removes the 'active'
* property from all other entries. The templates can use this for
@@ -104,7 +104,7 @@ class App {
/**
* @brief Read app metadata from the info.xml file
* @param string $app id of the app or the path of the info.xml file
- * @param boolean path (optional)
+ * @param boolean $path (optional)
* @returns array
*/
public static function getAppInfo( $app, $path=false ) {
@@ -114,7 +114,7 @@ class App {
/**
* @brief checks whether or not an app is enabled
* @param $app app
- * @returns true/false
+ * @returns boolean
*
* This function checks whether or not an app is enabled.
*/
@@ -133,7 +133,7 @@ class App {
/**
* @brief Get the last version of the app, either from appinfo/version or from appinfo/info.xml
* @param $app app
- * @returns true/false
+ * @returns boolean
*/
public static function getAppVersion( $app ) {
return \OC_App::getAppVersion( $app );
diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php
new file mode 100644
index 00000000000..d97c5c81848
--- /dev/null
+++ b/lib/public/appframework/app.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller deepdiver@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 OCP\AppFramework;
+
+
+/**
+ * Class App
+ * @package OCP\AppFramework
+ *
+ * Any application must inherit this call - all controller instances to be used are
+ * to be registered using IContainer::registerService
+ */
+class App {
+ public function __construct($appName) {
+ $this->container = new \OC\AppFramework\DependencyInjection\DIContainer($appName);
+ }
+
+ private $container;
+
+ /**
+ * @return IAppContainer
+ */
+ public function getContainer() {
+ return $this->container;
+ }
+
+ /**
+ * This function is called by the routing component to fire up the frameworks dispatch mechanism.
+ *
+ * Example code in routes.php of the task app:
+ * $this->create('tasks_index', '/')->get()->action(
+ * function($params){
+ * $app = new TaskApp();
+ * $app->dispatch('PageController', 'index', $params);
+ * }
+ * );
+ *
+ *
+ * Example for for TaskApp implementation:
+ * class TaskApp extends \OCP\AppFramework\App {
+ *
+ * public function __construct(){
+ * parent::__construct('tasks');
+ *
+ * $this->getContainer()->registerService('PageController', function(IAppContainer $c){
+ * $a = $c->query('API');
+ * $r = $c->query('Request');
+ * return new PageController($a, $r);
+ * });
+ * }
+ * }
+ *
+ * @param string $controllerName the name of the controller under which it is
+ * stored in the DI container
+ * @param string $methodName the method that you want to call
+ * @param array $urlParams an array with variables extracted from the routes
+ */
+ public function dispatch($controllerName, $methodName, array $urlParams) {
+ \OC\AppFramework\App::main($controllerName, $methodName, $urlParams, $this->container);
+ }
+}
diff --git a/lib/public/appframework/http/http.php b/lib/public/appframework/http/http.php
new file mode 100644
index 00000000000..9eafe782726
--- /dev/null
+++ b/lib/public/appframework/http/http.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCP\AppFramework\Http;
+
+
+class Http {
+
+ const STATUS_CONTINUE = 100;
+ const STATUS_SWITCHING_PROTOCOLS = 101;
+ const STATUS_PROCESSING = 102;
+ const STATUS_OK = 200;
+ const STATUS_CREATED = 201;
+ const STATUS_ACCEPTED = 202;
+ const STATUS_NON_AUTHORATIVE_INFORMATION = 203;
+ const STATUS_NO_CONTENT = 204;
+ const STATUS_RESET_CONTENT = 205;
+ const STATUS_PARTIAL_CONTENT = 206;
+ const STATUS_MULTI_STATUS = 207;
+ const STATUS_ALREADY_REPORTED = 208;
+ const STATUS_IM_USED = 226;
+ const STATUS_MULTIPLE_CHOICES = 300;
+ const STATUS_MOVED_PERMANENTLY = 301;
+ const STATUS_FOUND = 302;
+ const STATUS_SEE_OTHER = 303;
+ const STATUS_NOT_MODIFIED = 304;
+ const STATUS_USE_PROXY = 305;
+ const STATUS_RESERVED = 306;
+ const STATUS_TEMPORARY_REDIRECT = 307;
+ const STATUS_BAD_REQUEST = 400;
+ const STATUS_UNAUTHORIZED = 401;
+ const STATUS_PAYMENT_REQUIRED = 402;
+ const STATUS_FORBIDDEN = 403;
+ const STATUS_NOT_FOUND = 404;
+ const STATUS_METHOD_NOT_ALLOWED = 405;
+ const STATUS_NOT_ACCEPTABLE = 406;
+ const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407;
+ const STATUS_REQUEST_TIMEOUT = 408;
+ const STATUS_CONFLICT = 409;
+ const STATUS_GONE = 410;
+ const STATUS_LENGTH_REQUIRED = 411;
+ const STATUS_PRECONDITION_FAILED = 412;
+ const STATUS_REQUEST_ENTITY_TOO_LARGE = 413;
+ const STATUS_REQUEST_URI_TOO_LONG = 414;
+ const STATUS_UNSUPPORTED_MEDIA_TYPE = 415;
+ const STATUS_REQUEST_RANGE_NOT_SATISFIABLE = 416;
+ const STATUS_EXPECTATION_FAILED = 417;
+ const STATUS_IM_A_TEAPOT = 418;
+ const STATUS_UNPROCESSABLE_ENTITY = 422;
+ const STATUS_LOCKED = 423;
+ const STATUS_FAILED_DEPENDENCY = 424;
+ const STATUS_UPGRADE_REQUIRED = 426;
+ const STATUS_PRECONDITION_REQUIRED = 428;
+ const STATUS_TOO_MANY_REQUESTS = 429;
+ const STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
+ const STATUS_INTERNAL_SERVER_ERROR = 500;
+ const STATUS_NOT_IMPLEMENTED = 501;
+ const STATUS_BAD_GATEWAY = 502;
+ const STATUS_SERVICE_UNAVAILABLE = 503;
+ const STATUS_GATEWAY_TIMEOUT = 504;
+ const STATUS_HTTP_VERSION_NOT_SUPPORTED = 505;
+ const STATUS_VARIANT_ALSO_NEGOTIATES = 506;
+ const STATUS_INSUFFICIENT_STORAGE = 507;
+ const STATUS_LOOP_DETECTED = 508;
+ const STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509;
+ const STATUS_NOT_EXTENDED = 510;
+ const STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511;
+}
diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php
new file mode 100644
index 00000000000..085fdbed2f9
--- /dev/null
+++ b/lib/public/appframework/http/jsonresponse.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCP\AppFramework\Http;
+
+
+/**
+ * A renderer for JSON calls
+ */
+class JSONResponse extends Response {
+
+ protected $data;
+
+
+ /**
+ * @param array|object $data the object or array that should be transformed
+ * @param int $statusCode the Http status code, defaults to 200
+ */
+ public function __construct($data=array(), $statusCode=Http::STATUS_OK) {
+ $this->data = $data;
+ $this->setStatus($statusCode);
+ $this->addHeader('X-Content-Type-Options', 'nosniff');
+ $this->addHeader('Content-type', 'application/json; charset=utf-8');
+ }
+
+
+ /**
+ * Returns the rendered json
+ * @return string the rendered json
+ */
+ public function render(){
+ return json_encode($this->data);
+ }
+
+ /**
+ * Sets values in the data json array
+ * @param array|object $params an array or object which will be transformed
+ * to JSON
+ */
+ public function setData($data){
+ $this->data = $data;
+ }
+
+
+ /**
+ * Used to get the set parameters
+ * @return array the data
+ */
+ public function getData(){
+ return $this->data;
+ }
+
+}
diff --git a/lib/public/appframework/http/response.php b/lib/public/appframework/http/response.php
new file mode 100644
index 00000000000..64477258948
--- /dev/null
+++ b/lib/public/appframework/http/response.php
@@ -0,0 +1,169 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCP\AppFramework\Http;
+
+
+/**
+ * Base class for responses. Also used to just send headers
+ */
+class Response {
+
+ /**
+ * @var array default headers
+ */
+ private $headers = array(
+ 'Cache-Control' => 'no-cache, must-revalidate'
+ );
+
+
+ /**
+ * @var string
+ */
+ private $status = Http::STATUS_OK;
+
+
+ /**
+ * @var \DateTime
+ */
+ private $lastModified;
+
+
+ /**
+ * @var string
+ */
+ private $ETag;
+
+
+ /**
+ * Caches the response
+ * @param int $cacheSeconds the amount of seconds that should be cached
+ * if 0 then caching will be disabled
+ */
+ public function cacheFor($cacheSeconds) {
+
+ if($cacheSeconds > 0) {
+ $this->addHeader('Cache-Control', 'max-age=' . $cacheSeconds .
+ ', must-revalidate');
+ } else {
+ $this->addHeader('Cache-Control', 'no-cache, must-revalidate');
+ }
+
+ }
+
+
+ /**
+ * Adds a new header to the response that will be called before the render
+ * function
+ * @param string $name The name of the HTTP header
+ * @param string $value The value, null will delete it
+ */
+ public function addHeader($name, $value) {
+ if(is_null($value)) {
+ unset($this->headers[$name]);
+ } else {
+ $this->headers[$name] = $value;
+ }
+ }
+
+
+ /**
+ * Returns the set headers
+ * @return array the headers
+ */
+ public function getHeaders() {
+ $mergeWith = array();
+
+ if($this->lastModified) {
+ $mergeWith['Last-Modified'] =
+ $this->lastModified->format(\DateTime::RFC2822);
+ }
+
+ if($this->ETag) {
+ $mergeWith['ETag'] = '"' . $this->ETag . '"';
+ }
+
+ return array_merge($mergeWith, $this->headers);
+ }
+
+
+ /**
+ * By default renders no output
+ * @return null
+ */
+ public function render() {
+ return null;
+ }
+
+
+ /**
+ * Set response status
+ * @param int $status a HTTP status code, see also the STATUS constants
+ */
+ public function setStatus($status) {
+ $this->status = $status;
+ }
+
+
+ /**
+ * Get response status
+ */
+ public function getStatus() {
+ return $this->status;
+ }
+
+
+ /**
+ * @return string the etag
+ */
+ public function getETag() {
+ return $this->ETag;
+ }
+
+
+ /**
+ * @return string RFC2822 formatted last modified date
+ */
+ public function getLastModified() {
+ return $this->lastModified;
+ }
+
+
+ /**
+ * @param string $ETag
+ */
+ public function setETag($ETag) {
+ $this->ETag = $ETag;
+ }
+
+
+ /**
+ * @param \DateTime $lastModified
+ */
+ public function setLastModified($lastModified) {
+ $this->lastModified = $lastModified;
+ }
+
+
+}
diff --git a/lib/public/appframework/http/templateresponse.php b/lib/public/appframework/http/templateresponse.php
new file mode 100644
index 00000000000..97678c96cba
--- /dev/null
+++ b/lib/public/appframework/http/templateresponse.php
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCP\AppFramework\Http;
+
+use OC\AppFramework\Core\API;
+
+
+/**
+ * Response for a normal template
+ */
+class TemplateResponse extends Response {
+
+ protected $templateName;
+ protected $params;
+ protected $api;
+ protected $renderAs;
+ protected $appName;
+
+ /**
+ * @param API $api an API instance
+ * @param string $templateName the name of the template
+ * @param string $appName optional if you want to include a template from
+ * a different app
+ */
+ public function __construct(API $api, $templateName, $appName=null) {
+ $this->templateName = $templateName;
+ $this->appName = $appName;
+ $this->api = $api;
+ $this->params = array();
+ $this->renderAs = 'user';
+ }
+
+
+ /**
+ * Sets template parameters
+ * @param array $params an array with key => value structure which sets template
+ * variables
+ */
+ public function setParams(array $params){
+ $this->params = $params;
+ }
+
+
+ /**
+ * Used for accessing the set parameters
+ * @return array the params
+ */
+ public function getParams(){
+ return $this->params;
+ }
+
+
+ /**
+ * Used for accessing the name of the set template
+ * @return string the name of the used template
+ */
+ public function getTemplateName(){
+ return $this->templateName;
+ }
+
+
+ /**
+ * Sets the template page
+ * @param string $renderAs admin, user or blank. Admin also prints the admin
+ * settings header and footer, user renders the normal
+ * normal page including footer and header and blank
+ * just renders the plain template
+ */
+ public function renderAs($renderAs){
+ $this->renderAs = $renderAs;
+ }
+
+
+ /**
+ * Returns the set renderAs
+ * @return string the renderAs value
+ */
+ public function getRenderAs(){
+ return $this->renderAs;
+ }
+
+
+ /**
+ * Returns the rendered html
+ * @return string the rendered html
+ */
+ public function render(){
+
+ if($this->appName !== null){
+ $appName = $this->appName;
+ } else {
+ $appName = $this->api->getAppName();
+ }
+
+ $template = $this->api->getTemplate($this->templateName, $this->renderAs, $appName);
+
+ foreach($this->params as $key => $value){
+ $template->assign($key, $value);
+ }
+
+ return $template->fetchPage();
+ }
+
+}
diff --git a/lib/public/appframework/iapi.php b/lib/public/appframework/iapi.php
new file mode 100644
index 00000000000..fa6af5f5965
--- /dev/null
+++ b/lib/public/appframework/iapi.php
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCP\AppFramework;
+
+
+/**
+ * A few very basic and frequently used API functions are combined in here
+ */
+interface IApi {
+
+
+ /**
+ * Gets the userid of the current user
+ * @return string the user id of the current user
+ */
+ function getUserId();
+
+
+ /**
+ * Adds a new javascript file
+ * @param string $scriptName the name of the javascript in js/ without the suffix
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ function addScript($scriptName, $appName = null);
+
+
+ /**
+ * Adds a new css file
+ * @param string $styleName the name of the css file in css/without the suffix
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ function addStyle($styleName, $appName = null);
+
+
+ /**
+ * shorthand for addScript for files in the 3rdparty directory
+ * @param string $name the name of the file without the suffix
+ */
+ function add3rdPartyScript($name);
+
+
+ /**
+ * shorthand for addStyle for files in the 3rdparty directory
+ * @param string $name the name of the file without the suffix
+ */
+ function add3rdPartyStyle($name);
+
+ /**
+ * Returns the translation object
+ * @return \OC_L10N the translation object
+ *
+ * FIXME: returns private object / should be retrieved from teh ServerContainer
+ */
+ function getTrans();
+
+
+ /**
+ * Returns the URL for a route
+ * @param string $routeName the name of the route
+ * @param array $arguments an array with arguments which will be filled into the url
+ * @return string the url
+ */
+ function linkToRoute($routeName, $arguments=array());
+
+
+ /**
+ * Returns an URL for an image or file
+ * @param string $file the name of the file
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ function linkTo($file, $appName=null);
+
+
+ /**
+ * Returns the link to an image, like link to but only with prepending img/
+ * @param string $file the name of the file
+ * @param string $appName the name of the app, defaults to the current one
+ */
+ function imagePath($file, $appName = null);
+
+
+ /**
+ * Makes an URL absolute
+ * @param string $url the url
+ * @return string the absolute url
+ *
+ * FIXME: function should live in Request / Response
+ */
+ function getAbsoluteURL($url);
+
+
+ /**
+ * links to a file
+ * @param string $file the name of the file
+ * @param string $appName the name of the app, defaults to the current one
+ * @deprecated replaced with linkToRoute()
+ * @return string the url
+ */
+ function linkToAbsolute($file, $appName = null);
+
+
+ /**
+ * Checks if an app is enabled
+ * @param string $appName the name of an app
+ * @return bool true if app is enabled
+ */
+ public function isAppEnabled($appName);
+
+
+ /**
+ * Writes a function into the error log
+ * @param string $msg the error message to be logged
+ * @param int $level the error level
+ *
+ * FIXME: add logger instance to ServerContainer
+ */
+ function log($msg, $level = null);
+
+
+ /**
+ * Returns a template
+ * @param string $templateName the name of the template
+ * @param string $renderAs how it should be rendered
+ * @param string $appName the name of the app
+ * @return \OCP\Template a new template
+ */
+ function getTemplate($templateName, $renderAs='user', $appName=null);
+
+}
diff --git a/lib/public/appframework/iappcontainer.php b/lib/public/appframework/iappcontainer.php
new file mode 100644
index 00000000000..7d3b4b3bac7
--- /dev/null
+++ b/lib/public/appframework/iappcontainer.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller deepdiver@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 OCP\AppFramework;
+
+use OCP\AppFramework\IApi;
+use OCP\IContainer;
+
+/**
+ * Class IAppContainer
+ * @package OCP\AppFramework
+ *
+ * This container interface provides short cuts for app developers to access predefined app service.
+ */
+interface IAppContainer extends IContainer{
+
+ /**
+ * used to return the appname of the set application
+ * @return string the name of your application
+ */
+ function getAppName();
+
+ /**
+ * @return IApi
+ */
+ function getCoreApi();
+
+ /**
+ * @return \OCP\IServerContainer
+ */
+ function getServer();
+
+ /**
+ * @param IMiddleWare $middleWare
+ * @return boolean
+ */
+ function registerMiddleWare(IMiddleWare $middleWare);
+}
diff --git a/lib/public/appframework/imiddleware.php b/lib/public/appframework/imiddleware.php
new file mode 100644
index 00000000000..1e76d3bbe49
--- /dev/null
+++ b/lib/public/appframework/imiddleware.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale@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 Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OCP\AppFramework;
+use OCP\AppFramework\Http\Response;
+
+
+/**
+ * Middleware is used to provide hooks before or after controller methods and
+ * deal with possible exceptions raised in the controller methods.
+ * They're modeled after Django's middleware system:
+ * https://docs.djangoproject.com/en/dev/topics/http/middleware/
+ */
+interface IMiddleWare {
+
+
+ /**
+ * This is being run in normal order before the controller is being
+ * called which allows several modifications and checks
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ */
+ function beforeController($controller, $methodName);
+
+
+ /**
+ * This is being run when either the beforeController method or the
+ * controller method itself is throwing an exception. The middleware is
+ * asked in reverse order to handle the exception and to return a response.
+ * If the response is null, it is assumed that the exception could not be
+ * handled and the error will be thrown again
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param \Exception $exception the thrown exception
+ * @throws \Exception the passed in exception if it cant handle it
+ * @return Response a Response object in case that the exception was handled
+ */
+ function afterException($controller, $methodName, \Exception $exception);
+
+ /**
+ * This is being run after a successful controller method call and allows
+ * the manipulation of a Response object. The middleware is run in reverse order
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param Response $response the generated response from the controller
+ * @return Response a Response object
+ */
+ function afterController($controller, $methodName, Response $response);
+
+ /**
+ * This is being run after the response object has been rendered and
+ * allows the manipulation of the output. The middleware is run in reverse order
+ *
+ * @param Controller $controller the controller that is being called
+ * @param string $methodName the name of the method that will be called on
+ * the controller
+ * @param string $output the generated output from a response
+ * @return string the output that should be printed
+ */
+ function beforeOutput($controller, $methodName, $output);
+}
diff --git a/lib/public/contacts.php b/lib/public/contacts.php
index 88d812e735a..1b61d7aa4ff 100644
--- a/lib/public/contacts.php
+++ b/lib/public/contacts.php
@@ -90,13 +90,8 @@ namespace OCP {
* @return array of contacts which are arrays of key-value-pairs
*/
public static function search($pattern, $searchProperties = array(), $options = array()) {
- $result = array();
- foreach(self::$address_books as $address_book) {
- $r = $address_book->search($pattern, $searchProperties, $options);
- $result = array_merge($result, $r);
- }
-
- return $result;
+ $cm = \OC::$server->getContactsManager();
+ return $cm->search($pattern, $searchProperties, $options);
}
/**
@@ -107,14 +102,8 @@ namespace OCP {
* @return bool successful or not
*/
public static function delete($id, $address_book_key) {
- if (!array_key_exists($address_book_key, self::$address_books))
- return null;
-
- $address_book = self::$address_books[$address_book_key];
- if ($address_book->getPermissions() & \OCP\PERMISSION_DELETE)
- return null;
-
- return $address_book->delete($id);
+ $cm = \OC::$server->getContactsManager();
+ return $cm->delete($id, $address_book_key);
}
/**
@@ -126,15 +115,8 @@ namespace OCP {
* @return array representing the contact just created or updated
*/
public static function createOrUpdate($properties, $address_book_key) {
-
- if (!array_key_exists($address_book_key, self::$address_books))
- return null;
-
- $address_book = self::$address_books[$address_book_key];
- if ($address_book->getPermissions() & \OCP\PERMISSION_CREATE)
- return null;
-
- return $address_book->createOrUpdate($properties);
+ $cm = \OC::$server->getContactsManager();
+ return $cm->search($properties, $address_book_key);
}
/**
@@ -143,45 +125,40 @@ namespace OCP {
* @return bool true if enabled, false if not
*/
public static function isEnabled() {
- return !empty(self::$address_books);
+ $cm = \OC::$server->getContactsManager();
+ return $cm->isEnabled();
}
/**
* @param \OCP\IAddressBook $address_book
*/
public static function registerAddressBook(\OCP\IAddressBook $address_book) {
- self::$address_books[$address_book->getKey()] = $address_book;
+ $cm = \OC::$server->getContactsManager();
+ return $cm->registerAddressBook($address_book);
}
/**
* @param \OCP\IAddressBook $address_book
*/
public static function unregisterAddressBook(\OCP\IAddressBook $address_book) {
- unset(self::$address_books[$address_book->getKey()]);
+ $cm = \OC::$server->getContactsManager();
+ return $cm->unregisterAddressBook($address_book);
}
/**
* @return array
*/
public static function getAddressBooks() {
- $result = array();
- foreach(self::$address_books as $address_book) {
- $result[$address_book->getKey()] = $address_book->getDisplayName();
- }
-
- return $result;
+ $cm = \OC::$server->getContactsManager();
+ return $cm->getAddressBooks();
}
/**
* removes all registered address book instances
*/
public static function clear() {
- self::$address_books = array();
+ $cm = \OC::$server->getContactsManager();
+ $cm->clear();
}
-
- /**
- * @var \OCP\IAddressBook[] which holds all registered address books
- */
- private static $address_books = array();
}
}
diff --git a/lib/public/contacts/imanager.php b/lib/public/contacts/imanager.php
new file mode 100644
index 00000000000..3bfbca7be50
--- /dev/null
+++ b/lib/public/contacts/imanager.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller thomas.mueller@tmit.eu
+ *
+ * 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.
+ * Contacts Class
+ *
+ */
+
+// use OCP namespace for all classes that are considered public.
+// This means that they should be used by apps instead of the internal ownCloud classes
+namespace OCP\Contacts {
+
+ /**
+ * This class provides access to the contacts app. Use this class exclusively if you want to access contacts.
+ *
+ * Contacts in general will be expressed as an array of key-value-pairs.
+ * The keys will match the property names defined in https://tools.ietf.org/html/rfc2426#section-1
+ *
+ * Proposed workflow for working with contacts:
+ * - search for the contacts
+ * - manipulate the results array
+ * - createOrUpdate will save the given contacts overwriting the existing data
+ *
+ * For updating it is mandatory to keep the id.
+ * Without an id a new contact will be created.
+ *
+ */
+ interface IManager {
+
+ /**
+ * This function is used to search and find contacts within the users address books.
+ * In case $pattern is empty all contacts will be returned.
+ *
+ * Example:
+ * Following function shows how to search for contacts for the name and the email address.
+ *
+ * public static function getMatchingRecipient($term) {
+ * $cm = \OC::$server->getContactsManager();
+ * // The API is not active -> nothing to do
+ * if (!$cm->isEnabled()) {
+ * return array();
+ * }
+ *
+ * $result = $cm->search($term, array('FN', 'EMAIL'));
+ * $receivers = array();
+ * foreach ($result as $r) {
+ * $id = $r['id'];
+ * $fn = $r['FN'];
+ * $email = $r['EMAIL'];
+ * if (!is_array($email)) {
+ * $email = array($email);
+ * }
+ *
+ * // loop through all email addresses of this contact
+ * foreach ($email as $e) {
+ * $displayName = $fn . " <$e>";
+ * $receivers[] = array(
+ * 'id' => $id,
+ * 'label' => $displayName,
+ * 'value' => $displayName);
+ * }
+ * }
+ *
+ * return $receivers;
+ * }
+ *
+ *
+ * @param string $pattern which should match within the $searchProperties
+ * @param array $searchProperties defines the properties within the query pattern should match
+ * @param array $options - for future use. One should always have options!
+ * @return array of contacts which are arrays of key-value-pairs
+ */
+ function search($pattern, $searchProperties = array(), $options = array());
+
+ /**
+ * This function can be used to delete the contact identified by the given id
+ *
+ * @param object $id the unique identifier to a contact
+ * @param $address_book_key
+ * @return bool successful or not
+ */
+ function delete($id, $address_book_key);
+
+ /**
+ * This function is used to create a new contact if 'id' is not given or not present.
+ * Otherwise the contact will be updated by replacing the entire data set.
+ *
+ * @param array $properties this array if key-value-pairs defines a contact
+ * @param $address_book_key string to identify the address book in which the contact shall be created or updated
+ * @return array representing the contact just created or updated
+ */
+ function createOrUpdate($properties, $address_book_key);
+
+ /**
+ * Check if contacts are available (e.g. contacts app enabled)
+ *
+ * @return bool true if enabled, false if not
+ */
+ function isEnabled();
+
+ /**
+ * @param \OCP\IAddressBook $address_book
+ */
+ function registerAddressBook(\OCP\IAddressBook $address_book);
+
+ /**
+ * @param \OCP\IAddressBook $address_book
+ */
+ function unregisterAddressBook(\OCP\IAddressBook $address_book);
+
+ /**
+ * In order to improve lazy loading a closure can be registered which will be called in case
+ * address books are actually requested
+ *
+ * @param string $key
+ * @param \Closure $callable
+ */
+ function register($key, \Closure $callable);
+
+ /**
+ * @return array
+ */
+ function getAddressBooks();
+
+ /**
+ * removes all registered address book instances
+ */
+ function clear();
+ }
+}
diff --git a/lib/public/db.php b/lib/public/db.php
index 932e79d9ef1..9512cca2d19 100644
--- a/lib/public/db.php
+++ b/lib/public/db.php
@@ -102,4 +102,15 @@ class DB {
public static function isError($result) {
return(\OC_DB::isError($result));
}
+
+ /**
+ * returns the error code and message as a string for logging
+ * works with DoctrineException
+ * @param mixed $error
+ * @return string
+ */
+ public static function getErrorMessage($error) {
+ return(\OC_DB::getErrorMessage($error));
+ }
+
}
diff --git a/lib/public/files/alreadyexistsexception.php b/lib/public/files/alreadyexistsexception.php
new file mode 100644
index 00000000000..32947c7a5c3
--- /dev/null
+++ b/lib/public/files/alreadyexistsexception.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+class AlreadyExistsException extends \Exception {}
diff --git a/lib/public/files/file.php b/lib/public/files/file.php
new file mode 100644
index 00000000000..916b2edd6c4
--- /dev/null
+++ b/lib/public/files/file.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+interface File extends Node {
+ /**
+ * Get the content of the file as string
+ *
+ * @return string
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function getContent();
+
+ /**
+ * Write to the file from string data
+ *
+ * @param string $data
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function putContent($data);
+
+ /**
+ * Get the mimetype of the file
+ *
+ * @return string
+ */
+ public function getMimeType();
+
+ /**
+ * Open the file as stream, resulting resource can be operated as stream like the result from php's own fopen
+ *
+ * @param string $mode
+ * @return resource
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function fopen($mode);
+
+ /**
+ * Compute the hash of the file
+ * Type of hash is set with $type and can be anything supported by php's hash_file
+ *
+ * @param string $type
+ * @param bool $raw
+ * @return string
+ */
+ public function hash($type, $raw = false);
+}
diff --git a/lib/public/files/folder.php b/lib/public/files/folder.php
new file mode 100644
index 00000000000..da7f20fd366
--- /dev/null
+++ b/lib/public/files/folder.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+interface Folder extends Node {
+ /**
+ * Get the full path of an item in the folder within owncloud's filesystem
+ *
+ * @param string $path relative path of an item in the folder
+ * @return string
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function getFullPath($path);
+
+ /**
+ * Get the path of an item in the folder relative to the folder
+ *
+ * @param string $path absolute path of an item in the folder
+ * @throws \OCP\Files\NotFoundException
+ * @return string
+ */
+ public function getRelativePath($path);
+
+ /**
+ * check if a node is a (grand-)child of the folder
+ *
+ * @param \OCP\Files\Node $node
+ * @return bool
+ */
+ public function isSubNode($node);
+
+ /**
+ * get the content of this directory
+ *
+ * @throws \OCP\Files\NotFoundException
+ * @return \OCP\Files\Node[]
+ */
+ public function getDirectoryListing();
+
+ /**
+ * Get the node at $path
+ *
+ * @param string $path relative path of the file or folder
+ * @return \OCP\Files\Node
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function get($path);
+
+ /**
+ * Check if a file or folder exists in the folder
+ *
+ * @param string $path relative path of the file or folder
+ * @return bool
+ */
+ public function nodeExists($path);
+
+ /**
+ * Create a new folder
+ *
+ * @param string $path relative path of the new folder
+ * @return \OCP\Files\Folder
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function newFolder($path);
+
+ /**
+ * Create a new file
+ *
+ * @param string $path relative path of the new file
+ * @return \OCP\Files\File
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function newFile($path);
+
+ /**
+ * search for files with the name matching $query
+ *
+ * @param string $query
+ * @return \OCP\Files\Node[]
+ */
+ public function search($query);
+
+ /**
+ * search for files by mimetype
+ * $mimetype can either be a full mimetype (image/png) or a wildcard mimetype (image)
+ *
+ * @param string $mimetype
+ * @return \OCP\Files\Node[]
+ */
+ public function searchByMime($mimetype);
+
+ /**
+ * get a file or folder inside the folder by it's internal id
+ *
+ * @param int $id
+ * @return \OCP\Files\Node[]
+ */
+ public function getById($id);
+
+ /**
+ * Get the amount of free space inside the folder
+ *
+ * @return int
+ */
+ public function getFreeSpace();
+
+ /**
+ * Check if new files or folders can be created within the folder
+ *
+ * @return bool
+ */
+ public function isCreatable();
+}
diff --git a/lib/public/files/node.php b/lib/public/files/node.php
new file mode 100644
index 00000000000..b3ddf6de621
--- /dev/null
+++ b/lib/public/files/node.php
@@ -0,0 +1,159 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+interface Node {
+ /**
+ * Move the file or folder to a new location
+ *
+ * @param string $targetPath the absolute target path
+ * @throws \OCP\Files\NotPermittedException
+ * @return \OCP\Files\Node
+ */
+ public function move($targetPath);
+
+ /**
+ * Delete the file or folder
+ */
+ public function delete();
+
+ /**
+ * Cope the file or folder to a new location
+ *
+ * @param string $targetPath the absolute target path
+ * @return \OCP\Files\Node
+ */
+ public function copy($targetPath);
+
+ /**
+ * Change the modified date of the file or folder
+ * If $mtime is omitted the current time will be used
+ *
+ * @param int $mtime (optional) modified date as unix timestamp
+ * @throws \OCP\Files\NotPermittedException
+ */
+ public function touch($mtime = null);
+
+ /**
+ * Get the storage backend the file or folder is stored on
+ *
+ * @return \OCP\Files\Storage
+ * @throws \OCP\Files\NotFoundException
+ */
+ public function getStorage();
+
+ /**
+ * Get the full path of the file or folder
+ *
+ * @return string
+ */
+ public function getPath();
+
+ /**
+ * Get the path of the file or folder relative to the mountpoint of it's storage
+ *
+ * @return string
+ */
+ public function getInternalPath();
+
+ /**
+ * Get the internal file id for the file or folder
+ *
+ * @return int
+ */
+ public function getId();
+
+ /**
+ * Get metadata of the file or folder
+ * The returned array contains the following values:
+ * - mtime
+ * - size
+ *
+ * @return array
+ */
+ public function stat();
+
+ /**
+ * Get the modified date of the file or folder as unix timestamp
+ *
+ * @return int
+ */
+ public function getMTime();
+
+ /**
+ * Get the size of the file or folder in bytes
+ *
+ * @return int
+ */
+ public function getSize();
+
+ /**
+ * Get the Etag of the file or folder
+ * The Etag is an string id used to detect changes to a file or folder,
+ * every time the file or folder is changed the Etag will change to
+ *
+ * @return string
+ */
+ public function getEtag();
+
+
+ /**
+ * Get the permissions of the file or folder as a combination of one or more of the following constants:
+ * - \OCP\PERMISSION_READ
+ * - \OCP\PERMISSION_UPDATE
+ * - \OCP\PERMISSION_CREATE
+ * - \OCP\PERMISSION_DELETE
+ * - \OCP\PERMISSION_SHARE
+ *
+ * @return int
+ */
+ public function getPermissions();
+
+ /**
+ * Check if the file or folder is readable
+ *
+ * @return bool
+ */
+ public function isReadable();
+
+ /**
+ * Check if the file or folder is writable
+ *
+ * @return bool
+ */
+ public function isUpdateable();
+
+ /**
+ * Check if the file or folder is deletable
+ *
+ * @return bool
+ */
+ public function isDeletable();
+
+ /**
+ * Check if the file or folder is shareable
+ *
+ * @return bool
+ */
+ public function isShareable();
+
+ /**
+ * Get the parent folder of the file or folder
+ *
+ * @return Folder
+ */
+ public function getParent();
+
+ /**
+ * Get the filename of the file or folder
+ *
+ * @return string
+ */
+ public function getName();
+}
diff --git a/lib/public/files/notenoughspaceexception.php b/lib/public/files/notenoughspaceexception.php
new file mode 100644
index 00000000000..e51806666ad
--- /dev/null
+++ b/lib/public/files/notenoughspaceexception.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+class NotEnoughSpaceException extends \Exception {}
diff --git a/lib/public/files/notfoundexception.php b/lib/public/files/notfoundexception.php
new file mode 100644
index 00000000000..1ff426a40c6
--- /dev/null
+++ b/lib/public/files/notfoundexception.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+class NotFoundException extends \Exception {}
diff --git a/lib/public/files/notpermittedexception.php b/lib/public/files/notpermittedexception.php
new file mode 100644
index 00000000000..0509de7e829
--- /dev/null
+++ b/lib/public/files/notpermittedexception.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Files;
+
+class NotPermittedException extends \Exception {}
diff --git a/lib/public/files/storage.php b/lib/public/files/storage.php
new file mode 100644
index 00000000000..f32f2073483
--- /dev/null
+++ b/lib/public/files/storage.php
@@ -0,0 +1,297 @@
+<?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.
+ */
+
+namespace OCP\Files;
+
+/**
+ * Provide a common interface to all different storage options
+ *
+ * All paths passed to the storage are relative to the storage and should NOT have a leading slash.
+ */
+interface Storage {
+ /**
+ * $parameters is a free form array with the configuration options needed to construct the storage
+ *
+ * @param array $parameters
+ */
+ public function __construct($parameters);
+
+ /**
+ * Get the identifier for the storage,
+ * the returned id should be the same for every storage object that is created with the same parameters
+ * and two storage objects with the same id should refer to two storages that display the same files.
+ *
+ * @return string
+ */
+ public function getId();
+
+ /**
+ * see http://php.net/manual/en/function.mkdir.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function mkdir($path);
+
+ /**
+ * see http://php.net/manual/en/function.rmdir.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function rmdir($path);
+
+ /**
+ * see http://php.net/manual/en/function.opendir.php
+ *
+ * @param string $path
+ * @return resource
+ */
+ public function opendir($path);
+
+ /**
+ * see http://php.net/manual/en/function.is_dir.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function is_dir($path);
+
+ /**
+ * see http://php.net/manual/en/function.is_file.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function is_file($path);
+
+ /**
+ * see http://php.net/manual/en/function.stat.php
+ * only the following keys are required in the result: size and mtime
+ *
+ * @param string $path
+ * @return array
+ */
+ public function stat($path);
+
+ /**
+ * see http://php.net/manual/en/function.filetype.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function filetype($path);
+
+ /**
+ * see http://php.net/manual/en/function.filesize.php
+ * The result for filesize when called on a folder is required to be 0
+ *
+ * @param string $path
+ * @return int
+ */
+ public function filesize($path);
+
+ /**
+ * check if a file can be created in $path
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isCreatable($path);
+
+ /**
+ * check if a file can be read
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isReadable($path);
+
+ /**
+ * check if a file can be written to
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isUpdatable($path);
+
+ /**
+ * check if a file can be deleted
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isDeletable($path);
+
+ /**
+ * check if a file can be shared
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function isSharable($path);
+
+ /**
+ * get the full permissions of a path.
+ * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
+ *
+ * @param string $path
+ * @return int
+ */
+ public function getPermissions($path);
+
+ /**
+ * see http://php.net/manual/en/function.file_exists.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function file_exists($path);
+
+ /**
+ * see http://php.net/manual/en/function.filemtime.php
+ *
+ * @param string $path
+ * @return int
+ */
+ public function filemtime($path);
+
+ /**
+ * see http://php.net/manual/en/function.file_get_contents.php
+ *
+ * @param string $path
+ * @return string
+ */
+ public function file_get_contents($path);
+
+ /**
+ * see http://php.net/manual/en/function.file_put_contents.php
+ *
+ * @param string $path
+ * @param string $data
+ * @return bool
+ */
+ public function file_put_contents($path, $data);
+
+ /**
+ * see http://php.net/manual/en/function.unlink.php
+ *
+ * @param string $path
+ * @return bool
+ */
+ public function unlink($path);
+
+ /**
+ * see http://php.net/manual/en/function.rename.php
+ *
+ * @param string $path1
+ * @param string $path2
+ * @return bool
+ */
+ public function rename($path1, $path2);
+
+ /**
+ * see http://php.net/manual/en/function.copy.php
+ *
+ * @param string $path1
+ * @param string $path2
+ * @return bool
+ */
+ public function copy($path1, $path2);
+
+ /**
+ * see http://php.net/manual/en/function.fopen.php
+ *
+ * @param string $path
+ * @param string $mode
+ * @return resource
+ */
+ public function fopen($path, $mode);
+
+ /**
+ * get the mimetype for a file or folder
+ * The mimetype for a folder is required to be "httpd/unix-directory"
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getMimeType($path);
+
+ /**
+ * see http://php.net/manual/en/function.hash-file.php
+ *
+ * @param string $type
+ * @param string $path
+ * @param bool $raw
+ * @return string
+ */
+ public function hash($type, $path, $raw = false);
+
+ /**
+ * see http://php.net/manual/en/function.free_space.php
+ *
+ * @param string $path
+ * @return int
+ */
+ public function free_space($path);
+
+ /**
+ * search for occurrences of $query in file names
+ *
+ * @param string $query
+ * @return array
+ */
+ public function search($query);
+
+ /**
+ * see http://php.net/manual/en/function.touch.php
+ * If the backend does not support the operation, false should be returned
+ *
+ * @param string $path
+ * @param int $mtime
+ * @return bool
+ */
+ public function touch($path, $mtime = null);
+
+ /**
+ * get the path to a local version of the file.
+ * The local version of the file can be temporary and doesn't have to be persistent across requests
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getLocalFile($path);
+
+ /**
+ * get the path to a local version of the folder.
+ * The local version of the folder can be temporary and doesn't have to be persistent across requests
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getLocalFolder($path);
+ /**
+ * check if a file or folder has been updated since $time
+ *
+ * @param string $path
+ * @param int $time
+ * @return bool
+ *
+ * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
+ * returning true for other changes in the folder is optional
+ */
+ public function hasUpdated($path, $time);
+
+ /**
+ * get the ETag for a file or folder
+ *
+ * @param string $path
+ * @return string
+ */
+ public function getETag($path);
+}
diff --git a/lib/public/icache.php b/lib/public/icache.php
new file mode 100644
index 00000000000..436ee71b2b9
--- /dev/null
+++ b/lib/public/icache.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net)
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+namespace OCP;
+
+/**
+ * This interface defines method for accessing the file based user cache.
+ */
+interface ICache {
+
+ /**
+ * Get a value from the user cache
+ *
+ * @param string $key
+ * @return mixed
+ */
+ public function get($key);
+
+ /**
+ * Set a value in the user cache
+ *
+ * @param string $key
+ * @param mixed $value
+ * @param int $ttl Time To Live in seconds. Defaults to 60*60*24
+ * @return bool
+ */
+ public function set($key, $value, $ttl = 0);
+
+ /**
+ * Check if a value is set in the user cache
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function hasKey($key);
+
+ /**
+ * Remove an item from the user cache
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function remove($key);
+
+ /**
+ * clear the user cache of all entries starting with a prefix
+ * @param string $prefix (optional)
+ * @return bool
+ */
+ public function clear($prefix = '');
+}
diff --git a/lib/public/iconfig.php b/lib/public/iconfig.php
new file mode 100644
index 00000000000..850bddf6935
--- /dev/null
+++ b/lib/public/iconfig.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * Access to all the configuration options ownCloud offers
+ */
+interface IConfig {
+ /**
+ * Sets a new system wide value
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ * @todo need a use case for this
+ */
+// public function setSystemValue($key, $value);
+
+ /**
+ * Looks up a system wide defined value
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getSystemValue($key);
+
+
+ /**
+ * Writes a new app wide value
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key of the value, under which will be saved
+ * @param string $value the value that should be stored
+ */
+ public function setAppValue($appName, $key, $value);
+
+ /**
+ * Looks up an app wide defined value
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key of the value, under which it was saved
+ * @return string the saved value
+ */
+ public function getAppValue($appName, $key);
+
+
+ /**
+ * Set a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we want to store the value under
+ * @param string $key the key under which the value is being stored
+ * @param string $value the value that you want to store
+ */
+ public function setUserValue($userId, $appName, $key, $value);
+
+ /**
+ * Shortcut for getting a user defined value
+ * @param string $userId the userId of the user that we want to store the value under
+ * @param string $appName the appName that we stored the value under
+ * @param string $key the key under which the value is being stored
+ */
+ public function getUserValue($userId, $appName, $key);
+}
diff --git a/lib/public/icontainer.php b/lib/public/icontainer.php
new file mode 100644
index 00000000000..d43c1c90f11
--- /dev/null
+++ b/lib/public/icontainer.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller deepdiver@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 OCP;
+
+/**
+ * Class IContainer
+ *
+ * IContainer is the basic interface to be used for any internal dependency injection mechanism
+ *
+ * @package OCP
+ */
+interface IContainer {
+
+ /**
+ * Look up a service for a given name in the container.
+ *
+ * @param string $name
+ * @return mixed
+ */
+ function query($name);
+
+ /**
+ * A value is stored in the container with it's corresponding name
+ *
+ * @param string $name
+ * @param mixed $value
+ * @return void
+ */
+ function registerParameter($name, $value);
+
+ /**
+ * A service is registered in the container where a closure is passed in which will actually
+ * create the service on demand.
+ * In case the parameter $shared is set to true (the default usage) the once created service will remain in
+ * memory and be reused on subsequent calls.
+ * In case the parameter is false the service will be recreated on every call.
+ *
+ * @param string $name
+ * @param callable $closure
+ * @param bool $shared
+ * @return void
+ */
+ function registerService($name, \Closure $closure, $shared = true);
+}
diff --git a/lib/public/idbconnection.php b/lib/public/idbconnection.php
new file mode 100644
index 00000000000..c741a0f061a
--- /dev/null
+++ b/lib/public/idbconnection.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * TODO: Description
+ */
+interface IDBConnection {
+ /**
+ * Used to abstract the owncloud database access away
+ * @param string $sql the sql query with ? placeholder for params
+ * @param int $limit the maximum number of rows
+ * @param int $offset from which row we want to start
+ * @return \Doctrine\DBAL\Driver\Statement The prepared statement.
+ */
+ public function prepare($sql, $limit=null, $offset=null);
+
+ /**
+ * Used to get the id of the just inserted element
+ * @param string $tableName the name of the table where we inserted the item
+ * @return int the id of the inserted element
+ */
+ public function lastInsertId($table = null);
+
+ /**
+ * @brief Insert a row if a matching row doesn't exists.
+ * @param $table string The table name (will replace *PREFIX*) to perform the replace on.
+ * @param $input array
+ *
+ * The input array if in the form:
+ *
+ * array ( 'id' => array ( 'value' => 6,
+ * 'key' => true
+ * ),
+ * 'name' => array ('value' => 'Stoyan'),
+ * 'family' => array ('value' => 'Stefanov'),
+ * 'birth_date' => array ('value' => '1975-06-20')
+ * );
+ * @return bool
+ *
+ */
+ public function insertIfNotExist($table, $input);
+
+ /**
+ * @brief Start a transaction
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function beginTransaction();
+
+ /**
+ * @brief Commit the database changes done during a transaction that is in progress
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function commit();
+
+ /**
+ * @brief Rollback the database changes done during a transaction that is in progress
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function rollBack();
+
+ /**
+ * returns the error code and message as a string for logging
+ * @return string
+ */
+ public function getError();
+}
diff --git a/lib/public/inavigationmanager.php b/lib/public/inavigationmanager.php
new file mode 100644
index 00000000000..f89e790c1d0
--- /dev/null
+++ b/lib/public/inavigationmanager.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * Manages the ownCloud navigation
+ */
+interface INavigationManager {
+ /**
+ * Creates a new navigation entry
+ * @param array $entry containing: id, name, order, icon and href key
+ */
+ public function add(array $entry);
+
+ /**
+ * Sets the current navigation entry of the currently running app
+ * @param string $appId id of the app entry to activate (from added $entry)
+ */
+ public function setActiveEntry($appId);
+}
diff --git a/lib/public/ipreview.php b/lib/public/ipreview.php
new file mode 100644
index 00000000000..b01e7f5b539
--- /dev/null
+++ b/lib/public/ipreview.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org
+ * Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+namespace OCP;
+
+/**
+ * This class provides functions to render and show thumbnails and previews of files
+ */
+interface IPreview
+{
+
+ /**
+ * @brief return a preview of a file
+ * @param string $file The path to the file where you want a thumbnail from
+ * @param int $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image
+ * @param int $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
+ * @param boolean $scaleUp Scale smaller images up to the thumbnail size or not. Might look ugly
+ * @return \OCP\Image
+ */
+ function createPreview($file, $maxX = 100, $maxY = 75, $scaleUp = false);
+
+
+ /**
+ * @brief returns true if the passed mime type is supported
+ * @param string $mimeType
+ * @return boolean
+ */
+ function isMimeSupported($mimeType = '*');
+
+}
diff --git a/lib/public/irequest.php b/lib/public/irequest.php
new file mode 100644
index 00000000000..9f335b06f2a
--- /dev/null
+++ b/lib/public/irequest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller deepdiver@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 OCP;
+
+
+interface IRequest {
+
+ function getHeader($name);
+
+ /**
+ * Lets you access post and get parameters by the index
+ * In case of json requests the encoded json body is accessed
+ *
+ * @param string $key the key which you want to access in the URL Parameter
+ * placeholder, $_POST or $_GET array.
+ * The priority how they're returned is the following:
+ * 1. URL parameters
+ * 2. POST parameters
+ * 3. GET parameters
+ * @param mixed $default If the key is not found, this value will be returned
+ * @return mixed the content of the array
+ */
+ public function getParam($key, $default = null);
+
+
+ /**
+ * Returns all params that were received, be it from the request
+ *
+ * (as GET or POST) or through the URL by the route
+ * @return array the array with all parameters
+ */
+ public function getParams();
+
+ /**
+ * Returns the method of the request
+ *
+ * @return string the method of the request (POST, GET, etc)
+ */
+ public function getMethod();
+
+ /**
+ * Shortcut for accessing an uploaded file through the $_FILES array
+ *
+ * @param string $key the key that will be taken from the $_FILES array
+ * @return array the file in the $_FILES element
+ */
+ public function getUploadedFile($key);
+
+
+ /**
+ * Shortcut for getting env variables
+ *
+ * @param string $key the key that will be taken from the $_ENV array
+ * @return array the value in the $_ENV element
+ */
+ public function getEnv($key);
+
+
+ /**
+ * Shortcut for getting cookie variables
+ *
+ * @param string $key the key that will be taken from the $_COOKIE array
+ * @return array the value in the $_COOKIE element
+ */
+ function getCookie($key);
+
+
+ /**
+ * Returns the request body content.
+ *
+ * @param Boolean $asResource If true, a resource will be returned
+ * @return string|resource The request body content or a resource to read the body stream.
+ * @throws \LogicException
+ */
+ function getContent($asResource = false);
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
new file mode 100644
index 00000000000..f4045faefef
--- /dev/null
+++ b/lib/public/iservercontainer.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Thomas Müller
+ * @copyright 2013 Thomas Müller deepdiver@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 OCP;
+
+
+/**
+ * Class IServerContainer
+ * @package OCP
+ *
+ * This container holds all ownCloud services
+ */
+interface IServerContainer {
+
+ /**
+ * The contacts manager will act as a broker between consumers for contacts information and
+ * providers which actual deliver the contact information.
+ *
+ * @return \OCP\Contacts\IManager
+ */
+ function getContactsManager();
+
+ /**
+ * The current request object holding all information about the request currently being processed
+ * is returned from this method.
+ * In case the current execution was not initiated by a web request null is returned
+ *
+ * @return \OCP\IRequest|null
+ */
+ function getRequest();
+
+ /**
+ * Returns the preview manager which can create preview images for a given file
+ *
+ * @return \OCP\IPreview
+ */
+ function getPreviewManager();
+
+ /**
+ * Returns the tag manager which can get and set tags for different object types
+ *
+ * @see \OCP\ITagManager::load()
+ * @return \OCP\ITagManager
+ */
+ function getTagManager();
+
+ /**
+ * Returns the root folder of ownCloud's data directory
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getRootFolder();
+
+ /**
+ * Returns a view to ownCloud's files folder
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getUserFolder();
+
+ /**
+ * Returns an app-specific view in ownClouds data directory
+ *
+ * @return \OCP\Files\Folder
+ */
+ function getAppFolder();
+
+ /**
+ * Returns the user session
+ *
+ * @return \OCP\IUserSession
+ */
+ function getUserSession();
+
+ /**
+ * @return \OCP\INavigationManager
+ */
+ function getNavigationManager();
+
+ /**
+ * @return \OCP\IConfig
+ */
+ function getConfig();
+
+ /**
+ * Returns an ICache instance
+ *
+ * @return \OCP\ICache
+ */
+ function getCache();
+
+ /**
+ * Returns the current session
+ *
+ * @return \OCP\ISession
+ */
+ function getSession();
+
+ /**
+ * Returns the current session
+ *
+ * @return \OCP\IDBConnection
+ */
+ function getDatabaseConnection();
+
+}
diff --git a/lib/public/isession.php b/lib/public/isession.php
new file mode 100644
index 00000000000..0a77b0c823b
--- /dev/null
+++ b/lib/public/isession.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright (c) 2013 Thomas Tanghus (thomas@tanghus.net)
+ * @author Thomas Tanghus
+ * @author Robin Appelman
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP;
+
+/**
+ * Interface ISession
+ *
+ * wrap PHP's internal session handling into the ISession interface
+ */
+interface ISession {
+
+ /**
+ * Set a value in the session
+ *
+ * @param string $key
+ * @param mixed $value
+ */
+ public function set($key, $value);
+
+ /**
+ * Get a value from the session
+ *
+ * @param string $key
+ * @return mixed should return null if $key does not exist
+ */
+ public function get($key);
+
+ /**
+ * Check if a named key exists in the session
+ *
+ * @param string $key
+ * @return bool
+ */
+ public function exists($key);
+
+ /**
+ * Remove a $key/$value pair from the session
+ *
+ * @param string $key
+ */
+ public function remove($key);
+
+ /**
+ * Reset and recreate the session
+ */
+ public function clear();
+
+}
diff --git a/lib/public/itagmanager.php b/lib/public/itagmanager.php
new file mode 100644
index 00000000000..07e1d12fc0f
--- /dev/null
+++ b/lib/public/itagmanager.php
@@ -0,0 +1,48 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2013 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/>.
+*
+*/
+
+/**
+ * Factory class creating instances of \OCP\ITags
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+namespace OCP;
+
+interface ITagManager {
+
+ /**
+ * Create a new \OCP\ITags instance and load tags from db.
+ *
+ * @see \OCP\ITags
+ * @param string $type The type identifier e.g. 'contact' or 'event'.
+ * @param array $defaultTags An array of default tags to be used if none are stored.
+ * @return \OCP\ITags
+ */
+ public function load($type, $defaultTags=array());
+
+} \ No newline at end of file
diff --git a/lib/public/itags.php b/lib/public/itags.php
new file mode 100644
index 00000000000..5b1ebd189da
--- /dev/null
+++ b/lib/public/itags.php
@@ -0,0 +1,164 @@
+<?php
+/**
+* ownCloud
+*
+* @author Thomas Tanghus
+* @copyright 2013 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/>.
+*
+*/
+
+namespace OCP;
+
+// FIXME: Where should I put this? Or should it be implemented as a Listener?
+\OC_Hook::connect('OC_User', 'post_deleteUser', 'OC\Tags', 'post_deleteUser');
+
+/**
+ * Class for easily tagging objects by their id
+ *
+ * A tag can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
+ * anything else that is either parsed from a vobject or that the user chooses
+ * to add.
+ * Tag names are not case-sensitive, but will be saved with the case they
+ * are entered in. If a user already has a tag 'family' for a type, and
+ * tries to add a tag named 'Family' it will be silently ignored.
+ */
+
+interface ITags {
+
+ /**
+ * Check if any tags are saved for this type and user.
+ *
+ * @return boolean.
+ */
+ public function isEmpty();
+
+ /**
+ * Get the tags for a specific user.
+ *
+ * This returns an array with id/name maps:
+ * [
+ * ['id' => 0, 'name' = 'First tag'],
+ * ['id' => 1, 'name' = 'Second tag'],
+ * ]
+ *
+ * @returns array
+ */
+ public function getTags();
+
+ /**
+ * Get the a list if items tagged with $tag.
+ *
+ * Throws an exception if the tag could not be found.
+ *
+ * @param string|integer $tag Tag id or name.
+ * @return array An array of object ids or false on error.
+ */
+ public function getIdsForTag($tag);
+
+ /**
+ * Checks whether a tag is already saved.
+ *
+ * @param string $name The name to check for.
+ * @return bool
+ */
+ public function hasTag($name);
+
+ /**
+ * Add a new tag.
+ *
+ * @param string $name A string with a name of the tag
+ * @return int the id of the added tag or false if it already exists.
+ */
+ public function add($name);
+
+ /**
+ * Rename tag.
+ *
+ * @param string $from The name of the existing tag
+ * @param string $to The new name of the tag.
+ * @return bool
+ */
+ public function rename($from, $to);
+
+ /**
+ * Add a list of new tags.
+ *
+ * @param string[] $names A string with a name or an array of strings containing
+ * the name(s) of the to add.
+ * @param bool $sync When true, save the tags
+ * @param int|null $id int Optional object id to add to this|these tag(s)
+ * @return bool Returns false on error.
+ */
+ public function addMultiple($names, $sync=false, $id = null);
+
+ /**
+ * Delete tag/object relations from the db
+ *
+ * @param array $ids The ids of the objects
+ * @return boolean Returns false on error.
+ */
+ public function purgeObjects(array $ids);
+
+ /**
+ * Get favorites for an object type
+ *
+ * @return array An array of object ids.
+ */
+ public function getFavorites();
+
+ /**
+ * Add an object to favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function addToFavorites($objid);
+
+ /**
+ * Remove an object from favorites
+ *
+ * @param int $objid The id of the object
+ * @return boolean
+ */
+ public function removeFromFavorites($objid);
+
+ /**
+ * Creates a tag/object relation.
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean Returns false on database error.
+ */
+ public function tagAs($objid, $tag);
+
+ /**
+ * Delete single tag/object relation from the db
+ *
+ * @param int $objid The id of the object
+ * @param int|string $tag The id or name of the tag
+ * @return boolean
+ */
+ public function unTag($objid, $tag);
+
+ /**
+ * Delete tags from the
+ *
+ * @param string[] $names An array of tags to delete
+ * @return bool Returns false on error
+ */
+ public function delete($names);
+
+} \ No newline at end of file
diff --git a/lib/public/iusersession.php b/lib/public/iusersession.php
new file mode 100644
index 00000000000..5dc1ecf71e6
--- /dev/null
+++ b/lib/public/iusersession.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright (c) 2013 Bart Visscher <bartv@thisnet.nl>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ *
+ */
+
+namespace OCP;
+
+/**
+ * User session
+ */
+interface IUserSession {
+ /**
+ * Do a user login
+ * @param string $user the username
+ * @param string $password the password
+ * @return bool true if successful
+ */
+ public function login($user, $password);
+
+ /**
+ * @brief Logs the user out including all the session data
+ * Logout, destroys session
+ */
+ public function logout();
+
+}
diff --git a/lib/public/preview.php b/lib/public/preview.php
deleted file mode 100644
index 7588347eccb..00000000000
--- a/lib/public/preview.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/**
- * Copyright (c) 2013 Frank Karlitschek frank@owncloud.org
- * Copyright (c) 2013 Georg Ehrke georg@ownCloud.com
- * This file is licensed under the Affero General Public License version 3 or
- * later.
- * See the COPYING-README file.
- */
-namespace OCP;
-
-/**
- * This class provides functions to render and show thumbnails and previews of files
- */
-class Preview {
-
- /**
- * @brief return a preview of a file
- * @param $file The path to the file where you want a thumbnail from
- * @param $maxX The maximum X size of the thumbnail. It can be smaller depending on the shape of the image
- * @param $maxY The maximum Y size of the thumbnail. It can be smaller depending on the shape of the image
- * @param $scaleup Scale smaller images up to the thumbnail size or not. Might look ugly
- * @return image
- */
- public static function show($file,$maxX=100,$maxY=75,$scaleup=false) {
- return(\OC\Preview::show($file,$maxX,$maxY,$scaleup));
- }
-
-
-
- public static function isMimeSupported($mimetype='*') {
- return \OC\Preview::isMimeSupported($mimetype);
- }
-
-}
diff --git a/lib/public/share.php b/lib/public/share.php
index 9ab956d84b9..6c5783f1179 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -106,22 +106,22 @@ class Share {
}
return false;
}
-
+
/**
* @brief Prepare a path to be passed to DB as file_target
* @return string Prepared path
*/
public static function prepFileTarget( $path ) {
-
+
// Paths in DB are stored with leading slashes, so add one if necessary
if ( substr( $path, 0, 1 ) !== '/' ) {
-
+
$path = '/' . $path;
-
+
}
-
+
return $path;
-
+
}
/**
@@ -256,7 +256,7 @@ class Share {
return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format,
$parameters, 1, $includeCollections);
}
-
+
/**
* @brief Get the item of item type shared with the current user by source
* @param string Item type
@@ -293,7 +293,18 @@ class Share {
if (\OC_DB::isError($result)) {
\OC_Log::write('OCP\Share', \OC_DB::getErrorMessage($result) . ', token=' . $token, \OC_Log::ERROR);
}
- return $result->fetchRow();
+ $row = $result->fetchRow();
+
+ if (!empty($row['expiration'])) {
+ $now = new \DateTime();
+ $expirationDate = new \DateTime($row['expiration'], new \DateTimeZone('UTC'));
+ if ($now > $expirationDate) {
+ self::delete($row['id']);
+ return false;
+ }
+ }
+
+ return $row;
}
/**
@@ -450,6 +461,7 @@ class Share {
$uidOwner, self::FORMAT_NONE, null, 1)) {
// remember old token
$oldToken = $checkExists['token'];
+ $oldPermissions = $checkExists['permissions'];
//delete the old share
self::delete($checkExists['id']);
}
@@ -460,8 +472,11 @@ class Share {
$hasher = new \PasswordHash(8, $forcePortable);
$shareWith = $hasher->HashPassword($shareWith.\OC_Config::getValue('passwordsalt', ''));
} else {
- // reuse the already set password
- $shareWith = $checkExists['share_with'];
+ // reuse the already set password, but only if we change permissions
+ // otherwise the user disabled the password protection
+ if ($checkExists && (int)$permissions !== (int)$oldPermissions) {
+ $shareWith = $checkExists['share_with'];
+ }
}
// Generate token
@@ -745,10 +760,10 @@ class Share {
/**
* @brief Get the backend class for the specified item type
- * @param string Item type
- * @return Sharing backend object
+ * @param string $itemType
+ * @return Share_Backend
*/
- private static function getBackend($itemType) {
+ public static function getBackend($itemType) {
if (isset(self::$backends[$itemType])) {
return self::$backends[$itemType];
} else if (isset(self::$backendTypes[$itemType]['class'])) {
diff --git a/lib/public/user.php b/lib/public/user.php
index 23ff991642d..576a64d7048 100644
--- a/lib/public/user.php
+++ b/lib/public/user.php
@@ -102,7 +102,7 @@ class User {
* @brief Check if the password is correct
* @param $uid The username
* @param $password The password
- * @returns true/false
+ * @returns mixed username on success, false otherwise
*
* Check if the password is correct without logging in the user
*/
diff --git a/lib/vcategories.php b/lib/vcategories.php
deleted file mode 100644
index 84036958359..00000000000
--- a/lib/vcategories.php
+++ /dev/null
@@ -1,821 +0,0 @@
-<?php
-/**
-* ownCloud
-*
-* @author Thomas Tanghus
-* @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
-* @copyright 2012 Bart Visscher bartv@thisnet.nl
-*
-* 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/>.
-*
-*/
-
-OC_Hook::connect('OC_User', 'post_deleteUser', 'OC_VCategories', 'post_deleteUser');
-
-/**
- * Class for easy access to categories in VCARD, VEVENT, VTODO and VJOURNAL.
- * A Category can be e.g. 'Family', 'Work', 'Chore', 'Special Occation' or
- * anything else that is either parsed from a vobject or that the user chooses
- * to add.
- * Category names are not case-sensitive, but will be saved with the case they
- * are entered in. If a user already has a category 'family' for a type, and
- * tries to add a category named 'Family' it will be silently ignored.
- */
-class OC_VCategories {
-
- /**
- * Categories
- */
- private $categories = array();
-
- /**
- * Used for storing objectid/categoryname pairs while rescanning.
- */
- private static $relations = array();
-
- private $type = null;
- private $user = null;
-
- const CATEGORY_TABLE = '*PREFIX*vcategory';
- const RELATION_TABLE = '*PREFIX*vcategory_to_object';
-
- const CATEGORY_FAVORITE = '_$!<Favorite>!$_';
-
- const FORMAT_LIST = 0;
- const FORMAT_MAP = 1;
-
- /**
- * @brief Constructor.
- * @param $type The type identifier e.g. 'contact' or 'event'.
- * @param $user The user whos data the object will operate on. This
- * parameter should normally be omitted but to make an app able to
- * update categories for all users it is made possible to provide it.
- * @param $defcategories An array of default categories to be used if none is stored.
- */
- public function __construct($type, $user=null, $defcategories=array()) {
- $this->type = $type;
- $this->user = is_null($user) ? OC_User::getUser() : $user;
-
- $this->loadCategories();
- OCP\Util::writeLog('core', __METHOD__ . ', categories: '
- . print_r($this->categories, true),
- OCP\Util::DEBUG
- );
-
- if($defcategories && count($this->categories) === 0) {
- $this->addMulti($defcategories, true);
- }
- }
-
- /**
- * @brief Load categories from db.
- */
- private function loadCategories() {
- $this->categories = array();
- $result = null;
- $sql = 'SELECT `id`, `category` FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ? ORDER BY `category`';
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($this->user, $this->type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
-
- if(!is_null($result)) {
- while( $row = $result->fetchRow()) {
- // The keys are prefixed because array_search wouldn't work otherwise :-/
- $this->categories[$row['id']] = $row['category'];
- }
- }
- OCP\Util::writeLog('core', __METHOD__.', categories: ' . print_r($this->categories, true),
- OCP\Util::DEBUG);
- }
-
-
- /**
- * @brief Check if any categories are saved for this type and user.
- * @returns boolean.
- * @param $type The type identifier e.g. 'contact' or 'event'.
- * @param $user The user whos categories will be checked. If not set current user will be used.
- */
- public static function isEmpty($type, $user = null) {
- $user = is_null($user) ? OC_User::getUser() : $user;
- $sql = 'SELECT COUNT(*) FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ?';
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($user, $type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- return ($result->numRows() === 0);
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- }
-
- /**
- * @brief Get the categories for a specific user.
- * @param
- * @returns array containing the categories as strings.
- */
- public function categories($format = null) {
- if(!$this->categories) {
- return array();
- }
- $categories = array_values($this->categories);
- uasort($categories, 'strnatcasecmp');
- if($format == self::FORMAT_MAP) {
- $catmap = array();
- foreach($categories as $category) {
- if($category !== self::CATEGORY_FAVORITE) {
- $catmap[] = array(
- 'id' => $this->array_searchi($category, $this->categories),
- 'name' => $category
- );
- }
- }
- return $catmap;
- }
-
- // Don't add favorites to normal categories.
- $favpos = array_search(self::CATEGORY_FAVORITE, $categories);
- if($favpos !== false) {
- return array_splice($categories, $favpos);
- } else {
- return $categories;
- }
- }
-
- /**
- * Get the a list if items belonging to $category.
- *
- * Throws an exception if the category could not be found.
- *
- * @param string|integer $category Category id or name.
- * @returns array An array of object ids or false on error.
- */
- public function idsForCategory($category) {
- $result = null;
- if(is_numeric($category)) {
- $catid = $category;
- } elseif(is_string($category)) {
- $catid = $this->array_searchi($category, $this->categories);
- }
- OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG);
- if($catid === false) {
- $l10n = OC_L10N::get('core');
- throw new Exception(
- $l10n->t('Could not find category "%s"', $category)
- );
- }
-
- $ids = array();
- $sql = 'SELECT `objid` FROM `' . self::RELATION_TABLE
- . '` WHERE `categoryid` = ?';
-
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($catid));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
-
- if(!is_null($result)) {
- while( $row = $result->fetchRow()) {
- $ids[] = (int)$row['objid'];
- }
- }
-
- return $ids;
- }
-
- /**
- * Get the a list if items belonging to $category.
- *
- * Throws an exception if the category could not be found.
- *
- * @param string|integer $category Category id or name.
- * @param array $tableinfo Array in the form {'tablename' => table, 'fields' => ['field1', 'field2']}
- * @param int $limit
- * @param int $offset
- *
- * This generic method queries a table assuming that the id
- * field is called 'id' and the table name provided is in
- * the form '*PREFIX*table_name'.
- *
- * If the category name cannot be resolved an exception is thrown.
- *
- * TODO: Maybe add the getting permissions for objects?
- *
- * @returns array containing the resulting items or false on error.
- */
- public function itemsForCategory($category, $tableinfo, $limit = null, $offset = null) {
- $result = null;
- if(is_numeric($category)) {
- $catid = $category;
- } elseif(is_string($category)) {
- $catid = $this->array_searchi($category, $this->categories);
- }
- OCP\Util::writeLog('core', __METHOD__.', category: '.$catid.' '.$category, OCP\Util::DEBUG);
- if($catid === false) {
- $l10n = OC_L10N::get('core');
- throw new Exception(
- $l10n->t('Could not find category "%s"', $category)
- );
- }
- $fields = '';
- foreach($tableinfo['fields'] as $field) {
- $fields .= '`' . $tableinfo['tablename'] . '`.`' . $field . '`,';
- }
- $fields = substr($fields, 0, -1);
-
- $items = array();
- $sql = 'SELECT `' . self::RELATION_TABLE . '`.`categoryid`, ' . $fields
- . ' FROM `' . $tableinfo['tablename'] . '` JOIN `'
- . self::RELATION_TABLE . '` ON `' . $tableinfo['tablename']
- . '`.`id` = `' . self::RELATION_TABLE . '`.`objid` WHERE `'
- . self::RELATION_TABLE . '`.`categoryid` = ?';
-
- try {
- $stmt = OCP\DB::prepare($sql, $limit, $offset);
- $result = $stmt->execute(array($catid));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
-
- if(!is_null($result)) {
- while( $row = $result->fetchRow()) {
- $items[] = $row;
- }
- }
- //OCP\Util::writeLog('core', __METHOD__.', count: ' . count($items), OCP\Util::DEBUG);
- //OCP\Util::writeLog('core', __METHOD__.', sql: ' . $sql, OCP\Util::DEBUG);
-
- return $items;
- }
-
- /**
- * @brief Checks whether a category is already saved.
- * @param $name The name to check for.
- * @returns bool
- */
- public function hasCategory($name) {
- return $this->in_arrayi($name, $this->categories);
- }
-
- /**
- * @brief Add a new category.
- * @param $name A string with a name of the category
- * @returns int the id of the added category or false if it already exists.
- */
- public function add($name) {
- OCP\Util::writeLog('core', __METHOD__.', name: ' . $name, OCP\Util::DEBUG);
- if($this->hasCategory($name)) {
- OCP\Util::writeLog('core', __METHOD__.', name: ' . $name. ' exists already', OCP\Util::DEBUG);
- return false;
- }
- try {
- OCP\DB::insertIfNotExist(self::CATEGORY_TABLE,
- array(
- 'uid' => $this->user,
- 'type' => $this->type,
- 'category' => $name,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- $id = OCP\DB::insertid(self::CATEGORY_TABLE);
- OCP\Util::writeLog('core', __METHOD__.', id: ' . $id, OCP\Util::DEBUG);
- $this->categories[$id] = $name;
- return $id;
- }
-
- /**
- * @brief Rename category.
- * @param string $from The name of the existing category
- * @param string $to The new name of the category.
- * @returns bool
- */
- public function rename($from, $to) {
- $id = $this->array_searchi($from, $this->categories);
- if($id === false) {
- OCP\Util::writeLog('core', __METHOD__.', category: ' . $from. ' does not exist', OCP\Util::DEBUG);
- return false;
- }
-
- $sql = 'UPDATE `' . self::CATEGORY_TABLE . '` SET `category` = ? '
- . 'WHERE `uid` = ? AND `type` = ? AND `id` = ?';
- try {
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($to, $this->user, $this->type, $id));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- $this->categories[$id] = $to;
- return true;
- }
-
- /**
- * @brief Add a new category.
- * @param $names A string with a name or an array of strings containing
- * the name(s) of the categor(y|ies) to add.
- * @param $sync bool When true, save the categories
- * @param $id int Optional object id to add to this|these categor(y|ies)
- * @returns bool Returns false on error.
- */
- public function addMulti($names, $sync=false, $id = null) {
- if(!is_array($names)) {
- $names = array($names);
- }
- $names = array_map('trim', $names);
- $newones = array();
- foreach($names as $name) {
- if(($this->in_arrayi(
- $name, $this->categories) == false) && $name != '') {
- $newones[] = $name;
- }
- if(!is_null($id) ) {
- // Insert $objectid, $categoryid pairs if not exist.
- self::$relations[] = array('objid' => $id, 'category' => $name);
- }
- }
- $this->categories = array_merge($this->categories, $newones);
- if($sync === true) {
- $this->save();
- }
-
- return true;
- }
-
- /**
- * @brief Extracts categories from a vobject and add the ones not already present.
- * @param $vobject The instance of OC_VObject to load the categories from.
- */
- public function loadFromVObject($id, $vobject, $sync=false) {
- $this->addMulti($vobject->getAsArray('CATEGORIES'), $sync, $id);
- }
-
- /**
- * @brief Reset saved categories and rescan supplied vobjects for categories.
- * @param $objects An array of vobjects (as text).
- * To get the object array, do something like:
- * // For Addressbook:
- * $categories = new OC_VCategories('contacts');
- * $stmt = OC_DB::prepare( 'SELECT `carddata` FROM `*PREFIX*contacts_cards`' );
- * $result = $stmt->execute();
- * $objects = array();
- * if(!is_null($result)) {
- * while( $row = $result->fetchRow()){
- * $objects[] = array($row['id'], $row['carddata']);
- * }
- * }
- * $categories->rescan($objects);
- */
- public function rescan($objects, $sync=true, $reset=true) {
-
- if($reset === true) {
- $result = null;
- // Find all objectid/categoryid pairs.
- try {
- $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ?');
- $result = $stmt->execute(array($this->user, $this->type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
-
- // And delete them.
- if(!is_null($result)) {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `categoryid` = ? AND `type`= ?');
- while( $row = $result->fetchRow()) {
- $stmt->execute(array($row['id'], $this->type));
- }
- }
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ? AND `type` = ?');
- $result = $stmt->execute(array($this->user, $this->type));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__ . ', exception: '
- . $e->getMessage(), OCP\Util::ERROR);
- return;
- }
- $this->categories = array();
- }
- // Parse all the VObjects
- foreach($objects as $object) {
- $vobject = OC_VObject::parse($object[1]);
- if(!is_null($vobject)) {
- // Load the categories
- $this->loadFromVObject($object[0], $vobject, $sync);
- } else {
- OC_Log::write('core', __METHOD__ . ', unable to parse. ID: ' . ', '
- . substr($object, 0, 100) . '(...)', OC_Log::DEBUG);
- }
- }
- $this->save();
- }
-
- /**
- * @brief Save the list with categories
- */
- private function save() {
- if(is_array($this->categories)) {
- foreach($this->categories as $category) {
- try {
- OCP\DB::insertIfNotExist(self::CATEGORY_TABLE,
- array(
- 'uid' => $this->user,
- 'type' => $this->type,
- 'category' => $category,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- // reload categories to get the proper ids.
- $this->loadCategories();
- // Loop through temporarily cached objectid/categoryname pairs
- // and save relations.
- $categories = $this->categories;
- // For some reason this is needed or array_search(i) will return 0..?
- ksort($categories);
- foreach(self::$relations as $relation) {
- $catid = $this->array_searchi($relation['category'], $categories);
- OC_Log::write('core', __METHOD__ . 'catid, ' . $relation['category'] . ' ' . $catid, OC_Log::DEBUG);
- if($catid) {
- try {
- OCP\DB::insertIfNotExist(self::RELATION_TABLE,
- array(
- 'objid' => $relation['objid'],
- 'categoryid' => $catid,
- 'type' => $this->type,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- }
- self::$relations = array(); // reset
- } else {
- OC_Log::write('core', __METHOD__.', $this->categories is not an array! '
- . print_r($this->categories, true), OC_Log::ERROR);
- }
- }
-
- /**
- * @brief Delete categories and category/object relations for a user.
- * For hooking up on post_deleteUser
- * @param string $uid The user id for which entries should be purged.
- */
- public static function post_deleteUser($arguments) {
- // Find all objectid/categoryid pairs.
- $result = null;
- try {
- $stmt = OCP\DB::prepare('SELECT `id` FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ?');
- $result = $stmt->execute(array($arguments['uid']));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
-
- if(!is_null($result)) {
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `categoryid` = ?');
- while( $row = $result->fetchRow()) {
- try {
- $stmt->execute(array($row['id']));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- }
- }
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` '
- . 'WHERE `uid` = ?');
- $result = $stmt->execute(array($arguments['uid']));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__ . ', exception: '
- . $e->getMessage(), OCP\Util::ERROR);
- }
- }
-
- /**
- * @brief Delete category/object relations from the db
- * @param array $ids The ids of the objects
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean Returns false on error.
- */
- public function purgeObjects(array $ids, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- if(count($ids) === 0) {
- // job done ;)
- return true;
- }
- $updates = $ids;
- try {
- $query = 'DELETE FROM `' . self::RELATION_TABLE . '` ';
- $query .= 'WHERE `objid` IN (' . str_repeat('?,', count($ids)-1) . '?) ';
- $query .= 'AND `type`= ?';
- $updates[] = $type;
- $stmt = OCP\DB::prepare($query);
- $result = $stmt->execute($updates);
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- return false;
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: ' . $e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- return true;
- }
-
- /**
- * Get favorites for an object type
- *
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns array An array of object ids.
- */
- public function getFavorites($type = null) {
- $type = is_null($type) ? $this->type : $type;
-
- try {
- return $this->idsForCategory(self::CATEGORY_FAVORITE);
- } catch(Exception $e) {
- // No favorites
- return array();
- }
- }
-
- /**
- * Add an object to favorites
- *
- * @param int $objid The id of the object
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean
- */
- public function addToFavorites($objid, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- if(!$this->hasCategory(self::CATEGORY_FAVORITE)) {
- $this->add(self::CATEGORY_FAVORITE, true);
- }
- return $this->addToCategory($objid, self::CATEGORY_FAVORITE, $type);
- }
-
- /**
- * Remove an object from favorites
- *
- * @param int $objid The id of the object
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean
- */
- public function removeFromFavorites($objid, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- return $this->removeFromCategory($objid, self::CATEGORY_FAVORITE, $type);
- }
-
- /**
- * @brief Creates a category/object relation.
- * @param int $objid The id of the object
- * @param int|string $category The id or name of the category
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean Returns false on database error.
- */
- public function addToCategory($objid, $category, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- if(is_string($category) && !is_numeric($category)) {
- if(!$this->hasCategory($category)) {
- $this->add($category, true);
- }
- $categoryid = $this->array_searchi($category, $this->categories);
- } else {
- $categoryid = $category;
- }
- try {
- OCP\DB::insertIfNotExist(self::RELATION_TABLE,
- array(
- 'objid' => $objid,
- 'categoryid' => $categoryid,
- 'type' => $type,
- ));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- return true;
- }
-
- /**
- * @brief Delete single category/object relation from the db
- * @param int $objid The id of the object
- * @param int|string $category The id or name of the category
- * @param string $type The type of object (event/contact/task/journal).
- * Defaults to the type set in the instance
- * @returns boolean
- */
- public function removeFromCategory($objid, $category, $type = null) {
- $type = is_null($type) ? $this->type : $type;
- $categoryid = (is_string($category) && !is_numeric($category))
- ? $this->array_searchi($category, $this->categories)
- : $category;
- try {
- $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `objid` = ? AND `categoryid` = ? AND `type` = ?';
- OCP\Util::writeLog('core', __METHOD__.', sql: ' . $objid . ' ' . $categoryid . ' ' . $type,
- OCP\Util::DEBUG);
- $stmt = OCP\DB::prepare($sql);
- $stmt->execute(array($objid, $categoryid, $type));
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- return true;
- }
-
- /**
- * @brief Delete categories from the db and from all the vobject supplied
- * @param $names An array of categories to delete
- * @param $objects An array of arrays with [id,vobject] (as text) pairs suitable for updating the apps object table.
- */
- public function delete($names, array &$objects=null) {
- if(!is_array($names)) {
- $names = array($names);
- }
-
- OC_Log::write('core', __METHOD__ . ', before: '
- . print_r($this->categories, true), OC_Log::DEBUG);
- foreach($names as $name) {
- $id = null;
- OC_Log::write('core', __METHOD__.', '.$name, OC_Log::DEBUG);
- if($this->hasCategory($name)) {
- $id = $this->array_searchi($name, $this->categories);
- unset($this->categories[$id]);
- }
- try {
- $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` WHERE '
- . '`uid` = ? AND `type` = ? AND `category` = ?');
- $result = $stmt->execute(array($this->user, $this->type, $name));
- if (OC_DB::isError($result)) {
- OC_Log::write('core', __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__ . ', exception: '
- . $e->getMessage(), OCP\Util::ERROR);
- }
- if(!is_null($id) && $id !== false) {
- try {
- $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` '
- . 'WHERE `categoryid` = ?';
- $stmt = OCP\DB::prepare($sql);
- $result = $stmt->execute(array($id));
- if (OC_DB::isError($result)) {
- OC_Log::write('core',
- __METHOD__. 'DB error: ' . OC_DB::getErrorMessage($result),
- OC_Log::ERROR);
- }
- } catch(Exception $e) {
- OCP\Util::writeLog('core', __METHOD__.', exception: '.$e->getMessage(),
- OCP\Util::ERROR);
- return false;
- }
- }
- }
- OC_Log::write('core', __METHOD__.', after: '
- . print_r($this->categories, true), OC_Log::DEBUG);
- if(!is_null($objects)) {
- foreach($objects as $key=>&$value) {
- $vobject = OC_VObject::parse($value[1]);
- if(!is_null($vobject)) {
- $object = null;
- $componentname = '';
- if (isset($vobject->VEVENT)) {
- $object = $vobject->VEVENT;
- $componentname = 'VEVENT';
- } else
- if (isset($vobject->VTODO)) {
- $object = $vobject->VTODO;
- $componentname = 'VTODO';
- } else
- if (isset($vobject->VJOURNAL)) {
- $object = $vobject->VJOURNAL;
- $componentname = 'VJOURNAL';
- } else {
- $object = $vobject;
- }
- $categories = $object->getAsArray('CATEGORIES');
- foreach($names as $name) {
- $idx = $this->array_searchi($name, $categories);
- if($idx !== false) {
- OC_Log::write('core', __METHOD__
- .', unsetting: '
- . $categories[$this->array_searchi($name, $categories)],
- OC_Log::DEBUG);
- unset($categories[$this->array_searchi($name, $categories)]);
- }
- }
-
- $object->setString('CATEGORIES', implode(',', $categories));
- if($vobject !== $object) {
- $vobject[$componentname] = $object;
- }
- $value[1] = $vobject->serialize();
- $objects[$key] = $value;
- } else {
- OC_Log::write('core', __METHOD__
- .', unable to parse. ID: ' . $value[0] . ', '
- . substr($value[1], 0, 50) . '(...)', OC_Log::DEBUG);
- }
- }
- }
- }
-
- // case-insensitive in_array
- private function in_arrayi($needle, $haystack) {
- if(!is_array($haystack)) {
- return false;
- }
- return in_array(strtolower($needle), array_map('strtolower', $haystack));
- }
-
- // case-insensitive array_search
- private function array_searchi($needle, $haystack) {
- if(!is_array($haystack)) {
- return false;
- }
- return array_search(strtolower($needle), array_map('strtolower', $haystack));
- }
-}