diff options
author | Bart Visscher <bartv@thisnet.nl> | 2013-10-02 18:23:59 +0200 |
---|---|---|
committer | Bart Visscher <bartv@thisnet.nl> | 2013-10-02 18:23:59 +0200 |
commit | a90ea2c069998d378ec49825ce53b7651a459c1a (patch) | |
tree | 7b1afe4ef7dd5509f25c4be7829aa6834877a979 /lib | |
parent | 5db98aadd30b9f1218dda8f836acca0062ce1d9f (diff) | |
parent | 551e80979046358b9cbc8a0f8db0ff9cdf919e33 (diff) | |
download | nextcloud-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.php | 11 | ||||
-rw-r--r-- | lib/base.php | 26 | ||||
-rw-r--r-- | lib/cache/fileglobalgc.php | 8 | ||||
-rw-r--r-- | lib/l10n/lt_LT.php | 30 | ||||
-rw-r--r-- | lib/private/allconfig.php | 77 | ||||
-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.php | 98 | ||||
-rw-r--r-- | lib/private/appframework/controller/controller.php | 142 | ||||
-rw-r--r-- | lib/private/appframework/core/api.php | 348 | ||||
-rw-r--r-- | lib/private/appframework/dependencyinjection/dicontainer.php | 146 | ||||
-rw-r--r-- | lib/private/appframework/http/dispatcher.php | 100 | ||||
-rw-r--r-- | lib/private/appframework/http/downloadresponse.php | 50 | ||||
-rw-r--r-- | lib/private/appframework/http/http.php | 148 | ||||
-rw-r--r-- | lib/private/appframework/http/redirectresponse.php | 56 | ||||
-rw-r--r-- | lib/private/appframework/http/request.php | 307 | ||||
-rw-r--r-- | lib/private/appframework/middleware/middleware.php | 100 | ||||
-rw-r--r-- | lib/private/appframework/middleware/middlewaredispatcher.php | 159 | ||||
-rw-r--r-- | lib/private/appframework/middleware/security/securityexception.php | 41 | ||||
-rw-r--r-- | lib/private/appframework/middleware/security/securitymiddleware.php | 136 | ||||
-rw-r--r-- | lib/private/appframework/routing/routeactionhandler.php | 42 | ||||
-rw-r--r-- | lib/private/appframework/routing/routeconfig.php | 186 | ||||
-rw-r--r-- | lib/private/appframework/utility/methodannotationreader.php | 61 | ||||
-rw-r--r-- | lib/private/appframework/utility/simplecontainer.php | 44 | ||||
-rw-r--r-- | lib/private/appframework/utility/timefactory.php | 42 | ||||
-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.php | 89 | ||||
-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.php | 9 | ||||
-rw-r--r-- | lib/private/cache/usercache.php | 77 | ||||
-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.php | 101 | ||||
-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.php | 145 | ||||
-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.php | 50 | ||||
-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.php | 155 | ||||
-rw-r--r-- | lib/private/files/node/folder.php | 382 | ||||
-rw-r--r-- | lib/private/files/node/node.php | 245 | ||||
-rw-r--r-- | lib/private/files/node/nonexistingfile.php | 89 | ||||
-rw-r--r-- | lib/private/files/node/nonexistingfolder.php | 113 | ||||
-rw-r--r-- | lib/private/files/node/root.php | 337 | ||||
-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.php | 72 | ||||
-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.php | 8 | ||||
-rw-r--r-- | lib/private/l10n/oc.php (renamed from lib/l10n/oc.php) | 0 | ||||
-rw-r--r-- | lib/private/l10n/pa.php | 16 | ||||
-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.php | 10 | ||||
-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.php | 146 | ||||
-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.php | 64 | ||||
-rw-r--r-- | lib/private/notsquareexception.php | 12 | ||||
-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-x | lib/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-x | lib/private/previewmanager.php | 38 | ||||
-rwxr-xr-x | lib/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.php | 255 | ||||
-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.php | 68 | ||||
-rw-r--r-- | lib/private/tags.php | 642 | ||||
-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-x | lib/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.php | 16 | ||||
-rw-r--r-- | lib/public/appframework/app.php | 81 | ||||
-rw-r--r-- | lib/public/appframework/http/http.php | 89 | ||||
-rw-r--r-- | lib/public/appframework/http/jsonresponse.php | 74 | ||||
-rw-r--r-- | lib/public/appframework/http/response.php | 169 | ||||
-rw-r--r-- | lib/public/appframework/http/templateresponse.php | 126 | ||||
-rw-r--r-- | lib/public/appframework/iapi.php | 151 | ||||
-rw-r--r-- | lib/public/appframework/iappcontainer.php | 57 | ||||
-rw-r--r-- | lib/public/appframework/imiddleware.php | 88 | ||||
-rw-r--r-- | lib/public/contacts.php | 55 | ||||
-rw-r--r-- | lib/public/contacts/imanager.php | 150 | ||||
-rw-r--r-- | lib/public/db.php | 11 | ||||
-rw-r--r-- | lib/public/files/alreadyexistsexception.php | 11 | ||||
-rw-r--r-- | lib/public/files/file.php | 53 | ||||
-rw-r--r-- | lib/public/files/folder.php | 119 | ||||
-rw-r--r-- | lib/public/files/node.php | 159 | ||||
-rw-r--r-- | lib/public/files/notenoughspaceexception.php | 11 | ||||
-rw-r--r-- | lib/public/files/notfoundexception.php | 11 | ||||
-rw-r--r-- | lib/public/files/notpermittedexception.php | 11 | ||||
-rw-r--r-- | lib/public/files/storage.php | 297 | ||||
-rw-r--r-- | lib/public/icache.php | 55 | ||||
-rw-r--r-- | lib/public/iconfig.php | 65 | ||||
-rw-r--r-- | lib/public/icontainer.php | 64 | ||||
-rw-r--r-- | lib/public/idbconnection.php | 74 | ||||
-rw-r--r-- | lib/public/inavigationmanager.php | 27 | ||||
-rw-r--r-- | lib/public/ipreview.php | 35 | ||||
-rw-r--r-- | lib/public/irequest.php | 96 | ||||
-rw-r--r-- | lib/public/iservercontainer.php | 125 | ||||
-rw-r--r-- | lib/public/isession.php | 56 | ||||
-rw-r--r-- | lib/public/itagmanager.php | 48 | ||||
-rw-r--r-- | lib/public/itags.php | 164 | ||||
-rw-r--r-- | lib/public/iusersession.php | 30 | ||||
-rw-r--r-- | lib/public/preview.php | 34 | ||||
-rw-r--r-- | lib/public/share.php | 41 | ||||
-rw-r--r-- | lib/public/user.php | 2 | ||||
-rw-r--r-- | lib/vcategories.php | 821 |
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)); - } -} |